diff --git a/src/api/mes/moldget.js b/src/api/mes/moldget.js index 44fdb21..c1d333a 100644 --- a/src/api/mes/moldget.js +++ b/src/api/mes/moldget.js @@ -61,3 +61,12 @@ export function getSimpleUserList() { method: 'get' }) } + +// 仓库库区列表(根据仓库ID获取) +export function getWarehouseAreaSimpleList(warehouseId) { + return request({ + url: '/admin-api/erp/warehouse-area/simple-list', + method: 'get', + params: { warehouseId } + }) +} diff --git a/src/api/mes/sparepart.js b/src/api/mes/sparepart.js new file mode 100644 index 0000000..1afc49a --- /dev/null +++ b/src/api/mes/sparepart.js @@ -0,0 +1,22 @@ +import request from '@/utils/request' + +// 备件列表(分页查询全部产品,前端按 categoryType=5 过滤备件) +export function getSparepartSimpleList(pageNo = 1) { + return request({ + url: '/admin-api/erp/product/page', + method: 'get', + params: { + pageNo, + pageSize: 100 + } + }) +} + +// 备件详情(含供应商、图片等完整信息) +export function getSparepartDetail(id) { + return request({ + url: '/admin-api/erp/product/get', + method: 'get', + params: { id } + }) +} diff --git a/src/api/mes/sparepartInbound.js b/src/api/mes/sparepartInbound.js new file mode 100644 index 0000000..c4ff7a8 --- /dev/null +++ b/src/api/mes/sparepartInbound.js @@ -0,0 +1,36 @@ +import request from '@/utils/request' + +// 备件入库单创建 +export function createSparepartInbound(data) { + return request({ + url: '/admin-api/erp/stock-in/create', + method: 'post', + data: { ...data, inType: '备件入库' } + }) +} +// 备件入库单分页查询(待入库/待审核) +export function getSparepartInboundPage(params = {}) { + return request({ + url: '/admin-api/erp/stock-in/page', + method: 'get', + params: { ...params, inType: '备件入库' } + }) +} + +// 备件入库单审核(status: 20=通过, 1=驳回) +export function auditSparepartInbound(data) { + return request({ + url: '/admin-api/erp/stock-in/audit', + method: 'put', + data + }) +} + +// 备件入库单删除 +export function deleteSparepartInbound(id) { + return request({ + url: '/admin-api/erp/stock-in/delete', + method: 'delete', + params: { ids: String(id) } + }) +} diff --git a/src/api/mes/sparepartOutbound.js b/src/api/mes/sparepartOutbound.js new file mode 100644 index 0000000..5325f84 --- /dev/null +++ b/src/api/mes/sparepartOutbound.js @@ -0,0 +1,28 @@ +import request from '@/utils/request' + +// 备件出库单分页查询 +export function getSparepartOutboundPage(params = {}) { + return request({ + url: '/admin-api/erp/stock-out/page', + method: 'get', + params: { ...params, outType: '备件出库' } + }) +} + +// 备件出库单审核(status: 20=通过, 1=驳回) +export function auditSparepartOutbound(data) { + return request({ + url: '/admin-api/erp/stock-out/audit', + method: 'put', + data + }) +} + +// 备件出库单删除 +export function deleteSparepartOutbound(id) { + return request({ + url: '/admin-api/erp/stock-out/delete', + method: 'delete', + params: { ids: String(id) } + }) +} diff --git a/src/api/system/user.js b/src/api/system/user.js index 2641a5b..94acd63 100644 --- a/src/api/system/user.js +++ b/src/api/system/user.js @@ -22,10 +22,11 @@ export function getUserProfile() { }) } -export function getSimpleUserList() { +export function getSimpleUserList(params) { return request({ url: '/admin-api/system/user/simple-list', - method: 'get' + method: 'get', + params }) } diff --git a/src/components/common/PermissionMenuPage.vue b/src/components/common/PermissionMenuPage.vue index 8e1b115..314a4e5 100644 --- a/src/components/common/PermissionMenuPage.vue +++ b/src/components/common/PermissionMenuPage.vue @@ -37,7 +37,7 @@ - {{ translateLiteral(module.name) }} + {{ getDisplayName(module) }} @@ -60,9 +60,9 @@ size="24" :color="getModuleColor(moduleIndex)" > - {{ getMenuSymbol(entry.name, entryIndex) }} + {{ getMenuSymbol(getDisplayName(entry), entryIndex) }} - {{ translateLiteral(entry.name) }} + {{ getDisplayName(entry) }} @@ -77,10 +77,10 @@ diff --git a/src/pages_function/pages/moldoperate/deviceSelect.vue b/src/pages_function/pages/moldoperate/deviceSelect.vue index 4bbf07c..cac770e 100644 --- a/src/pages_function/pages/moldoperate/deviceSelect.vue +++ b/src/pages_function/pages/moldoperate/deviceSelect.vue @@ -69,6 +69,7 @@ import { useI18n } from 'vue-i18n' import NavBar from '@/components/common/NavBar.vue' import { getDeviceLedgerList } from '@/api/mes/moldoperate' import { getDeviceLineTree } from '@/api/mes/deviceLine' +import { getMoldBrandPage } from '@/api/mes/mold' const { t } = useI18n() @@ -105,65 +106,39 @@ function getStatusLabel(device) { return map[status] || textValue(device.deviceStatus) || '-' } -// 当前在机模具 - 优先从持久化存储读取(实时),否则 fallback 设备台账字段 -function getCurrentMold(device) { - const deviceId = device?.id - const deviceCode = device?.deviceCode +// 设备名 → 在机模具名 映射表 +const deviceMoldMap = ref(new Map()) - // 1. 优先读新版 _mountedMoldInfoMap(按 deviceId 索引,再用 deviceCode fallback) +async function loadDeviceMolds() { try { - const map = uni.getStorageSync('_mountedMoldInfoMap') || {} - // 先按 id 匹配 - const key = String(deviceId) - let info = deviceId != null ? map[key] : null - // 再按 deviceCode 匹配(兼容 id 可能不一致的情况) - if (!info && deviceCode) { - const found = Object.values(map).find((item) => item?.deviceCode === deviceCode) - if (found) info = found - } - - // 调试日志:只在首次加载时输出一次 - if (!getCurrentMold._logged) { - getCurrentMold._logged = true - console.log('[deviceSelect] === 调试信息 ===') - console.log('[deviceSelect] storage map keys:', Object.keys(map)) - console.log('[deviceSelect] storage map values:', map) - console.log('[deviceSelect] 当前设备 deviceId:', deviceId, 'type:', typeof deviceId, 'key:', key) - console.log('[deviceSelect] 当前设备 deviceCode:', deviceCode) - console.log('[deviceSelect] id匹配结果:', info ? '命中' : '未命中') - if (!info) { - console.log('[deviceSelect] 尝试 deviceCode fallback...') - for (const [k, v] of Object.entries(map)) { - console.log('[deviceSelect] storage[', k, '].deviceCode =', v?.deviceCode, 'vs 设备 code =', deviceCode, '匹配:', v?.deviceCode === deviceCode) - } + const res = await getMoldBrandPage({ pageSize: 100 }) + const root = res && res.data !== undefined ? res.data : res + const pageData = root?.pageResult || root + const list = Array.isArray(pageData) ? pageData : (Array.isArray(pageData?.list) ? pageData.list : []) + const map = new Map() + for (const mold of list) { + const deviceName = mold.deviceName + if (deviceName) { + if (!map.has(deviceName)) map.set(deviceName, []) + map.get(deviceName).push(mold.name || '') } - // fallback 检查 - const saved = uni.getStorageSync('_mountedMoldInfo') || null - console.log('[deviceSelect] 旧版 _mountedMoldInfo:', saved) - console.log('[deviceSelect] 设备台账字段 currentMold:', device?.currentMold, 'moldName:', device?.moldName, 'moldId:', device?.moldId) - } - - if (info?.mold) { - return info.mold.name || info.mold.moldName || '-' } + deviceMoldMap.value = map } catch (e) { - console.warn('[deviceSelect] read _mountedMoldInfoMap error', e) + console.error('loadDeviceMolds error', e) } +} - // 2. 兼容旧版 _mountedMoldInfo - let saved = null - try { saved = uni.getStorageSync('_mountedMoldInfo') || null } catch {} - if (saved) { - const idMatch = deviceId != null && String(saved.deviceId) === String(deviceId) - const codeMatch = deviceCode && saved.deviceCode === deviceCode - if (idMatch || codeMatch) { - return saved.mold?.name || saved.mold?.moldName || '-' - } +// 当前在机模具 - 从模具型号接口获取 +function getCurrentMold(device) { + if (!device) return t('moldOperate.noMoldOnDevice') + const deviceName = device.deviceName + if (deviceName && deviceMoldMap.value.has(deviceName)) { + const names = deviceMoldMap.value.get(deviceName) || [] + return names.join(',') } - - // 3. fallback 设备台账静态字段 - const staticMold = textValue(device.currentMold || device.moldName || device.moldId) - return staticMold === '-' ? t('moldOperate.noMoldOnDevice') : staticMold + // fallback 设备台账静态字段 + return textValue(device.currentMold || device.moldName) || t('moldOperate.noMoldOnDevice') } function flattenLineTree(nodes, parentId) { @@ -269,7 +244,7 @@ function handleConfirm() { } onShow(async () => { - await Promise.allSettled([loadDevices(), loadLineTree()]) + await Promise.allSettled([loadDevices(), loadLineTree(), loadDeviceMolds()]) }) diff --git a/src/pages_function/pages/moldoperate/dismount.vue b/src/pages_function/pages/moldoperate/dismount.vue index ada878e..ceffcd5 100644 --- a/src/pages_function/pages/moldoperate/dismount.vue +++ b/src/pages_function/pages/moldoperate/dismount.vue @@ -4,24 +4,24 @@ - - - - - {{ t('moldOperate.scanDevice') }} + + - - - {{ t('moldOperate.selectDevice') }} @@ -80,16 +80,6 @@ {{ t('moldOperate.product') }} {{ textValue(selectedMold.productName) }} - - {{ t('moldOperate.mountTime') }} - {{ textValue(selectedMold.mountTime) }} - - - - - {{ t('moldOperate.useCount') }} - {{ formatUseCount(selectedMold.useCount) }} - @@ -117,40 +107,15 @@ {{ t('moldOperate.operator') + ' & ' + t('moldOperate.remark') }} - - - - *{{ t('moldOperate.operator') }} - - - - {{ selectedOperator ? selectedOperator.label : t('moldOperate.placeholderOperator') }} - - - - - - - {{ item.label }} - - - 暂无数据 - + + + + *{{ t('moldOperate.operator') }} + + {{ currentUserName }} - {{ t('moldOperate.remark') }} @@ -202,11 +167,17 @@ import { computed, reactive, ref } from 'vue' import { onShow } from '@dcloudio/uni-app' import { useI18n } from 'vue-i18n' import NavBar from '@/components/common/NavBar.vue' -import { getLowerMoldList, getDeviceLedgerList, createMoldOperate } from '@/api/mes/moldoperate' +import { getDeviceLedgerList, createMoldOperate } from '@/api/mes/moldoperate' +import { getMoldBrandPage } from '@/api/mes/mold' +import useUserStore from '@/store/modules/user' import { getDeviceLineTree } from '@/api/mes/deviceLine' -import { getSimpleUserList } from '@/api/system/user' const { t } = useI18n() +const userStore = useUserStore() + +// 当前登录用户 +const currentUserName = computed(() => userStore.name || '未知用户') +const currentUserId = computed(() => userStore.userId) const lineInfoMap = ref(new Map()) // deviceLine id → { name, parentId, parentChain } @@ -282,10 +253,8 @@ const tempSelectedMoldId = ref(null) // ---- 操作人与备注 ---- const remarkText = ref('') -const operatorOptions = ref([]) const selectedOperator = ref(null) -const operatorIndex = ref(-1) -const showOperatorDropdown = ref(false) +const scanCodeInput = ref('') // ---- 工具函数 ---- function textValue(v) { @@ -295,12 +264,7 @@ function textValue(v) { return s || '-' } -function formatUseCount(count) { - if (count == null) return '-' - const num = Number(count) - if (isNaN(num)) return String(count) - return num.toLocaleString() + ' ' + t('moldOperate.countUnit') -} + function formatTime(time) { if (!time) return '-' @@ -374,45 +338,20 @@ function findArr(obj, d = 0) { return [] } -async function loadLowerMolds(deviceId) { +async function loadLowerMolds(deviceName) { lowerMoldLoading.value = true try { - // ====== 策略1:优先从持久化存储读取(按设备ID索引,不会互覆盖)====== - let map = {} - try { map = uni.getStorageSync('_mountedMoldInfoMap') || {} } catch {} - const savedInfo = map[String(deviceId)] || null - - console.log('[下模] 持久化在机模具信息 =', savedInfo ? JSON.stringify(savedInfo) : 'null', 'deviceId=', deviceId) - - if (savedInfo && savedInfo.mold) { - console.log('[下模] 命中持久化数据, deviceId=', deviceId) - const m = savedInfo.mold - lowerMoldOptions.value = [{ - id: m.id, - moldId: m.id, - moldName: m.name || m.moldName || '-', - moldCode: m.code || m.moldCode || '-', - productName: m.productName || '-', - mountTime: formatTime(savedInfo.mountTime), - useCount: '-' - }] - console.log('[下模] 使用持久化数据 =', JSON.stringify(lowerMoldOptions.value[0])) - return - } - console.log('[下模] 未命中持久化数据,进入接口查询') - - // ====== 策略2:fallback - 调用在机模具接口 ====== - let list = [] - try { - const res = await getLowerMoldList(deviceId) - const root = (res && res.data !== undefined) ? res.data : res - list = findArr(root) - } catch (apiErr) { - console.warn('[下模] getLowerMoldList 接口异常', apiErr) - } - - lowerMoldOptions.value = list - console.log('[下模] loadLowerMolds 返回 list.length =', list.length) + const res = await getMoldBrandPage({ deviceName, pageSize: 100 }) + const root = (res && res.data !== undefined) ? res.data : res + const pageData = root?.pageResult || root + const list = Array.isArray(pageData) ? pageData : (Array.isArray(pageData?.list) ? pageData.list : []) + lowerMoldOptions.value = list.map(m => ({ + id: m.id, + moldId: m.id, + moldName: m.name || '-', + moldCode: m.code || '-', + productName: m.productName || '-' + })) } catch (e) { console.error('loadLowerMolds error', e) } finally { @@ -420,17 +359,39 @@ async function loadLowerMolds(deviceId) { } } -// ---- 扫描设备码 ---- +// ---- 扫描/输入设备码 ---- +function matchDeviceByCode(code) { + if (!code) return null + let matched = null + if (code.toUpperCase().startsWith('EQUIPMENT-')) { + const idFromQr = code.replace(/EQUIPMENT-/i, '') + matched = deviceOptions.value.find((d) => String(d.raw.id) === idFromQr) + } + if (!matched) { + matched = deviceOptions.value.find((d) => + Object.values(d.raw).some((v) => + typeof v === 'string' && v.trim().toUpperCase() === code.toUpperCase() + ) || d.label.toUpperCase().includes(code.toUpperCase()) + ) + } + if (!matched) { + const idMatch = code.match(/(\d+)$/) + if (idMatch) { + matched = deviceOptions.value.find((d) => String(d.raw.id) === idMatch[1]) + } + } + return matched +} + function handleScan() { uni.scanCode({ onlyFromCamera: false, scanType: ['qrCode', 'barCode'], success(res) { - const code = res.result?.trim() + const code = (res.result || '').trim() if (!code) return - const matched = deviceOptions.value.find((d) => - d.raw.deviceCode === code || String(d.raw.code) === code || d.label.includes(code) - ) + scanCodeInput.value = code + const matched = matchDeviceByCode(code) if (matched) { selectDevice(matched.raw) } else { @@ -445,13 +406,24 @@ function handleScan() { }) } +function onScanInputConfirm() { + const code = scanCodeInput.value.trim() + if (!code) return + const matched = matchDeviceByCode(code) + if (matched) { + selectDevice(matched.raw) + } else { + uni.showToast({ title: t('moldOperate.deviceNotFound'), icon: 'none' }) + } +} + // ---- 设备选择 ---- function selectDevice(device) { selectedDevice.value = device || {} moldsLoaded.value = false selectedMold.value = {} - if (device?.id) { - loadLowerMolds(device.id).then(() => { + if (device?.deviceName) { + loadLowerMolds(device.deviceName).then(() => { moldsLoaded.value = true if (lowerMoldOptions.value.length > 0) { const first = lowerMoldOptions.value[0] @@ -459,9 +431,7 @@ function selectDevice(device) { id: first.id || first.moldId, moldName: first.moldName || first.name, moldCode: first.moldCode || first.code, - productName: first.productName || '-', - mountTime: first.mountTime || '-', - useCount: first.useCount ?? '-' + productName: first.productName || '-' } } }) @@ -475,12 +445,12 @@ function openDevicePicker() { // ---- 在机模具选择(更换下模对象)---- function openLowerMoldPicker() { - if (!selectedDevice.value?.id) { + if (!selectedDevice.value?.deviceName) { uni.showToast({ title: t('moldOperate.validatorDeviceRequired'), icon: 'none' }) return } tempSelectedMoldId.value = selectedMold.value ? String(selectedMold.value.id || selectedMold.value.moldId) : null - loadLowerMolds(selectedDevice.value.id).then(() => { + loadLowerMolds(selectedDevice.value.deviceName).then(() => { lowerMoldPickerRef.value?.open() }) } @@ -494,9 +464,7 @@ function confirmLowerMoldSelection() { id: mold.id || mold.moldId, moldName: mold.moldName || mold.name, moldCode: mold.moldCode || mold.code, - productName: mold.productName || '-', - mountTime: mold.mountTime || '-', - useCount: mold.useCount ?? '-' + productName: mold.productName || '-' } } lowerMoldPickerRef.value?.close() @@ -504,34 +472,16 @@ function confirmLowerMoldSelection() { function closeLowerMoldPicker() { lowerMoldPickerRef.value?.close() } -// ---- 操作人列表加载 ---- -async function loadOperators() { - try { - const res = await getSimpleUserList() - const data = Array.isArray(res) ? res : (Array.isArray(res?.data) ? res.data : []) - operatorOptions.value = data.map((u) => ({ - value: u.id || u.userId, - label: u.nickname || u.userName || u.name || String(u.id || '') - })) - } catch (e) { - console.error('loadOperators error', e) +// ---- 操作人自动设置为当前登录用户 ---- +function autoSetOperator() { + if (currentUserId.value && currentUserName.value) { + selectedOperator.value = { + value: currentUserId.value, + label: currentUserName.value + } } } -function toggleOperatorDropdown() { - showOperatorDropdown.value = !showOperatorDropdown.value -} - -function closeOperatorDropdown() { - showOperatorDropdown.value = false -} - -function handleSelectOperator(item, idx) { - selectedOperator.value = item - operatorIndex.value = idx - closeOperatorDropdown() -} - function goToHistory() { uni.navigateTo({ url: '/pages_function/pages/moldoperate/history?type=down' }) } @@ -578,21 +528,11 @@ async function handleConfirm() { console.log('[下模] 提交参数 =', JSON.stringify(payload)) await createMoldOperate(payload) uni.showToast({ title: t('functionCommon.createSuccess'), icon: 'success' }) - // 下模成功后清除该设备的持久化数据 - if (selectedDevice.value?.id) { - try { - const map = uni.getStorageSync('_mountedMoldInfoMap') || {} - delete map[String(selectedDevice.value.id)] - uni.setStorageSync('_mountedMoldInfoMap', map) - } catch {} - } // 重置表单 selectedDevice.value = {} selectedMold.value = {} lowerMoldOptions.value = [] remarkText.value = '' - selectedOperator.value = null - operatorIndex.value = -1 } catch (e) { console.error('[下模] 保存失败 =', e) const errMsg = e?.msg || (typeof e === 'string' ? e : e?.message) || '系统异常' @@ -608,7 +548,8 @@ function handleCancel() { } onShow(async () => { - await Promise.allSettled([loadDevices(), loadLineTree(), loadOperators()]) + autoSetOperator() + await Promise.allSettled([loadDevices(), loadLineTree()]) // 从 globalData 读取设备选择页回传的设备 const device = getApp().globalData._deviceSelectResult if (device) { @@ -621,21 +562,16 @@ onShow(async () => { diff --git a/src/pages_function/pages/sparepartInbound/index.vue b/src/pages_function/pages/sparepartInbound/index.vue new file mode 100644 index 0000000..bdc7497 --- /dev/null +++ b/src/pages_function/pages/sparepartInbound/index.vue @@ -0,0 +1,594 @@ + + + + + diff --git a/src/pages_function/pages/sparepartInbound/sparepartSelect.vue b/src/pages_function/pages/sparepartInbound/sparepartSelect.vue new file mode 100644 index 0000000..7730636 --- /dev/null +++ b/src/pages_function/pages/sparepartInbound/sparepartSelect.vue @@ -0,0 +1,295 @@ + + + + + diff --git a/src/pages_function/pages/sparepartInbound/userSelect.vue b/src/pages_function/pages/sparepartInbound/userSelect.vue new file mode 100644 index 0000000..e69de29 diff --git a/src/pages_function/pages/sparepartOutbound/create.vue b/src/pages_function/pages/sparepartOutbound/create.vue new file mode 100644 index 0000000..005d667 --- /dev/null +++ b/src/pages_function/pages/sparepartOutbound/create.vue @@ -0,0 +1,711 @@ + + + + + diff --git a/src/pages_function/pages/sparepartOutbound/index.vue b/src/pages_function/pages/sparepartOutbound/index.vue new file mode 100644 index 0000000..985b2a6 --- /dev/null +++ b/src/pages_function/pages/sparepartOutbound/index.vue @@ -0,0 +1,594 @@ + + + + + diff --git a/src/pages_mine/pages/setting/index.vue b/src/pages_mine/pages/setting/index.vue index e749f95..503daab 100644 --- a/src/pages_mine/pages/setting/index.vue +++ b/src/pages_mine/pages/setting/index.vue @@ -178,7 +178,7 @@ function dialogClose() { .server-address-text { max-width: 400rpx; - text-align: right; + // text-align: right; word-break: break-all; } diff --git a/src/utils/permissionMenu.js b/src/utils/permissionMenu.js index f61f7e5..885dbe5 100644 --- a/src/utils/permissionMenu.js +++ b/src/utils/permissionMenu.js @@ -1,3 +1,4 @@ +import { getCurrentLocale } from '@/locales' const DIRECT_ROUTE_PREFIXES = ['pages/', 'page_', 'pages_'] @@ -87,6 +88,12 @@ const MENU_ROUTE_MAP = { mold: '/pages_function/pages/mold/index', equipment: '/pages_function/pages/equipment/index', spare: '/pages_function/pages/spare/index', + sparepartInbound: '/pages_function/pages/sparepartInbound/index', + sparepartoutbound: '/pages_function/pages/sparepartOutbound/index', + '备件出库': '/pages_function/pages/sparepartOutbound/index', + sparepartinbound: '/pages_function/pages/sparepartInbound/index', + sparepartIn: '/pages_function/pages/sparepartInbound/index', + '备件入库': '/pages_function/pages/sparepartInbound/index', keypart: '/pages_function/pages/keypart/index', product: '/pages_function/pages/product/index' } @@ -185,7 +192,7 @@ export function getConfigurableNavMenus(menus) { export function buildNavMenuViewModels(menus) { return getConfigurableNavMenus(menus).map((menu, index) => { - const displayName = String(menu.name || menu.enName || '').trim() || `菜单${index + 1}` + const displayName = getLocalizedMenuName(menu, `菜单${index + 1}`) return { ...menu, displayName, @@ -305,7 +312,8 @@ export function resolveMenuUrl(menu) { return directRoute } - const keys = [menu?.component, menu?.path, menu?.enName, menu?.name] + // 优先用 menu.name(中文,最不容易冲突),再用 component/path + const keys = [menu?.name, menu?.enName, menu?.component, menu?.path] for (const key of keys) { const normalizedKey = normalizeMenuKey(key) if (normalizedKey && MENU_ROUTE_MAP[normalizedKey]) { @@ -328,13 +336,22 @@ export function getMenuSymbol(name, index) { return MENU_SYMBOLS[index % MENU_SYMBOLS.length] } +export function getLocalizedMenuName(menu, fallback = '') { + const name = String(menu?.name || '').trim() + const enName = String(menu?.enName || '').trim() + if (getCurrentLocale() === 'en-US') { + return enName || name || fallback + } + return name || enName || fallback +} + export function syncTabBarMenus(menus, options = {}) { const reportMenu = findTabMenuByPage(menus, 'pages/report') const workMenu = findTabMenuByPage(menus, 'pages/work') return [ options.homeText || '首页', - reportMenu?.name || options.reportFallback || '报表', - workMenu?.name || reportMenu?.name || options.workFallback || '管理', + getLocalizedMenuName(reportMenu, options.reportFallback || '报表'), + getLocalizedMenuName(workMenu, getLocalizedMenuName(reportMenu, options.workFallback || '管理')), options.mineText || '我的' ] }