feat(mes): 增加质检指标层级结构与多批次录入功能
- 新增 MesQcIndicatorItemType 枚举定义条目类型(录入项/分组项)
- 在质检指标表单中增加条目类型选择与所属分组关联选择功能
- 实现质检指标的树形层级展示,支持分组项与录入项结构
- 添加公式文本、单位文本、排序号等新字段配置
- 增加采样地点、证书编号、执行标准、复核人、审核人等字段
- 实现检测结果的多测量批次录入,支持同一指标多次检测
- 添加默认执行标准配置到质检方案模板
- 重构检测值录入界面,支持分组展示与批量测量管理
- 新增检验报告单打印数据接口与相关模型定义
| | |
| | | id?: number; // ç¼å· |
| | | code?: string; // æ£æµé¡¹ç¼ç |
| | | name?: string; // æ£æµé¡¹åç§° |
| | | parentId?: number; // ç¶ææ ç¼å·ï¼0=é¡¶çº§ï¼ |
| | | itemType?: number; // æ¡ç®ç±»åï¼1=å½å
¥é¡¹ï¼2=åç»é¡¹ |
| | | formulaText?: string; // å
¬å¼å±ç¤ºææ¬ï¼æå°ç¨ï¼ä¸åä¸è®¡ç®ï¼ |
| | | unitText?: string; // å使æ¬ï¼å¦ kg/m³ã/%ï¼ |
| | | sortOrder?: number; // å级æåºå· |
| | | type?: number; // æ£æµé¡¹ç±»å |
| | | tool?: string; // æ£æµå·¥å
· |
| | | resultType?: number; // ç»æå¼ç±»å |
| | | resultSpecification?: string; // ç»æå¼å±æ§ |
| | | remark?: string; // 夿³¨ |
| | | parentName?: string; // ç¶ææ åç§°ï¼å表/详æ
åå¡«ï¼ |
| | | createTime?: Date; // å建æ¶é´ |
| | | } |
| | | } |
| | |
| | | return requestClient.delete(`/mes/qc/indicator/delete?id=${id}`); |
| | | } |
| | | |
| | | /** æ¥è¯¢è´¨æ£ææ å
¨éå表ï¼å«åç»å±çº§ï¼ä¾æ 表/ä¸æä½¿ç¨ï¼ */ |
| | | export function getIndicatorList() { |
| | | return requestClient.get<MesQcIndicatorApi.Indicator[]>( |
| | | '/mes/qc/indicator/list', |
| | | ); |
| | | } |
| | | |
| | | /** 导åºè´¨æ£ææ */ |
| | | export function exportIndicator(params: any) { |
| | | return requestClient.download('/mes/qc/indicator/export-excel', { params }); |
| | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | export namespace MesQcIndicatorResultApi { |
| | | /** MES æ£éªç»ææç» */ |
| | | /** å¹³è¡æµéæ¹æ¬¡æç»ï¼å䏿æ ç䏿¬¡æµéï¼ */ |
| | | export interface Measure { |
| | | detailId?: number; // æç»ç¼å· |
| | | resultId?: number; // å
³èæ£éªç»æ ID |
| | | measureNo?: number; // æµéæ¹æ¬¡å·ï¼ä» 1 å¼å§ï¼ |
| | | value?: string; // æ£æµå¼ |
| | | remark?: string; // 夿³¨ |
| | | } |
| | | |
| | | /** MES æ£éªç»ææç»ï¼æ å½¢ï¼åç»é¡¹ä¸æå项ï¼å¹³è¡æµéæ¾å
¥ measuresï¼ */ |
| | | export interface IndicatorResultDetail { |
| | | id?: number; // ç¼å· |
| | | id?: number; // ç¼å·ï¼ç¬¬ä¸æ¹æç» IDï¼å
¼å®¹æ§åæ®µï¼ |
| | | resultId?: number; // å
³èæ£éªç»æ ID |
| | | indicatorId?: number; // æ£æµææ ID |
| | | value?: string; // æ£æµå¼ï¼ç»ä¸å为åç¬¦ä¸²ï¼ |
| | | value?: string; // æ£æµå¼ï¼ç¬¬ä¸æ¹ï¼å
¼å®¹æ§åæ®µï¼ |
| | | valueNumber?: number; // UI æ°å¼ç»å®ï¼æäº¤å转åç¬¦ä¸²ï¼ |
| | | measureNo?: number; // æµéæ¹æ¬¡å·ï¼æäº¤ç¨ï¼é»è®¤ 1ï¼ |
| | | remark?: string; // 夿³¨ |
| | | // å
³èæ¥è¯¢åæ®µï¼æ¥èª indicatorï¼ |
| | | indicatorName?: string; // æ£æµææ åç§° |
| | | valueType?: number; // è´¨æ£å¼ç±»å |
| | | valueSpecification?: string; // å¼å±æ§ |
| | | parentId?: number; // ç¶ææ ç¼å·ï¼0=é¡¶çº§ï¼ |
| | | itemType?: number; // æ¡ç®ç±»åï¼1=å½å
¥é¡¹ï¼2=åç»é¡¹ |
| | | formulaText?: string; // å
¬å¼å±ç¤ºææ¬ |
| | | unitText?: string; // åä½ææ¬ |
| | | sortOrder?: number; // å级æåºå· |
| | | measures?: Measure[]; // å¹³è¡æµéæ¹æ¬¡åè¡¨ï¼æ measureNo ååºï¼ |
| | | children?: IndicatorResultDetail[]; // å项å表ï¼åç»é¡¹ä¸æï¼ |
| | | } |
| | | |
| | | /** MES æ£éªç»æ */ |
| | |
| | | export function deleteIndicatorResult(id: number) { |
| | | return requestClient.delete(`/mes/qc/indicator-result/delete?id=${id}`); |
| | | } |
| | | |
| | | // ==================== æ£éªæ¥ååï¼æå°æ°æ®ï¼ ==================== |
| | | |
| | | export namespace MesQcReportApi { |
| | | /** æ¥åæµéå¼ */ |
| | | export interface ReportMeasure { |
| | | measureNo?: number; // æµéæ¹æ¬¡å· |
| | | value?: string; // æ£æµå¼ |
| | | remark?: string; // 夿³¨ |
| | | } |
| | | |
| | | /** æ¥åæ£éªé¡¹ï¼æ å½¢ï¼ */ |
| | | export interface ReportItem { |
| | | indicatorId?: number; |
| | | indicatorCode?: string; |
| | | indicatorName?: string; |
| | | parentId?: number; |
| | | itemType?: number; // 1=å½å
¥é¡¹ï¼2=åç»é¡¹ |
| | | formulaText?: string; |
| | | unitText?: string; |
| | | sortOrder?: number; |
| | | checkMethod?: string; // æ£æµæ¹æ³ |
| | | standardValue?: string; // æ åå¼ |
| | | thresholdMin?: string; // éå¼ä¸é |
| | | thresholdMax?: string; // éå¼ä¸é |
| | | measures?: ReportMeasure[]; |
| | | children?: ReportItem[]; |
| | | } |
| | | |
| | | /** æ£éªæ¥åå */ |
| | | export interface QcReport { |
| | | qcType?: number; |
| | | docCode?: string; |
| | | docName?: string; |
| | | itemCode?: string; |
| | | itemName?: string; |
| | | itemSpecification?: string; |
| | | batchNo?: string; |
| | | samplingLocation?: string; |
| | | certificateNo?: string; |
| | | executeStandard?: string; |
| | | samplingTime?: Date; |
| | | batchQuantity?: number; |
| | | checkResult?: number; |
| | | inspectorUserId?: number; |
| | | inspectorName?: string; |
| | | auditUserId?: number; |
| | | auditName?: string; |
| | | approveUserId?: number; |
| | | approveName?: string; |
| | | remark?: string; |
| | | measureNos?: number[]; // åå¤´ï¼æµéæ¹æ¬¡å·å表 |
| | | items?: ReportItem[]; |
| | | } |
| | | } |
| | | |
| | | /** æ¥è¯¢æ£éªæ¥ååæ°æ®ï¼æå°ç¨ï¼ */ |
| | | export function getQcReport(qcId: number, qcType: number, resultId?: number) { |
| | | return requestClient.get<MesQcReportApi.QcReport>('/mes/qc/indicator-result/report', { |
| | | params: { qcId, qcType, resultId }, |
| | | }); |
| | | } |
| | |
| | | inspectDate?: number; // æ£æµæ¥æ |
| | | inspectorUserId?: number; // æ£æµäººåç¨æ· ID |
| | | inspectorNickname?: string; // æ£æµäººåæµç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | auditUserId?: number; // 夿 ¸äºº ID |
| | | auditNickname?: string; // 夿 ¸äººæµç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | approveUserId?: number; // å®¡æ ¸äºº ID |
| | | approveNickname?: string; // å®¡æ ¸äººæµç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | samplingLocation?: string; // éæ ·å°ç¹ |
| | | certificateNo?: string; // è¯ä¹¦ç¼å·/åæ ¼è¯å· |
| | | executeStandard?: string; // æ§è¡æ å |
| | | status?: number; // ç¶æ |
| | | remark?: string; // 夿³¨ |
| | | } |
| | |
| | | inspector?: string; // æ£æµäººåï¼æµç§°ï¼ |
| | | inspectorUserId?: number; // æ£æµäººå ID |
| | | inspectorNickname?: string; // æ£æµäººåæµç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | auditUserId?: number; // 夿 ¸äºº ID |
| | | auditNickname?: string; // 夿 ¸äººæµç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | approveUserId?: number; // å®¡æ ¸äºº ID |
| | | approveNickname?: string; // å®¡æ ¸äººæµç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | samplingLocation?: string; // éæ ·å°ç¹ |
| | | certificateNo?: string; // è¯ä¹¦ç¼å·/åæ ¼è¯å· |
| | | executeStandard?: string; // æ§è¡æ å |
| | | status?: number; // ç¶æ |
| | | remark?: string; // 夿³¨ |
| | | } |
| | |
| | | inspectDate?: number; // æ£æµæ¥æ |
| | | inspectorUserId?: number; // æ£æµäººåç¨æ· ID |
| | | inspectorNickname?: string; // æ£æµäººåæµç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | auditUserId?: number; // 夿 ¸äºº ID |
| | | auditNickname?: string; // 夿 ¸äººæµç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | approveUserId?: number; // å®¡æ ¸äºº ID |
| | | approveNickname?: string; // å®¡æ ¸äººæµç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | samplingLocation?: string; // éæ ·å°ç¹ |
| | | certificateNo?: string; // è¯ä¹¦ç¼å·/åæ ¼è¯å· |
| | | executeStandard?: string; // æ§è¡æ å |
| | | status?: number; // ç¶æ |
| | | remark?: string; // 夿³¨ |
| | | } |
| | |
| | | inspectDate?: number; // æ£æµæ¥æ |
| | | inspectorUserId?: number; // æ£æµäººåç¨æ· ID |
| | | inspectorNickname?: string; // æ£æµäººåæµç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | auditUserId?: number; // 夿 ¸äºº ID |
| | | auditNickname?: string; // 夿 ¸äººæµç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | approveUserId?: number; // å®¡æ ¸äºº ID |
| | | approveNickname?: string; // å®¡æ ¸äººæµç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | samplingLocation?: string; // éæ ·å°ç¹ |
| | | certificateNo?: string; // è¯ä¹¦ç¼å·/åæ ¼è¯å· |
| | | executeStandard?: string; // æ§è¡æ å |
| | | status?: number; // ç¶æ |
| | | remark?: string; // 夿³¨ |
| | | // 缺é·ç»è®¡ |
| | |
| | | name?: string; // æ¹æ¡åç§° |
| | | types?: number[]; // æ£æµç§ç±» |
| | | status?: number; // ç¶æ |
| | | defaultExecuteStandard?: string; // é»è®¤æ§è¡æ åï¼å»ºåæ¶å¸¦å
¥ä¸»è¡¨ï¼ |
| | | remark?: string; // 夿³¨ |
| | | createTime?: Date; // å建æ¶é´ |
| | | } |
| | |
| | | thresholdMax?: number; // 误差ä¸é |
| | | thresholdMin?: number; // 误差ä¸é |
| | | docUrl?: string; // 说æå¾URL |
| | | sortOrder?: number; // æåºå·ï¼æ¹æ¡å
å±ç¤ºé¡ºåºï¼ |
| | | judgeFlag?: boolean; // æ¯å¦åä¸å¤å®æç¤ºï¼åç»/åæ°è¡=falseï¼ |
| | | remark?: string; // 夿³¨ |
| | | indicatorCode?: string; // æ£æµé¡¹ç¼ç ï¼JOINï¼ |
| | | indicatorName?: string; // æ£æµé¡¹åç§°ï¼JOINï¼ |
| | |
| | | FILE: 5, |
| | | } as const; |
| | | |
| | | /** MES è´¨æ£ææ æ¡ç®ç±»åæä¸¾ï¼1=å½å
¥é¡¹ï¼2=åç»é¡¹ï¼å¯¹é½å端 MesQcIndicatorItemTypeEnumï¼ */ |
| | | export const MesQcIndicatorItemType = { |
| | | RECORD: 1, |
| | | GROUP: 2, |
| | | } as const; |
| | | |
| | | /** MES ä¸å¡ç±»å常é */ |
| | | export const MesBizTypeEnum = { |
| | | // WM ä»åºæ¨¡å [100, 200) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { MesQcReportApi } from '#/api/mes/qc/indicatorresult'; |
| | | |
| | | import { computed, nextTick, ref } from 'vue'; |
| | | |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { getDictLabel } from '@vben/hooks'; |
| | | import { useUserStore } from '@vben/stores'; |
| | | import { formatDateTime } from '@vben/utils'; |
| | | |
| | | import { getQcReport } from '#/api/mes/qc/indicatorresult'; |
| | | |
| | | /** |
| | | * MES æ£éªæ¥ååæå°ç»ä»¶ï¼åå·¥æ£éªè®°å½çå¼ï¼è¡¨å¤´ + æ£éªé¡¹ç©éµ + å¹³è¡æµéå + ç¾ååºï¼ |
| | | * |
| | | * æå°æ ·å¼åè erp/sale/order/modules/print.vueï¼Teleport + body class + @media printï¼ã |
| | | */ |
| | | defineOptions({ name: 'MesQcReportPrint' }); |
| | | |
| | | const userStore = useUserStore(); |
| | | |
| | | /** æå¹³ååçæ¥åè¡ */ |
| | | interface PrintRow { |
| | | kind: 'group' | 'record'; |
| | | indicatorId?: number; |
| | | name?: string; |
| | | unit?: string; |
| | | method?: string; // åç»=å
¬å¼ææ¬ï¼å½å
¥é¡¹=æ£æµæ¹æ³ |
| | | standard?: string; // æ åå¼ï¼å«éå¼åºé´ï¼ |
| | | values: Record<number, string>; // measureNo -> æ£æµå¼ |
| | | remarks: Record<number, string>; // measureNo -> 夿³¨ |
| | | } |
| | | |
| | | const report = ref<MesQcReportApi.QcReport>({}); |
| | | const measureNos = ref<number[]>([1]); |
| | | const printTime = ref(''); |
| | | |
| | | /** æ åå¼å±ç¤ºï¼æ åå¼ + éå¼åºé´ */ |
| | | function formatStandard(item: MesQcReportApi.ReportItem) { |
| | | const parts: string[] = []; |
| | | if (item.standardValue != null) { |
| | | parts.push(String(item.standardValue)); |
| | | } |
| | | if (item.thresholdMin != null || item.thresholdMax != null) { |
| | | parts.push(`${item.thresholdMin ?? ''}~${item.thresholdMax ?? ''}`); |
| | | } |
| | | return parts.join(' '); |
| | | } |
| | | |
| | | /** å°æ£éªé¡¹æ æå¹³å为æå°è¡ï¼åç»è¡ + å
¶åå½å
¥è¡ï¼é¡¶çº§å½å
¥è¡ç¬ç«æè¡ï¼ */ |
| | | const printRows = computed<PrintRow[]>(() => { |
| | | const rows: PrintRow[] = []; |
| | | const pushRecord = (item: MesQcReportApi.ReportItem, method: string) => { |
| | | const values: Record<number, string> = {}; |
| | | const remarks: Record<number, string> = {}; |
| | | (item.measures ?? []).forEach((m) => { |
| | | if (m.measureNo != null) { |
| | | values[m.measureNo] = m.value ?? ''; |
| | | remarks[m.measureNo] = m.remark ?? ''; |
| | | } |
| | | }); |
| | | rows.push({ |
| | | kind: 'record', |
| | | indicatorId: item.indicatorId, |
| | | name: item.indicatorName, |
| | | unit: item.unitText, |
| | | method, |
| | | standard: formatStandard(item), |
| | | values, |
| | | remarks, |
| | | }); |
| | | }; |
| | | const walk = (items: MesQcReportApi.ReportItem[] = []) => { |
| | | items.forEach((item) => { |
| | | if (item.itemType === 2) { |
| | | rows.push({ |
| | | kind: 'group', |
| | | indicatorId: item.indicatorId, |
| | | name: item.indicatorName, |
| | | method: item.formulaText, |
| | | values: {}, |
| | | remarks: {}, |
| | | }); |
| | | walk(item.children ?? []); |
| | | } else { |
| | | pushRecord(item, item.checkMethod ?? ''); |
| | | } |
| | | }); |
| | | }; |
| | | walk(report.value.items ?? []); |
| | | return rows; |
| | | }); |
| | | |
| | | /** æ£æµç»æææ¡ï¼åå
¸ mes_qc_check_resultï¼ */ |
| | | const checkResultText = computed(() => { |
| | | if (report.value.checkResult == null) { |
| | | return '-'; |
| | | } |
| | | return ( |
| | | getDictLabel(DICT_TYPE.MES_QC_CHECK_RESULT, report.value.checkResult) || '-' |
| | | ); |
| | | }); |
| | | |
| | | function waitForPaint() { |
| | | return new Promise<void>((resolve) => { |
| | | requestAnimationFrame(() => requestAnimationFrame(() => resolve())); |
| | | }); |
| | | } |
| | | |
| | | function removePrintMode() { |
| | | document.body.classList.remove('mes-qc-report-printing'); |
| | | } |
| | | |
| | | /** æå°ï¼å è½½æ¥åæ°æ®ååå°æå°æ¨¡å¼è°ç¨æµè§å¨æå° */ |
| | | async function print(qcId: number, qcType: number, resultId?: number) { |
| | | const data = await getQcReport(qcId, qcType, resultId); |
| | | report.value = data; |
| | | measureNos.value = data.measureNos?.length ? data.measureNos : [1]; |
| | | printTime.value = formatDateTime(new Date()); |
| | | await nextTick(); |
| | | await waitForPaint(); |
| | | document.body.classList.add('mes-qc-report-printing'); |
| | | window.addEventListener('afterprint', removePrintMode, { once: true }); |
| | | window.print(); |
| | | } |
| | | |
| | | defineExpose({ print }); |
| | | </script> |
| | | |
| | | <template> |
| | | <Teleport to="body"> |
| | | <div |
| | | id="mesQcReportPrint" |
| | | class="mes-qc-report-print pointer-events-none fixed left-0 top-0 z-[-1] w-full bg-white text-[#303133] opacity-0" |
| | | > |
| | | <h2 class="m-0 mb-1 text-center text-[1.6em] font-bold leading-[1.2]"> |
| | | {{ report.docName || 'æ£éªæ¥å' }} |
| | | </h2> |
| | | <div class="mb-2 text-center text-sm"> |
| | | {{ report.itemName || '' }} |
| | | <span v-if="report.itemSpecification">ï¼{{ report.itemSpecification }}</span> |
| | | <span v-if="report.executeStandard">ãæ§è¡æ åï¼{{ report.executeStandard }}</span> |
| | | </div> |
| | | |
| | | <!-- è¡¨å¤´ä¿¡æ¯æ --> |
| | | <div |
| | | class="mb-3 grid grid-cols-3 gap-x-6 gap-y-1 border border-solid border-[#dcdfe6] p-3 text-sm leading-[1.6]" |
| | | > |
| | | <div>æ£éªåå·ï¼{{ report.docCode || '-' }}</div> |
| | | <div>ç©æç¼ç ï¼{{ report.itemCode || '-' }}</div> |
| | | <div>æ¹æ¬¡å·ï¼{{ report.batchNo || '-' }}</div> |
| | | <div>éæ ·å°ç¹ï¼{{ report.samplingLocation || '-' }}</div> |
| | | <div>è¯ä¹¦ç¼å·ï¼{{ report.certificateNo || '-' }}</div> |
| | | <div>æ¹éï¼{{ report.batchQuantity ?? '-' }}</div> |
| | | <div> |
| | | éæ ·/æ£éªæ¶é´ï¼{{ formatDateTime(report.samplingTime) || '-' }} |
| | | </div> |
| | | <div>æ£æµç»è®ºï¼{{ checkResultText }}</div> |
| | | <div>æå°æ¶é´ï¼{{ printTime || '-' }}</div> |
| | | </div> |
| | | |
| | | <!-- æ£éªé¡¹ç©éµ --> |
| | | <table class="w-full border-collapse text-[13px] leading-[1.5]"> |
| | | <thead> |
| | | <tr> |
| | | <th class="cell bg">æ£éªé¡¹ç®</th> |
| | | <th class="cell w-16 bg">åä½</th> |
| | | <th class="cell bg">æ¹æ³/å
¬å¼</th> |
| | | <th class="cell w-24 bg">æ åå¼</th> |
| | | <th v-for="no in measureNos" :key="`h-${no}`" class="cell w-20 bg"> |
| | | æµé{{ no }} |
| | | </th> |
| | | <th class="cell bg">夿³¨</th> |
| | | </tr> |
| | | </thead> |
| | | <tbody> |
| | | <tr v-for="(row, i) in printRows" :key="row.indicatorId ?? i"> |
| | | <template v-if="row.kind === 'group'"> |
| | | <td class="cell group-name" colspan="3">{{ row.name }}</td> |
| | | <td class="cell group-formula" :colspan="measureNos.length + 2"> |
| | | {{ row.method || '' }} |
| | | </td> |
| | | </template> |
| | | <template v-else> |
| | | <td class="cell record-name">{{ row.name }}</td> |
| | | <td class="cell text-center">{{ row.unit || '-' }}</td> |
| | | <td class="cell">{{ row.method || '-' }}</td> |
| | | <td class="cell text-center">{{ row.standard || '-' }}</td> |
| | | <td |
| | | v-for="no in measureNos" |
| | | :key="`v-${row.indicatorId}-${no}`" |
| | | class="cell text-center" |
| | | > |
| | | {{ row.values[no] || '' }} |
| | | </td> |
| | | <td class="cell"> |
| | | <template v-if="measureNos.length === 1"> |
| | | {{ row.remarks[measureNos[0]!] || '' }} |
| | | </template> |
| | | <template v-else> |
| | | <div v-for="no in measureNos" :key="`r-${row.indicatorId}-${no}`"> |
| | | {{ no }}:{{ row.remarks[no] || '' }} |
| | | </div> |
| | | </template> |
| | | </td> |
| | | </template> |
| | | </tr> |
| | | <tr v-if="printRows.length === 0"> |
| | | <td class="cell text-center" :colspan="6 + measureNos.length"> |
| | | ææ æ£éªé¡¹ |
| | | </td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | |
| | | <!-- 夿³¨ + ç¾ååº --> |
| | | <div class="mt-3 border border-solid border-[#dcdfe6] p-3 text-sm leading-[1.6]"> |
| | | 夿³¨ï¼{{ report.remark || '-' }} |
| | | </div> |
| | | <div |
| | | class="mt-4 grid grid-cols-3 gap-x-10 gap-y-4 border border-dashed border-[#dcdfe6] p-4 text-sm leading-[1.8]" |
| | | > |
| | | <div> |
| | | åæè
ï¼{{ report.inspectorName || '-' }} |
| | | </div> |
| | | <div> |
| | | 夿 ¸äººï¼{{ report.auditName || '-' }} |
| | | </div> |
| | | <div> |
| | | å®¡æ ¸äººï¼{{ report.approveName || '-' }} |
| | | </div> |
| | | <div> |
| | | ç¾åï¼<span class="sig"></span> |
| | | </div> |
| | | <div> |
| | | ç¾åï¼<span class="sig"></span> |
| | | </div> |
| | | <div> |
| | | ç¾åï¼<span class="sig"></span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="mt-4 flex justify-between text-xs text-[#909399]"> |
| | | <div>æå°äººåï¼{{ userStore.userInfo?.nickname || '-' }}</div> |
| | | <div>æå°æ¶é´ï¼{{ printTime || '-' }}</div> |
| | | </div> |
| | | </div> |
| | | </Teleport> |
| | | </template> |
| | | |
| | | <style scoped> |
| | | @page { |
| | | margin: 8mm 10mm; |
| | | } |
| | | |
| | | .mes-qc-report-print { |
| | | .cell { |
| | | padding: 4px 6px; |
| | | text-align: left; |
| | | border: 1px solid #dcdfe6; |
| | | } |
| | | |
| | | .cell.bg { |
| | | font-weight: bold; |
| | | background: #f5f7fa; |
| | | text-align: center; |
| | | } |
| | | |
| | | .cell.text-center { |
| | | text-align: center; |
| | | } |
| | | |
| | | .group-name { |
| | | font-weight: bold; |
| | | background: #fafafa; |
| | | } |
| | | |
| | | .group-formula { |
| | | font-style: italic; |
| | | color: #555; |
| | | background: #fafafa; |
| | | } |
| | | |
| | | .record-name { |
| | | padding-left: 20px; |
| | | } |
| | | |
| | | .sig { |
| | | display: inline-block; |
| | | width: 90px; |
| | | border-bottom: 1px solid #303133; |
| | | } |
| | | } |
| | | |
| | | @media print { |
| | | :global(body.mes-qc-report-printing) { |
| | | padding: 0 !important; |
| | | margin: 0 !important; |
| | | -webkit-print-color-adjust: exact; |
| | | print-color-adjust: exact; |
| | | } |
| | | |
| | | :global(body.mes-qc-report-printing *) { |
| | | visibility: hidden !important; |
| | | } |
| | | |
| | | :global(body.mes-qc-report-printing .mes-qc-report-print), |
| | | :global(body.mes-qc-report-printing .mes-qc-report-print *) { |
| | | visibility: visible !important; |
| | | } |
| | | |
| | | :global(body.mes-qc-report-printing .mes-qc-report-print) { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | z-index: auto; |
| | | box-sizing: border-box; |
| | | width: 100%; |
| | | padding: 0 !important; |
| | | margin: 0 !important; |
| | | pointer-events: auto; |
| | | opacity: 1; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | import { |
| | | DICT_TYPE, |
| | | MesAutoCodeRuleCode, |
| | | MesQcIndicatorItemType, |
| | | MesQcResultValueType, |
| | | } from '@vben/constants'; |
| | | import { getDictOptions } from '@vben/hooks'; |
| | | |
| | | import { Button } from 'ant-design-vue'; |
| | | |
| | | import { getIndicatorList } from '#/api/mes/qc/indicator'; |
| | | import { generateAutoCode } from '#/api/mes/md/autocode/record'; |
| | | |
| | | import { QcIndicatorResultSpecificationInput } from './components'; |
| | |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'itemType', |
| | | label: 'æ¡ç®ç±»å', |
| | | component: 'RadioGroup', |
| | | defaultValue: MesQcIndicatorItemType.RECORD, |
| | | componentProps: { |
| | | options: [ |
| | | { label: 'å½å
¥é¡¹', value: MesQcIndicatorItemType.RECORD }, |
| | | { label: 'åç»é¡¹', value: MesQcIndicatorItemType.GROUP }, |
| | | ], |
| | | optionType: 'button', |
| | | }, |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'parentId', |
| | | label: 'æå±åç»', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | allowClear: true, |
| | | api: async () => { |
| | | const list = await getIndicatorList(); |
| | | // ä»
å¯éæ©åç»é¡¹ä½ä¸ºç¶çº§ï¼ä¸åç»é¡¹æ¬èº«ä¸å¯åæç¶çº§ï¼ä»
ä¸¤çº§ï¼ |
| | | return list |
| | | .filter((i) => i.itemType === MesQcIndicatorItemType.GROUP) |
| | | .map((i) => ({ label: i.name, value: i.id })); |
| | | }, |
| | | placeholder: 'ä¸éå为顶级项', |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ['itemType'], |
| | | // åç»é¡¹å¿
须为顶级ï¼éèå¹¶æ¸
空ä¸çº§ |
| | | show: (values) => values.itemType !== MesQcIndicatorItemType.GROUP, |
| | | if: (values) => values.itemType !== MesQcIndicatorItemType.GROUP, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'type', |
| | | label: 'æ£æµé¡¹ç±»å', |
| | | component: 'Select', |
| | |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'formulaText', |
| | | label: 'å
¬å¼ææ¬', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 500, |
| | | placeholder: 'å¦ w3 = c à V à 0.06005 / m à 100%ï¼ä»
å±ç¤ºï¼ä¸åä¸è®¡ç®ï¼', |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ['itemType'], |
| | | if: (values) => values.itemType === MesQcIndicatorItemType.GROUP, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'tool', |
| | | label: 'æ£æµå·¥å
·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 100, |
| | | placeholder: '请è¾å
¥æ£æµå·¥å
·', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'unitText', |
| | | label: 'å使æ¬', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 50, |
| | | placeholder: 'å¦ %ãgãæ ï¼ä»
å±ç¤ºä¸åä¸è®¡ç®', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'sortOrder', |
| | | label: 'æåºå·', |
| | | component: 'InputNumber', |
| | | defaultValue: 0, |
| | | componentProps: { |
| | | min: 0, |
| | | precision: 0, |
| | | placeholder: 'å级æåºï¼æ°åå°çå¨å', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | placeholder: 'è¯·éæ©ç»æå¼ç±»å', |
| | | }, |
| | | rules: 'required', |
| | | dependencies: { |
| | | triggerFields: ['itemType'], |
| | | // åç»é¡¹ä¸å½å
¥ç»æå¼ï¼éèå¹¶è·³è¿æ ¡éª |
| | | if: (values) => values.itemType !== MesQcIndicatorItemType.GROUP, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'resultSpecification', |
| | |
| | | minWidth: 160, |
| | | }, |
| | | { |
| | | field: 'itemType', |
| | | title: 'æ¡ç®ç±»å', |
| | | width: 90, |
| | | formatter: ({ cellValue }) => |
| | | cellValue === MesQcIndicatorItemType.GROUP ? 'åç»é¡¹' : 'å½å
¥é¡¹', |
| | | }, |
| | | { |
| | | field: 'parentName', |
| | | title: 'æå±åç»', |
| | | width: 120, |
| | | formatter: ({ cellValue }) => cellValue || '-', |
| | | }, |
| | | { |
| | | field: 'type', |
| | | title: 'æ£æµé¡¹ç±»å', |
| | | width: 120, |
| | |
| | | width: 140, |
| | | }, |
| | | { |
| | | field: 'unitText', |
| | | title: 'åä½', |
| | | width: 80, |
| | | formatter: ({ cellValue }) => cellValue || '-', |
| | | }, |
| | | { |
| | | field: 'resultType', |
| | | title: 'ç»æå¼ç±»å', |
| | | width: 120, |
| | |
| | | import { computed, ref } from 'vue'; |
| | | |
| | | import { useVbenModal } from '@vben/common-ui'; |
| | | import { MesQcResultValueType } from '@vben/constants'; |
| | | import { MesQcIndicatorItemType, MesQcResultValueType } from '@vben/constants'; |
| | | import { getDictOptions } from '@vben/hooks'; |
| | | |
| | | import { |
| | | Button, |
| | | Form as AForm, |
| | | Divider, |
| | | Input, |
| | |
| | | qcType: number; |
| | | } |
| | | |
| | | /** å¯ç¼è¾æµéæ¹æ¬¡ï¼å¨æ¥å£ç»æä¸å¢å æ°å¼ç»å®åæ®µï¼ */ |
| | | interface EditMeasure { |
| | | detailId?: number; |
| | | resultId?: number; |
| | | measureNo: number; |
| | | value?: string; |
| | | valueNumber?: number; |
| | | remark?: string; |
| | | } |
| | | |
| | | /** å¯ç¼è¾æ£éªé¡¹ï¼æ å½¢èç¹ï¼ */ |
| | | interface EditItem { |
| | | indicatorId?: number; |
| | | indicatorName?: string; |
| | | valueType?: number; |
| | | valueSpecification?: string; |
| | | parentId?: number; |
| | | itemType?: number; |
| | | formulaText?: string; |
| | | unitText?: string; |
| | | sortOrder?: number; |
| | | measures: EditMeasure[]; |
| | | children?: EditItem[]; |
| | | } |
| | | |
| | | defineOptions({ name: 'QcIndicatorResultForm' }); |
| | | |
| | | const emit = defineEmits(['success']); |
| | | const formType = ref<FormType>('create'); |
| | | const items = ref<MesQcIndicatorResultApi.IndicatorResultDetail[]>([]); |
| | | const roots = ref<EditItem[]>([]); |
| | | const ctxData = ref<CtxData>(); |
| | | |
| | | const getTitle = computed(() => |
| | |
| | | wrapperClass: 'grid-cols-2', |
| | | }); |
| | | |
| | | /** æ¯å¦åç»é¡¹ï¼åç»é¡¹ä¸å½å
¥å¼ï¼ä»
æ¿è½½å±çº§ä¸å
¬å¼ææ¬ï¼ */ |
| | | function isGroup(item: EditItem) { |
| | | return item.itemType === MesQcIndicatorItemType.GROUP; |
| | | } |
| | | |
| | | /** æ¯å¦æ°å¼åå½å
¥ï¼å³å® InputNumber ä¸ææ¬æ§ä»¶ï¼ */ |
| | | function isNumeric(item: EditItem) { |
| | | return ( |
| | | item.valueType === MesQcResultValueType.FLOAT || |
| | | item.valueType === MesQcResultValueType.INTEGER |
| | | ); |
| | | } |
| | | |
| | | /** è·ååå
¸é项ï¼valueSpecification 为系ç»åå
¸ç±»ååï¼ */ |
| | | function getValueOptions(dictType?: string) { |
| | | return dictType |
| | |
| | | value: String(value), |
| | | })) |
| | | : []; |
| | | } |
| | | |
| | | /** å°æ¥å£è¿åçæç»æ 转æ¢ä¸ºå¯ç¼è¾ç»æï¼åç»éå½ãå½å
¥é¡¹ä¿è¯è³å°ä¸ä¸ªæµéæ¹æ¬¡ */ |
| | | function toEditItems( |
| | | items: MesQcIndicatorResultApi.IndicatorResultDetail[] = [], |
| | | ): EditItem[] { |
| | | return items.map((item) => { |
| | | const node: EditItem = { |
| | | indicatorId: item.indicatorId, |
| | | indicatorName: item.indicatorName, |
| | | valueType: item.valueType, |
| | | valueSpecification: item.valueSpecification, |
| | | parentId: item.parentId, |
| | | itemType: item.itemType, |
| | | formulaText: item.formulaText, |
| | | unitText: item.unitText, |
| | | sortOrder: item.sortOrder, |
| | | measures: [], |
| | | children: item.children ? toEditItems(item.children) : undefined, |
| | | }; |
| | | if (isGroup(node)) { |
| | | return node; |
| | | } |
| | | const measures = (item.measures ?? []).map((m) => ({ |
| | | detailId: m.detailId, |
| | | resultId: m.resultId, |
| | | measureNo: m.measureNo ?? 1, |
| | | value: m.value, |
| | | valueNumber: |
| | | isNumeric(node) && m.value !== null && m.value !== undefined |
| | | ? Number(m.value) |
| | | : undefined, |
| | | remark: m.remark, |
| | | })); |
| | | node.measures = measures.length > 0 ? measures : [{ measureNo: 1 }]; |
| | | return node; |
| | | }); |
| | | } |
| | | |
| | | /** æ¶éææå½å
¥é¡¹ï¼å¶åï¼ç¨äºæäº¤ä¸å±ç¤ºç»è®¡ */ |
| | | function collectLeaves(nodes: EditItem[]): EditItem[] { |
| | | const leaves: EditItem[] = []; |
| | | const walk = (list: EditItem[]) => { |
| | | list.forEach((n) => { |
| | | if (isGroup(n)) { |
| | | walk(n.children ?? []); |
| | | } else { |
| | | leaves.push(n); |
| | | } |
| | | }); |
| | | }; |
| | | walk(nodes); |
| | | return leaves; |
| | | } |
| | | |
| | | /** æ°å¢ä¸ä¸ªæµéæ¹æ¬¡ */ |
| | | function addMeasure(item: EditItem) { |
| | | const nextNo = |
| | | item.measures.reduce((max, m) => Math.max(max, m.measureNo ?? 0), 0) + 1; |
| | | item.measures.push({ measureNo: nextNo }); |
| | | } |
| | | |
| | | /** å 餿宿µéæ¹æ¬¡ï¼è³å°ä¿çä¸ä¸ªï¼ */ |
| | | function removeMeasure(item: EditItem, index: number) { |
| | | if (item.measures.length <= 1) { |
| | | message.warning('è³å°ä¿çä¸ä¸ªæµéæ¹æ¬¡'); |
| | | return; |
| | | } |
| | | item.measures.splice(index, 1); |
| | | } |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | |
| | | return; |
| | | } |
| | | modalApi.lock(); |
| | | // æäº¤è¡¨å |
| | | const head = |
| | | (await formApi.getValues()) as MesQcIndicatorResultApi.IndicatorResult; |
| | | const submitItems = items.value.map((item) => { |
| | | const submit: MesQcIndicatorResultApi.IndicatorResultDetail = { |
| | | id: item.id, |
| | | indicatorId: item.indicatorId, |
| | | remark: item.remark, |
| | | }; |
| | | if ( |
| | | item.valueType === MesQcResultValueType.FLOAT || |
| | | item.valueType === MesQcResultValueType.INTEGER |
| | | ) { |
| | | submit.value = |
| | | item.valueNumber === null ? undefined : String(item.valueNumber); |
| | | } else { |
| | | submit.value = item.value; |
| | | } |
| | | return submit; |
| | | // å±å¼ï¼æ¯ä¸ªå½å
¥é¡¹çæ¯ä¸ªæµéæ¹æ¬¡ â 䏿¡æç» |
| | | const submitItems: MesQcIndicatorResultApi.IndicatorResultDetail[] = []; |
| | | collectLeaves(roots.value).forEach((item) => { |
| | | item.measures.forEach((measure) => { |
| | | const value = isNumeric(item) |
| | | ? measure.valueNumber === null || measure.valueNumber === undefined |
| | | ? undefined |
| | | : String(measure.valueNumber) |
| | | : measure.value; |
| | | submitItems.push({ |
| | | id: measure.detailId, |
| | | resultId: measure.resultId, |
| | | indicatorId: item.indicatorId, |
| | | measureNo: measure.measureNo, |
| | | value, |
| | | remark: measure.remark, |
| | | }); |
| | | }); |
| | | }); |
| | | const payload: MesQcIndicatorResultApi.IndicatorResult = { |
| | | ...head, |
| | |
| | | await createIndicatorResult(payload); |
| | | message.success($t('common.createSuccess')); |
| | | } |
| | | // å
³éå¹¶æç¤º |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | } finally { |
| | |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (!isOpen) { |
| | | ctxData.value = undefined; |
| | | items.value = []; |
| | | roots.value = []; |
| | | return; |
| | | } |
| | | formApi.setState({ schema: useQcIndicatorResultFormSchema(formApi) }); |
| | | // å è½½æ°æ® |
| | | const data = modalApi.getData<CtxData>(); |
| | | ctxData.value = data; |
| | | formType.value = data.formType; |
| | |
| | | data.qcType, |
| | | data.id, |
| | | ); |
| | | // åå¡«æ°å¼å段ï¼ç¨äº InputNumber ç»å®ï¼ |
| | | items.value = (detail.items ?? []).map((item) => ({ |
| | | ...item, |
| | | valueNumber: |
| | | (item.valueType === MesQcResultValueType.FLOAT || |
| | | item.valueType === MesQcResultValueType.INTEGER) && |
| | | item.value !== null |
| | | ? Number(item.value) |
| | | : undefined, |
| | | })); |
| | | // è®¾ç½®å° values |
| | | roots.value = toEditItems(detail.items); |
| | | await formApi.setValues({ |
| | | id: detail.id, |
| | | code: detail.code, |
| | |
| | | } |
| | | }, |
| | | }); |
| | | |
| | | /** å个æµéå¼è¾å
¥æ§ä»¶ç»å®ï¼æ°å¼åèµ° valueNumberï¼å
¶ä½èµ° valueï¼ */ |
| | | function bindMeasure(item: EditItem, measure: EditMeasure) { |
| | | return isNumeric(item) ? measure.valueNumber : measure.value; |
| | | } |
| | | function onMeasureInput(item: EditItem, measure: EditMeasure, v: any) { |
| | | if (isNumeric(item)) { |
| | | measure.valueNumber = v === null ? undefined : Number(v); |
| | | } else { |
| | | measure.value = v; |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | |
| | | <div class="px-4"> |
| | | <Form /> |
| | | <Divider>æ£æµå¼</Divider> |
| | | <!-- æ£æµå¼æ§ä»¶ç±æ¯è¡ valueType 驱å¨ï¼éè¡æ¸²æï¼FLOAT/INTEGER èµ° InputNumberï¼DICT èµ° Select å¹¶æ valueSpecification è§£æé项 --> |
| | | <AForm :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }"> |
| | | <div |
| | | v-for="(item, index) in items" |
| | | :key="item.indicatorId ?? index" |
| | | class="mb-2" |
| | | > |
| | | <AForm.Item |
| | | :label="`æ£æµé¡¹${index + 1}ï¼${item.indicatorName ?? ''}`" |
| | | > |
| | | <InputNumber |
| | | v-if=" |
| | | item.valueType === MesQcResultValueType.FLOAT || |
| | | item.valueType === MesQcResultValueType.INTEGER |
| | | " |
| | | v-model:value="item.valueNumber" |
| | | :precision="item.valueType === MesQcResultValueType.FLOAT ? 4 : 0" |
| | | class="!w-full" |
| | | placeholder="请è¾å
¥" |
| | | /> |
| | | <Textarea |
| | | v-else-if="item.valueType === MesQcResultValueType.TEXT" |
| | | v-model:value="item.value" |
| | | :rows="2" |
| | | placeholder="请è¾å
¥æ£æµå¼" |
| | | /> |
| | | <Select |
| | | v-else-if="item.valueType === MesQcResultValueType.DICT" |
| | | v-model:value="item.value" |
| | | allow-clear |
| | | :options="getValueOptions(item.valueSpecification)" |
| | | placeholder="è¯·éæ©" |
| | | /> |
| | | <Input |
| | | v-else-if="item.valueType === MesQcResultValueType.FILE" |
| | | v-model:value="item.value" |
| | | placeholder="请è¾å
¥æä»¶å°å" |
| | | /> |
| | | <Input v-else v-model:value="item.value" placeholder="请è¾å
¥" /> |
| | | </AForm.Item> |
| | | </div> |
| | | </AForm> |
| | | <div v-if="roots.length === 0" class="py-4 text-center text-gray-400"> |
| | | 该质æ£åæªé
ç½®æ£æµææ |
| | | </div> |
| | | <div v-else class="qc-result-tree"> |
| | | <template v-for="(node, ni) in roots" :key="node.indicatorId ?? ni"> |
| | | <!-- åç»é¡¹ï¼æ é¢è¡ + å
¬å¼ææ¬ï¼ä¸æåå½å
¥é¡¹ --> |
| | | <div v-if="isGroup(node)"> |
| | | <div |
| | | class="mb-2 flex items-center justify-between rounded bg-gray-100 px-3 py-1.5 font-medium" |
| | | > |
| | | <span>{{ node.indicatorName }}</span> |
| | | <span v-if="node.formulaText" class="text-xs text-gray-500"> |
| | | {{ node.formulaText }} |
| | | </span> |
| | | </div> |
| | | <div |
| | | v-for="(child, ci) in node.children ?? []" |
| | | :key="child.indicatorId ?? ci" |
| | | class="mb-3 ml-4" |
| | | > |
| | | <div class="mb-1 flex items-center justify-between"> |
| | | <span class="font-medium"> |
| | | {{ child.indicatorName }} |
| | | <span v-if="child.unitText" class="text-xs text-gray-500"> |
| | | ï¼{{ child.unitText }}ï¼ |
| | | </span> |
| | | </span> |
| | | <Button |
| | | size="small" |
| | | type="link" |
| | | @click="addMeasure(child)" |
| | | > |
| | | + æµéæ¹æ¬¡ |
| | | </Button> |
| | | </div> |
| | | <div |
| | | v-for="(measure, mi) in child.measures" |
| | | :key="mi" |
| | | class="mb-1 flex items-center gap-2" |
| | | > |
| | | <span class="w-16 shrink-0 text-right text-xs text-gray-500"> |
| | | 第 {{ measure.measureNo }} 次 |
| | | </span> |
| | | <InputNumber |
| | | v-if="child.valueType === MesQcResultValueType.FLOAT || child.valueType === MesQcResultValueType.INTEGER" |
| | | :value="bindMeasure(child, measure)" |
| | | :precision="child.valueType === MesQcResultValueType.FLOAT ? 4 : 0" |
| | | class="!w-48" |
| | | placeholder="请è¾å
¥" |
| | | @update:value="(v) => onMeasureInput(child, measure, v)" |
| | | /> |
| | | <Textarea |
| | | v-else-if="child.valueType === MesQcResultValueType.TEXT" |
| | | v-model:value="measure.value" |
| | | :rows="1" |
| | | class="!w-48" |
| | | placeholder="请è¾å
¥æ£æµå¼" |
| | | /> |
| | | <Select |
| | | v-else-if="child.valueType === MesQcResultValueType.DICT" |
| | | v-model:value="measure.value" |
| | | allow-clear |
| | | class="!w-48" |
| | | :options="getValueOptions(child.valueSpecification)" |
| | | placeholder="è¯·éæ©" |
| | | /> |
| | | <Input |
| | | v-else-if="child.valueType === MesQcResultValueType.FILE" |
| | | v-model:value="measure.value" |
| | | class="!w-48" |
| | | placeholder="请è¾å
¥æä»¶å°å" |
| | | /> |
| | | <Input |
| | | v-else |
| | | v-model:value="measure.value" |
| | | class="!w-48" |
| | | placeholder="请è¾å
¥" |
| | | /> |
| | | <Input |
| | | v-model:value="measure.remark" |
| | | class="flex-1" |
| | | placeholder="夿³¨" |
| | | /> |
| | | <Button |
| | | size="small" |
| | | type="text" |
| | | danger |
| | | :disabled="child.measures.length <= 1" |
| | | @click="removeMeasure(child, mi)" |
| | | > |
| | | å é¤ |
| | | </Button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 顶级å½å
¥é¡¹ --> |
| | | <div v-else class="mb-3"> |
| | | <div class="mb-1 flex items-center justify-between"> |
| | | <span class="font-medium"> |
| | | {{ node.indicatorName }} |
| | | <span v-if="node.unitText" class="text-xs text-gray-500"> |
| | | ï¼{{ node.unitText }}ï¼ |
| | | </span> |
| | | </span> |
| | | <Button size="small" type="link" @click="addMeasure(node)"> |
| | | + æµéæ¹æ¬¡ |
| | | </Button> |
| | | </div> |
| | | <div |
| | | v-for="(measure, mi) in node.measures" |
| | | :key="mi" |
| | | class="mb-1 flex items-center gap-2" |
| | | > |
| | | <span class="w-16 shrink-0 text-right text-xs text-gray-500"> |
| | | 第 {{ measure.measureNo }} 次 |
| | | </span> |
| | | <InputNumber |
| | | v-if="node.valueType === MesQcResultValueType.FLOAT || node.valueType === MesQcResultValueType.INTEGER" |
| | | :value="bindMeasure(node, measure)" |
| | | :precision="node.valueType === MesQcResultValueType.FLOAT ? 4 : 0" |
| | | class="!w-48" |
| | | placeholder="请è¾å
¥" |
| | | @update:value="(v) => onMeasureInput(node, measure, v)" |
| | | /> |
| | | <Textarea |
| | | v-else-if="node.valueType === MesQcResultValueType.TEXT" |
| | | v-model:value="measure.value" |
| | | :rows="1" |
| | | class="!w-48" |
| | | placeholder="请è¾å
¥æ£æµå¼" |
| | | /> |
| | | <Select |
| | | v-else-if="node.valueType === MesQcResultValueType.DICT" |
| | | v-model:value="measure.value" |
| | | allow-clear |
| | | class="!w-48" |
| | | :options="getValueOptions(node.valueSpecification)" |
| | | placeholder="è¯·éæ©" |
| | | /> |
| | | <Input |
| | | v-else-if="node.valueType === MesQcResultValueType.FILE" |
| | | v-model:value="measure.value" |
| | | class="!w-48" |
| | | placeholder="请è¾å
¥æä»¶å°å" |
| | | /> |
| | | <Input |
| | | v-else |
| | | v-model:value="measure.value" |
| | | class="!w-48" |
| | | placeholder="请è¾å
¥" |
| | | /> |
| | | <Input |
| | | v-model:value="measure.remark" |
| | | class="flex-1" |
| | | placeholder="夿³¨" |
| | | /> |
| | | <Button |
| | | size="small" |
| | | type="text" |
| | | danger |
| | | :disabled="node.measures.length <= 1" |
| | | @click="removeMeasure(node, mi)" |
| | | > |
| | | å é¤ |
| | | </Button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </div> |
| | | </div> |
| | | </Modal> |
| | | </template> |
| | | |
| | | <style scoped> |
| | | .qc-result-tree { |
| | | max-height: 60vh; |
| | | overflow-y: auto; |
| | | } |
| | | </style> |
| | |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'samplingLocation', |
| | | label: 'éæ ·å°ç¹', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 100, |
| | | placeholder: '请è¾å
¥éæ ·å°ç¹', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'certificateNo', |
| | | label: 'è¯ä¹¦ç¼å·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 50, |
| | | placeholder: '请è¾å
¥è¯ä¹¦ç¼å·', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'executeStandard', |
| | | label: 'æ§è¡æ å', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 50, |
| | | placeholder: 'å¦ GB/T 6027ï¼éæ©è´¨æ£æ¹æ¡åèªå¨å¸¦å
¥', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'auditUserId', |
| | | label: '夿 ¸äºº', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | allowClear: true, |
| | | api: getSimpleUserList, |
| | | labelField: 'nickname', |
| | | placeholder: 'è¯·éæ©å¤æ ¸äºº', |
| | | valueField: 'id', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'approveUserId', |
| | | label: 'å®¡æ ¸äºº', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | allowClear: true, |
| | | api: getSimpleUserList, |
| | | labelField: 'nickname', |
| | | placeholder: 'è¯·éæ©å®¡æ ¸äºº', |
| | | valueField: 'id', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'checkResult', |
| | | label: 'æ£æµç»æ', |
| | | component: 'Select', |
| | |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesQcIpqcApi } from '#/api/mes/qc/ipqc'; |
| | | |
| | | import { ref } from 'vue'; |
| | | |
| | | import { Page, useVbenModal } from '@vben/common-ui'; |
| | | import { MesQcStatusEnum } from '@vben/constants'; |
| | | import { MesQcStatusEnum, MesQcTypeEnum } from '@vben/constants'; |
| | | |
| | | import { Button, message } from 'ant-design-vue'; |
| | | |
| | |
| | | import { deleteIpqc, exportIpqc, getIpqcPage } from '#/api/mes/qc/ipqc'; |
| | | import { $t } from '#/locales'; |
| | | import QcExportRangeModal from '#/views/mes/qc/components/export-range-modal.vue'; |
| | | import QcReportPrint from '#/views/mes/qc/components/qc-report-print.vue'; |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const printRef = ref<InstanceType<typeof QcReportPrint> | null>(null); |
| | | |
| | | /** å·æ°è¡¨æ ¼ */ |
| | | function handleRefresh() { |
| | | gridApi.query(); |
| | | } |
| | | |
| | | /** æå°æ£éªæ¥å */ |
| | | async function handlePrint(row: MesQcIpqcApi.Ipqc) { |
| | | await printRef.value?.print(row.id!, MesQcTypeEnum.IPQC); |
| | | } |
| | | |
| | | /** å建è¿ç¨æ£éªå */ |
| | |
| | | <Page auto-content-height> |
| | | <FormModal @success="handleRefresh" /> |
| | | <ExportRangeModal /> |
| | | <QcReportPrint ref="printRef" /> |
| | | <Grid table-title="è¿ç¨æ£éªåå表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'æå°æ¥å', |
| | | type: 'link', |
| | | icon: 'ant-design:printer-outlined', |
| | | auth: ['mes:qc-ipqc:query'], |
| | | onClick: handlePrint.bind(null, row), |
| | | }, |
| | | { |
| | | label: $t('common.detail'), |
| | | type: 'link', |
| | | icon: ACTION_ICON.VIEW, |
| | |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'samplingLocation', |
| | | label: 'éæ ·å°ç¹', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 100, |
| | | placeholder: '请è¾å
¥éæ ·å°ç¹', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'certificateNo', |
| | | label: 'è¯ä¹¦ç¼å·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 50, |
| | | placeholder: '请è¾å
¥è¯ä¹¦ç¼å·', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'executeStandard', |
| | | label: 'æ§è¡æ å', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 50, |
| | | placeholder: 'å¦ GB/T 6027ï¼éæ©è´¨æ£æ¹æ¡åèªå¨å¸¦å
¥', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'auditUserId', |
| | | label: '夿 ¸äºº', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | allowClear: true, |
| | | api: getSimpleUserList, |
| | | labelField: 'nickname', |
| | | placeholder: 'è¯·éæ©å¤æ ¸äºº', |
| | | valueField: 'id', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'approveUserId', |
| | | label: 'å®¡æ ¸äºº', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | allowClear: true, |
| | | api: getSimpleUserList, |
| | | labelField: 'nickname', |
| | | placeholder: 'è¯·éæ©å®¡æ ¸äºº', |
| | | valueField: 'id', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'checkResult', |
| | | label: 'æ£æµç»æ', |
| | | component: 'Select', |
| | |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesQcIqcApi } from '#/api/mes/qc/iqc'; |
| | | |
| | | import { onMounted } from 'vue'; |
| | | import { onMounted, ref } from 'vue'; |
| | | import { useRoute } from 'vue-router'; |
| | | |
| | | import { Page, useVbenModal } from '@vben/common-ui'; |
| | | import { MesQcStatusEnum } from '@vben/constants'; |
| | | import { MesQcStatusEnum, MesQcTypeEnum } from '@vben/constants'; |
| | | |
| | | import { Button, message } from 'ant-design-vue'; |
| | | |
| | |
| | | import { deleteIqc, exportIqc, getIqcPage } from '#/api/mes/qc/iqc'; |
| | | import { $t } from '#/locales'; |
| | | import QcExportRangeModal from '#/views/mes/qc/components/export-range-modal.vue'; |
| | | import QcReportPrint from '#/views/mes/qc/components/qc-report-print.vue'; |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | |
| | | defineOptions({ name: 'MesQcIqc' }); |
| | | |
| | | const route = useRoute(); |
| | | const printRef = ref<InstanceType<typeof QcReportPrint> | null>(null); |
| | | |
| | | const [FormModal, formModalApi] = useVbenModal({ |
| | | connectedComponent: Form, |
| | |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | /** æå°æ£éªæ¥å */ |
| | | async function handlePrint(row: MesQcIqcApi.Iqc) { |
| | | await printRef.value?.print(row.id!, MesQcTypeEnum.IQC); |
| | | } |
| | | |
| | | /** 导åºè¡¨æ ¼ï¼å¼¹çªéæ£éªæ¶é´èå´ï¼ */ |
| | |
| | | <Page auto-content-height> |
| | | <FormModal @success="handleRefresh" /> |
| | | <ExportRangeModal /> |
| | | <QcReportPrint ref="printRef" /> |
| | | <Grid table-title="æ¥ææ£éªåå表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'æå°æ¥å', |
| | | type: 'link', |
| | | icon: 'ant-design:printer-outlined', |
| | | auth: ['mes:qc-iqc:query'], |
| | | onClick: handlePrint.bind(null, row), |
| | | }, |
| | | { |
| | | label: $t('common.detail'), |
| | | type: 'link', |
| | | icon: ACTION_ICON.VIEW, |
| | |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'samplingLocation', |
| | | label: 'éæ ·å°ç¹', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 100, |
| | | placeholder: '请è¾å
¥éæ ·å°ç¹', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'certificateNo', |
| | | label: 'è¯ä¹¦ç¼å·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 50, |
| | | placeholder: '请è¾å
¥è¯ä¹¦ç¼å·', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'executeStandard', |
| | | label: 'æ§è¡æ å', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 50, |
| | | placeholder: 'å¦ GB/T 6027ï¼éæ©è´¨æ£æ¹æ¡åèªå¨å¸¦å
¥', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'auditUserId', |
| | | label: '夿 ¸äºº', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | allowClear: true, |
| | | api: getSimpleUserList, |
| | | labelField: 'nickname', |
| | | placeholder: 'è¯·éæ©å¤æ ¸äºº', |
| | | valueField: 'id', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'approveUserId', |
| | | label: 'å®¡æ ¸äºº', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | allowClear: true, |
| | | api: getSimpleUserList, |
| | | labelField: 'nickname', |
| | | placeholder: 'è¯·éæ©å®¡æ ¸äºº', |
| | | valueField: 'id', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'checkResult', |
| | | label: 'æ£æµç»æ', |
| | | component: 'Select', |
| | |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesQcOqcApi } from '#/api/mes/qc/oqc'; |
| | | |
| | | import { ref } from 'vue'; |
| | | |
| | | import { Page, useVbenModal } from '@vben/common-ui'; |
| | | import { MesQcStatusEnum } from '@vben/constants'; |
| | | import { MesQcStatusEnum, MesQcTypeEnum } from '@vben/constants'; |
| | | |
| | | import { Button, message } from 'ant-design-vue'; |
| | | |
| | |
| | | import { deleteOqc, exportOqc, getOqcPage } from '#/api/mes/qc/oqc'; |
| | | import { $t } from '#/locales'; |
| | | import QcExportRangeModal from '#/views/mes/qc/components/export-range-modal.vue'; |
| | | import QcReportPrint from '#/views/mes/qc/components/qc-report-print.vue'; |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const printRef = ref<InstanceType<typeof QcReportPrint> | null>(null); |
| | | |
| | | /** å·æ°è¡¨æ ¼ */ |
| | | function handleRefresh() { |
| | | gridApi.query(); |
| | | } |
| | | |
| | | /** æå°æ£éªæ¥å */ |
| | | async function handlePrint(row: MesQcOqcApi.Oqc) { |
| | | await printRef.value?.print(row.id!, MesQcTypeEnum.OQC); |
| | | } |
| | | |
| | | /** å建åºè´§æ£éªå */ |
| | |
| | | <Page auto-content-height> |
| | | <FormModal @success="handleRefresh" /> |
| | | <ExportRangeModal /> |
| | | <QcReportPrint ref="printRef" /> |
| | | <Grid table-title="åºè´§æ£éªåå表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'æå°æ¥å', |
| | | type: 'link', |
| | | icon: 'ant-design:printer-outlined', |
| | | auth: ['mes:qc-oqc:query'], |
| | | onClick: handlePrint.bind(null, row), |
| | | }, |
| | | { |
| | | label: $t('common.detail'), |
| | | type: 'link', |
| | | icon: ACTION_ICON.VIEW, |
| | |
| | | rules: 'selectRequired', |
| | | }, |
| | | { |
| | | fieldName: 'samplingLocation', |
| | | label: 'éæ ·å°ç¹', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 100, |
| | | placeholder: '请è¾å
¥éæ ·å°ç¹', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'certificateNo', |
| | | label: 'è¯ä¹¦ç¼å·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 50, |
| | | placeholder: '请è¾å
¥è¯ä¹¦ç¼å·', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'executeStandard', |
| | | label: 'æ§è¡æ å', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 50, |
| | | placeholder: 'å¦ GB/T 6027ï¼éæ©è´¨æ£æ¹æ¡åèªå¨å¸¦å
¥', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'auditUserId', |
| | | label: '夿 ¸äºº', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | allowClear: true, |
| | | api: getSimpleUserList, |
| | | labelField: 'nickname', |
| | | placeholder: 'è¯·éæ©å¤æ ¸äºº', |
| | | valueField: 'id', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'approveUserId', |
| | | label: 'å®¡æ ¸äºº', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | allowClear: true, |
| | | api: getSimpleUserList, |
| | | labelField: 'nickname', |
| | | placeholder: 'è¯·éæ©å®¡æ ¸äºº', |
| | | valueField: 'id', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'checkResult', |
| | | label: 'æ£æµç»æ', |
| | | component: 'Select', |
| | |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesQcRqcApi } from '#/api/mes/qc/rqc'; |
| | | |
| | | import { ref } from 'vue'; |
| | | |
| | | import { Page, useVbenModal } from '@vben/common-ui'; |
| | | import { MesQcStatusEnum } from '@vben/constants'; |
| | | import { MesQcStatusEnum, MesQcTypeEnum } from '@vben/constants'; |
| | | |
| | | import { Button, message } from 'ant-design-vue'; |
| | | |
| | |
| | | import { deleteRqc, exportRqc, getRqcPage } from '#/api/mes/qc/rqc'; |
| | | import { $t } from '#/locales'; |
| | | import QcExportRangeModal from '#/views/mes/qc/components/export-range-modal.vue'; |
| | | import QcReportPrint from '#/views/mes/qc/components/qc-report-print.vue'; |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const printRef = ref<InstanceType<typeof QcReportPrint> | null>(null); |
| | | |
| | | /** å·æ°è¡¨æ ¼ */ |
| | | function handleRefresh() { |
| | | gridApi.query(); |
| | | } |
| | | |
| | | /** æå°æ£éªæ¥å */ |
| | | async function handlePrint(row: MesQcRqcApi.Rqc) { |
| | | await printRef.value?.print(row.id!, MesQcTypeEnum.RQC); |
| | | } |
| | | |
| | | /** å建éè´§æ£éªå */ |
| | |
| | | <Page auto-content-height> |
| | | <FormModal @success="handleRefresh" /> |
| | | <ExportRangeModal /> |
| | | <QcReportPrint ref="printRef" /> |
| | | <Grid table-title="éè´§æ£éªåå表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'æå°æ¥å', |
| | | type: 'link', |
| | | icon: 'ant-design:printer-outlined', |
| | | auth: ['mes:qc-rqc:query'], |
| | | onClick: handlePrint.bind(null, row), |
| | | }, |
| | | { |
| | | label: $t('common.detail'), |
| | | type: 'link', |
| | | icon: ACTION_ICON.VIEW, |
| | |
| | | rules: z.array(z.number()).min(1, 'æ£æµç§ç±»ä¸è½ä¸ºç©º'), |
| | | }, |
| | | { |
| | | fieldName: 'defaultExecuteStandard', |
| | | label: 'é»è®¤æ§è¡æ å', |
| | | component: 'Input', |
| | | componentProps: { |
| | | maxlength: 50, |
| | | placeholder: 'å¦ GB/T 6027ï¼æ°å»ºæ£éªåéæ©æ¬æ¹æ¡åèªå¨å¸¦å
¥æ§è¡æ å', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'remark', |
| | | label: '夿³¨', |
| | | component: 'Textarea', |
| | |
| | | width: 100, |
| | | }, |
| | | { |
| | | field: 'sortOrder', |
| | | title: 'æåºå·', |
| | | width: 80, |
| | | }, |
| | | { |
| | | field: 'judgeFlag', |
| | | title: 'åä¸å¤å®', |
| | | width: 90, |
| | | slots: { default: 'judgeFlag' }, |
| | | }, |
| | | { |
| | | title: 'æä½', |
| | | width: 130, |
| | | fixed: 'right', |
| | |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'sortOrder', |
| | | label: 'æåºå·', |
| | | component: 'InputNumber', |
| | | defaultValue: 0, |
| | | componentProps: { |
| | | class: '!w-full', |
| | | min: 0, |
| | | precision: 0, |
| | | placeholder: 'æ¹æ¡å
å±ç¤ºé¡ºåºï¼å°çå¨å', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'judgeFlag', |
| | | label: 'åä¸å¤å®', |
| | | component: 'Switch', |
| | | defaultValue: true, |
| | | componentProps: { |
| | | checkedChildren: 'æ¯', |
| | | unCheckedChildren: 'å¦', |
| | | }, |
| | | help: 'åç»è¡/ä¸é´åæ°è¡è®¾ä¸ºå¦ï¼ä»
æç»ç»æé¡¹åä¸åæ ¼å¤å®æç¤º', |
| | | }, |
| | | { |
| | | fieldName: 'remark', |
| | | label: '夿³¨', |
| | | component: 'Textarea', |
| | |
| | | |
| | | import { useVbenModal } from '@vben/common-ui'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | import { message, Switch } from 'ant-design-vue'; |
| | | |
| | | import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { |
| | | deleteTemplateIndicator, |
| | | getTemplateIndicatorPage, |
| | | updateTemplateIndicator, |
| | | } from '#/api/mes/qc/template/indicator'; |
| | | import { $t } from '#/locales'; |
| | | |
| | |
| | | /** ç¼è¾ææ 项 */ |
| | | function handleEdit(row: MesQcTemplateIndicatorApi.TemplateIndicator) { |
| | | formModalApi.setData({ ...row, templateId: props.templateId }).open(); |
| | | } |
| | | |
| | | /** 忢æ¯å¦åä¸å¤å® */ |
| | | async function handleJudgeFlagChange( |
| | | row: MesQcTemplateIndicatorApi.TemplateIndicator, |
| | | checked: boolean, |
| | | ) { |
| | | await updateTemplateIndicator({ ...row, judgeFlag: checked }); |
| | | message.success(`æ£æµé¡¹[${row.indicatorName}]å·²${checked ? 'åä¸' : 'ä¸åä¸'}å¤å®`); |
| | | handleRefresh(); |
| | | } |
| | | |
| | | /** å 餿æ 项 */ |
| | |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #judgeFlag="{ row }"> |
| | | <Switch |
| | | :checked="row.judgeFlag !== false" |
| | | :disabled="readonly" |
| | | checked-children="æ¯" |
| | | un-checked-children="å¦" |
| | | @change=" |
| | | (checked: boolean) => handleJudgeFlagChange(row, checked) |
| | | " |
| | | /> |
| | | </template> |
| | | <template #actions="{ row }"> |
| | | <TableAction |
| | | :actions="[ |