liudong
2024-08-05 3db93fe877d797602f4399ca10add3de2595fbd9
智能体管理的测试助手页面的bug修改
12个文件已添加
1993 ■■■■■ 已修改文件
src/views/dmx/agent/components/addAgent.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/agent/components/card-wrap.vue 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/agent/components/custom-settings.vue 244 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/agent/components/editAgent.vue 332 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/agent/components/quality-inspection.vue 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/agent/components/rules-preset.vue 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/agent/components/sessionAction.vue 265 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/agent/components/the-service.vue 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/agent/index.vue 350 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/agent/locale/en-US.ts 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/agent/locale/zh-CN.ts 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/agent/mock.ts 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dmx/agent/components/addAgent.vue
New file
@@ -0,0 +1,149 @@
<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 label="你希望智能体的角色是什么,具体完成什么任务?">
        <a-textarea
          v-model="form.prompt_config.system"
          placeholder=""
          style="height: 180px"
        />
      </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
          >
          <editAgent
            ref="editAgentKuai"
            typeAngint="add"
            :formData="form"
            @cancelModal="handleCancel"
          ></editAgent>
        </div>
      </a-form-item>
    </a-form>
  </a-modal>
</template>
<script lang="ts" setup>
  import { onMounted, onBeforeMount, reactive, ref } from 'vue';
  import editAgent from '@/views/dmx/IntelligentAgent/components/editAgent.vue';
  const visible = ref(false);
  const loading = ref(false);
  const editAgentKuai = ref();
  const form = reactive({
    name: '',
    icon: '',
    language: 'English',
    prompt_config: {
      empty_response: '',
      prologue: '你好! 我是你的助理,有什么可以帮到你的吗?',
      quote: true,
      self_rag: true,
      system:
        '示例:\n' +
        '你是 XX,具有 XX 经验,擅长 XX,…\n' +
        '你的任务是 XX ,需要按照以下步骤执行:\n' +
        '1. XX\n' +
        '2. XX\n' +
        '3. …\n',
      parameters: [
        {
          key: 'knowledge',
          optional: false,
        },
      ],
    },
    kb_ids: [],
    llm_id: 'qwen-plus',
    llm_setting: {
      temperature: 0.1,
      top_p: 0.3,
      presence_penalty: 0.4,
      frequency_penalty: 0.7,
      max_tokens: 512,
    },
    similarity_threshold: 0.2,
    vector_similarity_weight: 0.30000000000000004,
    top_n: 8,
  });
  const formRef = ref(null);
  const rules = {
    name: [
      {
        required: true,
        message: '名称不允许为空',
      },
    ],
  };
  const handleSubmit = ({ values, errors }) => {
    console.log('values:', values, '\nerrors:', errors);
    if (!errors) {
      editAgentKuai.value.handleClick(form);
    }
  };
  const handleClick = () => {
    visible.value = true;
  };
  defineExpose({
    handleClick,
  });
  const handleCancel = () => {
    visible.value = false;
    formRef.value.resetFields();
    form.name = '';
  };
  const handleOpened = (el) => {
    // Object.assign(form,{
    //   name: '',// 用户名
    //   nameJoin: '',// 昵称
    //   post: '',// 岗位
    //   txt: '',// 备注
    // });
    formRef.value.resetFields();
    form.name = '';
    form.prompt_config.system =
      '示例:\n' +
      '你是 XX,具有 XX 经验,擅长 XX,…\n' +
      '你的任务是 XX ,需要按照以下步骤执行:\n' +
      '1. XX\n' +
      '2. XX\n' +
      '3. …\n'+
      '{knowledge}';
  };
  const file = ref();
  onBeforeMount(() => {});
  onMounted(() => {});
</script>
src/views/dmx/agent/components/card-wrap.vue
New file
@@ -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>
src/views/dmx/agent/components/custom-settings.vue
New file
@@ -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="请输入模型UID" />
        </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>
src/views/dmx/agent/components/editAgent.vue
New file
@@ -0,0 +1,332 @@
<template>
  <a-button
    v-if="typeAngint == 'edit'"
    type="text"
    size="small"
    @click="editClick"
  >
    <template #icon>
      <icon-tool />
    </template>
  </a-button>
  <!--  <a-button v-if="typeAngint=='add'" style="margin-left: 10px" type="primary" @click="handleClick">确定</a-button>-->
  <a-modal
    v-model:visible="visible"
    title=""
    @before-open="handleOpened"
    @cancel="handleCancel"
    :footer="false"
    title-align="start"
    fullscreen
  >
  <div class="main-container">
    <div class="main-container-lf">
      <div style="padding: 10px;font-size: 16px;background: var(--color-neutral-3);">智能体配置</div>
      <div style="display: flex;width: 100%;" :style="{height:height}">
        <div style="width: 50%;height: 100%">
          <div style="padding: 10px;font-size: 12px;color: #2a2a2b;">智能体画像</div>
          <div>
            <a-textarea v-model="system" placeholder="" disabled style="height: 400px;"  />
          </div>
        </div>
        <div style="width: 50%;border: 1px solid var(--color-neutral-3);background:  var(--color-neutral-3)">
          <a-form ref="formRef" :rules="rules" :model="form" @submit="handleSubmit"  layout="vertical" >
            <a-collapse :default-active-key="['1']">
              <a-collapse-item header="基础信息" key="0" v-if="typeAngint == 'edit'">
                <a-input v-model="form.name" placeholder="请输入智能体名称"  style="width:200px;margin-top: 10px" />
              </a-collapse-item>
              <a-collapse-item header="AI模型配置" key="1">
                <a-form-item field="llm_id" label="模型">
                  <a-space direction="vertical" size="large">
                    <a-select :size="'large'" field="llm_id" v-model="form.llm_id" :style="{width:'25rem'}" placeholder="请选择 ...">
                      <a-optgroup
                        :label="index"
                        v-for="(item, index) in modelList"
                        :key="index"
                      >
                        <a-option
                          v-for="obj in item"
                          :key="obj.fid"
                          :disabled="!obj.available"
                          :value="obj.llm_id"
                        >
                          {{ obj.llm_name }}
                        </a-option>
                      </a-optgroup>
                    </a-select>
                  </a-space>
                </a-form-item>
                </a-collapse-item>
                <a-collapse-item header="开场引导" :key="'2'" disabled>
                </a-collapse-item>
                <a-collapse-item  header="知识库" key="3">
                  <a-form-item field="kb_ids" label="知识库">
                    <a-select
                      v-model="form.kb_ids"
                      :style="{ width: '25rem' }"
                      placeholder="请选择 ..."
                      multiple
                    >
                      <a-option
                        v-for="item in tabs"
                        :key="item.id"
                        :value="item.id"
                      >{{ item.name }}</a-option
                      >
                    </a-select>
                  </a-form-item>
                </a-collapse-item>
                <a-collapse-item header="工具" key="4" disabled>
                </a-collapse-item>
                <a-collapse-item header="工作流" key="5" disabled>
                </a-collapse-item>
              </a-collapse>
              <a-form-item>
                <div
                  style="
                    position: absolute;
                    right: 10px;
                    top: 0px;
                    z-index: 99999;
                  "
                >
                  <!--                <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>
          </div>
        </div>
      </div>
      <div class="main-container-rt">
        <sessionAction></sessionAction>
      </div>
    </div>
  </a-modal>
</template>
<script lang="ts" setup>
  import { onMounted, onBeforeMount, reactive, ref, nextTick } from 'vue';
  import { IconSend } from '@arco-design/web-vue/es/icon';
  import { queryKbList, queryModelList } from '@/api/kbList';
  import useLoading from '@/hooks/loading';
  import { dialogSet } from '@/api/Agent';
  import { Message } from '@arco-design/web-vue';
  import EventBus from "@/utils/EventBus";
  import sessionAction  from "@/views/dmx/IntelligentAgent/components/sessionAction.vue";
  const { setLoading } = useLoading(true);
  const props = defineProps(['typeAngint', 'formData']);
  const visible = ref(false);
  const loading = ref(false);
  const form = reactive({
    name: '',
    icon: '',
    language: 'English',
    prompt_config: {
      empty_response: '',
      prologue: '你好! 我是你的助理,有什么可以帮到你的吗?',
      quote: true,
      self_rag: true,
      system:
        '示例:\n' +
        '你是 XX,具有 XX 经验,擅长 XX,…\n' +
        '你的任务是 XX ,需要按照以下步骤执行:\n' +
        '1. XX\n' +
        '2. XX\n' +
        '3. …\n' +
        '{knowlege}',
      parameters: [
        {
          key: 'knowledge',
          optional: false,
        },
      ],
    },
    kb_ids: [],
    llm_id: 'qwen-plus',
    llm_setting: {
      temperature: 0.1,
      top_p: 0.3,
      presence_penalty: 0.4,
      frequency_penalty: 0.7,
      max_tokens: 512,
    },
    similarity_threshold: 0.2,
    vector_similarity_weight: 0.30000000000000004,
    top_n: 8,
  });
  const system = ref('');
  const embdId = ref('');
  const modelList = ref({});
  const renderData = ref([]);
  const formRef = ref(null);
  let tabs = ref([]);
  const height = ref('calc(100vh - 150px)');
  const emit = defineEmits(['cancelModal']);
  const rules = {
    name: [
      {
        required: true,
        message: '名称不允许为空',
      },
    ],
    llm_id: [
      {
        required: true,
        message: '模型不能为空',
      },
    ],
    kb_ids: [
      {
        required: true,
        message: '知识库不能为空',
      },
    ],
  };
  const handleSubmit = async ({ values, errors }) => {
    // console.log('values:', values, '\nerrors:', errors)
    if(!errors){
      let title = '创建成功';
      let formNew = { ...form };
      if (props.typeAngint == 'edit') {
        formNew.dialog_id = form.id;
        delete formNew.id;
        delete formNew.off;
        title = '修改成功';
      }
      const data = await dialogSet(formNew);
      if (data.code == 0) {
        Message.success(title);
        handleCancel();
        EventBus.emit('queryList');
      }
    }
  };
  const editClick = (data) => {
    visible.value = true;
    console.log(props.formData);
    Object.assign(form, props.formData);
    console.log(form);
    system.value = form.prompt_config.system;
  };
  const handleClick = (data) => {
    visible.value = true;
    nextTick(() => {
      Object.assign(form, data);
      console.log(form,'传值');
      system.value = form.prompt_config.system;
      if(tabs.value && tabs.value.length>0){
        form.kb_ids = [tabs.value[0].id];
      }
    });
  };
  defineExpose({
    handleClick,
  });
  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;
    emit('cancelModal');
  };
  const handleOpened = (el) => {
    // formRef.value.resetFields();
  };
  const queryModel = async (params) => {
    try {
      const data = await queryModelList(params);
      console.log(data.data, '大模型列表');
      modelList.value = data.data;
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
    }
  };
  const file = ref();
  const onChange = (_, currentFile) => {
    file.value = {
      ...currentFile,
      // url: URL.createObjectURL(currentFile.file),
    };
  };
  const onProgress = (currentFile) => {
    file.value = currentFile;
  };
  const knowledgeData = async (params = { page: 1, page_size: 20 }) => {
    setLoading(true);
    try {
      const { data } = await queryKbList(params);
      console.log(data, 'data');
      nextTick(() => {
        tabs.value = data;
        console.log(tabs.value, 'tabs');
      });
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      setLoading(false);
    }
  };
  onBeforeMount(() => {
    queryModel({});
    knowledgeData();
  });
  onMounted(() => {});
</script>
<style scoped lang="less">
  .main-container {
    width: 100%;
    display: flex;
    .main-container-lf {
      width: 60%;
    }
    .main-container-rt {
      position: relative;
      width: 40%;
    }
  }
  .bottom {
    width: 100%;
    position: absolute;
    bottom: 40px;
    left: 0;
    .input {
      margin-left: 20%;
      width: 60%;
    }
    .text {
      margin-left: 40%;
      font-size: 12px;
      color: lightgrey;
      line-height: 40px;
    }
  }
  :deep(.arco-textarea-wrapper.arco-textarea-disabled){
      background: var(--color-bg-2);
      color: var(--color-text-1);
  }
</style>
src/views/dmx/agent/components/quality-inspection.vue
New file
@@ -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>
src/views/dmx/agent/components/rules-preset.vue
New file
@@ -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>
src/views/dmx/agent/components/sessionAction.vue
New file
@@ -0,0 +1,265 @@
<template>
  <div :style="{ height: heightrg }">
    <div style="padding: 10px">
      <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>
      调试预览
    </div>
    <a-divider style="margin: 0; margin-left: 10px" />
    <a-scrollbar
      ref="scrollbar"
      id="home"
      class="chat-list"
      style="width: 90%; overflow: auto; height: 70vh; margin: 0px auto;"
    >
      <div class="chat-item" v-for="sessionDetail in sessionDetailList">
        <a-comment
          v-if="sessionDetail.role === 'user'"
          avatar="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp"
        >
          <template #content>
            <div :class="{ light: theme === 'light' }" style="background-color: var(--color-bg-2);color: var(--color-text-3);border: none;padding: 16px;">{{
                sessionDetail.content
              }}</div>
          </template>
        </a-comment>
        <a-comment
          v-else-if="sessionDetail.role === 'assistant'"
          avatar="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/9eeb1800d9b78349b24682c3518ac4a3.png~tplv-uwbnlip3yd-webp.webp"
        >
          <template #content>
            <a-card
              class="chat-item-answer"
              style="background-color: var(--color-bg-2);color: var(--color-text-3);border: none"
            >
              <div :class="{ light: theme === 'light' }">{{
                  sessionDetail.content
                }}</div>
            </a-card>
          </template>
        </a-comment>
        <a-comment
          v-else-if="sessionDetail.role === 'last'"
          avatar="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/9eeb1800d9b78349b24682c3518ac4a3.png~tplv-uwbnlip3yd-webp.webp"
        >
          <template #content>
            <a-textarea
              readonly
              auto-size
              v-model="displayedText"
              class="chat-item-answer"
              style="background-color: var(--color-bg-2);color: var(--color-text-3);border: none"
            >
            </a-textarea>
          </template>
        </a-comment>
      </div>
    </a-scrollbar>
    <div class="bottom">
      <div class="input">
        <a-input
          v-model="inputMsg"
          @keydown.enter="sendMessage"
          placeholder="输入您想了解的内容,按Enter发送"
        >
          <template #suffix>
            <icon-send style="cursor: pointer" @click="sendMessage" />
          </template> </a-input
        ></div>
      <div class="text">内容由AI生成,仅供参考</div>
    </div>
  </div>
</template>
<script setup lang="ts">
import {
  IconMoreVertical,
  IconQuestionCircleFill,
  IconPoweroff,
  IconCommon,
  IconSend,
} from '@arco-design/web-vue/es/icon';
import img1 from '@/assets/images/u64.png';
import img2 from '@/assets/images/u69.png';
import img3 from '@/assets/images/u74.png';
import { ref, onMounted, computed, reactive, nextTick, watch } from 'vue';
import { useUserStore, useAppStore } from '@/store';
import {
  sessionListApi,
  deleteSessionApi,
  getSessionDetailsApi,
  chatApi,
} from '@/api/session';
import { Message } from '@arco-design/web-vue';
const userStore = useUserStore();
const appStore = useAppStore();
const theme = computed(() => {
  return appStore.theme;
});
const heightrg = ref('calc(100vh - 100px)');
const sessionList = ref([]); //会话列表
const sessionDetailList = ref([]); //根据会话id出来的会话详情
const activeSessionId = ref('');
const inputMsg = ref('');
const scrollbar = ref(null);
const currIndex = ref(0);
const displayedText = ref(''); // 正在显示的文字
let timer: number | null = null;
const streamStr = ref('');
const modalObj = reactive({ add: false });
//查询会话列表
const querySessionList = async () => {
  const { code, data } = await sessionListApi();
  if (code === 200) {
    sessionList.value = data;
    if (Array.isArray(data) && data.length > 0) {
      activeSessionId.value = data[1].id;
      const res = await getSessionDetailsApi(data[0].id);
      if (res.code === 200) {
        sessionDetailList.value = res.data.message;
        refreshScroll();
      }
    }
  } else {
    Message.warning('查询失败');
  }
};
//根据会话id删除会话
const deleteSession = async (session) => {
  const { code } = await deleteSessionApi([session.id]);
  if (code === 200) {
    Message.success('删除成功');
    querySessionList();
  }
};
// eslint-disable-next-line prettier/prettier
// 新增会话之后刷新会话列表
const addSession = () => {
  querySessionList();
};
// 初始化数据
const initData = () => {
  querySessionList();
};
// 获取登录信息
const userName = computed(() => {
  return userStore.name;
});
const avatar = computed(() => {
  return userStore.avatar;
});
const refreshScroll = () => {
  nextTick(() => {
    const container = document.getElementById('home');
    scrollbar.value.scrollTop(container.scrollHeight);
  });
};
// 根据会话id 查询会话详情
const querySessionDetail = async (session) => {
  activeSessionId.value = session.id;
  const { code, data } = await getSessionDetailsApi(session.id);
  if (code === 200) {
    sessionDetailList.value = data.message;
    refreshScroll(); //刷新滚动条位置
  }
};
const sendMessage = async () => {
  if (inputMsg.value) {
    const { code, data } = await chatApi({
      conversation_id: activeSessionId.value,
      messages: inputMsg.value,
    });
    const res = await getSessionDetailsApi(activeSessionId.value);
    if (res.code === 200) {
      sessionDetailList.value = res.data.message.map((item, index) => {
        if (index === res.data.message.length - 1) {
          item.role = 'last';
          displayedText.value = '';
          currIndex.value = 0;
          streamStr.value = item.content;
          startDisplayStr();
        }
        return item;
      });
      refreshScroll();
    }
    inputMsg.value = '';
  } else {
    Message.warning('消息不能为空');
  }
};
onMounted(() => {
  initData();
});
//文字动态输出
const startDisplayStr = () => {
  if (timer) {
    clearTimeout(timer!);
  }
  const res = streamStr.value;
  // 将数组中的字符串拼接起来
  if (currIndex.value < res.length) {
    displayedText.value += res[currIndex.value];
    currIndex.value++;
    setTimeout(startDisplayStr, 100);
  } else {
    clearTimeout(timer!);
    timer = null;
  }
};
watch(
  () => scrollbar.value,
  (newScroll, oldScroll) => {
    if (newScroll) {
      // 获取a-scroll的高度
      const height = newScroll.$el.offsetHeight;
      console.log('a-scroll height changed to:', height);
    }
  },
  { deep: true }
);
</script>
<style scoped lang="less">
.container {
  width: 100%;
  display: flex;
}
//.light {
//  color: white !important;
//}
.bottom {
  width: 100%;
  position: absolute;
  bottom: 40px;
  left: 0;
  .input {
    margin-left: 20%;
    width: 60%;
  }
  .text {
    margin-left: 40%;
    font-size: 12px;
    color: lightgrey;
    line-height: 40px;
  }
}
.chat-list {
  width: 90%;
  margin: 0px auto;
  .chat-item {
    margin-top: 20px;
    .chat-item-answer {
      color: white;
    }
  }
}
</style>
src/views/dmx/agent/components/the-service.vue
New file
@@ -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>
src/views/dmx/agent/index.vue
New file
@@ -0,0 +1,350 @@
<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"
              @change="queryList"
            />
          </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 agentList"
                  :key="item.id"
                >
                  <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
                      v-model="item.off"
                      style="position: absolute; top: 10px; right: 10px"
                      size="medium"
                      @change="handleChange(item)"
                    >
                      <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.name }}
                        </span>
                      </div>
                      <div class="arco-card-body-content-down">
                        {{ item.prompt_config.prologue }}
                      </div>
                    </div>
                    <div style="position: absolute; bottom: 1.4rem; left: 1rem">
                      <icon-user />
                      <span style="font-size: 12px">
                        <!--                      {{ item.name }}-->
                      </span>
                    </div>
                    <div style="position: absolute; bottom: 1rem; right: 1rem">
                      <a-space>
                        <span v-show="!item.off">
                          <editAgent
                            ref="editAgentKuai"
                            typeAngint="edit"
                            :formData="form"
                            @cancelModal="handleCancel"
                          ></editAgent>
                        </span>
                        <a-popconfirm
                          :content="'确定删除吗'"
                          type="warning"
                          @ok="deleteItem(item)"
                        >
                          <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, onBeforeMount, onMounted, onBeforeUnmount } from "vue";
  import addAgent from '@/views/dmx/IntelligentAgent/components/addAgent.vue';
  import editAgent from '@/views/dmx/IntelligentAgent/components/editAgent.vue';
  import { kbdocumentrm, queryKbList } from '@/api/kbList';
  import { Message } from '@arco-design/web-vue';
  import { deletedialog, querydialogList } from '@/api/Agent';
  import useLoading from '@/hooks/loading';
  const { loading, setLoading } = useLoading(true);
  import EventBus from '@/utils/EventBus';
  let count = 5;
  const activeKey = ref(1);
  const addAgents = ref();
  const editAgentKuai = ref();
  const agentList = 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 queryList = async (params = {}) => {
    setLoading(true);
    try {
      const { data } = await querydialogList(params);
      console.log(data, 'data');
      agentList.value = data.map((item) => {
        return {
          ...item,
          off: true,
        };
      });
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      setLoading(false);
    }
  };
  const deleteItem = async (row) => {
    console.log(row);
    let data = await deletedialog({ dialog_ids: [row.id] });
    if (data.code == 0) {
      Message.success('删除成功');
      queryList();
    }
  };
  const handleChange = async (item) => {
    if (item) {
      Object.assign(form, item);
    }
  };
  const handleCancel = () => {
    queryList();
  };
  const handleSubmit = ({ values, errors }) => {
    this.$refs.formRef.validate().then((res, a, b) => {
      debugger;
      console.log('values', values);
    });
  };
  onBeforeMount(() => {
    queryList();
  });
  onMounted(()=>{
    EventBus.on('queryList',()=>{
      queryList();
    })
  })
  onBeforeUnmount(()=>{
    EventBus.off('queryList')
  })
</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: 23%;
    height: 200px;
    margin: 1%;
    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>
src/views/dmx/agent/locale/en-US.ts
New file
@@ -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',
};
src/views/dmx/agent/locale/zh-CN.ts
New file
@@ -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': '已启用',
};
src/views/dmx/agent/mock.ts
New file
@@ -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:
      '快速诊断用户人群,地域细分情况,了解数据分布的集中度,以及主要的数据分布的区间段是什么。',
    enable: true,
    actionType: 'button',
    expires: true,
  },
  {
    id: 3,
    icon: 'user',
    title: '资源分发',
    description:
      '移动端动态化资源分发解决方案。提供稳定大流量服务支持、灵活定制的分发圈选规则,通过离线化预加载。',
    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(),
        }))
      );
    });
  },
});