From 940fb6ea83ce997c7907738bfb0837a7312a50ad Mon Sep 17 00:00:00 2001 From: “wangming” <“wangming@antissoft.com”> Date: Mon, 9 Mar 2026 10:51:56 +0800 Subject: [PATCH] 又改了一个版本,这泰额太纠结了,一个设计,还要看示例数据对不对。 --- 美国版/Food Labeling Management App UniApp/README.md | 2 +- 美国版/Food Labeling Management App UniApp/src/App.vue | 29 +++++++++++++++++++++-------- 美国版/Food Labeling Management App UniApp/src/components/AppIcon.vue | 7 +++++-- 美国版/Food Labeling Management App UniApp/src/components/LocationPicker.vue | 205 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management App UniApp/src/components/SideMenu.vue | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------- 美国版/Food Labeling Management App UniApp/src/components/TabBar.vue | 2 +- 美国版/Food Labeling Management App UniApp/src/locales/en.ts | 3 +++ 美国版/Food Labeling Management App UniApp/src/locales/zh.ts | 3 +++ 美国版/Food Labeling Management App UniApp/src/manifest.json | 5 +++++ 美国版/Food Labeling Management App UniApp/src/pages.json | 28 ++++++++++++++++++++++++++++ 美国版/Food Labeling Management App UniApp/src/pages/index/index.vue | 16 ++++++++++++++-- 美国版/Food Labeling Management App UniApp/src/pages/labels/bluetooth.vue | 294 +++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 美国版/Food Labeling Management App UniApp/src/pages/labels/bluetooth.vue.bak | 653 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management App UniApp/src/pages/labels/food-select.vue | 2 -- 美国版/Food Labeling Management App UniApp/src/pages/labels/labels.vue | 681 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------- 美国版/Food Labeling Management App UniApp/src/pages/labels/preview.vue | 815 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 美国版/Food Labeling Management App UniApp/src/pages/login/login.vue | 2 +- 美国版/Food Labeling Management App UniApp/src/pages/more/change-password.vue | 309 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management App UniApp/src/pages/more/label-report.vue | 390 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management App UniApp/src/pages/more/language.vue | 6 +++++- 美国版/Food Labeling Management App UniApp/src/pages/more/location.vue | 6 +++++- 美国版/Food Labeling Management App UniApp/src/pages/more/print-detail.vue | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management App UniApp/src/pages/more/print-log.vue | 253 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management App UniApp/src/pages/more/profile.vue | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------- 美国版/Food Labeling Management App UniApp/src/pages/more/support.vue | 6 +++++- 美国版/Food Labeling Management App UniApp/src/pages/more/sync.vue | 6 +++++- 美国版/Food Labeling Management App UniApp/src/static/lable1.png | Bin 0 -> 26593 bytes 美国版/Food Labeling Management App UniApp/src/static/lable2.png | Bin 0 -> 69082 bytes 美国版/Food Labeling Management App UniApp/src/uni.scss | 8 ++++---- 美国版/Food Labeling Management App UniApp/src/utils/printRecords.ts | 29 +++++++++++++++++++++++++++++ 美国版/Food Labeling Management App UniApp/src/utils/stores.ts | 22 ++++++++++++++++++++++ 美国版/Food Labeling Management App UniApp/vite.config.ts | 22 +++++++++++++++++++++- 32 files changed, 3586 insertions(+), 777 deletions(-) create mode 100644 美国版/Food Labeling Management App UniApp/src/components/LocationPicker.vue create mode 100644 美国版/Food Labeling Management App UniApp/src/pages/labels/bluetooth.vue.bak create mode 100644 美国版/Food Labeling Management App UniApp/src/pages/more/change-password.vue create mode 100644 美国版/Food Labeling Management App UniApp/src/pages/more/label-report.vue create mode 100644 美国版/Food Labeling Management App UniApp/src/pages/more/print-detail.vue create mode 100644 美国版/Food Labeling Management App UniApp/src/pages/more/print-log.vue create mode 100644 美国版/Food Labeling Management App UniApp/src/static/lable1.png create mode 100644 美国版/Food Labeling Management App UniApp/src/static/lable2.png create mode 100644 美国版/Food Labeling Management App UniApp/src/utils/printRecords.ts create mode 100644 美国版/Food Labeling Management App UniApp/src/utils/stores.ts diff --git a/美国版/Food Labeling Management App UniApp/README.md b/美国版/Food Labeling Management App UniApp/README.md index 86959d4..f48cdd9 100644 --- a/美国版/Food Labeling Management App UniApp/README.md +++ b/美国版/Food Labeling Management App UniApp/README.md @@ -52,7 +52,7 @@ npm run build:h5 ## 设计规范(与 React 版一致) -- 主色: #2563eb (Enterprise Blue) +- 主色: #1F3A8A (Enterprise Blue) - 最大宽度: 480px (约 960rpx) - 底部导航: Dashboard / Labels / More - 触控高度: ≥ 48px (96rpx) diff --git a/美国版/Food Labeling Management App UniApp/src/App.vue b/美国版/Food Labeling Management App UniApp/src/App.vue index f93e91e..d6429ce 100644 --- a/美国版/Food Labeling Management App UniApp/src/App.vue +++ b/美国版/Food Labeling Management App UniApp/src/App.vue @@ -15,17 +15,30 @@ onHide(() => { diff --git a/美国版/Food Labeling Management App UniApp/src/components/AppIcon.vue b/美国版/Food Labeling Management App UniApp/src/components/AppIcon.vue index 01a0655..4ed8f61 100644 --- a/美国版/Food Labeling Management App UniApp/src/components/AppIcon.vue +++ b/美国版/Food Labeling Management App UniApp/src/components/AppIcon.vue @@ -50,6 +50,9 @@ const icons: Record = { bluetooth: '', minus: '', eye: '', + lock: '', + chevronDown: '', + chevronUp: '', } const svgContent = computed(() => icons[props.name] || icons.food) @@ -80,9 +83,9 @@ const wrapStyle = computed(() => ({})) .icon-lg { width: 64rpx; height: 64rpx; } .icon-gray :deep(svg) { stroke: #6b7280; } -.icon-primary :deep(svg) { stroke: #2563eb; } +.icon-primary :deep(svg) { stroke: var(--theme-primary, #1F3A8A); } .icon-white :deep(svg) { stroke: #ffffff; } -.icon-blue :deep(svg) { stroke: #2563eb; } +.icon-blue :deep(svg) { stroke: var(--theme-primary, #1F3A8A); } .icon-orange :deep(svg) { stroke: #ea580c; } .icon-green :deep(svg) { stroke: #16a34a; } .icon-purple :deep(svg) { stroke: #7c3aed; } diff --git a/美国版/Food Labeling Management App UniApp/src/components/LocationPicker.vue b/美国版/Food Labeling Management App UniApp/src/components/LocationPicker.vue new file mode 100644 index 0000000..2d4fb63 --- /dev/null +++ b/美国版/Food Labeling Management App UniApp/src/components/LocationPicker.vue @@ -0,0 +1,205 @@ + + + + + diff --git a/美国版/Food Labeling Management App UniApp/src/components/SideMenu.vue b/美国版/Food Labeling Management App UniApp/src/components/SideMenu.vue index f63cb79..a2029b8 100644 --- a/美国版/Food Labeling Management App UniApp/src/components/SideMenu.vue +++ b/美国版/Food Labeling Management App UniApp/src/components/SideMenu.vue @@ -14,22 +14,56 @@ - - - + @@ -70,27 +104,43 @@ const storeName = computed(() => { return stored || 'MedVantage' }) +const expandedKey = ref(null) + const items = [ - { key: 'home', path: '/pages/index/index', icon: 'home', labelKey: 'home' }, - { key: 'labels', path: '/pages/labels/labels', icon: 'tag', labelKey: 'nav.labels' }, + { key: 'home', path: '/pages/index/index', icon: 'home', labelKey: 'Home' }, + { key: 'Labeling', path: '/pages/labels/labels', icon: 'tag', labelKey: 'Labeling' }, + { + key: 'report', + icon: 'fileText', + labelKey: 'more.report', + children: [ + { path: '/pages/more/print-log', labelKey: 'more.printLog' }, + { path: '/pages/more/label-report', labelKey: 'more.labelReport' }, + ], + }, { key: 'profile', path: '/pages/more/profile', icon: 'user', labelKey: 'more.profile' }, { key: 'location', path: '/pages/more/location', icon: 'mapPin', labelKey: 'more.location' }, { key: 'sync', path: '/pages/more/sync', icon: 'refresh', labelKey: 'more.sync' }, - { key: 'language', path: '/pages/more/language', icon: 'globe', labelKey: 'more.language' }, { key: 'support', path: '/pages/more/support', icon: 'help', labelKey: 'more.support' }, { key: 'logout', path: '__logout__', icon: 'logout', labelKey: 'more.logout', danger: true }, ] +const toggleExpand = (key: string) => { + expandedKey.value = expandedKey.value === key ? null : key +} + watch( () => props.modelValue, (val) => { if (val) { isShown.value = true + if (currentPath.value.startsWith('/pages/more/print-log') || currentPath.value.startsWith('/pages/more/label-report')) { + expandedKey.value = 'report' + } nextTick(() => { animClass.value = 'opening' }) } else if (isShown.value) { - // 先播放关闭动画,再卸载 animClass.value = 'closing' setTimeout(() => { isShown.value = false @@ -112,7 +162,7 @@ const currentPath = computed(() => { return route }) -const isActive = (path: string) => !!path && currentPath.value === path +const isActive = (path: string) => !!path && path !== '__logout__' && currentPath.value === path const handleLogout = () => { uni.removeStorageSync('isLoggedIn') @@ -152,7 +202,7 @@ const handleItemClick = (item: any) => { .drawer-panel { width: 76%; max-width: 640rpx; - background: #111827; + background: #1F3A8A; padding: 16rpx 32rpx 0; box-shadow: 4rpx 0 32rpx rgba(0, 0, 0, 0.5); display: flex; @@ -253,13 +303,35 @@ const handleItemClick = (item: any) => { } .menu-item.active { - background: var(--theme-primary); + background: #1447E6; } .menu-item.active .menu-label { color: #ffffff; } +.menu-group { + margin-bottom: 4rpx; +} + +.menu-chevron { + margin-left: auto; +} + +.menu-children { + padding-left: 76rpx; + padding-bottom: 8rpx; +} + +.menu-item.child { + padding: 12rpx 12rpx; +} + +.menu-item.child .menu-icon { + width: 0; + min-width: 0; +} + .drawer-footer { padding: 24rpx 0 48rpx; border-top: 1rpx solid rgba(148, 163, 184, 0.2); diff --git a/美国版/Food Labeling Management App UniApp/src/components/TabBar.vue b/美国版/Food Labeling Management App UniApp/src/components/TabBar.vue index 7f8733d..c3df625 100644 --- a/美国版/Food Labeling Management App UniApp/src/components/TabBar.vue +++ b/美国版/Food Labeling Management App UniApp/src/components/TabBar.vue @@ -78,7 +78,7 @@ const switchTab = (path: string) => { } .tab-label.active { - color: #2563eb; + color: var(--theme-primary, #1F3A8A); font-weight: 600; } diff --git a/美国版/Food Labeling Management App UniApp/src/locales/en.ts b/美国版/Food Labeling Management App UniApp/src/locales/en.ts index 2023edb..3b44c80 100644 --- a/美国版/Food Labeling Management App UniApp/src/locales/en.ts +++ b/美国版/Food Labeling Management App UniApp/src/locales/en.ts @@ -89,6 +89,9 @@ export default { more: { title: 'More', profile: 'My Profile', 'profile.desc': 'View and edit your profile', + report: 'Report', + printLog: 'Print Log', + labelReport: 'Label Report', printers: 'Printer Settings', 'printers.desc': 'Manage connected printers', location: 'Location', 'location.desc': 'Change your work location', sync: 'Sync Status', 'sync.desc': 'View sync status and data', diff --git a/美国版/Food Labeling Management App UniApp/src/locales/zh.ts b/美国版/Food Labeling Management App UniApp/src/locales/zh.ts index 51bdf39..208150d 100644 --- a/美国版/Food Labeling Management App UniApp/src/locales/zh.ts +++ b/美国版/Food Labeling Management App UniApp/src/locales/zh.ts @@ -89,6 +89,9 @@ export default { more: { title: '更多', profile: '我的资料', 'profile.desc': '查看和编辑您的个人资料', + report: '报表', + printLog: '打印日志', + labelReport: '标签报表', printers: '打印机设置', 'printers.desc': '管理连接的打印机', location: '工作地点', 'location.desc': '更改您的工作地点', sync: '同步状态', 'sync.desc': '查看同步状态和数据', diff --git a/美国版/Food Labeling Management App UniApp/src/manifest.json b/美国版/Food Labeling Management App UniApp/src/manifest.json index 7da2f48..e48f6be 100644 --- a/美国版/Food Labeling Management App UniApp/src/manifest.json +++ b/美国版/Food Labeling Management App UniApp/src/manifest.json @@ -73,5 +73,10 @@ "uniStatistics" : { "enable" : false }, + "h5" : { + "router" : { + "base" : "/app/" + } + }, "vueVersion" : "3" } diff --git a/美国版/Food Labeling Management App UniApp/src/pages.json b/美国版/Food Labeling Management App UniApp/src/pages.json index 7d47cd8..ef52dba 100644 --- a/美国版/Food Labeling Management App UniApp/src/pages.json +++ b/美国版/Food Labeling Management App UniApp/src/pages.json @@ -50,6 +50,27 @@ } }, { + "path": "pages/more/print-log", + "style": { + "navigationBarTitleText": "Print Log", + "navigationStyle": "custom" + } + }, + { + "path": "pages/more/label-report", + "style": { + "navigationBarTitleText": "Label Report", + "navigationStyle": "custom" + } + }, + { + "path": "pages/more/print-detail", + "style": { + "navigationBarTitleText": "Print Detail", + "navigationStyle": "custom" + } + }, + { "path": "pages/more/more", "style": { "navigationBarTitleText": "More", @@ -97,6 +118,13 @@ "navigationBarTitleText": "Support", "navigationStyle": "custom" } + }, + { + "path": "pages/more/change-password", + "style": { + "navigationBarTitleText": "Change Password", + "navigationStyle": "custom" + } } ], "globalStyle": { diff --git a/美国版/Food Labeling Management App UniApp/src/pages/index/index.vue b/美国版/Food Labeling Management App UniApp/src/pages/index/index.vue index 111b90a..842cdee 100644 --- a/美国版/Food Labeling Management App UniApp/src/pages/index/index.vue +++ b/美国版/Food Labeling Management App UniApp/src/pages/index/index.vue @@ -5,12 +5,15 @@ - {{ storeName }} + + {{ storeName }} + + @@ -40,6 +43,7 @@ import { ref, computed } from 'vue' import { useI18n } from 'vue-i18n' import AppIcon from '../../components/AppIcon.vue' import SideMenu from '../../components/SideMenu.vue' +import LocationPicker from '../../components/LocationPicker.vue' import { getStatusBarHeight } from '../../utils/statusBar' const { t } = useI18n() @@ -50,7 +54,7 @@ const isMenuOpen = ref(false) const quickActions = computed(() => [ { - label: t('nav.labels'), + label: t('Labeling'), icon: 'tag', path: '/pages/labels/labels', }, @@ -114,9 +118,17 @@ const navTo = (path: string) => { margin-bottom: 8rpx; } +.hero-info { + display: flex; + flex-direction: column; + align-items: center; + padding-top: 16rpx; +} + .app-sub { font-size: 26rpx; color: rgba(255, 255, 255, 0.9); + margin-bottom: 12rpx; } .main { diff --git a/美国版/Food Labeling Management App UniApp/src/pages/labels/bluetooth.vue b/美国版/Food Labeling Management App UniApp/src/pages/labels/bluetooth.vue index dcb2449..d018435 100644 --- a/美国版/Food Labeling Management App UniApp/src/pages/labels/bluetooth.vue +++ b/美国版/Food Labeling Management App UniApp/src/pages/labels/bluetooth.vue @@ -7,6 +7,7 @@ Bluetooth Printer + @@ -15,13 +16,6 @@ - - - - {{ errorMsg }} - - - @@ -37,45 +31,38 @@ - - Available Devices + Available Printers {{ isScanning ? 'Scanning...' : 'Scan' }} - + - Searching for nearby devices... - - - - - No Devices Found - Make sure your Bluetooth printer is turned on and in pairing mode, then tap Scan. + Searching for nearby printers... - - + + - {{ dev.name || 'Unknown Device' }} + {{ dev.name }} {{ dev.deviceId }} - Printer - Signal: {{ dev.RSSI }}dBm + Printer + Signal: {{ dev.RSSI }}dBm @@ -102,40 +89,24 @@ diff --git a/美国版/Food Labeling Management App UniApp/src/pages/labels/food-select.vue b/美国版/Food Labeling Management App UniApp/src/pages/labels/food-select.vue index 0be538c..cf1725a 100644 --- a/美国版/Food Labeling Management App UniApp/src/pages/labels/food-select.vue +++ b/美国版/Food Labeling Management App UniApp/src/pages/labels/food-select.vue @@ -75,10 +75,8 @@ const isMenuOpen = ref(false) const allFoods = [ { id: 'food-001', nameKey: 'food.chickenBreast', descKey: 'food.chickenBreast.desc', image: 'https://images.unsplash.com/photo-1532550907401-a500c9a57435?w=400', categoryKey: 'category.meat' }, { id: 'food-002', nameKey: 'food.caesarSalad', descKey: 'food.caesarSalad.desc', image: 'https://images.unsplash.com/photo-1546793665-c74683f339c1?w=400', categoryKey: 'category.salads' }, - { id: 'food-003', nameKey: 'food.salmonFillet', descKey: 'food.salmonFillet.desc', image: 'https://images.unsplash.com/photo-1519708227418-c8fd9a32b7a2?w=400', categoryKey: 'category.seafood' }, { id: 'food-004', nameKey: 'food.beefPatties', descKey: 'food.beefPatties.desc', image: 'https://images.unsplash.com/photo-1607623488235-e2e6794c30b5?w=400', categoryKey: 'category.meat' }, { id: 'food-005', nameKey: 'food.marinaraSauce', descKey: 'food.marinaraSauce.desc', image: 'https://images.unsplash.com/photo-1621996346565-e3dbc646d9a9?w=400', categoryKey: 'category.sauces' }, - { id: 'food-006', nameKey: 'food.vegetables', descKey: 'food.vegetables.desc', image: 'https://images.unsplash.com/photo-1540420773420-3366772f4999?w=400', categoryKey: 'category.vegetables' }, { id: 'food-007', nameKey: 'food.brownie', descKey: 'food.brownie.desc', image: 'https://images.unsplash.com/photo-1606313564200-e75d5e30476c?w=400', categoryKey: 'category.desserts' }, { id: 'food-008', nameKey: 'food.shrimpPasta', descKey: 'food.shrimpPasta.desc', image: 'https://images.unsplash.com/photo-1563379926898-05f4575a45d8?w=400', categoryKey: 'category.prepared' }, { id: 'food-009', nameKey: 'food.iceCream', descKey: 'food.iceCream.desc', image: 'https://images.unsplash.com/photo-1563805042-7684c019e1cb?w=400', categoryKey: 'category.frozen' }, diff --git a/美国版/Food Labeling Management App UniApp/src/pages/labels/labels.vue b/美国版/Food Labeling Management App UniApp/src/pages/labels/labels.vue index 07586af..eb97d31 100644 --- a/美国版/Food Labeling Management App UniApp/src/pages/labels/labels.vue +++ b/美国版/Food Labeling Management App UniApp/src/pages/labels/labels.vue @@ -6,7 +6,8 @@ - {{ t('labels.title') }} + Labeling + @@ -15,7 +16,7 @@ - + {{ btConnected ? btDeviceName : 'No printer connected' }} @@ -29,17 +30,17 @@ - - - + + + - {{ t(type.nameKey) }} + {{ cat.name }} @@ -52,34 +53,88 @@ - + - {{ t('labels.noFoodFound') }} + No products found - + - - + + + + + + + {{ pCat.name }} + {{ pCat.products.length }} items + + + + + + + + + + + + {{ product.templateSize }} + + + {{ product.labelTypes.length }} Types + + + {{ product.name }} + {{ product.templateName }} + + - {{ t(food.nameKey) }} - {{ t(food.descKey) }} + + + Select Label Type + {{ selectedProduct ? selectedProduct.name : '' }} + + + {{ lt.name }} + + + + + Cancel + + + + @@ -87,16 +142,19 @@ @@ -176,7 +482,8 @@ const goPreview = (foodId: string) => { justify-content: space-between; } -.top-left, .top-right { +.top-left, +.top-right { width: 64rpx; height: 64rpx; border-radius: 999rpx; @@ -188,7 +495,9 @@ const goPreview = (foodId: string) => { .top-center { flex: 1; - text-align: center; + display: flex; + flex-direction: column; + align-items: center; } .app-name { @@ -197,7 +506,6 @@ const goPreview = (foodId: string) => { color: #ffffff; } -/* Bluetooth status bar */ .bt-bar { display: flex; align-items: center; @@ -207,7 +515,6 @@ const goPreview = (foodId: string) => { margin-bottom: 16rpx; background: rgba(255, 255, 255, 0.12); border-radius: 16rpx; - cursor: pointer; } .bt-left { @@ -252,7 +559,6 @@ const goPreview = (foodId: string) => { color: rgba(255, 255, 255, 0.85); } -/* Body */ .body { flex: 1; display: flex; @@ -272,7 +578,6 @@ const goPreview = (foodId: string) => { flex-direction: column; align-items: center; padding: 20rpx 8rpx; - cursor: pointer; position: relative; } @@ -300,19 +605,31 @@ const goPreview = (foodId: string) => { margin-bottom: 8rpx; } -.cat-icon.blue { background: #eff6ff; } -.cat-icon.red { background: #fef2f2; } -.cat-icon.cyan { background: #ecfeff; } -.cat-icon.orange { background: #fff7ed; } -.cat-icon.purple { background: #faf5ff; } -.cat-icon.green { background: #f0fdf4; } +.cat-icon.green { + background: #f0fdf4; +} -.cat-item.active .cat-icon.blue, -.cat-item.active .cat-icon.red, -.cat-item.active .cat-icon.cyan, +.cat-icon.orange { + background: #fff7ed; +} + +.cat-icon.red { + background: #fef2f2; +} + +.cat-icon.blue { + background: #eff6ff; +} + +.cat-icon.cyan { + background: #ecfeff; +} + +.cat-item.active .cat-icon.green, .cat-item.active .cat-icon.orange, -.cat-item.active .cat-icon.purple, -.cat-item.active .cat-icon.green { +.cat-item.active .cat-icon.red, +.cat-item.active .cat-icon.blue, +.cat-item.active .cat-icon.cyan { background: var(--theme-primary); } @@ -374,23 +691,104 @@ const goPreview = (foodId: string) => { margin-top: 24rpx; } +.category-list { + display: flex; + flex-direction: column; + gap: 16rpx; +} + +.cat-section { + background: #fff; + border-radius: 16rpx; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); + overflow: hidden; +} + +.cat-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 24rpx; +} + +.cat-header-left { + display: flex; + align-items: center; + gap: 16rpx; + flex: 1; + min-width: 0; +} + +.cat-header-icon { + width: 56rpx; + height: 56rpx; + border-radius: 14rpx; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +.cat-header-icon.bg-red { + background: #fef2f2; +} + +.cat-header-icon.bg-blue { + background: #eff6ff; +} + +.cat-header-icon.bg-green { + background: #f0fdf4; +} + +.cat-header-icon.bg-orange { + background: #fff7ed; +} + +.cat-header-icon.bg-purple { + background: #faf5ff; +} + +.cat-header-info { + flex: 1; + min-width: 0; +} + +.cat-header-name { + font-size: 28rpx; + font-weight: 600; + color: #111827; + display: block; +} + +.cat-header-count { + font-size: 22rpx; + color: #9ca3af; + display: block; + margin-top: 2rpx; +} + +.cat-foods { + padding: 0 16rpx 16rpx; + border-top: 1rpx solid #f3f4f6; +} + .food-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); - column-gap: 16rpx; - row-gap: 16rpx; + column-gap: 12rpx; + row-gap: 12rpx; + padding-top: 16rpx; } .food-card { - background: #fff; - padding: 12rpx; - border-radius: 16rpx; - box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04); - cursor: pointer; + background: #f9fafb; + padding: 10rpx; + border-radius: 14rpx; } .food-card:active { - background: #fafafa; + background: #f3f4f6; } .food-img-wrap { @@ -398,8 +796,8 @@ const goPreview = (foodId: string) => { position: relative; padding-top: 75%; border-radius: 10rpx; - background: #f3f4f6; - margin-bottom: 12rpx; + background: #e5e7eb; + margin-bottom: 10rpx; overflow: hidden; } @@ -411,12 +809,42 @@ const goPreview = (foodId: string) => { height: 100%; } +.size-badge { + position: absolute; + left: 8rpx; + top: 8rpx; + background: rgba(0, 0, 0, 0.25); + padding: 4rpx 12rpx; + border-radius: 8rpx; +} + +.size-badge-text { + font-size: 18rpx; + color: #fff; + font-weight: 500; +} + +.type-badge { + position: absolute; + right: 8rpx; + bottom: 8rpx; + background: rgba(0, 0, 0, 0.25); + padding: 4rpx 12rpx; + border-radius: 8rpx; +} + +.type-badge-text { + font-size: 18rpx; + color: #fff; + font-weight: 500; +} + .food-name { font-size: 24rpx; font-weight: 600; color: #111827; display: block; - margin-bottom: 4rpx; + margin-bottom: 2rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -425,11 +853,94 @@ const goPreview = (foodId: string) => { .food-desc { font-size: 20rpx; color: #6b7280; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; + display: block; overflow: hidden; - line-height: 1.4; + text-overflow: ellipsis; + white-space: nowrap; +} + +.modal-mask { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba(0, 0, 0, 0.5); + z-index: 1000; + display: flex; + align-items: flex-end; + justify-content: center; +} + +.modal-body { + width: 100%; + background: #fff; + border-radius: 32rpx 32rpx 0 0; + padding: 40rpx 32rpx; + max-height: 70vh; + overflow-y: auto; +} + +.modal-title { + font-size: 36rpx; + font-weight: 700; + color: #111827; + display: block; + margin-bottom: 8rpx; +} + +.modal-desc { + font-size: 28rpx; + color: #6b7280; + display: block; + margin-bottom: 32rpx; +} + +.subtype-list { + display: flex; + flex-direction: column; + gap: 16rpx; + margin-bottom: 24rpx; +} + +.subtype-item { + display: flex; + align-items: center; + gap: 20rpx; + padding: 28rpx 24rpx; + background: #f9fafb; + border-radius: 16rpx; + border: 2rpx solid #e5e7eb; +} + +.subtype-item:active { + background: var(--theme-primary-light); + border-color: var(--theme-primary); +} + +.subtype-name { + flex: 1; + min-width: 0; + font-size: 30rpx; + font-weight: 600; + color: #111827; +} + +.modal-cancel { + width: 100%; + height: 88rpx; + background: #f3f4f6; + border-radius: 16rpx; + display: flex; + align-items: center; + justify-content: center; +} + +.modal-cancel-text { + font-size: 30rpx; + font-weight: 500; + color: #374151; + line-height: 1; } @media (min-width: 768px) { @@ -439,8 +950,8 @@ const goPreview = (foodId: string) => { .food-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); - column-gap: 20rpx; - row-gap: 20rpx; + column-gap: 16rpx; + row-gap: 16rpx; } } diff --git a/美国版/Food Labeling Management App UniApp/src/pages/labels/preview.vue b/美国版/Food Labeling Management App UniApp/src/pages/labels/preview.vue index 04e761e..157bfd5 100644 --- a/美国版/Food Labeling Management App UniApp/src/pages/labels/preview.vue +++ b/美国版/Food Labeling Management App UniApp/src/pages/labels/preview.vue @@ -6,8 +6,8 @@ - {{ t('labels.preview.title') }} - {{ t('labels.preview.subtitle') }} + Label Preview + @@ -16,20 +16,21 @@ - - - {{ food ? t(food.nameKey) : '' }} - {{ food ? t(food.categoryKey) : '' }} + {{ displayProductName }} + {{ productCategory }} + + + {{ labelTypeName }} + + + + {{ templateSize }} + {{ templateName }} - Print Quantity @@ -43,46 +44,32 @@ - - {{ t('labels.preview.labelPreview') }} + Label Preview - - - - - - {{ t(labelData.titleKey) }} - - - {{ food ? t(food.nameKey) : '' }} - - - - {{ t(field.labelKey) }} - {{ field.value }} - - - - {{ t('labels.preview.printedBy') }}: {{ userName }} - {{ t('labels.preview.printDate') }}: {{ printDate }} - + + + + + + + + Last Edited + {{ lastEdited }} + + + Location + {{ locationName }} - {{ t('labels.preview.note') }} + This is a preview of the label. Actual printed labels may vary slightly in appearance. - - + {{ printQty }} label{{ printQty > 1 ? 's' : '' }} @@ -96,47 +83,18 @@ - {{ isPrinting ? t('labels.print.printing') : t('labels.print.button') }} + {{ isPrinting ? 'Printing...' : 'Print' }} - - - - Label Preview - - + + + + - - - - - {{ t(labelData.titleKey) }} - - - {{ food ? t(food.nameKey) : '' }} - - - - {{ t(field.labelKey) }} - {{ field.value }} - - - - {{ userName }} | {{ printDate }} - - - - Actual print size: {{ printQty }} {{ printQty > 1 ? 'copies' : 'copy' }} - @@ -146,17 +104,13 @@ @@ -285,31 +226,61 @@ const handlePrint = () => { .page { min-height: 100vh; background: #f9fafb; + overflow-x: hidden; + overflow-x: clip; + width: 100%; + max-width: 100vw; + box-sizing: border-box; } -/* ---- Header ---- */ .header-hero { background: linear-gradient(135deg, var(--theme-primary), var(--theme-primary-dark)); padding: 16rpx 32rpx 24rpx; } -.top-bar { height: 96rpx; display: flex; align-items: center; justify-content: space-between; } -.top-left, .top-right { - width: 64rpx; height: 64rpx; border-radius: 999rpx; - background: rgba(255,255,255,0.15); - display: flex; align-items: center; justify-content: center; + +.top-bar { + height: 96rpx; + display: flex; + align-items: center; + justify-content: space-between; +} + +.top-left, +.top-right { + width: 64rpx; + height: 64rpx; + border-radius: 999rpx; + background: rgba(255, 255, 255, 0.15); + display: flex; + align-items: center; + justify-content: center; +} + +.top-center { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; +} + +.page-title { + font-size: 34rpx; + font-weight: 600; + color: #fff; + display: block; } -.top-center { flex: 1; text-align: center; } -.page-title { font-size: 34rpx; font-weight: 600; color: #fff; display: block; } -.page-sub { font-size: 24rpx; color: rgba(255,255,255,0.85); } -/* ---- Content ---- */ .content { padding: 32rpx; padding-bottom: 300rpx; box-sizing: border-box; + overflow-x: hidden; + overflow-x: clip; + width: 100%; + max-width: 100%; + min-width: 0; } -/* Food card */ .food-card { background: #fff; padding: 28rpx; @@ -317,204 +288,428 @@ const handlePrint = () => { margin-bottom: 24rpx; display: flex; align-items: center; + justify-content: space-between; gap: 24rpx; - box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04); + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); } -.food-img { - width: 120rpx; height: 120rpx; - border-radius: 16rpx; background: #f3f4f6; flex-shrink: 0; + +.food-info { + flex: 1; + min-width: 0; } -.food-info { flex: 1; min-width: 0; } + .food-name { - font-size: 32rpx; font-weight: 600; color: #111827; - display: block; margin-bottom: 4rpx; - overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + font-size: 32rpx; + font-weight: 600; + color: #111827; + display: block; + margin-bottom: 4rpx; +} + +.food-cat { + font-size: 26rpx; + color: #6b7280; + display: block; +} + +.food-label-type { + display: flex; + align-items: center; + gap: 8rpx; + margin-top: 12rpx; +} + +.food-label-type-text { + font-size: 24rpx; + color: var(--theme-primary); + font-weight: 500; +} + +.food-template { + flex-shrink: 0; + text-align: center; + background: #f3f4f6; + padding: 16rpx 20rpx; + border-radius: 14rpx; +} + +.template-size { + font-size: 28rpx; + font-weight: 700; + color: #111827; + display: block; +} + +.template-name { + font-size: 22rpx; + color: #6b7280; + display: block; + margin-top: 4rpx; } -.food-cat { font-size: 26rpx; color: #6b7280; } -/* Quantity card */ .qty-card { - display: flex; align-items: center; justify-content: space-between; - background: #fff; padding: 24rpx 28rpx; border-radius: 20rpx; - margin-bottom: 32rpx; box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04); + display: flex; + align-items: center; + justify-content: space-between; + background: #fff; + padding: 24rpx 28rpx; + border-radius: 20rpx; + margin-bottom: 32rpx; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); +} + +.qty-label { + font-size: 30rpx; + font-weight: 600; + color: #111827; +} + +.qty-control { + display: flex; + align-items: center; } -.qty-label { font-size: 30rpx; font-weight: 600; color: #111827; } -.qty-control { display: flex; align-items: center; } + .qty-btn { - width: 64rpx; height: 64rpx; border-radius: 14rpx; background: #f3f4f6; - display: flex; align-items: center; justify-content: center; - cursor: pointer; transition: background 0.15s; + width: 64rpx; + height: 64rpx; + border-radius: 14rpx; + background: #f3f4f6; + display: flex; + align-items: center; + justify-content: center; +} + +.qty-btn:active { + background: #e5e7eb; +} + +.qty-btn.disabled { + opacity: 0.35; } -.qty-btn:active { background: #e5e7eb; } -.qty-btn.disabled { opacity: 0.35; } + .qty-value { - width: 88rpx; text-align: center; - font-size: 36rpx; font-weight: 700; color: #111827; + width: 88rpx; + text-align: center; + font-size: 36rpx; + font-weight: 700; + color: #111827; } -/* Section title */ .section-title { - font-size: 30rpx; font-weight: 600; color: #111827; - display: block; margin-bottom: 20rpx; + font-size: 30rpx; + font-weight: 600; + color: #111827; + display: block; + margin-bottom: 20rpx; } -/* Label card */ +/* 使用 block 布局避免移动端 Safari flex+图片溢出问题 */ .label-card { - background: #fff; border-radius: 20rpx; overflow: hidden; - margin-bottom: 24rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); - box-sizing: border-box; width: 100%; -} -.label-border { border: 6rpx solid #1f2937; } -.label-header { - background: #1f2937; color: #fff; - padding: 28rpx; text-align: center; + background: #fff; + border-radius: 20rpx; + overflow: hidden; + overflow-x: clip; + margin-bottom: 24rpx; + box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06); + padding: 24rpx 0; + display: block; + width: 100%; + max-width: 100%; + position: relative; + contain: layout; +} + +.label-img-wrap { + width: 100%; + max-width: 100%; + overflow: hidden; + overflow-x: clip; + box-sizing: border-box; + position: relative; +} + +/* 移动端:width:auto + max-width:100% 比 width:100% 更可靠 */ +.label-img { + width: 100%; + max-width: 100%; + height: auto; + display: block; + vertical-align: top; + object-fit: contain; + border-radius: 12rpx; + box-sizing: border-box; } -.label-type-icon-wrap { display: flex; justify-content: center; margin-bottom: 12rpx; } -.label-title { font-size: 36rpx; font-weight: 700; } -.label-food-name { - border-bottom: 6rpx solid #1f2937; - background: #f9fafb; padding: 24rpx; -} -.label-food-name text { - font-size: 40rpx; font-weight: 700; - text-align: center; display: block; - word-break: break-word; +.info-row { + display: flex; + gap: 16rpx; + margin-bottom: 24rpx; } -.label-fields { padding: 32rpx; } -.field-row { - display: flex; justify-content: space-between; align-items: center; - padding: 16rpx 0; border-bottom: 1rpx solid #e5e7eb; -} -.field-row-last { - border-bottom: none; +.info-item { + flex: 1; + background: #fff; + padding: 20rpx 24rpx; + border-radius: 16rpx; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); } -.field-row.indent { padding-left: 24rpx; } -.field-label { font-size: 26rpx; color: #4b5563; flex-shrink: 0; margin-right: 16rpx; } -.field-value { font-size: 26rpx; color: #111827; text-align: right; word-break: break-word; } -.field-label.bold, .field-value.bold { font-weight: 700; } -.field-label.warning, .field-value.warning { color: #dc2626; } -.label-footer { - border-top: 6rpx solid #1f2937; - background: #f9fafb; padding: 20rpx 28rpx; text-align: center; +.info-label { + font-size: 22rpx; + color: #9ca3af; + display: block; + margin-bottom: 6rpx; } -.label-footer text { - display: block; font-size: 24rpx; color: #6b7280; line-height: 1.6; + +.info-value { + font-size: 26rpx; + font-weight: 600; + color: #111827; + display: block; } -/* Note */ .note-card { - display: flex; align-items: flex-start; gap: 16rpx; - padding: 24rpx 28rpx; background: #eff6ff; - border: 1rpx solid #bfdbfe; border-radius: 16rpx; + display: flex; + align-items: flex-start; + gap: 16rpx; + padding: 24rpx 28rpx; + background: #eff6ff; + border: 1rpx solid #bfdbfe; + border-radius: 16rpx; +} + +.note-text { + flex: 1; + font-size: 26rpx; + color: #1e40af; + line-height: 1.5; } -.note-text { flex: 1; font-size: 26rpx; color: #1e40af; line-height: 1.5; } -/* ---- Bottom bar ---- */ .bottom-bar { - position: fixed; bottom: 0; left: 0; right: 0; - padding: 20rpx 32rpx; padding-bottom: 48rpx; - background: #fff; border-top: 1rpx solid #e5e7eb; - box-shadow: 0 -4rpx 16rpx rgba(0,0,0,0.04); + position: fixed; + bottom: 0; + left: 0; + right: 0; + padding: 20rpx 32rpx; + /* 兼容浏览器:env(safe-area-inset-bottom) + 最小 36px,避免打印按钮偏上/遮挡 */ + padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 36px); + background: #fff; + border-top: 1rpx solid #e5e7eb; + box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.04); } + .bottom-info { - display: flex; justify-content: space-between; align-items: center; + display: flex; + justify-content: space-between; + align-items: center; margin-bottom: 16rpx; } -.bottom-qty { font-size: 26rpx; font-weight: 600; color: #111827; } + +.bottom-qty { + font-size: 26rpx; + font-weight: 600; + color: #111827; +} + .bt-indicator { - display: flex; align-items: center; gap: 8rpx; + display: flex; + align-items: center; + gap: 8rpx; } + .bt-dot { - width: 12rpx; height: 12rpx; border-radius: 50%; + width: 12rpx; + height: 12rpx; + border-radius: 50%; background: #d1d5db; } -.bt-indicator.connected .bt-dot { background: #4ade80; } -.bt-name { font-size: 24rpx; color: #9ca3af; } -.bt-indicator.connected .bt-name { color: #16a34a; } + +.bt-indicator.connected .bt-dot { + background: #4ade80; +} + +.bt-name { + font-size: 24rpx; + color: #9ca3af; +} + +.bt-indicator.connected .bt-name { + color: #16a34a; +} .bottom-actions { - display: flex; align-items: stretch; gap: 24rpx; + display: flex; + align-items: stretch; + gap: 24rpx; } .btn-preview-sq { - width: 100rpx; height: 100rpx; flex-shrink: 0; - background: #fff; border: 2rpx solid #d1d5db; border-radius: 16rpx; - display: flex; align-items: center; justify-content: center; - cursor: pointer; transition: background 0.15s; + width: 100rpx; + height: 100rpx; + flex-shrink: 0; + background: #fff; + border: 2rpx solid #d1d5db; + border-radius: 16rpx; + display: flex; + align-items: center; + justify-content: center; +} + +.btn-preview-sq:active { + background: #f3f4f6; } -.btn-preview-sq:active { background: #f3f4f6; } .print-btn { - flex: 1; min-width: 0; height: 100rpx; - background: var(--theme-primary); border-radius: 16rpx; - display: flex; align-items: center; justify-content: center; gap: 12rpx; - cursor: pointer; transition: opacity 0.15s; + flex: 1; + min-width: 0; + height: 100rpx; + background: var(--theme-primary); + border-radius: 16rpx; + display: flex; + align-items: center; + justify-content: center; + gap: 12rpx; +} + +.print-btn.disabled { + opacity: 0.6; } -.print-btn.disabled { opacity: 0.6; } + .print-btn-text { - font-size: 30rpx; font-weight: 600; color: #fff; line-height: 1; + font-size: 30rpx; + font-weight: 600; + color: #fff; + line-height: 1; } -/* ---- Modal ---- */ .modal-mask { - position: fixed; top: 0; left: 0; right: 0; bottom: 0; - background: rgba(0,0,0,0.5); - display: flex; align-items: center; justify-content: center; - z-index: 999; padding: 48rpx; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 999; + padding: 24rpx; } + .modal-body { - width: 100%; max-width: 640rpx; max-height: 80vh; - background: #fff; border-radius: 24rpx; overflow: hidden; - display: flex; flex-direction: column; + width: 100%; + max-width: 700rpx; + max-height: 85vh; + background: #fff; + border-radius: 24rpx; + overflow-x: hidden; + overflow-y: hidden; + display: flex; + flex-direction: column; + min-width: 0; } + +.modal-body-label-only .modal-label-wrap { + margin-bottom: 0; + padding: 24rpx; +} + .modal-top { - display: flex; justify-content: space-between; align-items: center; - padding: 28rpx 32rpx; border-bottom: 1rpx solid #e5e7eb; flex-shrink: 0; + display: flex; + justify-content: space-between; + align-items: center; + padding: 28rpx 32rpx; + border-bottom: 1rpx solid #e5e7eb; + flex-shrink: 0; } -.modal-title { font-size: 30rpx; font-weight: 600; color: #111827; } + +.modal-title { + font-size: 30rpx; + font-weight: 600; + color: #111827; +} + .modal-close { - width: 52rpx; height: 52rpx; - display: flex; align-items: center; justify-content: center; - border-radius: 50%; background: #f3f4f6; cursor: pointer; + width: 52rpx; + height: 52rpx; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + background: #f3f4f6; transform: rotate(45deg); } -.modal-scroll { flex: 1; padding: 28rpx; overflow-y: auto; } - -.pv-card { border-radius: 12rpx; overflow: hidden; margin-bottom: 20rpx; } -.pv-border { border: 4rpx solid #1f2937; } -.pv-header { - background: #1f2937; color: #fff; - padding: 16rpx; text-align: center; -} -.pv-type { font-size: 26rpx; font-weight: 700; } -.pv-food { - padding: 14rpx 16rpx; border-bottom: 4rpx solid #1f2937; - background: #f9fafb; text-align: center; -} -.pv-food text { font-size: 30rpx; font-weight: 700; } -.pv-fields { padding: 16rpx; } -.pv-row { - display: flex; justify-content: space-between; - padding: 8rpx 0; border-bottom: 1rpx solid #e5e7eb; -} -.pv-row-last { - border-bottom: none; -} -.pv-label { font-size: 22rpx; color: #4b5563; } -.pv-value { font-size: 22rpx; color: #111827; } -.pv-value.bold { font-weight: 700; } -.pv-value.warning { color: #dc2626; } -.pv-footer { - border-top: 4rpx solid #1f2937; - padding: 10rpx; text-align: center; background: #f9fafb; -} -.pv-footer text { font-size: 20rpx; color: #6b7280; } -.pv-note { - font-size: 24rpx; color: #6b7280; - text-align: center; display: block; +.modal-scroll { + flex: 1; + min-width: 0; + padding: 28rpx 40rpx; + overflow-y: auto; + overflow-x: hidden; + overflow-x: clip; + box-sizing: border-box; +} + +.modal-label-wrap { + width: 100%; + max-width: 100%; + margin-bottom: 24rpx; + padding: 0; + box-sizing: border-box; + overflow: hidden; + overflow-x: clip; +} + +.modal-label-inner { + width: 100%; + max-width: 100%; + min-width: 0; + overflow: hidden; + overflow-x: clip; + box-sizing: border-box; +} + +.modal-label-img { + width: 100%; + max-width: 100%; + height: auto; + display: block; + vertical-align: top; + object-fit: contain; + border-radius: 12rpx; + box-sizing: border-box; +} + +.modal-info { + text-align: center; +} + +.modal-info-text { + font-size: 30rpx; + font-weight: 600; + color: #111827; + display: block; + margin-bottom: 8rpx; +} + +.modal-info-sub { + font-size: 24rpx; + color: #6b7280; + display: block; + margin-bottom: 4rpx; +} + +/* 移动端额外约束,防止部分浏览器仍出现溢出 */ +@media screen and (max-width: 768px) { + .page, + .content, + .label-card, + .label-img-wrap { + max-width: 100vw; + } + .label-img, + .modal-label-img { + max-width: 100% !important; + } } diff --git a/美国版/Food Labeling Management App UniApp/src/pages/login/login.vue b/美国版/Food Labeling Management App UniApp/src/pages/login/login.vue index 825557c..6b3459c 100644 --- a/美国版/Food Labeling Management App UniApp/src/pages/login/login.vue +++ b/美国版/Food Labeling Management App UniApp/src/pages/login/login.vue @@ -31,7 +31,7 @@ - + {{ t('login.rememberMe') }} {{ t('login.forgotPassword') }} diff --git a/美国版/Food Labeling Management App UniApp/src/pages/more/change-password.vue b/美国版/Food Labeling Management App UniApp/src/pages/more/change-password.vue new file mode 100644 index 0000000..dc65138 --- /dev/null +++ b/美国版/Food Labeling Management App UniApp/src/pages/more/change-password.vue @@ -0,0 +1,309 @@ + + + + + diff --git a/美国版/Food Labeling Management App UniApp/src/pages/more/label-report.vue b/美国版/Food Labeling Management App UniApp/src/pages/more/label-report.vue new file mode 100644 index 0000000..f813db1 --- /dev/null +++ b/美国版/Food Labeling Management App UniApp/src/pages/more/label-report.vue @@ -0,0 +1,390 @@ + + + + + diff --git a/美国版/Food Labeling Management App UniApp/src/pages/more/language.vue b/美国版/Food Labeling Management App UniApp/src/pages/more/language.vue index ddb3fca..65958c1 100644 --- a/美国版/Food Labeling Management App UniApp/src/pages/more/language.vue +++ b/美国版/Food Labeling Management App UniApp/src/pages/more/language.vue @@ -7,6 +7,7 @@ {{ t('language.title') }} + @@ -44,6 +45,7 @@ import { useI18n } from 'vue-i18n' import { setLocale } from '../../utils/i18n' import AppIcon from '../../components/AppIcon.vue' import SideMenu from '../../components/SideMenu.vue' +import LocationPicker from '../../components/LocationPicker.vue' import { getStatusBarHeight } from '../../utils/statusBar' const { t, locale } = useI18n() @@ -100,7 +102,9 @@ const handleChange = (code: 'en' | 'zh') => { .top-center { flex: 1; - text-align: center; + display: flex; + flex-direction: column; + align-items: center; } .page-title { diff --git a/美国版/Food Labeling Management App UniApp/src/pages/more/location.vue b/美国版/Food Labeling Management App UniApp/src/pages/more/location.vue index b279938..6b7bedb 100644 --- a/美国版/Food Labeling Management App UniApp/src/pages/more/location.vue +++ b/美国版/Food Labeling Management App UniApp/src/pages/more/location.vue @@ -7,6 +7,7 @@ {{ t('location.title') }} + @@ -131,6 +132,7 @@ import { ref, computed } from 'vue' import { useI18n } from 'vue-i18n' import AppIcon from '../../components/AppIcon.vue' import SideMenu from '../../components/SideMenu.vue' +import LocationPicker from '../../components/LocationPicker.vue' import { getStatusBarHeight } from '../../utils/statusBar' const { t } = useI18n() @@ -200,7 +202,9 @@ const handleSwitch = () => { .top-center { flex: 1; - text-align: center; + display: flex; + flex-direction: column; + align-items: center; } .page-title { diff --git a/美国版/Food Labeling Management App UniApp/src/pages/more/print-detail.vue b/美国版/Food Labeling Management App UniApp/src/pages/more/print-detail.vue new file mode 100644 index 0000000..7e0c0dd --- /dev/null +++ b/美国版/Food Labeling Management App UniApp/src/pages/more/print-detail.vue @@ -0,0 +1,238 @@ + + + + + diff --git a/美国版/Food Labeling Management App UniApp/src/pages/more/print-log.vue b/美国版/Food Labeling Management App UniApp/src/pages/more/print-log.vue new file mode 100644 index 0000000..11cf059 --- /dev/null +++ b/美国版/Food Labeling Management App UniApp/src/pages/more/print-log.vue @@ -0,0 +1,253 @@ + + + + + diff --git a/美国版/Food Labeling Management App UniApp/src/pages/more/profile.vue b/美国版/Food Labeling Management App UniApp/src/pages/more/profile.vue index 8b65a53..9361ace 100644 --- a/美国版/Food Labeling Management App UniApp/src/pages/more/profile.vue +++ b/美国版/Food Labeling Management App UniApp/src/pages/more/profile.vue @@ -7,6 +7,7 @@ {{ t('profile.title') }} + @@ -17,35 +18,56 @@ + {{ name }} + Employee - - - {{ t('profile.name') }} - + + + + + + + + {{ t('profile.name') }} + {{ name }} + - - {{ t('profile.email') }} - + + + + + + + {{ t('profile.email') }} + {{ email }} + - - {{ t('profile.phone') }} - + + + + + + + {{ t('profile.phone') }} + {{ phone }} + - - {{ t('profile.employeeId') }} - + + + + + + + {{ t('profile.employeeId') }} + {{ employeeId }} + - - - {{ t('common.cancel') }} - - - {{ t('profile.saveChanges') }} - - - - {{ t('profile.editProfile') }} + + + + Change Password + @@ -58,11 +80,11 @@ import { ref } from 'vue' import { useI18n } from 'vue-i18n' import AppIcon from '../../components/AppIcon.vue' import SideMenu from '../../components/SideMenu.vue' +import LocationPicker from '../../components/LocationPicker.vue' import { getStatusBarHeight } from '../../utils/statusBar' const { t } = useI18n() const statusBarHeight = getStatusBarHeight() -const isEditing = ref(false) const isMenuOpen = ref(false) const name = ref(uni.getStorageSync('userName') || 'John Smith') const email = ref('john.smith@company.com') @@ -78,10 +100,8 @@ const goBack = () => { } } -const handleSave = () => { - uni.setStorageSync('userName', name.value) - isEditing.value = false - uni.showToast({ title: 'Profile updated successfully!', icon: 'success' }) +const goChangePassword = () => { + uni.navigateTo({ url: '/pages/more/change-password' }) } @@ -116,7 +136,9 @@ const handleSave = () => { .top-center { flex: 1; - text-align: center; + display: flex; + flex-direction: column; + align-items: center; } .page-title { @@ -131,93 +153,114 @@ const handleSave = () => { .avatar-wrap { display: flex; - justify-content: center; - margin-bottom: 48rpx; + flex-direction: column; + align-items: center; + margin-bottom: 40rpx; } .avatar { - width: 160rpx; - height: 160rpx; + width: 140rpx; + height: 140rpx; background: var(--theme-primary); border-radius: 50%; display: flex; align-items: center; justify-content: center; + margin-bottom: 16rpx; } -.form-card { - background: #fff; - padding: 48rpx; - border-radius: 20rpx; - margin-bottom: 48rpx; - box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); -} - -.form-group { - margin-bottom: 32rpx; -} - -.label { - font-size: 30rpx; - font-weight: 500; - color: #374151; +.avatar-name { + font-size: 36rpx; + font-weight: 700; + color: #111827; display: block; - margin-bottom: 16rpx; + margin-bottom: 4rpx; } -.input { - height: 96rpx; - padding: 0 24rpx; - background: #f3f4f6; - border-radius: 16rpx; - font-size: 32rpx; +.avatar-role { + font-size: 26rpx; + color: #6b7280; } -.input.disabled { - background: #f9fafb; - color: #9ca3af; +.info-card { + background: #fff; + padding: 12rpx 32rpx; + border-radius: 20rpx; + margin-bottom: 32rpx; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); } -.actions { +.info-row { display: flex; + align-items: center; gap: 24rpx; + padding: 28rpx 0; } -.btn-outline { - flex: 1; - height: 96rpx; +.info-divider { + height: 1rpx; background: #f3f4f6; +} + +.info-icon-box { + width: 72rpx; + height: 72rpx; border-radius: 16rpx; display: flex; align-items: center; justify-content: center; + flex-shrink: 0; } -.btn-outline-text { - font-size: 32rpx; - font-weight: 600; - color: #374151; - line-height: 1; +.info-icon-box.blue { + background: #eff6ff; } -.btn-primary { +.info-icon-box.green { + background: #f0fdf4; +} + +.info-icon-box.orange { + background: #fff7ed; +} + +.info-icon-box.purple { + background: #faf5ff; +} + +.info-detail { flex: 1; - height: 96rpx; - background: var(--theme-primary); - border-radius: 16rpx; - display: flex; - align-items: center; - justify-content: center; + min-width: 0; } -.btn-primary.full { - width: 100%; +.info-label { + font-size: 24rpx; + color: #9ca3af; + display: block; + margin-bottom: 4rpx; +} + +.info-value { + font-size: 30rpx; + font-weight: 500; + color: #111827; + display: block; +} + +.btn-password { + background: #fff; + padding: 32rpx; + border-radius: 20rpx; + display: flex; + align-items: center; + gap: 20rpx; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); } -.btn-primary-text { - font-size: 32rpx; +.btn-password-text { + flex: 1; + font-size: 30rpx; font-weight: 600; - color: #fff; - line-height: 1; + color: #111827; } diff --git a/美国版/Food Labeling Management App UniApp/src/pages/more/support.vue b/美国版/Food Labeling Management App UniApp/src/pages/more/support.vue index 0739a6d..cf9f954 100644 --- a/美国版/Food Labeling Management App UniApp/src/pages/more/support.vue +++ b/美国版/Food Labeling Management App UniApp/src/pages/more/support.vue @@ -7,6 +7,7 @@ {{ t('support.title') }} + @@ -120,6 +121,7 @@ import { ref } from 'vue' import { useI18n } from 'vue-i18n' import AppIcon from '../../components/AppIcon.vue' import SideMenu from '../../components/SideMenu.vue' +import LocationPicker from '../../components/LocationPicker.vue' import { getStatusBarHeight } from '../../utils/statusBar' const { t } = useI18n() @@ -175,7 +177,9 @@ const callEmergency = () => { .top-center { flex: 1; - text-align: center; + display: flex; + flex-direction: column; + align-items: center; } .page-title { diff --git a/美国版/Food Labeling Management App UniApp/src/pages/more/sync.vue b/美国版/Food Labeling Management App UniApp/src/pages/more/sync.vue index ec54138..98bc0ec 100644 --- a/美国版/Food Labeling Management App UniApp/src/pages/more/sync.vue +++ b/美国版/Food Labeling Management App UniApp/src/pages/more/sync.vue @@ -7,6 +7,7 @@ {{ t('sync.title') }} + @@ -71,6 +72,7 @@ import { ref } from 'vue' import { useI18n } from 'vue-i18n' import AppIcon from '../../components/AppIcon.vue' import SideMenu from '../../components/SideMenu.vue' +import LocationPicker from '../../components/LocationPicker.vue' import { getStatusBarHeight } from '../../utils/statusBar' const { t } = useI18n() @@ -130,7 +132,9 @@ const handleSync = () => { .top-center { flex: 1; - text-align: center; + display: flex; + flex-direction: column; + align-items: center; } .page-title { diff --git a/美国版/Food Labeling Management App UniApp/src/static/lable1.png b/美国版/Food Labeling Management App UniApp/src/static/lable1.png new file mode 100644 index 0000000..2651381 Binary files /dev/null and b/美国版/Food Labeling Management App UniApp/src/static/lable1.png differ diff --git a/美国版/Food Labeling Management App UniApp/src/static/lable2.png b/美国版/Food Labeling Management App UniApp/src/static/lable2.png new file mode 100644 index 0000000..d3456e8 Binary files /dev/null and b/美国版/Food Labeling Management App UniApp/src/static/lable2.png differ diff --git a/美国版/Food Labeling Management App UniApp/src/uni.scss b/美国版/Food Labeling Management App UniApp/src/uni.scss index 6ee7417..767a0a2 100644 --- a/美国版/Food Labeling Management App UniApp/src/uni.scss +++ b/美国版/Food Labeling Management App UniApp/src/uni.scss @@ -15,7 +15,7 @@ /* 颜色变量 */ /* 行为相关颜色 */ -$uni-color-primary: #2563eb; /* 欧美简洁风格主色 */ +$uni-color-primary: #1F3A8A; /* 欧美简洁风格主色 */ $uni-color-success: #4cd964; $uni-color-warning: #f0ad4e; $uni-color-error: #dd524d; @@ -38,9 +38,9 @@ $uni-border-color: #c8c7cc; $uni-border-color-light: #e5e7eb; /* 主题色 —— 修改此处可全局换色(SCSS 编译时使用) */ -$theme-primary: #4278bd; -$theme-primary-dark: #2a288f; -$theme-primary-light: #eef4fb; +$theme-primary: #1F3A8A; +$theme-primary-dark: #142a6c; +$theme-primary-light: #e8ecf5; /* 欧美版:卡片/区块 */ $app-card-radius: 20rpx; diff --git a/美国版/Food Labeling Management App UniApp/src/utils/printRecords.ts b/美国版/Food Labeling Management App UniApp/src/utils/printRecords.ts new file mode 100644 index 0000000..24d7972 --- /dev/null +++ b/美国版/Food Labeling Management App UniApp/src/utils/printRecords.ts @@ -0,0 +1,29 @@ +export interface PrintRecord { + id: string + productName: string + category: string + qty: number + userName: string + date: string + dateFull: string + time: string + labelType?: string + templateSize: string + templateName: string + printer: string +} + +export const printRecordsList: PrintRecord[] = [ + { id: '1', productName: 'Chicken Sandwich', category: 'Sandwich', qty: 2, userName: 'John Smith', date: '12/04', dateFull: 'Dec 4, 2025', time: '10:45 AM', templateSize: '2"x6"', templateName: "G'n'G", printer: 'Zebra ZD421' }, + { id: '2', productName: 'Chicken', category: 'Meat', qty: 1, userName: 'John Smith', date: '12/04', dateFull: 'Dec 4, 2025', time: '10:32 AM', labelType: 'Defrost', templateSize: '2"x2"', templateName: 'Basic', printer: 'Zebra ZD421' }, + { id: '3', productName: 'Caesar Salad', category: 'Salads', qty: 3, userName: 'Jane Doe', date: '12/04', dateFull: 'Dec 4, 2025', time: '09:15 AM', templateSize: '2"x4"', templateName: "G'n'G", printer: 'Brother QL-820NWB' }, + { id: '4', productName: 'Beef', category: 'Meat', qty: 1, userName: 'John Smith', date: '12/03', dateFull: 'Dec 3, 2025', time: '4:20 PM', labelType: 'Heated', templateSize: '2"x2"', templateName: 'Basic', printer: 'Zebra ZD421' }, + { id: '5', productName: 'Cheese Burger', category: 'Sandwich', qty: 2, userName: 'Jane Doe', date: '12/03', dateFull: 'Dec 3, 2025', time: '3:45 PM', templateSize: '2"x6"', templateName: "G'n'G", printer: 'Brother QL-820NWB' }, + { id: '6', productName: 'Ice Cream', category: 'Frozen', qty: 1, userName: 'John Smith', date: '12/03', dateFull: 'Dec 3, 2025', time: '2:30 PM', labelType: 'Vanilla', templateSize: '2"x2"', templateName: 'Storage', printer: 'Epson TM-T88VI' }, + { id: '7', productName: 'Milk', category: 'Dairy', qty: 1, userName: 'Jane Doe', date: '12/03', dateFull: 'Dec 3, 2025', time: '11:00 AM', templateSize: '2"x2"', templateName: 'Basic', printer: 'Zebra ZD421' }, + { id: '8', productName: 'Turkey Club', category: 'Sandwich', qty: 1, userName: 'John Smith', date: '12/02', dateFull: 'Dec 2, 2025', time: '1:20 PM', templateSize: '2"x6"', templateName: "G'n'G", printer: 'Brother QL-820NWB' }, +] + +export function getRecordById(id: string): PrintRecord | undefined { + return printRecordsList.find(function (r) { return r.id === id }) +} diff --git a/美国版/Food Labeling Management App UniApp/src/utils/stores.ts b/美国版/Food Labeling Management App UniApp/src/utils/stores.ts new file mode 100644 index 0000000..3cc4907 --- /dev/null +++ b/美国版/Food Labeling Management App UniApp/src/utils/stores.ts @@ -0,0 +1,22 @@ +export interface StoreInfo { + id: string + nameKey: string + address: string + city: string +} + +export const storeList: StoreInfo[] = [ + { id: '1', nameKey: 'login.store1', address: '123 Main St', city: 'New York, NY 10001' }, + { id: '2', nameKey: 'login.store2', address: '456 Oak Ave', city: 'Brooklyn, NY 11201' }, + { id: '3', nameKey: 'login.store3', address: '789 Pine Rd', city: 'Queens, NY 11354' }, + { id: '4', nameKey: 'login.store4', address: '321 Elm St', city: 'Manhattan, NY 10002' }, +] + +export function getCurrentStoreId(): string { + return uni.getStorageSync('storeId') || '1' +} + +export function switchStore(id: string, storeName: string) { + uni.setStorageSync('storeId', id) + uni.setStorageSync('storeName', storeName) +} diff --git a/美国版/Food Labeling Management App UniApp/vite.config.ts b/美国版/Food Labeling Management App UniApp/vite.config.ts index 46e36fe..42ebd3d 100644 --- a/美国版/Food Labeling Management App UniApp/vite.config.ts +++ b/美国版/Food Labeling Management App UniApp/vite.config.ts @@ -3,5 +3,25 @@ import uni from "@dcloudio/vite-plugin-uni"; // https://vitejs.dev/config/ export default defineConfig({ - plugins: [uni()], + base: "/app/", + plugins: [ + uni(), + { + name: "redirect-root-to-app", + configureServer(server) { + server.middlewares.use((req, res, next) => { + const url = (req.url || "/").split("?")[0]; + if (url === "/" || url === "/index.html") { + res.writeHead(302, { Location: "/app/" }); + res.end(); + return; + } + next(); + }); + }, + }, + ], + server: { + open: "/app/", + }, }); -- libgit2 0.21.4