zhangxiao
2024-08-05 c1498006d64ac53630980aaa2aaf424300e9815c
fix: 获取URL
4个文件已添加
3个文件已修改
1345 ■■■■ 已修改文件
package.json 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/upload/index.vue 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/model/components/addKeyUrl.vue 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/model/components/addModel.vue 214 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/model/components/addPageModel.vue 351 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/model/components/addTableName.vue 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/model/index.vue 410 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -16,16 +16,14 @@
  },
  "lint-staged": {
    "*.{js,ts,jsx,tsx}": [
      "prettier --write",
      "eslint --fix"
      "prettier --write"
    ],
    "*.vue": [
      "stylelint --fix",
      "prettier --write",
      "eslint --fix"
      "prettier --write"
    ],
    "*.{less,css}": [
      "stylelint --fix",
      "prettier --write"
    ]
  },
src/components/upload/index.vue
New file
@@ -0,0 +1,35 @@
<template>
  <a-upload
    v-model:fileList="fileList"
    list-type="picture-card"
    :limit="limit"
    :action="action"
    @change="handleChange"
    image-preview
  />
</template>
<script setup>
  import { ref } from 'vue';
  const props = defineProps({
    limit: {
      type: Number,
      default: 1,
    },
    action: String, // 上传的服务器地址
  });
  const emit = defineEmits(['update:fileList', 'success']);
  const fileList = ref([]);
  const handleChange = (fileList) => {
    emit('update:fileList', fileList);
    const successFiles = fileList.filter((item) => item.status === 'done');
    if (successFiles.length > 0) {
      emit(
        'success',
        successFiles.map((item) => item.response.data)
      );
    }
  };
</script>
src/views/dmx/model/components/addKeyUrl.vue
New file
@@ -0,0 +1,161 @@
<template>
  <a-modal
    v-model:visible="addTabVisible"
    title="添加模式"
    @before-open="handleOpened"
    @cancel="handleCancel"
    :footer="false"
    title-align="start"
    width="600px"
  >
    <a-form
      ref="formRef"
      :rules="rules"
      :model="form"
      @submit="handleSubmit"
      :style="{ width: '90%', margin: '0 auto' }"
      layout="vertical"
    >
      <a-form-item field="name" label="模型名称">
        <a-input v-model="form.name" placeholder="请输入模型名称" />
      </a-form-item>
      <a-form-item field="describe" label="模型描述">
        <a-textarea placeholder="请输入模型描述" allow-clear />
      </a-form-item>
      <a-form-item field="section" label="模型图片">
        <a-space direction="vertical" :style="{ width: '100%' }">
          <Upload
            :limit="1"
            @update:fileList="updateFileList"
            :oploadUrl="uploadAction"
            @success="handleChange"
          ></Upload>
        </a-space>
      </a-form-item>
      <a-form-item>
        <div style="width: 100%; text-align: right">
          <a-button @click="addTabVisible = false">取消</a-button>
          <a-button style="margin-left: 10px" type="primary" html-type="submit"
            >确定</a-button
          >
        </div>
      </a-form-item>
    </a-form>
  </a-modal>
</template>
<script lang="ts" setup>
  import { onMounted, onBeforeMount, reactive, ref } from 'vue';
  const addTabVisible = defineModel('tabShow');
  const loading = ref(false);
  const props = defineProps({
    task_id: {
      type: Number,
      default: null,
    },
  });
  const form = reactive({
    size: 'medium',
    name: '',
    describe: '',
    age: undefined,
    section: '0',
    province: 'haidian',
    options: [],
    date: '',
    time: '',
    radio: 'radio one',
    slider: 5,
    score: 5,
    switch: false,
    multiSelect: ['section one'],
    treeSelect: '',
    raptor: false,
    prompt:
      '请总结以下段落。 小心数字,不要编造。 段落如下:\n' +
      '      {cluster_content}\n' +
      '以上就是你需要总结的内容。',
  });
  const formRef = ref(null);
  const rules = {
    name: [
      {
        required: true,
        message: '名称不允许为空',
      },
    ],
    describe: [
      {
        required: true,
        message: '描述不允许为空',
      },
    ],
  };
  const handleSubmit = ({ values, errors }) => {
    console.log('values:', values, '\nerrors:', errors);
  };
  const handleClick = () => {
    addTabVisible.value = true;
  };
  const handleBeforeOk = (done) => {
    formRef.value.validate().then((res) => {
      console.log('form:', form);
      if (!form.name) {
        done(false);
      } else {
        console.log('请求数据');
      }
    });
  };
  const handleCancel = () => {
    addTabVisible.value = false;
  };
  //图片上传
  const fileList = ref([]);
  const imageUrls = ref([]);
  const uploadAction = ref('/api/v1/llm/upload');
  const updateFileList = (newFileList) => {
    fileList.value = newFileList;
  };
  const handleChange = (urls) => {
    console.log(urls, 9999);
  };
  const handleOpened = (el) => {
    Object.assign(form, {
      name: '', // 用户名
      nameJoin: '', // 昵称
      post: '', // 岗位
      txt: '', // 备注
    });
    formRef.value.resetFields();
  };
  const file = ref();
  const onChange = (_, currentFile) => {
    file.value = {
      ...currentFile,
      // url: URL.createObjectURL(currentFile.file),
    };
  };
  const onProgress = (currentFile) => {
    file.value = currentFile;
  };
  onBeforeMount(() => {});
  onMounted(() => {});
</script>
<script lang="ts">
  export default {
    name: 'add',
    methods: {},
  };
</script>
src/views/dmx/model/components/addModel.vue
@@ -1,18 +1,26 @@
<template>
  <a-button type="primary" @click="handleClick" style="margin-left: 10px">
    <template #icon>
      <icon-plus />
    </template>
  </a-button>
  <a-modal v-model:visible="visible" title="添加模式"
           @before-open="handleOpened"
           @cancel="handleCancel"
           :footer="false"
           title-align="start"
           width="600px"
  <a-modal
    v-model:visible="visible"
    title="添加模式"
    @before-open="handleOpened"
    @cancel="handleCancel"
    :footer="false"
    title-align="start"
    width="600px"
  >
    <a-form ref="formRef" :rules="rules" :model="form" @submit="handleSubmit" :style="{width:'90%',margin:'0 auto'}" layout="vertical" >
    <a-form
      ref="formRef"
      :rules="rules"
      :model="form"
      @submit="handleSubmit"
      :style="{ width: '90%', margin: '0 auto' }"
      layout="vertical"
    >
      <a-form-item field="name" label="模型类型">
        <a-select v-model="form.section" placeholder="请选择">
          <a-option value="section one">Section One</a-option>
@@ -21,7 +29,7 @@
        </a-select>
      </a-form-item>
      <a-form-item field="name" label="模型名称">
        <a-input v-model="form.name" placeholder="请输入名称"/>
        <a-input v-model="form.name" placeholder="请输入名称" />
      </a-form-item>
      <a-form-item field="section" label="模型图片">
        <a-space direction="vertical" :style="{ width: '100%' }">
@@ -35,8 +43,10 @@
            <template #upload-button>
              <div
                :class="`arco-upload-list-item${
            file && file.status === 'error' ? ' arco-upload-list-item-error' : ''
          }`"
                  file && file.status === 'error'
                    ? ' arco-upload-list-item-error'
                    : ''
                }`"
              >
                <div
                  class="arco-upload-list-picture custom-upload-avatar"
@@ -52,11 +62,11 @@
                    type="circle"
                    size="mini"
                    :style="{
                position: 'absolute',
                left: '50%',
                top: '50%',
                transform: 'translateX(-50%) translateY(-50%)',
              }"
                      position: 'absolute',
                      left: '50%',
                      top: '50%',
                      transform: 'translateX(-50%) translateY(-50%)',
                    }"
                  />
                </div>
                <div class="arco-upload-picture-card" v-else>
@@ -71,16 +81,18 @@
        </a-space>
      </a-form-item>
      <a-form-item field="name" label="基础Url">
        <a-input v-model="form.name" placeholder="请输入名称"/>
        <a-input v-model="form.name" placeholder="请输入名称" />
      </a-form-item>
      <a-form-item field="raptor" label="是否支持 Vision">
        <a-switch v-model="form.raptor" />
      </a-form-item>
      <a-form-item>
        <div style="width: 100%;text-align: right">
        <div style="width: 100%; text-align: right">
          <a-button @click="visible = false">取消</a-button>
          <a-button style="margin-left: 10px" type="primary" html-type="submit">确定</a-button>
          <a-button style="margin-left: 10px" type="primary" html-type="submit"
            >确定</a-button
          >
        </div>
      </a-form-item>
    </a-form>
@@ -88,100 +100,92 @@
</template>
<script lang="ts" setup>
import { onMounted ,onBeforeMount, reactive, ref } from "vue";
  import { onMounted, onBeforeMount, reactive, ref } from 'vue';
const visible = ref(false);
const loading = ref(false);
const form = reactive({
  size: "medium",
  name: "",
  age: undefined,
  section: "0",
  province: "haidian",
  options: [],
  date: "",
  time: "",
  radio: "radio one",
  slider: 5,
  score: 5,
  switch: false,
  multiSelect: ["section one"],
  treeSelect: "",
  raptor: false,
  prompt: '请总结以下段落。 小心数字,不要编造。 段落如下:\n' +
    '      {cluster_content}\n' +
    '以上就是你需要总结的内容。',
});
const formRef = ref(null);
const rules = {
  name: [
    {
      required: true,
      message:'名称不允许为空',
    },
  ],
}
const handleSubmit = ({values, errors}) => {
  console.log('values:', values, '\nerrors:', errors)
}
const handleClick = () => {
  visible.value = true;
};
const handleBeforeOk = (done) => {
    formRef.value.validate().then(res => {
      console.log('form:', form)
      if (!form.name) {
        done(false)
      }else {
        console.log('请求数据');
      }
    })
};
const handleCancel = () => {
  visible.value = false;
}
const handleOpened =(el) => {
  Object.assign(form,{
    name: '',// 用户名
    nameJoin: '',// 昵称
    post: '',// 岗位
    txt: '',// 备注
  const visible = ref(false);
  const loading = ref(false);
  const form = reactive({
    size: 'medium',
    name: '',
    age: undefined,
    section: '0',
    province: 'haidian',
    options: [],
    date: '',
    time: '',
    radio: 'radio one',
    slider: 5,
    score: 5,
    switch: false,
    multiSelect: ['section one'],
    treeSelect: '',
    raptor: false,
    prompt:
      '请总结以下段落。 小心数字,不要编造。 段落如下:\n' +
      '      {cluster_content}\n' +
      '以上就是你需要总结的内容。',
  });
  formRef.value.resetFields();
}
  const formRef = ref(null);
const file = ref();
const onChange = (_, currentFile) => {
  file.value = {
    ...currentFile,
    // url: URL.createObjectURL(currentFile.file),
  const rules = {
    name: [
      {
        required: true,
        message: '名称不允许为空',
      },
    ],
  };
};
const onProgress = (currentFile) => {
  file.value = currentFile;
};
onBeforeMount(()=>{
  const handleSubmit = ({ values, errors }) => {
    console.log('values:', values, '\nerrors:', errors);
  };
})
onMounted(()=>{
  const handleClick = () => {
    visible.value = true;
  };
  const handleBeforeOk = (done) => {
    formRef.value.validate().then((res) => {
      console.log('form:', form);
      if (!form.name) {
        done(false);
      } else {
        console.log('请求数据');
      }
    });
  };
  const handleCancel = () => {
    visible.value = false;
  };
  const handleOpened = (el) => {
    Object.assign(form, {
      name: '', // 用户名
      nameJoin: '', // 昵称
      post: '', // 岗位
      txt: '', // 备注
    });
    formRef.value.resetFields();
  };
})
  const file = ref();
  const onChange = (_, currentFile) => {
    file.value = {
      ...currentFile,
      // url: URL.createObjectURL(currentFile.file),
    };
  };
  const onProgress = (currentFile) => {
    file.value = currentFile;
  };
  onBeforeMount(() => {});
  onMounted(() => {});
</script>
<script lang="ts">
export default {
  name: 'add',
  methods: {
  }
};
</script>
  export default {
    name: 'add',
    methods: {},
  };
</script>
src/views/dmx/model/components/addPageModel.vue
New file
@@ -0,0 +1,351 @@
<template>
  <!-- 添加编辑子模型 -->
  <a-modal
    v-model:visible="addPageModelVisible"
    :title="title"
    @before-open="handleOpened"
    @cancel="handleCancel"
    :footer="false"
    title-align="start"
    width="600px"
  >
    <a-form
      ref="form_ref"
      :rules="rules"
      :model="form"
      @submit="handleSubmit"
      :style="{ width: '90%', margin: '0 auto' }"
      layout="vertical"
    >
      <div v-if="isType !== 1">
        <a-form-item field="model_type" label="模型类型">
          <a-select v-model="form.model_type" placeholder="请选择">
            <a-option value="chat">chat</a-option>
            <a-option value="embedding">embedding</a-option>
          </a-select>
        </a-form-item>
        <a-form-item field="llm_name" label="模型名称">
          <a-input v-model="form.llm_name" placeholder="请输入模型名称" />
        </a-form-item>
        <!-- <a-form-item field="volc_ak" label="火山 ACCESS_KEY">
          <a-input v-model="form.volc_ak" placeholder="请输入火山 ACCESS_KEY" />
          <a-button
            type="primary"
            @click="handleClick"
            style="margin-left: 10px"
          >
            <template #icon>
              <icon-plus />
            </template>
          </a-button>
        </a-form-item>
        <a-form-item field="volc_sk" label="火山 SECRET_KEY">
          <a-input v-model="form.volc_sk" placeholder="请输入火山 SECRET_KEY" />
        </a-form-item> -->
        <a-form-item field="api_base" label="基础URL">
          <a-input v-model="form.api_base" placeholder="请输入基础URL" />
        </a-form-item>
        <a-form-item
          field="raptor"
          label="是否支持 Vision"
          v-if="form.model_type === 'chat'"
        >
          <a-switch v-model="form.raptor" />
        </a-form-item>
        <a-form-item field="logo" label="模型图片">
          <a-space direction="vertical" :style="{ width: '100%' }">
            <Upload
              :action="uploadAction"
              :limit="1"
              @update:fileList="updateFileList"
              @success="handleSuccess"
            ></Upload>
          </a-space>
        </a-form-item>
        <a-form-item field="all_params" label="增加其它参数配置">
          <a-button
            type="primary"
            @click="handleAddClick"
            style="margin-left: 10px"
          >
            <template #icon>
              <icon-plus />
            </template>
          </a-button>
        </a-form-item>
        <a-form-item v-for="(item, index) in form.addFomList" :key="index">
          <div class="addInput">
            <a-input
              style="width: 230px"
              v-model="item.name"
              placeholder="请输入key"
            />
            :
            <a-input v-model="item.value" placeholder="请输入value" />
            <a-button
              status="danger"
              @click="handleDelInput(index)"
              style="margin-left: 10px"
            >
              <template #icon>
                <icon-minus size="22" />
              </template>
            </a-button>
          </div>
        </a-form-item>
      </div>
      <div v-else>
        <a-form-item field="name" label="API-Key">
          <a-input v-model="form.name" placeholder="API-Key" />
        </a-form-item>
        <a-form-item field="describe" label="Base-Url">
          <a-input v-model="form.name" placeholder="Base-Url" />
        </a-form-item>
        <a-form-item field="section" label="模型图片">
          <a-space direction="vertical" :style="{ width: '100%' }">
            <Upload
              :action="uploadAction"
              :limit="1"
              @update:fileList="updateFileList"
              @success="handleSuccess"
            ></Upload>
          </a-space>
        </a-form-item>
      </div>
      <a-form-item>
        <div style="width: 100%; text-align: right">
          <a-button @click="addPageModelVisible = false">取消</a-button>
          <a-button style="margin-left: 10px" type="primary" html-type="submit"
            >确定</a-button
          >
        </div>
      </a-form-item>
    </a-form>
  </a-modal>
</template>
<script lang="ts" setup>
  import { reactive, ref, computed, watch } from 'vue';
  import { addLlm, getLlmDetail } from '@/api/model';
  import { Modal, Message } from '@arco-design/web-vue';
  import message from '@arco-design/web-vue/es/message';
  import { resolveUnref } from '@vueuse/core';
  const addPageModelVisible = defineModel('show');
  const loading = ref(false);
  const props = defineProps({
    task_id: {
      type: Number,
      default: null,
    },
    type: {
      type: Number,
      default: 0,
    },
    title: {
      type: String,
      default: '',
    },
    editList: {
      type: Object,
      default: {},
    },
  });
  const isType = computed(() => props.type);
  const editList = computed(() => props.editList);
  watch(
    () => editList.value.name,
    (newValue) => {
      getDetail();
    }
  );
  const form = reactive({
    size: 'medium',
    name: '',
    llm_factory: '',
    model_type: '',
    province: 'haidian',
    options: [],
    llm_name: '',
    api_base: '',
    volc_ak: '',
    volc_sk: '',
    logo: '',
    radio: 'radio one',
    slider: 5,
    score: 5,
    switch: false,
    multiSelect: ['section one'],
    treeSelect: '',
    raptor: false,
    addFomList: [],
  });
  const form_ref = ref(null);
  const rules = {
    model_type: [
      {
        required: true,
        message: '请选择模型类型',
      },
    ],
    llm_name: [
      {
        required: true,
        message: '名称不允许为空',
      },
    ],
    volc_sk: [
      {
        required: true,
        message: '请输入volc_sk',
      },
    ],
    volc_ak: [
      {
        required: true,
        message: '请输入volc_ak',
      },
    ],
    api_base: [
      {
        required: true,
        message: '请输入api_base',
      },
    ],
  };
  const uploadAction = '/api/v1/llm/upload'; // 替换为你的上传API
  const fileList = ref([]);
  const imageUrls = ref([]);
  const updateFileList = (newFileList) => {
    fileList.value = newFileList;
    console.log(newFileList, 88);
  };
  const handleSuccess = (urls) => {
    imageUrls.value = urls; // 拿到上传的图片地址
  };
  const emit = defineEmits(['refresh-parent']);
  const handleSubmit = ({ values, errors }) => {
    const all_params = form.addFomList.map((item) => {
      console.log(item, 8888);
      return item.name + ':' + item.value;
    });
    form_ref.value
      ?.validate()
      .then(async (res) => {
        if (!res) {
          const data = await addLlm({
            llm_factory: editList.value.llm_factory,
            llm_name: form.llm_name,
            model_type: form.model_type,
            volc_ak: form.volc_ak,
            volc_sk: form.volc_sk,
            api_base: form.api_base,
            raptor: form.raptor,
            all_params: all_params,
            logo: imageUrls.value[0],
          });
          if ((data as any).retmsg == 'success') {
            message.success('添加成功');
            emit('refresh-parent');
          } else {
            message.error('添加失败');
          }
        }
      })
      .catch((err) => {
        console.log(err);
      });
  };
  //   const addPageModelVisible = ref(false);
  const handleAddPageModel = () => {
    addPageModelVisible.value = true;
  };
  const handleClick = () => {
    addPageModelVisible.value = true;
  };
  const handleBeforeOk = (done) => {
    form_ref.value?.validate().then((res) => {
      console.log('form:', form);
      if (!form.name) {
        done(false);
      } else {
        console.log('请求数据');
      }
    });
  };
  //增加其他参数
  const handleAddClick = () => {
    form.addFomList.push({ name: '', value: '' });
  };
  //减少其他参数
  const handleDelInput = (index) => {
    form.addFomList.splice(index, 1);
  };
  const handleCancel = () => {
    addPageModelVisible.value = false;
  };
  const handleOpened = (el) => {
    Object.assign(form, {
      name: '', // 用户名
      nameJoin: '', // 昵称
      post: '', // 岗位
      txt: '', // 备注
    });
    form_ref.value?.resetFields();
  };
  const file = ref();
  const onChange = (_, currentFile) => {
    file.value = {
      ...currentFile,
      // url: URL.createObjectURL(currentFile.file),
    };
  };
  const onProgress = (currentFile) => {
    file.value = currentFile;
  };
  //获取详情
  const getDetail = async () => {
    const data = await getLlmDetail(
      editList.value.llm_factory,
      editList.value.name
    );
    console.log(data.data, 8888);
    form.llm_name = data.data.llm_name;
    form.model_type = data.data.model_type;
    form.volc_ak = data.data.volc_ak;
    form.volc_sk = data.data.volc_sk;
    form.api_base = data.data.api_base;
    form.raptor = data.data.raptor;
    form.addFomList = data.data.all_params.map((item) => {
      return { name: item.split(':')[0], value: item.split(':')[1] };
    });
    imageUrls.value = data.data.logo;
  };
</script>
<style scoped lang="less">
  .addInput {
    display: flex;
    width: 100%;
  }
</style>
src/views/dmx/model/components/addTableName.vue
New file
@@ -0,0 +1,164 @@
<template>
  <!-- 添加模型 -->
  <a-modal
    v-model:visible="addTabVisible"
    title="添加模式"
    @before-open="handleOpened"
    @cancel="handleCancel"
    :footer="false"
    title-align="start"
    width="600px"
  >
    <a-form
      ref="formRef"
      :rules="rules"
      :model="form"
      @submit="handleSubmit"
      :style="{ width: '90%', margin: '0 auto' }"
      layout="vertical"
    >
      <a-form-item field="name" label="模型名称">
        <a-input v-model="form.name" placeholder="请输入模型名称" />
      </a-form-item>
      <a-form-item field="apiKey" label="API-Key">
        <a-input v-model="form.apiKey" placeholder="API-Key" />
      </a-form-item>
      <a-form-item field="baseUrl" label="Base-Url">
        <a-input v-model="form.baseUrl" placeholder="Base-Url" />
      </a-form-item>
      <a-form-item field="tags" label="模型描述">
        <a-textarea
          v-model="form.tags"
          placeholder="请输入模型描述"
          allow-clear
        />
      </a-form-item>
      <a-form-item field="section" label="模型图片">
        <a-space direction="vertical" :style="{ width: '100%' }">
          <Upload
            :action="uploadAction"
            :limit="1"
            @update:fileList="updateFileList"
            @success="handleSuccess"
          ></Upload>
        </a-space>
      </a-form-item>
      <a-form-item>
        <div style="width: 100%; text-align: right">
          <a-button @click="addTabVisible = false">取消</a-button>
          <a-button style="margin-left: 10px" type="primary" html-type="submit"
            >确定</a-button
          >
        </div>
      </a-form-item>
    </a-form>
  </a-modal>
</template>
<script lang="ts" setup>
  import { onMounted, onBeforeMount, reactive, ref, computed } from 'vue';
  import { addLlmFactory } from '@/api/model';
  import { Message } from '@arco-design/web-vue';
  const addTabVisible = defineModel('tabShow');
  const loading = ref(false);
  const props = defineProps({
    task_id: {
      type: Number,
      default: null,
    },
    nameList: {
      type: Object,
      default: {},
    },
  });
  const editList = computed(() => props.nameList);
  const form = reactive({
    size: 'medium',
    name: '',
    describe: '',
    api_base: '',
    tags: '',
    logo: '',
  });
  const formRef = ref(null);
  const rules = {
    name: [
      {
        required: true,
        message: '名称不允许为空',
      },
    ],
    describe: [
      {
        required: true,
        message: '描述不允许为空',
      },
    ],
  };
  const handleSubmit = ({ values, errors }) => {
    console.log(editList, 9999);
    formRef.value.validate().then(async (res) => {
      if (!res) {
        await addLlmFactory({
          name: form.name,
          tags: form.tags,
          api_base: form.api_base,
          // all_params: all_params,
          logo: imageUrls.value[0],
        })
          .then((resData) => {
            if ((resData as any).code === 200) {
              emit('refresh-parent');
              addTabVisible.value = false;
              Message.success('添加成功');
            }
          })
          .catch(() => {
            Message.error('添加失败');
          });
      }
    });
  };
  const emit = defineEmits(['refresh-parent']);
  const handleClick = () => {
    addTabVisible.value = true;
  };
  const handleCancel = () => {
    addTabVisible.value = false;
  };
  //图片上传
  const uploadAction = '/api/v1/llm/upload'; // 替换为你的上传API
  const fileList = ref([]);
  const imageUrls = ref([]);
  const updateFileList = (newFileList) => {
    fileList.value = newFileList;
  };
  const handleSuccess = (urls) => {
    imageUrls.value = urls; // 拿到上传的图片地址
    console.log(urls, 77777);
  };
  const handleOpened = (el) => {
    Object.assign(form, {
      name: '', // 用户名
      nameJoin: '', // 昵称
      post: '', // 岗位
      txt: '', // 备注
    });
    formRef.value?.resetFields();
  };
</script>
<script lang="ts">
  export default {
    name: 'add',
    methods: {},
  };
</script>
src/views/dmx/model/index.vue
@@ -1,126 +1,291 @@
<template>
  <div class="container">
    <Breadcrumb :items="['大模型', '大模型管理']" />
    <a-row :gutter="20" align="stretch">
      <a-col :span="24">
        <a-card class="general-card" :title="$t('大模型管理')">
        <a-card
          class="general-card"
          style="min-height: 130px"
          :title="$t('大模型管理')"
        >
          <a-row justify="space-between">
            <a-col :span="24">
            <a-col :span="24" class="table_add_clore" v-if="loading">
              <a-tabs
                :active-key="activeKey"
                :default-active-key="tabKey"
                type="line"
                :editable="true"
                @tab-click="changeTabs"
                @add="handleAdd"
                @delete="handleDelete"
                show-add-button
                auto-switch
              >
                <a-tab-pane
                  v-for="(item, index) of data"
                  :key="item.key"
                  :title="item.title"
                  :closable="index >= 4"
                  v-for="(item, index) in tabData"
                  :key="index"
                  :title="index"
                  :closable="Object.keys(tabData).length >= 4"
                >
                  <div style="display: flex; flex-wrap: wrap;justify-content: space-between;">
                    <div class="card-wrap"    v-for="(item, index) of data" :key="index">
                      <a-card :bordered="false" hoverable >
                        <template #cover>
                          <div
                          >
                            <img
                              :style="{ width: '100%', transform: 'translateY(-20px)' }"
                              alt="dessert"
                              src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a20012a2d4d5b9db43dfc6a01fe508c0.png~tplv-uwbnlip3yd-webp.webp"
                            />
                          </div>
                        </template>
                        <div class="arco-card-body-content">
                          <div class="arco-card-body-content-title">
                            {{ item.title }}
                          </div>
                  <div
                    style="display: flex; flex-wrap: wrap"
                    class="card_content"
                  >
                    <div class="card-wrap">
                      <div class="card_wrap_box">
                        <div class="card_wrap_box_img">
                          <img
                            :style="{
                              width: '100%',
                            }"
                            alt="dessert"
                            :src="item.logo"
                          />
                        </div>
                        <div style="position: absolute; bottom: 1rem; right: 1rem;">
                          <a-space>
                            <a-button>
                              删除
                            </a-button>
                            <editModel></editModel>
                          </a-space>
                        <a-card :bordered="false" hoverable>
                          <div class="arco-card-body-content">
                            <div
                              class="arco-card-body-content-title"
                              style="word-wrap: break-word"
                            >
                              {{ item.tags }}
                            </div>
                            <!-- <div class="arco-card-body-content-dec">{{
                            list.type
                          }}</div> -->
                          </div>
                          <div class="arco-btn-group">
                            <a-space class="btn-group">
                              <!-- <editModel></editModel> -->
                              <a-button type="primary" @click="handleEditModel">
                                编辑
                              </a-button>
                            </a-space>
                          </div>
                        </a-card>
                      </div>
                    </div>
                    <div
                      class="card-wrap"
                      v-for="(list, index) of item.llm"
                      :key="index"
                    >
                      <div class="card_wrap_box">
                        <div>
                          <img
                            :style="{
                              width: '100%',
                              transform: 'translateY(-20px)',
                            }"
                            alt="dessert"
                            :src="list.logo"
                          />
                          <!--   src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a20012a2d4d5b9db43dfc6a01fe508c0.png~tplv-uwbnlip3yd-webp.webp" -->
                        </div>
                      </a-card>
                        <a-card :bordered="false" hoverable>
                          <div class="arco-card-body-content">
                            <div class="arco-card-body-content-title">
                              {{ list.name }}
                            </div>
                            <div class="arco-card-body-content-dec">{{
                              list.type
                            }}</div>
                          </div>
                          <div class="arco-btn-group">
                            <a-space class="btn-group">
                              <a-button @click="handleDeleteModel(list)">
                                删除
                              </a-button>
                              <a-button
                                type="primary"
                                @click="handleEditModel(list)"
                              >
                                编辑
                              </a-button>
                              <!-- <editModel></editModel> -->
                            </a-space>
                          </div>
                        </a-card>
                      </div>
                    </div>
                  </div>
                </a-tab-pane>
              </a-tabs>
            </a-col>
            <div> </div>
            <a-input-search
              :placeholder="$t('cardList.searchInput.placeholder')"
              style="width: 240px; position: absolute; top: 60px; right: 60px"
            />
            <div style="position: absolute; top: 60px; right: 20px">
              <addModel></addModel>
            <div class="box_right">
              <div class="search_input">
                <a-input-search
                  :placeholder="$t('cardList.searchInput.placeholder')"
                  style="width: 240px"
                />
              </div>
              <div>
                <!-- <addModel></addModel> -->
                <a-button
                  type="primary"
                  :loading="loading2"
                  @click="handleAddModel"
                >
                  <template #icon>
                    <icon-plus />
                  </template>
                  添加
                </a-button>
              </div>
            </div>
          </a-row>
        </a-card>
      </a-col>
    </a-row>
  </div>
  <!-- 添加模型 -->
  <addPageModel
    v-model:show="show"
    :task_id="task_id"
    :type="modelType"
    :title="title"
    :editList="editList"
    @refresh-parent="refreshParentMethod"
    v-if="show"
  ></addPageModel>
  <!-- 添加tab模式 -->
  <addTableName
    v-model:tabShow="tabShow"
    :nameList="editList"
    @refresh-parent="refreshParentMethod"
    v-if="tabShow"
  ></addTableName>
</template>
<script lang="ts" setup>
  import { ref, reactive, nextTick } from 'vue';
  import QualityInspection from './components/quality-inspection.vue';
  import TheService from './components/the-service.vue';
  import RulesPreset from './components/rules-preset.vue';
  import CustomSettings from './components/custom-settings.vue';
  import addModel from "@/views/dmx/model/components/addModel.vue";
  import editModel from "@/views/dmx/model/components/editModel.vue";
  import addModel from '@/views/dmx/model/components/addModel.vue';
  import editModel from '@/views/dmx/model/components/editModel.vue';
  import addPageModel from './components/addPageModel.vue';
  import addTableName from './components/addTableName.vue';
  import {
    modelList,
    modelmyLlms,
    deleteLlm,
    deleteLlmFactory,
  } from '@/api/model';
  import { Modal, Message } from '@arco-design/web-vue';
  let count = 5;
  const activeKey = ref(1);
  const data = ref([
    {
      key: 1,
      title: '全部',
      title: 'key',
      content: 'Content of Tab Panel 1',
    },
    {
      key: 2,
      title: '内容质检',
      title: 'Ollama',
      content: 'Content of Tab Panel 2',
    },
    {
      key: 3,
      title: '开通服务',
      title: 'Xinference',
      content: 'Content of Tab Panel 3',
    },
    {
      key: 4,
      title: '规则预置',
      content: 'Content of Tab Panel 4',
    },
  ]);
const changeTabs = (val) => {
  activeKey.value = val;
}
  const handleAdd = () => {
    visible.value = true;
  const tabData = ref({
    key: {
      tags: '添加key',
      id: 1,
    },
  });
  const isDeleteDialogVisible = ref(false); //删除提醒
  const apiUrl = ref('http://127.0.0.1:5173');
  // const httpUrl = import.meta.env.VITE_API_BASE_URL;
  // console.log(apiUrl.value, 777);
  const modalList = ref({});
  const tabKey = ref('key');
  const changeTabs = (val) => {
    tabKey.value = val;
  };
  const handleDelete = (key: any) => {
    data.value = data.value.filter((item) => item.key !== key);
  const show = ref(false);
  const tabShow = ref(false);
  const title = ref('添加模式');
  const task_id = ref(1);
  const modelType = ref(1);
  const handleAdd = () => {
    tabShow.value = true;
    editList.value.llm_factory = tabKey.value;
  };
  const editList = ref({ llm_factory: '' });
  //增加模型子类
  const handleAddModel = () => {
    if (tabKey.value == 'key') {
      tabShow.value = true;
    } else {
      modelType.value = 2;
      editList.value.llm_factory = tabKey.value;
      show.value = true;
      title.value = '添加模式';
    }
  };
  //编辑模型子类
  const handleEditModel = (val) => {
    if (tabKey.value == 'key') {
      tabShow.value = true;
    } else {
      modelType.value = 2;
      task_id.value = val.id;
      show.value = true;
      title.value = '编辑';
      editList.value = val;
      editList.value.llm_factory = tabKey.value;
    }
  };
  //删除模型
  const handleDeleteModel = (val) => {
    Modal.confirm({
      title: '警告',
      content: '确认删除吗',
      okText: '确定',
      cancelText: '取消',
      onOk: async () => {
        const factory = tabKey.value;
        const res = await deleteLlm({
          llm_factory: tabKey.value,
          llm_name: val.name,
        });
        if ((res as any).code == 0) {
          queryModel();
          tabKey.value = factory;
        } else {
        }
      },
      onCancel: () => {},
    });
  };
  //父级模型
  const handleDelete = async (key: any) => {
    console.log(key, 45455);
    // tabData.value = tabData.value.filter((item) => item.key !== key);
    Reflect.deleteProperty(tabData.value, key);
    await deleteLlmFactory(key);
    queryModel();
  };
  const visible = ref(false);
  const formRef = ref(null);
  const form = reactive({
    size: 'medium',
    name: '',
  });
  const handleOk = () => {
    count += 1;
    formRef.value.validate().then((res) => {
    formRef.value?.validate().then((res) => {
      if (res) {
        return;
      }
@@ -134,19 +299,33 @@
    });
    nextTick(() => {
      visible.value = true;
    })
    });
    return false;
  };
  const handleCancel = () => {
    formRef.value.resetFields();
    visible.value = false;
  // const handleCancel = () => {
  //   formRef.value.resetFields();
  //   visible.value = false;
  // };
  // const handleSubmit = ({ values, errors }) => {
  //   this.$refs.formRef.validate().then((res, a, b) => {
  //     debugger;
  //     console.log('values', values);
  //   });
  // };
  //获取模型列表
  const loading = ref(false);
  const queryModel = async () => {
    const res = await modelmyLlms();
    modalList.value = res.data;
    loading.value = true;
    tabData.value = Object.assign({}, tabData.value, res.data);
  };
  const handleSubmit = ({ values, errors }) => {
    this.$refs.formRef.validate().then((res, a, b) => {
      debugger;
      console.log('values', values);
    });
  queryModel();
  const refreshParentMethod = () => {
    queryModel();
    // 这里执行需要的操作
  };
</script>
@@ -199,6 +378,93 @@
      }
    }
  }
  .table_add_clore {
    :deep(.arco-tabs-nav-add-btn .arco-icon-hover::before) {
      top: 50%;
      left: 50%;
      width: 20px;
      height: 20px;
      transform: translate(-50%, -50%);
      border-radius: 0;
      background-color: #165dff;
    }
    :deep(.arco-tabs-nav-add-btn .arco-icon-hover .arco-icon) {
      color: #fff;
    }
    :deep(.arco-tabs-nav) {
      max-width: 60%;
    }
    :deep(.arco-icon-hover::before) {
      top: 50%;
      left: 50%;
      width: 20px;
      height: 20px;
      transform: translate(-50%, -50%);
      // border-radius: 0;
      // background-color: #eee;
    }
    :deep(.arco-tabs-tab-close-btn .arco-icon) {
      color: #666;
    }
  }
  .box_right {
    position: absolute;
    top: 60px;
    right: 20px;
    display: flex;
    .search_input {
      margin-right: 10px;
    }
  }
  .arco-card-body-content {
    .arco-card-body-content-title {
      font-size: 16px;
      color: #333;
      margin-bottom: 10px;
      font-weight: 400;
    }
  }
  .card_content {
    position: relative;
    .arco-btn-group {
      position: absolute;
      right: 10px;
      top: 100px;
    }
    .card_wrap_box_img {
      min-height: 200px;
      max-height: 240px;
    }
  }
  .card-wrap {
    width: 320px;
    height: 350px;
    margin: 30px;
    transition: all 0.3s;
    border: 1px solid var(--color-neutral-3);
    border-radius: 4px;
    position: relative;
    &:hover {
      transform: translateY(-4px);
      // box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.1);
    }
  }
  .card-wrap {
    width: 320px;
    height: 350px;
    margin: 30px;
    transition: all 0.3s;
    border: 1px solid var(--color-neutral-3);
    border-radius: 4px;
    position: relative;
    &:hover {
      transform: translateY(-4px);
      // box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.1);
    }
  }
  .card-wrap {
    width: 320px;
    height: 350px;