3
0
刘洋 1 жил өмнө
parent
commit
61d9cee65f

+ 71 - 0
src/components/AppTypeSelect.vue

@@ -0,0 +1,71 @@
+<template>
+  <el-select
+    v-model="selected"
+    class="app-type-select"
+    :placeholder="placeholder"
+    filterable
+    :clearable="clearable"
+    :disabled="disabled"
+    @change="select"
+  >
+    <el-option
+      v-for="item in optionList"
+      :key="item.code"
+      :value="item.code"
+      :label="item.name"
+    >
+    </el-option>
+  </el-select>
+</template>
+
+<script>
+import { appTypeList } from "../modules/admin/api";
+
+export default {
+  name: "app-type-select",
+  props: {
+    disabled: { type: Boolean, default: false },
+    placeholder: { type: String, default: "请选择应用类型" },
+    value: { type: [Number, String], default: "" },
+    clearable: { type: Boolean, default: false },
+    init: { type: Boolean, default: false },
+  },
+  data() {
+    return {
+      optionList: [],
+      selected: "",
+    };
+  },
+  watch: {
+    value: {
+      immediate: true,
+      handler(val) {
+        this.selected = val;
+      },
+    },
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    async search() {
+      this.optionList = [];
+
+      const res = await appTypeList();
+      this.optionList = res || [];
+      this.$emit("getOptions", this.optionList);
+      if (this.init && res?.length) {
+        this.selected = res[0].code;
+        this.select();
+      }
+    },
+    select() {
+      this.$emit("input", this.selected);
+      this.$emit(
+        "change",
+        this.optionList.find((item) => item.id === this.selected)
+      );
+    },
+  },
+};
+</script>

+ 77 - 0
src/components/ModelSelect.vue

@@ -0,0 +1,77 @@
+<template>
+  <el-cascader
+    v-model="selected"
+    :options="options"
+    :props="attrs"
+    @change="handleChange"
+  ></el-cascader>
+</template>
+
+<script>
+import { modelSupplierListQuery } from "@/modules/admin/api.js";
+export default {
+  name: "ModelSelect",
+  props: {
+    level: {
+      type: Number,
+      default: 1,
+    },
+    value: {
+      type: [Number, String],
+    },
+  },
+  computed: {
+    attrs() {
+      const l = this.level;
+      return l > 1
+        ? {
+            lazy: true,
+            lazyLoad(node, resolve) {
+              console.log("node", node);
+              return [];
+              // setTimeout(() => {
+              //   const nodes = Array.from({ length: level + 1 }).map((item) => ({
+              //     value: ++id,
+              //     label: `选项${id}`,
+              //     leaf: level >= l,
+              //   }));
+              //   // 通过调用resolve将子节点数据返回,通知组件数据加载完成
+              //   resolve(nodes);
+              // }, 1000);
+            },
+          }
+        : null;
+    },
+  },
+  data() {
+    return {
+      selected: "",
+      options: [],
+    };
+  },
+  created() {
+    this.selected = this.value || "";
+    modelSupplierListQuery().then((res) => {
+      this.options = (res || []).map((item) => ({
+        value: item.id,
+        label: item.name,
+      }));
+    });
+  },
+  methods: {
+    handleChange() {
+      this.$emit(
+        "input",
+        this.selected?.length ? this.selected[this.selected.length - 1] : ""
+      );
+    },
+  },
+  watch: {
+    value(val) {
+      this.selected = String(val);
+    },
+  },
+};
+</script>
+
+<style></style>

+ 2 - 0
src/constants/navs.js

@@ -38,11 +38,13 @@ export const navs = [
     parentId: "1",
     name: "OCR管理",
     url: "OcrManage",
+    privilege: "OCR_SUPPLIER_VIEW",
   },
   {
     id: "7",
     parentId: "1",
     name: "大模型管理",
     url: "ModelSupplierManage",
+    privilege: "LLM_SUPPLIER_VIEW",
   },
 ];

+ 48 - 0
src/modules/admin/api.js

@@ -280,3 +280,51 @@ export const ocrInsertOrUpdate = (datas) => {
     paramsSerializer: qsRepeatParams,
   });
 };
+
+export const ocrSupplierDetail = (params) => {
+  return $postParam("/api/admin/ocr/supplier/detail", params);
+};
+
+export const modelSupplierListQuery = () => {
+  return $postParam("/api/admin/llm/supplier/list");
+};
+
+export const ModelSupplierInsertOrUpdate = (datas) => {
+  const url = datas.id
+    ? "/api/admin/llm/supplier/update"
+    : "/api/admin/llm/supplier/insert";
+  return $postParam(url, datas, {
+    paramsSerializer: qsRepeatParams,
+  });
+};
+
+export const modelSupplierDetail = (params) => {
+  return $postParam("/api/admin/llm/supplier/detail", params);
+};
+
+export const modelListQuery = (params) => {
+  return $postParam("/api/admin/llm/model/list", params);
+};
+export const ModelInsertOrUpdate = (datas) => {
+  const url = datas.id
+    ? "/api/admin/llm/model/update"
+    : "/api/admin/llm/model/insert";
+  return $postParam(url, datas, {
+    paramsSerializer: qsRepeatParams,
+  });
+};
+
+export const cueWordListQuery = (params) => {
+  return $postParam("/api/admin/llm/model/prompt_template/list", params);
+};
+export const appTypeList = (datas = {}) => {
+  return $postParam("/api/admin/llm/app_types", datas);
+};
+export const cueWrdInsertOrUpdate = (datas) => {
+  const url = datas.id
+    ? "/api/admin/llm/model/prompt_template/update"
+    : "/api/admin/llm/model/prompt_template/insert";
+  return $postParam(url, datas, {
+    paramsSerializer: qsRepeatParams,
+  });
+};

+ 165 - 0
src/modules/admin/big-model/ModelManage/CueWordTpl/ModifyTpl.vue

@@ -0,0 +1,165 @@
+<template>
+  <el-dialog
+    class="modify-model"
+    :visible.sync="modalIsShow"
+    :title="title"
+    top="10vh"
+    width="600px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @open="visibleChange"
+  >
+    <el-form
+      ref="modalFormComp"
+      :model="modalForm"
+      :rules="rules"
+      label-width="180px"
+    >
+      <el-form-item prop="appType" label="应用类型:">
+        <AppTypeSelect
+          v-model="modalForm.appType"
+          :disabled="isEdit"
+        ></AppTypeSelect>
+      </el-form-item>
+      <el-form-item prop="system" label="system角色提示词模版:">
+        <el-input
+          v-model.trim="modalForm.system"
+          placeholder="请输入system角色提示词模版"
+          clearable
+        ></el-input>
+      </el-form-item>
+      <el-form-item prop="user" label="user角色提示词模版:">
+        <el-input
+          v-model.trim="modalForm.user"
+          placeholder="请输入user角色提示词模版"
+          clearable
+        ></el-input>
+      </el-form-item>
+      <el-form-item prop="remark" label="备注:">
+        <el-input
+          v-model.trim="modalForm.remark"
+          placeholder="请输入备注"
+          clearable
+        ></el-input>
+      </el-form-item>
+    </el-form>
+    <div slot="footer">
+      <el-button type="danger" @click="cancel" plain>取消</el-button>
+      <el-button type="primary" :disabled="isSubmit" @click="submit"
+        >确认</el-button
+      >
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { cueWrdInsertOrUpdate } from "../../../api";
+import AppTypeSelect from "@/components/AppTypeSelect.vue";
+
+const initModalForm = {
+  id: "",
+  appType: "",
+  system: "",
+  user: "",
+  remark: "",
+};
+
+export default {
+  name: "modifyCueWordTpl",
+  components: { AppTypeSelect },
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+    modelId: {
+      type: [Number, String],
+      default: "",
+    },
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return "模型提示词" + (this.isEdit ? "编辑" : "新增");
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: {},
+      rules: {
+        appType: [
+          {
+            required: true,
+            message: "请选择应用类型",
+          },
+        ],
+        system: [
+          {
+            required: true,
+            message: "请输入system角色提示词模版",
+          },
+        ],
+        user: [
+          {
+            required: true,
+            message: "请输入user角色提示词模版",
+          },
+        ],
+        remark: [
+          {
+            required: true,
+            message: "请输入备注",
+          },
+        ],
+      },
+    };
+  },
+  methods: {
+    initData(val) {
+      if (val.id) {
+        this.modalForm = this.$objAssign(initModalForm, val);
+      } else {
+        this.modalForm = { ...initModalForm };
+      }
+      this.$nextTick(() => {
+        this.$refs.modalFormComp.clearValidate();
+      });
+    },
+    visibleChange() {
+      this.initData(this.instance);
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+
+      const datas = { ...this.modalForm, modelId: this.modelId };
+      if (this.isEdit) {
+        delete datas.appType;
+      }
+      const data = await cueWrdInsertOrUpdate(datas).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$message.success((this.isEdit ? "修改" : "新增") + "成功!");
+      this.cancel();
+      this.$emit("modified");
+    },
+  },
+};
+</script>

+ 142 - 0
src/modules/admin/big-model/ModelManage/CueWordTpl/index.vue

@@ -0,0 +1,142 @@
+<template>
+  <div class="model-manage">
+    <el-dialog
+      title="提示词模板列表"
+      class="page-dialog"
+      :visible.sync="modalIsShow"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      append-to-body
+      fullscreen
+      @opened="visibleChange"
+    >
+      <div class="part-box part-box-filter part-box-flex">
+        <el-form ref="FilterForm" label-position="left" inline>
+          <el-form-item label="应用类型:">
+            <AppTypeSelect
+              v-model="appType"
+              :init="true"
+              @getOptions="getAppTypeOptions"
+            ></AppTypeSelect>
+          </el-form-item>
+          <el-form-item label-width="0px">
+            <el-button type="primary" @click="getList">查询</el-button>
+          </el-form-item>
+          <el-form-item label-width="0px">
+            <el-button type="success" @click="toAdd">新增</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="part-box part-box-pad">
+        <el-table ref="TableList" :data="dataList" v-loading="loading">
+          <el-table-column prop="id" label="ID"></el-table-column>
+          <el-table-column prop="appType" label="应用类型">
+            <span slot-scope="scope">
+              {{ getAppTypeStr(scope.row.appType) }}
+            </span>
+          </el-table-column>
+          <el-table-column prop="system" label="system角色提示词模版">
+          </el-table-column>
+          <el-table-column prop="user" label="user角色提示词模版">
+          </el-table-column>
+          <el-table-column prop="remark" label="备注"> </el-table-column>
+
+          <el-table-column
+            class-name="action-column"
+            label="操作"
+            width="120"
+            fixed="right"
+          >
+            <template slot-scope="scope">
+              <el-button
+                class="btn-primary"
+                type="text"
+                @click="toEdit(scope.row)"
+                >编辑</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </el-dialog>
+    <ModifyTpl
+      :instance="curCueWordRow"
+      ref="ModifyTpl"
+      :modelId="curRow.id"
+      @modified="getList"
+    ></ModifyTpl>
+  </div>
+</template>
+
+<script>
+import { cueWordListQuery } from "../../../api";
+import AppTypeSelect from "@/components/AppTypeSelect.vue";
+import ModifyTpl from "./ModifyTpl.vue";
+export default {
+  name: "CueWordTpl",
+  components: { AppTypeSelect, ModifyTpl },
+  props: {
+    curRow: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      loading: false,
+      dataList: [],
+      curCueWordRow: {},
+      appType: "",
+      appTypeOptions: [],
+    };
+  },
+  methods: {
+    getAppTypeOptions(arr) {
+      this.appTypeOptions = arr;
+    },
+    getAppTypeStr(code) {
+      return this.appTypeOptions.find((item) => item.code == code)?.name;
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    getList() {
+      this.loading = true;
+      cueWordListQuery({ modelId: this.curRow.id, appType: this.appType }).then(
+        (res) => {
+          this.dataList = res || [];
+          this.loading = false;
+        }
+      );
+    },
+    async visibleChange() {
+      if (this.appType) {
+        this.getList();
+      }
+    },
+    toAdd() {
+      this.curCueWordRow = {};
+      this.$refs.ModifyTpl.open();
+    },
+    toEdit(row) {
+      this.curCueWordRow = row;
+      this.$refs.ModifyTpl.open();
+    },
+  },
+  watch: {
+    appType(val) {
+      if (val) {
+        this.getList();
+      }
+    },
+  },
+};
+</script>
+
+<style></style>

+ 167 - 0
src/modules/admin/big-model/ModelManage/ModifyModel.vue

@@ -0,0 +1,167 @@
+<template>
+  <el-dialog
+    class="modify-model"
+    :visible.sync="modalIsShow"
+    :title="title"
+    top="10vh"
+    width="500px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @open="visibleChange"
+  >
+    <el-form
+      ref="modalFormComp"
+      :model="modalForm"
+      :rules="rules"
+      label-width="110px"
+    >
+      <el-form-item prop="supplierId" label="供应商:">
+        <ModelSelect v-model="modalForm.supplierId" :level="1"></ModelSelect>
+      </el-form-item>
+      <el-form-item prop="name" label="名称:">
+        <el-input
+          v-model.trim="modalForm.name"
+          placeholder="请输入名称"
+          clearable
+        ></el-input>
+      </el-form-item>
+      <el-form-item prop="qpm" label="QPM限流:">
+        <el-input
+          v-model.trim="modalForm.qpm"
+          placeholder="请输入QPM限流"
+          clearable
+        ></el-input>
+      </el-form-item>
+      <el-form-item prop="tpm" label="TPM限流:">
+        <el-input
+          v-model.trim="modalForm.tpm"
+          placeholder="请输入TPM限流"
+          clearable
+        ></el-input>
+      </el-form-item>
+    </el-form>
+    <div slot="footer">
+      <el-button type="danger" @click="cancel" plain>取消</el-button>
+      <el-button type="primary" :disabled="isSubmit" @click="submit"
+        >确认</el-button
+      >
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { ModelInsertOrUpdate } from "../../api";
+import ModelSelect from "@/components/ModelSelect.vue";
+
+const initModalForm = {
+  id: "",
+  supplierId: "",
+  name: "",
+  qpm: "",
+  tpm: "",
+};
+
+export default {
+  name: "modifyModel",
+  components: { ModelSelect },
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return "大模型" + (this.isEdit ? "编辑" : "新增");
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: {
+        id: "",
+        supplierId: "",
+        name: "",
+        qpm: "",
+        tpm: "",
+      },
+      rules: {
+        supplierId: [
+          {
+            required: true,
+            message: "请选择供应商",
+          },
+        ],
+        name: [
+          {
+            required: true,
+            message: "请输入名称",
+          },
+        ],
+        qpm: [
+          {
+            required: true,
+            message: "请输入QPM限流",
+          },
+        ],
+        tpm: [
+          {
+            required: true,
+            message: "请输入TPM限流",
+          },
+        ],
+      },
+    };
+  },
+  methods: {
+    initData(val) {
+      if (val.id) {
+        this.modalForm = {
+          id: val.id,
+          supplierId: val.supplierId,
+          name: val.name,
+          qpm: val.qpm,
+          tpm: val.tpm,
+        };
+      } else {
+        this.modalForm = { ...initModalForm };
+      }
+      this.$nextTick(() => {
+        this.$refs.modalFormComp.clearValidate();
+      });
+    },
+    visibleChange() {
+      this.initData(this.instance);
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+
+      const datas = { ...this.modalForm };
+      const data = await ModelInsertOrUpdate(datas).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$message.success((this.isEdit ? "修改" : "新增") + "成功!");
+      this.cancel();
+      this.$emit("modified");
+    },
+  },
+};
+</script>

+ 138 - 0
src/modules/admin/big-model/ModelManage/index.vue

@@ -0,0 +1,138 @@
+<template>
+  <div class="model-manage">
+    <el-dialog
+      title="模型列表"
+      class="page-dialog"
+      :visible.sync="modalIsShow"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      append-to-body
+      fullscreen
+      @opened="visibleChange"
+    >
+      <div
+        class="part-box part-box-filter part-box-flex"
+        style="padding-bottom: 20px"
+      >
+        <el-button
+          v-if="checkPrivilege('LLM_MODEL_INSERT')"
+          type="success"
+          @click="toAdd"
+          >新增</el-button
+        >
+        <span v-else></span>
+        <el-tooltip effect="dark" content="刷新" placement="bottom">
+          <el-button icon="el-icon-refresh-right" @click="getList"></el-button>
+        </el-tooltip>
+      </div>
+      <div class="part-box part-box-pad">
+        <el-table ref="TableList" :data="dataList" v-loading="loading">
+          <el-table-column prop="id" label="ID"></el-table-column>
+          <el-table-column prop="name" label="名称"> </el-table-column>
+          <el-table-column prop="qpm" label="QPM限流"> </el-table-column>
+          <el-table-column prop="tpm" label="TPM限流"> </el-table-column>
+          <el-table-column prop="createTime" label="创建时间">
+            <span slot-scope="scope">{{
+              scope.row.createTime | timestampFilter
+            }}</span>
+          </el-table-column>
+          <el-table-column prop="updateTime" label="修改时间">
+            <span slot-scope="scope">{{
+              scope.row.updateTime | timestampFilter
+            }}</span>
+          </el-table-column>
+          <el-table-column
+            class-name="action-column"
+            label="操作"
+            width="200"
+            fixed="right"
+          >
+            <template slot-scope="scope">
+              <el-button
+                v-if="checkPrivilege('LLM_MODEL_EDIT')"
+                class="btn-primary"
+                type="text"
+                @click="toEdit(scope.row)"
+                >编辑</el-button
+              >
+              <el-button
+                class="btn-primary"
+                type="text"
+                @click="toCueWord(scope.row)"
+                >提示词模板</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </el-dialog>
+    <ModifyModel
+      :instance="curModel"
+      ref="ModifyModel"
+      @modified="getList"
+    ></ModifyModel>
+    <CueWordTpl
+      :curRow="curModel"
+      ref="CueWordTpl"
+      @modified="getList"
+    ></CueWordTpl>
+  </div>
+</template>
+
+<script>
+import { modelListQuery } from "../../api";
+import ModifyModel from "./ModifyModel.vue";
+import CueWordTpl from "./CueWordTpl/index.vue";
+export default {
+  name: "ModelManage",
+  components: { ModifyModel, CueWordTpl },
+  props: {
+    curRow: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      loading: false,
+      dataList: [],
+      curModel: {},
+    };
+  },
+  methods: {
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    getList() {
+      this.loading = true;
+      modelListQuery({ supplierId: this.curRow.id }).then((res) => {
+        this.dataList = res || [];
+        this.loading = false;
+      });
+    },
+    async visibleChange() {
+      this.getList();
+    },
+    toAdd() {
+      this.curModel = {};
+      this.$refs.ModifyModel.open();
+    },
+    toEdit(row) {
+      this.curModel = row;
+      this.$refs.ModifyModel.open();
+    },
+    toCueWord(row) {
+      this.curModel = row;
+      this.$refs.CueWordTpl.open();
+    },
+  },
+};
+</script>
+
+<style></style>

+ 107 - 2
src/modules/admin/big-model/ModelSupplierManage.vue

@@ -1,9 +1,114 @@
 <template>
-  <div class="model-supplier">模型供应商</div>
+  <div class="model-supplier">
+    <div
+      class="part-box part-box-filter part-box-flex"
+      style="padding-bottom: 20px"
+    >
+      <el-button
+        v-if="checkPrivilege('LLM_SUPPLIER_INSERT')"
+        type="success"
+        @click="toAdd"
+        >新增</el-button
+      >
+      <span v-else></span>
+      <el-tooltip effect="dark" content="刷新" placement="bottom">
+        <el-button icon="el-icon-refresh-right" @click="getList"></el-button>
+      </el-tooltip>
+    </div>
+    <div class="part-box part-box-pad">
+      <el-table ref="TableList" :data="dataList" v-loading="loading">
+        <el-table-column prop="id" label="ID"></el-table-column>
+        <el-table-column prop="name" label="名称"> </el-table-column>
+        <el-table-column prop="createTime" label="创建时间">
+          <span slot-scope="scope">{{
+            scope.row.createTime | timestampFilter
+          }}</span>
+        </el-table-column>
+        <el-table-column prop="updateTime" label="修改时间">
+          <span slot-scope="scope">{{
+            scope.row.updateTime | timestampFilter
+          }}</span>
+        </el-table-column>
+        <el-table-column
+          v-if="
+            checkPrivilege('LLM_SUPPLIER_EDIT') ||
+            checkPrivilege('LLM_MODEL_VIEW')
+          "
+          class-name="action-column"
+          label="操作"
+          width="120"
+          fixed="right"
+        >
+          <template slot-scope="scope">
+            <el-button
+              v-if="checkPrivilege('LLM_SUPPLIER_EDIT')"
+              class="btn-primary"
+              type="text"
+              @click="toEdit(scope.row)"
+              >编辑</el-button
+            >
+            <el-button
+              v-if="checkPrivilege('LLM_MODEL_VIEW')"
+              class="btn-primary"
+              type="text"
+              @click="toModelManage(scope.row)"
+              >模型管理</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <modify-supplier
+      ref="ModifySupplier"
+      :instance="curRow"
+      @modified="getList"
+    ></modify-supplier>
+    <ModelManage ref="ModelManage" :curRow="curRow"></ModelManage>
+  </div>
 </template>
 
 <script>
-export default {};
+import { modelSupplierListQuery } from "../api";
+import ModifySupplier from "./ModifySupplier.vue";
+import ModelManage from "./ModelManage/index.vue";
+
+export default {
+  name: "model-supplier",
+  components: { ModifySupplier, ModelManage },
+  data() {
+    return {
+      dataList: [],
+      curRow: {},
+      loading: false,
+    };
+  },
+  created() {
+    this.initData();
+  },
+  methods: {
+    async getList() {
+      this.loading = true;
+      const data = await modelSupplierListQuery();
+      this.dataList = data;
+      this.loading = false;
+    },
+    initData() {
+      this.getList();
+    },
+    toAdd() {
+      this.curRow = {};
+      this.$refs.ModifySupplier.open();
+    },
+    toEdit(row) {
+      this.curRow = row;
+      this.$refs.ModifySupplier.open();
+    },
+    toModelManage(row) {
+      this.curRow = row;
+      this.$refs.ModelManage.open();
+    },
+  },
+};
 </script>
 
 <style></style>

+ 169 - 0
src/modules/admin/big-model/ModifySupplier.vue

@@ -0,0 +1,169 @@
+<template>
+  <el-dialog
+    class="modify-supplier"
+    :visible.sync="modalIsShow"
+    :title="title"
+    top="10vh"
+    width="500px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @open="visibleChange"
+  >
+    <el-form
+      ref="modalFormComp"
+      :model="modalForm"
+      :rules="rules"
+      label-width="110px"
+    >
+      <el-form-item prop="name" label="名称:">
+        <el-input
+          v-model.trim="modalForm.name"
+          placeholder="请输入名称"
+          clearable
+        ></el-input>
+      </el-form-item>
+      <el-form-item prop="url" label="访问地址:">
+        <el-input
+          v-model.trim="modalForm.url"
+          placeholder="请输入访问地址"
+          clearable
+        ></el-input>
+      </el-form-item>
+      <el-form-item prop="secret" label="访问secret:">
+        <el-input
+          v-model.trim="modalForm.secret"
+          placeholder="请输入访问secret"
+          clearable
+        ></el-input>
+      </el-form-item>
+      <el-form-item prop="clientClass" label="实现类名称:">
+        <el-input
+          v-model.trim="modalForm.chatClientClass"
+          placeholder="请输入实现类名称"
+          clearable
+        ></el-input>
+      </el-form-item>
+    </el-form>
+    <div slot="footer">
+      <el-button type="danger" @click="cancel" plain>取消</el-button>
+      <el-button type="primary" :disabled="isSubmit" @click="submit"
+        >确认</el-button
+      >
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { ModelSupplierInsertOrUpdate, modelSupplierDetail } from "../api";
+
+const initModalForm = {
+  id: "",
+  name: "",
+  url: "",
+  secret: "",
+  chatClientClass: "",
+};
+
+export default {
+  name: "modify-supplier",
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+    readonly: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return (
+        "大模型供应商" +
+        (this.readonly ? "详情" : this.isEdit ? "编辑" : "新增")
+      );
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: {},
+      rules: {
+        name: [
+          {
+            required: true,
+            message: "请输入名称",
+          },
+        ],
+        url: [
+          {
+            required: true,
+            message: "请输入访问地址",
+          },
+        ],
+        secret: [
+          {
+            required: true,
+            message: "请输入访问secret",
+          },
+        ],
+        chatClientClass: [
+          {
+            required: true,
+            message: "请输入实现类名称",
+          },
+        ],
+      },
+    };
+  },
+  methods: {
+    getDetail(id) {
+      modelSupplierDetail({ id }).then((res) => {
+        this.modalForm = this.$objAssign(initModalForm, res || {});
+      });
+    },
+    initData(val) {
+      if (val.id) {
+        this.getDetail(val.id);
+      } else {
+        this.modalForm = { ...initModalForm };
+      }
+      this.$nextTick(() => {
+        this.$refs.modalFormComp.clearValidate();
+      });
+    },
+    visibleChange() {
+      this.initData(this.instance);
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+
+      const datas = { ...this.modalForm };
+      const data = await ModelSupplierInsertOrUpdate(datas).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$message.success((this.isEdit ? "修改" : "新增") + "成功!");
+      this.cancel();
+      this.$emit("modified");
+    },
+  },
+};
+</script>

+ 19 - 3
src/modules/admin/ocr/ModifyOcr.vue

@@ -15,6 +15,7 @@
       :model="modalForm"
       :rules="rules"
       label-width="110px"
+      :disabled="readonly"
     >
       <el-form-item prop="name" label="名称:">
         <el-input
@@ -46,6 +47,7 @@
       </el-form-item>
       <el-form-item prop="clientClass" label="实现类名称:">
         <el-input
+          :disabled="isEdit"
           v-model.trim="modalForm.clientClass"
           placeholder="请输入实现类名称"
           clearable
@@ -69,7 +71,7 @@
 </template>
 
 <script>
-import { ocrInsertOrUpdate } from "../api";
+import { ocrInsertOrUpdate, ocrSupplierDetail } from "../api";
 
 const initModalForm = {
   id: "",
@@ -90,13 +92,19 @@ export default {
         return {};
       },
     },
+    readonly: {
+      type: Boolean,
+      default: false,
+    },
   },
   computed: {
     isEdit() {
       return !!this.instance.id;
     },
     title() {
-      return (this.isEdit ? "编辑" : "新增") + "OCR供应商";
+      return (
+        "OCR供应商" + (this.readonly ? "详情" : this.isEdit ? "编辑" : "新增")
+      );
     },
   },
   data() {
@@ -145,9 +153,14 @@ export default {
     };
   },
   methods: {
+    getDetail(id) {
+      ocrSupplierDetail({ id }).then((res) => {
+        this.modalForm = this.$objAssign(initModalForm, res || {});
+      });
+    },
     initData(val) {
       if (val.id) {
-        this.modalForm = this.$objAssign(initModalForm, val);
+        this.getDetail(val.id);
       } else {
         this.modalForm = { ...initModalForm };
       }
@@ -172,6 +185,9 @@ export default {
       this.isSubmit = true;
 
       const datas = { ...this.modalForm };
+      if (this.isEdit) {
+        delete datas.chatClientClass;
+      }
       const data = await ocrInsertOrUpdate(datas).catch(() => {});
       this.isSubmit = false;
       if (!data) return;

+ 4 - 20
src/modules/admin/ocr/OcrManage.vue

@@ -16,7 +16,7 @@
       </el-tooltip>
     </div>
     <div class="part-box part-box-pad">
-      <el-table ref="TableList" :data="dataList">
+      <el-table ref="TableList" :data="dataList" v-loading="loading">
         <el-table-column prop="id" label="ID"></el-table-column>
         <el-table-column prop="name" label="名称"> </el-table-column>
         <el-table-column prop="createTime" label="创建时间">
@@ -30,23 +30,13 @@
           }}</span>
         </el-table-column>
         <el-table-column
-          v-if="
-            checkPrivilege('OCR_SUPPLIER_EDIT') ||
-            checkPrivilege('OCR_SUPPLIER_VIEW')
-          "
+          v-if="checkPrivilege('OCR_SUPPLIER_EDIT')"
           class-name="action-column"
           label="操作"
           width="120"
           fixed="right"
         >
           <template slot-scope="scope">
-            <el-button
-              v-if="checkPrivilege('OCR_SUPPLIER_EDIT')"
-              class="btn-primary"
-              type="text"
-              @click="toEdit(scope.row)"
-              >详情</el-button
-            >
             <el-button
               v-if="checkPrivilege('OCR_SUPPLIER_EDIT')"
               class="btn-primary"
@@ -76,8 +66,6 @@ export default {
 
   data() {
     return {
-      size: this.GLOBAL.pageSize,
-      total: 0,
       dataList: [],
       curRow: {},
       loading: false,
@@ -92,9 +80,10 @@ export default {
       this.toPage();
     },
     async getList() {
+      this.loading = true;
       const data = await ocrListQuery();
       this.dataList = data;
-      this.total = data.total;
+      this.loading = false;
     },
     toPage() {
       this.getList();
@@ -109,11 +98,6 @@ export default {
       this.curRow = row;
       this.$refs.ModifyOcr.open();
     },
-    toDetail(row) {
-      this.dialogReadonly = true;
-      this.curRow = row;
-      this.$refs.ModifyOcr.open();
-    },
   },
 };
 </script>