| | |
| | | VITE_BASE_URL = / |
| | | |
| | | # API 地址前缀 |
| | | VITE_API_URL = /rsf-server |
| | | # VITE_API_URL = /rsf-server |
| | | VITE_API_URL = http://127.0.0.1:8085/rsf-server |
| | | |
| | | # Delete console |
| | | VITE_DROP_CONSOLE = true |
| | |
| | | }) |
| | | } |
| | | |
| | | export function fetchWaveOrderRelaPage(params = {}) { |
| | | return request.post({ |
| | | url: '/waveOrderRela/page', |
| | | params: buildWaveItemPageParams(params) |
| | | }) |
| | | } |
| | | |
| | | export function fetchGetWaveDetail(id) { |
| | | return request.get({ |
| | | url: `/wave/${id}` |
| | |
| | | }) |
| | | } |
| | | |
| | | export function fetchSelectWaveTask(payload = {}) { |
| | | return request.post({ |
| | | url: '/wave/selects/task', |
| | | params: payload |
| | | }) |
| | | } |
| | | |
| | | export function fetchWaveAutoExceFlag() { |
| | | return request.get({ |
| | | url: '/config/flag/WaveAutoExce' |
| | | }) |
| | | } |
| | | |
| | | export function fetchUpdateWaveAutoExceFlag(enabled) { |
| | | return request.post({ |
| | | url: '/config/byFlag', |
| | | params: { |
| | | val: !!enabled, |
| | | flag: 'WaveAutoExce' |
| | | } |
| | | }) |
| | | } |
| | | |
| | | export function fetchCreateOutStockWave(payload = {}) { |
| | | return request.post({ |
| | | url: '/outStock/generate/wave', |
| | |
| | | "requestCancelled": "Request cancelled", |
| | | "networkError": "Network connection error, please check your connection", |
| | | "requestFailed": "Request failed", |
| | | "requestConfigError": "Request configuration error" |
| | | "requestConfigError": "Request configuration error", |
| | | "invalidResponseFormat": "Unexpected API response format, please check the server response", |
| | | "invalidHtmlResponse": "The API returned an HTML page, please check proxy or deployment routing" |
| | | }, |
| | | "topBar": { |
| | | "search": { |
| | |
| | | "codePlaceholder": "Enter wave No.", |
| | | "type": "Wave Type", |
| | | "exceStatus": "Wave Status", |
| | | "anfme": "Wave Qty", |
| | | "anfmePlaceholder": "Enter wave quantity", |
| | | "qty": "Executed Qty", |
| | | "qtyPlaceholder": "Enter executed quantity", |
| | | "orderNum": "Order Count", |
| | | "orderNumPlaceholder": "Enter order count", |
| | | "status": "Status", |
| | | "memo": "Remark", |
| | | "memoPlaceholder": "Enter remark", |
| | | "timeStart": "Start Time", |
| | | "timeEnd": "End Time" |
| | | }, |
| | | "buttons": { |
| | | "batchPublicTask": "Batch Dispatch", |
| | | "autoStart": "Enable Auto Run", |
| | | "autoPause": "Pause Auto Run" |
| | | }, |
| | | "status": { |
| | | "type": { |
| | |
| | | "type": "Wave Type", |
| | | "exceStatus": "Wave Status", |
| | | "anfme": "Expected Qty", |
| | | "groupQty": "Merged Qty", |
| | | "workQty": "Running Qty", |
| | | "qty": "Completed Qty", |
| | | "orderNum": "Document Count", |
| | |
| | | "createTime": "Created At", |
| | | "updateTime": "Updated At", |
| | | "status": "Status" |
| | | }, |
| | | "rela": { |
| | | "asnCode": "Document No.", |
| | | "platOrderCode": "Platform Order No.", |
| | | "spec": "Spec", |
| | | "model": "Model", |
| | | "unitPlaceholder": "Enter unit" |
| | | }, |
| | | "preview": { |
| | | "waveCode": "Wave No.", |
| | |
| | | "updateBy": "Updated By", |
| | | "updateTime": "Updated At", |
| | | "memo": "Remark", |
| | | "previewTitle": "Wave Preview Items - Material Code" |
| | | "previewTitle": "Wave Preview Items - Material Code", |
| | | "itemTitle": "Wave Items" |
| | | }, |
| | | "publicTask": { |
| | | "title": "Dispatch Wave Task", |
| | |
| | | "publicTaskTimeout": "Wave dispatch preview timed out and waiting has stopped", |
| | | "publicTaskSuccess": "Wave dispatched", |
| | | "publicTaskFailed": "Wave dispatch failed", |
| | | "publicTaskWarning": "Wave preview data is unavailable. Please check location configuration first." |
| | | "publicTaskWarning": "Wave preview data is unavailable. Please check location configuration first.", |
| | | "batchPublicTaskSelect": "Please select waves first", |
| | | "batchPublicTaskConfirm": "Are you sure you want to dispatch {count} selected waves?", |
| | | "batchPublicTaskTitle": "Batch Dispatch Confirmation", |
| | | "batchPublicTaskSuccess": "Waves dispatched in batch", |
| | | "batchPublicTaskFailed": "Batch dispatch failed", |
| | | "autoStartSuccess": "Auto run enabled", |
| | | "autoPauseSuccess": "Auto run paused", |
| | | "autoUpdateFailed": "Failed to update auto run settings" |
| | | } |
| | | }, |
| | | "waveItem": { |
| | |
| | | "requestCancelled": "请求已取消", |
| | | "networkError": "网络连接异常,请检查网络连接", |
| | | "requestFailed": "请求失败", |
| | | "requestConfigError": "请求配置错误" |
| | | "requestConfigError": "请求配置错误", |
| | | "invalidResponseFormat": "接口响应格式异常,请检查服务端返回", |
| | | "invalidHtmlResponse": "接口返回了 HTML 页面,请检查接口代理或部署路由配置" |
| | | }, |
| | | "topBar": { |
| | | "search": { |
| | |
| | | "codePlaceholder": "请输入波次单号", |
| | | "type": "波次类型", |
| | | "exceStatus": "波次状态", |
| | | "anfme": "波次数量", |
| | | "anfmePlaceholder": "请输入波次数量", |
| | | "qty": "已执行数量", |
| | | "qtyPlaceholder": "请输入已执行数量", |
| | | "orderNum": "订单数", |
| | | "orderNumPlaceholder": "请输入订单数", |
| | | "status": "状态", |
| | | "memo": "备注", |
| | | "memoPlaceholder": "请输入备注", |
| | | "timeStart": "开始时间", |
| | | "timeEnd": "结束时间" |
| | | }, |
| | | "buttons": { |
| | | "batchPublicTask": "批量下发", |
| | | "autoStart": "开启自动执行", |
| | | "autoPause": "暂停自动执行" |
| | | }, |
| | | "status": { |
| | | "type": { |
| | |
| | | "type": "波次类型", |
| | | "exceStatus": "波次状态", |
| | | "anfme": "应盘数量", |
| | | "groupQty": "合并数量", |
| | | "workQty": "执行数量", |
| | | "qty": "已盘数量", |
| | | "orderNum": "单据数量", |
| | |
| | | "createTime": "创建时间", |
| | | "updateTime": "更新时间", |
| | | "status": "状态" |
| | | }, |
| | | "rela": { |
| | | "asnCode": "单据号", |
| | | "platOrderCode": "平台单号", |
| | | "spec": "规格", |
| | | "model": "型号", |
| | | "unitPlaceholder": "请输入单位" |
| | | }, |
| | | "preview": { |
| | | "waveCode": "波次号", |
| | |
| | | "updateBy": "更新人", |
| | | "updateTime": "更新时间", |
| | | "memo": "备注", |
| | | "previewTitle": "波次预览明细 - 物料编码" |
| | | "previewTitle": "波次预览明细 - 物料编码", |
| | | "itemTitle": "波次明细" |
| | | }, |
| | | "publicTask": { |
| | | "title": "波次下发任务", |
| | |
| | | "publicTaskTimeout": "波次下发预览加载超时,已停止等待", |
| | | "publicTaskSuccess": "波次已下发", |
| | | "publicTaskFailed": "波次下发失败", |
| | | "publicTaskWarning": "波次预览数据不可用,请先检查库位配置" |
| | | "publicTaskWarning": "波次预览数据不可用,请先检查库位配置", |
| | | "batchPublicTaskSelect": "请先选择波次", |
| | | "batchPublicTaskConfirm": "确定下发选中的 {count} 个波次吗?", |
| | | "batchPublicTaskTitle": "批量下发确认", |
| | | "batchPublicTaskSuccess": "波次已批量下发", |
| | | "batchPublicTaskFailed": "波次批量下发失败", |
| | | "autoStartSuccess": "已开启自动执行", |
| | | "autoPauseSuccess": "已暂停自动执行", |
| | | "autoUpdateFailed": "自动执行开关更新失败" |
| | | } |
| | | }, |
| | | "waveItem": { |
| | |
| | | this.timestamp = /* @__PURE__ */ new Date().toISOString() |
| | | this.url = options?.url |
| | | this.method = options?.method |
| | | this.status = options?.status |
| | | this.contentType = options?.contentType |
| | | } |
| | | toLogData() { |
| | | return { |
| | |
| | | timestamp: this.timestamp, |
| | | url: this.url, |
| | | method: this.method, |
| | | status: this.status, |
| | | contentType: this.contentType, |
| | | stack: this.stack |
| | | } |
| | | } |
| | | } |
| | | function resolveRequestUrl(config) { |
| | | const baseURL = String(config?.baseURL || '').trim() |
| | | const requestUrl = String(config?.url || '').trim() |
| | | if (!baseURL && !requestUrl) { |
| | | return void 0 |
| | | } |
| | | if (!baseURL) { |
| | | return requestUrl || void 0 |
| | | } |
| | | if (!requestUrl) { |
| | | return baseURL |
| | | } |
| | | const isAbsoluteBase = /^https?:\/\//i.test(baseURL) |
| | | if (!isAbsoluteBase) { |
| | | const normalizedBase = baseURL.replace(/\/+$/, '') |
| | | const normalizedUrl = requestUrl.replace(/^\/+/, '') |
| | | if (!normalizedBase) { |
| | | return requestUrl |
| | | } |
| | | if (!normalizedUrl) { |
| | | return normalizedBase |
| | | } |
| | | return `${normalizedBase}/${normalizedUrl}` |
| | | } |
| | | try { |
| | | const origin = globalThis?.location?.origin || 'http://localhost' |
| | | const normalizedBase = new URL(baseURL, origin) |
| | | return new URL(requestUrl, normalizedBase).toString() |
| | | } catch { |
| | | const normalizedBase = baseURL.replace(/\/+$/, '') |
| | | const normalizedUrl = requestUrl.replace(/^\/+/, '') |
| | | if (!normalizedBase) { |
| | | return requestUrl |
| | | } |
| | | if (!normalizedUrl) { |
| | | return normalizedBase |
| | | } |
| | | return `${normalizedBase}/${normalizedUrl}` |
| | | } |
| | | } |
| | | const getErrorMessage = (status) => { |
| | |
| | | const requestConfig = error.config |
| | | if (isRequestCancelled(error)) { |
| | | throw new HttpError($t('httpMsg.requestCancelled'), 'REQUEST_CANCELLED', { |
| | | url: requestConfig?.url, |
| | | url: resolveRequestUrl(requestConfig), |
| | | method: requestConfig?.method?.toUpperCase() |
| | | }) |
| | | } |
| | |
| | | const errorMessage = error.response?.data?.msg || error.message |
| | | if (!error.response) { |
| | | throw new HttpError($t('httpMsg.networkError'), ApiStatus.error, { |
| | | url: requestConfig?.url, |
| | | url: resolveRequestUrl(requestConfig), |
| | | method: requestConfig?.method?.toUpperCase() |
| | | }) |
| | | } |
| | |
| | | : errorMessage || $t('httpMsg.requestFailed') |
| | | throw new HttpError(message, statusCode || ApiStatus.error, { |
| | | data: error.response.data, |
| | | url: requestConfig?.url, |
| | | method: requestConfig?.method?.toUpperCase() |
| | | url: resolveRequestUrl(requestConfig), |
| | | method: requestConfig?.method?.toUpperCase(), |
| | | status: statusCode, |
| | | contentType: error.response?.headers?.['content-type'] |
| | | }) |
| | | } |
| | | function showError(error, showMessage = true) { |
| | |
| | | const isHttpError = (error) => { |
| | | return error instanceof HttpError |
| | | } |
| | | export { HttpError, handleError, isHttpError, showError, showSuccess } |
| | | export { HttpError, handleError, isHttpError, resolveRequestUrl, showError, showSuccess } |
| | |
| | | import axios from 'axios' |
| | | import { useUserStore } from '@/store/modules/user' |
| | | import { ApiStatus } from './status' |
| | | import { HttpError, handleError, showError, showSuccess } from './error' |
| | | import { HttpError, handleError, resolveRequestUrl, showError, showSuccess } from './error' |
| | | import { $t } from '@/locales' |
| | | const REQUEST_TIMEOUT = 30e3 |
| | | const LOGOUT_DELAY = 500 |
| | |
| | | ) |
| | | axiosInstance.interceptors.response.use( |
| | | (response) => { |
| | | if (!isStandardResponse(response.data)) { |
| | | throw createInvalidResponseError(response) |
| | | } |
| | | const { code, msg } = response.data |
| | | if (code === ApiStatus.success) return response |
| | | if (code === ApiStatus.unauthorized) handleUnauthorizedError(msg) |
| | | throw createHttpError(msg || $t('httpMsg.requestFailed'), code) |
| | | if (code === ApiStatus.unauthorized) handleUnauthorizedError(msg, response.config) |
| | | throw createHttpError( |
| | | msg || $t('httpMsg.requestFailed'), |
| | | code ?? ApiStatus.error, |
| | | createErrorOptions( |
| | | response.config, |
| | | { |
| | | data: response.data, |
| | | status: response.status, |
| | | contentType: response.headers?.['content-type'] |
| | | }, |
| | | response |
| | | ) |
| | | ) |
| | | }, |
| | | (error) => { |
| | | if (error.response?.status === ApiStatus.unauthorized) handleUnauthorizedError() |
| | | return Promise.reject(handleError(error)) |
| | | } |
| | | ) |
| | | function createHttpError(message, code) { |
| | | return new HttpError(message, code) |
| | | function createHttpError(message, code, options) { |
| | | return new HttpError(message, code, options) |
| | | } |
| | | function handleUnauthorizedError(message) { |
| | | const error = createHttpError(message || $t('httpMsg.unauthorized'), ApiStatus.unauthorized) |
| | | function handleUnauthorizedError(message, config) { |
| | | const error = createHttpError( |
| | | message || $t('httpMsg.unauthorized'), |
| | | ApiStatus.unauthorized, |
| | | createErrorOptions(config) |
| | | ) |
| | | if (!isUnauthorizedErrorShown) { |
| | | isUnauthorizedErrorShown = true |
| | | logOut() |
| | |
| | | ApiStatus.gatewayTimeout |
| | | ].includes(statusCode) |
| | | } |
| | | function createErrorOptions(config, extra = {}, response) { |
| | | return { |
| | | url: response?.request?.responseURL || resolveRequestUrl(config), |
| | | method: config?.method?.toUpperCase(), |
| | | ...extra |
| | | } |
| | | } |
| | | function isStandardResponse(payload) { |
| | | return payload !== null && typeof payload === 'object' && !Array.isArray(payload) && 'code' in payload |
| | | } |
| | | function createInvalidResponseError(response) { |
| | | const responseData = response?.data |
| | | const responseText = |
| | | typeof responseData === 'string' ? responseData.slice(0, 300) : responseData |
| | | const contentType = String(response?.headers?.['content-type'] || '') |
| | | const looksLikeHtml = |
| | | contentType.includes('text/html') || |
| | | (typeof responseData === 'string' && |
| | | /<(!doctype|html|head|body)\b/i.test(responseData.trim().slice(0, 120))) |
| | | const message = looksLikeHtml |
| | | ? $t('httpMsg.invalidHtmlResponse') |
| | | : $t('httpMsg.invalidResponseFormat') |
| | | return createHttpError( |
| | | message, |
| | | ApiStatus.error, |
| | | createErrorOptions( |
| | | response?.config, |
| | | { |
| | | data: responseText, |
| | | status: response?.status, |
| | | contentType |
| | | }, |
| | | response |
| | | ) |
| | | ) |
| | | } |
| | | async function retryRequest(config, retries = MAX_RETRIES) { |
| | | try { |
| | | return await request(config) |
| | |
| | | <ElCard class="art-table-card"> |
| | | <ArtTableHeader v-model:columns="columnChecks" :loading="loading" @refresh="refreshData"> |
| | | <template #left> |
| | | <ElSpace wrap> |
| | | <ElButton |
| | | type="primary" |
| | | :loading="batchTaskSubmitting" |
| | | :disabled="loading || batchTaskSubmitting || !selectedRows.length" |
| | | @click="handleBatchPublicTask" |
| | | > |
| | | {{ t('pages.orders.wave.buttons.batchPublicTask') }} |
| | | </ElButton> |
| | | <ElButton |
| | | :loading="autoExceSubmitting" |
| | | :disabled="loading || autoExceSubmitting || autoExce" |
| | | @click="toggleAutoExce(true)" |
| | | > |
| | | {{ t('pages.orders.wave.buttons.autoStart') }} |
| | | </ElButton> |
| | | <ElButton |
| | | :loading="autoExceSubmitting" |
| | | :disabled="loading || autoExceSubmitting || !autoExce" |
| | | @click="toggleAutoExce(false)" |
| | | > |
| | | {{ t('pages.orders.wave.buttons.autoPause') }} |
| | | </ElButton> |
| | | <ListExportPrint |
| | | :preview-visible="previewVisible" |
| | | @update:previewVisible="handlePreviewVisibleChange" |
| | |
| | | @export="handleExport" |
| | | @print="handlePrint" |
| | | /> |
| | | </ElSpace> |
| | | </template> |
| | | </ArtTableHeader> |
| | | |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, reactive, ref } from 'vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import { computed, onMounted, reactive, ref } from 'vue' |
| | | import { ElButton, ElMessage, ElMessageBox, ElSpace } from 'element-plus' |
| | | import { useI18n } from 'vue-i18n' |
| | | import { useUserStore } from '@/store/modules/user' |
| | | import { useTable } from '@/hooks/core/useTable' |
| | |
| | | fetchGetWaveMany, |
| | | fetchPauseWave, |
| | | fetchPublicWaveTask, |
| | | fetchSelectWaveTask, |
| | | fetchStopWave, |
| | | fetchUpdateWaveAutoExceFlag, |
| | | fetchWaveAutoExceFlag, |
| | | fetchWavePage, |
| | | fetchWavePreviewPage |
| | | } from '@/api/wave' |
| | |
| | | const publicTaskSubmitting = ref(false) |
| | | const publicTaskWave = ref({}) |
| | | const publicTaskRows = ref([]) |
| | | const autoExce = ref(false) |
| | | const batchTaskSubmitting = ref(false) |
| | | const autoExceSubmitting = ref(false) |
| | | |
| | | const detailPagination = reactive({ |
| | | current: 1, |
| | |
| | | const detailColumns = computed(() => createWaveDetailItemColumns(t)) |
| | | const publicTaskColumns = computed(() => createWavePreviewItemColumns(t)) |
| | | const publicTaskCanSubmit = computed( |
| | | () => publicTaskRows.value.length > 0 && publicTaskRows.value.every((row) => row.stockLocsText && row.stockLocsText !== '[]') |
| | | () => |
| | | publicTaskRows.value.length > 0 && |
| | | publicTaskRows.value.every((row) => row.stockLocsText && row.stockLocsText !== '[]') |
| | | ) |
| | | const publicTaskWarningText = computed(() => t('pages.orders.wave.messages.publicTaskWarning')) |
| | | const searchItems = computed(() => [ |
| | |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.orders.wave.search.anfme'), |
| | | key: 'anfme', |
| | | type: 'inputNumber', |
| | | props: { |
| | | clearable: true, |
| | | controlsPosition: 'right', |
| | | placeholder: t('pages.orders.wave.search.anfmePlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.orders.wave.search.qty'), |
| | | key: 'qty', |
| | | type: 'inputNumber', |
| | | props: { |
| | | clearable: true, |
| | | controlsPosition: 'right', |
| | | placeholder: t('pages.orders.wave.search.qtyPlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.orders.wave.search.orderNum'), |
| | | key: 'orderNum', |
| | | type: 'inputNumber', |
| | | props: { |
| | | clearable: true, |
| | | controlsPosition: 'right', |
| | | placeholder: t('pages.orders.wave.search.orderNumPlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.orders.wave.search.status'), |
| | | key: 'status', |
| | | type: 'select', |
| | |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: t('pages.orders.wave.search.memoPlaceholder') } |
| | | }, |
| | | { label: t('pages.orders.wave.search.timeStart'), key: 'timeStart', type: 'date', props: { clearable: true, type: 'date', valueFormat: 'YYYY-MM-DD' } }, |
| | | { label: t('pages.orders.wave.search.timeEnd'), key: 'timeEnd', type: 'date', props: { clearable: true, type: 'date', valueFormat: 'YYYY-MM-DD' } } |
| | | { |
| | | label: t('pages.orders.wave.search.timeStart'), |
| | | key: 'timeStart', |
| | | type: 'date', |
| | | props: { clearable: true, type: 'date', valueFormat: 'YYYY-MM-DD' } |
| | | }, |
| | | { |
| | | label: t('pages.orders.wave.search.timeEnd'), |
| | | key: 'timeEnd', |
| | | type: 'date', |
| | | props: { clearable: true, type: 'date', valueFormat: 'YYYY-MM-DD' } |
| | | } |
| | | ]) |
| | | |
| | | function updatePaginationState(target, response, fallbackCurrent, fallbackSize) { |
| | |
| | | return |
| | | } |
| | | if (action.key === 'stop') { |
| | | await ElMessageBox.confirm(t('pages.orders.wave.messages.stopConfirm', { code: row.code || '' }), t('pages.orders.wave.messages.stopTitle'), { |
| | | await ElMessageBox.confirm( |
| | | t('pages.orders.wave.messages.stopConfirm', { code: row.code || '' }), |
| | | t('pages.orders.wave.messages.stopTitle'), |
| | | { |
| | | confirmButtonText: t('common.confirm'), |
| | | cancelButtonText: t('common.cancel'), |
| | | type: 'warning' |
| | | }) |
| | | } |
| | | ) |
| | | await fetchStopWave(row.id) |
| | | ElMessage.success(t('pages.orders.wave.messages.stopSuccess')) |
| | | await refreshData() |
| | |
| | | columnsFactory: () => createWaveTableColumns({ handleActionClick, t }) |
| | | }, |
| | | transform: { |
| | | dataTransformer: (records) => (Array.isArray(records) ? records.map((item) => normalizeWaveRow(item, t)) : []) |
| | | dataTransformer: (records) => |
| | | Array.isArray(records) ? records.map((item) => normalizeWaveRow(item, t)) : [] |
| | | } |
| | | }) |
| | | |
| | |
| | | detailLoading.value = true |
| | | try { |
| | | const [detailResponse, previewResponse] = await Promise.all([ |
| | | guardRequestWithMessage(fetchGetWaveDetail(activeWaveId.value), {}, { timeoutMessage: t('pages.orders.wave.messages.detailTimeout') }), |
| | | guardRequestWithMessage( |
| | | fetchWavePreviewPage(buildWaveDetailQueryParams({ waveId: activeWaveId.value, current: detailPagination.current, pageSize: detailPagination.size })), |
| | | fetchGetWaveDetail(activeWaveId.value), |
| | | {}, |
| | | { timeoutMessage: t('pages.orders.wave.messages.detailTimeout') } |
| | | ), |
| | | guardRequestWithMessage( |
| | | fetchWavePreviewPage( |
| | | buildWaveDetailQueryParams({ |
| | | waveId: activeWaveId.value, |
| | | current: detailPagination.current, |
| | | pageSize: detailPagination.size |
| | | }) |
| | | ), |
| | | { records: [], total: 0, current: detailPagination.current, size: detailPagination.size }, |
| | | { timeoutMessage: t('pages.orders.wave.messages.previewTimeout') } |
| | | ) |
| | | ]) |
| | | detailData.value = normalizeWaveRow(detailResponse, t) |
| | | detailTableData.value = Array.isArray(previewResponse?.records) ? previewResponse.records.map((item) => normalizeWaveItemRow(item, t)) : [] |
| | | updatePaginationState(detailPagination, previewResponse, detailPagination.current, detailPagination.size) |
| | | detailTableData.value = Array.isArray(previewResponse?.records) |
| | | ? previewResponse.records.map((item) => normalizeWaveItemRow(item, t)) |
| | | : [] |
| | | updatePaginationState( |
| | | detailPagination, |
| | | previewResponse, |
| | | detailPagination.current, |
| | | detailPagination.size |
| | | ) |
| | | } finally { |
| | | detailLoading.value = false |
| | | } |
| | |
| | | publicTaskLoading.value = true |
| | | try { |
| | | const previewResponse = await guardRequestWithMessage( |
| | | fetchWavePreviewPage(buildWaveDetailQueryParams({ waveId: publicTaskWave.value.id, current: publicTaskPagination.current, pageSize: publicTaskPagination.size })), |
| | | { records: [], total: 0, current: publicTaskPagination.current, size: publicTaskPagination.size }, |
| | | fetchWavePreviewPage( |
| | | buildWaveDetailQueryParams({ |
| | | waveId: publicTaskWave.value.id, |
| | | current: publicTaskPagination.current, |
| | | pageSize: publicTaskPagination.size |
| | | }) |
| | | ), |
| | | { |
| | | records: [], |
| | | total: 0, |
| | | current: publicTaskPagination.current, |
| | | size: publicTaskPagination.size |
| | | }, |
| | | { timeoutMessage: t('pages.orders.wave.messages.publicTaskTimeout') } |
| | | ) |
| | | publicTaskRows.value = Array.isArray(previewResponse?.records) ? previewResponse.records.map((item) => normalizeWaveItemRow(item, t)) : [] |
| | | updatePaginationState(publicTaskPagination, previewResponse, publicTaskPagination.current, publicTaskPagination.size) |
| | | publicTaskRows.value = Array.isArray(previewResponse?.records) |
| | | ? previewResponse.records.map((item) => normalizeWaveItemRow(item, t)) |
| | | : [] |
| | | updatePaginationState( |
| | | publicTaskPagination, |
| | | previewResponse, |
| | | publicTaskPagination.current, |
| | | publicTaskPagination.size |
| | | ) |
| | | } finally { |
| | | publicTaskLoading.value = false |
| | | } |
| | |
| | | ElMessage.error(error?.message || t('pages.orders.wave.messages.publicTaskFailed')) |
| | | } finally { |
| | | publicTaskSubmitting.value = false |
| | | } |
| | | } |
| | | |
| | | async function handleBatchPublicTask() { |
| | | if (!selectedRows.value.length) { |
| | | ElMessage.warning(t('pages.orders.wave.messages.batchPublicTaskSelect')) |
| | | return |
| | | } |
| | | try { |
| | | await ElMessageBox.confirm( |
| | | t('pages.orders.wave.messages.batchPublicTaskConfirm', { |
| | | count: selectedRows.value.length |
| | | }), |
| | | t('pages.orders.wave.messages.batchPublicTaskTitle'), |
| | | { |
| | | confirmButtonText: t('common.confirm'), |
| | | cancelButtonText: t('common.cancel'), |
| | | type: 'warning' |
| | | } |
| | | ) |
| | | batchTaskSubmitting.value = true |
| | | await fetchSelectWaveTask({ |
| | | ids: selectedRows.value.map((item) => item.id) |
| | | }) |
| | | ElMessage.success(t('pages.orders.wave.messages.batchPublicTaskSuccess')) |
| | | selectedRows.value = [] |
| | | await refreshData() |
| | | } catch (error) { |
| | | if (error === 'cancel' || error?.message === 'cancel') return |
| | | ElMessage.error(error?.message || t('pages.orders.wave.messages.batchPublicTaskFailed')) |
| | | } finally { |
| | | batchTaskSubmitting.value = false |
| | | } |
| | | } |
| | | |
| | | async function toggleAutoExce(enabled) { |
| | | try { |
| | | autoExceSubmitting.value = true |
| | | await fetchUpdateWaveAutoExceFlag(enabled) |
| | | autoExce.value = !!enabled |
| | | ElMessage.success( |
| | | enabled |
| | | ? t('pages.orders.wave.messages.autoStartSuccess') |
| | | : t('pages.orders.wave.messages.autoPauseSuccess') |
| | | ) |
| | | } catch (error) { |
| | | ElMessage.error(error?.message || t('pages.orders.wave.messages.autoUpdateFailed')) |
| | | } finally { |
| | | autoExceSubmitting.value = false |
| | | } |
| | | } |
| | | |
| | | async function loadAutoExceFlag() { |
| | | try { |
| | | const response = await fetchWaveAutoExceFlag() |
| | | const rawVal = response?.val ?? response?.value ?? false |
| | | autoExce.value = rawVal === true || rawVal === 'true' |
| | | } catch { |
| | | autoExce.value = false |
| | | } |
| | | } |
| | | |
| | |
| | | t |
| | | }) |
| | | ) |
| | | |
| | | onMounted(() => { |
| | | loadAutoExceFlag() |
| | | }) |
| | | </script> |
| | |
| | | <ElScrollbar class="wave-detail-scroll"> |
| | | <div class="flex min-h-full flex-col gap-4 pr-2"> |
| | | <ElDescriptions :column="4" border> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.code')">{{ detail.code || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.type')">{{ detail.typeLabel || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.exceStatus')">{{ detail.exceStatusText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.code')">{{ |
| | | detail.code || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.type')">{{ |
| | | detail.typeLabel || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.exceStatus')">{{ |
| | | detail.exceStatusText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.status')"> |
| | | <ElTag :type="Number(detail.status) === 1 ? 'success' : 'danger'" effect="light"> |
| | | {{ detail.statusLabel || '--' }} |
| | | </ElTag> |
| | | </ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.anfme')">{{ detail.anfme ?? '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.workQty')">{{ detail.workQty ?? '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.qty')">{{ detail.qty ?? '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.orderNum')">{{ detail.orderNum ?? '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.groupQty')">{{ detail.groupQty ?? '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.targSite')">{{ detail.targSite || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.stationId')">{{ detail.stationId || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.locCode')">{{ detail.locCode || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.createBy')">{{ detail.createByText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.createTime')">{{ detail.createTimeText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.updateBy')">{{ detail.updateByText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.updateTime')">{{ detail.updateTimeText || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.memo')" :span="4">{{ detail.memo || '--' }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.anfme')">{{ |
| | | detail.anfme ?? '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.workQty')">{{ |
| | | detail.workQty ?? '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.qty')">{{ |
| | | detail.qty ?? '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.orderNum')">{{ |
| | | detail.orderNum ?? '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.groupQty')">{{ |
| | | detail.groupQty ?? '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.targSite')">{{ |
| | | detail.targSite || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.stationId')">{{ |
| | | detail.stationId || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.locCode')">{{ |
| | | detail.locCode || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.createBy')">{{ |
| | | detail.createByText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.createTime')">{{ |
| | | detail.createTimeText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.updateBy')">{{ |
| | | detail.updateByText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.updateTime')">{{ |
| | | detail.updateTimeText || '--' |
| | | }}</ElDescriptionsItem> |
| | | <ElDescriptionsItem :label="t('pages.orders.wave.detail.memo')" :span="4">{{ |
| | | detail.memo || '--' |
| | | }}</ElDescriptionsItem> |
| | | </ElDescriptions> |
| | | |
| | | <ElCard shadow="never" class="border border-[var(--art-border-color)]"> |
| | | <template #header> |
| | | <div class="text-sm font-medium text-[var(--art-text-gray-800)]">{{ t('pages.orders.wave.detail.previewTitle') }}</div> |
| | | <div class="text-sm font-medium text-[var(--art-text-gray-800)]">{{ |
| | | t('pages.orders.wave.detail.previewTitle') |
| | | }}</div> |
| | | </template> |
| | | <ArtTable |
| | | :loading="loading" |
| | |
| | | @pagination:current-change="$emit('current-change', $event)" |
| | | /> |
| | | </ElCard> |
| | | |
| | | <ElCard shadow="never" class="border border-[var(--art-border-color)]"> |
| | | <template #header> |
| | | <div class="text-sm font-medium text-[var(--art-text-gray-800)]"> |
| | | {{ t('pages.orders.wave.detail.itemTitle') }} |
| | | </div> |
| | | </template> |
| | | <WaveItemPanel :wave-id="detail.id" /> |
| | | </ElCard> |
| | | </div> |
| | | </ElScrollbar> |
| | | </ElDrawer> |
| | |
| | | |
| | | <script setup> |
| | | import { useI18n } from 'vue-i18n' |
| | | import WaveItemPanel from './wave-item-panel.vue' |
| | | |
| | | defineOptions({ name: 'WaveDetailDrawer' }) |
| | | const { t } = useI18n() |
| New file |
| | |
| | | <template> |
| | | <div class="flex flex-col gap-4"> |
| | | <ArtSearchBar |
| | | v-model="searchForm" |
| | | :items="searchItems" |
| | | :showExpand="true" |
| | | @search="handleSearch" |
| | | @reset="handleReset" |
| | | /> |
| | | |
| | | <ArtTable |
| | | :loading="loading" |
| | | :data="rows" |
| | | :columns="columns" |
| | | :pagination="pagination" |
| | | @pagination:size-change="handleSizeChange" |
| | | @pagination:current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, reactive, ref, watch } from 'vue' |
| | | import { useI18n } from 'vue-i18n' |
| | | import { defaultResponseAdapter } from '@/utils/table/tableUtils' |
| | | import { fetchWaveItemPage } from '@/api/wave-item' |
| | | import { |
| | | buildWaveItemPageQueryParams, |
| | | createWaveItemSearchState, |
| | | normalizeWaveItemRow |
| | | } from '@/views/orders/wave-item/waveItemPage.helpers' |
| | | import { createWaveItemTableColumns } from '@/views/orders/wave-item/waveItemTable.columns' |
| | | |
| | | const props = defineProps({ |
| | | waveId: { type: [Number, String], default: undefined } |
| | | }) |
| | | |
| | | const { t } = useI18n() |
| | | const loading = ref(false) |
| | | const rows = ref([]) |
| | | const searchForm = ref(createWaveItemSearchState()) |
| | | const pagination = reactive({ |
| | | current: 1, |
| | | size: 20, |
| | | total: 0 |
| | | }) |
| | | |
| | | const columns = computed(() => |
| | | createWaveItemTableColumns({ |
| | | t, |
| | | handleActionClick: () => {} |
| | | }).filter((column) => column.prop !== 'operation') |
| | | ) |
| | | |
| | | const searchItems = computed(() => [ |
| | | { |
| | | label: t('pages.orders.waveItem.search.condition'), |
| | | key: 'condition', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: t('pages.orders.waveItem.search.conditionPlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.orders.waveItem.search.waveCode'), |
| | | key: 'waveCode', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: t('pages.orders.waveItem.search.waveCodePlaceholder') } |
| | | }, |
| | | { |
| | | label: t('pages.orders.waveItem.search.orderCode'), |
| | | key: 'orderCode', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: t('pages.orders.waveItem.search.orderCodePlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.orders.waveItem.search.matnrCode'), |
| | | key: 'matnrCode', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: t('pages.orders.waveItem.search.matnrCodePlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: t('pages.orders.waveItem.search.maktx'), |
| | | key: 'maktx', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: t('pages.orders.waveItem.search.maktxPlaceholder') } |
| | | }, |
| | | { |
| | | label: t('pages.orders.waveItem.search.batch'), |
| | | key: 'batch', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: t('pages.orders.waveItem.search.batchPlaceholder') } |
| | | }, |
| | | { |
| | | label: t('pages.orders.waveItem.search.splrBatch'), |
| | | key: 'splrBatch', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: t('pages.orders.waveItem.search.splrBatchPlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: t('table.unit'), |
| | | key: 'unit', |
| | | type: 'input', |
| | | props: { clearable: true, placeholder: t('pages.orders.wave.rela.unitPlaceholder') } |
| | | }, |
| | | { |
| | | label: t('pages.orders.waveItem.search.fieldsIndex'), |
| | | key: 'fieldsIndex', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: t('pages.orders.waveItem.search.fieldsIndexPlaceholder') |
| | | } |
| | | } |
| | | ]) |
| | | |
| | | function buildParams() { |
| | | return buildWaveItemPageQueryParams({ |
| | | ...searchForm.value, |
| | | waveId: props.waveId, |
| | | current: pagination.current, |
| | | pageSize: pagination.size |
| | | }) |
| | | } |
| | | |
| | | async function loadRows() { |
| | | if (props.waveId === undefined || props.waveId === null || props.waveId === '') { |
| | | rows.value = [] |
| | | pagination.total = 0 |
| | | return |
| | | } |
| | | loading.value = true |
| | | try { |
| | | const response = await fetchWaveItemPage(buildParams()) |
| | | const normalized = defaultResponseAdapter(response) |
| | | rows.value = Array.isArray(normalized.records) |
| | | ? normalized.records.map((item) => normalizeWaveItemRow(item, t)) |
| | | : [] |
| | | pagination.total = Number(normalized.total || 0) |
| | | pagination.current = Number(normalized.current || pagination.current || 1) |
| | | pagination.size = Number(normalized.size || pagination.size || 20) |
| | | } catch { |
| | | rows.value = [] |
| | | pagination.total = 0 |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | function handleSearch(params) { |
| | | searchForm.value = { ...searchForm.value, ...params } |
| | | pagination.current = 1 |
| | | loadRows() |
| | | } |
| | | |
| | | function handleReset() { |
| | | searchForm.value = createWaveItemSearchState() |
| | | pagination.current = 1 |
| | | loadRows() |
| | | } |
| | | |
| | | function handleSizeChange(size) { |
| | | pagination.size = size |
| | | pagination.current = 1 |
| | | loadRows() |
| | | } |
| | | |
| | | function handleCurrentChange(current) { |
| | | pagination.current = current |
| | | loadRows() |
| | | } |
| | | |
| | | watch( |
| | | () => props.waveId, |
| | | () => { |
| | | pagination.current = 1 |
| | | loadRows() |
| | | }, |
| | | { immediate: true } |
| | | ) |
| | | </script> |
| New file |
| | |
| | | <template> |
| | | <div class="wave-order-rela-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 { fetchWaveOrderRelaPage } from '@/api/wave' |
| | | import { normalizeWaveOrderRelaRow } from '../wavePage.helpers' |
| | | import { createWaveOrderRelaColumns } from '../waveTable.columns' |
| | | |
| | | const props = defineProps({ |
| | | waveId: { type: [Number, String], default: undefined } |
| | | }) |
| | | |
| | | const loading = ref(false) |
| | | const rows = ref([]) |
| | | const { t } = useI18n() |
| | | const columns = computed(() => createWaveOrderRelaColumns(t)) |
| | | |
| | | async function loadRows() { |
| | | if (props.waveId === undefined || props.waveId === null || props.waveId === '') { |
| | | rows.value = [] |
| | | return |
| | | } |
| | | loading.value = true |
| | | try { |
| | | const response = await fetchWaveOrderRelaPage({ |
| | | waveId: Number(props.waveId), |
| | | current: 1, |
| | | pageSize: 200 |
| | | }) |
| | | const records = defaultResponseAdapter(response).records |
| | | rows.value = Array.isArray(records) |
| | | ? records.map((item) => normalizeWaveOrderRelaRow(item)) |
| | | : [] |
| | | } catch { |
| | | rows.value = [] |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | watch( |
| | | () => props.waveId, |
| | | () => { |
| | | loadRows() |
| | | }, |
| | | { immediate: true } |
| | | ) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .wave-order-rela-panel { |
| | | padding: 12px 0; |
| | | } |
| | | </style> |
| | |
| | | code: '', |
| | | type: '', |
| | | exceStatus: '', |
| | | anfme: '', |
| | | qty: '', |
| | | orderNum: '', |
| | | status: '', |
| | | memo: '', |
| | | timeStart: '', |
| | | timeEnd: '' |
| | | timeEnd: '', |
| | | orderBy: 'create_time desc' |
| | | } |
| | | } |
| | | |
| | | export function buildWaveSearchParams(params = {}) { |
| | | const result = {} |
| | | ;['condition', 'code', 'memo', 'timeStart', 'timeEnd'].forEach((key) => { |
| | | ;['condition', 'code', 'memo', 'timeStart', 'timeEnd', 'orderBy'].forEach((key) => { |
| | | const value = normalizeText(params[key]) |
| | | if (value) { |
| | | result[key] = value |
| | |
| | | result.status = Number(params.status) |
| | | } |
| | | |
| | | ;['anfme', 'qty', 'orderNum'].forEach((key) => { |
| | | if (params[key] !== '' && params[key] !== undefined && params[key] !== null) { |
| | | result[key] = Number(params[key]) |
| | | } |
| | | }) |
| | | |
| | | return result |
| | | } |
| | | |
| | |
| | | return { |
| | | current: params.current || 1, |
| | | pageSize: params.pageSize || params.size || 20, |
| | | orderBy: normalizeText(params.orderBy) || 'create_time desc', |
| | | ...buildWaveSearchParams(params) |
| | | } |
| | | } |
| | |
| | | |
| | | export function normalizeWaveRow(record = {}, t) { |
| | | const statusConfig = getStatusConfig(record.exceStatus, record['exceStatus$'], t) |
| | | const progress = normalizeNumber(record.anfme) > 0 |
| | | ? Math.min(Math.round((normalizeNumber(record.workQty) / normalizeNumber(record.anfme)) * 100), 100) |
| | | const progress = |
| | | normalizeNumber(record.anfme) > 0 |
| | | ? Math.min( |
| | | Math.round((normalizeNumber(record.workQty) / normalizeNumber(record.anfme)) * 100), |
| | | 100 |
| | | ) |
| | | : 0 |
| | | |
| | | return { |
| | | ...record, |
| | | code: record.code || '-', |
| | | typeLabel: record['type$'] || translate(t, `pages.orders.wave.status.type.${record.type}`) || record.type || '-', |
| | | typeLabel: |
| | | record['type$'] || |
| | | translate(t, `pages.orders.wave.status.type.${record.type}`) || |
| | | record.type || |
| | | '-', |
| | | exceStatusText: statusConfig.label, |
| | | exceStatusTagType: statusConfig.tagType, |
| | | statusLabel: |
| | | record['status$'] || |
| | | translate(t, Number(record.status) === 1 ? 'common.status.normal' : 'common.status.disabled') || |
| | | translate( |
| | | t, |
| | | Number(record.status) === 1 ? 'common.status.normal' : 'common.status.disabled' |
| | | ) || |
| | | record.status || |
| | | '-', |
| | | anfme: normalizeNumber(record.anfme), |
| | |
| | | const statusConfig = getItemStatusConfig(record.exceStatus, record['exceStatus$'], t) |
| | | return { |
| | | ...record, |
| | | id: record.id ?? null, |
| | | waveId: record.waveId ?? '-', |
| | | waveCode: record.waveCode || '-', |
| | | orderCode: record.orderCode || '-', |
| | | orderItemId: record.orderItemId ?? '-', |
| | | matnrId: record.matnrId ?? '-', |
| | | matnrCode: record.matnrCode || '-', |
| | | maktx: record.maktx || '-', |
| | | batch: record.batch || '-', |
| | | splrBatch: record.splrBatch || '-', |
| | | unit: record.unit || '-', |
| | | memo: record.memo || '-', |
| | | trackCode: record.trackCode || '-', |
| | | fieldsIndex: record.fieldsIndex || '-', |
| | | anfme: normalizeNumber(record.anfme), |
| | |
| | | workQty: normalizeNumber(record.workQty), |
| | | stockQty: normalizeNumber(record.stockQty), |
| | | stockLocsText: normalizeStockLocs(record.stockLocs), |
| | | updateByText: record['updateBy$'] || record.updateBy || '-', |
| | | createByText: record['createBy$'] || record.createBy || '-', |
| | | statusLabel: record['status$'] || record.status || '-', |
| | | exceStatusText: statusConfig.label, |
| | | exceStatusTagType: statusConfig.tagType, |
| | |
| | | ...buildWaveItemSearchParams(params) |
| | | } |
| | | } |
| | | |
| | | export function normalizeWaveOrderRelaRow(record = {}) { |
| | | return { |
| | | ...record, |
| | | id: record.id ?? null, |
| | | asnCode: record.asnCode || record.orderCode || '-', |
| | | matnrCode: record.matnrCode || '-', |
| | | maktx: record.maktx || '-', |
| | | splrBatch: record.splrBatch || '-', |
| | | platOrderCode: record.platOrderCode || '-', |
| | | spec: record.spec || '-', |
| | | model: record.model || '-', |
| | | stockUnit: record.stockUnit || '-', |
| | | splrName: record.splrName || '-', |
| | | anfme: normalizeNumber(record.anfme) |
| | | } |
| | | } |
| | |
| | | import { $t } from '@/locales' |
| | | import ArtButtonMore from '@/components/core/forms/art-button-more/index.vue' |
| | | import { getWaveActionList } from './wavePage.helpers' |
| | | import WaveOrderRelaPanel from './modules/wave-order-rela-panel.vue' |
| | | |
| | | export function createWaveTableColumns({ handleActionClick, t }) { |
| | | const translate = typeof t === 'function' ? t : $t |
| | | return [ |
| | | { |
| | | type: 'expand', |
| | | width: 56, |
| | | formatter: (row) => ({ |
| | | render() { |
| | | return h(WaveOrderRelaPanel, { |
| | | waveId: row.id |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | { type: 'selection', width: 48, align: 'center' }, |
| | | { type: 'globalIndex', label: translate('table.index'), width: 72, align: 'center' }, |
| | | { |
| | | prop: 'id', |
| | | label: translate('table.id'), |
| | | width: 90, |
| | | align: 'center' |
| | | }, |
| | | { |
| | | prop: 'code', |
| | | label: translate('pages.orders.wave.table.code'), |
| | |
| | | { |
| | | prop: 'anfme', |
| | | label: translate('pages.orders.wave.table.anfme'), |
| | | width: 110, |
| | | align: 'right' |
| | | }, |
| | | { |
| | | prop: 'groupQty', |
| | | label: translate('pages.orders.wave.table.groupQty'), |
| | | width: 110, |
| | | align: 'right' |
| | | }, |
| | |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'updateByText', |
| | | label: translate('table.updateBy'), |
| | | minWidth: 120, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'createByText', |
| | | label: translate('table.createBy'), |
| | | minWidth: 120, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'statusLabel', |
| | | label: translate('pages.orders.wave.table.status'), |
| | | width: 100, |
| | |
| | | { type: Number(row.status) === 1 ? 'success' : 'danger', effect: 'light' }, |
| | | () => row.statusLabel |
| | | ) |
| | | }, |
| | | { |
| | | prop: 'memo', |
| | | label: translate('table.memo'), |
| | | minWidth: 150, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'operation', |
| | |
| | | export function createWaveDetailItemColumns(t) { |
| | | return createWavePreviewItemColumns(t) |
| | | } |
| | | |
| | | export function createWaveOrderRelaColumns(t) { |
| | | const translate = typeof t === 'function' ? t : $t |
| | | return [ |
| | | { type: 'globalIndex', label: translate('table.index'), width: 72, align: 'center' }, |
| | | { |
| | | prop: 'asnCode', |
| | | label: translate('pages.orders.wave.rela.asnCode'), |
| | | minWidth: 160, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'matnrCode', |
| | | label: translate('table.materialCode'), |
| | | minWidth: 140, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'maktx', |
| | | label: translate('table.materialName'), |
| | | minWidth: 220, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'splrBatch', |
| | | label: translate('table.supplierBatch'), |
| | | minWidth: 140, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'platOrderCode', |
| | | label: translate('pages.orders.wave.rela.platOrderCode'), |
| | | minWidth: 140, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'spec', |
| | | label: translate('pages.orders.wave.rela.spec'), |
| | | minWidth: 120, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'model', |
| | | label: translate('pages.orders.wave.rela.model'), |
| | | minWidth: 120, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { prop: 'anfme', label: translate('table.quantity'), width: 100, align: 'right' }, |
| | | { prop: 'stockUnit', label: translate('table.unit'), width: 90, align: 'center' }, |
| | | { |
| | | prop: 'splrName', |
| | | label: translate('table.supplier'), |
| | | minWidth: 150, |
| | | showOverflowTooltip: true |
| | | } |
| | | ] |
| | | } |
| | |
| | | manualChunks: createManualChunks |
| | | } |
| | | }, |
| | | minify: 'terser', |
| | | minify: 'esbuild', |
| | | terserOptions: { |
| | | compress: { |
| | | drop_console: true, |