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 @@
+
+
+
+ LOC-{{ currentId }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t(s.nameKey) }}
+ {{ s.address }}, {{ s.city }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
@@ -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 }}
-
-
-
-
-
+
- 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
-
+ Printer
+
@@ -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('labels.noFoodFound') }}
+ No products found
-
+
-
-
+
+
+
+
+
+
+
+
+ {{ 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
-
-
-
- {{ food ? t(food.nameKey) : '' }}
-
-
-
- {{ t(field.labelKey) }}
- {{ field.value }}
-
-
-
+
+
+
+
+
+
+
+ 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
-
-
+
+
+
+
-
-
-
-
-
- {{ food ? t(food.nameKey) : '' }}
-
-
-
- {{ t(field.labelKey) }}
- {{ field.value }}
-
-
-
-
-
- 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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Current Password
+
+
+
+
+
+
+
+
+
+ New Password
+
+
+
+
+
+
+
+
+
+ Confirm New Password
+
+
+
+
+
+
+
+
+
+
+ Password Requirements
+ At least 8 characters long
+ Contains uppercase and lowercase letters
+ Contains at least one number
+ Contains at least one special character
+
+
+
+ Update Password
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+
+ Total Labels Printed
+ 2,543
+ +20.1% from last month
+
+
+ Most Printed Category
+ Dairy
+ 450 labels generated
+
+
+ Top Product
+ Whole Milk
+ 182 labels generated
+
+
+ Avg. Daily Prints
+ 85
+ +12% from last week
+
+
+
+
+
+ Labels by Category
+ Distribution of printed labels across product categories.
+
+
+ {{ item.name }}
+
+
+
+ {{ item.value }}
+
+
+
+
+
+
+ Print Volume Trends
+ Daily label printing volume for the last 7 days.
+
+
+
+
+
+
+
+ {{ d }}
+
+
+
+
+
+
+ Most Used Products
+
+
+
+ {{ p.name }}
+ {{ p.category }}
+ {{ p.total }}
+ {{ p.usage }}%
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+
+ Label Content
+
+
+
+
+
+
+ Print Info
+
+
+ Print Time
+ {{ record.dateFull }} {{ record.time }}
+
+
+ Product
+ {{ displayProductName }}
+
+
+ Quantity
+ {{ record.qty }} label{{ record.qty > 1 ? 's' : '' }}
+
+
+ Label Type
+ {{ record.labelType }}
+
+
+ Template
+ {{ record.templateSize }} {{ record.templateName }}
+
+
+ Printed By
+ {{ record.userName }}
+
+
+ Printer
+ {{ record.printer }}
+
+
+
+
+
+
+
+ Record not found
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+
+
+ {{ row.category }}
+ {{ row.template }}
+
+
+
+
+ {{ row.printedAt }}
+
+
+
+ {{ row.printedBy }}
+
+
+
+ {{ row.location }}
+
+
+
+ Expires {{ row.expiryDate }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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