| | |
| | | packages: ['xgplayer/'] |
| | | }, |
| | | { |
| | | name: 'vendor-element-plus', |
| | | packages: ['element-plus/', '@element-plus/'] |
| | | }, |
| | | { |
| | | name: 'vendor-vue', |
| | | packages: ['vue-router/', 'pinia/', '@vueuse/'] |
| | | // Keep Vue runtime, router/store, vueuse, and Element Plus together. |
| | | // Splitting these into separate chunks can create circular chunk imports |
| | | // after Rollup optimization, which then crashes at runtime with |
| | | // "Cannot access 'x' before initialization". |
| | | name: 'vendor-framework', |
| | | packages: [ |
| | | 'vue/', |
| | | '@vue/', |
| | | 'vue-router/', |
| | | 'pinia/', |
| | | 'vue-demi/', |
| | | '@vueuse/', |
| | | 'element-plus/', |
| | | '@element-plus/', |
| | | '@floating-ui/' |
| | | ] |
| | | }, |
| | | { |
| | | name: 'vendor-utils', |
| | |
| | | return { |
| | | current: params.current || 1, |
| | | pageSize: params.pageSize || params.size || 20, |
| | | orderBy: |
| | | typeof params.orderBy === 'string' && params.orderBy.trim() |
| | | ? params.orderBy.trim() |
| | | : 'create_time desc', |
| | | ...filterParams(params, ['current', 'pageSize', 'size']) |
| | | } |
| | | } |
| | |
| | | return { |
| | | current: params.current || 1, |
| | | pageSize: params.pageSize || params.size || 20, |
| | | orderBy: |
| | | typeof params.orderBy === 'string' && params.orderBy.trim() |
| | | ? params.orderBy.trim() |
| | | : 'create_time desc', |
| | | ...filterParams(params, ['current', 'pageSize', 'size']) |
| | | } |
| | | } |
| | |
| | | |
| | | export function buildTransferSearchParams(params = {}) { |
| | | const result = {} |
| | | ;['condition', 'code', 'orgWareName', 'tarWareName', 'orgAreaName', 'tarAreaName', 'memo', 'timeStart', 'timeEnd'].forEach((key) => { |
| | | ;[ |
| | | 'condition', |
| | | 'code', |
| | | 'orgWareName', |
| | | 'tarWareName', |
| | | 'orgAreaName', |
| | | 'tarAreaName', |
| | | 'memo', |
| | | 'timeStart', |
| | | 'timeEnd', |
| | | 'orderBy' |
| | | ].forEach((key) => { |
| | | const value = normalizeText(params[key]) |
| | | if (value) result[key] = value |
| | | }) |
| | | ;['type', 'source', 'exceStatus', 'status', 'orgWareId', 'tarWareId', 'orgAreaId', 'tarAreaId'].forEach((key) => { |
| | | ;[ |
| | | 'type', |
| | | 'source', |
| | | 'exceStatus', |
| | | 'status', |
| | | 'orgWareId', |
| | | 'tarWareId', |
| | | 'orgAreaId', |
| | | 'tarAreaId' |
| | | ].forEach((key) => { |
| | | if (params[key] !== '' && params[key] !== undefined && params[key] !== null) { |
| | | result[key] = normalizeNumber(params[key]) |
| | | } |
| | |
| | | return { |
| | | current: params.current || 1, |
| | | pageSize: params.pageSize || params.size || 20, |
| | | orderBy: normalizeText(params.orderBy) || 'create_time desc', |
| | | ...buildTransferSearchParams(params) |
| | | } |
| | | } |
| | | |
| | | export function buildTransferLocsItemPageParams(params = {}) { |
| | | return { |
| | | orgAreaId: normalizeNumber(params.orgAreaId, void 0), |
| | | matnrCode: normalizeText(params.matnrCode || params.code || ''), |
| | | maktx: normalizeText(params.maktx || params.name || ''), |
| | | current: params.current || 1, |
| | | pageSize: params.pageSize || params.size || 20 |
| | | } |
| | | } |
| | | |
| | | export function buildTransferOrderPageParams(params = {}) { |
| | | return { |
| | | ...(normalizeNumber(params.id, void 0) !== void 0 |
| | | ? { id: normalizeNumber(params.id, void 0) } |
| | | : {}), |
| | | condition: normalizeText(params.code || params.condition), |
| | | code: normalizeText(params.code || params.condition), |
| | | current: params.current || 1, |
| | | pageSize: params.pageSize || params.size || 20 |
| | | pageSize: params.pageSize || params.size || 20, |
| | | orderBy: normalizeText(params.orderBy) || 'create_time desc' |
| | | } |
| | | } |
| | | |
| | |
| | | const tarAreaId = normalizeNumber(formData.tarAreaId, void 0) |
| | | const orgArea = optionMap.get(orgAreaId) || {} |
| | | const tarArea = optionMap.get(tarAreaId) || {} |
| | | const orgWareId = normalizeNumber(orgArea.warehouseId ?? orgArea.warehouse_id ?? orgArea.warehouseIdValue, void 0) |
| | | const tarWareId = normalizeNumber(tarArea.warehouseId ?? tarArea.warehouse_id ?? tarArea.warehouseIdValue, void 0) |
| | | const orgWareId = normalizeNumber( |
| | | orgArea.warehouseId ?? orgArea.warehouse_id ?? orgArea.warehouseIdValue, |
| | | void 0 |
| | | ) |
| | | const tarWareId = normalizeNumber( |
| | | tarArea.warehouseId ?? tarArea.warehouse_id ?? tarArea.warehouseIdValue, |
| | | void 0 |
| | | ) |
| | | |
| | | return { |
| | | ...(formData.id !== undefined && formData.id !== null && formData.id !== '' |
| | |
| | | ...(tarAreaId !== void 0 ? { tarAreaId } : {}), |
| | | ...(orgWareId !== void 0 ? { orgWareId } : {}), |
| | | ...(tarWareId !== void 0 ? { tarWareId } : {}), |
| | | ...(normalizeText(orgArea.name || orgArea.areaName) ? { orgAreaName: normalizeText(orgArea.name || orgArea.areaName) } : {}), |
| | | ...(normalizeText(tarArea.name || tarArea.areaName) ? { tarAreaName: normalizeText(tarArea.name || tarArea.areaName) } : {}), |
| | | ...(normalizeText(orgArea.warehouseId$ || orgArea.warehouseName) ? { orgWareName: normalizeText(orgArea.warehouseId$ || orgArea.warehouseName) } : {}), |
| | | ...(normalizeText(tarArea.warehouseId$ || tarArea.warehouseName) ? { tarWareName: normalizeText(tarArea.warehouseId$ || tarArea.warehouseName) } : {}), |
| | | ...(normalizeText(orgArea.name || orgArea.areaName) |
| | | ? { orgAreaName: normalizeText(orgArea.name || orgArea.areaName) } |
| | | : {}), |
| | | ...(normalizeText(tarArea.name || tarArea.areaName) |
| | | ? { tarAreaName: normalizeText(tarArea.name || tarArea.areaName) } |
| | | : {}), |
| | | ...(normalizeText(orgArea.warehouseId$ || orgArea.warehouseName) |
| | | ? { orgWareName: normalizeText(orgArea.warehouseId$ || orgArea.warehouseName) } |
| | | : {}), |
| | | ...(normalizeText(tarArea.warehouseId$ || tarArea.warehouseName) |
| | | ? { tarWareName: normalizeText(tarArea.warehouseId$ || tarArea.warehouseName) } |
| | | : {}), |
| | | ...(formData.status !== undefined && formData.status !== null && formData.status !== '' |
| | | ? { status: normalizeNumber(formData.status) } |
| | | : { status: 1 }), |
| | |
| | | return request.post({ url: '/transfer/update', params: payload }) |
| | | } |
| | | |
| | | export function fetchSaveTransferItems(payload = {}) { |
| | | return request.post({ url: '/transfer/items/save', params: payload }) |
| | | } |
| | | |
| | | export function fetchUpdateTransferItems(payload = {}) { |
| | | return request.post({ url: '/transfer/items/update', params: payload }) |
| | | } |
| | | |
| | | export function fetchTransferOrdersPage(params = {}) { |
| | | return request.post({ url: '/transfer/orders/page', params: buildTransferOrderPageParams(params) }) |
| | | return request.post({ |
| | | url: '/transfer/orders/page', |
| | | params: buildTransferOrderPageParams(params) |
| | | }) |
| | | } |
| | | |
| | | export function fetchTransferLocsItemsPage(params = {}) { |
| | | return request.post({ |
| | | url: '/transfer/locs/items', |
| | | params: buildTransferLocsItemPageParams(params) |
| | | }) |
| | | } |
| | | |
| | | export function fetchTransferPubOutStock(payload = {}) { |
| | | return request.post({ url: '/transfer/pub/outStock', params: payload }) |
| | | } |
| | | |
| | | export function fetchEnabledTransferFields() { |
| | | return request.get({ url: '/fields/enable/list' }) |
| | | } |
| | | |
| | | export async function fetchExportTransferReport(payload = {}, options = {}) { |
| | | return fetch(`${import.meta.env.VITE_API_URL}/transfer/export`, { |
| | | method: 'POST', |
| | |
| | | "search": { |
| | | "condition": "Keyword", |
| | | "conditionPlaceholder": "Enter No./remark/warehouse/area", |
| | | "timeStart": "Start Time", |
| | | "timeEnd": "End Time", |
| | | "code": "Transfer No.", |
| | | "codePlaceholder": "Enter transfer No.", |
| | | "type": "Transfer Type", |
| | | "source": "Source", |
| | | "exceStatus": "Execution Status", |
| | | "orgWareId": "Source Warehouse ID", |
| | | "orgWareName": "Source Warehouse", |
| | | "orgWareNamePlaceholder": "Enter source warehouse", |
| | | "tarWareId": "Target Warehouse ID", |
| | | "tarWareName": "Target Warehouse", |
| | | "tarWareNamePlaceholder": "Enter target warehouse", |
| | | "orgAreaId": "Source Area ID", |
| | | "orgAreaName": "Source Area", |
| | | "orgAreaNamePlaceholder": "Enter source area", |
| | | "tarAreaId": "Target Area ID", |
| | | "tarAreaName": "Target Area", |
| | | "tarAreaNamePlaceholder": "Enter target area", |
| | | "status": "Status", |
| | |
| | | "placeholder": { |
| | | "condition": "Enter No./remark/warehouse/area", |
| | | "code": "Enter transfer No.", |
| | | "orgWareId": "Enter source warehouse ID", |
| | | "orgWareName": "Enter source warehouse", |
| | | "tarWareId": "Enter target warehouse ID", |
| | | "tarWareName": "Enter target warehouse", |
| | | "orgAreaId": "Enter source area ID", |
| | | "orgAreaName": "Enter source area", |
| | | "tarAreaId": "Enter target area ID", |
| | | "tarAreaName": "Enter target area", |
| | | "memo": "Enter remark" |
| | | }, |
| | |
| | | "placeholderTarAreaId": "Please select a target area", |
| | | "placeholderStatus": "Please select a status", |
| | | "placeholderMemo": "Please enter a remark", |
| | | "addMaterial": "Add Material", |
| | | "deleteSelected": "Delete Selected", |
| | | "itemCount": "Items: {count}", |
| | | "supplierCode": "Supplier Code", |
| | | "supplierName": "Supplier Name", |
| | | "materialDuplicate": "The selected material already exists", |
| | | "validation": { |
| | | "type": "Please select a transfer type", |
| | | "orgAreaId": "Please select a source area", |
| | | "tarAreaId": "Please select a target area" |
| | | "tarAreaId": "Please select a target area", |
| | | "items": "Please add at least one transfer item", |
| | | "anfme": "Transfer quantity must be greater than 0" |
| | | } |
| | | }, |
| | | "materialDialog": { |
| | | "title": "Select Transfer Materials", |
| | | "selected": "Added", |
| | | "unselected": "Not Added", |
| | | "table": { |
| | | "status": "Status" |
| | | }, |
| | | "placeholder": { |
| | | "maktx": "Enter material name", |
| | | "matnrCode": "Enter material code" |
| | | } |
| | | }, |
| | | "messages": { |
| | | "detailTimeout": "Transfer detail timed out and waiting has stopped", |
| | | "ordersTimeout": "Transfer items timed out and waiting has stopped", |
| | | "itemsTimeout": "Transfer edit items timed out and waiting has stopped", |
| | | "ordersLoadFailed": "Failed to load transfer items", |
| | | "detailLoadFailed": "Failed to load transfer detail", |
| | | "publishConfirm": "Are you sure you want to dispatch transfer order \"{code}\"?", |
| | |
| | | "publishSuccess": "Dispatched successfully", |
| | | "publishFailed": "Dispatch failed", |
| | | "typeOptionsTimeout": "Transfer type options timed out and waiting has stopped", |
| | | "areaOptionsTimeout": "Area options timed out and waiting has stopped" |
| | | "areaOptionsTimeout": "Area options timed out and waiting has stopped", |
| | | "fieldTimeout": "Field definitions timed out and waiting has stopped" |
| | | } |
| | | }, |
| | | "transferItem": { |
| | |
| | | "search": { |
| | | "condition": "关键字", |
| | | "conditionPlaceholder": "请输入单号/备注/仓库/库区", |
| | | "timeStart": "开始时间", |
| | | "timeEnd": "结束时间", |
| | | "code": "调拨单号", |
| | | "codePlaceholder": "请输入调拨单号", |
| | | "type": "调拨类型", |
| | | "source": "来源", |
| | | "exceStatus": "执行状态", |
| | | "orgWareId": "源仓库ID", |
| | | "orgWareName": "源仓库", |
| | | "orgWareNamePlaceholder": "请输入源仓库", |
| | | "tarWareId": "目标仓库ID", |
| | | "tarWareName": "目标仓库", |
| | | "tarWareNamePlaceholder": "请输入目标仓库", |
| | | "orgAreaId": "源库区ID", |
| | | "orgAreaName": "源库区", |
| | | "orgAreaNamePlaceholder": "请输入源库区", |
| | | "tarAreaId": "目标库区ID", |
| | | "tarAreaName": "目标库区", |
| | | "tarAreaNamePlaceholder": "请输入目标库区", |
| | | "status": "状态", |
| | |
| | | "placeholder": { |
| | | "condition": "请输入单号/备注/仓库/库区", |
| | | "code": "请输入调拨单号", |
| | | "orgWareId": "请输入源仓库ID", |
| | | "orgWareName": "请输入源仓库", |
| | | "tarWareId": "请输入目标仓库ID", |
| | | "tarWareName": "请输入目标仓库", |
| | | "orgAreaId": "请输入源库区ID", |
| | | "orgAreaName": "请输入源库区", |
| | | "tarAreaId": "请输入目标库区ID", |
| | | "tarAreaName": "请输入目标库区", |
| | | "memo": "请输入备注" |
| | | }, |
| | |
| | | "placeholderTarAreaId": "请选择目标库区", |
| | | "placeholderStatus": "请选择状态", |
| | | "placeholderMemo": "请输入备注", |
| | | "addMaterial": "新增物料", |
| | | "deleteSelected": "删除选中", |
| | | "itemCount": "明细数:{count}", |
| | | "supplierCode": "供应商编码", |
| | | "supplierName": "供应商名称", |
| | | "materialDuplicate": "所选物料已存在,无需重复添加", |
| | | "validation": { |
| | | "type": "请选择调拨类型", |
| | | "orgAreaId": "请选择源库区", |
| | | "tarAreaId": "请选择目标库区" |
| | | "tarAreaId": "请选择目标库区", |
| | | "items": "请至少添加一条调拨明细", |
| | | "anfme": "调拨数量必须大于 0" |
| | | } |
| | | }, |
| | | "materialDialog": { |
| | | "title": "选择调拨物料", |
| | | "selected": "已添加", |
| | | "unselected": "未添加", |
| | | "table": { |
| | | "status": "状态" |
| | | }, |
| | | "placeholder": { |
| | | "maktx": "请输入物料名称", |
| | | "matnrCode": "请输入物料编码" |
| | | } |
| | | }, |
| | | "messages": { |
| | | "detailTimeout": "调拨单详情加载超时,已停止等待", |
| | | "ordersTimeout": "调拨单明细加载超时,已停止等待", |
| | | "itemsTimeout": "调拨单编辑明细加载超时,已停止等待", |
| | | "ordersLoadFailed": "调拨单明细加载失败", |
| | | "detailLoadFailed": "调拨单详情加载失败", |
| | | "publishConfirm": "确定要下发调拨单「{code}」吗?", |
| | |
| | | "publishSuccess": "下发执行成功", |
| | | "publishFailed": "下发执行失败", |
| | | "typeOptionsTimeout": "调拨类型选项加载超时,已停止等待", |
| | | "areaOptionsTimeout": "库区选项加载超时,已停止等待" |
| | | "areaOptionsTimeout": "库区选项加载超时,已停止等待", |
| | | "fieldTimeout": "扩展字段加载超时,已停止等待" |
| | | } |
| | | }, |
| | | "transferItem": { |
| | |
| | | logId: '', |
| | | taskId: '', |
| | | taskItemId: '', |
| | | orderId: '', |
| | | orderType: '', |
| | | orderItemId: '', |
| | | matnrId: '', |
| | | maktx: '', |
| | | platItemId: '', |
| | |
| | | sourceCode: '', |
| | | sourceId: '', |
| | | matnrCode: '', |
| | | trackCode: '', |
| | | unit: '', |
| | | anfme: '', |
| | | batch: '', |
| | |
| | | keeperId: '', |
| | | keeperName: '', |
| | | targetWarehouseId: '', |
| | | sourceWarehouseId: '' |
| | | sourceWarehouseId: '', |
| | | orderBy: 'create_time desc' |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | ;[ |
| | | 'condition', |
| | | 'orderType', |
| | | 'maktx', |
| | | 'platItemId', |
| | | 'platOrderCode', |
| | |
| | | 'projectCode', |
| | | 'sourceCode', |
| | | 'matnrCode', |
| | | 'trackCode', |
| | | 'unit', |
| | | 'batch', |
| | | 'spec', |
| | |
| | | result[key] = value |
| | | } |
| | | }) |
| | | |
| | | ;['timeStart', 'timeEnd'].forEach((key) => { |
| | | if (params[key]) { |
| | | result[key] = params[key] |
| | | } |
| | | }) |
| | | |
| | | ;['logId', 'taskId', 'taskItemId', 'matnrId', 'source', 'sourceId', 'anfme', 'status'].forEach( |
| | | (key) => { |
| | | const value = normalizeNumber(params[key]) |
| | | if (value !== null) { |
| | | result[key] = value |
| | | } |
| | | ;[ |
| | | 'logId', |
| | | 'taskId', |
| | | 'taskItemId', |
| | | 'orderId', |
| | | 'orderItemId', |
| | | 'matnrId', |
| | | 'source', |
| | | 'sourceId', |
| | | 'anfme', |
| | | 'status' |
| | | ].forEach((key) => { |
| | | const value = normalizeNumber(params[key]) |
| | | if (value !== null) { |
| | | result[key] = value |
| | | } |
| | | ) |
| | | }) |
| | | |
| | | return { |
| | | condition: '', |
| | |
| | | return { |
| | | current: params.current || 1, |
| | | pageSize: params.pageSize || params.size || 20, |
| | | orderBy: normalizeText(params.orderBy) || 'create_time desc', |
| | | ...buildTaskItemLogSearchParams(params) |
| | | } |
| | | } |
| | |
| | | logId: record.logId ?? '--', |
| | | taskId: record.taskId ?? '--', |
| | | taskItemId: record.taskItemId ?? '--', |
| | | orderId: record.orderId ?? '--', |
| | | orderType: normalizeReportText(record.orderType || record['orderType$']), |
| | | orderItemId: record.orderItemId ?? '--', |
| | | matnrId: record.matnrId ?? '--', |
| | | maktx: normalizeReportText(record.maktx), |
| | | platItemId: normalizeReportText(record.platItemId), |
| | |
| | | sourceCode: normalizeReportText(record.sourceCode), |
| | | sourceId: record.sourceId ?? '--', |
| | | matnrCode: normalizeReportText(record.matnrCode), |
| | | trackCode: normalizeReportText(record.trackCode), |
| | | unit: normalizeReportText(record.unit), |
| | | anfme: record.anfme ?? '--', |
| | | batch: normalizeReportText(record.batch), |
| | |
| | | return [ |
| | | { source: 'taskId', label: '任务ID' }, |
| | | { source: 'taskItemId', label: '任务明细ID' }, |
| | | { source: 'orderId', label: '单据ID' }, |
| | | { source: 'orderType', label: '单据类型' }, |
| | | { source: 'orderItemId', label: '单据明细ID' }, |
| | | { source: 'matnrId', label: '物料ID' }, |
| | | { source: 'maktx', label: '物料名称' }, |
| | | { source: 'platWorkCode', label: '工单号' }, |
| | |
| | | { source: 'source', label: '源编码' }, |
| | | { source: 'sourceCode', label: '源单号' }, |
| | | { source: 'matnrCode', label: '物料编码' }, |
| | | { source: 'trackCode', label: '追踪码' }, |
| | | { source: 'unit', label: '库存单位' }, |
| | | { source: 'anfme', label: '数量' }, |
| | | { source: 'batch', label: '库存批次' }, |
| | |
| | | return { |
| | | taskId: row.taskId, |
| | | taskItemId: row.taskItemId, |
| | | orderId: row.orderId, |
| | | orderType: row.orderType, |
| | | orderItemId: row.orderItemId, |
| | | matnrId: row.matnrId, |
| | | maktx: row.maktx, |
| | | platWorkCode: row.platWorkCode, |
| | |
| | | source: row.source, |
| | | sourceCode: row.sourceCode, |
| | | matnrCode: row.matnrCode, |
| | | trackCode: row.trackCode, |
| | | unit: row.unit, |
| | | anfme: row.anfme, |
| | | batch: row.batch, |
| | |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'orderId', |
| | | label: '单据ID', |
| | | width: 110, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'orderType', |
| | | label: '单据类型', |
| | | minWidth: 120, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'orderItemId', |
| | | label: '单据明细ID', |
| | | width: 120, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'matnrId', |
| | | label: '物料ID', |
| | | width: 110, |
| | |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'trackCode', |
| | | label: '追踪码', |
| | | minWidth: 150, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'unit', |
| | | label: '库存单位', |
| | | width: 100, |
| | |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.detail.taskId'), |
| | | key: 'taskId', |
| | | type: 'inputNumber', |
| | | props: { |
| | | clearable: true, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入任务ID' |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.table.taskCode'), |
| | | key: 'taskCode', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: t('pages.manager.taskLog.search.taskCodePlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.table.taskStatus'), |
| | | key: 'taskStatus', |
| | | type: 'inputNumber', |
| | | props: { |
| | | clearable: true, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入任务状态' |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.table.taskType'), |
| | | key: 'taskType', |
| | | type: 'inputNumber', |
| | | props: { |
| | | clearable: true, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入任务类型' |
| | | } |
| | | }, |
| | | { |
| | |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.table.orgSite'), |
| | | key: 'orgSite', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入源站点' |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.table.targLoc'), |
| | | key: 'targLoc', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: t('pages.manager.taskLog.search.targLocPlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.table.targSite'), |
| | | key: 'targSite', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入目标站点' |
| | | } |
| | | }, |
| | | { |
| | |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.detail.exceStatus'), |
| | | key: 'exceStatus', |
| | | type: 'inputNumber', |
| | | props: { |
| | | clearable: true, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入执行状态' |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.detail.expDesc'), |
| | | key: 'expDesc', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入异常描述' |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.detail.sort'), |
| | | key: 'sort', |
| | | type: 'inputNumber', |
| | | props: { |
| | | clearable: true, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入优先级' |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.detail.expCode'), |
| | | key: 'expCode', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入异常编码' |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.search.timeStart'), |
| | | key: 'timeStart', |
| | | type: 'date', |
| | |
| | | clearable: true, |
| | | valueFormat: 'YYYY-MM-DD', |
| | | type: 'date' |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.table.startTime'), |
| | | key: 'startTime', |
| | | type: 'date', |
| | | props: { |
| | | clearable: true, |
| | | valueFormat: 'YYYY-MM-DD', |
| | | type: 'date' |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.manager.taskLog.table.endTime'), |
| | | key: 'endTime', |
| | | type: 'date', |
| | | props: { |
| | | clearable: true, |
| | | valueFormat: 'YYYY-MM-DD', |
| | | type: 'date' |
| | | } |
| | | }, |
| | | { |
| | | label: t('table.memo'), |
| | | key: 'memo', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入备注' |
| | | } |
| | | }, |
| | | { |
| | | label: t('table.status'), |
| | | key: 'status', |
| | | type: 'select', |
| | | props: { |
| | | clearable: true, |
| | | options: [ |
| | | { label: t('common.status.enabled'), value: 1 }, |
| | | { label: t('common.status.disabled'), value: 0 } |
| | | ] |
| | | } |
| | | } |
| | | ]) |
| | |
| | | columnsFactory: () => createTaskLogTableColumns({ handleView: openDetail }) |
| | | }, |
| | | transform: { |
| | | dataTransformer: (records) => (Array.isArray(records) ? records.map((item) => normalizeTaskLogRow(item)) : []) |
| | | dataTransformer: (records) => |
| | | Array.isArray(records) ? records.map((item) => normalizeTaskLogRow(item)) : [] |
| | | } |
| | | }) |
| | | |
| | |
| | | } |
| | | |
| | | function handleSearch(params) { |
| | | searchForm.value = { ...searchForm.value, ...params } |
| | | replaceSearchParams(buildTaskLogSearchParams(params)) |
| | | getData() |
| | | } |
| New file |
| | |
| | | <template> |
| | | <div class="task-item-log-panel space-y-4"> |
| | | <ArtSearchBar |
| | | v-model="searchForm" |
| | | :items="searchItems" |
| | | :showExpand="true" |
| | | @search="handleSearch" |
| | | @reset="handleReset" |
| | | /> |
| | | |
| | | <div class="flex items-center justify-between"> |
| | | <div class="text-sm font-medium text-[var(--art-gray-900)]">任务明细历史档</div> |
| | | <ListExportPrint |
| | | class="inline-flex" |
| | | :preview-visible="previewVisible" |
| | | @update:previewVisible="handlePreviewVisibleChange" |
| | | :report-title="reportTitle" |
| | | :selected-rows="selectedRows" |
| | | :query-params="reportQueryParams" |
| | | :columns="reportColumns" |
| | | :preview-rows="previewRows" |
| | | :preview-meta="previewMeta" |
| | | :total="pagination.total" |
| | | :disabled="loading || !effectiveLogId" |
| | | @export="handleExport" |
| | | @print="handlePrint" |
| | | /> |
| | | </div> |
| | | |
| | | <ArtTable |
| | | :loading="loading" |
| | | :data="data" |
| | | :columns="columns" |
| | | :pagination="pagination" |
| | | @selection-change="handleSelectionChange" |
| | | @pagination:size-change="handleSizeChange" |
| | | @pagination:current-change="handleCurrentChange" |
| | | /> |
| | | |
| | | <TaskItemLogDetailDrawer v-model:visible="detailDrawerVisible" :detail="detailData" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, ref, watch } from 'vue' |
| | | import { useUserStore } from '@/store/modules/user' |
| | | import { useTable } from '@/hooks/core/useTable' |
| | | import { usePrintExportPage } from '@/views/system/common/usePrintExportPage' |
| | | import ListExportPrint from '@/components/biz/list-export-print/index.vue' |
| | | import { defaultResponseAdapter } from '@/utils/table/tableUtils' |
| | | import { |
| | | fetchExportTaskItemLogReport, |
| | | fetchGetTaskItemLogDetail, |
| | | fetchGetTaskItemLogMany, |
| | | fetchTaskItemLogPage |
| | | } from '@/api/task-item-log' |
| | | import { |
| | | buildTaskItemLogPageQueryParams, |
| | | buildTaskItemLogPrintRows, |
| | | buildTaskItemLogSearchParams, |
| | | createTaskItemLogSearchState, |
| | | getTaskItemLogPaginationKey, |
| | | getTaskItemLogReportColumns, |
| | | normalizeTaskItemLogRow, |
| | | TASK_ITEM_LOG_REPORT_TITLE |
| | | } from '@/views/manager/task-item-log/taskItemLogPage.helpers.js' |
| | | import { createTaskItemLogTableColumns } from '@/views/manager/task-item-log/taskItemLogTable.columns.js' |
| | | import TaskItemLogDetailDrawer from '@/views/manager/task-item-log/modules/task-item-log-detail-drawer.vue' |
| | | |
| | | defineOptions({ name: 'TaskItemLogPanel' }) |
| | | |
| | | const props = defineProps({ |
| | | logId: { type: [Number, String], default: undefined } |
| | | }) |
| | | |
| | | const userStore = useUserStore() |
| | | const searchForm = ref(createTaskItemLogSearchState()) |
| | | const selectedRows = ref([]) |
| | | const detailDrawerVisible = ref(false) |
| | | const detailData = ref({}) |
| | | const reportTitle = TASK_ITEM_LOG_REPORT_TITLE |
| | | const reportColumns = getTaskItemLogReportColumns() |
| | | |
| | | const effectiveLogId = computed(() => { |
| | | if (props.logId === '' || props.logId === null || props.logId === undefined) return undefined |
| | | const numericValue = Number(props.logId) |
| | | return Number.isFinite(numericValue) ? numericValue : undefined |
| | | }) |
| | | |
| | | const reportQueryParams = computed(() => |
| | | buildTaskItemLogSearchParams({ |
| | | ...searchForm.value, |
| | | logId: effectiveLogId.value |
| | | }) |
| | | ) |
| | | |
| | | const searchItems = computed(() => [ |
| | | { |
| | | label: '关键字', |
| | | key: 'condition', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: '请输入物料/任务/单号关键词' } |
| | | }, |
| | | { |
| | | label: '任务ID', |
| | | key: 'taskId', |
| | | type: 'inputNumber', |
| | | props: { clearable: true, controlsPosition: 'right', placeholder: '请输入任务ID' } |
| | | }, |
| | | { |
| | | label: '任务明细ID', |
| | | key: 'taskItemId', |
| | | type: 'inputNumber', |
| | | props: { clearable: true, controlsPosition: 'right', placeholder: '请输入任务明细ID' } |
| | | }, |
| | | { |
| | | label: '单据ID', |
| | | key: 'orderId', |
| | | type: 'inputNumber', |
| | | props: { clearable: true, controlsPosition: 'right', placeholder: '请输入单据ID' } |
| | | }, |
| | | { |
| | | label: '单据类型', |
| | | key: 'orderType', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: '请输入单据类型' } |
| | | }, |
| | | { |
| | | label: '物料ID', |
| | | key: 'matnrId', |
| | | type: 'inputNumber', |
| | | props: { clearable: true, controlsPosition: 'right', placeholder: '请输入物料ID' } |
| | | }, |
| | | { |
| | | label: '物料名称', |
| | | key: 'maktx', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: '请输入物料名称' } |
| | | }, |
| | | { |
| | | label: '物料编码', |
| | | key: 'matnrCode', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: '请输入物料编码' } |
| | | }, |
| | | { |
| | | label: '追踪码', |
| | | key: 'trackCode', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: '请输入追踪码' } |
| | | }, |
| | | { |
| | | label: '库存单位', |
| | | key: 'unit', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: '请输入库存单位' } |
| | | }, |
| | | { |
| | | label: '数量', |
| | | key: 'anfme', |
| | | type: 'inputNumber', |
| | | props: { clearable: true, controlsPosition: 'right', placeholder: '请输入数量' } |
| | | }, |
| | | { |
| | | label: '库存批次', |
| | | key: 'batch', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: '请输入库存批次' } |
| | | }, |
| | | { |
| | | label: '规格', |
| | | key: 'spec', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: '请输入规格' } |
| | | }, |
| | | { |
| | | label: '型号', |
| | | key: 'model', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: '请输入型号' } |
| | | }, |
| | | { |
| | | label: '字段索引', |
| | | key: 'fieldsIndex', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: '请输入字段索引' } |
| | | }, |
| | | { |
| | | label: '备注', |
| | | key: 'memo', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: '请输入备注' } |
| | | }, |
| | | { |
| | | label: '状态', |
| | | key: 'status', |
| | | type: 'select', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请选择状态', |
| | | options: [ |
| | | { label: '正常', value: 1 }, |
| | | { label: '冻结', value: 0 } |
| | | ] |
| | | } |
| | | }, |
| | | { |
| | | label: '开始日期', |
| | | key: 'timeStart', |
| | | type: 'date', |
| | | props: { clearable: true, valueFormat: 'YYYY-MM-DD', type: 'date' } |
| | | }, |
| | | { |
| | | label: '结束日期', |
| | | key: 'timeEnd', |
| | | type: 'date', |
| | | props: { clearable: true, valueFormat: 'YYYY-MM-DD', type: 'date' } |
| | | } |
| | | ]) |
| | | |
| | | function buildPanelParams(extra = {}) { |
| | | return buildTaskItemLogPageQueryParams({ |
| | | ...searchForm.value, |
| | | ...extra, |
| | | logId: effectiveLogId.value |
| | | }) |
| | | } |
| | | |
| | | function openDetail(row) { |
| | | detailDrawerVisible.value = true |
| | | loadDetail(row.id, row) |
| | | } |
| | | |
| | | const { |
| | | columns, |
| | | data, |
| | | loading, |
| | | pagination, |
| | | getData, |
| | | replaceSearchParams, |
| | | handleSizeChange, |
| | | handleCurrentChange |
| | | } = useTable({ |
| | | core: { |
| | | apiFn: fetchTaskItemLogPage, |
| | | apiParams: buildPanelParams(), |
| | | paginationKey: getTaskItemLogPaginationKey(), |
| | | columnsFactory: () => createTaskItemLogTableColumns({ handleView: openDetail }) |
| | | }, |
| | | transform: { |
| | | dataTransformer: (records) => |
| | | Array.isArray(records) ? records.map((item) => normalizeTaskItemLogRow(item)) : [] |
| | | } |
| | | }) |
| | | |
| | | const resolvePrintRecords = async (payload) => { |
| | | if (Array.isArray(payload?.ids) && payload.ids.length > 0) { |
| | | return defaultResponseAdapter(await fetchGetTaskItemLogMany(payload.ids)).records |
| | | } |
| | | return defaultResponseAdapter( |
| | | await fetchTaskItemLogPage({ |
| | | ...reportQueryParams.value, |
| | | logId: effectiveLogId.value, |
| | | current: 1, |
| | | pageSize: Number(pagination.total) > 0 ? Number(pagination.total) : 20 |
| | | }) |
| | | ).records |
| | | } |
| | | |
| | | const { |
| | | previewVisible, |
| | | previewRows, |
| | | previewMeta, |
| | | handlePreviewVisibleChange, |
| | | handleExport, |
| | | handlePrint |
| | | } = usePrintExportPage({ |
| | | downloadFileName: 'task-item-log.xlsx', |
| | | requestExport: (payload) => |
| | | fetchExportTaskItemLogReport( |
| | | { |
| | | ...payload, |
| | | ...reportQueryParams.value, |
| | | logId: effectiveLogId.value |
| | | }, |
| | | { |
| | | headers: { |
| | | Authorization: userStore.accessToken || '' |
| | | } |
| | | } |
| | | ), |
| | | resolvePrintRecords, |
| | | buildPreviewRows: (records) => buildTaskItemLogPrintRows(records), |
| | | buildPreviewMeta: (rows) => ({ |
| | | reportTitle, |
| | | reportDate: new Date().toLocaleDateString('zh-CN'), |
| | | printedAt: new Date().toLocaleString('zh-CN', { hour12: false }), |
| | | operator: userStore.getUserInfo?.name || userStore.getUserInfo?.username || '', |
| | | count: rows.length |
| | | }) |
| | | }) |
| | | |
| | | async function loadDetail(id, fallback) { |
| | | const detail = await fetchGetTaskItemLogDetail(id) |
| | | detailData.value = normalizeTaskItemLogRow({ |
| | | ...fallback, |
| | | ...detail |
| | | }) |
| | | } |
| | | |
| | | function handleSelectionChange(rows) { |
| | | selectedRows.value = Array.isArray(rows) ? rows : [] |
| | | } |
| | | |
| | | function handleSearch(params) { |
| | | searchForm.value = { ...searchForm.value, ...params } |
| | | replaceSearchParams(buildPanelParams(params)) |
| | | getData() |
| | | } |
| | | |
| | | function handleReset() { |
| | | searchForm.value = createTaskItemLogSearchState() |
| | | selectedRows.value = [] |
| | | replaceSearchParams(buildPanelParams()) |
| | | getData() |
| | | } |
| | | |
| | | watch( |
| | | () => effectiveLogId.value, |
| | | (value) => { |
| | | if (value === undefined) return |
| | | selectedRows.value = [] |
| | | searchForm.value = createTaskItemLogSearchState() |
| | | replaceSearchParams(buildPanelParams()) |
| | | getData() |
| | | }, |
| | | { immediate: true } |
| | | ) |
| | | </script> |
| | |
| | | <ElScrollbar class="h-[calc(100vh-120px)]"> |
| | | <div class="flex min-h-full flex-col gap-4 pr-2"> |
| | | <ElDescriptions :column="4" border> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.detail.taskId')">{{ detail.taskId ?? '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.taskCode')">{{ detail.taskCode || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.taskStatus')">{{ detail.taskStatusText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.taskType')">{{ detail.taskTypeText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.orgLoc')">{{ detail.orgLoc || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.orgSite')">{{ detail.orgSite || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.targLoc')">{{ detail.targLoc || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.targSite')">{{ detail.targSite || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.barcode')">{{ detail.barcode || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.robotCode')">{{ detail.robotCode || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.detail.exceStatus')">{{ detail.exceStatusText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.detail.sort')">{{ detail.sort ?? '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.detail.expDesc')">{{ detail.expDesc || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.detail.expCode')">{{ detail.expCode || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.startTime')">{{ detail.startTimeText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.endTime')">{{ detail.endTimeText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('table.createBy')">{{ detail.createByText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('table.createTime')">{{ detail.createTimeText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('table.updateBy')">{{ detail.updateByText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('table.updateTime')">{{ detail.updateTimeText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.detail.taskId')">{{ |
| | | detail.taskId ?? '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.taskCode')">{{ |
| | | detail.taskCode || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.taskStatus')">{{ |
| | | detail.taskStatusText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.taskType')">{{ |
| | | detail.taskTypeText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.orgLoc')">{{ |
| | | detail.orgLoc || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.orgSite')">{{ |
| | | detail.orgSite || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.targLoc')">{{ |
| | | detail.targLoc || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.targSite')">{{ |
| | | detail.targSite || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.barcode')">{{ |
| | | detail.barcode || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.robotCode')">{{ |
| | | detail.robotCode || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.detail.exceStatus')">{{ |
| | | detail.exceStatusText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.detail.sort')">{{ |
| | | detail.sort ?? '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.detail.expDesc')">{{ |
| | | detail.expDesc || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.detail.expCode')">{{ |
| | | detail.expCode || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.startTime')">{{ |
| | | detail.startTimeText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.manager.taskLog.table.endTime')">{{ |
| | | detail.endTimeText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('table.createBy')">{{ |
| | | detail.createByText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('table.createTime')">{{ |
| | | detail.createTimeText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('table.updateBy')">{{ |
| | | detail.updateByText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('table.updateTime')">{{ |
| | | detail.updateTimeText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('table.status')"> |
| | | <ElTag :type="detail.statusType || 'info'" effect="light">{{ detail.statusText || '--' }}</ElTag> |
| | | <ElTag :type="detail.statusType || 'info'" effect="light">{{ |
| | | detail.statusText || '--' |
| | | }}</ElTag> |
| | | </ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('table.memo')" :span="3">{{ detail.memo || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('table.memo')" :span="3">{{ |
| | | detail.memo || '--' |
| | | }}</ElDescriptionsItem> |
| | | </ElDescriptions> |
| | | |
| | | <TaskItemLogPanel :log-id="detail.id" /> |
| | | </div> |
| | | </ElScrollbar> |
| | | </ElDrawer> |
| | |
| | | |
| | | <script setup> |
| | | import { useI18n } from 'vue-i18n' |
| | | import TaskItemLogPanel from './task-item-log-panel.vue' |
| | | |
| | | defineOptions({ name: 'TaskLogDetailDrawer' }) |
| | | |
| | | defineProps({ |
| | |
| | | sort: '', |
| | | expCode: '', |
| | | startTime: '', |
| | | endTime: '' |
| | | endTime: '', |
| | | memo: '', |
| | | status: '', |
| | | orderBy: 'create_time desc' |
| | | } |
| | | } |
| | | |
| | |
| | | 'barcode', |
| | | 'robotCode', |
| | | 'expDesc', |
| | | 'expCode' |
| | | 'expCode', |
| | | 'memo' |
| | | ].forEach((key) => { |
| | | const value = normalizeText(params[key]) |
| | | if (value) { |
| | | result[key] = value |
| | | } |
| | | }) |
| | | |
| | | ;['timeStart', 'timeEnd', 'startTime', 'endTime'].forEach((key) => { |
| | | if (params[key]) { |
| | | result[key] = params[key] |
| | | } |
| | | }) |
| | | |
| | | ;['taskId', 'taskStatus', 'taskType', 'exceStatus', 'sort'].forEach((key) => { |
| | | ;['taskId', 'taskStatus', 'taskType', 'exceStatus', 'sort', 'status'].forEach((key) => { |
| | | const value = normalizeNumber(params[key]) |
| | | if (value !== null) { |
| | | result[key] = value |
| | |
| | | return { |
| | | current: params.current || 1, |
| | | pageSize: params.pageSize || params.size || 20, |
| | | orderBy: normalizeText(params.orderBy) || 'create_time desc', |
| | | ...buildTaskLogSearchParams(params) |
| | | } |
| | | } |
| | |
| | | |
| | | export function getTaskLogReportColumns() { |
| | | return [ |
| | | { prop: 'id', label: $t('table.id') }, |
| | | { prop: 'taskId', label: $t('pages.manager.taskLog.detail.taskId') }, |
| | | { prop: 'taskCode', label: $t('pages.manager.taskLog.table.taskCode') }, |
| | | { prop: 'taskStatusText', label: $t('pages.manager.taskLog.table.taskStatus') }, |
| | | { prop: 'taskTypeText', label: $t('pages.manager.taskLog.table.taskType') }, |
| | | { prop: 'orgLoc', label: $t('pages.manager.taskLog.table.orgLoc') }, |
| | | { prop: 'orgSite', label: $t('pages.manager.taskLog.table.orgSite') }, |
| | | { prop: 'targLoc', label: $t('pages.manager.taskLog.table.targLoc') }, |
| | | { prop: 'targSite', label: $t('pages.manager.taskLog.table.targSite') }, |
| | | { prop: 'barcode', label: $t('pages.manager.taskLog.table.barcode') }, |
| | | { prop: 'robotCode', label: $t('pages.manager.taskLog.table.robotCode') }, |
| | | { prop: 'exceStatusText', label: $t('pages.manager.taskLog.detail.exceStatus') }, |
| | | { prop: 'sort', label: $t('pages.manager.taskLog.detail.sort') }, |
| | | { prop: 'expCode', label: $t('pages.manager.taskLog.detail.expCode') }, |
| | | { prop: 'startTimeText', label: $t('pages.manager.taskLog.table.startTime') }, |
| | | { prop: 'endTimeText', label: $t('pages.manager.taskLog.table.endTime') } |
| | | { prop: 'endTimeText', label: $t('pages.manager.taskLog.table.endTime') }, |
| | | { prop: 'createByText', label: $t('table.createBy') }, |
| | | { prop: 'createTimeText', label: $t('table.createTime') }, |
| | | { prop: 'updateByText', label: $t('table.updateBy') }, |
| | | { prop: 'updateTimeText', label: $t('table.updateTime') }, |
| | | { prop: 'memo', label: $t('table.memo') } |
| | | ] |
| | | } |
| | | |
| | |
| | | return records.map((record) => { |
| | | const row = normalizeTaskLogRow(record) |
| | | return { |
| | | id: row.id ?? '--', |
| | | taskId: row.taskId, |
| | | taskCode: row.taskCode, |
| | | taskStatusText: row.taskStatusText, |
| | | taskTypeText: row.taskTypeText, |
| | | orgLoc: row.orgLoc, |
| | | orgSite: row.orgSite, |
| | | targLoc: row.targLoc, |
| | | targSite: row.targSite, |
| | | barcode: row.barcode, |
| | | robotCode: row.robotCode, |
| | | exceStatusText: row.exceStatusText, |
| | | sort: row.sort, |
| | | expCode: row.expCode, |
| | | startTimeText: row.startTimeText, |
| | | endTimeText: row.endTimeText |
| | | endTimeText: row.endTimeText, |
| | | createByText: row.createByText, |
| | | createTimeText: row.createTimeText, |
| | | updateByText: row.updateByText, |
| | | updateTimeText: row.updateTimeText, |
| | | memo: row.memo |
| | | } |
| | | }) |
| | | } |
| | |
| | | { type: 'selection', width: 48, align: 'center' }, |
| | | { type: 'globalIndex', label: $t('table.index'), width: 72, align: 'center' }, |
| | | { |
| | | prop: 'id', |
| | | label: $t('table.id'), |
| | | width: 90, |
| | | align: 'center', |
| | | formatter: (row) => row.id ?? '--' |
| | | }, |
| | | { |
| | | prop: 'taskId', |
| | | label: $t('pages.manager.taskLog.detail.taskId'), |
| | | width: 110, |
| | | align: 'center', |
| | | formatter: (row) => row.taskId ?? '--' |
| | | }, |
| | | { |
| | | prop: 'taskCode', |
| | | label: $t('pages.manager.taskLog.table.taskCode'), |
| | | minWidth: 170, |
| | |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'exceStatusText', |
| | | label: $t('pages.manager.taskLog.detail.exceStatus'), |
| | | minWidth: 120, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'sort', |
| | | label: $t('pages.manager.taskLog.detail.sort'), |
| | | width: 100, |
| | | align: 'right', |
| | | formatter: (row) => row.sort ?? '--' |
| | | }, |
| | | { |
| | | prop: 'expCode', |
| | | label: $t('pages.manager.taskLog.detail.expCode'), |
| | | minWidth: 140, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'startTimeText', |
| | | label: $t('pages.manager.taskLog.table.startTime'), |
| | | minWidth: 170, |
| | |
| | | ) |
| | | }, |
| | | { |
| | | prop: 'createByText', |
| | | label: $t('table.createBy'), |
| | | minWidth: 120, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'createTimeText', |
| | | label: $t('table.createTime'), |
| | | minWidth: 170, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'updateByText', |
| | | label: $t('table.updateBy'), |
| | | minWidth: 120, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'updateTimeText', |
| | | label: $t('table.updateTime'), |
| | | minWidth: 170, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'memo', |
| | | label: $t('table.memo'), |
| | | minWidth: 180, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'operation', |
| | | label: $t('table.operation'), |
| | | width: 92, |
| | |
| | | <ArtTableHeader v-model:columns="columnChecks" :loading="loading" @refresh="refreshData"> |
| | | <template #left> |
| | | <ElSpace wrap> |
| | | <ElButton v-if="canCreate" type="primary" @click="showDialog('add')" v-ripple>{{ t('pages.orders.transfer.actions.add') }}</ElButton> |
| | | <ElButton v-if="canCreate" type="primary" @click="showDialog('add')" v-ripple>{{ |
| | | t('pages.orders.transfer.actions.add') |
| | | }}</ElButton> |
| | | <ElButton |
| | | v-if="canDelete" |
| | | type="danger" |
| | |
| | | :transfer-data="currentTransferData" |
| | | :type-options="typeOptions" |
| | | :area-options="areaOptions" |
| | | :field-definitions="fieldDefinitions" |
| | | :submit-loading="dialogSubmitting" |
| | | @submit="handleDialogSubmit" |
| | | /> |
| | |
| | | :detail="detailData" |
| | | :order-rows="detailOrderRows" |
| | | :order-pagination="detailOrderPagination" |
| | | :on-order-view="handleViewRelatedOrder" |
| | | @size-change="handleDetailSizeChange" |
| | | @current-change="handleDetailCurrentChange" |
| | | /> |
| | |
| | | import { guardRequestWithMessage } from '@/utils/sys/requestGuard' |
| | | import { fetchDictDataPage } from '@/api/system-manage' |
| | | import { fetchWarehouseAreasList } from '@/api/warehouse-areas' |
| | | import { fetchTransferItemList } from '@/api/transfer-item' |
| | | import { |
| | | fetchDeleteTransfer, |
| | | fetchEnabledTransferFields, |
| | | fetchExportTransferReport, |
| | | fetchTransferDetail, |
| | | fetchTransferMany, |
| | | fetchSaveTransferItems, |
| | | fetchTransferOrdersPage, |
| | | fetchTransferPage, |
| | | fetchTransferPubOutStock, |
| | | fetchSaveTransfer, |
| | | fetchUpdateTransfer |
| | | fetchUpdateTransferItems |
| | | } from '@/api/transfer' |
| | | import TransferDialog from './modules/transfer-dialog.vue' |
| | | import TransferDetailDrawer from './modules/transfer-detail-drawer.vue' |
| | |
| | | import { |
| | | TRANSFER_REPORT_STYLE, |
| | | buildTransferDetailOrderQueryParams, |
| | | buildTransferDialogModel, |
| | | buildTransferItemsSavePayload, |
| | | buildTransferManageDialogModel, |
| | | buildTransferPageQueryParams, |
| | | buildTransferPrintRows, |
| | | buildTransferReportMeta, |
| | | buildTransferSavePayload, |
| | | buildTransferSearchParams, |
| | | createTransferFormState, |
| | | createTransferSearchState, |
| | |
| | | const searchForm = ref(createTransferSearchState()) |
| | | const typeOptions = ref([]) |
| | | const areaOptions = ref([]) |
| | | const fieldDefinitions = ref([]) |
| | | const selectedRows = ref([]) |
| | | const detailDrawerVisible = ref(false) |
| | | const detailLoading = ref(false) |
| | |
| | | |
| | | const reportQueryParams = computed(() => buildTransferSearchParams(searchForm.value)) |
| | | const searchItems = computed(() => [ |
| | | { label: t('pages.orders.transfer.search.condition'), key: 'condition', type: 'input', props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.condition') } }, |
| | | { label: t('pages.orders.transfer.search.code'), key: 'code', type: 'input', props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.code') } }, |
| | | { |
| | | label: t('pages.orders.transfer.search.condition'), |
| | | key: 'condition', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.condition') } |
| | | }, |
| | | { |
| | | label: t('pages.orders.transfer.search.code'), |
| | | key: 'code', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.code') } |
| | | }, |
| | | { |
| | | label: t('pages.orders.transfer.search.type'), |
| | | key: 'type', |
| | |
| | | type: 'select', |
| | | props: { clearable: true, options: getTransferExceStatusOptions(t) } |
| | | }, |
| | | { label: t('pages.orders.transfer.search.orgWareName'), key: 'orgWareName', type: 'input', props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.orgWareName') } }, |
| | | { label: t('pages.orders.transfer.search.tarWareName'), key: 'tarWareName', type: 'input', props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.tarWareName') } }, |
| | | { label: t('pages.orders.transfer.search.orgAreaName'), key: 'orgAreaName', type: 'input', props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.orgAreaName') } }, |
| | | { label: t('pages.orders.transfer.search.tarAreaName'), key: 'tarAreaName', type: 'input', props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.tarAreaName') } }, |
| | | { |
| | | label: t('pages.orders.transfer.search.timeStart'), |
| | | key: 'timeStart', |
| | | type: 'date', |
| | | props: { clearable: true, type: 'date', valueFormat: 'YYYY-MM-DD' } |
| | | }, |
| | | { |
| | | label: t('pages.orders.transfer.search.timeEnd'), |
| | | key: 'timeEnd', |
| | | type: 'date', |
| | | props: { clearable: true, type: 'date', valueFormat: 'YYYY-MM-DD' } |
| | | }, |
| | | { |
| | | label: t('pages.orders.transfer.search.orgWareId'), |
| | | key: 'orgWareId', |
| | | type: 'inputNumber', |
| | | props: { |
| | | clearable: true, |
| | | controlsPosition: 'right', |
| | | placeholder: t('pages.orders.transfer.placeholder.orgWareId') |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.orders.transfer.search.orgWareName'), |
| | | key: 'orgWareName', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.orgWareName') } |
| | | }, |
| | | { |
| | | label: t('pages.orders.transfer.search.tarWareId'), |
| | | key: 'tarWareId', |
| | | type: 'inputNumber', |
| | | props: { |
| | | clearable: true, |
| | | controlsPosition: 'right', |
| | | placeholder: t('pages.orders.transfer.placeholder.tarWareId') |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.orders.transfer.search.tarWareName'), |
| | | key: 'tarWareName', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.tarWareName') } |
| | | }, |
| | | { |
| | | label: t('pages.orders.transfer.search.orgAreaId'), |
| | | key: 'orgAreaId', |
| | | type: 'inputNumber', |
| | | props: { |
| | | clearable: true, |
| | | controlsPosition: 'right', |
| | | placeholder: t('pages.orders.transfer.placeholder.orgAreaId') |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.orders.transfer.search.orgAreaName'), |
| | | key: 'orgAreaName', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.orgAreaName') } |
| | | }, |
| | | { |
| | | label: t('pages.orders.transfer.search.tarAreaId'), |
| | | key: 'tarAreaId', |
| | | type: 'inputNumber', |
| | | props: { |
| | | clearable: true, |
| | | controlsPosition: 'right', |
| | | placeholder: t('pages.orders.transfer.placeholder.tarAreaId') |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.orders.transfer.search.tarAreaName'), |
| | | key: 'tarAreaName', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.tarAreaName') } |
| | | }, |
| | | { |
| | | label: t('pages.orders.transfer.search.status'), |
| | | key: 'status', |
| | | type: 'select', |
| | | props: { clearable: true, options: getTransferStatusOptions(t) } |
| | | }, |
| | | { label: t('pages.orders.transfer.search.memo'), key: 'memo', type: 'input', props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.memo') } } |
| | | { |
| | | label: t('pages.orders.transfer.search.memo'), |
| | | key: 'memo', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: t('pages.orders.transfer.placeholder.memo') } |
| | | } |
| | | ]) |
| | | |
| | | function handleSelectionChange(rows) { |
| | |
| | | } |
| | | } |
| | | |
| | | async function loadTransferOrders(code) { |
| | | async function loadTransferOrders(transferId, code) { |
| | | detailOrdersLoading.value = true |
| | | try { |
| | | const response = await guardRequestWithMessage( |
| | | fetchTransferOrdersPage( |
| | | buildTransferDetailOrderQueryParams({ |
| | | id: transferId, |
| | | code, |
| | | current: detailOrderPagination.current, |
| | | pageSize: detailOrderPagination.size |
| | | }) |
| | | ), |
| | | { records: [], total: 0, current: detailOrderPagination.current, size: detailOrderPagination.size }, |
| | | { |
| | | records: [], |
| | | total: 0, |
| | | current: detailOrderPagination.current, |
| | | size: detailOrderPagination.size |
| | | }, |
| | | { timeoutMessage: t('pages.orders.transfer.messages.ordersTimeout') } |
| | | ) |
| | | const normalized = defaultResponseAdapter(response) |
| | | detailOrderRows.value = normalized.records.map((item) => normalizeTransferOrderRow(item, t)) |
| | | detailOrderPagination.total = Number(normalized.total || 0) |
| | | detailOrderPagination.current = Number(normalized.current || detailOrderPagination.current || 1) |
| | | detailOrderPagination.current = Number( |
| | | normalized.current || detailOrderPagination.current || 1 |
| | | ) |
| | | detailOrderPagination.size = Number(normalized.size || detailOrderPagination.size || 20) |
| | | } catch (error) { |
| | | detailOrderRows.value = [] |
| | |
| | | try { |
| | | await loadTransferDetail(row.id) |
| | | activeTransferCode.value = detailData.value.code || row.code || activeTransferCode.value |
| | | await loadTransferOrders(activeTransferCode.value) |
| | | await loadTransferOrders(row.id, activeTransferCode.value) |
| | | } catch (error) { |
| | | detailDrawerVisible.value = false |
| | | detailData.value = {} |
| | |
| | | |
| | | async function openEditDialog(row) { |
| | | try { |
| | | const detail = await guardRequestWithMessage( |
| | | fetchTransferDetail(row.id), |
| | | {}, |
| | | { timeoutMessage: t('pages.orders.transfer.messages.detailTimeout') } |
| | | ) |
| | | showDialog('edit', detail) |
| | | const [detail, itemResponse] = await Promise.all([ |
| | | guardRequestWithMessage( |
| | | fetchTransferDetail(row.id), |
| | | {}, |
| | | { timeoutMessage: t('pages.orders.transfer.messages.detailTimeout') } |
| | | ), |
| | | guardRequestWithMessage(fetchTransferItemList({ transferId: row.id }), [], { |
| | | timeoutMessage: t('pages.orders.transfer.messages.itemsTimeout') |
| | | }) |
| | | ]) |
| | | const itemRecords = Array.isArray(itemResponse) |
| | | ? itemResponse |
| | | : defaultResponseAdapter(itemResponse).records |
| | | showDialog('edit', { |
| | | transfer: detail, |
| | | items: itemRecords |
| | | }) |
| | | } catch (error) { |
| | | ElMessage.error(error?.message || t('pages.orders.transfer.messages.detailLoadFailed')) |
| | | } |
| | |
| | | |
| | | async function handlePublish(row) { |
| | | try { |
| | | await ElMessageBox.confirm(t('pages.orders.transfer.messages.publishConfirm', { code: row.code || row.id }), t('pages.orders.transfer.messages.publishTitle'), { |
| | | confirmButtonText: t('common.confirm'), |
| | | cancelButtonText: t('common.cancel'), |
| | | type: 'warning' |
| | | }) |
| | | const response = await fetchTransferPubOutStock({ id: row.id }) |
| | | if (response?.code !== 200 && response?.success !== true) { |
| | | throw new Error(response?.message || t('pages.orders.transfer.messages.publishFailed')) |
| | | } |
| | | ElMessage.success(response?.message || t('pages.orders.transfer.messages.publishSuccess')) |
| | | await ElMessageBox.confirm( |
| | | t('pages.orders.transfer.messages.publishConfirm', { code: row.code || row.id }), |
| | | t('pages.orders.transfer.messages.publishTitle'), |
| | | { |
| | | confirmButtonText: t('common.confirm'), |
| | | cancelButtonText: t('common.cancel'), |
| | | type: 'warning' |
| | | } |
| | | ) |
| | | await fetchTransferPubOutStock({ id: row.id }) |
| | | ElMessage.success(t('pages.orders.transfer.messages.publishSuccess')) |
| | | await refreshData() |
| | | if (detailDrawerVisible.value && activeTransferId.value === row.id) { |
| | | await loadTransferDetail(row.id) |
| | | await loadTransferOrders(row.code || activeTransferCode.value) |
| | | await loadTransferOrders(row.id, row.code || activeTransferCode.value) |
| | | } |
| | | router.push('/orders/out-stock') |
| | | } catch (error) { |
| | | if (error === 'cancel' || error?.message === 'cancel') return |
| | | ElMessage.error(error?.message || t('pages.orders.transfer.messages.publishFailed')) |
| | |
| | | apiFn: fetchTransferPage, |
| | | apiParams: buildTransferPageQueryParams(searchForm.value), |
| | | paginationKey: getTransferPaginationKey(), |
| | | columnsFactory: () => createTransferTableColumns({ handleActionClick }) |
| | | columnsFactory: () => |
| | | createTransferTableColumns({ |
| | | handleActionClick, |
| | | handleViewOrder: handleViewRelatedOrder |
| | | }) |
| | | }, |
| | | transform: { |
| | | dataTransformer: (records) => (Array.isArray(records) ? records.map((item) => normalizeTransferRow(item, t)) : []) |
| | | dataTransformer: (records) => |
| | | Array.isArray(records) ? records.map((item) => normalizeTransferRow(item, t)) : [] |
| | | } |
| | | }) |
| | | |
| | |
| | | dialogVisible, |
| | | dialogType, |
| | | currentRecord: currentTransferData, |
| | | selectedRows: crudSelectedRows, |
| | | handleSelectionChange: handleCrudSelectionChange, |
| | | showDialog, |
| | | handleDialogSubmit: handleCrudDialogSubmit, |
| | | handleDelete, |
| | | handleBatchDelete |
| | | } = useCrudPage({ |
| | | createEmptyModel: () => createTransferFormState(), |
| | | buildEditModel: (record) => buildTransferDialogModel(record), |
| | | buildSavePayload: (formData) => buildTransferSavePayload(formData, areaOptions.value), |
| | | saveRequest: fetchSaveTransfer, |
| | | updateRequest: fetchUpdateTransfer, |
| | | createEmptyModel: () => ({ |
| | | transfer: createTransferFormState(), |
| | | items: [] |
| | | }), |
| | | buildEditModel: (record) => buildTransferManageDialogModel(record, fieldDefinitions.value), |
| | | buildSavePayload: (formData) => |
| | | buildTransferItemsSavePayload(formData, areaOptions.value, fieldDefinitions.value), |
| | | saveRequest: fetchSaveTransferItems, |
| | | updateRequest: fetchUpdateTransferItems, |
| | | deleteRequest: fetchDeleteTransfer, |
| | | entityName: t('pages.orders.transfer.entity'), |
| | | resolveRecordLabel: (record) => record?.code || record?.id, |
| | |
| | | |
| | | async function loadTypeOptions() { |
| | | const response = await guardRequestWithMessage( |
| | | fetchDictDataPage({ current: 1, pageSize: 200, dictTypeCode: 'sys_transfer_type', status: 1 }), |
| | | fetchDictDataPage({ |
| | | current: 1, |
| | | pageSize: 200, |
| | | dictTypeCode: 'sys_transfer_type', |
| | | status: 1 |
| | | }), |
| | | { records: [] }, |
| | | { timeoutMessage: t('pages.orders.transfer.messages.typeOptionsTimeout') } |
| | | ) |
| | |
| | | areaOptions.value = resolveTransferAreaOptions(defaultResponseAdapter(response).records) |
| | | } |
| | | |
| | | async function loadFieldDefinitions() { |
| | | const records = await guardRequestWithMessage(fetchEnabledTransferFields(), [], { |
| | | timeoutMessage: t('pages.orders.transfer.messages.fieldTimeout') |
| | | }) |
| | | fieldDefinitions.value = Array.isArray(records) ? records : [] |
| | | } |
| | | |
| | | function handleViewRelatedOrder(row) { |
| | | if (row?.type === 'out') { |
| | | router.push('/orders/out-stock') |
| | | return |
| | | } |
| | | if (row?.type === 'in') { |
| | | router.push('/orders/asn-order') |
| | | } |
| | | } |
| | | |
| | | function handleSearch(params) { |
| | | searchForm.value = { ...searchForm.value, ...params } |
| | | replaceSearchParams(buildTransferSearchParams(searchForm.value)) |
| | |
| | | |
| | | async function handleDetailCurrentChange(current) { |
| | | detailOrderPagination.current = current |
| | | await loadTransferOrders(activeTransferCode.value) |
| | | await loadTransferOrders(activeTransferId.value, activeTransferCode.value) |
| | | } |
| | | |
| | | async function handleDetailSizeChange(size) { |
| | | detailOrderPagination.size = size |
| | | detailOrderPagination.current = 1 |
| | | await loadTransferOrders(activeTransferCode.value) |
| | | await loadTransferOrders(activeTransferId.value, activeTransferCode.value) |
| | | } |
| | | |
| | | const resolvePrintRecords = async (payload) => { |
| | |
| | | await fetchTransferPage({ |
| | | ...reportQueryParams.value, |
| | | current: 1, |
| | | pageSize: Number(pagination.total) > 0 ? Number(pagination.total) : Number(payload?.pageSize) || 20 |
| | | pageSize: |
| | | Number(pagination.total) > 0 ? Number(pagination.total) : Number(payload?.pageSize) || 20 |
| | | }) |
| | | ).records |
| | | } |
| | |
| | | } = usePrintExportPage({ |
| | | downloadFileName: 'transfer.xlsx', |
| | | requestExport: (payload) => |
| | | fetchExportTransferReport(Array.isArray(payload?.ids) && payload.ids.length > 0 ? reportQueryParams.value : payload, { |
| | | headers: { |
| | | Authorization: userStore.accessToken || '' |
| | | fetchExportTransferReport( |
| | | Array.isArray(payload?.ids) && payload.ids.length > 0 ? reportQueryParams.value : payload, |
| | | { |
| | | headers: { |
| | | Authorization: userStore.accessToken || '' |
| | | } |
| | | } |
| | | }), |
| | | ), |
| | | resolvePrintRecords, |
| | | buildPreviewRows: (records) => buildTransferPrintRows(records, t), |
| | | buildPreviewMeta: (rows) => { |
| | |
| | | buildTransferReportMeta({ |
| | | previewMeta: rawPreviewMeta.value, |
| | | count: previewRows.value.length, |
| | | orientation: rawPreviewMeta.value?.reportStyle?.orientation || TRANSFER_REPORT_STYLE.orientation, |
| | | orientation: |
| | | rawPreviewMeta.value?.reportStyle?.orientation || TRANSFER_REPORT_STYLE.orientation, |
| | | t |
| | | }) |
| | | ) |
| | | |
| | | onMounted(async () => { |
| | | await Promise.allSettled([loadTypeOptions(), loadAreaOptions()]) |
| | | await Promise.allSettled([loadTypeOptions(), loadAreaOptions(), loadFieldDefinitions()]) |
| | | }) |
| | | </script> |
| | |
| | | </div> |
| | | <div v-else class="space-y-4"> |
| | | <ElDescriptions :title="t('pages.orders.transfer.detail.baseInfo')" :column="2" border> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.code')">{{ detail.code || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.type')">{{ detail.typeLabel || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.code')">{{ |
| | | detail.code || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.type')">{{ |
| | | detail.typeLabel || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.source')"> |
| | | <ElTag :type="detail.sourceTagType || 'info'" effect="light"> |
| | | {{ detail.sourceText || '--' }} |
| | |
| | | {{ detail.exceStatusText || '--' }} |
| | | </ElTag> |
| | | </ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.orgWareName')">{{ detail.orgWareName || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.tarWareName')">{{ detail.tarWareName || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.orgAreaName')">{{ detail.orgAreaName || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.tarAreaName')">{{ detail.tarAreaName || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.orgWareName')">{{ |
| | | detail.orgWareName || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.tarWareName')">{{ |
| | | detail.tarWareName || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.orgAreaName')">{{ |
| | | detail.orgAreaName || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.tarAreaName')">{{ |
| | | detail.tarAreaName || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.status')"> |
| | | <ElTag :type="detail.statusType || 'info'" effect="light"> |
| | | {{ detail.statusText || '--' }} |
| | | </ElTag> |
| | | </ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.memo')" :span="2">{{ detail.memo || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.memo')" :span="2">{{ |
| | | detail.memo || '--' |
| | | }}</ElDescriptionsItem> |
| | | </ElDescriptions> |
| | | |
| | | <ElDescriptions :title="t('pages.orders.transfer.detail.auditInfo')" :column="2" border> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.createBy')">{{ detail.createByText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.createTime')">{{ detail.createTimeText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.updateBy')">{{ detail.updateByText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.updateTime')">{{ detail.updateTimeText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.createBy')">{{ |
| | | detail.createByText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.createTime')">{{ |
| | | detail.createTimeText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.updateBy')">{{ |
| | | detail.updateByText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.transfer.detail.updateTime')">{{ |
| | | detail.updateTimeText || '--' |
| | | }}</ElDescriptionsItem> |
| | | </ElDescriptions> |
| | | |
| | | <div class="space-y-3"> |
| | | <div class="flex items-center justify-between"> |
| | | <div class="text-sm font-medium text-[var(--art-gray-900)]">{{ t('pages.orders.transfer.detail.relatedOrders') }}</div> |
| | | <div class="text-sm font-medium text-[var(--art-gray-900)]">{{ |
| | | t('pages.orders.transfer.detail.relatedOrders') |
| | | }}</div> |
| | | <ElTag effect="plain">{{ t('common.count', { count: orderRows.length }) }}</ElTag> |
| | | </div> |
| | | <ArtTable |
| | |
| | | ordersLoading: { type: Boolean, default: false }, |
| | | detail: { type: Object, default: () => ({}) }, |
| | | orderRows: { type: Array, default: () => [] }, |
| | | orderPagination: { type: Object, default: () => ({ current: 1, size: 20, total: 0 }) } |
| | | orderPagination: { type: Object, default: () => ({ current: 1, size: 20, total: 0 }) }, |
| | | onOrderView: { type: Function, default: null } |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:visible', 'size-change', 'current-change']) |
| | | const { t } = useI18n() |
| | | |
| | | const orderColumns = createTransferOrderTableColumns() |
| | | const orderColumns = computed(() => |
| | | createTransferOrderTableColumns({ |
| | | handleViewOrder: props.onOrderView |
| | | }) |
| | | ) |
| | | |
| | | const visible = computed({ |
| | | get: () => props.visible, |
| | |
| | | <template> |
| | | <ElDialog |
| | | :model-value="visible" |
| | | :title="dialogTitle" |
| | | width="92%" |
| | | top="4vh" |
| | | destroy-on-close |
| | | @update:model-value="handleVisibleChange" |
| | | @closed="handleClosed" |
| | | > |
| | | <div class="flex flex-col gap-4"> |
| | | <ArtForm |
| | | ref="formRef" |
| | | v-model="form" |
| | | :items="formItems" |
| | | :rules="rules" |
| | | :span="8" |
| | | :gutter="20" |
| | | label-width="110px" |
| | | :show-reset="false" |
| | | :show-submit="false" |
| | | /> |
| | | |
| | | <div class="flex flex-wrap items-center justify-between gap-3"> |
| | | <ElSpace wrap> |
| | | <ElButton type="primary" @click="handleOpenMaterialDialog"> |
| | | {{ t('pages.orders.transfer.dialog.addMaterial') }} |
| | | </ElButton> |
| | | <ElButton |
| | | type="danger" |
| | | plain |
| | | :disabled="isEdit || selectedItemKeys.length === 0" |
| | | @click="handleBatchRemove" |
| | | > |
| | | {{ t('pages.orders.transfer.dialog.deleteSelected') }} |
| | | </ElButton> |
| | | </ElSpace> |
| | | <div class="text-xs text-[var(--art-gray-600)]"> |
| | | {{ t('pages.orders.transfer.dialog.itemCount', { count: itemRows.length }) }} |
| | | </div> |
| | | </div> |
| | | |
| | | <ElTable |
| | | :data="itemRows" |
| | | row-key="__rowKey" |
| | | border |
| | | size="small" |
| | | max-height="420" |
| | | @selection-change="handleItemSelectionChange" |
| | | > |
| | | <ElTableColumn type="selection" width="48" align="center" /> |
| | | <ElTableColumn type="index" :label="t('table.index')" width="72" align="center" /> |
| | | <ElTableColumn |
| | | prop="matnrCode" |
| | | :label="t('table.materialCode')" |
| | | min-width="140" |
| | | show-overflow-tooltip |
| | | /> |
| | | <ElTableColumn |
| | | prop="maktx" |
| | | :label="t('table.materialName')" |
| | | min-width="220" |
| | | show-overflow-tooltip |
| | | /> |
| | | <ElTableColumn |
| | | prop="spec" |
| | | :label="t('pages.orders.transferItem.table.spec')" |
| | | min-width="140" |
| | | show-overflow-tooltip |
| | | /> |
| | | <ElTableColumn |
| | | prop="model" |
| | | :label="t('pages.orders.transferItem.table.model')" |
| | | min-width="140" |
| | | show-overflow-tooltip |
| | | /> |
| | | <ElTableColumn :label="t('table.quantity')" width="150" align="right"> |
| | | <template #default="{ row }"> |
| | | <ElInputNumber |
| | | v-model="row.anfme" |
| | | :min="0" |
| | | :precision="2" |
| | | controls-position="right" |
| | | class="w-full" |
| | | /> |
| | | </template> |
| | | </ElTableColumn> |
| | | <ElTableColumn |
| | | :label="t('pages.orders.transfer.dialog.supplierCode')" |
| | | min-width="150" |
| | | show-overflow-tooltip |
| | | > |
| | | <template #default="{ row }"> |
| | | <ElInput v-model="row.splrCode" clearable /> |
| | | </template> |
| | | </ElTableColumn> |
| | | <ElTableColumn |
| | | :label="t('pages.orders.transfer.dialog.supplierName')" |
| | | min-width="180" |
| | | show-overflow-tooltip |
| | | > |
| | | <template #default="{ row }"> |
| | | <ElInput v-model="row.splrName" clearable /> |
| | | </template> |
| | | </ElTableColumn> |
| | | <ElTableColumn :label="t('table.batch')" min-width="140" show-overflow-tooltip> |
| | | <template #default="{ row }"> |
| | | <ElInput v-model="row.batch" clearable /> |
| | | </template> |
| | | </ElTableColumn> |
| | | <ElTableColumn :label="t('table.unit')" width="120" align="center"> |
| | | <template #default="{ row }"> |
| | | <ElInput v-model="row.unit" clearable /> |
| | | </template> |
| | | </ElTableColumn> |
| | | <ElTableColumn |
| | | v-for="field in fieldDefinitions" |
| | | :key="field.fields" |
| | | :label="field.fieldsAlise || field.fields" |
| | | min-width="140" |
| | | > |
| | | <template #default="{ row }"> |
| | | <ElInput v-model="row[field.fields]" clearable /> |
| | | </template> |
| | | </ElTableColumn> |
| | | <ElTableColumn :label="t('table.operation')" fixed="right" width="88" align="center"> |
| | | <template #default="{ row }"> |
| | | <ElButton link type="danger" :disabled="isEdit" @click="handleRemoveRow(row)"> |
| | | {{ t('pages.orders.transfer.actions.delete') }} |
| | | </ElButton> |
| | | </template> |
| | | </ElTableColumn> |
| | | </ElTable> |
| | | </div> |
| | | |
| | | <template #footer> |
| | | <ElSpace> |
| | | <ElButton @click="handleVisibleChange(false)">{{ t('common.cancel') }}</ElButton> |
| | | <ElButton type="primary" :loading="submitLoading" @click="handleSubmit"> |
| | | {{ t('common.confirm') }} |
| | | </ElButton> |
| | | </ElSpace> |
| | | </template> |
| | | |
| | | <TransferMaterialDialog |
| | | v-model:visible="materialDialogVisible" |
| | | :org-area-id="form.orgAreaId" |
| | | :field-definitions="fieldDefinitions" |
| | | :selected-matnr-ids="selectedMatnrIds" |
| | | @confirm="handleMaterialConfirm" |
| | | /> |
| | | </ElDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, nextTick, reactive, ref, watch } from 'vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { useI18n } from 'vue-i18n' |
| | | import ArtForm from '@/components/core/forms/art-form/index.vue' |
| | | import { |
| | | buildTransferDialogModel, |
| | | createTransferFormState, |
| | | getTransferStatusOptions |
| | | buildTransferManageDialogModel, |
| | | createTransferEditableItemFromMaterial, |
| | | createTransferFormState |
| | | } from '../transferPage.helpers.js' |
| | | import TransferMaterialDialog from './transfer-material-dialog.vue' |
| | | |
| | | const props = defineProps({ |
| | | visible: { type: Boolean, default: false }, |
| | | dialogType: { type: String, default: 'add' }, |
| | | transferData: { type: Object, default: () => ({}) }, |
| | | transferData: { |
| | | type: Object, |
| | | default: () => ({ |
| | | transfer: {}, |
| | | items: [] |
| | | }) |
| | | }, |
| | | typeOptions: { type: Array, default: () => [] }, |
| | | areaOptions: { type: Array, default: () => [] }, |
| | | fieldDefinitions: { type: Array, default: () => [] }, |
| | | submitLoading: { type: Boolean, default: false } |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:visible', 'submit']) |
| | | const { t } = useI18n() |
| | | |
| | | const formRef = ref() |
| | | const form = reactive(createTransferFormState()) |
| | | const { t } = useI18n() |
| | | const itemRows = ref([]) |
| | | const selectedItemKeys = ref([]) |
| | | const materialDialogVisible = ref(false) |
| | | |
| | | const isEdit = computed(() => props.dialogType === 'edit') |
| | | const dialogTitle = computed(() => |
| | | isEdit.value ? t('pages.orders.transfer.dialog.titleEdit') : t('pages.orders.transfer.dialog.titleAdd') |
| | | isEdit.value |
| | | ? t('pages.orders.transfer.dialog.titleEdit') |
| | | : t('pages.orders.transfer.dialog.titleAdd') |
| | | ) |
| | | const selectedMatnrIds = computed(() => |
| | | itemRows.value.map((item) => item.matnrId).filter((item) => item !== undefined && item !== null) |
| | | ) |
| | | |
| | | const rules = computed(() => ({ |
| | | type: [{ required: true, message: t('pages.orders.transfer.dialog.validation.type'), trigger: 'change' }], |
| | | orgAreaId: [{ required: true, message: t('pages.orders.transfer.dialog.validation.orgAreaId'), trigger: 'change' }], |
| | | tarAreaId: [{ required: true, message: t('pages.orders.transfer.dialog.validation.tarAreaId'), trigger: 'change' }] |
| | | type: [ |
| | | { |
| | | required: true, |
| | | message: t('pages.orders.transfer.dialog.validation.type'), |
| | | trigger: 'change' |
| | | } |
| | | ], |
| | | orgAreaId: [ |
| | | { |
| | | required: true, |
| | | message: t('pages.orders.transfer.dialog.validation.orgAreaId'), |
| | | trigger: 'change' |
| | | } |
| | | ], |
| | | tarAreaId: [ |
| | | { |
| | | required: true, |
| | | message: t('pages.orders.transfer.dialog.validation.tarAreaId'), |
| | | trigger: 'change' |
| | | } |
| | | ] |
| | | })) |
| | | |
| | | const formItems = computed(() => [ |
| | |
| | | props: { |
| | | placeholder: t('pages.orders.transfer.dialog.placeholderStatus'), |
| | | clearable: true, |
| | | options: getTransferStatusOptions() |
| | | options: [ |
| | | { label: t('pages.orders.transfer.status.normal'), value: 1 }, |
| | | { label: t('pages.orders.transfer.status.frozen'), value: 0 } |
| | | ] |
| | | } |
| | | }, |
| | | { |
| | |
| | | } |
| | | ]) |
| | | |
| | | const loadFormData = () => { |
| | | Object.assign(form, buildTransferDialogModel(props.transferData)) |
| | | function loadDialogData() { |
| | | const dialogData = buildTransferManageDialogModel(props.transferData, props.fieldDefinitions) |
| | | Object.assign(form, dialogData.transfer) |
| | | itemRows.value = dialogData.items |
| | | selectedItemKeys.value = [] |
| | | } |
| | | |
| | | const resetForm = () => { |
| | | function resetDialogData() { |
| | | Object.assign(form, createTransferFormState()) |
| | | itemRows.value = [] |
| | | selectedItemKeys.value = [] |
| | | materialDialogVisible.value = false |
| | | formRef.value?.clearValidate?.() |
| | | } |
| | | |
| | | const handleSubmit = async () => { |
| | | function handleItemSelectionChange(rows) { |
| | | selectedItemKeys.value = Array.isArray(rows) ? rows.map((item) => item.__rowKey) : [] |
| | | } |
| | | |
| | | function handleRemoveRow(row) { |
| | | itemRows.value = itemRows.value.filter((item) => item.__rowKey !== row.__rowKey) |
| | | selectedItemKeys.value = selectedItemKeys.value.filter((item) => item !== row.__rowKey) |
| | | } |
| | | |
| | | function handleBatchRemove() { |
| | | if (!selectedItemKeys.value.length) return |
| | | const selectedKeySet = new Set(selectedItemKeys.value) |
| | | itemRows.value = itemRows.value.filter((item) => !selectedKeySet.has(item.__rowKey)) |
| | | selectedItemKeys.value = [] |
| | | } |
| | | |
| | | function handleOpenMaterialDialog() { |
| | | if (!form.orgAreaId) { |
| | | ElMessage.warning(t('pages.orders.transfer.dialog.validation.orgAreaId')) |
| | | return |
| | | } |
| | | if (!form.tarAreaId) { |
| | | ElMessage.warning(t('pages.orders.transfer.dialog.validation.tarAreaId')) |
| | | return |
| | | } |
| | | materialDialogVisible.value = true |
| | | } |
| | | |
| | | function handleMaterialConfirm(rows) { |
| | | const existingMatnrIds = new Set(selectedMatnrIds.value) |
| | | const nextRows = rows |
| | | .map((item) => createTransferEditableItemFromMaterial(item, props.fieldDefinitions)) |
| | | .filter((item) => !existingMatnrIds.has(item.matnrId)) |
| | | |
| | | if (!nextRows.length) { |
| | | ElMessage.warning(t('pages.orders.transfer.dialog.materialDuplicate')) |
| | | return |
| | | } |
| | | |
| | | itemRows.value = [...itemRows.value, ...nextRows] |
| | | } |
| | | |
| | | function validateItems() { |
| | | if (!itemRows.value.length) { |
| | | ElMessage.warning(t('pages.orders.transfer.dialog.validation.items')) |
| | | return false |
| | | } |
| | | |
| | | const invalidRow = itemRows.value.find((item) => Number(item.anfme) <= 0) |
| | | if (invalidRow) { |
| | | ElMessage.warning(t('pages.orders.transfer.dialog.validation.anfme')) |
| | | return false |
| | | } |
| | | |
| | | return true |
| | | } |
| | | |
| | | async function handleSubmit() { |
| | | if (!formRef.value) return |
| | | |
| | | try { |
| | | await formRef.value.validate() |
| | | emit('submit', { ...form }) |
| | | } catch { |
| | | return |
| | | } |
| | | |
| | | if (!validateItems()) { |
| | | return |
| | | } |
| | | |
| | | emit('submit', { |
| | | transfer: { ...form }, |
| | | items: itemRows.value.map((item) => ({ ...item })) |
| | | }) |
| | | } |
| | | |
| | | const handleCancel = () => { |
| | | emit('update:visible', false) |
| | | function handleVisibleChange(visible) { |
| | | emit('update:visible', visible) |
| | | } |
| | | |
| | | const handleClosed = () => { |
| | | resetForm() |
| | | function handleClosed() { |
| | | resetDialogData() |
| | | } |
| | | |
| | | watch( |
| | | () => props.visible, |
| | | (visible) => { |
| | | if (visible) { |
| | | loadFormData() |
| | | loadDialogData() |
| | | nextTick(() => { |
| | | formRef.value?.clearValidate?.() |
| | | }) |
| | |
| | | () => props.transferData, |
| | | () => { |
| | | if (props.visible) { |
| | | loadFormData() |
| | | loadDialogData() |
| | | } |
| | | }, |
| | | { deep: true } |
| | | ) |
| | | </script> |
| | | |
| | | <template> |
| | | <ElDialog |
| | | :title="dialogTitle" |
| | | :model-value="visible" |
| | | width="760px" |
| | | align-center |
| | | destroy-on-close |
| | | @update:model-value="handleCancel" |
| | | @closed="handleClosed" |
| | | > |
| | | <div class="mb-3 rounded-lg border border-[var(--art-border-color)] bg-[var(--art-bg-color)] px-3 py-2 text-xs text-[var(--art-text-gray-600)]"> |
| | | {{ t('pages.orders.transfer.dialog.tip') }} |
| | | </div> |
| | | |
| | | <ArtForm |
| | | ref="formRef" |
| | | v-model="form" |
| | | :items="formItems" |
| | | :rules="rules" |
| | | :span="12" |
| | | :gutter="20" |
| | | label-width="110px" |
| | | :show-reset="false" |
| | | :show-submit="false" |
| | | /> |
| | | |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <ElButton @click="handleCancel">{{ t('common.cancel') }}</ElButton> |
| | | <ElButton type="primary" :loading="submitLoading" @click="handleSubmit">{{ t('common.confirm') }}</ElButton> |
| | | </span> |
| | | </template> |
| | | </ElDialog> |
| | | </template> |
| New file |
| | |
| | | <template> |
| | | <ElDialog |
| | | :model-value="visible" |
| | | :title="t('pages.orders.transfer.materialDialog.title')" |
| | | width="88%" |
| | | top="5vh" |
| | | destroy-on-close |
| | | @update:model-value="handleVisibleChange" |
| | | > |
| | | <div class="flex flex-col gap-4"> |
| | | <ArtSearchBar |
| | | v-model="searchForm" |
| | | :items="searchItems" |
| | | :showExpand="false" |
| | | @search="handleSearch" |
| | | @reset="handleReset" |
| | | /> |
| | | |
| | | <ArtTable |
| | | :loading="loading" |
| | | :data="data" |
| | | :columns="columns" |
| | | :pagination="pagination" |
| | | @selection-change="handleSelectionChange" |
| | | @pagination:size-change="handleSizeChange" |
| | | @pagination:current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | |
| | | <template #footer> |
| | | <ElSpace> |
| | | <ElButton @click="handleVisibleChange(false)">{{ t('common.cancel') }}</ElButton> |
| | | <ElButton type="primary" @click="handleConfirm">{{ t('common.confirm') }}</ElButton> |
| | | </ElSpace> |
| | | </template> |
| | | </ElDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, h, ref, watch } from 'vue' |
| | | import { ElTag } from 'element-plus' |
| | | import { useI18n } from 'vue-i18n' |
| | | import { useTable } from '@/hooks/core/useTable' |
| | | import { fetchTransferLocsItemsPage } from '@/api/transfer' |
| | | import { |
| | | createTransferEditableItemFromMaterial, |
| | | createTransferMaterialSearchState |
| | | } from '../transferPage.helpers' |
| | | |
| | | const props = defineProps({ |
| | | visible: { type: Boolean, default: false }, |
| | | orgAreaId: { type: [Number, String], default: undefined }, |
| | | fieldDefinitions: { type: Array, default: () => [] }, |
| | | selectedMatnrIds: { type: Array, default: () => [] } |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:visible', 'confirm']) |
| | | const { t } = useI18n() |
| | | |
| | | const searchForm = ref(createTransferMaterialSearchState()) |
| | | const selectedRows = ref([]) |
| | | |
| | | const searchItems = computed(() => [ |
| | | { |
| | | label: t('table.materialName'), |
| | | key: 'maktx', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: t('pages.orders.transfer.materialDialog.placeholder.maktx') |
| | | } |
| | | }, |
| | | { |
| | | label: t('table.materialCode'), |
| | | key: 'matnrCode', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: t('pages.orders.transfer.materialDialog.placeholder.matnrCode') |
| | | } |
| | | } |
| | | ]) |
| | | |
| | | const createColumns = () => { |
| | | const baseColumns = [ |
| | | { type: 'selection', width: 48, align: 'center' }, |
| | | { type: 'globalIndex', label: t('table.index'), width: 72, align: 'center' }, |
| | | { |
| | | prop: 'matnrCode', |
| | | label: t('table.materialCode'), |
| | | minWidth: 150, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'maktx', |
| | | label: t('table.materialName'), |
| | | minWidth: 220, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'spec', |
| | | label: t('pages.orders.transferItem.table.spec'), |
| | | minWidth: 140, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'model', |
| | | label: t('pages.orders.transferItem.table.model'), |
| | | minWidth: 140, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'batch', |
| | | label: t('table.batch'), |
| | | minWidth: 140, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'unit', |
| | | label: t('table.unit'), |
| | | width: 100, |
| | | align: 'center' |
| | | }, |
| | | { |
| | | prop: 'anfme', |
| | | label: t('table.quantity'), |
| | | width: 110, |
| | | align: 'right' |
| | | }, |
| | | { |
| | | prop: 'selected', |
| | | label: t('pages.orders.transfer.materialDialog.table.status'), |
| | | width: 110, |
| | | formatter: (row) => |
| | | h( |
| | | ElTag, |
| | | { |
| | | type: props.selectedMatnrIds.includes(row.matnrId) ? 'warning' : 'info', |
| | | effect: 'light' |
| | | }, |
| | | () => |
| | | props.selectedMatnrIds.includes(row.matnrId) |
| | | ? t('pages.orders.transfer.materialDialog.selected') |
| | | : t('pages.orders.transfer.materialDialog.unselected') |
| | | ) |
| | | } |
| | | ] |
| | | |
| | | return [ |
| | | ...baseColumns, |
| | | ...props.fieldDefinitions.map((item) => ({ |
| | | prop: item.fields, |
| | | label: item.fieldsAlise || item.fields, |
| | | minWidth: 140, |
| | | showOverflowTooltip: true, |
| | | visible: false |
| | | })) |
| | | ] |
| | | } |
| | | |
| | | const { |
| | | data, |
| | | loading, |
| | | pagination, |
| | | columns, |
| | | replaceSearchParams, |
| | | handleSizeChange, |
| | | handleCurrentChange, |
| | | getData, |
| | | resetColumns |
| | | } = useTable({ |
| | | core: { |
| | | apiFn: fetchTransferLocsItemsPage, |
| | | apiParams: { |
| | | ...createTransferMaterialSearchState(), |
| | | orgAreaId: props.orgAreaId |
| | | }, |
| | | immediate: false, |
| | | columnsFactory: createColumns |
| | | }, |
| | | transform: { |
| | | dataTransformer: (records) => |
| | | Array.isArray(records) |
| | | ? records.map((item) => { |
| | | const editable = createTransferEditableItemFromMaterial(item, props.fieldDefinitions) |
| | | return { |
| | | ...item, |
| | | ...editable |
| | | } |
| | | }) |
| | | : [] |
| | | } |
| | | }) |
| | | |
| | | function buildParams() { |
| | | return { |
| | | ...searchForm.value, |
| | | orgAreaId: props.orgAreaId |
| | | } |
| | | } |
| | | |
| | | function handleSelectionChange(rows) { |
| | | selectedRows.value = Array.isArray(rows) ? rows : [] |
| | | } |
| | | |
| | | function handleSearch(params) { |
| | | searchForm.value = { ...searchForm.value, ...params } |
| | | replaceSearchParams(buildParams()) |
| | | getData() |
| | | } |
| | | |
| | | function handleReset() { |
| | | searchForm.value = createTransferMaterialSearchState() |
| | | replaceSearchParams(buildParams()) |
| | | getData() |
| | | } |
| | | |
| | | function handleConfirm() { |
| | | emit( |
| | | 'confirm', |
| | | selectedRows.value.map((item) => ({ ...item })) |
| | | ) |
| | | handleVisibleChange(false) |
| | | } |
| | | |
| | | function handleVisibleChange(visible) { |
| | | emit('update:visible', visible) |
| | | } |
| | | |
| | | watch( |
| | | () => props.visible, |
| | | (visible) => { |
| | | if (!visible) { |
| | | searchForm.value = createTransferMaterialSearchState() |
| | | selectedRows.value = [] |
| | | return |
| | | } |
| | | |
| | | searchForm.value = createTransferMaterialSearchState() |
| | | replaceSearchParams(buildParams()) |
| | | getData() |
| | | } |
| | | ) |
| | | |
| | | watch( |
| | | () => props.fieldDefinitions, |
| | | () => { |
| | | resetColumns?.() |
| | | }, |
| | | { deep: true } |
| | | ) |
| | | </script> |
| New file |
| | |
| | | <template> |
| | | <div class="transfer-orders-panel"> |
| | | <ArtTable :loading="loading" :data="rows" :columns="columns" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, ref, watch } from 'vue' |
| | | import { useI18n } from 'vue-i18n' |
| | | import { defaultResponseAdapter } from '@/utils/table/tableUtils' |
| | | import { fetchTransferOrdersPage } from '@/api/transfer' |
| | | import { |
| | | buildTransferDetailOrderQueryParams, |
| | | normalizeTransferOrderRow |
| | | } from '../transferPage.helpers.js' |
| | | import { createTransferOrderTableColumns } from '../transferTable.columns.js' |
| | | |
| | | defineOptions({ name: 'TransferOrdersPanel' }) |
| | | |
| | | const props = defineProps({ |
| | | transferId: { type: [Number, String], default: undefined }, |
| | | transferCode: { type: String, default: '' }, |
| | | onOrderView: { type: Function, default: null } |
| | | }) |
| | | |
| | | const loading = ref(false) |
| | | const rows = ref([]) |
| | | const { t } = useI18n() |
| | | |
| | | const columns = computed(() => |
| | | createTransferOrderTableColumns({ |
| | | handleViewOrder: props.onOrderView |
| | | }) |
| | | ) |
| | | |
| | | async function loadRows() { |
| | | if (props.transferId === undefined || props.transferId === null || props.transferId === '') { |
| | | rows.value = [] |
| | | return |
| | | } |
| | | |
| | | loading.value = true |
| | | try { |
| | | const response = await fetchTransferOrdersPage( |
| | | buildTransferDetailOrderQueryParams({ |
| | | id: props.transferId, |
| | | code: props.transferCode, |
| | | current: 1, |
| | | pageSize: 200 |
| | | }) |
| | | ) |
| | | const records = defaultResponseAdapter(response).records |
| | | rows.value = Array.isArray(records) |
| | | ? records.map((item) => normalizeTransferOrderRow(item, t)) |
| | | : [] |
| | | } catch { |
| | | rows.value = [] |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | watch( |
| | | () => [props.transferId, props.transferCode], |
| | | () => { |
| | | loadRows() |
| | | }, |
| | | { immediate: true } |
| | | ) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .transfer-orders-panel { |
| | | padding: 12px 0; |
| | | } |
| | | </style> |
| | |
| | | export function createTransferSearchState() { |
| | | return { |
| | | condition: '', |
| | | timeStart: '', |
| | | timeEnd: '', |
| | | code: '', |
| | | type: '', |
| | | source: '', |
| | | exceStatus: '', |
| | | orgWareId: '', |
| | | orgWareName: '', |
| | | tarWareId: '', |
| | | tarWareName: '', |
| | | orgAreaId: '', |
| | | orgAreaName: '', |
| | | tarAreaId: '', |
| | | tarAreaName: '', |
| | | memo: '', |
| | | status: '', |
| | | timeStart: '', |
| | | timeEnd: '' |
| | | orderBy: 'create_time desc' |
| | | } |
| | | } |
| | | |
| | |
| | | export function buildTransferDialogModel(record = {}) { |
| | | return { |
| | | ...createTransferFormState(), |
| | | ...(record.id !== undefined && record.id !== null && record.id !== '' ? { id: Number(record.id) } : {}), |
| | | ...(record.id !== undefined && record.id !== null && record.id !== '' |
| | | ? { id: Number(record.id) } |
| | | : {}), |
| | | code: normalizeText(record.code || ''), |
| | | type: record.type !== undefined && record.type !== null && record.type !== '' ? Number(record.type) : '', |
| | | source: record.source !== undefined && record.source !== null && record.source !== '' ? Number(record.source) : 2, |
| | | type: |
| | | record.type !== undefined && record.type !== null && record.type !== '' |
| | | ? Number(record.type) |
| | | : '', |
| | | source: |
| | | record.source !== undefined && record.source !== null && record.source !== '' |
| | | ? Number(record.source) |
| | | : 2, |
| | | exceStatus: |
| | | record.exceStatus !== undefined && record.exceStatus !== null && record.exceStatus !== '' |
| | | ? Number(record.exceStatus) |
| | |
| | | : void 0, |
| | | status: record.status !== undefined && record.status !== null ? Number(record.status) : 1, |
| | | memo: normalizeText(record.memo || '') |
| | | } |
| | | } |
| | | |
| | | function createTransferItemRowKey(record = {}) { |
| | | const keySeed = [ |
| | | record.id ?? 'new', |
| | | record.transferId ?? 'transfer', |
| | | record.matnrId ?? 'matnr', |
| | | record.batch ?? '', |
| | | record.fieldsIndex ?? '' |
| | | ] |
| | | return keySeed.join('-') |
| | | } |
| | | |
| | | function resolveDynamicFieldValues(record = {}, fieldDefinitions = []) { |
| | | return Object.fromEntries( |
| | | (Array.isArray(fieldDefinitions) ? fieldDefinitions : []).map((item) => [ |
| | | item.fields, |
| | | record[item.fields] ?? record.extendFields?.[item.fields] ?? '' |
| | | ]) |
| | | ) |
| | | } |
| | | |
| | | export function buildTransferManageDialogModel(record = {}, fieldDefinitions = []) { |
| | | const transferRecord = record?.transfer || record || {} |
| | | const itemRecords = Array.isArray(record?.items) ? record.items : [] |
| | | return { |
| | | transfer: buildTransferDialogModel(transferRecord), |
| | | items: itemRecords.map((item) => buildTransferEditableItem(item, fieldDefinitions)) |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | export function buildTransferSearchParams(params = {}) { |
| | | const result = {} |
| | | ;['condition', 'code', 'orgWareName', 'tarWareName', 'orgAreaName', 'tarAreaName', 'memo'].forEach((key) => { |
| | | ;[ |
| | | 'condition', |
| | | 'code', |
| | | 'orgWareName', |
| | | 'tarWareName', |
| | | 'orgAreaName', |
| | | 'tarAreaName', |
| | | 'memo' |
| | | ].forEach((key) => { |
| | | const value = normalizeText(params[key]) |
| | | if (value) result[key] = value |
| | | }) |
| | | ;['type', 'source', 'exceStatus', 'status', 'orgWareId', 'tarWareId', 'orgAreaId', 'tarAreaId'].forEach((key) => { |
| | | ;[ |
| | | 'type', |
| | | 'source', |
| | | 'exceStatus', |
| | | 'status', |
| | | 'orgWareId', |
| | | 'tarWareId', |
| | | 'orgAreaId', |
| | | 'tarAreaId' |
| | | ].forEach((key) => { |
| | | if (params[key] !== '' && params[key] !== undefined && params[key] !== null) { |
| | | result[key] = normalizeNumber(params[key]) |
| | | } |
| | |
| | | return { |
| | | current: params.current || 1, |
| | | pageSize: params.pageSize || params.size || 20, |
| | | orderBy: normalizeText(params.orderBy) || 'create_time desc', |
| | | ...buildTransferSearchParams(params) |
| | | } |
| | | } |
| | | |
| | | export function buildTransferDetailOrderQueryParams(params = {}) { |
| | | return { |
| | | ...(normalizeNumber(params.id, void 0) !== void 0 |
| | | ? { id: normalizeNumber(params.id, void 0) } |
| | | : {}), |
| | | condition: normalizeText(params.code || params.condition), |
| | | code: normalizeText(params.code || params.condition), |
| | | current: params.current || 1, |
| | | pageSize: params.pageSize || params.size || 20 |
| | | pageSize: params.pageSize || params.size || 20, |
| | | orderBy: normalizeText(params.orderBy) || 'create_time desc' |
| | | } |
| | | } |
| | | |
| | |
| | | const tarAreaId = normalizeNumber(formData.tarAreaId, void 0) |
| | | const orgArea = optionMap.get(orgAreaId) || {} |
| | | const tarArea = optionMap.get(tarAreaId) || {} |
| | | const orgWareId = normalizeNumber(orgArea.warehouseId ?? orgArea.warehouse_id ?? orgArea.warehouseIdValue, void 0) |
| | | const tarWareId = normalizeNumber(tarArea.warehouseId ?? tarArea.warehouse_id ?? tarArea.warehouseIdValue, void 0) |
| | | const orgWareId = normalizeNumber( |
| | | orgArea.warehouseId ?? orgArea.warehouse_id ?? orgArea.warehouseIdValue, |
| | | void 0 |
| | | ) |
| | | const tarWareId = normalizeNumber( |
| | | tarArea.warehouseId ?? tarArea.warehouse_id ?? tarArea.warehouseIdValue, |
| | | void 0 |
| | | ) |
| | | |
| | | return { |
| | | ...(formData.id !== undefined && formData.id !== null && formData.id !== '' |
| | |
| | | ...(formData.source !== undefined && formData.source !== null && formData.source !== '' |
| | | ? { source: normalizeNumber(formData.source) } |
| | | : {}), |
| | | ...(formData.exceStatus !== undefined && formData.exceStatus !== null && formData.exceStatus !== '' |
| | | ...(formData.exceStatus !== undefined && |
| | | formData.exceStatus !== null && |
| | | formData.exceStatus !== '' |
| | | ? { exceStatus: normalizeNumber(formData.exceStatus) } |
| | | : {}), |
| | | ...(orgAreaId !== void 0 ? { orgAreaId } : {}), |
| | | ...(tarAreaId !== void 0 ? { tarAreaId } : {}), |
| | | ...(orgWareId !== void 0 ? { orgWareId } : {}), |
| | | ...(tarWareId !== void 0 ? { tarWareId } : {}), |
| | | ...(normalizeText(orgArea.name || orgArea.areaName) ? { orgAreaName: normalizeText(orgArea.name || orgArea.areaName) } : {}), |
| | | ...(normalizeText(tarArea.name || tarArea.areaName) ? { tarAreaName: normalizeText(tarArea.name || tarArea.areaName) } : {}), |
| | | ...(normalizeText(orgArea.warehouseId$ || orgArea.warehouseName) ? { orgWareName: normalizeText(orgArea.warehouseId$ || orgArea.warehouseName) } : {}), |
| | | ...(normalizeText(tarArea.warehouseId$ || tarArea.warehouseName) ? { tarWareName: normalizeText(tarArea.warehouseId$ || tarArea.warehouseName) } : {}), |
| | | ...(normalizeText(orgArea.name || orgArea.areaName) |
| | | ? { orgAreaName: normalizeText(orgArea.name || orgArea.areaName) } |
| | | : {}), |
| | | ...(normalizeText(tarArea.name || tarArea.areaName) |
| | | ? { tarAreaName: normalizeText(tarArea.name || tarArea.areaName) } |
| | | : {}), |
| | | ...(normalizeText(orgArea.warehouseId$ || orgArea.warehouseName) |
| | | ? { orgWareName: normalizeText(orgArea.warehouseId$ || orgArea.warehouseName) } |
| | | : {}), |
| | | ...(normalizeText(tarArea.warehouseId$ || tarArea.warehouseName) |
| | | ? { tarWareName: normalizeText(tarArea.warehouseId$ || tarArea.warehouseName) } |
| | | : {}), |
| | | ...(formData.status !== undefined && formData.status !== null && formData.status !== '' |
| | | ? { status: normalizeNumber(formData.status) } |
| | | : { status: 1 }), |
| | |
| | | } |
| | | |
| | | function resolveAreaText(record = {}, key) { |
| | | return normalizeText(record[`${key}AreaName$`] || record[`${key}AreaName`] || record[`${key}AreaId$`] || record[`${key}AreaId`]) |
| | | return normalizeText( |
| | | record[`${key}AreaName$`] || |
| | | record[`${key}AreaName`] || |
| | | record[`${key}AreaId$`] || |
| | | record[`${key}AreaId`] |
| | | ) |
| | | } |
| | | |
| | | function resolveWarehouseText(record = {}, key) { |
| | | return normalizeText(record[`${key}WareName$`] || record[`${key}WareName`] || record[`${key}WareId$`] || record[`${key}WareId`]) |
| | | return normalizeText( |
| | | record[`${key}WareName$`] || |
| | | record[`${key}WareName`] || |
| | | record[`${key}WareId$`] || |
| | | record[`${key}WareId`] |
| | | ) |
| | | } |
| | | |
| | | export function normalizeTransferRow(record = {}, t = $t) { |
| | | const statusMeta = metaByValue(record.statusBool ?? record.status, getTransferStatusMetaMap(t), t('common.status.unknown')) |
| | | const exceStatusMeta = metaByValue(record.exceStatus, getTransferExceStatusMetaMap(t), record.exceStatusText) |
| | | const statusMeta = metaByValue( |
| | | record.statusBool ?? record.status, |
| | | getTransferStatusMetaMap(t), |
| | | t('common.status.unknown') |
| | | ) |
| | | const exceStatusMeta = metaByValue( |
| | | record.exceStatus, |
| | | getTransferExceStatusMetaMap(t), |
| | | record.exceStatusText |
| | | ) |
| | | const sourceMeta = metaByValue(record.source, getTransferSourceMetaMap(t), record.sourceText) |
| | | return { |
| | | ...record, |
| | |
| | | typeLabel: normalizeText(record['type$'] || record.type) || '--', |
| | | sourceText: sourceMeta.text, |
| | | sourceTagType: sourceMeta.type, |
| | | exceStatusText: normalizeText(record['exceStatus$'] || record.exceStatusText) || exceStatusMeta.text, |
| | | exceStatusText: |
| | | normalizeText(record['exceStatus$'] || record.exceStatusText) || exceStatusMeta.text, |
| | | exceStatusTagType: exceStatusMeta.type, |
| | | orgWareName: resolveWarehouseText(record, 'org') || '--', |
| | | tarWareName: resolveWarehouseText(record, 'tar') || '--', |
| | |
| | | statusType: statusMeta.type, |
| | | statusBool: record.statusBool !== void 0 ? Boolean(record.statusBool) : statusMeta.bool, |
| | | createByText: normalizeText(record['createBy$'] || record.createByText) || '--', |
| | | createTimeText: normalizeText(record['createTime$'] || record.createTimeText || record.createTime) || '--', |
| | | createTimeText: |
| | | normalizeText(record['createTime$'] || record.createTimeText || record.createTime) || '--', |
| | | updateByText: normalizeText(record['updateBy$'] || record.updateByText) || '--', |
| | | updateTimeText: normalizeText(record['updateTime$'] || record.updateTimeText || record.updateTime) || '--', |
| | | updateTimeText: |
| | | normalizeText(record['updateTime$'] || record.updateTimeText || record.updateTime) || '--', |
| | | memo: normalizeText(record.memo) || '--' |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | export function normalizeTransferOrderRow(record = {}, t = $t) { |
| | | const statusMeta = metaByValue(record.statusBool ?? record.status, getTransferStatusMetaMap(t), t('common.status.unknown')) |
| | | const exceStatusMeta = metaByValue(record.exceStatus, getTransferExceStatusMetaMap(t), record.exceStatusText) |
| | | const statusMeta = metaByValue( |
| | | record.statusBool ?? record.status, |
| | | getTransferStatusMetaMap(t), |
| | | t('common.status.unknown') |
| | | ) |
| | | const exceStatusMeta = metaByValue( |
| | | record.exceStatus, |
| | | getTransferExceStatusMetaMap(t), |
| | | record.exceStatusText |
| | | ) |
| | | return { |
| | | ...record, |
| | | id: record.id ?? null, |
| | |
| | | poCode: normalizeText(record.poCode) || '--', |
| | | typeLabel: normalizeText(record['type$'] || record.type) || '--', |
| | | wkTypeLabel: normalizeText(record['wkType$'] || record.wkType) || '--', |
| | | exceStatusText: normalizeText(record['exceStatus$'] || record.exceStatusText) || exceStatusMeta.text, |
| | | exceStatusText: |
| | | normalizeText(record['exceStatus$'] || record.exceStatusText) || exceStatusMeta.text, |
| | | exceStatusTagType: exceStatusMeta.type, |
| | | statusText: statusMeta.text, |
| | | statusType: statusMeta.type, |
| | |
| | | workQty: record.workQty ?? '--', |
| | | qty: record.qty ?? '--', |
| | | stationId: normalizeText(record.stationId) || '--', |
| | | businessTimeText: normalizeText(record['businessTime$'] || record.businessTimeText || record.businessTime) || '--', |
| | | businessTimeText: |
| | | normalizeText(record['businessTime$'] || record.businessTimeText || record.businessTime) || |
| | | '--', |
| | | createByText: normalizeText(record['createBy$'] || record.createByText) || '--', |
| | | createTimeText: normalizeText(record['createTime$'] || record.createTimeText || record.createTime) || '--', |
| | | createTimeText: |
| | | normalizeText(record['createTime$'] || record.createTimeText || record.createTime) || '--', |
| | | updateByText: normalizeText(record['updateBy$'] || record.updateByText) || '--', |
| | | updateTimeText: normalizeText(record['updateTime$'] || record.updateTimeText || record.updateTime) || '--', |
| | | updateTimeText: |
| | | normalizeText(record['updateTime$'] || record.updateTimeText || record.updateTime) || '--', |
| | | memo: normalizeText(record.memo) || '--' |
| | | } |
| | | } |
| | | |
| | | export function buildTransferEditableItem(record = {}, fieldDefinitions = []) { |
| | | return { |
| | | __rowKey: createTransferItemRowKey(record), |
| | | id: normalizeNumber(record.id, void 0), |
| | | transferId: normalizeNumber(record.transferId, void 0), |
| | | transferCode: normalizeText(record.transferCode || ''), |
| | | matnrId: normalizeNumber(record.matnrId, void 0), |
| | | maktx: normalizeText(record.maktx || ''), |
| | | matnrCode: normalizeText(record.matnrCode || ''), |
| | | anfme: normalizeNumber(record.anfme, 0) ?? 0, |
| | | splrCode: normalizeText(record.splrCode || ''), |
| | | splrName: normalizeText(record.splrName || ''), |
| | | batch: normalizeText(record.batch || ''), |
| | | unit: normalizeText(record.unit || record.stockUnit || ''), |
| | | stockUnit: normalizeText(record.stockUnit || record.unit || ''), |
| | | spec: normalizeText(record.spec || ''), |
| | | model: normalizeText(record.model || ''), |
| | | fieldsIndex: normalizeText(record.fieldsIndex || ''), |
| | | platItemId: normalizeText(record.platItemId || ''), |
| | | platOrderCode: normalizeText(record.platOrderCode || ''), |
| | | platWorkCode: normalizeText(record.platWorkCode || ''), |
| | | projectCode: normalizeText(record.projectCode || ''), |
| | | status: normalizeNumber(record.status, 1) ?? 1, |
| | | memo: normalizeText(record.memo || ''), |
| | | ...resolveDynamicFieldValues(record, fieldDefinitions) |
| | | } |
| | | } |
| | | |
| | | export function createTransferEditableItemFromMaterial(record = {}, fieldDefinitions = []) { |
| | | return { |
| | | __rowKey: createTransferItemRowKey({ |
| | | ...record, |
| | | id: void 0, |
| | | matnrId: record.matnrId ?? record.id |
| | | }), |
| | | id: void 0, |
| | | transferId: void 0, |
| | | transferCode: '', |
| | | matnrId: normalizeNumber(record.matnrId ?? record.id, void 0), |
| | | maktx: normalizeText(record.maktx || ''), |
| | | matnrCode: normalizeText(record.matnrCode || ''), |
| | | anfme: normalizeNumber(record.anfme, 0) ?? 0, |
| | | splrCode: '', |
| | | splrName: '', |
| | | batch: normalizeText(record.batch || ''), |
| | | unit: normalizeText(record.unit || record.stockUnit || ''), |
| | | stockUnit: normalizeText(record.stockUnit || record.unit || ''), |
| | | spec: normalizeText(record.spec || ''), |
| | | model: normalizeText(record.model || ''), |
| | | fieldsIndex: normalizeText(record.fieldsIndex || ''), |
| | | platItemId: '', |
| | | platOrderCode: '', |
| | | platWorkCode: '', |
| | | projectCode: '', |
| | | status: 1, |
| | | memo: '', |
| | | ...resolveDynamicFieldValues(record, fieldDefinitions) |
| | | } |
| | | } |
| | | |
| | | export function buildTransferItemsSavePayload( |
| | | formData = {}, |
| | | areaOptions = [], |
| | | fieldDefinitions = [] |
| | | ) { |
| | | const transfer = buildTransferSavePayload(formData.transfer || formData, areaOptions) |
| | | const rows = Array.isArray(formData.items) ? formData.items : [] |
| | | return { |
| | | transfer, |
| | | items: rows.map((item) => { |
| | | const payload = { |
| | | ...(item.id !== undefined && item.id !== null && item.id !== '' |
| | | ? { id: normalizeNumber(item.id, void 0) } |
| | | : {}), |
| | | ...(item.transferId !== undefined && item.transferId !== null && item.transferId !== '' |
| | | ? { transferId: normalizeNumber(item.transferId, void 0) } |
| | | : {}), |
| | | ...(normalizeText(item.transferCode) |
| | | ? { transferCode: normalizeText(item.transferCode) } |
| | | : {}), |
| | | ...(item.matnrId !== undefined && item.matnrId !== null && item.matnrId !== '' |
| | | ? { matnrId: normalizeNumber(item.matnrId, void 0) } |
| | | : {}), |
| | | ...(normalizeText(item.maktx) ? { maktx: normalizeText(item.maktx) } : {}), |
| | | ...(normalizeText(item.matnrCode) ? { matnrCode: normalizeText(item.matnrCode) } : {}), |
| | | ...(item.anfme !== undefined && item.anfme !== null && item.anfme !== '' |
| | | ? { anfme: normalizeNumber(item.anfme, 0) } |
| | | : {}), |
| | | ...(normalizeText(item.splrCode) ? { splrCode: normalizeText(item.splrCode) } : {}), |
| | | ...(normalizeText(item.splrName) ? { splrName: normalizeText(item.splrName) } : {}), |
| | | ...(normalizeText(item.batch) ? { batch: normalizeText(item.batch) } : {}), |
| | | ...(normalizeText(item.unit || item.stockUnit) |
| | | ? { |
| | | unit: normalizeText(item.unit || item.stockUnit), |
| | | stockUnit: normalizeText(item.stockUnit || item.unit) |
| | | } |
| | | : {}), |
| | | ...(normalizeText(item.spec) ? { spec: normalizeText(item.spec) } : {}), |
| | | ...(normalizeText(item.model) ? { model: normalizeText(item.model) } : {}), |
| | | ...(normalizeText(item.fieldsIndex) |
| | | ? { fieldsIndex: normalizeText(item.fieldsIndex) } |
| | | : {}), |
| | | ...(normalizeText(item.platItemId) ? { platItemId: normalizeText(item.platItemId) } : {}), |
| | | ...(normalizeText(item.platOrderCode) |
| | | ? { platOrderCode: normalizeText(item.platOrderCode) } |
| | | : {}), |
| | | ...(normalizeText(item.platWorkCode) |
| | | ? { platWorkCode: normalizeText(item.platWorkCode) } |
| | | : {}), |
| | | ...(normalizeText(item.projectCode) |
| | | ? { projectCode: normalizeText(item.projectCode) } |
| | | : {}), |
| | | ...(item.status !== undefined && item.status !== null && item.status !== '' |
| | | ? { status: normalizeNumber(item.status, 1) } |
| | | : { status: 1 }), |
| | | memo: normalizeText(item.memo || '') |
| | | } |
| | | |
| | | fieldDefinitions.forEach((field) => { |
| | | const value = item[field.fields] |
| | | if (value !== undefined && value !== null && String(value).trim() !== '') { |
| | | payload[field.fields] = value |
| | | } |
| | | }) |
| | | |
| | | return payload |
| | | }) |
| | | } |
| | | } |
| | | |
| | | export function createTransferMaterialSearchState() { |
| | | return { |
| | | maktx: '', |
| | | matnrCode: '' |
| | | } |
| | | } |
| | | |
| | |
| | | { key: 'edit', label: $t('pages.orders.transfer.actions.edit'), icon: 'ri:pencil-line' } |
| | | ] |
| | | if (Number(normalizedRow.exceStatus) === 0) { |
| | | actions.push({ key: 'publish', label: $t('pages.orders.transfer.actions.publish'), icon: 'ri:send-plane-line' }) |
| | | actions.push({ key: 'delete', label: $t('pages.orders.transfer.actions.delete'), icon: 'ri:delete-bin-5-line', color: 'var(--art-error)' }) |
| | | actions.push({ |
| | | key: 'publish', |
| | | label: $t('pages.orders.transfer.actions.publish'), |
| | | icon: 'ri:send-plane-line' |
| | | }) |
| | | actions.push({ |
| | | key: 'delete', |
| | | label: $t('pages.orders.transfer.actions.delete'), |
| | | icon: 'ri:delete-bin-5-line', |
| | | color: 'var(--art-error)' |
| | | }) |
| | | } |
| | | return actions |
| | | } |
| | |
| | | if (value === void 0) return null |
| | | return { |
| | | value, |
| | | label: normalizeText(item.name || item.areaName || item.code || item.warehouseId$ || item.warehouseName || `${$t('menu.warehouseAreas')} ${value}`), |
| | | label: normalizeText( |
| | | item.name || |
| | | item.areaName || |
| | | item.code || |
| | | item.warehouseId$ || |
| | | item.warehouseName || |
| | | `${$t('menu.warehouseAreas')} ${value}` |
| | | ), |
| | | raw: item |
| | | } |
| | | }) |
| | |
| | | if (value === void 0) return null |
| | | return { |
| | | value, |
| | | label: normalizeText(item.label || item.name || item.dictLabel || `${$t('pages.orders.transfer.dialog.type')} ${value}`) |
| | | label: normalizeText( |
| | | item.label || |
| | | item.name || |
| | | item.dictLabel || |
| | | `${$t('pages.orders.transfer.dialog.type')} ${value}` |
| | | ) |
| | | } |
| | | }) |
| | | .filter(Boolean) |
| | |
| | | import { h } from 'vue' |
| | | import { ElTag } from 'element-plus' |
| | | import { ElLink, ElTag } from 'element-plus' |
| | | import { $t } from '@/locales' |
| | | import ArtButtonMore from '@/components/core/forms/art-button-more/index.vue' |
| | | import { getTransferActionList } from './transferPage.helpers.js' |
| | | import TransferOrdersPanel from './modules/transfer-orders-panel.vue' |
| | | |
| | | export function createTransferTableColumns({ handleActionClick } = {}) { |
| | | export function createTransferTableColumns({ handleActionClick, handleViewOrder } = {}) { |
| | | return [ |
| | | { |
| | | type: 'expand', |
| | | width: 56, |
| | | formatter: (row) => ({ |
| | | render() { |
| | | return h(TransferOrdersPanel, { |
| | | transferId: row.id, |
| | | transferCode: row.code, |
| | | onOrderView: handleViewOrder |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | { type: 'selection', width: 48, align: 'center' }, |
| | | { type: 'globalIndex', label: $t('table.index'), width: 72, align: 'center' }, |
| | | { |
| | | prop: 'id', |
| | | label: $t('table.id'), |
| | | width: 100, |
| | | align: 'center', |
| | | formatter: (row) => row.id ?? '--' |
| | | }, |
| | | { |
| | | prop: 'code', |
| | | label: $t('pages.orders.transfer.search.code'), |
| | |
| | | minWidth: 120, |
| | | showOverflowTooltip: true, |
| | | formatter: (row) => |
| | | h(ElTag, { type: row.sourceTagType || 'info', effect: 'light' }, () => row.sourceText || '--') |
| | | h( |
| | | ElTag, |
| | | { type: row.sourceTagType || 'info', effect: 'light' }, |
| | | () => row.sourceText || '--' |
| | | ) |
| | | }, |
| | | { |
| | | prop: 'orgWareName', |
| | |
| | | label: $t('pages.orders.transfer.search.exceStatus'), |
| | | minWidth: 120, |
| | | formatter: (row) => |
| | | h(ElTag, { type: row.exceStatusTagType || 'info', effect: 'light' }, () => row.exceStatusText || '--') |
| | | h( |
| | | ElTag, |
| | | { type: row.exceStatusTagType || 'info', effect: 'light' }, |
| | | () => row.exceStatusText || '--' |
| | | ) |
| | | }, |
| | | { |
| | | prop: 'statusText', |
| | |
| | | align: 'center', |
| | | formatter: (row) => |
| | | h(ElTag, { type: row.statusType || 'info', effect: 'light' }, () => row.statusText || '--') |
| | | }, |
| | | { |
| | | prop: 'updateByText', |
| | | label: $t('table.updateBy'), |
| | | minWidth: 120, |
| | | showOverflowTooltip: true, |
| | | formatter: (row) => row.updateByText || '--' |
| | | }, |
| | | { |
| | | prop: 'createByText', |
| | | label: $t('table.createBy'), |
| | | minWidth: 120, |
| | | showOverflowTooltip: true, |
| | | formatter: (row) => row.createByText || '--' |
| | | }, |
| | | { |
| | | prop: 'updateTimeText', |
| | |
| | | ] |
| | | } |
| | | |
| | | export function createTransferOrderTableColumns() { |
| | | export function createTransferOrderTableColumns({ handleViewOrder } = {}) { |
| | | return [ |
| | | { type: 'globalIndex', label: $t('table.index'), width: 72, align: 'center' }, |
| | | { |
| | |
| | | label: $t('pages.orders.transfer.detail.relatedCode'), |
| | | minWidth: 170, |
| | | showOverflowTooltip: true, |
| | | formatter: (row) => row.code || '--' |
| | | formatter: (row) => |
| | | row.code && typeof handleViewOrder === 'function' |
| | | ? h( |
| | | ElLink, |
| | | { |
| | | type: 'primary', |
| | | underline: 'hover', |
| | | onClick: () => handleViewOrder(row) |
| | | }, |
| | | () => row.code |
| | | ) |
| | | : row.code || '--' |
| | | }, |
| | | { |
| | | prop: 'poCode', |
| | |
| | | label: $t('pages.orders.transfer.detail.exceStatus'), |
| | | minWidth: 120, |
| | | formatter: (row) => |
| | | h(ElTag, { type: row.exceStatusTagType || 'info', effect: 'light' }, () => row.exceStatusText || '--') |
| | | h( |
| | | ElTag, |
| | | { type: row.exceStatusTagType || 'info', effect: 'light' }, |
| | | () => row.exceStatusText || '--' |
| | | ) |
| | | }, |
| | | { |
| | | prop: 'statusText', |