gaoluyang
9 小时以前 bff63ed3dd1a585f84b8c41f9396fa6f7a4ff4c7
银川
1.质量管理模块AI辅助判定检验结果联调
已添加3个文件
已修改5个文件
237 ■■■■■ 文件已修改
src/api/mes/qc/ai/index.ts 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/components/ai-assistant.vue 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/components/ai-suggest.vue 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/defectrecord/components/inline-list.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/ipqc/modules/form.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/iqc/modules/form.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/oqc/modules/form.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/rqc/modules/form.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mes/qc/ai/index.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
import { requestClient } from '#/api/request';
export namespace MesQcAiApi {
  export interface SuggestResultReqVO {
    qcId: number;
    qcType: number;
  }
  export interface SuggestResultRespVO {
    suggestedResult: number;
    suggestedResultName: string;
    reasoning: string;
    keyPoints: string[];
  }
}
/** AI è¾…助判定检验结果 */
export function suggestQcResult(params: MesQcAiApi.SuggestResultReqVO) {
  return requestClient.post<MesQcAiApi.SuggestResultRespVO>(
    '/mes/qc/ai/suggest-result',
    params,
  );
}
src/views/mes/qc/components/ai-assistant.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,88 @@
<script lang="ts" setup>
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { Empty, Input, Spin } from 'ant-design-vue';
import { searchKnowledgeSegment } from '#/api/ai/knowledge/segment';
defineOptions({ name: 'MesQcAiAssistant' });
const knowledgeId = 1; // è´¨æ£€æ ‡å‡†çŸ¥è¯†åº“ ID,需根据实际配置修改
const keyword = ref('');
const loading = ref(false);
const segments = ref<
  Array<{ id: number; content: string; score: number; documentName: string }>
>([]);
async function handleSearch() {
  if (!keyword.value.trim()) return;
  loading.value = true;
  try {
    const data = await searchKnowledgeSegment({
      knowledgeId,
      content: keyword.value,
      topK: 5,
      similarityThreshold: 0.5,
    });
    segments.value = (data || []) as typeof segments.value;
  } finally {
    loading.value = false;
  }
}
function handleKeywordChange(e: Event) {
  keyword.value = (e.target as HTMLInputElement).value;
}
const [AssistantModal, modalApi] = useVbenModal({
  footer: false,
});
</script>
<template>
  <a-button type="default" @click="modalApi.open()">
    è´¨æ£€åŠ©æ‰‹
  </a-button>
  <AssistantModal title="质检助手" class="w-1/3">
    <div class="mb-4">
      <a-textarea
        :value="keyword"
        placeholder="输入问题,如:外观检验标准是什么?"
        :rows="3"
        @change="handleKeywordChange"
      />
    </div>
    <div class="mb-4 flex justify-end">
      <a-button type="primary" :loading="loading" @click="handleSearch">
        æœç´¢
      </a-button>
    </div>
    <Spin :spinning="loading" tip="检索中...">
      <template v-if="segments.length === 0 && !loading">
        <Empty description="未找到相关标准,请尝试其他关键词" />
      </template>
      <div v-else class="space-y-3">
        <div
          v-for="segment in segments"
          :key="segment.id"
          class="rounded border border-gray-200 p-3"
        >
          <div class="mb-1 text-xs text-gray-500">
            æ¥æºï¼š{{ segment.documentName || '未知文档' }}
          </div>
          <div class="text-sm leading-relaxed">
            {{ segment.content }}
          </div>
          <div class="mt-1 text-xs text-gray-400">
            ç›¸ä¼¼åº¦ {{ ((segment.score ?? 0) * 100).toFixed(0) }}%
          </div>
        </div>
      </div>
    </Spin>
  </AssistantModal>
</template>
src/views/mes/qc/components/ai-suggest.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
<script lang="ts" setup>
import type { MesQcAiApi } from '#/api/mes/qc/ai';
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { IconifyIcon } from '@vben/icons';
import { Alert, Button, message, Tag } from 'ant-design-vue';
import { suggestQcResult } from '#/api/mes/qc/ai';
interface Props {
  qcId: number;
  qcType: number;
}
defineOptions({ name: 'MesQcAiSuggest' });
const props = defineProps<Props>();
const loading = ref(false);
const result = ref<MesQcAiApi.SuggestResultRespVO>();
const resultTagColor: Record<number, string> = {
  1: 'green',
  2: 'orange',
  3: 'red',
  4: 'red',
};
async function handleSuggest() {
  loading.value = true;
  result.value = undefined;
  try {
    result.value = await suggestQcResult({
      qcId: props.qcId,
      qcType: props.qcType,
    });
    modalApi.open();
  } catch {
    message.error('AI åˆ¤å®šæš‚时不可用,请人工判定');
  } finally {
    loading.value = false;
  }
}
const [ResultModal, modalApi] = useVbenModal({
  footer: false,
});
</script>
<template>
  <Button type="default" :loading="loading" @click="handleSuggest">
    <template #icon>
      <IconifyIcon icon="ant-design:robot-outlined" />
    </template>
    AI è¾…助判定
  </Button>
  <ResultModal title="AI è¾…助判定结果" class="w-1/2">
    <template v-if="result">
      <div class="mb-4 flex items-center gap-2">
        <span class="text-base font-medium">建议判定:</span>
        <Tag :color="resultTagColor[result.suggestedResult]">
          {{ result.suggestedResultName }}
        </Tag>
      </div>
      <div class="mb-4">
        <div class="mb-2 text-base font-medium">推理依据:</div>
        <div class="rounded bg-gray-50 p-3 text-sm leading-relaxed">
          {{ result.reasoning }}
        </div>
      </div>
      <div v-if="result.keyPoints?.length">
        <div class="mb-2 text-base font-medium">关注点:</div>
        <Alert
          v-for="(point, index) in result.keyPoints"
          :key="index"
          type="warning"
          show-icon
          class="mb-2"
          :message="point"
        />
      </div>
    </template>
  </ResultModal>
</template>
src/views/mes/qc/defectrecord/components/inline-list.vue
@@ -131,7 +131,9 @@
      return;
    }
    ctxData.value = modalApi.getData<CtxData>();
    await gridApi.query();
    setTimeout(() => {
      gridApi.query();
    }, 50);
  },
});
</script>
src/views/mes/qc/ipqc/modules/form.vue
@@ -15,6 +15,8 @@
import { $t } from '#/locales';
import { QcIndicatorResultList } from '../../indicatorresult/components';
import MesQcAiSuggest from '../../components/ai-suggest.vue';
import MesQcAiAssistant from '../../components/ai-assistant.vue';
import { useFormSchema } from '../data';
import LineList from './line-list.vue';
@@ -228,6 +230,12 @@
        <Button v-if="canFinish" type="primary" @click="handleFinish">
          å®Œæˆ
        </Button>
        <MesQcAiSuggest
          v-if="canFinish && formData?.id"
          :qc-id="formData.id"
          :qc-type="MesQcTypeEnum.IPQC"
        />
        <MesQcAiAssistant />
      </div>
    </template>
  </Modal>
src/views/mes/qc/iqc/modules/form.vue
@@ -15,6 +15,8 @@
import { $t } from '#/locales';
import { QcIndicatorResultList } from '../../indicatorresult/components';
import MesQcAiSuggest from '../../components/ai-suggest.vue';
import MesQcAiAssistant from '../../components/ai-assistant.vue';
import { useFormSchema } from '../data';
import LineList from './line-list.vue';
@@ -229,6 +231,12 @@
        <Button v-if="canFinish" type="primary" @click="handleFinish">
          å®Œæˆ
        </Button>
        <MesQcAiSuggest
          v-if="canFinish && formData?.id"
          :qc-id="formData.id"
          :qc-type="MesQcTypeEnum.IQC"
        />
        <MesQcAiAssistant />
      </div>
    </template>
  </Modal>
src/views/mes/qc/oqc/modules/form.vue
@@ -15,6 +15,8 @@
import { $t } from '#/locales';
import { QcIndicatorResultList } from '../../indicatorresult/components';
import MesQcAiSuggest from '../../components/ai-suggest.vue';
import MesQcAiAssistant from '../../components/ai-assistant.vue';
import { useFormSchema } from '../data';
import LineList from './line-list.vue';
@@ -232,6 +234,12 @@
        <Button v-if="canFinish" type="primary" @click="handleFinish">
          å®Œæˆ
        </Button>
        <MesQcAiSuggest
          v-if="canFinish && formData?.id"
          :qc-id="formData.id"
          :qc-type="MesQcTypeEnum.OQC"
        />
        <MesQcAiAssistant />
      </div>
    </template>
  </Modal>
src/views/mes/qc/rqc/modules/form.vue
@@ -15,6 +15,8 @@
import { $t } from '#/locales';
import { QcIndicatorResultList } from '../../indicatorresult/components';
import MesQcAiSuggest from '../../components/ai-suggest.vue';
import MesQcAiAssistant from '../../components/ai-assistant.vue';
import { useFormSchema } from '../data';
import LineList from './line-list.vue';
@@ -228,6 +230,12 @@
        <Button v-if="canFinish" type="primary" @click="handleFinish">
          å®Œæˆ
        </Button>
        <MesQcAiSuggest
          v-if="canFinish && formData?.id"
          :qc-id="formData.id"
          :qc-type="MesQcTypeEnum.RQC"
        />
        <MesQcAiAssistant />
      </div>
    </template>
  </Modal>