| | |
| | | return typeof value === 'string' ? value.trim() : value |
| | | } |
| | | |
| | | function hasValue(value) { |
| | | return value !== '' && value !== null && value !== undefined |
| | | } |
| | | |
| | | function normalizeIds(ids) { |
| | | if (Array.isArray(ids)) { |
| | | return ids |
| | |
| | | } |
| | | |
| | | function normalizeNumber(value, fallback = void 0) { |
| | | if (value === '' || value === null || value === undefined) { |
| | | if (!hasValue(value)) { |
| | | return fallback |
| | | } |
| | | const parsed = Number(value) |
| | | return Number.isNaN(parsed) ? fallback : parsed |
| | | } |
| | | |
| | | function toOptionalNumber(value) { |
| | | return hasValue(value) ? Number(value) : void 0 |
| | | } |
| | | |
| | | function toNumberOr(value, fallback) { |
| | | return hasValue(value) ? Number(value) : fallback |
| | | } |
| | | |
| | | function buildNumberField(key, value) { |
| | | return hasValue(value) ? { [key]: Number(value) } : {} |
| | | } |
| | | |
| | | function normalizeTypeIds(typeIds = []) { |
| | |
| | | export function buildLocSearchParams(params = {}) { |
| | | const searchParams = { |
| | | condition: normalizeText(params.condition), |
| | | warehouseId: |
| | | params.warehouseId !== undefined && params.warehouseId !== null && params.warehouseId !== '' |
| | | ? Number(params.warehouseId) |
| | | : void 0, |
| | | areaId: |
| | | params.areaId !== undefined && params.areaId !== null && params.areaId !== '' |
| | | ? Number(params.areaId) |
| | | : void 0, |
| | | warehouseId: toOptionalNumber(params.warehouseId), |
| | | areaId: toOptionalNumber(params.areaId), |
| | | code: normalizeText(params.code), |
| | | useStatus: normalizeText(params.useStatus), |
| | | row: |
| | | params.row !== undefined && params.row !== null && params.row !== '' |
| | | ? Number(params.row) |
| | | : void 0, |
| | | col: |
| | | params.col !== undefined && params.col !== null && params.col !== '' |
| | | ? Number(params.col) |
| | | : void 0, |
| | | lev: |
| | | params.lev !== undefined && params.lev !== null && params.lev !== '' |
| | | ? Number(params.lev) |
| | | : void 0, |
| | | channel: |
| | | params.channel !== undefined && params.channel !== null && params.channel !== '' |
| | | ? Number(params.channel) |
| | | : void 0, |
| | | status: |
| | | params.status !== undefined && params.status !== null && params.status !== '' |
| | | ? Number(params.status) |
| | | : void 0, |
| | | row: toOptionalNumber(params.row), |
| | | col: toOptionalNumber(params.col), |
| | | lev: toOptionalNumber(params.lev), |
| | | channel: toOptionalNumber(params.channel), |
| | | status: toOptionalNumber(params.status), |
| | | barcode: normalizeText(params.barcode), |
| | | memo: normalizeText(params.memo) |
| | | } |
| | | |
| | | return Object.fromEntries( |
| | | Object.entries(searchParams).filter(([, value]) => value !== '' && value !== void 0 && value !== null) |
| | | ) |
| | | return Object.fromEntries(Object.entries(searchParams).filter(([, value]) => hasValue(value))) |
| | | } |
| | | |
| | | export function buildLocSavePayload(formData = {}) { |
| | | return { |
| | | ...(formData.id !== undefined && formData.id !== null && formData.id !== '' |
| | | ? { id: Number(formData.id) } |
| | | : {}), |
| | | ...(formData.version !== undefined && formData.version !== null && formData.version !== '' |
| | | ? { version: Number(formData.version) } |
| | | : {}), |
| | | ...(formData.warehouseId !== undefined && formData.warehouseId !== null && formData.warehouseId !== '' |
| | | ? { warehouseId: Number(formData.warehouseId) } |
| | | : {}), |
| | | ...(formData.areaId !== undefined && formData.areaId !== null && formData.areaId !== '' |
| | | ? { areaId: Number(formData.areaId) } |
| | | : {}), |
| | | ...buildNumberField('id', formData.id), |
| | | ...buildNumberField('version', formData.version), |
| | | ...buildNumberField('warehouseId', formData.warehouseId), |
| | | ...buildNumberField('areaId', formData.areaId), |
| | | code: normalizeText(formData.code) || '', |
| | | typeIds: normalizeTypeIds(formData.typeIds), |
| | | ...(formData.flagLogic !== undefined && formData.flagLogic !== null && formData.flagLogic !== '' |
| | | ? { flagLogic: Number(formData.flagLogic) } |
| | | : {}), |
| | | ...buildNumberField('flagLogic', formData.flagLogic), |
| | | fucAtrrs: normalizeText(formData.fucAtrrs) || '', |
| | | barcode: normalizeText(formData.barcode) || '', |
| | | unit: normalizeText(formData.unit) || '', |
| | | ...(formData.length !== undefined && formData.length !== null && formData.length !== '' |
| | | ? { length: Number(formData.length) } |
| | | : {}), |
| | | ...(formData.height !== undefined && formData.height !== null && formData.height !== '' |
| | | ? { height: Number(formData.height) } |
| | | : {}), |
| | | ...(formData.width !== undefined && formData.width !== null && formData.width !== '' |
| | | ? { width: Number(formData.width) } |
| | | : {}), |
| | | ...(formData.row !== undefined && formData.row !== null && formData.row !== '' |
| | | ? { row: Number(formData.row) } |
| | | : {}), |
| | | ...(formData.col !== undefined && formData.col !== null && formData.col !== '' |
| | | ? { col: Number(formData.col) } |
| | | : {}), |
| | | ...(formData.lev !== undefined && formData.lev !== null && formData.lev !== '' |
| | | ? { lev: Number(formData.lev) } |
| | | : {}), |
| | | ...(formData.channel !== undefined && formData.channel !== null && formData.channel !== '' |
| | | ? { channel: Number(formData.channel) } |
| | | : {}), |
| | | ...(formData.maxParts !== undefined && formData.maxParts !== null && formData.maxParts !== '' |
| | | ? { maxParts: Number(formData.maxParts) } |
| | | : {}), |
| | | ...(formData.maxPack !== undefined && formData.maxPack !== null && formData.maxPack !== '' |
| | | ? { maxPack: Number(formData.maxPack) } |
| | | : {}), |
| | | ...buildNumberField('length', formData.length), |
| | | ...buildNumberField('height', formData.height), |
| | | ...buildNumberField('width', formData.width), |
| | | ...buildNumberField('row', formData.row), |
| | | ...buildNumberField('col', formData.col), |
| | | ...buildNumberField('lev', formData.lev), |
| | | ...buildNumberField('channel', formData.channel), |
| | | ...buildNumberField('maxParts', formData.maxParts), |
| | | ...buildNumberField('maxPack', formData.maxPack), |
| | | useStatus: normalizeText(formData.useStatus) || 'O', |
| | | ...(formData.flagLabelMange !== undefined && formData.flagLabelMange !== null && formData.flagLabelMange !== '' |
| | | ? { flagLabelMange: Number(formData.flagLabelMange) } |
| | | : {}), |
| | | ...buildNumberField('flagLabelMange', formData.flagLabelMange), |
| | | locAttrs: normalizeText(formData.locAttrs) || '', |
| | | status: |
| | | formData.status !== undefined && formData.status !== null && formData.status !== '' |
| | | ? Number(formData.status) |
| | | : 1, |
| | | status: toNumberOr(formData.status, 1), |
| | | memo: normalizeText(formData.memo) || '' |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | function fetchOperationRecordPage(params = {}) { |
| | | return request.post({ url: '/operationRecord/page', params: buildOperationRecordPageParams(params) }) |
| | | return request.post({ |
| | | url: '/operationRecord/page', |
| | | params: buildOperationRecordPageParams(params) |
| | | }) |
| | | } |
| | | |
| | | function fetchConfigPage(params = {}) { |
| | |
| | | } |
| | | |
| | | function fetchGetMenuList(params = {}) { |
| | | return request.post({ url: '/menu/list', params }).then((menuList) => adaptLegacyMenuTree(buildLegacyMenuTree(menuList))) |
| | | return request |
| | | .post({ url: '/menu/list', params }) |
| | | .then((menuList) => adaptLegacyMenuTree(buildLegacyMenuTree(menuList))) |
| | | } |
| | | |
| | | function adaptLegacyMenuTree(menuTree) { |
| | |
| | | return [] |
| | | } |
| | | |
| | | return menuTree |
| | | .map((node) => adaptLegacyMenuNode(node)) |
| | | .filter(Boolean) |
| | | return menuTree.map((node) => adaptLegacyMenuNode(node)).filter(Boolean) |
| | | } |
| | | |
| | | function buildLegacyMenuTree(menuList) { |
| | |
| | | } |
| | | |
| | | function buildLegacyMenuPath(node) { |
| | | const rawPath = typeof node.route === 'string' && node.route.trim() |
| | | ? node.route |
| | | : typeof node.path === 'string' |
| | | ? node.path |
| | | : '' |
| | | const rawPath = |
| | | typeof node.route === 'string' && node.route.trim() |
| | | ? node.route |
| | | : typeof node.path === 'string' |
| | | ? node.path |
| | | : '' |
| | | return normalizeLegacyPath(rawPath) |
| | | } |
| | | |
| | |
| | | <ArtTableHeader v-model:columns="columnChecks" :loading="loading" @refresh="refreshData"> |
| | | <template #left> |
| | | <ElSpace wrap> |
| | | <ElButton v-auth="'add'" @click="handleShowDialog('add')" v-ripple>新增站点区域</ElButton> |
| | | <ElButton v-auth="'add'" @click="handleShowDialog('add')" v-ripple |
| | | >新增站点区域</ElButton |
| | | > |
| | | <ElButton |
| | | v-auth="'delete'" |
| | | type="danger" |
| | |
| | | detailDrawerVisible.value = true |
| | | detailLoading.value = true |
| | | try { |
| | | const detail = await guardRequestWithMessage(fetchBasStationAreaDetail(row.id), {}, { |
| | | timeoutMessage: '站点区域详情加载超时,已停止等待' |
| | | }) |
| | | const detail = await guardRequestWithMessage( |
| | | fetchBasStationAreaDetail(row.id), |
| | | {}, |
| | | { |
| | | timeoutMessage: '站点区域详情加载超时,已停止等待' |
| | | } |
| | | ) |
| | | detailData.value = normalizeBasStationAreaDetailRecord(detail, { |
| | | resolveAreaLabel, |
| | | resolveCrossZoneAreaLabel, |
| | |
| | | timeoutMessage: '站点别名选项加载超时,已停止等待' |
| | | } |
| | | ) |
| | | stationOptions.value = resolveBasStationAreaStationOptions(defaultResponseAdapter(response).records) |
| | | stationOptions.value = resolveBasStationAreaStationOptions( |
| | | defaultResponseAdapter(response).records |
| | | ) |
| | | stationOptionsLoaded.value = true |
| | | })() |
| | | |
| | |
| | | |
| | | async function openEditDialog(row) { |
| | | try { |
| | | const detail = await guardRequestWithMessage(fetchBasStationAreaDetail(row.id), {}, { |
| | | timeoutMessage: '站点区域详情加载超时,已停止等待' |
| | | }) |
| | | const detail = await guardRequestWithMessage( |
| | | fetchBasStationAreaDetail(row.id), |
| | | {}, |
| | | { |
| | | timeoutMessage: '站点区域详情加载超时,已停止等待' |
| | | } |
| | | ) |
| | | await handleShowDialog('edit', detail) |
| | | } catch (error) { |
| | | ElMessage.error(error?.message || '获取站点区域详情失败') |
| | | } |
| | | } |
| | | |
| | | const { columns, columnChecks, data, loading, pagination, getData, replaceSearchParams, resetSearchParams, handleSizeChange, handleCurrentChange, refreshData, refreshCreate, refreshUpdate, refreshRemove } = |
| | | useTable({ |
| | | core: { |
| | | apiFn: fetchBasStationAreaPage, |
| | | apiParams: buildBasStationAreaPageQueryParams(searchForm.value), |
| | | paginationKey: getBasStationAreaPaginationKey(), |
| | | columnsFactory: () => |
| | | createBasStationAreaTableColumns({ |
| | | handleView: openDetail, |
| | | handleEdit: hasAuth('update') ? openEditDialog : null, |
| | | handleDelete: hasAuth('delete') ? (row) => handleDeleteAction?.(row) : null, |
| | | canEdit: hasAuth('update'), |
| | | canDelete: hasAuth('delete') |
| | | }) |
| | | }, |
| | | transform: { |
| | | dataTransformer: (records) => { |
| | | if (!Array.isArray(records)) { |
| | | return [] |
| | | } |
| | | return records.map((item) => |
| | | normalizeBasStationAreaListRow(item, { |
| | | resolveAreaLabel, |
| | | resolveCrossZoneAreaLabel, |
| | | resolveContainerTypeLabel, |
| | | resolveTypeLabel, |
| | | resolveStationAliasLabel, |
| | | resolveUseStatusLabel |
| | | }) |
| | | ) |
| | | const { |
| | | columns, |
| | | columnChecks, |
| | | data, |
| | | loading, |
| | | pagination, |
| | | getData, |
| | | replaceSearchParams, |
| | | resetSearchParams, |
| | | handleSizeChange, |
| | | handleCurrentChange, |
| | | refreshData, |
| | | refreshCreate, |
| | | refreshUpdate, |
| | | refreshRemove |
| | | } = useTable({ |
| | | core: { |
| | | apiFn: fetchBasStationAreaPage, |
| | | apiParams: buildBasStationAreaPageQueryParams(searchForm.value), |
| | | paginationKey: getBasStationAreaPaginationKey(), |
| | | columnsFactory: () => |
| | | createBasStationAreaTableColumns({ |
| | | handleView: openDetail, |
| | | handleEdit: hasAuth('update') ? openEditDialog : null, |
| | | handleDelete: hasAuth('delete') ? (row) => handleDeleteAction?.(row) : null, |
| | | canEdit: hasAuth('update'), |
| | | canDelete: hasAuth('delete') |
| | | }) |
| | | }, |
| | | transform: { |
| | | dataTransformer: (records) => { |
| | | if (!Array.isArray(records)) { |
| | | return [] |
| | | } |
| | | return records.map((item) => |
| | | normalizeBasStationAreaListRow(item, { |
| | | resolveAreaLabel, |
| | | resolveCrossZoneAreaLabel, |
| | | resolveContainerTypeLabel, |
| | | resolveTypeLabel, |
| | | resolveStationAliasLabel, |
| | | resolveUseStatusLabel |
| | | }) |
| | | ) |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | const { |
| | | dialogVisible, |
| | |
| | | const response = await guardRequestWithMessage(fetchWarehouseAreasList(), [], { |
| | | timeoutMessage: '库区选项加载超时,已停止等待' |
| | | }) |
| | | const options = resolveBasStationAreaWarehouseAreaOptions(defaultResponseAdapter(response).records) |
| | | const options = resolveBasStationAreaWarehouseAreaOptions( |
| | | defaultResponseAdapter(response).records |
| | | ) |
| | | areaOptions.value = options |
| | | crossZoneAreaOptions.value = options |
| | | } |
| | |
| | | { records: [] }, |
| | | { timeoutMessage: '容器类型选项加载超时,已停止等待' } |
| | | ) |
| | | containerTypeOptions.value = resolveBasStationAreaContainerTypeOptions(defaultResponseAdapter(response).records) |
| | | containerTypeOptions.value = resolveBasStationAreaContainerTypeOptions( |
| | | defaultResponseAdapter(response).records |
| | | ) |
| | | } |
| | | |
| | | async function loadUseStatusOptions() { |
| | |
| | | { records: [] }, |
| | | { timeoutMessage: '使用状态选项加载超时,已停止等待' } |
| | | ) |
| | | useStatusOptions.value = resolveBasStationAreaUseStatusOptions(defaultResponseAdapter(response).records) |
| | | useStatusOptions.value = resolveBasStationAreaUseStatusOptions( |
| | | defaultResponseAdapter(response).records |
| | | ) |
| | | } |
| | | |
| | | onMounted(async () => { |
| | |
| | | buildLocSavePayload, |
| | | buildLocSearchParams, |
| | | createLocSearchState, |
| | | filterLocAreaOptionsByWarehouse, |
| | | getLocPaginationKey, |
| | | getLocStatusOptions, |
| | | getLocUseStatusOptions, |
| | |
| | | |
| | | const reportTitle = LOC_REPORT_TITLE |
| | | const reportQueryParams = computed(() => buildLocSearchParams(searchForm.value)) |
| | | const filteredSearchAreaOptions = computed(() => |
| | | filterLocAreaOptionsByWarehouse(areaOptions.value, searchForm.value.warehouseId) |
| | | ) |
| | | |
| | | const searchItems = computed(() => [ |
| | | { |
| | | label: '关键字', |
| | | key: 'condition', |
| | | function createInputSearchItem(label, key, placeholder) { |
| | | return { |
| | | label, |
| | | key, |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入库位号/容器编码/备注' |
| | | } |
| | | }, |
| | | { |
| | | label: '仓库', |
| | | key: 'warehouseId', |
| | | type: 'select', |
| | | props: { |
| | | clearable: true, |
| | | filterable: true, |
| | | options: warehouseOptions.value |
| | | } |
| | | }, |
| | | { |
| | | label: '库区', |
| | | key: 'areaId', |
| | | type: 'select', |
| | | props: { |
| | | clearable: true, |
| | | filterable: true, |
| | | options: areaOptions.value.filter((item) => { |
| | | if (!searchForm.value.warehouseId) { |
| | | return true |
| | | } |
| | | if (item?.warehouseId === undefined || item?.warehouseId === null) { |
| | | return true |
| | | } |
| | | return Number(item.warehouseId) === Number(searchForm.value.warehouseId) |
| | | }) |
| | | } |
| | | }, |
| | | { |
| | | label: '库位号', |
| | | key: 'code', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入库位号' |
| | | } |
| | | }, |
| | | { |
| | | label: '使用状态', |
| | | key: 'useStatus', |
| | | type: 'select', |
| | | props: { |
| | | clearable: true, |
| | | filterable: true, |
| | | options: getLocUseStatusOptions() |
| | | } |
| | | }, |
| | | { |
| | | label: '排', |
| | | key: 'row', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入排' |
| | | } |
| | | }, |
| | | { |
| | | label: '列', |
| | | key: 'col', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入列' |
| | | } |
| | | }, |
| | | { |
| | | label: '层', |
| | | key: 'lev', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入层' |
| | | } |
| | | }, |
| | | { |
| | | label: '巷道', |
| | | key: 'channel', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入巷道' |
| | | } |
| | | }, |
| | | { |
| | | label: '状态', |
| | | key: 'status', |
| | | type: 'select', |
| | | props: { |
| | | clearable: true, |
| | | options: getLocStatusOptions() |
| | | } |
| | | }, |
| | | { |
| | | label: '容器编码', |
| | | key: 'barcode', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入容器编码' |
| | | } |
| | | }, |
| | | { |
| | | label: '备注', |
| | | key: 'memo', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入备注' |
| | | placeholder |
| | | } |
| | | } |
| | | } |
| | | |
| | | function createNumberSearchItem(label, key, placeholder) { |
| | | return { |
| | | label, |
| | | key, |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | controlsPosition: 'right', |
| | | placeholder |
| | | } |
| | | } |
| | | } |
| | | |
| | | function createSelectSearchItem(label, key, options, extraProps = {}) { |
| | | return { |
| | | label, |
| | | key, |
| | | type: 'select', |
| | | props: { |
| | | clearable: true, |
| | | ...extraProps, |
| | | options |
| | | } |
| | | } |
| | | } |
| | | |
| | | const searchItems = computed(() => [ |
| | | createInputSearchItem('关键字', 'condition', '请输入库位号/容器编码/备注'), |
| | | createSelectSearchItem('仓库', 'warehouseId', warehouseOptions.value, { filterable: true }), |
| | | createSelectSearchItem('库区', 'areaId', filteredSearchAreaOptions.value, { filterable: true }), |
| | | createInputSearchItem('库位号', 'code', '请输入库位号'), |
| | | createSelectSearchItem('使用状态', 'useStatus', getLocUseStatusOptions(), { filterable: true }), |
| | | createNumberSearchItem('排', 'row', '请输入排'), |
| | | createNumberSearchItem('列', 'col', '请输入列'), |
| | | createNumberSearchItem('层', 'lev', '请输入层'), |
| | | createNumberSearchItem('巷道', 'channel', '请输入巷道'), |
| | | createSelectSearchItem('状态', 'status', getLocStatusOptions()), |
| | | createInputSearchItem('容器编码', 'barcode', '请输入容器编码'), |
| | | createInputSearchItem('备注', 'memo', '请输入备注') |
| | | ]) |
| | | |
| | | async function fetchLocDetailById(id) { |
| | | return guardRequestWithMessage(fetchGetLocDetail(id), {}, { |
| | | timeoutMessage: '库位详情加载超时,已停止等待' |
| | | }) |
| | | } |
| | | |
| | | async function openDetail(row) { |
| | | detailDrawerVisible.value = true |
| | | detailLoading.value = true |
| | | try { |
| | | const detail = await guardRequestWithMessage(fetchGetLocDetail(row.id), {}, { |
| | | timeoutMessage: '库位详情加载超时,已停止等待' |
| | | }) |
| | | detailData.value = normalizeLocListRow(detail) |
| | | detailData.value = normalizeLocListRow(await fetchLocDetailById(row.id)) |
| | | } catch (error) { |
| | | detailDrawerVisible.value = false |
| | | detailData.value = {} |
| | |
| | | |
| | | async function openEditDialog(row) { |
| | | try { |
| | | const detail = await guardRequestWithMessage(fetchGetLocDetail(row.id), {}, { |
| | | timeoutMessage: '库位详情加载超时,已停止等待' |
| | | }) |
| | | showDialog('edit', detail) |
| | | showDialog('edit', await fetchLocDetailById(row.id)) |
| | | } catch (error) { |
| | | ElMessage.error(error?.message || '获取库位详情失败') |
| | | } |
| | |
| | | }) |
| | | ) |
| | | |
| | | async function loadWarehouseOptions() { |
| | | const response = await guardRequestWithMessage(fetchWarehouseList(), [], { |
| | | timeoutMessage: '仓库选项加载超时,已停止等待' |
| | | }) |
| | | warehouseOptions.value = resolveLocWarehouseOptions(defaultResponseAdapter(response).records) |
| | | } |
| | | |
| | | async function loadAreaOptions() { |
| | | const response = await guardRequestWithMessage(fetchWarehouseAreasList(), [], { |
| | | timeoutMessage: '库区选项加载超时,已停止等待' |
| | | }) |
| | | areaOptions.value = resolveLocAreaOptions(defaultResponseAdapter(response).records) |
| | | } |
| | | |
| | | async function loadLocTypeOptions() { |
| | | const response = await guardRequestWithMessage(fetchLocTypeList(), [], { |
| | | timeoutMessage: '库位类型选项加载超时,已停止等待' |
| | | }) |
| | | locTypeOptions.value = resolveLocTypeOptions(defaultResponseAdapter(response).records) |
| | | async function loadOptions(requestFn, resolver, targetRef, timeoutMessage) { |
| | | const response = await guardRequestWithMessage(requestFn(), [], { timeoutMessage }) |
| | | targetRef.value = resolver(defaultResponseAdapter(response).records) |
| | | } |
| | | |
| | | function handleSearch(params) { |
| | |
| | | } |
| | | |
| | | onMounted(async () => { |
| | | await Promise.all([loadWarehouseOptions(), loadAreaOptions(), loadLocTypeOptions()]) |
| | | await Promise.all([ |
| | | loadOptions(fetchWarehouseList, resolveLocWarehouseOptions, warehouseOptions, '仓库选项加载超时,已停止等待'), |
| | | loadOptions(fetchWarehouseAreasList, resolveLocAreaOptions, areaOptions, '库区选项加载超时,已停止等待'), |
| | | loadOptions(fetchLocTypeList, resolveLocTypeOptions, locTypeOptions, '库位类型选项加载超时,已停止等待') |
| | | ]) |
| | | }) |
| | | </script> |
| | |
| | | F: { text: '在库', type: 'primary' } |
| | | } |
| | | |
| | | const LOC_ID_FIELDS = ['id', 'version', 'warehouseId', 'areaId'] |
| | | const LOC_SIZE_FIELDS = ['length', 'height', 'width'] |
| | | const LOC_POSITION_FIELDS = ['row', 'col', 'lev', 'channel'] |
| | | const LOC_CAPACITY_FIELDS = ['maxParts', 'maxPack'] |
| | | const LOC_OPTIONAL_NUMBER_FIELDS = [...LOC_ID_FIELDS, ...LOC_SIZE_FIELDS, ...LOC_POSITION_FIELDS, ...LOC_CAPACITY_FIELDS] |
| | | |
| | | export const LOC_REPORT_TITLE = '库位报表' |
| | | export const LOC_REPORT_STYLE = { |
| | | titleAlign: 'center', |
| | |
| | | return String(value ?? '').trim() |
| | | } |
| | | |
| | | function hasValue(value) { |
| | | return value !== '' && value !== null && value !== undefined |
| | | } |
| | | |
| | | function normalizeNumber(value, fallback = void 0) { |
| | | if (value === '' || value === null || value === undefined) { |
| | | if (!hasValue(value)) { |
| | | return fallback |
| | | } |
| | | const parsed = Number(value) |
| | | return Number.isNaN(parsed) ? fallback : parsed |
| | | } |
| | | |
| | | function toOptionalNumber(value) { |
| | | return hasValue(value) ? Number(value) : void 0 |
| | | } |
| | | |
| | | function toNumberOr(value, fallback) { |
| | | return hasValue(value) ? Number(value) : fallback |
| | | } |
| | | |
| | | function buildNumberField(key, value) { |
| | | return hasValue(value) ? { [key]: Number(value) } : {} |
| | | } |
| | | |
| | | function buildOptionalNumberFields(source = {}, fields = []) { |
| | | return Object.fromEntries(fields.map((field) => [field, toOptionalNumber(source[field])]).filter(([, value]) => hasValue(value))) |
| | | } |
| | | |
| | | function normalizeFlagText(value) { |
| | |
| | | |
| | | function normalizeTypeIds(typeIds = []) { |
| | | if (Array.isArray(typeIds)) { |
| | | return typeIds |
| | | .map((item) => normalizeNumber(item, void 0)) |
| | | .filter((item) => item !== void 0 && item !== null) |
| | | return typeIds.map((item) => normalizeNumber(item, void 0)).filter(hasValue) |
| | | } |
| | | |
| | | if (typeof typeIds === 'string' && typeIds.trim()) { |
| | | return typeIds |
| | | .split(',') |
| | | .map((item) => normalizeNumber(item, void 0)) |
| | | .filter((item) => item !== void 0 && item !== null) |
| | | return typeIds.split(',').map((item) => normalizeNumber(item, void 0)).filter(hasValue) |
| | | } |
| | | |
| | | return [] |
| | | } |
| | | |
| | | export function filterLocAreaOptionsByWarehouse(options = [], warehouseId) { |
| | | if (!warehouseId) { |
| | | return options |
| | | } |
| | | |
| | | return options.filter((item) => { |
| | | if (!hasValue(item?.warehouseId)) { |
| | | return true |
| | | } |
| | | return Number(item.warehouseId) === Number(warehouseId) |
| | | }) |
| | | } |
| | | |
| | | export function createLocSearchState() { |
| | |
| | | export function buildLocSearchParams(params = {}) { |
| | | const searchParams = { |
| | | condition: normalizeText(params.condition), |
| | | warehouseId: |
| | | params.warehouseId !== undefined && params.warehouseId !== null && params.warehouseId !== '' |
| | | ? Number(params.warehouseId) |
| | | : void 0, |
| | | areaId: |
| | | params.areaId !== undefined && params.areaId !== null && params.areaId !== '' |
| | | ? Number(params.areaId) |
| | | : void 0, |
| | | warehouseId: toOptionalNumber(params.warehouseId), |
| | | areaId: toOptionalNumber(params.areaId), |
| | | code: normalizeText(params.code), |
| | | useStatus: normalizeText(params.useStatus), |
| | | row: |
| | | params.row !== undefined && params.row !== null && params.row !== '' |
| | | ? Number(params.row) |
| | | : void 0, |
| | | col: |
| | | params.col !== undefined && params.col !== null && params.col !== '' |
| | | ? Number(params.col) |
| | | : void 0, |
| | | lev: |
| | | params.lev !== undefined && params.lev !== null && params.lev !== '' |
| | | ? Number(params.lev) |
| | | : void 0, |
| | | channel: |
| | | params.channel !== undefined && params.channel !== null && params.channel !== '' |
| | | ? Number(params.channel) |
| | | : void 0, |
| | | status: |
| | | params.status !== undefined && params.status !== null && params.status !== '' |
| | | ? Number(params.status) |
| | | : void 0, |
| | | row: toOptionalNumber(params.row), |
| | | col: toOptionalNumber(params.col), |
| | | lev: toOptionalNumber(params.lev), |
| | | channel: toOptionalNumber(params.channel), |
| | | status: toOptionalNumber(params.status), |
| | | barcode: normalizeText(params.barcode), |
| | | memo: normalizeText(params.memo) |
| | | } |
| | | |
| | | return Object.fromEntries( |
| | | Object.entries(searchParams).filter(([, value]) => value !== '' && value !== void 0 && value !== null) |
| | | ) |
| | | return Object.fromEntries(Object.entries(searchParams).filter(([, value]) => hasValue(value))) |
| | | } |
| | | |
| | | export function buildLocPageQueryParams(params = {}) { |
| | |
| | | |
| | | export function buildLocSavePayload(formData = {}) { |
| | | return { |
| | | ...(formData.id !== undefined && formData.id !== null && formData.id !== '' |
| | | ? { id: Number(formData.id) } |
| | | : {}), |
| | | ...(formData.version !== undefined && formData.version !== null && formData.version !== '' |
| | | ? { version: Number(formData.version) } |
| | | : {}), |
| | | ...(formData.warehouseId !== undefined && formData.warehouseId !== null && formData.warehouseId !== '' |
| | | ? { warehouseId: Number(formData.warehouseId) } |
| | | : {}), |
| | | ...(formData.areaId !== undefined && formData.areaId !== null && formData.areaId !== '' |
| | | ? { areaId: Number(formData.areaId) } |
| | | : {}), |
| | | ...buildOptionalNumberFields(formData, LOC_ID_FIELDS), |
| | | code: normalizeText(formData.code) || '', |
| | | typeIds: normalizeTypeIds(formData.typeIds), |
| | | ...(formData.flagLogic !== undefined && formData.flagLogic !== null && formData.flagLogic !== '' |
| | | ? { flagLogic: Number(formData.flagLogic) } |
| | | : {}), |
| | | ...buildNumberField('flagLogic', formData.flagLogic), |
| | | fucAtrrs: normalizeText(formData.fucAtrrs) || '', |
| | | barcode: normalizeText(formData.barcode) || '', |
| | | unit: normalizeText(formData.unit) || '', |
| | | ...(formData.length !== undefined && formData.length !== null && formData.length !== '' |
| | | ? { length: Number(formData.length) } |
| | | : {}), |
| | | ...(formData.height !== undefined && formData.height !== null && formData.height !== '' |
| | | ? { height: Number(formData.height) } |
| | | : {}), |
| | | ...(formData.width !== undefined && formData.width !== null && formData.width !== '' |
| | | ? { width: Number(formData.width) } |
| | | : {}), |
| | | ...(formData.row !== undefined && formData.row !== null && formData.row !== '' |
| | | ? { row: Number(formData.row) } |
| | | : {}), |
| | | ...(formData.col !== undefined && formData.col !== null && formData.col !== '' |
| | | ? { col: Number(formData.col) } |
| | | : {}), |
| | | ...(formData.lev !== undefined && formData.lev !== null && formData.lev !== '' |
| | | ? { lev: Number(formData.lev) } |
| | | : {}), |
| | | ...(formData.channel !== undefined && formData.channel !== null && formData.channel !== '' |
| | | ? { channel: Number(formData.channel) } |
| | | : {}), |
| | | ...(formData.maxParts !== undefined && formData.maxParts !== null && formData.maxParts !== '' |
| | | ? { maxParts: Number(formData.maxParts) } |
| | | : {}), |
| | | ...(formData.maxPack !== undefined && formData.maxPack !== null && formData.maxPack !== '' |
| | | ? { maxPack: Number(formData.maxPack) } |
| | | : {}), |
| | | ...buildOptionalNumberFields(formData, [...LOC_SIZE_FIELDS, ...LOC_POSITION_FIELDS, ...LOC_CAPACITY_FIELDS]), |
| | | useStatus: normalizeText(formData.useStatus) || 'O', |
| | | ...(formData.flagLabelMange !== undefined && formData.flagLabelMange !== null && formData.flagLabelMange !== '' |
| | | ? { flagLabelMange: Number(formData.flagLabelMange) } |
| | | : {}), |
| | | ...buildNumberField('flagLabelMange', formData.flagLabelMange), |
| | | locAttrs: normalizeText(formData.locAttrs) || '', |
| | | status: |
| | | formData.status !== undefined && formData.status !== null && formData.status !== '' |
| | | ? Number(formData.status) |
| | | : 1, |
| | | status: toNumberOr(formData.status, 1), |
| | | memo: normalizeText(formData.memo) || '' |
| | | } |
| | | } |
| | |
| | | export function buildLocDialogModel(record = {}) { |
| | | return { |
| | | ...createLocFormState(), |
| | | ...(record.id !== undefined && record.id !== null && record.id !== '' ? { id: Number(record.id) } : {}), |
| | | ...(record.version !== undefined && record.version !== null && record.version !== '' |
| | | ? { version: Number(record.version) } |
| | | : {}), |
| | | warehouseId: |
| | | record.warehouseId !== undefined && record.warehouseId !== null && record.warehouseId !== '' |
| | | ? Number(record.warehouseId) |
| | | : void 0, |
| | | areaId: |
| | | record.areaId !== undefined && record.areaId !== null && record.areaId !== '' |
| | | ? Number(record.areaId) |
| | | : void 0, |
| | | ...buildOptionalNumberFields(record, LOC_OPTIONAL_NUMBER_FIELDS), |
| | | code: normalizeText(record.code || ''), |
| | | typeIds: normalizeTypeIds(record.typeIds ?? record.type ?? ''), |
| | | flagLogic: |
| | | record.flagLogic !== undefined && record.flagLogic !== null && record.flagLogic !== '' |
| | | ? Number(record.flagLogic) |
| | | : 0, |
| | | flagLogic: toNumberOr(record.flagLogic, 0), |
| | | fucAtrrs: normalizeText(record.fucAtrrs || ''), |
| | | barcode: normalizeText(record.barcode || ''), |
| | | unit: normalizeText(record.unit || ''), |
| | | length: |
| | | record.length !== undefined && record.length !== null && record.length !== '' |
| | | ? Number(record.length) |
| | | : void 0, |
| | | height: |
| | | record.height !== undefined && record.height !== null && record.height !== '' |
| | | ? Number(record.height) |
| | | : void 0, |
| | | width: |
| | | record.width !== undefined && record.width !== null && record.width !== '' |
| | | ? Number(record.width) |
| | | : void 0, |
| | | row: |
| | | record.row !== undefined && record.row !== null && record.row !== '' |
| | | ? Number(record.row) |
| | | : void 0, |
| | | col: |
| | | record.col !== undefined && record.col !== null && record.col !== '' |
| | | ? Number(record.col) |
| | | : void 0, |
| | | lev: |
| | | record.lev !== undefined && record.lev !== null && record.lev !== '' |
| | | ? Number(record.lev) |
| | | : void 0, |
| | | channel: |
| | | record.channel !== undefined && record.channel !== null && record.channel !== '' |
| | | ? Number(record.channel) |
| | | : void 0, |
| | | maxParts: |
| | | record.maxParts !== undefined && record.maxParts !== null && record.maxParts !== '' |
| | | ? Number(record.maxParts) |
| | | : void 0, |
| | | maxPack: |
| | | record.maxPack !== undefined && record.maxPack !== null && record.maxPack !== '' |
| | | ? Number(record.maxPack) |
| | | : void 0, |
| | | useStatus: normalizeText(record.useStatus || 'O') || 'O', |
| | | flagLabelMange: |
| | | record.flagLabelMange !== undefined && record.flagLabelMange !== null && record.flagLabelMange !== '' |
| | | ? Number(record.flagLabelMange) |
| | | : 0, |
| | | flagLabelMange: toNumberOr(record.flagLabelMange, 0), |
| | | locAttrs: normalizeText(record.locAttrs || ''), |
| | | status: record.status !== undefined && record.status !== null ? Number(record.status) : 1, |
| | | status: toNumberOr(record.status, 1), |
| | | memo: normalizeText(record.memo || '') |
| | | } |
| | | } |
| | |
| | | const typeIds = normalizeTypeIds(record.typeIds ?? record.type ?? '') |
| | | return { |
| | | ...record, |
| | | ...buildOptionalNumberFields(record, [...LOC_SIZE_FIELDS, ...LOC_POSITION_FIELDS, ...LOC_CAPACITY_FIELDS]), |
| | | warehouseName: normalizeText(record.warehouseId$ || record.warehouseName || ''), |
| | | areaName: normalizeText(record.areaId$ || record.areaName || ''), |
| | | typeIds, |
| | |
| | | statusText: statusMeta.text, |
| | | statusType: statusMeta.type, |
| | | statusBool: record.statusBool !== void 0 ? Boolean(record.statusBool) : statusMeta.bool, |
| | | row: record.row !== undefined && record.row !== null ? Number(record.row) : void 0, |
| | | col: record.col !== undefined && record.col !== null ? Number(record.col) : void 0, |
| | | lev: record.lev !== undefined && record.lev !== null ? Number(record.lev) : void 0, |
| | | channel: record.channel !== undefined && record.channel !== null ? Number(record.channel) : void 0, |
| | | length: record.length !== undefined && record.length !== null ? Number(record.length) : void 0, |
| | | height: record.height !== undefined && record.height !== null ? Number(record.height) : void 0, |
| | | width: record.width !== undefined && record.width !== null ? Number(record.width) : void 0, |
| | | maxParts: record.maxParts !== undefined && record.maxParts !== null ? Number(record.maxParts) : void 0, |
| | | maxPack: record.maxPack !== undefined && record.maxPack !== null ? Number(record.maxPack) : void 0, |
| | | createByText: normalizeText(record.createBy$ || record.createByText || ''), |
| | | createTimeText: normalizeText(record.createTime$ || record.createTime || ''), |
| | | updateByText: normalizeText(record.updateBy$ || record.updateByText || ''), |
| | |
| | | return null |
| | | } |
| | | const value = item.id ?? item.value |
| | | if (value === void 0 || value === null || value === '') { |
| | | if (!hasValue(value)) { |
| | | return null |
| | | } |
| | | return { |
| | |
| | | return null |
| | | } |
| | | const value = item.id ?? item.value |
| | | if (value === void 0 || value === null || value === '') { |
| | | if (!hasValue(value)) { |
| | | return null |
| | | } |
| | | return { |
| | | value: Number(value), |
| | | label: normalizeText(item.name || item.code || `库区 ${value}`), |
| | | warehouseId: |
| | | item.warehouseId !== undefined && item.warehouseId !== null && item.warehouseId !== '' |
| | | ? Number(item.warehouseId) |
| | | : void 0 |
| | | warehouseId: toOptionalNumber(item.warehouseId) |
| | | } |
| | | }) |
| | | .filter(Boolean) |
| | |
| | | return null |
| | | } |
| | | const value = item.id ?? item.value |
| | | if (value === void 0 || value === null || value === '') { |
| | | if (!hasValue(value)) { |
| | | return null |
| | | } |
| | | return { |
| | |
| | | import ArtButtonMore from '@/components/core/forms/art-button-more/index.vue' |
| | | import { getLocStatusMeta, getLocUseStatusMeta } from './locPage.helpers' |
| | | |
| | | function createTextColumn(prop, label, minWidth, formatter) { |
| | | return { |
| | | prop, |
| | | label, |
| | | minWidth, |
| | | showOverflowTooltip: true, |
| | | formatter: formatter || ((row) => row[prop] || '--') |
| | | } |
| | | } |
| | | |
| | | function createNumberColumn(prop, label, width) { |
| | | return { |
| | | prop, |
| | | label, |
| | | width, |
| | | align: 'center', |
| | | formatter: (row) => row[prop] ?? '--' |
| | | } |
| | | } |
| | | |
| | | function createTagColumn(prop, label, width, resolveMeta) { |
| | | return { |
| | | prop, |
| | | label, |
| | | width, |
| | | align: 'center', |
| | | formatter: (row) => { |
| | | const statusMeta = resolveMeta(row) |
| | | return h(ElTag, { type: statusMeta.type, effect: 'light' }, () => statusMeta.text) |
| | | } |
| | | } |
| | | } |
| | | |
| | | export function createLocTableColumns({ |
| | | handleView, |
| | | handleEdit, |
| | |
| | | return [ |
| | | { type: 'selection', width: 48, align: 'center' }, |
| | | { type: 'globalIndex', label: '序号', width: 72, align: 'center' }, |
| | | { |
| | | prop: 'code', |
| | | label: '库位号', |
| | | minWidth: 160, |
| | | showOverflowTooltip: true, |
| | | formatter: (row) => row.code || '--' |
| | | }, |
| | | { |
| | | prop: 'warehouseName', |
| | | label: '仓库', |
| | | minWidth: 150, |
| | | showOverflowTooltip: true, |
| | | formatter: (row) => row.warehouseName || row.warehouseId$ || '--' |
| | | }, |
| | | { |
| | | prop: 'areaName', |
| | | label: '库区', |
| | | minWidth: 150, |
| | | showOverflowTooltip: true, |
| | | formatter: (row) => row.areaName || row.areaId$ || '--' |
| | | }, |
| | | { |
| | | prop: 'typeIdsText', |
| | | label: '库位类型', |
| | | minWidth: 180, |
| | | showOverflowTooltip: true, |
| | | formatter: (row) => row.typeIdsText || '--' |
| | | }, |
| | | { |
| | | prop: 'row', |
| | | label: '排', |
| | | width: 80, |
| | | align: 'center', |
| | | formatter: (row) => row.row ?? '--' |
| | | }, |
| | | { |
| | | prop: 'col', |
| | | label: '列', |
| | | width: 80, |
| | | align: 'center', |
| | | formatter: (row) => row.col ?? '--' |
| | | }, |
| | | { |
| | | prop: 'lev', |
| | | label: '层', |
| | | width: 80, |
| | | align: 'center', |
| | | formatter: (row) => row.lev ?? '--' |
| | | }, |
| | | { |
| | | prop: 'channel', |
| | | label: '巷道', |
| | | width: 90, |
| | | align: 'center', |
| | | formatter: (row) => row.channel ?? '--' |
| | | }, |
| | | { |
| | | prop: 'useStatus', |
| | | label: '使用状态', |
| | | width: 110, |
| | | align: 'center', |
| | | formatter: (row) => { |
| | | const statusMeta = getLocUseStatusMeta(row.useStatus) |
| | | return h(ElTag, { type: statusMeta.type, effect: 'light' }, () => statusMeta.text) |
| | | } |
| | | }, |
| | | { |
| | | prop: 'flagLogicText', |
| | | label: '虚拟库位', |
| | | width: 110, |
| | | align: 'center', |
| | | formatter: (row) => row.flagLogicText || '--' |
| | | }, |
| | | { |
| | | prop: 'flagLabelMangeText', |
| | | label: '标签管理', |
| | | width: 110, |
| | | align: 'center', |
| | | formatter: (row) => row.flagLabelMangeText || '--' |
| | | }, |
| | | { |
| | | prop: 'barcode', |
| | | label: '容器编码', |
| | | minWidth: 150, |
| | | showOverflowTooltip: true, |
| | | formatter: (row) => row.barcode || '--' |
| | | }, |
| | | { |
| | | prop: 'status', |
| | | label: '状态', |
| | | width: 100, |
| | | align: 'center', |
| | | formatter: (row) => { |
| | | const statusMeta = getLocStatusMeta(row.statusBool ?? row.status) |
| | | return h(ElTag, { type: statusMeta.type, effect: 'light' }, () => statusMeta.text) |
| | | } |
| | | }, |
| | | { |
| | | prop: 'updateTimeText', |
| | | label: '更新时间', |
| | | minWidth: 170, |
| | | showOverflowTooltip: true, |
| | | formatter: (row) => row.updateTimeText || row.updateTime$ || '--' |
| | | }, |
| | | { |
| | | prop: 'memo', |
| | | label: '备注', |
| | | minWidth: 180, |
| | | showOverflowTooltip: true, |
| | | formatter: (row) => row.memo || '--' |
| | | }, |
| | | createTextColumn('code', '库位号', 160), |
| | | createTextColumn('warehouseName', '仓库', 150, (row) => row.warehouseName || row.warehouseId$ || '--'), |
| | | createTextColumn('areaName', '库区', 150, (row) => row.areaName || row.areaId$ || '--'), |
| | | createTextColumn('typeIdsText', '库位类型', 180), |
| | | createNumberColumn('row', '排', 80), |
| | | createNumberColumn('col', '列', 80), |
| | | createNumberColumn('lev', '层', 80), |
| | | createNumberColumn('channel', '巷道', 90), |
| | | createTagColumn('useStatus', '使用状态', 110, (row) => getLocUseStatusMeta(row.useStatus)), |
| | | createTextColumn('flagLogicText', '虚拟库位', 110), |
| | | createTextColumn('flagLabelMangeText', '标签管理', 110), |
| | | createTextColumn('barcode', '容器编码', 150), |
| | | createTagColumn('status', '状态', 100, (row) => getLocStatusMeta(row.statusBool ?? row.status)), |
| | | createTextColumn('updateTimeText', '更新时间', 170, (row) => row.updateTimeText || row.updateTime$ || '--'), |
| | | createTextColumn('memo', '备注', 180), |
| | | { |
| | | prop: 'operation', |
| | | label: '操作', |
| | |
| | | import { |
| | | buildLocDialogModel, |
| | | createLocFormState, |
| | | filterLocAreaOptionsByWarehouse, |
| | | getLocBinaryOptions, |
| | | getLocStatusOptions, |
| | | getLocUseStatusOptions |
| | |
| | | const isEdit = computed(() => props.dialogType === 'edit') |
| | | const dialogTitle = computed(() => (isEdit.value ? '编辑库位' : '新增库位')) |
| | | |
| | | const filteredAreaOptions = computed(() => { |
| | | if (!form.warehouseId) { |
| | | return props.areaOptions |
| | | const filteredAreaOptions = computed(() => |
| | | filterLocAreaOptionsByWarehouse(props.areaOptions || [], form.warehouseId) |
| | | ) |
| | | |
| | | function createInputFormItem(label, key, placeholder, extraProps = {}, extraConfig = {}) { |
| | | return { |
| | | label, |
| | | key, |
| | | type: 'input', |
| | | props: { |
| | | placeholder, |
| | | clearable: true, |
| | | ...extraProps |
| | | }, |
| | | ...extraConfig |
| | | } |
| | | return (props.areaOptions || []).filter((item) => { |
| | | if (item?.warehouseId === undefined || item?.warehouseId === null) { |
| | | return true |
| | | } |
| | | return Number(item.warehouseId) === Number(form.warehouseId) |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | function createNumberFormItem(label, key, placeholder, extraProps = {}, extraConfig = {}) { |
| | | return { |
| | | label, |
| | | key, |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | controlsPosition: 'right', |
| | | placeholder, |
| | | ...extraProps |
| | | }, |
| | | ...extraConfig |
| | | } |
| | | } |
| | | |
| | | function createSelectFormItem(label, key, placeholder, options, extraProps = {}, extraConfig = {}) { |
| | | return { |
| | | label, |
| | | key, |
| | | type: 'select', |
| | | props: { |
| | | placeholder, |
| | | clearable: true, |
| | | options, |
| | | ...extraProps |
| | | }, |
| | | ...extraConfig |
| | | } |
| | | } |
| | | |
| | | const rules = computed(() => ({ |
| | | warehouseId: [{ required: true, message: '请选择仓库', trigger: 'change' }], |
| | |
| | | })) |
| | | |
| | | const formItems = computed(() => [ |
| | | { |
| | | label: '仓库', |
| | | key: 'warehouseId', |
| | | type: 'select', |
| | | props: { |
| | | placeholder: '请选择仓库', |
| | | clearable: true, |
| | | filterable: true, |
| | | options: props.warehouseOptions |
| | | } |
| | | }, |
| | | { |
| | | label: '库区', |
| | | key: 'areaId', |
| | | type: 'select', |
| | | props: { |
| | | placeholder: '请选择库区', |
| | | clearable: true, |
| | | filterable: true, |
| | | options: filteredAreaOptions.value |
| | | } |
| | | }, |
| | | { |
| | | label: '库位号', |
| | | key: 'code', |
| | | type: 'input', |
| | | props: { |
| | | placeholder: '请输入库位号', |
| | | clearable: true |
| | | } |
| | | }, |
| | | { |
| | | label: '库位类型', |
| | | key: 'typeIds', |
| | | type: 'select', |
| | | props: { |
| | | placeholder: '请选择库位类型', |
| | | clearable: true, |
| | | multiple: true, |
| | | collapseTags: true, |
| | | filterable: true, |
| | | options: props.locTypeOptions |
| | | } |
| | | }, |
| | | { |
| | | label: '使用状态', |
| | | key: 'useStatus', |
| | | type: 'select', |
| | | props: { |
| | | placeholder: '请选择使用状态', |
| | | clearable: true, |
| | | filterable: true, |
| | | options: getLocUseStatusOptions() |
| | | } |
| | | }, |
| | | { |
| | | label: '状态', |
| | | key: 'status', |
| | | type: 'select', |
| | | props: { |
| | | placeholder: '请选择状态', |
| | | clearable: true, |
| | | options: getLocStatusOptions() |
| | | } |
| | | }, |
| | | { |
| | | label: '排', |
| | | key: 'row', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入排' |
| | | } |
| | | }, |
| | | { |
| | | label: '列', |
| | | key: 'col', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入列' |
| | | } |
| | | }, |
| | | { |
| | | label: '层', |
| | | key: 'lev', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入层' |
| | | } |
| | | }, |
| | | { |
| | | label: '巷道', |
| | | key: 'channel', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入巷道' |
| | | } |
| | | }, |
| | | { |
| | | label: '容器编码', |
| | | key: 'barcode', |
| | | type: 'input', |
| | | props: { |
| | | placeholder: '请输入容器编码', |
| | | clearable: true |
| | | } |
| | | }, |
| | | { |
| | | label: '存放单位', |
| | | key: 'unit', |
| | | type: 'input', |
| | | props: { |
| | | placeholder: '请输入存放单位', |
| | | clearable: true |
| | | } |
| | | }, |
| | | { |
| | | label: '虚拟库位', |
| | | key: 'flagLogic', |
| | | type: 'select', |
| | | props: { |
| | | placeholder: '请选择虚拟库位', |
| | | clearable: true, |
| | | options: getLocBinaryOptions() |
| | | } |
| | | }, |
| | | { |
| | | label: '标签管理', |
| | | key: 'flagLabelMange', |
| | | type: 'select', |
| | | props: { |
| | | placeholder: '请选择标签管理', |
| | | clearable: true, |
| | | options: getLocBinaryOptions() |
| | | } |
| | | }, |
| | | { |
| | | label: '长', |
| | | key: 'length', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | step: 0.01, |
| | | precision: 2, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入长' |
| | | } |
| | | }, |
| | | { |
| | | label: '宽', |
| | | key: 'width', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | step: 0.01, |
| | | precision: 2, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入宽' |
| | | } |
| | | }, |
| | | { |
| | | label: '高', |
| | | key: 'height', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | step: 0.01, |
| | | precision: 2, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入高' |
| | | } |
| | | }, |
| | | { |
| | | label: '最大零件数', |
| | | key: 'maxParts', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入最大零件数' |
| | | } |
| | | }, |
| | | { |
| | | label: '最大包装数', |
| | | key: 'maxPack', |
| | | type: 'number', |
| | | props: { |
| | | min: 0, |
| | | controlsPosition: 'right', |
| | | placeholder: '请输入最大包装数' |
| | | } |
| | | }, |
| | | { |
| | | label: '功能属性', |
| | | key: 'fucAtrrs', |
| | | type: 'input', |
| | | span: 24, |
| | | props: { |
| | | placeholder: '请输入功能属性', |
| | | clearable: true |
| | | } |
| | | }, |
| | | { |
| | | label: '属性', |
| | | key: 'locAttrs', |
| | | type: 'input', |
| | | span: 24, |
| | | props: { |
| | | placeholder: '请输入属性', |
| | | clearable: true |
| | | } |
| | | }, |
| | | { |
| | | label: '备注', |
| | | key: 'memo', |
| | | type: 'input', |
| | | span: 24, |
| | | props: { |
| | | type: 'textarea', |
| | | rows: 3, |
| | | placeholder: '请输入备注', |
| | | clearable: true |
| | | } |
| | | } |
| | | createSelectFormItem('仓库', 'warehouseId', '请选择仓库', props.warehouseOptions, { filterable: true }), |
| | | createSelectFormItem('库区', 'areaId', '请选择库区', filteredAreaOptions.value, { filterable: true }), |
| | | createInputFormItem('库位号', 'code', '请输入库位号'), |
| | | createSelectFormItem('库位类型', 'typeIds', '请选择库位类型', props.locTypeOptions, { |
| | | multiple: true, |
| | | collapseTags: true, |
| | | filterable: true |
| | | }), |
| | | createSelectFormItem('使用状态', 'useStatus', '请选择使用状态', getLocUseStatusOptions(), { filterable: true }), |
| | | createSelectFormItem('状态', 'status', '请选择状态', getLocStatusOptions()), |
| | | createNumberFormItem('排', 'row', '请输入排'), |
| | | createNumberFormItem('列', 'col', '请输入列'), |
| | | createNumberFormItem('层', 'lev', '请输入层'), |
| | | createNumberFormItem('巷道', 'channel', '请输入巷道'), |
| | | createInputFormItem('容器编码', 'barcode', '请输入容器编码'), |
| | | createInputFormItem('存放单位', 'unit', '请输入存放单位'), |
| | | createSelectFormItem('虚拟库位', 'flagLogic', '请选择虚拟库位', getLocBinaryOptions()), |
| | | createSelectFormItem('标签管理', 'flagLabelMange', '请选择标签管理', getLocBinaryOptions()), |
| | | createNumberFormItem('长', 'length', '请输入长', { step: 0.01, precision: 2 }), |
| | | createNumberFormItem('宽', 'width', '请输入宽', { step: 0.01, precision: 2 }), |
| | | createNumberFormItem('高', 'height', '请输入高', { step: 0.01, precision: 2 }), |
| | | createNumberFormItem('最大零件数', 'maxParts', '请输入最大零件数'), |
| | | createNumberFormItem('最大包装数', 'maxPack', '请输入最大包装数'), |
| | | createInputFormItem('功能属性', 'fucAtrrs', '请输入功能属性', {}, { span: 24 }), |
| | | createInputFormItem('属性', 'locAttrs', '请输入属性', {}, { span: 24 }), |
| | | createInputFormItem( |
| | | '备注', |
| | | 'memo', |
| | | '请输入备注', |
| | | { type: 'textarea', rows: 3 }, |
| | | { span: 24 } |
| | | ) |
| | | ]) |
| | | |
| | | const loadFormData = () => { |
| | |
| | | const userStore = useUserStore() |
| | | const reportTitle = ROLE_REPORT_TITLE |
| | | const reportQueryParams = computed(() => buildRoleSearchParams(searchForm.value)) |
| | | const roleActionHandlers = { |
| | | 'scope-menu': (row) => openScopeDialog('menu', row), |
| | | 'scope-pda': (row) => openScopeDialog('pda', row), |
| | | 'scope-matnr': (row) => openScopeDialog('matnr', row), |
| | | 'scope-warehouse': (row) => openScopeDialog('warehouse', row), |
| | | edit: (row) => showDialog('edit', row), |
| | | delete: (row) => handleDelete(row) |
| | | } |
| | | |
| | | function openScopeDialog(scopeType, row) { |
| | | permissionScopeType.value = scopeType |
| | |
| | | } |
| | | |
| | | function handleActionClick(item, row) { |
| | | switch (item.key) { |
| | | case 'scope-menu': |
| | | openScopeDialog('menu', row) |
| | | break |
| | | case 'scope-pda': |
| | | openScopeDialog('pda', row) |
| | | break |
| | | case 'scope-matnr': |
| | | openScopeDialog('matnr', row) |
| | | break |
| | | case 'scope-warehouse': |
| | | openScopeDialog('warehouse', row) |
| | | break |
| | | case 'edit': |
| | | showDialog('edit', row) |
| | | break |
| | | case 'delete': |
| | | handleDelete(row) |
| | | break |
| | | default: |
| | | break |
| | | } |
| | | roleActionHandlers[item.key]?.(row) |
| | | } |
| | | |
| | | const { |
| | |
| | | }) |
| | | ) |
| | | |
| | | const handleSearch = (params) => { |
| | | function handleSearch(params) { |
| | | replaceSearchParams(buildRoleSearchParams(params)) |
| | | getData() |
| | | } |
| | | |
| | | const handleReset = () => { |
| | | function handleReset() { |
| | | Object.assign(searchForm.value, createRoleSearchState()) |
| | | resetSearchParams() |
| | | } |
| | |
| | | |
| | | <script setup> |
| | | import ArtForm from '@/components/core/forms/art-form/index.vue' |
| | | import { buildRoleDialogModel, createRoleFormState } from '../rolePage.helpers' |
| | | import { buildRoleDialogModel, createRoleFormState, getRoleStatusOptions } from '../rolePage.helpers' |
| | | |
| | | const props = defineProps({ |
| | | visible: { required: false, default: false }, |
| | |
| | | name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }] |
| | | })) |
| | | |
| | | const formItems = computed(() => [ |
| | | { |
| | | label: '角色名称', |
| | | key: 'name', |
| | | function createInputFormItem(label, key, placeholder, extraProps = {}, extraConfig = {}) { |
| | | return { |
| | | label, |
| | | key, |
| | | type: 'input', |
| | | props: { |
| | | placeholder: '请输入角色名称', |
| | | clearable: true |
| | | } |
| | | }, |
| | | { |
| | | label: '角色编码', |
| | | key: 'code', |
| | | type: 'input', |
| | | props: { |
| | | placeholder: '请输入角色编码', |
| | | clearable: true |
| | | } |
| | | }, |
| | | { |
| | | label: '状态', |
| | | key: 'status', |
| | | placeholder, |
| | | clearable: true, |
| | | ...extraProps |
| | | }, |
| | | ...extraConfig |
| | | } |
| | | } |
| | | |
| | | function createSelectFormItem(label, key, placeholder, options, extraProps = {}, extraConfig = {}) { |
| | | return { |
| | | label, |
| | | key, |
| | | type: 'select', |
| | | props: { |
| | | placeholder: '请选择状态', |
| | | placeholder, |
| | | clearable: true, |
| | | options: [ |
| | | { label: '正常', value: 1 }, |
| | | { label: '禁用', value: 0 } |
| | | ] |
| | | } |
| | | }, |
| | | { |
| | | label: '备注', |
| | | key: 'memo', |
| | | type: 'input', |
| | | span: 24, |
| | | props: { |
| | | type: 'textarea', |
| | | rows: 3, |
| | | placeholder: '请输入备注', |
| | | clearable: true |
| | | } |
| | | options, |
| | | ...extraProps |
| | | }, |
| | | ...extraConfig |
| | | } |
| | | } |
| | | |
| | | const formItems = computed(() => [ |
| | | createInputFormItem('角色名称', 'name', '请输入角色名称'), |
| | | createInputFormItem('角色编码', 'code', '请输入角色编码'), |
| | | createSelectFormItem('状态', 'status', '请选择状态', getRoleStatusOptions()), |
| | | createInputFormItem('备注', 'memo', '请输入备注', { type: 'textarea', rows: 3 }, { span: 24 }) |
| | | ]) |
| | | |
| | | const resetForm = () => { |
| | |
| | | label: 'label', |
| | | children: 'children' |
| | | } |
| | | const scopeState = reactive( |
| | | Object.fromEntries( |
| | | scopeConfigs.map((config) => [ |
| | | config.scopeType, |
| | | { |
| | | loading: false, |
| | | loaded: false, |
| | | treeData: [], |
| | | checkedKeys: [], |
| | | halfCheckedKeys: [], |
| | | condition: '' |
| | | } |
| | | ]) |
| | | ) |
| | | ) |
| | | const scopeState = reactive(Object.fromEntries(scopeConfigs.map((config) => [config.scopeType, createScopeTabState()]))) |
| | | |
| | | const visible = computed({ |
| | | get: () => props.visible, |
| | |
| | | |
| | | const roleLabel = computed(() => props.roleData?.name || props.roleData?.code || '未选择角色') |
| | | |
| | | function createScopeTabState() { |
| | | return { |
| | | loading: false, |
| | | loaded: false, |
| | | treeData: [], |
| | | checkedKeys: [], |
| | | halfCheckedKeys: [], |
| | | condition: '' |
| | | } |
| | | } |
| | | |
| | | function resetScopeTabState(state) { |
| | | Object.assign(state, createScopeTabState()) |
| | | } |
| | | |
| | | function hasNodeKey(value) { |
| | | return value !== void 0 && value !== null && value !== '' |
| | | } |
| | | |
| | | const loadScopeData = async (scopeType, { reloadSelection = true } = {}) => { |
| | | const config = getRoleScopeConfig(scopeType) |
| | | const state = scopeState[scopeType] |
| | | state.loading = true |
| | | try { |
| | | const requests = [fetchGetRoleScopeTree(config.scopeType, { condition: state.condition || '' })] |
| | | if (reloadSelection) { |
| | | requests.unshift(fetchGetRoleScopeList(config.scopeType, props.roleData.id)) |
| | | } |
| | | const selectionRequest = reloadSelection |
| | | ? fetchGetRoleScopeList(config.scopeType, props.roleData.id) |
| | | : Promise.resolve(state.checkedKeys) |
| | | const treeRequest = fetchGetRoleScopeTree(config.scopeType, { condition: state.condition || '' }) |
| | | |
| | | const guardedResult = await guardRequestWithMessage( |
| | | reloadSelection ? Promise.all(requests) : Promise.resolve([state.checkedKeys, await requests[0]]), |
| | | Promise.all([selectionRequest, treeRequest]), |
| | | null, |
| | | { |
| | | timeoutMessage: `${config.title}加载超时,已停止等待` |
| | |
| | | const handleClosed = () => { |
| | | activeScopeType.value = props.scopeType || 'menu' |
| | | Object.keys(scopeState).forEach((key) => { |
| | | scopeState[key].loading = false |
| | | scopeState[key].loaded = false |
| | | scopeState[key].treeData = [] |
| | | scopeState[key].checkedKeys = [] |
| | | scopeState[key].halfCheckedKeys = [] |
| | | scopeState[key].condition = '' |
| | | resetScopeTabState(scopeState[key]) |
| | | }) |
| | | } |
| | | |
| | |
| | | const keys = [] |
| | | const traverse = (nodeList) => { |
| | | nodeList.forEach((node) => { |
| | | if (node.id !== void 0 && node.id !== null && node.id !== '') { |
| | | if (hasNodeKey(node.id)) { |
| | | keys.push(String(node.id)) |
| | | } |
| | | if (node.children?.length) { |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { createRoleSearchState } from '../rolePage.helpers' |
| | | import { createRoleSearchState, getRoleStatusOptions } from '../rolePage.helpers' |
| | | |
| | | const props = defineProps({ |
| | | modelValue: { required: true } |
| | |
| | | set: (val) => emit('update:modelValue', val) |
| | | }) |
| | | |
| | | const formItems = computed(() => [ |
| | | { |
| | | label: '角色名称', |
| | | key: 'name', |
| | | function createInputSearchItem(label, key, placeholder) { |
| | | return { |
| | | label, |
| | | key, |
| | | type: 'input', |
| | | props: { |
| | | placeholder: '请输入角色名称', |
| | | placeholder, |
| | | clearable: true |
| | | } |
| | | }, |
| | | { |
| | | label: '角色编码', |
| | | key: 'code', |
| | | type: 'input', |
| | | props: { |
| | | placeholder: '请输入角色编码', |
| | | clearable: true |
| | | } |
| | | }, |
| | | { |
| | | label: '备注', |
| | | key: 'memo', |
| | | type: 'input', |
| | | props: { |
| | | placeholder: '请输入备注', |
| | | clearable: true |
| | | } |
| | | }, |
| | | { |
| | | label: '关键字', |
| | | key: 'condition', |
| | | type: 'input', |
| | | props: { |
| | | placeholder: '输入关键字搜索', |
| | | clearable: true |
| | | } |
| | | }, |
| | | { |
| | | label: '状态', |
| | | key: 'status', |
| | | type: 'select', |
| | | props: { |
| | | placeholder: '请选择状态', |
| | | clearable: true, |
| | | options: [ |
| | | { label: '正常', value: 1 }, |
| | | { label: '禁用', value: 0 } |
| | | ] |
| | | } |
| | | } |
| | | } |
| | | |
| | | function createSelectSearchItem(label, key, placeholder, options) { |
| | | return { |
| | | label, |
| | | key, |
| | | type: 'select', |
| | | props: { |
| | | placeholder, |
| | | clearable: true, |
| | | options |
| | | } |
| | | } |
| | | } |
| | | |
| | | const formItems = computed(() => [ |
| | | createInputSearchItem('角色名称', 'name', '请输入角色名称'), |
| | | createInputSearchItem('角色编码', 'code', '请输入角色编码'), |
| | | createInputSearchItem('备注', 'memo', '请输入备注'), |
| | | createInputSearchItem('关键字', 'condition', '输入关键字搜索'), |
| | | createSelectSearchItem('状态', 'status', '请选择状态', getRoleStatusOptions()) |
| | | ]) |
| | | |
| | | function handleReset() { |
| | |
| | | const ROLE_STATUS_META = { |
| | | 1: { type: 'success', text: '正常', bool: true }, |
| | | 0: { type: 'danger', text: '禁用', bool: false } |
| | | } |
| | | |
| | | const ROLE_STATUS_OPTIONS = [ |
| | | { label: '正常', value: 1 }, |
| | | { label: '禁用', value: 0 } |
| | | ] |
| | | |
| | | export function createRoleSearchState() { |
| | | return { |
| | | name: '', |
| | |
| | | status: void 0, |
| | | condition: '' |
| | | } |
| | | } |
| | | |
| | | function hasValue(value) { |
| | | return value !== '' && value !== void 0 && value !== null |
| | | } |
| | | |
| | | function normalizeText(value) { |
| | | return String(value ?? '').trim() |
| | | } |
| | | |
| | | export function createRoleFormState() { |
| | |
| | | } |
| | | } |
| | | |
| | | export function getRoleStatusOptions() { |
| | | return ROLE_STATUS_OPTIONS.map((option) => ({ ...option })) |
| | | } |
| | | |
| | | export function buildRoleSearchParams(params = {}) { |
| | | const searchParams = { |
| | | name: params.name, |
| | | code: params.code, |
| | | memo: params.memo, |
| | | name: normalizeText(params.name), |
| | | code: normalizeText(params.code), |
| | | memo: normalizeText(params.memo), |
| | | status: params.status, |
| | | condition: params.condition |
| | | condition: normalizeText(params.condition) |
| | | } |
| | | |
| | | return Object.fromEntries( |
| | | Object.entries(searchParams).filter( |
| | | ([, value]) => value !== '' && value !== void 0 && value !== null |
| | | ) |
| | | ) |
| | | return Object.fromEntries(Object.entries(searchParams).filter(([, value]) => hasValue(value))) |
| | | } |
| | | |
| | | export function buildRolePageQueryParams(params = {}) { |
| | |
| | | export function buildRoleDialogModel(record = {}) { |
| | | return { |
| | | ...createRoleFormState(), |
| | | id: normalizeRoleId(record.id), |
| | | name: record.name || '', |
| | | code: record.code || '', |
| | | memo: record.memo || '', |
| | | status: record.status !== void 0 && record.status !== null ? record.status : 1 |
| | | ...buildRoleFormData(record) |
| | | } |
| | | } |
| | | |
| | | export function buildRoleSavePayload(form = {}) { |
| | | return { |
| | | id: normalizeRoleId(form.id), |
| | | name: form.name || '', |
| | | code: form.code || '', |
| | | memo: form.memo || '', |
| | | status: form.status !== void 0 && form.status !== null ? form.status : 1 |
| | | } |
| | | return buildRoleFormData(form) |
| | | } |
| | | |
| | | export function normalizeRoleListRow(record = {}) { |
| | |
| | | statusBool: record.statusBool !== void 0 ? Boolean(record.statusBool) : statusMeta.bool, |
| | | statusText: statusMeta.text, |
| | | statusType: statusMeta.type, |
| | | createTimeText: record.createTime$ || record.createTime || '', |
| | | updateTimeText: record.updateTime$ || record.updateTime || '' |
| | | createTimeText: normalizeText(record.createTime$ || record.createTime), |
| | | updateTimeText: normalizeText(record.updateTime$ || record.updateTime) |
| | | } |
| | | } |
| | | |
| | | export function getRoleStatusMeta(status) { |
| | | if (status === true || status === 1) { |
| | | return { type: 'success', text: '正常', bool: true } |
| | | if (status === true || status === 1 || status === '1') { |
| | | return ROLE_STATUS_META[1] |
| | | } |
| | | if (status === false || status === 0) { |
| | | return { type: 'danger', text: '禁用', bool: false } |
| | | if (status === false || status === 0 || status === '0') { |
| | | return ROLE_STATUS_META[0] |
| | | } |
| | | return { type: 'info', text: '未知', bool: false } |
| | | } |
| | |
| | | } |
| | | |
| | | function normalizeRoleId(value) { |
| | | if (value === '' || value === null || value === void 0) { |
| | | if (!hasValue(value)) { |
| | | return void 0 |
| | | } |
| | | const numeric = Number(value) |
| | |
| | | } |
| | | return numeric |
| | | } |
| | | |
| | | function buildRoleFormData(source = {}) { |
| | | return { |
| | | id: normalizeRoleId(source.id), |
| | | name: normalizeText(source.name), |
| | | code: normalizeText(source.code), |
| | | memo: normalizeText(source.memo), |
| | | status: hasValue(source.status) ? source.status : 1 |
| | | } |
| | | } |
| | |
| | | } |
| | | ] |
| | | |
| | | function createTextColumn(prop, label, minWidth, extra = {}) { |
| | | return { |
| | | prop, |
| | | label, |
| | | minWidth, |
| | | showOverflowTooltip: true, |
| | | ...extra |
| | | } |
| | | } |
| | | |
| | | function createTagColumn(prop, label, width, resolveMeta) { |
| | | return { |
| | | prop, |
| | | label, |
| | | width, |
| | | formatter: (row) => { |
| | | const statusMeta = resolveMeta(row) |
| | | return h(ElTag, { type: statusMeta.type, effect: 'light' }, () => statusMeta.text) |
| | | } |
| | | } |
| | | } |
| | | |
| | | export function createRoleTableColumns(handleActionClick) { |
| | | return [ |
| | | { type: 'selection', width: 52, fixed: 'left' }, |
| | | { |
| | | prop: 'name', |
| | | label: '角色名称', |
| | | minWidth: 140, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'code', |
| | | label: '角色编码', |
| | | minWidth: 140, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'memo', |
| | | label: '备注', |
| | | minWidth: 180, |
| | | showOverflowTooltip: true |
| | | }, |
| | | { |
| | | prop: 'status', |
| | | label: '状态', |
| | | width: 120, |
| | | formatter: (row) => { |
| | | const statusMeta = getRoleStatusMeta(row.statusBool ?? row.status) |
| | | return h(ElTag, { type: statusMeta.type, effect: 'light' }, () => statusMeta.text) |
| | | } |
| | | }, |
| | | { |
| | | prop: 'updateTimeText', |
| | | label: '更新时间', |
| | | minWidth: 180, |
| | | createTextColumn('name', '角色名称', 140), |
| | | createTextColumn('code', '角色编码', 140), |
| | | createTextColumn('memo', '备注', 180), |
| | | createTagColumn('status', '状态', 120, (row) => getRoleStatusMeta(row.statusBool ?? row.status)), |
| | | createTextColumn('updateTimeText', '更新时间', 180, { |
| | | sortable: true, |
| | | formatter: (row) => row.updateTimeText || '-' |
| | | }, |
| | | { |
| | | prop: 'createTimeText', |
| | | label: '创建时间', |
| | | minWidth: 180, |
| | | }), |
| | | createTextColumn('createTimeText', '创建时间', 180, { |
| | | sortable: true, |
| | | formatter: (row) => row.createTimeText || '-' |
| | | }, |
| | | }), |
| | | { |
| | | prop: 'operation', |
| | | label: '操作', |
| | |
| | | align: 'center', |
| | | fixed: 'right', |
| | | formatter: (row) => |
| | | h('div', [ |
| | | h(ArtButtonMore, { |
| | | list: ROLE_MORE_ACTIONS, |
| | | onClick: (item) => handleActionClick(item, row) |
| | | }) |
| | | ]) |
| | | h(ArtButtonMore, { |
| | | list: ROLE_MORE_ACTIONS, |
| | | onClick: (item) => handleActionClick(item, row) |
| | | }) |
| | | } |
| | | ] |
| | | } |