From 7cc74731d2426123d5e4caa313c53d67a51550bc Mon Sep 17 00:00:00 2001 From: liudong <liudong> Date: 星期五, 02 八月 2024 17:34:25 +0800 Subject: [PATCH] 智能体管理的页面开发和功能开发 --- src/views/dmx/IntelligentAgent/components/custom-settings.vue | 244 +++++++++ src/views/dmx/IntelligentAgent/index.vue | 287 +++++++++++ src/views/dmx/IntelligentAgent/mock.ts | 186 +++++++ src/views/dmx/IntelligentAgent/components/rules-preset.vue | 51 ++ src/views/dmx/IntelligentAgent/locale/zh-CN.ts | 20 src/views/dmx/IntelligentAgent/components/editAgent.vue | 188 +++++++ src/views/dmx/IntelligentAgent/locale/en-US.ts | 20 src/views/dmx/IntelligentAgent/components/addAgent.vue | 102 ++++ src/router/routes/modules/dmx.ts | 10 src/views/dmx/IntelligentAgent/components/card-wrap.vue | 204 ++++++++ src/views/dmx/IntelligentAgent/components/quality-inspection.vue | 115 ++++ src/views/dmx/IntelligentAgent/components/the-service.vue | 57 ++ 12 files changed, 1,484 insertions(+), 0 deletions(-) diff --git a/src/router/routes/modules/dmx.ts b/src/router/routes/modules/dmx.ts index bd3ec29..ffdf5ae 100644 --- a/src/router/routes/modules/dmx.ts +++ b/src/router/routes/modules/dmx.ts @@ -32,6 +32,16 @@ roles: ['*'], }, }, + { + path: 'intelligentAgent', + name: 'IntelligentAgent', + component: () => import('@/views/dmx/IntelligentAgent/index.vue'), + meta: { + locale: '鏅鸿兘浣撶鐞�', + requiresAuth: true, + roles: ['*'], + }, + }, ], }; diff --git a/src/views/dmx/IntelligentAgent/components/addAgent.vue b/src/views/dmx/IntelligentAgent/components/addAgent.vue new file mode 100644 index 0000000..178d923 --- /dev/null +++ b/src/views/dmx/IntelligentAgent/components/addAgent.vue @@ -0,0 +1,102 @@ + +<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-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> + <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> + </div> + </a-form-item> + </a-form> + </a-modal> +</template> + +<script lang="ts" setup> +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; +}; +defineExpose({ + handleClick +}) + +const handleCancel = () => { + visible.value = false; +} + +const handleOpened =(el) => { + Object.assign(form,{ + name: '',// 鐢ㄦ埛鍚� + nameJoin: '',// 鏄电О + post: '',// 宀椾綅 + txt: '',// 澶囨敞 + }); + formRef.value.resetFields(); +} + +const file = ref(); + +onBeforeMount(()=>{ + +}) +onMounted(()=>{ + + +}) +</script> \ No newline at end of file diff --git a/src/views/dmx/IntelligentAgent/components/card-wrap.vue b/src/views/dmx/IntelligentAgent/components/card-wrap.vue new file mode 100644 index 0000000..9b876d8 --- /dev/null +++ b/src/views/dmx/IntelligentAgent/components/card-wrap.vue @@ -0,0 +1,204 @@ +<template> + <div class="card-wrap"> + <a-card v-if="loading" :bordered="false" hoverable> + <slot name="skeleton"></slot> + </a-card> + <a-card v-else :bordered="false" hoverable> + <a-space align="start"> + <a-avatar + v-if="icon" + :size="24" + style="margin-right: 8px; background-color: #626aea" + > + <icon-filter /> + </a-avatar> + <a-card-meta> + <template #title> + <a-typography-text style="margin-right: 10px"> + {{ title }} + </a-typography-text> + <template v-if="showTag"> + <a-tag + v-if="open && isExpires === false" + size="small" + color="green" + > + <template #icon> + <icon-check-circle-fill /> + </template> + <span>{{ tagText }}</span> + </a-tag> + <a-tag v-else-if="isExpires" size="small" color="red"> + <template #icon> + <icon-check-circle-fill /> + </template> + <span>{{ expiresTagText }}</span> + </a-tag> + </template> + </template> + <template #description> + {{ description }} + <slot></slot> + </template> + </a-card-meta> + </a-space> + <template #actions> + <a-switch v-if="actionType === 'switch'" v-model="open" /> + <a-space v-else-if="actionType === 'button'"> + <template v-if="isExpires"> + <a-button type="outline" @click="renew"> + {{ expiresText }} + </a-button> + </template> + <template v-else> + <a-button v-if="open" @click="handleToggle"> + {{ closeTxt }} + </a-button> + <a-button v-else-if="!open" type="outline" @click="handleToggle"> + {{ openTxt }} + </a-button> + </template> + </a-space> + <div v-else> + <a-space> + <a-button @click="toggle(false)"> + {{ closeTxt }} + </a-button> + <a-button type="primary" @click="toggle(true)"> + {{ openTxt }} + </a-button> + </a-space> + </div> + </template> + </a-card> + </div> +</template> + +<script lang="ts" setup> + import { ref } from 'vue'; + import { useToggle } from '@vueuse/core'; + + const props = defineProps({ + loading: { + type: Boolean, + default: false, + }, + title: { + type: String, + default: '', + }, + description: { + type: String, + default: '', + }, + actionType: { + type: String, + default: '', + }, + defaultValue: { + type: Boolean, + default: false, + }, + openTxt: { + type: String, + default: '', + }, + closeTxt: { + type: String, + default: '', + }, + expiresText: { + type: String, + default: '', + }, + icon: { + type: String, + default: '', + }, + showTag: { + type: Boolean, + default: true, + }, + tagText: { + type: String, + default: '', + }, + expires: { + type: Boolean, + default: false, + }, + expiresTagText: { + type: String, + default: '', + }, + }); + const [open, toggle] = useToggle(props.defaultValue); + const handleToggle = () => { + toggle(); + }; + const isExpires = ref(props.expires); + const renew = () => { + isExpires.value = false; + }; +</script> + +<style scoped lang="less"> + .card-wrap { + height: 100%; + transition: all 0.3s; + border: 1px solid var(--color-neutral-3); + border-radius: 4px; + &:hover { + transform: translateY(-4px); + // box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.1); + } + :deep(.arco-card) { + height: 100%; + border-radius: 4px; + .arco-card-body { + height: 100%; + .arco-space { + width: 100%; + height: 100%; + .arco-space-item { + height: 100%; + &:last-child { + flex: 1; + } + .arco-card-meta { + height: 100%; + display: flex; + flex-flow: column; + .arco-card-meta-content { + flex: 1; + .arco-card-meta-description { + margin-top: 8px; + color: rgb(var(--gray-6)); + line-height: 20px; + font-size: 12px; + } + } + .arco-card-meta-footer { + margin-top: 0; + } + } + } + } + } + } + :deep(.arco-card-meta-title) { + display: flex; + align-items: center; + + // To prevent the shaking + line-height: 28px; + } + :deep(.arco-skeleton-line) { + &:last-child { + display: flex; + justify-content: flex-end; + margin-top: 20px; + } + } + } +</style> diff --git a/src/views/dmx/IntelligentAgent/components/custom-settings.vue b/src/views/dmx/IntelligentAgent/components/custom-settings.vue new file mode 100644 index 0000000..666fd89 --- /dev/null +++ b/src/views/dmx/IntelligentAgent/components/custom-settings.vue @@ -0,0 +1,244 @@ +<template> + <div class="list-wrap"> + <a-typography-title class="block-title" :heading="6"> + {{ $t('cardList.tab.title.content') }} + </a-typography-title> + <a-button class='add-button' type="primary" @click="addCard">娣诲姞</a-button> + + <a-row class="list-row" :gutter="24"> + <a-col + :xs="12" + :sm="12" + :md="12" + :lg="6" + :xl="6" + :xxl="6" + class="list-col" + > + <div class="card-wrap empty-wrap"> + <a-card :bordered="false" hoverable > + <a-result :status="null" title="Xinference妯″瀷鏄釜寰堝帀瀹崇殑妯″瀷"> + <template #icon> + <icon-plus style="font-size: 20px" /> + </template> + </a-result> + </a-card> + </div> + </a-col> + <a-col + v-for="item in renderData" + :key="item.id" + class="list-col" + :xs="12" + :sm="12" + :md="12" + :lg="6" + :xl="6" + :xxl="6" + > + <CardWrap + :loading="loading" + :title="item.title" + :description="item.description" + :default-value="item.enable" + :action-type="item.actionType" + :icon="item.icon" + :open-txt="$t('cardList.content.inspection')" + :close-txt="$t('cardList.content.delete')" + :show-tag="false" + > + <a-descriptions + style="margin-top: 16px" + :data="item.data" + layout="inline-horizontal" + :column="2" + /> + <template #skeleton> + <a-skeleton :animation="true"> + <a-skeleton-line + :widths="['50%', '50%', '100%', '40%']" + :rows="4" + /> + <a-skeleton-line :widths="['40%']" :rows="1" /> + </a-skeleton> + </template> + </CardWrap> + </a-col> + </a-row> + + <a-modal v-model:visible="visible" @Ok="handleOk" @cancel="handleCancel"> + <template #title> 娣诲姞LLM </template> + <a-form + ref="formRef" + :size="form.size" + :model="form" + auto-label-width + @submit="handleSubmit" + > + <a-form-item + field="type" + label="妯″瀷绫诲瀷" + :rules="[{ required: true, message: '涓嶈兘涓虹┖' }]" + :validate-trigger="['change', 'input']" + > + <a-select + v-model="form.type" + placeholder="璇烽�夋嫨妯″瀷绫诲瀷" + allow-clear + > + <a-option>chartGpt 4</a-option> + <a-option>chartGpt o</a-option> + <a-option>LLM</a-option> + </a-select> + </a-form-item> + + <a-form-item + field="UID" + label="妯″瀷UID" + :rules="[ + { required: true, message: '涓嶈兘涓虹┖' }, + { minLength: 1, message: '鑷冲皯涓�涓瓧绗�' }, + ]" + :validate-trigger="['change', 'input']" + > + <a-input v-model="form.UID" placeholder="璇疯緭鍏ユā鍨婾ID" /> + </a-form-item> + + <a-form-item + field="Url" + label="鍩虹Url" + :rules="[ + { required: true, message: '涓嶈兘涓虹┖' }, + { minLength: 1, message: '鑷冲皯涓�涓瓧绗�' }, + ]" + :validate-trigger="['change', 'input']" + > + <a-input v-model="form.Url" placeholder="璇疯緭鍏ュ熀纭�Url" /> + </a-form-item> + + <a-form-item + field="vision" + label="鏄惁鏀寔 vision" + :validate-trigger="['change', 'input']" + > + <a-switch v-model="form.vision" /> + </a-form-item> + </a-form> + </a-modal> + </div> +</template> + +<script lang="ts" setup> + import { nextTick, reactive, ref } from 'vue'; + import { queryInspectionList, ServiceRecord } from '@/api/list'; + import useRequest from '@/hooks/request'; + import CardWrap from './card-wrap.vue'; + + const defaultValue: ServiceRecord[] = new Array(3).fill({}); + const { loading, response: renderData } = useRequest<ServiceRecord[]>( + queryInspectionList, + defaultValue + ); + const visible = ref(false); + const addCard = () => { + visible.value = true; + }; + + const formRef = ref(null); + const form = reactive({ + size: 'medium', + type: '', + UID: '', + Url: '', + vision: false, + }); + const handleOk = () => { + formRef.value.validate().then((res) => { + if (res) { + return; + } + renderData.value = renderData.value.concat({ + id: renderData.value.length + 1, + title: form.type, + description: form.Url, + icon: 'icon-setting', + actionType: 'inspection', + enable: true, + data: [ + { + label: '寰呰川妫�鏁�', + value: '120', + }, + { + label: '绉帇鏃堕暱', + value: '60s', + }, + { + label: '寰呮娊妫�鏁�', + value: '0', + }, + ], + }); + visible.value = false; + }); + nextTick(() => { + visible.value = true; + }); + return false; + }; + const handleCancel = () => { + formRef.value.resetFields(); + visible.value = false; + }; +</script> + +<style scoped lang="less"> + .card-wrap { + height: 100%; + transition: all 0.3s; + border: 1px solid var(--color-neutral-3); + &:hover { + transform: translateY(-4px); + } + :deep(.arco-card-meta-description) { + color: rgb(var(--gray-6)); + .arco-descriptions-item-label-inline { + font-weight: normal; + font-size: 12px; + color: rgb(var(--gray-6)); + } + .arco-descriptions-item-value-inline { + color: rgb(var(--gray-8)); + } + } + } + .empty-wrap { + height: 200px; + border-radius: 4px; + :deep(.arco-card) { + height: 100%; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; + .arco-result-title { + color: rgb(var(--gray-6)); + } + } + } + + .list-wrap{ + position: relative; + + ::v-deep .block-title{ + height: 36px; + lin-height: 36px; + } + + .add-button{ + position: absolute; + right: 20px; + top: 0; + } + } +</style> diff --git a/src/views/dmx/IntelligentAgent/components/editAgent.vue b/src/views/dmx/IntelligentAgent/components/editAgent.vue new file mode 100644 index 0000000..d7def9c --- /dev/null +++ b/src/views/dmx/IntelligentAgent/components/editAgent.vue @@ -0,0 +1,188 @@ + +<template> + <a-button type="text" size="small" @click="handleClick"> + <template #icon> + <icon-tool /> + </template> + </a-button> + + <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-item field="name" label="妯″瀷绫诲瀷"> + <a-select v-model="form.section" placeholder="璇烽�夋嫨"> + <a-option value="section one">Section One</a-option> + <a-option value="section two">Section Two</a-option> + <a-option value="section three">Section Three</a-option> + </a-select> + </a-form-item> + <a-form-item field="name" label="妯″瀷鍚嶇О"> + <a-input v-model="form.name" placeholder="璇疯緭鍏ュ悕绉�"/> + </a-form-item> + <a-form-item field="section" label="妯″瀷鍥剧墖"> + <a-space direction="vertical" :style="{ width: '100%' }"> + <a-upload + action="/" + :fileList="file ? [file] : []" + :show-file-list="false" + @change="onChange" + @progress="onProgress" + > + <template #upload-button> + <div + :class="`arco-upload-list-item${ + file && file.status === 'error' ? ' arco-upload-list-item-error' : '' + }`" + > + <div + class="arco-upload-list-picture custom-upload-avatar" + v-if="file && file.url" + > + <img :src="file.url" /> + <div class="arco-upload-list-picture-mask"> + <IconEdit /> + </div> + <a-progress + v-if="file.status === 'uploading' && file.percent < 100" + :percent="file.percent" + type="circle" + size="mini" + :style="{ + position: 'absolute', + left: '50%', + top: '50%', + transform: 'translateX(-50%) translateY(-50%)', + }" + /> + </div> + <div class="arco-upload-picture-card" v-else> + <div class="arco-upload-picture-card-text"> + <IconPlus /> + <div style="margin-top: 10px; font-weight: 600">涓婁紶</div> + </div> + </div> + </div> + </template> + </a-upload> + </a-space> + </a-form-item> + <a-form-item field="name" label="鍩虹Url"> + <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"> + <a-button @click="visible = 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 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: '',// 澶囨敞 + }); + 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> \ No newline at end of file diff --git a/src/views/dmx/IntelligentAgent/components/quality-inspection.vue b/src/views/dmx/IntelligentAgent/components/quality-inspection.vue new file mode 100644 index 0000000..88167b6 --- /dev/null +++ b/src/views/dmx/IntelligentAgent/components/quality-inspection.vue @@ -0,0 +1,115 @@ +<template> + <div class="list-wrap"> + <a-typography-title class="block-title" :heading="6"> + {{ $t('cardList.tab.title.content') }} + </a-typography-title> + <a-row class="list-row" :gutter="24"> + <a-col + :xs="12" + :sm="12" + :md="12" + :lg="6" + :xl="6" + :xxl="6" + class="list-col" + > + <div class="card-wrap empty-wrap"> + <a-card :bordered="false" hoverable> + <a-result :status="null" :title="$t('cardList.content.action')"> + <template #icon> + <icon-plus style="font-size: 20px" /> + </template> + </a-result> + </a-card> + </div> + </a-col> + <a-col + v-for="item in renderData" + :key="item.id" + class="list-col" + :xs="12" + :sm="12" + :md="12" + :lg="6" + :xl="6" + :xxl="6" + > + <CardWrap + :loading="loading" + :title="item.title" + :description="item.description" + :default-value="item.enable" + :action-type="item.actionType" + :icon="item.icon" + :open-txt="$t('cardList.content.inspection')" + :close-txt="$t('cardList.content.delete')" + :show-tag="false" + > + <a-descriptions + style="margin-top: 16px" + :data="item.data" + layout="inline-horizontal" + :column="2" + /> + <template #skeleton> + <a-skeleton :animation="true"> + <a-skeleton-line + :widths="['50%', '50%', '100%', '40%']" + :rows="4" + /> + <a-skeleton-line :widths="['40%']" :rows="1" /> + </a-skeleton> + </template> + </CardWrap> + </a-col> + </a-row> + </div> +</template> + +<script lang="ts" setup> + import { queryInspectionList, ServiceRecord } from '@/api/list'; + import useRequest from '@/hooks/request'; + import CardWrap from './card-wrap.vue'; + + const defaultValue: ServiceRecord[] = new Array(3).fill({}); + const { loading, response: renderData } = useRequest<ServiceRecord[]>( + queryInspectionList, + defaultValue + ); +</script> + +<style scoped lang="less"> + .card-wrap { + height: 100%; + transition: all 0.3s; + border: 1px solid var(--color-neutral-3); + &:hover { + transform: translateY(-4px); + } + :deep(.arco-card-meta-description) { + color: rgb(var(--gray-6)); + .arco-descriptions-item-label-inline { + font-weight: normal; + font-size: 12px; + color: rgb(var(--gray-6)); + } + .arco-descriptions-item-value-inline { + color: rgb(var(--gray-8)); + } + } + } + .empty-wrap { + height: 200px; + border-radius: 4px; + :deep(.arco-card) { + height: 100%; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; + .arco-result-title { + color: rgb(var(--gray-6)); + } + } + } +</style> diff --git a/src/views/dmx/IntelligentAgent/components/rules-preset.vue b/src/views/dmx/IntelligentAgent/components/rules-preset.vue new file mode 100644 index 0000000..e5a2878 --- /dev/null +++ b/src/views/dmx/IntelligentAgent/components/rules-preset.vue @@ -0,0 +1,51 @@ +<template> + <div class="list-wrap"> + <a-typography-title class="block-title" :heading="6"> + {{ $t('cardList.tab.title.preset') }} + </a-typography-title> + <a-row class="list-row" :gutter="24"> + <a-col + v-for="item in renderData" + :key="item.id" + :xs="12" + :sm="12" + :md="12" + :lg="6" + :xl="6" + :xxl="6" + class="list-col" + style="min-height: 140px" + > + <CardWrap + :loading="loading" + :title="item.title" + :description="item.description" + :default-value="item.enable" + :action-type="item.actionType" + :tag-text="$t('cardList.preset.tag')" + > + <template #skeleton> + <a-skeleton :animation="true"> + <a-skeleton-line :widths="['100%', '40%']" :rows="2" /> + <a-skeleton-line :widths="['40%']" :rows="1" /> + </a-skeleton> + </template> + </CardWrap> + </a-col> + </a-row> + </div> +</template> + +<script lang="ts" setup> + import { queryRulesPresetList, ServiceRecord } from '@/api/list'; + import useRequest from '@/hooks/request'; + import CardWrap from './card-wrap.vue'; + + const defaultValue: ServiceRecord[] = new Array(6).fill({}); + const { loading, response: renderData } = useRequest<ServiceRecord[]>( + queryRulesPresetList, + defaultValue + ); +</script> + +<style scoped lang="less"></style> diff --git a/src/views/dmx/IntelligentAgent/components/the-service.vue b/src/views/dmx/IntelligentAgent/components/the-service.vue new file mode 100644 index 0000000..2f4748e --- /dev/null +++ b/src/views/dmx/IntelligentAgent/components/the-service.vue @@ -0,0 +1,57 @@ +<template> + <div class="list-wrap"> + <a-typography-title class="block-title" :heading="6"> + {{ $t('cardList.tab.title.service') }} + </a-typography-title> + <a-row class="list-row" :gutter="24"> + <a-col + v-for="item in renderData" + :key="item.id" + :xs="12" + :sm="12" + :md="12" + :lg="6" + :xl="6" + :xxl="6" + class="list-col" + style="min-height: 162px" + > + <CardWrap + :loading="loading" + :title="item.title" + :description="item.description" + :default-value="item.enable" + :action-type="item.actionType" + :expires="item.expires" + :open-txt="$t('cardList.service.open')" + :close-txt="$t('cardList.service.cancel')" + :expires-text="$t('cardList.service.renew')" + :tag-text="$t('cardList.service.tag')" + :expires-tag-text="$t('cardList.service.expiresTag')" + :icon="item.icon" + > + <template #skeleton> + <a-skeleton :animation="true"> + <a-skeleton-line :widths="['100%', '40%', '100%']" :rows="3" /> + <a-skeleton-line :widths="['40%']" :rows="1" /> + </a-skeleton> + </template> + </CardWrap> + </a-col> + </a-row> + </div> +</template> + +<script lang="ts" setup> + import { queryTheServiceList, ServiceRecord } from '@/api/list'; + import useRequest from '@/hooks/request'; + import CardWrap from './card-wrap.vue'; + + const defaultValue: ServiceRecord[] = new Array(4).fill({}); + const { loading, response: renderData } = useRequest<ServiceRecord[]>( + queryTheServiceList, + defaultValue + ); +</script> + +<style scoped lang="less"></style> diff --git a/src/views/dmx/IntelligentAgent/index.vue b/src/views/dmx/IntelligentAgent/index.vue new file mode 100644 index 0000000..63a184b --- /dev/null +++ b/src/views/dmx/IntelligentAgent/index.vue @@ -0,0 +1,287 @@ +<template> + <div class="container"> + <Breadcrumb :items="['澶фā鍨�', '鏅鸿兘浣撶鐞�']" /> + <a-row :gutter="20" align="stretch"> + <a-col :span="24"> + <a-card class="general-card" :title="$t('鏅鸿兘浣撶鐞�')"> + <div style="display: flex;justify-content: right;"> + <a-input-search + :placeholder="$t('cardList.searchInput.placeholder')" + style="width: 240px;" + /> + </div> + <a-divider style="margin: 10px 0" /> + <a-row justify="space-between"> + <a-col :span="24"> + <div style="display: flex; flex-wrap: wrap;"> + <div class="card-wrap" style="cursor: pointer;" @click="handleAdd"> + <a-card :bordered="false" hoverable > + <div style="margin-top: 30px;text-align: center"> + <a-avatar style="background: #3370ff;"> + <icon-plus /> + </a-avatar> + </div> + <div class="arco-card-body-content"> + <div style="text-align: center;margin-top: 10px"> + 鏂板缓鏅鸿兘浣� + </div> + <div style="text-align:center;margin-top: 10px;font-size: 12px;color: #999999"> + 閫氳繃鎻忚堪瑙掕壊鍜屼换鍔℃潵鍒涘缓浣犵殑鏅鸿兘浣�<br> + 鏅鸿兘浣撳彲浠ヨ皟鐢ㄥ涓伐浣滄祦鍜屽伐鍏� + </div> + </div> + <add-agent ref="addAgents"></add-agent> +<!-- <div style="position: absolute; bottom: 1rem; right: 1rem;">--> +<!-- <a-space>--> +<!-- </a-space>--> +<!-- </div>--> + </a-card> + </div> + <div class="card-wrap" v-for="(item, index) of data" :key="index"> + <a-card :bordered="false" hoverable > + <a-avatar :style="{ backgroundColor: '#3370ff' }"> + <img + :style="{ width: '100%'}" + alt="dessert" + src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a20012a2d4d5b9db43dfc6a01fe508c0.png~tplv-uwbnlip3yd-webp.webp" + /> + </a-avatar> + <a-switch style="position: absolute;top: 10px;right: 10px" size="medium"> + <template #checked> + 涓婄嚎 + </template> + <template #unchecked> + 涓嬬嚎 + </template> + </a-switch> + <div class="arco-card-body-content"> + <div class="arco-card-body-content-top"> + <span style="font-size: 18px;font-weight: 900"> + {{ item.title }} + </span> + </div> + <div class="arco-card-body-content-down"> + 閫氳繃鎻忚堪瑙掕壊鍜屼换鍔℃潵鍒涘缓浣犵殑鏅鸿兘浣� + 鏅鸿兘浣撳彲浠ヨ皟鐢ㄥ涓伐浣滄祦鍜屽伐鍏� + </div> + + </div> + <div style="position: absolute; bottom: 1.4rem; left: 1rem;"> + <icon-user /> <span style="font-size: 12px">鐜嬫旦</span> + </div> + <div style="position: absolute; bottom: 1rem; right: 1rem;"> + <a-space> + <editAgent></editAgent> + <a-popconfirm :content="'纭畾鍒犻櫎鍚�'" type="warning" @ok="deleteItem(record)"> + <a-button type="text" size="small"> + <template #icon> + <icon-delete /> + </template> + </a-button> + </a-popconfirm> + </a-space> + </div> + </a-card> + </div> + </div> + </a-col> + </a-row> + </a-card> + </a-col> + </a-row> + </div> +</template> + +<script lang="ts" setup> + import { ref, reactive, nextTick } from 'vue'; + import addAgent from "@/views/dmx/IntelligentAgent/components/addAgent.vue"; + import editAgent from "@/views/dmx/IntelligentAgent/components/editAgent.vue"; + import { kbdocumentrm } from "@/api/kbList"; + import { Message } from "@arco-design/web-vue"; + + let count = 5; + const activeKey = ref(1); + const addAgents = ref(); + const data = ref([ + { + key: 2, + title: '鍐呭璐ㄦ', + content: 'Content of Tab Panel 2', + }, + { + key: 3, + title: '寮�閫氭湇鍔�', + content: 'Content of Tab Panel 3', + }, + { + key: 4, + title: '瑙勫垯棰勭疆', + content: 'Content of Tab Panel 4', + }, + ]); +const changeTabs = (val) => { + activeKey.value = val; +} + const handleAdd = () => { + addAgents.value.handleClick(); + }; + const handleDelete = (key: any) => { + data.value = data.value.filter((item) => item.key !== key); + }; + + const visible = ref(false); + const formRef = ref(null); + const form = reactive({ + size: 'medium', + name: '', + }); + const deleteItem = async (row)=>{ + console.log(row); + let data = await kbdocumentrm({doc_id: row.id}) + if(data.code == 0){ + Message.success('鍒犻櫎鎴愬姛'); + console.log(kbobj, 'kbobj'); + fetchData({ + kb_id: kbobj.id, + page: 1, + page_size: 20 + }) + } + } + 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); + }); + }; +</script> + +<script lang="ts"> + export default { + name: 'Card', + }; +</script> + +<style scoped lang="less"> + .container { + padding: 0 20px 20px 20px; + :deep(.arco-list-content) { + overflow-x: hidden; + } + + :deep(.arco-card-meta-title) { + font-size: 14px; + } + } + :deep(.arco-list-col) { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-between; + } + + :deep(.arco-list-item) { + width: 33%; + } + + :deep(.block-title) { + margin: 0 0 12px 0; + font-size: 14px; + } + :deep(.list-wrap) { + // min-height: 140px; + .list-row { + align-items: stretch; + .list-col { + margin-bottom: 16px; + } + } + :deep(.arco-space) { + width: 100%; + .arco-space-item { + &:last-child { + flex: 1; + } + } + } + } + .card-wrap { + width: 20%; + height: 200px; + margin: 10px; + 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); + } + :deep(.arco-card) { + height: 100%; + border-radius: 4px; + .arco-card-body { + height: 100%; + .arco-space { + width: 100%; + height: 100%; + .arco-space-item { + height: 100%; + &:last-child { + flex: 1; + } + .arco-card-meta { + height: 100%; + display: flex; + flex-flow: column; + .arco-card-meta-content { + flex: 1; + .arco-card-meta-description { + margin-top: 8px; + color: rgb(var(--gray-6)); + line-height: 20px; + font-size: 12px; + } + } + .arco-card-meta-footer { + margin-top: 0; + } + } + } + } + } + } + :deep(.arco-card-meta-title) { + display: flex; + align-items: center; + + // To prevent the shaking + line-height: 28px; + } + :deep(.arco-skeleton-line) { + &:last-child { + display: flex; + justify-content: flex-end; + margin-top: 20px; + } + } + } + .arco-card-body-content{ + .arco-card-body-content-top{ + margin-top: 10px; + text-align: center; + } + .arco-card-body-content-down{ + text-align:center; + margin-top: 10px; + font-size: 12px; + color: #999999; + width: 100%; + height: 60px; + } + } +</style> diff --git a/src/views/dmx/IntelligentAgent/locale/en-US.ts b/src/views/dmx/IntelligentAgent/locale/en-US.ts new file mode 100644 index 0000000..04cddd0 --- /dev/null +++ b/src/views/dmx/IntelligentAgent/locale/en-US.ts @@ -0,0 +1,20 @@ +export default { + // 'menu.list.cardList': 'Card List', + 'menu.dmx.setting': 'GPT Setting', + 'cardList.tab.title.all': 'All', + 'cardList.tab.title.content': 'Quality Inspection', + 'cardList.tab.title.service': 'The service', + 'cardList.tab.title.preset': 'Rules Preset', + 'cardList.searchInput.placeholder': 'Search', + 'cardList.enable': 'Enable', + 'cardList.disable': 'Disable', + 'cardList.content.delete': 'Delete', + 'cardList.content.inspection': 'Inspection', + 'cardList.content.action': 'Click Create Qc Content queue', + 'cardList.service.open': 'Open', + 'cardList.service.cancel': 'Cancel', + 'cardList.service.renew': 'Contract of service', + 'cardList.service.tag': 'Opened', + 'cardList.service.expiresTag': 'Expired', + 'cardList.preset.tag': 'Enable', +}; diff --git a/src/views/dmx/IntelligentAgent/locale/zh-CN.ts b/src/views/dmx/IntelligentAgent/locale/zh-CN.ts new file mode 100644 index 0000000..49a4478 --- /dev/null +++ b/src/views/dmx/IntelligentAgent/locale/zh-CN.ts @@ -0,0 +1,20 @@ +export default { + // 'menu.list.cardList': '鍗$墖鍒楄〃', + 'menu.dmx.setting': '澶фā鍨嬭缃�', + 'cardList.tab.title.all': '鍏ㄩ儴', + 'cardList.tab.title.content': '鍐呭璐ㄦ', + 'cardList.tab.title.service': '寮�閫氭湇鍔�', + 'cardList.tab.title.preset': '瑙勫垯棰勭疆', + 'cardList.searchInput.placeholder': '鎼滅储', + // 'cardList.statistic.enable': '宸插惎鐢�', + // 'cardList.statistic.disable': '鏈惎鐢�', + 'cardList.content.delete': '鍒犻櫎', + 'cardList.content.inspection': '璐ㄦ', + 'cardList.content.action': '鐐瑰嚮鍒涘缓璐ㄦ鍐呭闃熷垪', + 'cardList.service.open': '寮�閫氭湇鍔�', + 'cardList.service.cancel': '鍙栨秷鏈嶅姟', + 'cardList.service.renew': '缁害鏈嶅姟', + 'cardList.service.tag': '宸插紑閫�', + 'cardList.service.expiresTag': '宸茶繃鏈�', + 'cardList.preset.tag': '宸插惎鐢�', +}; diff --git a/src/views/dmx/IntelligentAgent/mock.ts b/src/views/dmx/IntelligentAgent/mock.ts new file mode 100644 index 0000000..68cf096 --- /dev/null +++ b/src/views/dmx/IntelligentAgent/mock.ts @@ -0,0 +1,186 @@ +import Mock from 'mockjs'; +import setupMock, { successResponseWrap } from '@/utils/setup-mock'; +import { ServiceRecord } from '@/api/list'; + +const qualityInspectionList: ServiceRecord[] = [ + { + id: 1, + name: 'quality', + title: '瑙嗛绫�-鍘嗗彶瀵煎叆', + description: '2021-10-12 00:00:00', + data: [ + { + label: '寰呰川妫�鏁�', + value: '120', + }, + { + label: '绉帇鏃堕暱', + value: '60s', + }, + { + label: '寰呮娊妫�鏁�', + value: '0', + }, + ], + }, + { + id: 2, + name: 'quality', + title: '鍥炬枃绫�-鍥剧墖鐗堟潈', + description: '2021-12-11 18:30:00', + data: [ + { + label: '寰呰川妫�鏁�', + value: '120', + }, + { + label: '绉帇鏃堕暱', + value: '60s', + }, + { + label: '寰呮娊妫�鏁�', + value: '0', + }, + ], + }, + { + id: 3, + name: 'quality', + title: '鍥炬枃绫�-楂樻竻鍥剧墖', + description: '2021-10-15 08:10:00', + data: [ + { + label: '寰呰川妫�鏁�', + value: '120', + }, + { + label: '绉帇鏃堕暱', + value: '60s', + }, + { + label: '寰呮娊妫�鏁�', + value: '0', + }, + ], + }, +]; +const theServiceList: ServiceRecord[] = [ + { + id: 1, + icon: 'code', + title: '婕忔枟鍒嗘瀽', + description: + '鐢ㄦ埛琛屼负鍒嗘瀽涔嬫紡鏂楀垎鏋愭ā鍨嬫槸浼佷笟瀹炵幇绮剧粏鍖栬繍钀ャ�佽繘琛岀敤鎴疯涓哄垎鏋愮殑閲嶈鏁版嵁鍒嗘瀽妯″瀷銆�', + enable: true, + actionType: 'button', + }, + { + id: 2, + icon: 'edit', + title: '鐢ㄦ埛鍒嗗竷', + description: + '蹇�熻瘖鏂敤鎴蜂汉缇わ紝鍦板煙缁嗗垎鎯呭喌锛屼簡瑙f暟鎹垎甯冪殑闆嗕腑搴︼紝浠ュ強涓昏鐨勬暟鎹垎甯冪殑鍖洪棿娈垫槸浠�涔堛��', + enable: true, + actionType: 'button', + expires: true, + }, + { + id: 3, + icon: 'user', + title: '璧勬簮鍒嗗彂', + description: + '绉诲姩绔姩鎬佸寲璧勬簮鍒嗗彂瑙e喅鏂规銆傛彁渚涚ǔ瀹氬ぇ娴侀噺鏈嶅姟鏀寔銆佺伒娲诲畾鍒剁殑鍒嗗彂鍦堥�夎鍒欙紝閫氳繃绂荤嚎鍖栭鍔犺浇銆�', + enable: false, + actionType: 'button', + }, + { + id: 4, + icon: 'user', + title: '鐢ㄦ埛鐢诲儚鍒嗘瀽', + description: + '鐢ㄦ埛鐢诲儚灏辨槸灏嗗吀鍨嬬敤鎴蜂俊鎭爣绛惧寲锛屾牴鎹敤鎴风壒寰併�佷笟鍔″満鏅拰鐢ㄦ埛琛屼负绛変俊鎭紝鏋勫缓涓�涓爣绛惧寲鐨勭敤鎴锋ā鍨嬨��', + enable: true, + actionType: 'button', + }, +]; +const rulesPresetList: ServiceRecord[] = [ + { + id: 1, + title: '鍐呭灞忚斀瑙勫垯', + description: + '鐢ㄦ埛鍦ㄦ墽琛岀壒瀹氱殑鍐呭鍒嗗彂浠诲姟鏃讹紝鍙娇鐢ㄥ唴瀹瑰睆钄借鍒欐牴鎹壒瀹氭爣绛撅紝杩囨护鍐呭闆嗗悎銆�', + enable: true, + actionType: 'switch', + }, + { + id: 2, + title: '鍐呭缃《瑙勫垯', + description: + '璇ヨ鍒欐敮鎸佺敤鎴峰湪鎵ц鐗瑰畾鍐呭鍒嗗彂浠诲姟鏃讹紝瀵瑰浐瀹氱殑鍑犳潯鍐呭缃《銆�', + enable: true, + actionType: 'switch', + }, + { + id: 3, + title: '鍐呭鍔犳潈瑙勫垯', + description: '閫夊畾鍐呭鍔犳潈瑙勫垯鍚庡彲鑷畾涔変粠涓嶅悓鍐呭闆嗗悎鑾峰彇鍐呭鐨勬鐜囥��', + enable: false, + actionType: 'switch', + }, + { + id: 4, + title: '鍐呭鍒嗗彂瑙勫垯', + description: '鍐呭鍒嗗彂鏃讹紝瀵规煇浜涘唴瀹归渶瑕佸浐瀹氬湪C绔睍绀虹殑浣嶇疆銆�', + enable: true, + actionType: 'switch', + }, + { + id: 5, + title: '杩濈鍐呭璇嗗埆', + description: '绮惧噯璇嗗埆璧屽崥銆佸垁鏋�佹瘨鍝併�侀�犲亣銆佽穿鍋囩瓑杩濊鐗╁搧鍜岃繚瑙勮涓恒��', + enable: false, + actionType: 'switch', + }, + { + id: 6, + title: '澶氳瑷�鏂囧瓧绗﹀彿璇嗗埆', + description: + '绮惧噯璇嗗埆鑻辫銆佺淮璇�佽棌璇�佽挋鍙よ銆佹湞椴滆绛夊绉嶈瑷�浠ュ強emoji琛ㄦ儏褰㈡�佺殑璇箟璇嗗埆銆�', + enable: false, + actionType: 'switch', + }, +]; + +setupMock({ + setup() { + // Quality Inspection + Mock.mock(new RegExp('/api/list/quality-inspection'), () => { + return successResponseWrap( + qualityInspectionList.map((_, index) => ({ + ...qualityInspectionList[index % qualityInspectionList.length], + id: Mock.Random.guid(), + })) + ); + }); + + // the service + Mock.mock(new RegExp('/api/list/the-service'), () => { + return successResponseWrap( + theServiceList.map((_, index) => ({ + ...theServiceList[index % theServiceList.length], + id: Mock.Random.guid(), + })) + ); + }); + + // rules preset + Mock.mock(new RegExp('/api/list/rules-preset'), () => { + return successResponseWrap( + rulesPresetList.map((_, index) => ({ + ...rulesPresetList[index % rulesPresetList.length], + id: Mock.Random.guid(), + })) + ); + }); + }, +}); -- Gitblit v1.8.0