diff --git a/.gitignore b/.gitignore index ef30b45..478ee37 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ AGENTS.md *.njsproj *.sln *.sw? +/src/views/biz/tool/usage.vue diff --git a/src/api/AssingWorkDetail.ts b/src/api/AssingWorkDetail.ts index 1ec912c..81c4598 100644 --- a/src/api/AssingWorkDetail.ts +++ b/src/api/AssingWorkDetail.ts @@ -72,10 +72,11 @@ export const assingWorkDetailApi = { //根据派工id获取详情信息 - selectAssingWorkDetailListByAssingWorkId(assingWorkId:number) { + selectAssingWorkDetailListByAssingWorkId(params:{page?:number;pageSize?:number;assingWorkId?:number}) { return request({ - url:`/biz/assingWorkDetail/getAssingWorkDetailList/${assingWorkId}`, - method:"get" + url:`/biz/assingWorkDetail/getAssingWorkDetailList`, + method:"get", + params }) } } \ No newline at end of file diff --git a/src/api/basicProcessPlan.ts b/src/api/basicProcessPlan.ts index 03ae68f..5a8cc78 100644 --- a/src/api/basicProcessPlan.ts +++ b/src/api/basicProcessPlan.ts @@ -22,6 +22,14 @@ export interface BasicProcessPlan { departmentName?: string + sectionId?: number | null + + workShopId?: number | null + + sectionName?: string + + workShopName?: string + operDescription?: string createBy?: number diff --git a/src/api/device.ts b/src/api/device.ts index 7324e36..ba220eb 100644 --- a/src/api/device.ts +++ b/src/api/device.ts @@ -31,15 +31,51 @@ export interface DeviceRealtimeVO { displayName: string synEquipId: number bound: boolean + /** connected:机台是否在线 */ connected?: number | null + /** cnc_status:控制器状态 */ cncStatus?: number | null cncStatusText?: string + /** part_count:目前工件数 */ partCount?: number | null + /** part_count_required:需求工件数 */ + partCountRequired?: number | null + /** main_program:各轴群的当前加工号码 */ mainProgram?: string | null + /** feedrate_act:轴群的实际进给速率 */ + feedrateAct?: number | null + /** feedrate_override:轴群的实际进给倍率 */ + feedrateOverride?: number | null + /** speed_act:轴群的加工主轴转速 */ + speedAct?: number | null + /** speed_cmd:轴群的加工主轴转速命令 */ + speedCmd?: number | null + /** load:轴群的加工主轴负载率 */ + load?: number | null + /** speed_override:轴群的加工主轴速度百分比 */ + speedOverride?: number | null + /** tool_id:各轴群的加工主轴刀号 */ + toolId?: string | null + /** torque_load:轴向负载率 */ + torqueLoad?: number | null + /** span_cutting_cycle:单件加工时间 */ + spanCuttingCycle?: number | null + /** span_cutting_acc:累计加工时间 */ + spanCuttingAcc?: number | null + /** span_power_on_acc:累计开机时间 */ + spanPowerOnAcc?: number | null + /** span_cutting_install:安装累计加工时间 */ + spanCuttingInstall?: number | null + /** span_power_on:开机时间 */ + spanPowerOn?: number | null + /** alarm_current:警报相关 */ alarmCount?: number alarmMessages?: string[] dataTimestamp?: number + sectionId?: number | null sectionName?: string + workshopId?: number | null + workshopName?: string } diff --git a/src/api/maintenanceRecord.ts b/src/api/maintenanceRecord.ts index 3218c32..bf2fb57 100644 --- a/src/api/maintenanceRecord.ts +++ b/src/api/maintenanceRecord.ts @@ -14,15 +14,15 @@ export interface MaintenanceRecord { executorId?: number - startTime?: string + startTime?: string | number - endTime?: string + endTime?: string | number recordStatus?: string - createTime?: string + createTime?: string | number - updateTime?: string + updateTime?: string | number } diff --git a/src/api/nccode.ts b/src/api/nccode.ts index abf99da..c3778df 100644 --- a/src/api/nccode.ts +++ b/src/api/nccode.ts @@ -101,3 +101,11 @@ export function exportNccode(params:any) { params }) } + +//加载全部NC代码 +export function loadAllNcCode() { + return request({ + url: `biz/ncCode/loadAllNcCode`, + method: 'get' + }) +} diff --git a/src/api/orderItem.ts b/src/api/orderItem.ts index 0fa130b..65eb887 100644 --- a/src/api/orderItem.ts +++ b/src/api/orderItem.ts @@ -52,6 +52,9 @@ export interface OrderItem { routeCode?: string workshopId?: number | null + + /** 开工后关联的执行侧 mes_order_item.id */ + orderItemId?: number | null } export interface KingdeePrdMo { @@ -131,8 +134,8 @@ export const orderItemApi = { return request({ url: `/biz/orderItem/${id}/startWork`, method: 'post' }) }, - /** 按工艺路线编码查询工艺路线(含工序);可带 orderItemId 精确匹配 */ - getRoute(params: { routeCode?: string; orderItemId?: number | string }) { + /** 按工艺路线编码查询;orderItemId/planId 均为计划订单 id(mes_order_item_plan.id) */ + getRoute(params: { routeCode?: string; orderItemId?: number | string; planId?: number | string }) { return request({ url: '/biz/orderItem/route', method: 'get', params }) }, //根据生产编号查询预生产订单 diff --git a/src/api/orderProcessPlan.ts b/src/api/orderProcessPlan.ts index f62c023..ec1f2ec 100644 --- a/src/api/orderProcessPlan.ts +++ b/src/api/orderProcessPlan.ts @@ -70,6 +70,9 @@ export interface ProcessPlanItemVO { workOrderCode?: string + /** 拆单来源工序计划ID */ + splitFromId?: number | null + processCode?: string operNumber?: number @@ -150,6 +153,9 @@ export interface OrderProcessPlanVO { orderItemId?: number + /** 工单号(列表按工单分组) */ + workOrderCode?: string + mainCode?: string materialCode?: string @@ -290,7 +296,7 @@ export function toOrderProcessPlanPayload(data: Record): OrderP const displayKeys = [ - 'mainCode', 'materialCode', 'materialName', 'orderCode', 'routeCode', 'workshopName', + 'mainCode', 'materialCode', 'materialName', 'orderCode', 'routeCode', 'workshopName', 'workOrderCode', 'actualStartTime', 'actualEndTime', 'completedQty', 'orderStatus', 'currentProcessName', @@ -302,7 +308,7 @@ export function toOrderProcessPlanPayload(data: Record): OrderP 'transferOutQty', 'scrapQty', 'reworkQty', 'assign', 'assignByName', 'assignTime', - 'processStatus', 'prevPlanId', 'nextPlanId', 'assignWorkList', + 'processStatus', 'prevPlanId', 'nextPlanId', 'assignWorkList', 'splitFromId', ] @@ -354,9 +360,9 @@ export const orderProcessPlanApi = { - // 获取详情(路径参数为生产订单 id) + // 获取详情(路径参数为生产订单 id;可选 workOrderCode 隔离拆单工单) - detail(orderItemId: number | string) { + detail(orderItemId: number | string, workOrderCode?: string) { return request({ @@ -364,6 +370,8 @@ export const orderProcessPlanApi = { method: 'get', + params: workOrderCode ? { workOrderCode } : undefined, + }) }, @@ -493,6 +501,81 @@ export const orderProcessPlanApi = { }) }, + /** 工序工单拆单预览 */ + splitPreview(planId: number | string) { + return request({ + url: `/biz/orderProcessPlan/split/preview/${planId}`, + method: 'get', + }) + }, + + /** 工序工单拆单 */ + split(data: ProcessPlanSplitPayload) { + return request({ + url: '/biz/orderProcessPlan/split', + method: 'post', + data, + }) + }, + +} + +/** 拆单预览 */ +export interface ProcessPlanSplitPreview { + planId?: number + workOrderCode?: string + orderItemId?: number + orderItemName?: string + /** 物料编码,用于查金蝶工艺路线 */ + materialCode?: string + processCount?: number + processNames?: string[] + /** 工单计划数量 */ + quantity?: number + /** 已进入生产数量(不可拆)= MAX(各工序投入) */ + investedQty?: number + /** 可拆 = 计划 − 已进入生产数量 */ + splittableQty?: number + canSplit?: boolean + reason?: string | null +} + +/** 拆单请求:quantities[0]=原单保留(≥不可拆),其余=新工单;新工艺二选一 */ +export interface ProcessPlanSplitPayload { + planId: number + quantities: number[] + /** kingdee=金蝶工艺路线;assemble=工序表组装 */ + routeMode: 'kingdee' | 'assemble' + /** routeMode=kingdee:金蝶工艺路线编码 FNumber */ + routingNo?: string | null + /** routeMode=assemble:完整工序明细(推荐) */ + assembleSteps?: ProcessPlanSplitStep[] + /** 兼容旧版:仅工序 id */ + processIds?: number[] +} + +/** 拆单组装工序行(对齐金蝶工艺路线主要字段) */ +export interface ProcessPlanSplitStep { + processId?: number | null + operNumber?: number | null + processCode?: string | null + processName?: string | null + operDescription?: string | null + sectionId?: number | null + workshopId?: number | null + activityUnit?: string | null + optCtrlCodeName?: string | null + activityQty?: number | null + qualityInspection?: number | null + storageEntry?: number | null + procurement?: number | null + isOutsource?: number | null +} + +/** 拆单结果 */ +export interface ProcessPlanSplitResult { + source?: ProcessPlanItemVO + created?: ProcessPlanItemVO[] } /** 委外可选工序项 */ diff --git a/src/api/permissionConfig.ts b/src/api/permissionConfig.ts new file mode 100644 index 0000000..c38cc5a --- /dev/null +++ b/src/api/permissionConfig.ts @@ -0,0 +1,72 @@ +import { request } from '@/utils/request' + +// 数据权限配置 类型定义 +export interface PermissionConfig { + id?: number + + mapperKey?: string + + controlMethod?: string + + permissionControl?: string + +} + +// 数据权限配置 API +export const permissionConfigApi = { + // 分页查询 + page(params: { page: number; pageSize: number; mapperKey?: string; controlMethod?: string }) { + return request({ url: '/biz/permissionConfig/page', method: 'get', params }) + }, + + // 新增 + options() { + return request({ url: '/biz/permissionConfig/options', method: 'get' }) + }, + + // 获取详情 + detail(id: string) { + return request({ url: `/biz/permissionConfig/${id}`, method: 'get' }) + }, + + // 新增 + create(data: PermissionConfig) { + return request({ url: '/biz/permissionConfig', method: 'post', data }) + }, + + // 修改 + update(data: PermissionConfig) { + return request({ url: '/biz/permissionConfig', method: 'put', data }) + }, + + // 删除 + delete(ids: string[]) { + return request({ url: `/biz/permissionConfig/${ids.join(',')}`, method: 'delete' }) + }, + + // 导出 + export(params?: { ids?: string[]; mapperKey?: string; controlMethod?: string }) { + const p: Record = {} + if (params?.ids?.length) p.ids = params.ids.join(',') + if (params?.mapperKey !== undefined && params?.mapperKey !== null) p.mapperKey = params.mapperKey + if (params?.controlMethod !== undefined && params?.controlMethod !== null) p.controlMethod = params.controlMethod + return request({ url: `/biz/permissionConfig/export`, method: 'get', params: p, responseType: 'blob' }) + }, + + // 导入 + importData(file: File) { + const formData = new FormData() + formData.append('file', file) + return request<{ success: number; fail: number; errors: string[] }>({ + url: `/biz/permissionConfig/import`, + method: 'post', + data: formData, + headers: { 'Content-Type': 'multipart/form-data' } + }) + }, + + // 下载导入模板 + downloadTemplate() { + return request({ url: `/biz/permissionConfig/template`, method: 'get', responseType: 'blob' }) + } +} diff --git a/src/api/processRoute.ts b/src/api/processRoute.ts index 1cd883a..74d27c7 100644 --- a/src/api/processRoute.ts +++ b/src/api/processRoute.ts @@ -88,5 +88,43 @@ export const processRouteApi = { // 下载导入模板 downloadTemplate() { return request({ url: `/biz/processRoute/template`, method: 'get', responseType: 'blob' }) - } + }, + + /** 按物料编码查询金蝶工艺路线选项(含工艺路线编码) */ + kingdeeSelect(materialCode: string) { + return request({ + url: '/biz/processRoute/kingdee/select', + method: 'get', + params: { materialCode }, + }) + }, +} + +/** 金蝶工艺路线下拉选项 */ +export interface ProcessRouteSelectOption { + routingNo?: string + materialCode?: string + materialName?: string + stepCount?: number + processNames?: string[] + /** 工序明细 */ + steps?: KingdeeProcessRouteStep[] +} + +/** 金蝶工艺路线工序行 */ +export interface KingdeeProcessRouteStep { + routingNo?: string + materialCode?: string + materialName?: string + operNumber?: number + processCode?: string + processName?: string + operDescription?: string + workCenterName?: string + departmentName?: string + optCtrlCodeName?: string + activityUnit?: string + activityQty?: number + qualityInspection?: number + storageEntry?: number } diff --git a/src/api/qualityTesting.ts b/src/api/qualityTesting.ts index 54df286..cd7f07d 100644 --- a/src/api/qualityTesting.ts +++ b/src/api/qualityTesting.ts @@ -106,7 +106,7 @@ export const qualityTestingApi = { }, //加载质检单 - loadQualityTestingList(assingId:number) { - return request({url:`/mes/qc/loadQualityTestingList/${assingId}`,method:'get'}) + loadQualityTestingList(params:{page?:number,pageSize?:number,assingId?:number}) { + return request({url:`/mes/qc/loadQualityTestingList`,method:'get', params}) } } \ No newline at end of file diff --git a/src/api/submitLog.ts b/src/api/submitLog.ts index 97f7962..80f2d8d 100644 --- a/src/api/submitLog.ts +++ b/src/api/submitLog.ts @@ -99,7 +99,8 @@ export const submitLogApi = { }, //加载汇报列表 - loadSumbitLog(assingId?:number){ - return request({url:`/mes/report/loadSumbitLog/${assingId}`,method:'get'}) + loadSumbitLog(params:{assingId:number,page?:number,pageSize?:number}){ + console.log(params) + return request({url:`/mes/report/loadSumbitLog`,method:'get',params}) } } diff --git a/src/router/index.ts b/src/router/index.ts index 8143e1e..8347676 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -201,7 +201,27 @@ const routes: RouteRecordRaw[] = [ component: () => import('@/views/test/test/index.vue'), meta: { title: '测试菜单', icon: 'StarOutline' } }, + // 设备维修保养记录 + { + path: 'biz/maintenanceRecord', + name: 'MaintenanceRecord', + component: () => import('@/views/biz/maintenanceRecord/index.vue'), + meta: { title: '设备维修保养记录', icon: 'BuildOutline' } + }, + // 设备状态监控(独立页) + { + path: 'biz/device/board', + name: 'deviceRealtimeBoard', + component: () => import('@/views/biz/device/board.vue'), + meta: { title: '设备状态监控', icon: 'PulseOutline' } + }, // 开发工具 + { + path: 'biz/permissionConfig', + name: 'permissionConfig', + component: () => import('@/views/biz/permissionConfig/index.vue'), + meta: { title: '数据权限配置', icon: 'ListOutline' } + }, { path: 'tool/gen', name: 'ToolGen', @@ -390,4 +410,4 @@ router.beforeEach(async (to, _from, next) => { }) -export default router \ No newline at end of file +export default router diff --git a/src/views/biz/device/DeviceAbnomarlRecord.vue b/src/views/biz/device/DeviceAbnomarlRecord.vue index 206b6c0..3aa97e0 100644 --- a/src/views/biz/device/DeviceAbnomarlRecord.vue +++ b/src/views/biz/device/DeviceAbnomarlRecord.vue @@ -35,8 +35,12 @@ value: '2' }, { - label: '其他异常', + label: '设备异常', value: '3' + }, + { + label: '其他异常', + value: '4' } ] @@ -170,16 +174,11 @@ - - - - - - + diff --git a/src/views/biz/device/board.vue b/src/views/biz/device/board.vue index 13ea600..b40db81 100644 --- a/src/views/biz/device/board.vue +++ b/src/views/biz/device/board.vue @@ -1,26 +1,31 @@ diff --git a/src/views/biz/device/index.vue b/src/views/biz/device/index.vue index ff7a71a..ef9804e 100644 --- a/src/views/biz/device/index.vue +++ b/src/views/biz/device/index.vue @@ -379,7 +379,13 @@ const columns: DataTableColumns = [ title: '新代ID', key: 'synEquipId', width: 90, render: (row) => row.synEquipId ?? '-' }, - {title: '设备类型', key: 'deviceType'}, + {title: '设备类型', key: 'deviceTypeId', + render: (row) =>{ + let val = row.deviceTypeId + const opt = deviceTypeList.value.find(o => o.value === val || String(o.value) === String(val)) + return h(NTag, {type: opt.class, size: 'small'}, {default: () => opt.label}) + } + }, {title: '设备负责人', key: 'deviceManagerName'}, {title: '所属工段', key: 'sectionName'}, {title: '设备型号', key: 'spec'}, diff --git a/src/views/biz/maintenanceRecord/index.vue b/src/views/biz/maintenanceRecord/index.vue index 75f3095..c1fa9c8 100644 --- a/src/views/biz/maintenanceRecord/index.vue +++ b/src/views/biz/maintenanceRecord/index.vue @@ -50,7 +50,7 @@ :data="tableData" :loading="loading" :pagination="pagination" - :row-key="(row) => row.recordId" + :row-key="(row: MaintenanceRecord) => row.recordId" :scroll-x="1200" @update:page="handlePageChange" @update:page-size="handlePageSizeChange" @@ -59,31 +59,31 @@ - - - - + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + userStore.hasPermission(permission const message = useMessage() const dialog = useDialog() +const splitVisible = ref(false) +const splitPlanId = ref(null) + +/** 列表拆单入口:是否可拆以后端预览为准,这里只做粗过滤 */ +function canSplitProcess(proc: ProcessPlanItemVO) { + const qty = proc.quantity ?? 0 + return qty > 0 +} + +function openSplit(process: ProcessPlanItemVO) { + if (!process.planId) { + message.warning('工序计划无效') + return + } + // 后端按工单号拆整单:任意工序 id 均可定位,拆出工单带全部工序 + splitPlanId.value = process.planId + splitVisible.value = true +} + // 搜索表单 const searchForm = reactive({ id: '', @@ -450,6 +477,7 @@ const orderScrollX = 2090 const processScrollX = 2788 function orderRowKey(row: OrderProcessPlanVO) { + if (row.workOrderCode) return row.workOrderCode return row.orderItemId ?? `order-${row.mainCode}-${row.orderCode}` } @@ -490,7 +518,7 @@ function buildProcessActionColumn(order: OrderProcessPlanVO): DataTableColumns

disphand(row, order), }, { default: () => '派工' })) } + if (hasPermission('biz:orderProcessPlan:edit') && canSplitProcess(row)) { + buttons.push(h(NButton, { + size: 'small', + type: 'info', + ghost: true, + onClick: () => openSplit(row), + }, { default: () => '拆单' })) + } return buttons.length > 0 ? h(NSpace, { justify: 'center' }, { default: () => buttons }) : '-' }, } @@ -602,8 +638,12 @@ const orderColumns: DataTableColumns = [ align: 'center', ellipsis: { tooltip: true }, render: (row) => { - const codes = (row.processList ?? []).map((p) => p.workOrderCode).filter(Boolean) - return codes.length ? codes.join('、') : '-' + if (row.workOrderCode) return row.workOrderCode + const codes = (row.processList ?? []) + .map((p) => p.workOrderCode) + .filter((c): c is string => !!c) + const unique = [...new Set(codes)] + return unique.length ? unique.join('、') : '-' }, }, { title: '数量', key: 'quantity', width: 72, align: 'center' }, diff --git a/src/views/biz/orderProcessPlan/pgitem.vue b/src/views/biz/orderProcessPlan/pgitem.vue index fccf5e9..f06bc41 100644 --- a/src/views/biz/orderProcessPlan/pgitem.vue +++ b/src/views/biz/orderProcessPlan/pgitem.vue @@ -1,195 +1,211 @@ \ No newline at end of file diff --git a/src/views/biz/permissionConfig/index.vue b/src/views/biz/permissionConfig/index.vue new file mode 100644 index 0000000..44a3874 --- /dev/null +++ b/src/views/biz/permissionConfig/index.vue @@ -0,0 +1,452 @@ + + + + + diff --git a/src/views/biz/station/index.vue b/src/views/biz/station/index.vue index d6c4c60..4ece1e6 100644 --- a/src/views/biz/station/index.vue +++ b/src/views/biz/station/index.vue @@ -217,7 +217,6 @@ const columns: DataTableColumns = [ { type: 'selection' }, { title: '工位编码', key: 'deviceCode' }, { title: '工位名称', key: 'deviceName' }, - { title: '工位类型', key: 'deviceType' }, { title: '所属工段', key: 'sectionName' }, { title: '状态', key: 'status', render:(row) =>{ diff --git a/src/views/login/index.vue b/src/views/login/index.vue index b68194a..c553e4c 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -606,7 +606,6 @@ async function doLogin() { if (rememberMeEnabled.value) { loginData.rememberMe = formData.rememberMe } - await userStore.login(loginData) message.success('登录成功') const redirect = route.query.redirect as string diff --git a/src/views/production/componets/AssingWorkTreeTable.vue b/src/views/production/componets/AssingWorkTreeTable.vue index 279040a..144c4e4 100644 --- a/src/views/production/componets/AssingWorkTreeTable.vue +++ b/src/views/production/componets/AssingWorkTreeTable.vue @@ -22,6 +22,7 @@ :max-height="1000" size="small" style="margin-bottom:15px" + @update-expanded-row-keys="handleExpandChange" /> @@ -105,7 +106,7 @@ import { import { mytasks,type AssingWork } from '@/api/production'; import { - NButton, NSpace, NTag, NDataTable, DataTableColumns, NDescriptions, NDescriptionsItem + NButton, NSpace, NTag, NDataTable, DataTableColumns, NDescriptions, NDescriptionsItem, NPagination } from 'naive-ui' import { dictDataApi } from '@/api/org' import { assingWorkDetailApi,AssingWorkDetail } from '@/api/AssingWorkDetail' @@ -360,6 +361,7 @@ const AssingWorkDetailColums:DataTableColumns = [ render(row:any) { const val = row.status const opt = qcAssingWorkDetailStatusOptions.value.find(o => o.value === val || String(o.value) === String(val)) + if (!opt) return val ?? '-' return h(NTag, { type: opt.class, size: 'small' }, { default: () => opt.label }) @@ -449,48 +451,112 @@ function AssingWorkToggleExpandAll() { } // 缓存:key=派工id,value=明细数组 -const expandDataMap = new Map() +interface DetailPageState { + list: AssingWorkDetail[] + page: number + pageSize: number + total: number + loading: boolean +} +// key:父行id +const expandDetailMap = new Map() function renderAssingWorkExpand(row: AssingWork) { - // 1. 首次展开,发起请求 - if (!expandDataMap.has(row.id)) { - expandDataMap.set(row.id, []) - loadingRowIds.value.add(row.id) + const rowId = row.id - // 异步请求,不阻塞当前渲染 - getAssingWorkDetail(row.id).then((detailList) => { - expandDataMap.set(row.id, detailList) - loadingRowIds.value.delete(row.id) - }) + if (!expandDetailMap.has(rowId)) { + expandDetailMap.set(rowId, reactive({ + list: [], + page: 1, + pageSize: 10, + total: 0, + loading: true + })) + loadDetail(rowId) } - // 2. 根据缓存状态渲染 - if (loadingRowIds.value.has(row.id)) { - return h('div', { style: 'padding:12px' }, '加载中...') - } + const state = expandDetailMap.get(rowId)! + console.log(state) + console.log(state.list) + + // 加载中提示 + // if (state.loading) { + // return h('div', {style: 'padding:12px'}, '加载中...') + // } + - const tableData = expandDataMap.get(row.id)! return h('div', { style: 'padding: 0 16px 12px' }, [ h(NDataTable, { columns: AssingWorkDetailColums, - data: tableData, + data: state.list, rowKey: DetailRowKey, size: 'small', bordered: true, striped: true, scrollX: 1360 - }) + }), + // ✅ 复刻你原来的分页容器 + n‑pagination + prefix插槽 + h('div', { + class: 'pagination-container', + style: 'display: flex; justify-content: flex-end; margin-top: 12px' + }, [ + h(NPagination, { + page: state.page, + pageSize: state.pageSize, + itemCount: state.total, + onUpdatePage: (p: number) => handleDetailPageChange(rowId, p), + onUpdatePageSize: (sz: number) => handleDetailPageSizeChange(rowId, sz) + }, { + // ✅ #prefix 插槽 + prefix: () => h('span', `共 ${state.total} 条`) + }) + ]) ]) } +// 分页切换事件,点击页码/每页大小 +async function handleDetailPageChange(rowId: number,page:number) { + const state = expandDetailMap.get(rowId) + if (!state) return + state.page = page + loadDetail(rowId) +} + +async function handleDetailPageSizeChange(rowId: number,pageSize: number) { + const state = expandDetailMap.get(rowId) + if (!state) return + state.pageSize = pageSize + state.page = 1 + loadDetail(rowId) +} + +function handleExpandChange(openKeys: number[]){ + for (const [rowId] of expandDetailMap) { + if (!openKeys.includes(rowId)) { + expandDetailMap.delete(rowId) + } + } +} -async function getAssingWorkDetail(assingWorkId:number) { - const res = await assingWorkDetailApi.selectAssingWorkDetailListByAssingWorkId(assingWorkId) - return res - } +const loadDetail = async (rowId: number)=>{ + const state = expandDetailMap.get(rowId) + if (!state) return + state.loading = true + try { + const res = await assingWorkDetailApi.selectAssingWorkDetailListByAssingWorkId({ + assingWorkId: rowId, + page: state.page, + pageSize: state.pageSize + }) + state.list = res.list + state.total = res.total + }finally { + state.loading = false + } +} // 加载字典选项 async function loadDictOptions() { diff --git a/src/views/production/componets/QualityInfoPage.vue b/src/views/production/componets/QualityInfoPage.vue index 9db9414..2222e83 100644 --- a/src/views/production/componets/QualityInfoPage.vue +++ b/src/views/production/componets/QualityInfoPage.vue @@ -31,12 +31,27 @@ remote :scroll-x="600" /> - +

+ + + +