| | |
| | | }, |
| | | "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" |
| | | ] |
| | | }, |
New file |
| | |
| | | <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> |
New file |
| | |
| | | <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> |
| | |
| | | |
| | | <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> |
| | |
| | | </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%' }"> |
| | |
| | | <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" |
| | |
| | | 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> |
| | |
| | | </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> |
| | |
| | | </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> |
New file |
| | |
| | | <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> |
New file |
| | |
| | | <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> |
| | |
| | | <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; |
| | | } |
| | |
| | | }); |
| | | 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> |
| | | |
| | |
| | | } |
| | | } |
| | | } |
| | | .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; |