Bläddra i källkod

重构目录结构

Huanyi 1 månad sedan
förälder
incheckning
b250f9c3d2

+ 6 - 0
json/cube-products.json

@@ -0,0 +1,6 @@
+[
+  { "name": "建筑铝材", "desc": "门窗/幕墙/家装",    "image": "/static/index/cube1.jpg" },
+  { "name": "工业型材", "desc": "光伏/轨道/汽配",    "image": "/static/index/cube2.jpg" },
+  { "name": "特种定制", "desc": "精密开模/特种合金", "image": "/static/index/cube3.jpg" },
+  { "name": "深加工",   "desc": "切割/冲压/CNC",     "image": "/static/index/cube4.jpg" }
+]

+ 6 - 0
json/mine-menu.json

@@ -0,0 +1,6 @@
+[
+  { "label": "用户协议", "icon": "/static/mine/protocol.png",  "id": "agreement" },
+  { "label": "隐私政策", "icon": "/static/mine/privacy.png",   "id": "privacy" },
+  { "label": "投诉与建议","icon": "/static/mine/complaint.png", "id": "complaint" },
+  { "label": "联系客服", "icon": "/static/mine/service.png",   "id": "service" }
+]

+ 6 - 0
json/order-states.json

@@ -0,0 +1,6 @@
+[
+  { "label": "待审核", "icon": "/static/mine/pending_review.png" },
+  { "label": "待签批", "icon": "/static/mine/pending_sign.png" },
+  { "label": "生产中", "icon": "/static/mine/producing.png" },
+  { "label": "已完成", "icon": "/static/mine/completed.png" }
+]

+ 1 - 0
json/order-status-tabs.json

@@ -0,0 +1 @@
+["全部", "待审核", "待签批", "生产中", "已完成"]

+ 1 - 0
json/package-list.json

@@ -0,0 +1 @@
+["不贴膜+3点捆扎", "贴膜+纸箱", "气泡膜包装", "简易编织袋", "木托架包装"]

+ 1 - 0
json/surface-list.json

@@ -0,0 +1 @@
+["PL坯料", "阳极氧化", "电泳涂漆", "粉末喷涂", "氟碳喷涂", "木纹转印"]

+ 14 - 0
mock/banners.json

@@ -0,0 +1,14 @@
+[
+  {
+    "url": "/static/index/banner2.jpg",
+    "tag": "建筑美学",
+    "title": "高端系统门窗",
+    "subTitle": "智造美好生活空间"
+  },
+  {
+    "url": "/static/index/banner1.jpg",
+    "tag": "领航品质",
+    "title": "工业铝型材定制",
+    "subTitle": "提供一站式工业型材解决方案"
+  }
+]

+ 49 - 0
mock/orders.json

@@ -0,0 +1,49 @@
+[
+  {
+    "orderNo": "ORD20240428001",
+    "models": [
+      { "type": "TY0019", "length": "6000", "surface": "阳极氧化", "count": "100" },
+      { "type": "TY0018", "length": "6000", "surface": "PL坯料",   "count": "50" }
+    ],
+    "totalCount": 150,
+    "status": 1,
+    "statusName": "待审核",
+    "statusType": "pending",
+    "time": "2024-04-28 10:20"
+  },
+  {
+    "orderNo": "ORD20240428002",
+    "models": [
+      { "type": "TY0020", "length": "5800", "surface": "粉末喷涂", "count": "80" }
+    ],
+    "totalCount": 80,
+    "status": 2,
+    "statusName": "待签批",
+    "statusType": "process",
+    "time": "2024-04-28 09:15"
+  },
+  {
+    "orderNo": "ORD20240427088",
+    "models": [
+      { "type": "TY0018", "length": "6000", "surface": "PL坯料", "count": "300" }
+    ],
+    "totalCount": 300,
+    "status": 4,
+    "statusName": "已完成",
+    "statusType": "finish",
+    "time": "2024-04-27 15:40"
+  },
+  {
+    "orderNo": "ORD20240427045",
+    "models": [
+      { "type": "TY0021", "length": "3000", "surface": "电泳涂漆", "count": "50" },
+      { "type": "TY0022", "length": "4000", "surface": "木纹转印", "count": "40" },
+      { "type": "TY0023", "length": "5000", "surface": "氟碳喷涂", "count": "30" }
+    ],
+    "totalCount": 120,
+    "status": 3,
+    "statusName": "生产中",
+    "statusType": "making",
+    "time": "2024-04-27 11:05"
+  }
+]

+ 1 - 0
mock/type-list.json

@@ -0,0 +1 @@
+["TY0018", "TY0019", "TY0020", "TY0021", "TY0022", "TY0023", "TY0024", "TY0025", "TY0026", "TY0027", "TY0028"]

+ 12 - 12
pages.json

@@ -9,14 +9,14 @@
 			}
 		},
 		{
-			"path": "pages/login/login",
+			"path": "pages/login/index",
 			"style": {
 				"navigationBarTitleText": "登录",
 				"navigationStyle": "custom"
 			}
 		},
 		{
-			"path": "pages/order/order",
+			"path": "pages/order/index",
 			"style": {
 				"navigationBarTitleText": "ERP 下单",
 				"navigationBarBackgroundColor": "#FFFFFF",
@@ -24,28 +24,28 @@
 			}
 		},
 		{
-			"path": "pages/order/success",
+			"path": "pages/order/success/index",
 			"style": {
 				"navigationBarTitleText": "下单成功",
 				"navigationBarBackgroundColor": "#FFFFFF"
 			}
 		},
 		{
-			"path": "pages/order/add_model",
+			"path": "pages/order/add_model/index",
 			"style": {
 				"navigationBarTitleText": "添加型号",
 				"navigationBarBackgroundColor": "#FFFFFF"
 			}
 		},
 		{
-			"path": "pages/order/edit_model",
+			"path": "pages/order/edit_model/index",
 			"style": {
 				"navigationBarTitleText": "编辑型号",
 				"navigationBarBackgroundColor": "#FFFFFF"
 			}
 		},
 		{
-			"path": "pages/order/list",
+			"path": "pages/order/list/index",
 			"style": {
 				"navigationBarTitleText": "我的订单",
 				"navigationStyle": "custom",
@@ -53,42 +53,42 @@
 			}
 		},
 		{
-			"path": "pages/order/detail",
+			"path": "pages/order/detail/index",
 			"style": {
 				"navigationBarTitleText": "订单详情",
 				"navigationStyle": "custom"
 			}
 		},
 		{
-			"path": "pages/mine/settings",
+			"path": "pages/mine/settings/index",
 			"style": {
 				"navigationBarTitleText": "个人资料设置",
 				"navigationStyle": "custom"
 			}
 		},
 		{
-			"path": "pages/mine/agreement",
+			"path": "pages/mine/agreement/index",
 			"style": {
 				"navigationBarTitleText": "用户协议",
 				"navigationStyle": "custom"
 			}
 		},
 		{
-			"path": "pages/mine/privacy",
+			"path": "pages/mine/privacy/index",
 			"style": {
 				"navigationBarTitleText": "隐私政策",
 				"navigationStyle": "custom"
 			}
 		},
 		{
-			"path": "pages/mine/complaint",
+			"path": "pages/mine/complaint/index",
 			"style": {
 				"navigationBarTitleText": "投诉与建议",
 				"navigationStyle": "custom"
 			}
 		},
 		{
-			"path": "pages/mine/mine",
+			"path": "pages/mine/index",
 			"style": {
 				"navigationBarTitleText": "个人中心",
 				"navigationBarBackgroundColor": "#C1001C",

+ 384 - 134
pages/index/index.vue

@@ -3,23 +3,24 @@
 		<scroll-view class="main-scroll" scroll-y :show-scrollbar="false" :enhanced="true">
 			<!-- 1. 灵动大屏轮播 (无缝全屏感) -->
 			<view class="hero-section">
-				<swiper class="hero-swiper" circular autoplay interval="5000" duration="800" @change="handleBannerChange">
+				<swiper class="hero-swiper" circular autoplay interval="5000" duration="800"
+					@change="handleBannerChange">
 					<swiper-item v-for="(item, index) in banners" :key="index">
 						<view class="hero-card">
 							<image :src="item.url" mode="aspectFill" class="hero-img"></image>
 							<view class="hero-overlay"></view>
 							<view class="hero-text-content">
-								<text class="hero-tag">{{item.tag}}</text>
-								<text class="hero-main-title">{{item.title}}</text>
-								<text class="hero-sub-title">{{item.subTitle}}</text>
+								<text class="hero-tag">{{ item.tag }}</text>
+								<text class="hero-main-title">{{ item.title }}</text>
+								<text class="hero-sub-title">{{ item.subTitle }}</text>
 							</view>
 						</view>
 					</swiper-item>
 				</swiper>
 				<!-- 胶囊样式指示器 -->
 				<view class="hero-indicators">
-					<view v-for="(item, index) in banners" :key="index" 
-						class="indicator-pill" :class="{ active: currentBanner === index }"></view>
+					<view v-for="(item, index) in banners" :key="index" class="indicator-pill"
+						:class="{ active: currentBanner === index }"></view>
 				</view>
 			</view>
 
@@ -47,16 +48,16 @@
 						<text class="en">CATEGORIES</text>
 					</view>
 				</view>
-				
+
 				<view class="cube-container">
 					<view class="cube-grid">
 						<view class="cube-card" v-for="(item, index) in cubeProducts" :key="index" @click="goToOrder">
 							<image :src="item.image" mode="aspectFill" class="cube-bg"></image>
 							<view class="cube-mask"></view>
 							<view class="cube-content">
-								<text class="cube-title">{{item.name}}</text>
+								<text class="cube-title">{{ item.name }}</text>
 								<view class="cube-line"></view>
-								<text class="cube-desc">{{item.desc}}</text>
+								<text class="cube-desc">{{ item.desc }}</text>
 							</view>
 							<view class="cube-arrow">→</view>
 						</view>
@@ -103,138 +104,387 @@
 </template>
 
 <script>
-	import ErpTabBar from '@/components/erp-tab-bar/erp-tab-bar.vue';
-	import assets from '@/utils/assets.js';
-
-	export default {
-		components: { ErpTabBar },
-		data() {
-			return {
-				assets,
-				statusBarHeight: 0,
-				currentBanner: 0,
-				banners: [
-					{ 
-						url: '/static/index/banner2.jpg', 
-						tag: '建筑美学', 
-						title: '高端系统门窗', 
-						subTitle: '智造美好生活空间' 
-					},
-					{ 
-						url: '/static/index/banner1.jpg', 
-						tag: '领航品质', 
-						title: '工业铝型材定制', 
-						subTitle: '提供一站式工业型材解决方案' 
+import ErpTabBar from '@/components/erp-tab-bar/erp-tab-bar.vue';
+import assets from '@/utils/assets.js';
+import banners from '@/mock/banners.json';
+import cubeProducts from '@/json/cube-products.json';
+
+export default {
+	components: { ErpTabBar },
+	data() {
+		return {
+			assets,
+			statusBarHeight: 0,
+			currentBanner: 0,
+			banners,
+			cubeProducts
+		}
+	},
+	onLoad() {
+	},
+	methods: {
+		handleBannerChange(e) { this.currentBanner = e.detail.current; },
+		callService() {
+			uni.showModal({
+				title: '管家式服务',
+				content: '即将为您拨打华晟型材专家电话 13888888888',
+				confirmText: '立即咨询',
+				confirmColor: '#C1001C',
+				cancelText: '稍后再说',
+				cancelColor: '#999',
+				success: (res) => {
+					if (res.confirm) {
+						uni.makePhoneCall({ phoneNumber: '13888888888' });
 					}
-				],
-				cubeProducts: [
-					{ name: '建筑铝材', desc: '门窗/幕墙/家装', image: '/static/index/cube1.jpg' },
-					{ name: '工业型材', desc: '光伏/轨道/汽配', image: '/static/index/cube2.jpg' },
-					{ name: '特种定制', desc: '精密开模/特种合金', image: '/static/index/cube3.jpg' },
-					{ name: '深加工', desc: '切割/冲压/CNC', image: '/static/index/cube4.jpg' }
-				]
-			}
-		},
-		onLoad() {
+				}
+			});
 		},
-		methods: {
-			handleBannerChange(e) { this.currentBanner = e.detail.current; },
-			callService() { 
-				uni.showModal({
-					title: '管家式服务',
-					content: '即将为您拨打华晟型材专家电话 13888888888',
-					confirmText: '立即咨询',
-					confirmColor: '#C1001C',
-					cancelText: '稍后再说',
-					cancelColor: '#999',
-					success: (res) => {
-						if (res.confirm) {
-							uni.makePhoneCall({ phoneNumber: '13888888888' });
-						}
-					}
-				});
-			},
-			goToOrder() { uni.reLaunch({ url: '/pages/order/order' }); }
-		}
+		goToOrder() { uni.reLaunch({ url: '/pages/order/index' }); }
 	}
+}
 </script>
 
 <style scoped>
-	.home-page { width: 100vw; height: 100vh; background-color: #F8FAFC; display: flex; flex-direction: column; }
-	.main-scroll { flex: 1; height: 0; }
-
-	/* 英雄轮播区 */
-	.hero-section { position: relative; width: 100%; height: 500rpx; overflow: hidden; }
-	.hero-swiper { height: 100%; }
-	.hero-card { position: relative; width: 100%; height: 100%; }
-	.hero-img { width: 100%; height: 100%; }
-	.hero-overlay { position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(0,0,0,0.1), rgba(0,0,0,0.5)); }
-	
-	.hero-text-content { position: absolute; left: 40rpx; bottom: 80rpx; color: #fff; z-index: 2; }
-	.hero-tag { font-size: 20rpx; background: rgba(193,0,28,0.8); padding: 4rpx 16rpx; border-radius: 4rpx; margin-bottom: 12rpx; display: inline-block; }
-	.hero-main-title { font-size: 44rpx; font-weight: bold; display: block; margin-bottom: 8rpx; }
-	.hero-sub-title { font-size: 24rpx; opacity: 0.8; letter-spacing: 1rpx; }
-
-	.hero-indicators { position: absolute; bottom: 40rpx; right: 40rpx; display: flex; gap: 8rpx; }
-	.indicator-pill { width: 12rpx; height: 6rpx; background: rgba(255,255,255,0.3); border-radius: 4rpx; transition: 0.3s; }
-	.indicator-pill.active { width: 32rpx; background: #fff; }
-
-	/* 咨询卡片 */
-	.contact-card {
-		margin: -40rpx 40rpx 40rpx; position: relative; z-index: 10;
-		background: rgba(255,255,255,0.9); backdrop-filter: blur(20px);
-		border-radius: 24rpx; padding: 32rpx 40rpx; display: flex; align-items: center; 
-		justify-content: space-between; border: 1rpx solid #fff;
-		box-shadow: 0 12rpx 40rpx rgba(0,0,0,0.06);
-	}
-	.contact-info { display: flex; align-items: center; }
-	.contact-icon-box { width: 88rpx; height: 88rpx; background: #FFF1F2; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-right: 24rpx; }
-	.contact-icon-box image { width: 44rpx; height: 44rpx; }
-	.main-txt { font-size: 30rpx; font-weight: bold; color: #1a1a1a; display: block; margin-bottom: 4rpx; }
-	.sub-txt { font-size: 22rpx; color: #7a7a7a; }
-	.call-btn-circle { width: 72rpx; height: 72rpx; background: #C1001C; border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: 0 6rpx 12rpx rgba(193,0,28,0.3); }
-	.call-btn-circle image { width: 32rpx; height: 32rpx; }
-
-	/* 魔方布局 */
-	.cube-section { padding: 20rpx 40rpx; }
-	.section-header { margin-bottom: 30rpx; }
-	.title-with-line { display: flex; align-items: baseline; gap: 16rpx; }
-	.title-with-line .zh { font-size: 36rpx; font-weight: 800; color: #1a1a1a; }
-	.title-with-line .en { font-size: 20rpx; color: #999; font-family: 'Georgia'; letter-spacing: 2rpx; }
-
-	.cube-container { width: 100%; }
-	.cube-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20rpx; }
-	.cube-card { 
-		position: relative; height: 320rpx; border-radius: 20rpx; overflow: hidden;
-		background: #eee; transition: 0.3s;
-	}
-	.cube-bg { width: 100%; height: 100%; }
-	.cube-mask { position: absolute; inset: 0; background: rgba(0,0,0,0.3); }
-	.cube-content { position: absolute; left: 30rpx; top: 30rpx; z-index: 2; }
-	.cube-title { font-size: 32rpx; font-weight: bold; color: #fff; margin-bottom: 12rpx; display: block; }
-	.cube-line { width: 40rpx; height: 4rpx; background: #C1001C; margin-bottom: 12rpx; }
-	.cube-desc { font-size: 20rpx; color: rgba(255,255,255,0.8); max-width: 240rpx; line-height: 1.4; display: block; }
-	.cube-arrow { position: absolute; right: 30rpx; bottom: 30rpx; color: #fff; font-size: 30rpx; opacity: 0.6; }
-
-	/* 企业实力 */
-	.brand-strength { padding: 40rpx; margin-bottom: 40rpx; }
-	.strength-card { 
-		background: #1a1a1a; border-radius: 32rpx; padding: 48rpx 40rpx; color: #fff;
-		box-shadow: 0 20rpx 60rpx rgba(0,0,0,0.15);
-	}
-	.s-header { margin-bottom: 50rpx; }
-	.s-title { font-size: 34rpx; font-weight: bold; display: block; margin-bottom: 8rpx; color: #fff; letter-spacing: 4rpx; }
-	.s-subtitle { font-size: 18rpx; color: #666; font-family: 'Arial'; text-transform: uppercase; }
+.home-page {
+	width: 100vw;
+	height: 100vh;
+	background-color: #F8FAFC;
+	display: flex;
+	flex-direction: column;
+}
+
+.main-scroll {
+	flex: 1;
+	height: 0;
+}
+
+/* 英雄轮播区 */
+.hero-section {
+	position: relative;
+	width: 100%;
+	height: 500rpx;
+	overflow: hidden;
+}
+
+.hero-swiper {
+	height: 100%;
+}
+
+.hero-card {
+	position: relative;
+	width: 100%;
+	height: 100%;
+}
+
+.hero-img {
+	width: 100%;
+	height: 100%;
+}
+
+.hero-overlay {
+	position: absolute;
+	inset: 0;
+	background: linear-gradient(to bottom, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.5));
+}
+
+.hero-text-content {
+	position: absolute;
+	left: 40rpx;
+	bottom: 80rpx;
+	color: #fff;
+	z-index: 2;
+}
+
+.hero-tag {
+	font-size: 20rpx;
+	background: rgba(193, 0, 28, 0.8);
+	padding: 4rpx 16rpx;
+	border-radius: 4rpx;
+	margin-bottom: 12rpx;
+	display: inline-block;
+}
+
+.hero-main-title {
+	font-size: 44rpx;
+	font-weight: bold;
+	display: block;
+	margin-bottom: 8rpx;
+}
+
+.hero-sub-title {
+	font-size: 24rpx;
+	opacity: 0.8;
+	letter-spacing: 1rpx;
+}
+
+.hero-indicators {
+	position: absolute;
+	bottom: 40rpx;
+	right: 40rpx;
+	display: flex;
+	gap: 8rpx;
+}
+
+.indicator-pill {
+	width: 12rpx;
+	height: 6rpx;
+	background: rgba(255, 255, 255, 0.3);
+	border-radius: 4rpx;
+	transition: 0.3s;
+}
+
+.indicator-pill.active {
+	width: 32rpx;
+	background: #fff;
+}
+
+/* 咨询卡片 */
+.contact-card {
+	margin: -40rpx 40rpx 40rpx;
+	position: relative;
+	z-index: 10;
+	background: rgba(255, 255, 255, 0.9);
+	backdrop-filter: blur(20px);
+	border-radius: 24rpx;
+	padding: 32rpx 40rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	border: 1rpx solid #fff;
+	box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.06);
+}
+
+.contact-info {
+	display: flex;
+	align-items: center;
+}
+
+.contact-icon-box {
+	width: 88rpx;
+	height: 88rpx;
+	background: #FFF1F2;
+	border-radius: 50%;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	margin-right: 24rpx;
+}
+
+.contact-icon-box image {
+	width: 44rpx;
+	height: 44rpx;
+}
+
+.main-txt {
+	font-size: 30rpx;
+	font-weight: bold;
+	color: #1a1a1a;
+	display: block;
+	margin-bottom: 4rpx;
+}
+
+.sub-txt {
+	font-size: 22rpx;
+	color: #7a7a7a;
+}
+
+.call-btn-circle {
+	width: 72rpx;
+	height: 72rpx;
+	background: #C1001C;
+	border-radius: 50%;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	box-shadow: 0 6rpx 12rpx rgba(193, 0, 28, 0.3);
+}
+
+.call-btn-circle image {
+	width: 32rpx;
+	height: 32rpx;
+}
+
+/* 魔方布局 */
+.cube-section {
+	padding: 20rpx 40rpx;
+}
+
+.section-header {
+	margin-bottom: 30rpx;
+}
+
+.title-with-line {
+	display: flex;
+	align-items: baseline;
+	gap: 16rpx;
+}
+
+.title-with-line .zh {
+	font-size: 36rpx;
+	font-weight: 800;
+	color: #1a1a1a;
+}
+
+.title-with-line .en {
+	font-size: 20rpx;
+	color: #999;
+	font-family: 'Georgia';
+	letter-spacing: 2rpx;
+}
+
+.cube-container {
+	width: 100%;
+}
+
+.cube-grid {
+	display: grid;
+	grid-template-columns: repeat(2, 1fr);
+	gap: 20rpx;
+}
+
+.cube-card {
+	position: relative;
+	height: 320rpx;
+	border-radius: 20rpx;
+	overflow: hidden;
+	background: #eee;
+	transition: 0.3s;
+}
+
+.cube-bg {
+	width: 100%;
+	height: 100%;
+}
+
+.cube-mask {
+	position: absolute;
+	inset: 0;
+	background: rgba(0, 0, 0, 0.3);
+}
+
+.cube-content {
+	position: absolute;
+	left: 30rpx;
+	top: 30rpx;
+	z-index: 2;
+}
+
+.cube-title {
+	font-size: 32rpx;
+	font-weight: bold;
+	color: #fff;
+	margin-bottom: 12rpx;
+	display: block;
+}
+
+.cube-line {
+	width: 40rpx;
+	height: 4rpx;
+	background: #C1001C;
+	margin-bottom: 12rpx;
+}
+
+.cube-desc {
+	font-size: 20rpx;
+	color: rgba(255, 255, 255, 0.8);
+	max-width: 240rpx;
+	line-height: 1.4;
+	display: block;
+}
+
+.cube-arrow {
+	position: absolute;
+	right: 30rpx;
+	bottom: 30rpx;
+	color: #fff;
+	font-size: 30rpx;
+	opacity: 0.6;
+}
+
+/* 企业实力 */
+.brand-strength {
+	padding: 40rpx;
+	margin-bottom: 40rpx;
+}
+
+.strength-card {
+	background: #1a1a1a;
+	border-radius: 32rpx;
+	padding: 48rpx 40rpx;
+	color: #fff;
+	box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);
+}
+
+.s-header {
+	margin-bottom: 50rpx;
+}
+
+.s-title {
+	font-size: 34rpx;
+	font-weight: bold;
+	display: block;
+	margin-bottom: 8rpx;
+	color: #fff;
+	letter-spacing: 4rpx;
+}
+
+.s-subtitle {
+	font-size: 18rpx;
+	color: #666;
+	font-family: 'Arial';
+	text-transform: uppercase;
+}
+
+.s-stats {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	margin-bottom: 40rpx;
+}
+
+.stat-box {
+	text-align: center;
+	flex: 1;
+}
+
+.stat-box .num {
+	font-size: 44rpx;
+	font-weight: 800;
+	color: #FFD700;
+	display: block;
+	margin-bottom: 4rpx;
+}
+
+.stat-box .unit {
+	font-size: 20rpx;
+	margin-left: 4rpx;
+	font-weight: normal;
+}
+
+.stat-box .label {
+	font-size: 22rpx;
+	color: #ababab;
+}
+
+.stat-divider {
+	width: 1rpx;
+	height: 50rpx;
+	background: rgba(255, 255, 255, 0.1);
+}
 
-	.s-stats { display: flex; justify-content: space-between; align-items: center; margin-bottom: 40rpx; }
-	.stat-box { text-align: center; flex: 1; }
-	.stat-box .num { font-size: 44rpx; font-weight: 800; color: #FFD700; display: block; margin-bottom: 4rpx; }
-	.stat-box .unit { font-size: 20rpx; margin-left: 4rpx; font-weight: normal; }
-	.stat-box .label { font-size: 22rpx; color: #ababab; }
-	.stat-divider { width: 1rpx; height: 50rpx; background: rgba(255,255,255,0.1); }
+.s-footer {
+	border-top: 1rpx solid rgba(255, 255, 255, 0.05);
+	padding-top: 30rpx;
+	text-align: center;
+}
 
-	.s-footer { border-top: 1rpx solid rgba(255,255,255,0.05); padding-top: 30rpx; text-align: center; }
-	.s-footer text { font-size: 18rpx; color: #555; letter-spacing: 6rpx; }
+.s-footer text {
+	font-size: 18rpx;
+	color: #555;
+	letter-spacing: 6rpx;
+}
 
-	.safe-bottom-gap { height: 140rpx; }
+.safe-bottom-gap {
+	height: 140rpx;
+}
 </style>

+ 0 - 0
pages/login/login.vue → pages/login/index.vue


+ 0 - 0
pages/mine/agreement.vue → pages/mine/agreement/index.vue


+ 0 - 0
pages/mine/complaint.vue → pages/mine/complaint/index.vue


+ 454 - 0
pages/mine/index.vue

@@ -0,0 +1,454 @@
+<template>
+	<view class="mine-page">
+		<scroll-view class="mine-scroll" scroll-y enable-back-to-top :show-scrollbar="false" :enhanced="true">
+			<!-- 顶部大气定制背景 (带柔和渐变与底部圆角弧度) -->
+			<view class="header-bg-shape">
+				<view class="header-bg-gradient"></view>
+			</view>
+
+			<!-- 整体内容下移 -->
+			<view class="content-wrapper">
+				<!-- 1. 登录状态卡片 -->
+				<view class="user-card" v-if="isLogin">
+					<view class="avatar-box">
+						<image class="avatar-img" src="https://img.icons8.com/color/144/user.png" mode="aspectFill">
+						</image>
+					</view>
+					<view class="info-box">
+						<text class="nickname">张经理</text>
+						<view class="tags-row">
+							<text class="customer-tag">授权客户: 广东铝材实业</text>
+						</view>
+						<text class="phone-text">138-8888-8888</text>
+					</view>
+					<!-- 新增:右侧设置图标 -->
+					<view class="settings-btn" @click="goToSettings">
+						<image class="settings-icon" :src="assets.mineSettings" mode="aspectFit"></image>
+					</view>
+				</view>
+
+				<!-- 1. 未登录状态卡片 -->
+				<view class="user-card unlogged" v-else @click="goToLogin">
+					<view class="avatar-box gray-avatar">
+						<image class="avatar-img" src="https://img.icons8.com/material-outlined/100/cccccc/user.png"
+							mode="aspectFit"></image>
+					</view>
+					<view class="info-box">
+						<text class="nickname login-hint">未登录</text>
+						<text class="phone-text">点击此处登录,体验完整功能</text>
+					</view>
+					<image class="arrow-icon-right" :src="assets.mineArrow"></image>
+				</view>
+
+				<!-- 2. 我的订单 (线性图标) -->
+				<view class="section-card">
+					<view class="section-header">
+						<text class="section-title">我的订单</text>
+						<view class="more-link" @click="goToOrderList(0)">
+							<text>全部</text>
+							<image class="arrow-icon" :src="assets.mineArrow"></image>
+						</view>
+					</view>
+					<view class="stat-grid">
+						<view class="stat-item" v-for="(item, index) in orderStates" :key="index"
+							@click="goToOrderList(index + 1)">
+							<image class="stat-icon" :src="item.icon" mode="aspectFit"></image>
+							<text class="stat-label">{{ item.label }}</text>
+						</view>
+					</view>
+				</view>
+
+				<!-- 3. 功能菜单列表 (线性图标) -->
+				<view class="section-card menu-card">
+					<view class="menu-item" v-for="(menu, index) in menuList" :key="index"
+						@click="handleMenuClick(menu)">
+						<view class="menu-left">
+							<image class="menu-icon" :src="menu.icon" mode="aspectFit"></image>
+							<text class="menu-label">{{ menu.label }}</text>
+						</view>
+						<image class="arrow-icon-right" :src="assets.mineArrow"></image>
+					</view>
+				</view>
+
+				<!-- 4. 退出登录按钮 (仅登录后显示) -->
+				<view class="logout-section" v-if="isLogin">
+					<button class="logout-btn" @click="handleLogout">退出登录</button>
+				</view>
+
+				<view class="bottom-placeholder"></view>
+			</view>
+		</scroll-view>
+
+		<erp-tab-bar active="mine"></erp-tab-bar>
+	</view>
+</template>
+
+<script>
+import ErpTabBar from '@/components/erp-tab-bar/erp-tab-bar.vue';
+import assets from '@/utils/assets.js';
+import orderStates from '@/json/order-states.json';
+import menuList from '@/json/mine-menu.json';
+
+export default {
+	components: {
+		ErpTabBar
+	},
+	data() {
+		return {
+			assets,
+			isLogin: false, // 控制登录状态
+			orderStates,
+			menuList
+		}
+	},
+	onShow() {
+		// 页面显示时检查登录状态
+		this.isLogin = !!uni.getStorageSync('isLogin');
+	},
+	methods: {
+		goToLogin() {
+			uni.navigateTo({ url: '/pages/login/index?redirect=' + encodeURIComponent('/pages/mine/index') });
+		},
+		// 跳转至设置页面
+		goToSettings() {
+			if (this.isLogin) {
+				uni.navigateTo({
+					url: '/pages/mine/settings/index'
+				});
+			}
+		},
+		// 新增:跳转至订单列表
+		goToOrderList(status) {
+			if (!this.isLogin) {
+				return this.goToLogin();
+			}
+			uni.navigateTo({
+				url: `/pages/order/list/index?tab=${status}`
+			});
+		},
+		handleLogout() {
+			uni.showModal({
+				title: '退出提示',
+				content: '确认退出当前账号吗?',
+				confirmColor: '#C1001C',
+				success: (res) => {
+					if (res.confirm) {
+						uni.removeStorageSync('isLogin');
+						this.isLogin = false;
+					}
+				}
+			});
+		},
+		// 新增:菜单点击处理
+		handleMenuClick(menu) {
+			if (menu.id === 'agreement') {
+				uni.navigateTo({ url: '/pages/mine/agreement/index' });
+			} else if (menu.id === 'privacy') {
+				uni.navigateTo({ url: '/pages/mine/privacy/index' });
+			} else if (menu.id === 'complaint') {
+				uni.navigateTo({ url: '/pages/mine/complaint/index' });
+			} else if (menu.id === 'service') {
+				uni.showModal({
+					title: '联系客服',
+					content: '客服电话:138-8888-8888',
+					confirmText: '立即拨打',
+					confirmColor: '#C1001C',
+					cancelColor: '#999999',
+					success: (res) => {
+						if (res.confirm) {
+							uni.makePhoneCall({
+								phoneNumber: '13888888888'
+							});
+						}
+					}
+				});
+			}
+		}
+	}
+}
+</script>
+
+<style scoped>
+.mine-page {
+	width: 100%;
+	height: 100vh;
+	background: #f7f8fa;
+	position: relative;
+	display: flex;
+	flex-direction: column;
+	overflow: hidden;
+}
+
+.mine-scroll {
+	width: 100%;
+	height: 100%;
+}
+
+/* 隐藏滚动条 */
+.mine-scroll ::-webkit-scrollbar {
+	width: 0 !important;
+	height: 0 !important;
+	color: transparent !important;
+	display: none !important;
+}
+
+/* 顶部定制背景:高级渐变蓝 + 柔和弧度 */
+.header-bg-shape {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 380rpx;
+	background: linear-gradient(135deg, #C1001C 0%, #FF4D4F 100%);
+	border-bottom-left-radius: 60rpx;
+	border-bottom-right-radius: 60rpx;
+	z-index: 1;
+	box-shadow: 0 10rpx 30rpx rgba(193, 0, 28, 0.15);
+}
+
+.header-bg-gradient {
+	width: 100%;
+	height: 100%;
+	background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.1) 100%);
+	border-bottom-left-radius: 60rpx;
+	border-bottom-right-radius: 60rpx;
+}
+
+/* 标题栏已恢复为原生,此处仅需正常的容器内边距即可 */
+.content-wrapper {
+	position: relative;
+	z-index: 2;
+	flex: 1;
+	display: flex;
+	flex-direction: column;
+	padding: 40rpx 30rpx 0;
+	box-sizing: border-box;
+}
+
+/* 用户信息卡片 */
+.user-card {
+	background: #fff;
+	border-radius: 32rpx;
+	padding: 50rpx 40rpx;
+	display: flex;
+	align-items: center;
+	margin-bottom: 30rpx;
+	margin-top: 20rpx;
+	box-shadow: 0 16rpx 40rpx rgba(0, 0, 0, 0.05);
+}
+
+.user-card.unlogged {
+	cursor: pointer;
+}
+
+.avatar-box {
+	width: 130rpx;
+	height: 130rpx;
+	border-radius: 65rpx;
+	background: #f5f6f7;
+	margin-right: 30rpx;
+	overflow: hidden;
+	border: 4rpx solid #fff;
+	box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
+}
+
+.gray-avatar {
+	background: #f0f0f0;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.avatar-img {
+	width: 100%;
+	height: 100%;
+}
+
+.info-box {
+	flex: 1;
+	display: flex;
+	flex-direction: column;
+	justify-content: center;
+}
+
+.nickname {
+	font-size: 40rpx;
+	font-weight: bold;
+	color: #1a1a1a;
+	margin-bottom: 12rpx;
+}
+
+.login-hint {
+	color: #333;
+}
+
+.tags-row {
+	display: flex;
+	align-items: center;
+	margin-bottom: 12rpx;
+}
+
+.customer-tag {
+	font-size: 24rpx;
+	color: #C1001C;
+	background: rgba(193, 0, 28, 0.1);
+	padding: 6rpx 16rpx;
+	border-radius: 8rpx;
+	font-weight: 500;
+}
+
+.phone-text {
+	font-size: 26rpx;
+	color: #999;
+}
+
+/* 设置图标 & 右侧箭头 */
+.settings-btn {
+	width: 60rpx;
+	height: 60rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.settings-icon {
+	width: 44rpx;
+	height: 44rpx;
+	opacity: 0.6;
+}
+
+.arrow-icon-right {
+	width: 24rpx;
+	height: 24rpx;
+	opacity: 0.4;
+}
+
+/* 通用卡片样式 */
+.section-card {
+	background: #fff;
+	border-radius: 24rpx;
+	padding: 40rpx 30rpx;
+	margin-bottom: 30rpx;
+	box-shadow: 0 8rpx 30rpx rgba(0, 0, 0, 0.02);
+}
+
+/* 订单统计区块 */
+.section-header {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	margin-bottom: 40rpx;
+}
+
+.section-title {
+	font-size: 32rpx;
+	font-weight: bold;
+	color: #333;
+}
+
+.more-link {
+	display: flex;
+	align-items: center;
+	font-size: 26rpx;
+	color: #999;
+}
+
+.arrow-icon {
+	width: 20rpx;
+	height: 20rpx;
+	opacity: 0.5;
+	margin-left: 6rpx;
+	position: relative;
+	top: 2rpx;
+}
+
+.stat-grid {
+	display: flex;
+	justify-content: space-around;
+}
+
+.stat-item {
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+}
+
+.stat-icon {
+	width: 56rpx;
+	height: 56rpx;
+	margin-bottom: 16rpx;
+	opacity: 0.8;
+}
+
+.stat-label {
+	font-size: 26rpx;
+	color: #666;
+}
+
+/* 菜单列表区块 */
+.menu-card {
+	padding: 10rpx 30rpx;
+}
+
+.menu-item {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding: 36rpx 0;
+	border-bottom: 1rpx solid #f5f6f7;
+}
+
+.menu-item:last-child {
+	border-bottom: none;
+}
+
+.menu-left {
+	display: flex;
+	align-items: center;
+}
+
+.menu-icon {
+	width: 44rpx;
+	height: 44rpx;
+	margin-right: 20rpx;
+	opacity: 0.7;
+}
+
+.menu-label {
+	font-size: 30rpx;
+	color: #333;
+}
+
+/* 退出登录 */
+.logout-section {
+	margin-top: 40rpx;
+}
+
+.logout-btn {
+	width: 100%;
+	height: 96rpx;
+	background: #fff;
+	color: #ff5e5e;
+	border-radius: 24rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 32rpx;
+	font-weight: bold;
+	border: none;
+	box-shadow: 0 4rpx 20rpx rgba(255, 94, 94, 0.05);
+	transition: all 0.2s;
+}
+
+.logout-btn:active {
+	background: #fff0f0;
+}
+
+button::after {
+	border: none;
+}
+
+.bottom-placeholder {
+	height: 180rpx;
+}
+</style>

+ 0 - 253
pages/mine/mine.vue

@@ -1,253 +0,0 @@
-<template>
-	<view class="mine-page">
-		<scroll-view class="mine-scroll" scroll-y enable-back-to-top :show-scrollbar="false" :enhanced="true">
-			<!-- 顶部大气定制背景 (带柔和渐变与底部圆角弧度) -->
-			<view class="header-bg-shape">
-				<view class="header-bg-gradient"></view>
-			</view>
-
-			<!-- 整体内容下移 -->
-			<view class="content-wrapper">
-				<!-- 1. 登录状态卡片 -->
-				<view class="user-card" v-if="isLogin">
-					<view class="avatar-box">
-						<image class="avatar-img" src="https://img.icons8.com/color/144/user.png" mode="aspectFill"></image>
-					</view>
-					<view class="info-box">
-						<text class="nickname">张经理</text>
-						<view class="tags-row">
-							<text class="customer-tag">授权客户: 广东铝材实业</text>
-						</view>
-						<text class="phone-text">138-8888-8888</text>
-					</view>
-					<!-- 新增:右侧设置图标 -->
-					<view class="settings-btn" @click="goToSettings">
-						<image class="settings-icon" :src="assets.mineSettings" mode="aspectFit"></image>
-					</view>
-				</view>
-
-				<!-- 1. 未登录状态卡片 -->
-				<view class="user-card unlogged" v-else @click="goToLogin">
-					<view class="avatar-box gray-avatar">
-						<image class="avatar-img" src="https://img.icons8.com/material-outlined/100/cccccc/user.png" mode="aspectFit"></image>
-					</view>
-					<view class="info-box">
-						<text class="nickname login-hint">未登录</text>
-						<text class="phone-text">点击此处登录,体验完整功能</text>
-					</view>
-					<image class="arrow-icon-right" :src="assets.mineArrow"></image>
-				</view>
-
-				<!-- 2. 我的订单 (线性图标) -->
-				<view class="section-card">
-					<view class="section-header">
-						<text class="section-title">我的订单</text>
-						<view class="more-link" @click="goToOrderList(0)">
-							<text>全部</text>
-							<image class="arrow-icon" :src="assets.mineArrow"></image>
-						</view>
-					</view>
-					<view class="stat-grid">
-						<view class="stat-item" v-for="(item, index) in orderStates" :key="index" @click="goToOrderList(index + 1)">
-							<image class="stat-icon" :src="item.icon" mode="aspectFit"></image>
-							<text class="stat-label">{{ item.label }}</text>
-						</view>
-					</view>
-				</view>
-
-				<!-- 3. 功能菜单列表 (线性图标) -->
-				<view class="section-card menu-card">
-					<view class="menu-item" v-for="(menu, index) in menuList" :key="index" @click="handleMenuClick(menu)">
-						<view class="menu-left">
-							<image class="menu-icon" :src="menu.icon" mode="aspectFit"></image>
-							<text class="menu-label">{{ menu.label }}</text>
-						</view>
-						<image class="arrow-icon-right" :src="assets.mineArrow"></image>
-					</view>
-				</view>
-
-				<!-- 4. 退出登录按钮 (仅登录后显示) -->
-				<view class="logout-section" v-if="isLogin">
-					<button class="logout-btn" @click="handleLogout">退出登录</button>
-				</view>
-				
-				<view class="bottom-placeholder"></view>
-			</view>
-		</scroll-view>
-
-		<erp-tab-bar active="mine"></erp-tab-bar>
-	</view>
-</template>
-
-<script>
-	import ErpTabBar from '@/components/erp-tab-bar/erp-tab-bar.vue';
-	import assets from '@/utils/assets.js';
-
-	export default {
-		components: {
-			ErpTabBar
-		},
-		data() {
-			return {
-				assets,
-				isLogin: false, // 控制登录状态
-				orderStates: [
-					{ label: '待审核', icon: assets.minePendingReview },
-					{ label: '待签批', icon: assets.minePendingSign },
-					{ label: '生产中', icon: assets.mineProducing },
-					{ label: '已完成', icon: assets.mineCompleted }
-				],
-				menuList: [
-					{ label: '用户协议', icon: assets.mineProtocol, id: 'agreement' },
-					{ label: '隐私政策', icon: assets.minePrivacy, id: 'privacy' },
-					{ label: '投诉与建议', icon: assets.mineComplaint, id: 'complaint' },
-					{ label: '联系客服', icon: assets.mineService, id: 'service' }
-				]
-			}
-		},
-		onShow() {
-			// 页面显示时检查登录状态
-			this.isLogin = !!uni.getStorageSync('isLogin');
-		},
-		methods: {
-			goToLogin() {
-				uni.navigateTo({ url: '/pages/login/login?redirect=' + encodeURIComponent('/pages/mine/mine') });
-			},
-			// 跳转至设置页面
-			goToSettings() {
-				if(this.isLogin) {
-					uni.navigateTo({
-						url: '/pages/mine/settings'
-					});
-				}
-			},
-			// 新增:跳转至订单列表
-			goToOrderList(status) {
-				if(!this.isLogin) {
-					return this.goToLogin();
-				}
-				uni.navigateTo({
-					url: `/pages/order/list?tab=${status}`
-				});
-			},
-			handleLogout() {
-				uni.showModal({
-					title: '退出提示',
-					content: '确认退出当前账号吗?',
-					confirmColor: '#C1001C',
-					success: (res) => {
-						if (res.confirm) {
-							uni.removeStorageSync('isLogin');
-							this.isLogin = false;
-						}
-					}
-				});
-			},
-			// 新增:菜单点击处理
-			handleMenuClick(menu) {
-				if (menu.id === 'agreement') {
-					uni.navigateTo({ url: '/pages/mine/agreement' });
-				} else if (menu.id === 'privacy') {
-					uni.navigateTo({ url: '/pages/mine/privacy' });
-				} else if (menu.id === 'complaint') {
-					uni.navigateTo({ url: '/pages/mine/complaint' });
-				} else if (menu.id === 'service') {
-					uni.showModal({
-						title: '联系客服',
-						content: '客服电话:138-8888-8888',
-						confirmText: '立即拨打',
-						confirmColor: '#C1001C',
-						cancelColor: '#999999',
-						success: (res) => {
-							if (res.confirm) {
-								uni.makePhoneCall({
-									phoneNumber: '13888888888'
-								});
-							}
-						}
-					});
-				}
-			}
-		}
-	}
-</script>
-
-<style scoped>
-	.mine-page { width: 100%; height: 100vh; background: #f7f8fa; position: relative; display: flex; flex-direction: column; overflow: hidden; }
-	
-	.mine-scroll { width: 100%; height: 100%; }
-	/* 隐藏滚动条 */
-	.mine-scroll ::-webkit-scrollbar { width: 0 !important; height: 0 !important; color: transparent !important; display: none !important; }
-
-	/* 顶部定制背景:高级渐变蓝 + 柔和弧度 */
-	.header-bg-shape {
-		position: absolute;
-		top: 0;
-		left: 0;
-		width: 100%;
-		height: 380rpx;
-		background: linear-gradient(135deg, #C1001C 0%, #FF4D4F 100%);
-		border-bottom-left-radius: 60rpx;
-		border-bottom-right-radius: 60rpx;
-		z-index: 1;
-		box-shadow: 0 10rpx 30rpx rgba(193, 0, 28, 0.15);
-	}
-	.header-bg-gradient {
-		width: 100%;
-		height: 100%;
-		background: linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.1) 100%);
-		border-bottom-left-radius: 60rpx;
-		border-bottom-right-radius: 60rpx;
-	}
-
-	/* 标题栏已恢复为原生,此处仅需正常的容器内边距即可 */
-	.content-wrapper { position: relative; z-index: 2; flex: 1; display: flex; flex-direction: column; padding: 40rpx 30rpx 0; box-sizing: border-box; }
-
-	/* 用户信息卡片 */
-	.user-card { background: #fff; border-radius: 32rpx; padding: 50rpx 40rpx; display: flex; align-items: center; margin-bottom: 30rpx; margin-top: 20rpx; box-shadow: 0 16rpx 40rpx rgba(0, 0, 0, 0.05); }
-	.user-card.unlogged { cursor: pointer; }
-	.avatar-box { width: 130rpx; height: 130rpx; border-radius: 65rpx; background: #f5f6f7; margin-right: 30rpx; overflow: hidden; border: 4rpx solid #fff; box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.05); }
-	.gray-avatar { background: #f0f0f0; display: flex; align-items: center; justify-content: center; }
-	.avatar-img { width: 100%; height: 100%; }
-	.info-box { flex: 1; display: flex; flex-direction: column; justify-content: center; }
-	.nickname { font-size: 40rpx; font-weight: bold; color: #1a1a1a; margin-bottom: 12rpx; }
-	.login-hint { color: #333; }
-	.tags-row { display: flex; align-items: center; margin-bottom: 12rpx; }
-	.customer-tag { font-size: 24rpx; color: #C1001C; background: rgba(193, 0, 28, 0.1); padding: 6rpx 16rpx; border-radius: 8rpx; font-weight: 500; }
-	.phone-text { font-size: 26rpx; color: #999; }
-	
-	/* 设置图标 & 右侧箭头 */
-	.settings-btn { width: 60rpx; height: 60rpx; display: flex; align-items: center; justify-content: center; }
-	.settings-icon { width: 44rpx; height: 44rpx; opacity: 0.6; }
-	.arrow-icon-right { width: 24rpx; height: 24rpx; opacity: 0.4; }
-
-	/* 通用卡片样式 */
-	.section-card { background: #fff; border-radius: 24rpx; padding: 40rpx 30rpx; margin-bottom: 30rpx; box-shadow: 0 8rpx 30rpx rgba(0,0,0,0.02); }
-	
-	/* 订单统计区块 */
-	.section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 40rpx; }
-	.section-title { font-size: 32rpx; font-weight: bold; color: #333; }
-	.more-link { display: flex; align-items: center; font-size: 26rpx; color: #999; }
-	.arrow-icon { width: 20rpx; height: 20rpx; opacity: 0.5; margin-left: 6rpx; position: relative; top: 2rpx; }
-	
-	.stat-grid { display: flex; justify-content: space-around; }
-	.stat-item { display: flex; flex-direction: column; align-items: center; }
-	.stat-icon { width: 56rpx; height: 56rpx; margin-bottom: 16rpx; opacity: 0.8; }
-	.stat-label { font-size: 26rpx; color: #666; }
-
-	/* 菜单列表区块 */
-	.menu-card { padding: 10rpx 30rpx; }
-	.menu-item { display: flex; justify-content: space-between; align-items: center; padding: 36rpx 0; border-bottom: 1rpx solid #f5f6f7; }
-	.menu-item:last-child { border-bottom: none; }
-	.menu-left { display: flex; align-items: center; }
-	.menu-icon { width: 44rpx; height: 44rpx; margin-right: 20rpx; opacity: 0.7; }
-	.menu-label { font-size: 30rpx; color: #333; }
-
-	/* 退出登录 */
-	.logout-section { margin-top: 40rpx; }
-	.logout-btn { width: 100%; height: 96rpx; background: #fff; color: #ff5e5e; border-radius: 24rpx; display: flex; align-items: center; justify-content: center; font-size: 32rpx; font-weight: bold; border: none; box-shadow: 0 4rpx 20rpx rgba(255, 94, 94, 0.05); transition: all 0.2s; }
-	.logout-btn:active { background: #fff0f0; }
-	
-	button::after { border: none; }
-	.bottom-placeholder { height: 180rpx; }
-</style>

+ 0 - 0
pages/mine/privacy.vue → pages/mine/privacy/index.vue


+ 0 - 0
pages/mine/settings.vue → pages/mine/settings/index.vue


+ 0 - 294
pages/order/add_model.vue

@@ -1,294 +0,0 @@
-<template>
-	<view class="order-container">
-		<scroll-view 
-			:scroll-y="!showTypePicker && !showSurfacePicker && !showPackagePicker" 
-			class="order-scroll" 
-			:show-scrollbar="false"
-			:enhanced="true">
-			<view class="form-content">
-				
-				<!-- 模块 1:型材 -->
-				<view class="section-card">
-					<view class="section-header">
-						<view class="blue-bar"></view>
-						<text class="section-title">型材</text>
-					</view>
-					<view class="form-item">
-						<text class="label required">型号</text>
-						<view class="picker-box" @click="openTypePicker">
-							<view class="picker-inner">
-								<view class="picker-val" :class="{placeholder: !formData.type}">
-									{{ formData.type || '请选择型号' }}
-								</view>
-								<view class="line-arrow-down"></view>
-							</view>
-						</view>
-					</view>
-					<view class="row-flex">
-						<view class="half-item">
-							<text class="label">名称</text>
-							<input class="input-box readonly small-font" v-model="formData.name" disabled placeholder="型号名称" />
-						</view>
-						<view class="half-item">
-							<text class="label">材质</text>
-							<input class="input-box readonly small-font" v-model="formData.material" disabled placeholder="材质" />
-						</view>
-					</view>
-				</view>
-
-				<!-- 模块 2:表面处理 -->
-				<view class="section-card">
-					<view class="section-header">
-						<view class="blue-bar"></view>
-						<text class="section-title">表面处理</text>
-					</view>
-					<view class="form-item">
-						<text class="label required">表面名称</text>
-						<view class="picker-box" @click="openSurfacePicker">
-							<view class="picker-inner">
-								<view class="picker-val" :class="{placeholder: !formData.surfaceName}">
-									{{ formData.surfaceName || '请选择表面名称' }}
-								</view>
-								<view class="line-arrow-down"></view>
-							</view>
-						</view>
-					</view>
-				</view>
-
-				<!-- 模块 3:包装 -->
-				<view class="section-card">
-					<view class="section-header">
-						<view class="blue-bar"></view>
-						<text class="section-title">包装</text>
-					</view>
-					<view class="form-item">
-						<text class="label required">包装方式</text>
-						<view class="picker-box" @click="openPackagePicker">
-							<view class="picker-inner">
-								<view class="picker-val" :class="{placeholder: !formData.packageMethod}">
-									{{ formData.packageMethod || '请选择包装方式' }}
-								</view>
-								<view class="line-arrow-down"></view>
-							</view>
-						</view>
-					</view>
-				</view>
-
-				<!-- 模块 4:壁厚 -->
-				<view class="section-card">
-					<view class="section-header">
-						<view class="blue-bar"></view>
-						<text class="section-title">壁厚</text>
-					</view>
-					<view class="row-flex">
-						<view class="half-item">
-							<text class="label required">长度</text>
-							<view class="input-wrap">
-								<input class="input-box" type="digit" v-model="formData.length" placeholder="请输入" />
-								<text class="unit">mm</text>
-							</view>
-						</view>
-						<view class="half-item">
-							<text class="label required">壁厚</text>
-							<view class="input-wrap">
-								<input class="input-box" type="digit" v-model="formData.wallThickness" placeholder="请输入" />
-								<text class="unit">mm</text>
-							</view>
-						</view>
-					</view>
-				</view>
-
-				<!-- 模块 5:数量 -->
-				<view class="section-card">
-					<view class="section-header">
-						<view class="blue-bar"></view>
-						<text class="section-title">数量</text>
-					</view>
-					<view class="form-item no-margin-bottom">
-						<text class="label required">支数</text>
-						<input class="input-box full-width" type="number" v-model="formData.count" placeholder="请输入支付支数" />
-					</view>
-				</view>
-
-				<view class="bottom-placeholder"></view>
-			</view>
-		</scroll-view>
-
-		<view class="fixed-submit-bar">
-			<button class="submit-btn" @click="confirmAddModel">确认并添加</button>
-		</view>
-
-		<!-- 型号选择 -->
-		<view class="custom-picker-mask" v-if="showTypePicker" @click="closeTypePicker" @touchmove.stop.prevent>
-			<view class="picker-popup" @click.stop>
-				<view class="popup-header">
-					<text class="cancel-text" @click="closeTypePicker">取消</text>
-					<text class="popup-title">选择产品型号</text>
-					<text class="confirm-text" @click="confirmTypeSelect">确定</text>
-				</view>
-				<scroll-view scroll-y class="item-list">
-					<view class="option-item" v-for="(item, index) in typeList" :key="index" 
-						:class="{active: tempSelectedIndex === index}" @click="selectTypeItem(index)">
-						<text>{{item}}</text>
-						<icon type="success_no_circle" size="16" color="#C1001C" v-if="tempSelectedIndex === index"></icon>
-					</view>
-				</scroll-view>
-			</view>
-		</view>
-
-		<!-- 表面处理选择 -->
-		<view class="custom-picker-mask" v-if="showSurfacePicker" @click="closeSurfacePicker" @touchmove.stop.prevent>
-			<view class="picker-popup" @click.stop>
-				<view class="popup-header">
-					<text class="cancel-text" @click="closeSurfacePicker">取消</text>
-					<text class="popup-title">选择表面处理</text>
-					<text class="confirm-text" @click="confirmSurfaceSelect">确定</text>
-				</view>
-				<scroll-view scroll-y class="item-list">
-					<view class="option-item" v-for="(item, index) in surfaceList" :key="index" 
-						:class="{active: tempSurfaceIndex === index}" @click="selectSurfaceItem(index)">
-						<text>{{item}}</text>
-						<icon type="success_no_circle" size="16" color="#C1001C" v-if="tempSurfaceIndex === index"></icon>
-					</view>
-				</scroll-view>
-			</view>
-		</view>
-
-		<!-- 包装方式选择 -->
-		<view class="custom-picker-mask" v-if="showPackagePicker" @click="closePackagePicker" @touchmove.stop.prevent>
-			<view class="picker-popup" @click.stop>
-				<view class="popup-header">
-					<text class="cancel-text" @click="closePackagePicker">取消</text>
-					<text class="popup-title">选择包装方式</text>
-					<text class="confirm-text" @click="confirmPackageSelect">确定</text>
-				</view>
-				<scroll-view scroll-y class="item-list">
-					<view class="option-item" v-for="(item, index) in packageList" :key="index" 
-						:class="{active: tempPackageIndex === index}" @click="selectPackageItem(index)">
-						<text>{{item}}</text>
-						<icon type="success_no_circle" size="16" color="#C1001C" v-if="tempPackageIndex === index"></icon>
-					</view>
-				</scroll-view>
-			</view>
-		</view>
-
-	</view>
-</template>
-
-<script>
-	export default {
-		data() {
-			return {
-				showTypePicker: false, showSurfacePicker: false, showPackagePicker: false,
-				tempSelectedIndex: -1, tempSurfaceIndex: -1, tempPackageIndex: -1,
-				typeList: ['TY0018', 'TY0019', 'TY0020', 'TY0021', 'TY0022', 'TY0023', 'TY0024', 'TY0025', 'TY0026', 'TY0027', 'TY0028'],
-				surfaceList: ['PL坯料', '阳极氧化', '电泳涂漆', '粉末喷涂', '氟碳喷涂', '木纹转印'],
-				packageList: ['不贴膜+3点捆扎', '贴膜+纸箱', '气泡膜包装', '简易编织袋', '木托架包装'],
-				formData: {
-					type: '', name: '', material: '',
-					surfaceName: '', packageMethod: '', length: '',
-					wallThickness: '', count: ''
-				}
-			}
-		},
-		methods: {
-			openTypePicker() { if (this.formData.type) this.tempSelectedIndex = this.typeList.indexOf(this.formData.type); this.showTypePicker = true; },
-			closeTypePicker() { this.showTypePicker = false; },
-			selectTypeItem(index) { this.tempSelectedIndex = index; },
-			confirmTypeSelect() { if (this.tempSelectedIndex === -1) return; const val = this.typeList[this.tempSelectedIndex]; this.formData.type = val; this.formData.name = '工业铝材'; this.formData.material = (this.tempSelectedIndex % 2 === 0) ? '6063-T5' : '6061-T6'; this.closeTypePicker(); },
-			openSurfacePicker() { if (this.formData.surfaceName) this.tempSurfaceIndex = this.surfaceList.indexOf(this.formData.surfaceName); this.showSurfacePicker = true; },
-			closeSurfacePicker() { this.showSurfacePicker = false; },
-			selectSurfaceItem(index) { this.tempSurfaceIndex = index; },
-			confirmSurfaceSelect() { if (this.tempSurfaceIndex === -1) return; this.formData.surfaceName = this.surfaceList[this.tempSurfaceIndex]; this.closeSurfacePicker(); },
-			openPackagePicker() { if (this.formData.packageMethod) this.tempPackageIndex = this.packageList.indexOf(this.formData.packageMethod); this.showPackagePicker = true; },
-			closePackagePicker() { this.showPackagePicker = false; },
-			selectPackageItem(index) { this.tempPackageIndex = index; },
-			confirmPackageSelect() { if (this.tempPackageIndex === -1) return; this.formData.packageMethod = this.packageList[this.tempPackageIndex]; this.closePackagePicker(); },
-			confirmAddModel() {
-				const fields = [
-					{ key: 'type', label: '型号' },
-					{ key: 'surfaceName', label: '表面名称' },
-					{ key: 'packageMethod', label: '包装方式' },
-					{ key: 'length', label: '长度' },
-					{ key: 'wallThickness', label: '壁厚' },
-					{ key: 'count', label: '支数' }
-				];
-				for (let item of fields) {
-					if (!this.formData[item.key]) {
-						uni.showToast({ title: `请完善项目:${item.label}`, icon: 'none' });
-						return;
-					}
-				}
-				uni.$emit('add_order_item', JSON.parse(JSON.stringify(this.formData)));
-				uni.navigateBack();
-			}
-		}
-	}
-</script>
-
-<style scoped>
-	/deep/ ::-webkit-scrollbar { display: none !important; width: 0 !important; height: 0 !important; }
-	.order-container { width: 100%; height: 100vh; background: #f7f8fa; display: flex; flex-direction: column; overflow: hidden; }
-	.order-scroll { flex: 1; height: 0; }
-	.form-content { 
-		padding: 30rpx; 
-		padding-bottom: calc(180rpx + env(safe-area-inset-bottom)); 
-	}
-	.section-card { background: #fff; border-radius: 24rpx; padding: 30rpx; margin-bottom: 30rpx; box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.02); }
-	.section-header { display: flex; align-items: center; margin-bottom: 40rpx; }
-	.blue-bar { width: 8rpx; height: 32rpx; background: #C1001C; border-radius: 4rpx; margin-right: 16rpx; }
-	.section-title { font-size: 32rpx; font-weight: bold; color: #333; }
-	.form-item { margin-bottom: 40rpx; }
-	.no-margin-bottom { margin-bottom: 0; }
-	.row-flex { display: flex; justify-content: space-between; }
-	.half-item { width: 48%; }
-	.label { font-size: 28rpx; color: #333; margin-bottom: 20rpx; display: block; font-weight: 500; }
-	.label.required::after { content: ' *'; color: #ff4d4f; font-weight: bold; margin-left: 4rpx; }
-	.picker-box { background: #f9fafc; border-radius: 12rpx; height: 100rpx; border: 1rpx solid #eee; display: flex; align-items: center; }
-	.picker-inner { width: 100%; height: 100%; display: flex; align-items: center; justify-content: space-between; padding: 0 30rpx; box-sizing: border-box; }
-	.picker-val { font-size: 30rpx; color: #333; }
-	.picker-val.placeholder { color: #ccc; font-size: 28rpx; }
-	.line-arrow-down { width: 14rpx; height: 14rpx; border-right: 3rpx solid #bbb; border-bottom: 3rpx solid #bbb; transform: rotate(45deg); margin-top: -8rpx; margin-right: 4rpx; }
-	.input-wrap { position: relative; width: 100%; }
-	.input-box { font-size: 30rpx; color: #333; width: 100%; height: 100rpx; background: #f9fafc; border-radius: 12rpx; padding: 0 80rpx 0 30rpx; box-sizing: border-box; border: 1rpx solid #eee; }
-	.input-box.readonly { background: #f8f9fa; color: #666; border-color: #f0f0f0; }
-	.input-box.full-width { padding: 0 30rpx; }
-	.unit { position: absolute; right: 24rpx; top: 50%; transform: translateY(-50%); font-size: 26rpx; color: #999; font-weight: 500; }
-	.small-font { font-size: 26rpx !important; }
-	
-	.fixed-submit-bar { 
-		position: fixed; 
-		bottom: 0; 
-		left: 0; 
-		width: 100%; 
-		background: #fff; 
-		padding: 20rpx 30rpx calc(env(safe-area-inset-bottom) + 20rpx); 
-		box-sizing: border-box; 
-		box-shadow: 0 -10rpx 30rpx rgba(0,0,0,0.05);
-		z-index: 100;
-	}
-	.submit-btn { 
-		background: #C1001C; 
-		color: #fff; 
-		height: 100rpx; 
-		border-radius: 50rpx; 
-		display: flex; 
-		align-items: center; 
-		justify-content: center; 
-		font-size: 34rpx; 
-		font-weight: bold; 
-		border: none; 
-	}
-	.submit-btn:active { opacity: 0.9; transform: scale(0.98); }
-	.custom-picker-mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.4); z-index: 1000; display: flex; align-items: flex-end; }
-	.picker-popup { width: 100%; background: #fff; border-radius: 32rpx 32rpx 0 0; padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx); animation: slideUp 0.15s ease-out; }
-	@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
-	.popup-header { display: flex; justify-content: space-between; align-items: center; padding: 30rpx 40rpx; border-bottom: 1rpx solid #f0f0f0; }
-	.popup-title { font-size: 32rpx; font-weight: bold; color: #333; }
-	.cancel-text, .confirm-text { font-size: 30rpx; padding: 10rpx; }
-	.confirm-text { color: #C1001C; font-weight: bold; }
-	.item-list { max-height: 50vh; padding: 0 40rpx; }
-	.option-item { height: 110rpx; display: flex; align-items: center; justify-content: space-between; border-bottom: 1rpx solid #f8f8f8; font-size: 32rpx; color: #333; }
-	.option-item.active { color: #C1001C; font-weight: bold; }
-	.bottom-placeholder { height: 60rpx; }
-</style>

+ 511 - 0
pages/order/add_model/index.vue

@@ -0,0 +1,511 @@
+<template>
+	<view class="order-container">
+		<scroll-view :scroll-y="!showTypePicker && !showSurfacePicker && !showPackagePicker" class="order-scroll"
+			:show-scrollbar="false" :enhanced="true">
+			<view class="form-content">
+
+				<!-- 模块 1:型材 -->
+				<view class="section-card">
+					<view class="section-header">
+						<view class="blue-bar"></view>
+						<text class="section-title">型材</text>
+					</view>
+					<view class="form-item">
+						<text class="label required">型号</text>
+						<view class="picker-box" @click="openTypePicker">
+							<view class="picker-inner">
+								<view class="picker-val" :class="{ placeholder: !formData.type }">
+									{{ formData.type || '请选择型号' }}
+								</view>
+								<view class="line-arrow-down"></view>
+							</view>
+						</view>
+					</view>
+					<view class="row-flex">
+						<view class="half-item">
+							<text class="label">名称</text>
+							<input class="input-box readonly small-font" v-model="formData.name" disabled
+								placeholder="型号名称" />
+						</view>
+						<view class="half-item">
+							<text class="label">材质</text>
+							<input class="input-box readonly small-font" v-model="formData.material" disabled
+								placeholder="材质" />
+						</view>
+					</view>
+				</view>
+
+				<!-- 模块 2:表面处理 -->
+				<view class="section-card">
+					<view class="section-header">
+						<view class="blue-bar"></view>
+						<text class="section-title">表面处理</text>
+					</view>
+					<view class="form-item">
+						<text class="label required">表面名称</text>
+						<view class="picker-box" @click="openSurfacePicker">
+							<view class="picker-inner">
+								<view class="picker-val" :class="{ placeholder: !formData.surfaceName }">
+									{{ formData.surfaceName || '请选择表面名称' }}
+								</view>
+								<view class="line-arrow-down"></view>
+							</view>
+						</view>
+					</view>
+				</view>
+
+				<!-- 模块 3:包装 -->
+				<view class="section-card">
+					<view class="section-header">
+						<view class="blue-bar"></view>
+						<text class="section-title">包装</text>
+					</view>
+					<view class="form-item">
+						<text class="label required">包装方式</text>
+						<view class="picker-box" @click="openPackagePicker">
+							<view class="picker-inner">
+								<view class="picker-val" :class="{ placeholder: !formData.packageMethod }">
+									{{ formData.packageMethod || '请选择包装方式' }}
+								</view>
+								<view class="line-arrow-down"></view>
+							</view>
+						</view>
+					</view>
+				</view>
+
+				<!-- 模块 4:壁厚 -->
+				<view class="section-card">
+					<view class="section-header">
+						<view class="blue-bar"></view>
+						<text class="section-title">壁厚</text>
+					</view>
+					<view class="row-flex">
+						<view class="half-item">
+							<text class="label required">长度</text>
+							<view class="input-wrap">
+								<input class="input-box" type="digit" v-model="formData.length" placeholder="请输入" />
+								<text class="unit">mm</text>
+							</view>
+						</view>
+						<view class="half-item">
+							<text class="label required">壁厚</text>
+							<view class="input-wrap">
+								<input class="input-box" type="digit" v-model="formData.wallThickness"
+									placeholder="请输入" />
+								<text class="unit">mm</text>
+							</view>
+						</view>
+					</view>
+				</view>
+
+				<!-- 模块 5:数量 -->
+				<view class="section-card">
+					<view class="section-header">
+						<view class="blue-bar"></view>
+						<text class="section-title">数量</text>
+					</view>
+					<view class="form-item no-margin-bottom">
+						<text class="label required">支数</text>
+						<input class="input-box full-width" type="number" v-model="formData.count"
+							placeholder="请输入支付支数" />
+					</view>
+				</view>
+
+				<view class="bottom-placeholder"></view>
+			</view>
+		</scroll-view>
+
+		<view class="fixed-submit-bar">
+			<button class="submit-btn" @click="confirmAddModel">确认并添加</button>
+		</view>
+
+		<!-- 型号选择 -->
+		<view class="custom-picker-mask" v-if="showTypePicker" @click="closeTypePicker" @touchmove.stop.prevent>
+			<view class="picker-popup" @click.stop>
+				<view class="popup-header">
+					<text class="cancel-text" @click="closeTypePicker">取消</text>
+					<text class="popup-title">选择产品型号</text>
+					<text class="confirm-text" @click="confirmTypeSelect">确定</text>
+				</view>
+				<scroll-view scroll-y class="item-list">
+					<view class="option-item" v-for="(item, index) in typeList" :key="index"
+						:class="{ active: tempSelectedIndex === index }" @click="selectTypeItem(index)">
+						<text>{{ item }}</text>
+						<icon type="success_no_circle" size="16" color="#C1001C" v-if="tempSelectedIndex === index">
+						</icon>
+					</view>
+				</scroll-view>
+			</view>
+		</view>
+
+		<!-- 表面处理选择 -->
+		<view class="custom-picker-mask" v-if="showSurfacePicker" @click="closeSurfacePicker" @touchmove.stop.prevent>
+			<view class="picker-popup" @click.stop>
+				<view class="popup-header">
+					<text class="cancel-text" @click="closeSurfacePicker">取消</text>
+					<text class="popup-title">选择表面处理</text>
+					<text class="confirm-text" @click="confirmSurfaceSelect">确定</text>
+				</view>
+				<scroll-view scroll-y class="item-list">
+					<view class="option-item" v-for="(item, index) in surfaceList" :key="index"
+						:class="{ active: tempSurfaceIndex === index }" @click="selectSurfaceItem(index)">
+						<text>{{ item }}</text>
+						<icon type="success_no_circle" size="16" color="#C1001C" v-if="tempSurfaceIndex === index">
+						</icon>
+					</view>
+				</scroll-view>
+			</view>
+		</view>
+
+		<!-- 包装方式选择 -->
+		<view class="custom-picker-mask" v-if="showPackagePicker" @click="closePackagePicker" @touchmove.stop.prevent>
+			<view class="picker-popup" @click.stop>
+				<view class="popup-header">
+					<text class="cancel-text" @click="closePackagePicker">取消</text>
+					<text class="popup-title">选择包装方式</text>
+					<text class="confirm-text" @click="confirmPackageSelect">确定</text>
+				</view>
+				<scroll-view scroll-y class="item-list">
+					<view class="option-item" v-for="(item, index) in packageList" :key="index"
+						:class="{ active: tempPackageIndex === index }" @click="selectPackageItem(index)">
+						<text>{{ item }}</text>
+						<icon type="success_no_circle" size="16" color="#C1001C" v-if="tempPackageIndex === index">
+						</icon>
+					</view>
+				</scroll-view>
+			</view>
+		</view>
+
+	</view>
+</template>
+
+<script>
+import typeList from '@/mock/type-list.json';
+import surfaceList from '@/json/surface-list.json';
+import packageList from '@/json/package-list.json';
+
+export default {
+	data() {
+		return {
+			showTypePicker: false, showSurfacePicker: false, showPackagePicker: false,
+			tempSelectedIndex: -1, tempSurfaceIndex: -1, tempPackageIndex: -1,
+			typeList,
+			surfaceList,
+			packageList,
+			formData: {
+				type: '', name: '', material: '',
+				surfaceName: '', packageMethod: '', length: '',
+				wallThickness: '', count: ''
+			}
+		}
+	},
+	methods: {
+		openTypePicker() { if (this.formData.type) this.tempSelectedIndex = this.typeList.indexOf(this.formData.type); this.showTypePicker = true; },
+		closeTypePicker() { this.showTypePicker = false; },
+		selectTypeItem(index) { this.tempSelectedIndex = index; },
+		confirmTypeSelect() { if (this.tempSelectedIndex === -1) return; const val = this.typeList[this.tempSelectedIndex]; this.formData.type = val; this.formData.name = '工业铝材'; this.formData.material = (this.tempSelectedIndex % 2 === 0) ? '6063-T5' : '6061-T6'; this.closeTypePicker(); },
+		openSurfacePicker() { if (this.formData.surfaceName) this.tempSurfaceIndex = this.surfaceList.indexOf(this.formData.surfaceName); this.showSurfacePicker = true; },
+		closeSurfacePicker() { this.showSurfacePicker = false; },
+		selectSurfaceItem(index) { this.tempSurfaceIndex = index; },
+		confirmSurfaceSelect() { if (this.tempSurfaceIndex === -1) return; this.formData.surfaceName = this.surfaceList[this.tempSurfaceIndex]; this.closeSurfacePicker(); },
+		openPackagePicker() { if (this.formData.packageMethod) this.tempPackageIndex = this.packageList.indexOf(this.formData.packageMethod); this.showPackagePicker = true; },
+		closePackagePicker() { this.showPackagePicker = false; },
+		selectPackageItem(index) { this.tempPackageIndex = index; },
+		confirmPackageSelect() { if (this.tempPackageIndex === -1) return; this.formData.packageMethod = this.packageList[this.tempPackageIndex]; this.closePackagePicker(); },
+		confirmAddModel() {
+			const fields = [
+				{ key: 'type', label: '型号' },
+				{ key: 'surfaceName', label: '表面名称' },
+				{ key: 'packageMethod', label: '包装方式' },
+				{ key: 'length', label: '长度' },
+				{ key: 'wallThickness', label: '壁厚' },
+				{ key: 'count', label: '支数' }
+			];
+			for (let item of fields) {
+				if (!this.formData[item.key]) {
+					uni.showToast({ title: `请完善项目:${item.label}`, icon: 'none' });
+					return;
+				}
+			}
+			uni.$emit('add_order_item', JSON.parse(JSON.stringify(this.formData)));
+			uni.navigateBack();
+		}
+	}
+}
+</script>
+
+<style scoped>
+/deep/ ::-webkit-scrollbar {
+	display: none !important;
+	width: 0 !important;
+	height: 0 !important;
+}
+
+.order-container {
+	width: 100%;
+	height: 100vh;
+	background: #f7f8fa;
+	display: flex;
+	flex-direction: column;
+	overflow: hidden;
+}
+
+.order-scroll {
+	flex: 1;
+	height: 0;
+}
+
+.form-content {
+	padding: 30rpx;
+	padding-bottom: calc(180rpx + env(safe-area-inset-bottom));
+}
+
+.section-card {
+	background: #fff;
+	border-radius: 24rpx;
+	padding: 30rpx;
+	margin-bottom: 30rpx;
+	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.02);
+}
+
+.section-header {
+	display: flex;
+	align-items: center;
+	margin-bottom: 40rpx;
+}
+
+.blue-bar {
+	width: 8rpx;
+	height: 32rpx;
+	background: #C1001C;
+	border-radius: 4rpx;
+	margin-right: 16rpx;
+}
+
+.section-title {
+	font-size: 32rpx;
+	font-weight: bold;
+	color: #333;
+}
+
+.form-item {
+	margin-bottom: 40rpx;
+}
+
+.no-margin-bottom {
+	margin-bottom: 0;
+}
+
+.row-flex {
+	display: flex;
+	justify-content: space-between;
+}
+
+.half-item {
+	width: 48%;
+}
+
+.label {
+	font-size: 28rpx;
+	color: #333;
+	margin-bottom: 20rpx;
+	display: block;
+	font-weight: 500;
+}
+
+.label.required::after {
+	content: ' *';
+	color: #ff4d4f;
+	font-weight: bold;
+	margin-left: 4rpx;
+}
+
+.picker-box {
+	background: #f9fafc;
+	border-radius: 12rpx;
+	height: 100rpx;
+	border: 1rpx solid #eee;
+	display: flex;
+	align-items: center;
+}
+
+.picker-inner {
+	width: 100%;
+	height: 100%;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	padding: 0 30rpx;
+	box-sizing: border-box;
+}
+
+.picker-val {
+	font-size: 30rpx;
+	color: #333;
+}
+
+.picker-val.placeholder {
+	color: #ccc;
+	font-size: 28rpx;
+}
+
+.line-arrow-down {
+	width: 14rpx;
+	height: 14rpx;
+	border-right: 3rpx solid #bbb;
+	border-bottom: 3rpx solid #bbb;
+	transform: rotate(45deg);
+	margin-top: -8rpx;
+	margin-right: 4rpx;
+}
+
+.input-wrap {
+	position: relative;
+	width: 100%;
+}
+
+.input-box {
+	font-size: 30rpx;
+	color: #333;
+	width: 100%;
+	height: 100rpx;
+	background: #f9fafc;
+	border-radius: 12rpx;
+	padding: 0 80rpx 0 30rpx;
+	box-sizing: border-box;
+	border: 1rpx solid #eee;
+}
+
+.input-box.readonly {
+	background: #f8f9fa;
+	color: #666;
+	border-color: #f0f0f0;
+}
+
+.input-box.full-width {
+	padding: 0 30rpx;
+}
+
+.unit {
+	position: absolute;
+	right: 24rpx;
+	top: 50%;
+	transform: translateY(-50%);
+	font-size: 26rpx;
+	color: #999;
+	font-weight: 500;
+}
+
+.small-font {
+	font-size: 26rpx !important;
+}
+
+.fixed-submit-bar {
+	position: fixed;
+	bottom: 0;
+	left: 0;
+	width: 100%;
+	background: #fff;
+	padding: 20rpx 30rpx calc(env(safe-area-inset-bottom) + 20rpx);
+	box-sizing: border-box;
+	box-shadow: 0 -10rpx 30rpx rgba(0, 0, 0, 0.05);
+	z-index: 100;
+}
+
+.submit-btn {
+	background: #C1001C;
+	color: #fff;
+	height: 100rpx;
+	border-radius: 50rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 34rpx;
+	font-weight: bold;
+	border: none;
+}
+
+.submit-btn:active {
+	opacity: 0.9;
+	transform: scale(0.98);
+}
+
+.custom-picker-mask {
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	background: rgba(0, 0, 0, 0.4);
+	z-index: 1000;
+	display: flex;
+	align-items: flex-end;
+}
+
+.picker-popup {
+	width: 100%;
+	background: #fff;
+	border-radius: 32rpx 32rpx 0 0;
+	padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx);
+	animation: slideUp 0.15s ease-out;
+}
+
+@keyframes slideUp {
+	from {
+		transform: translateY(100%);
+	}
+
+	to {
+		transform: translateY(0);
+	}
+}
+
+.popup-header {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding: 30rpx 40rpx;
+	border-bottom: 1rpx solid #f0f0f0;
+}
+
+.popup-title {
+	font-size: 32rpx;
+	font-weight: bold;
+	color: #333;
+}
+
+.cancel-text,
+.confirm-text {
+	font-size: 30rpx;
+	padding: 10rpx;
+}
+
+.confirm-text {
+	color: #C1001C;
+	font-weight: bold;
+}
+
+.item-list {
+	max-height: 50vh;
+	padding: 0 40rpx;
+}
+
+.option-item {
+	height: 110rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	border-bottom: 1rpx solid #f8f8f8;
+	font-size: 32rpx;
+	color: #333;
+}
+
+.option-item.active {
+	color: #C1001C;
+	font-weight: bold;
+}
+
+.bottom-placeholder {
+	height: 60rpx;
+}
+</style>

+ 0 - 215
pages/order/detail.vue

@@ -1,215 +0,0 @@
-<template>
-	<view class="detail-page-container">
-		<!-- 1. 顶部自定义导航栏:白色背景 + 黑色文字 -->
-		<view class="white-nav-section" :style="{ paddingTop: statusBarHeight + 'px' }">
-			<view class="custom-nav-bar">
-				<view class="back-icon" @click="goBack">
-					<view class="arrow-left"></view>
-				</view>
-				<text class="nav-title">订单详情</text>
-				<view class="placeholder-right"></view>
-			</view>
-		</view>
-
-		<!-- 2. 状态横幅区域:不再包含状态栏边距 -->
-		<view class="status-banner-container" :class="order.statusType" id="nav-header">
-			<view class="status-banner-content">
-				<view class="header-main">
-					<text class="status-title">{{order.statusName}}</text>
-					<text class="status-sub">{{statusSubText}}</text>
-				</view>
-				<view class="header-icon-wrap">
-					<view class="status-visual-icon"></view>
-				</view>
-			</view>
-		</view>
-
-		<!-- 2. 主内容滚动区:计算锁定高度以支持 100% 滚动 -->
-		<scroll-view scroll-y class="main-content-scroll" :style="{ height: scrollHeight }" :show-scrollbar="false">
-			<view class="detail-inner-box">
-				<!-- 卡片:规格清单 (支持多个型号展现) -->
-				<view class="model-item-card-inner" v-for="(model, mIdx) in (order.models || [order])" :key="mIdx">
-					<view class="data-group-card" :class="{'first-card': mIdx === 0}">
-						<view class="card-head">规格清单 #{{mIdx + 1}}</view>
-						<view class="data-item"><text class="l">产品型号</text><text class="v bold">{{model.type}}</text></view>
-						<view class="data-item"><text class="l">型号名称</text><text class="v">{{model.typeName || '铝型材主料'}}</text></view>
-						<view class="data-item"><text class="l">型材材质</text><text class="v">{{model.material || '6063-T5'}}</text></view>
-						<view class="line-split"></view>
-						<view class="data-item"><text class="l">表面处理</text><text class="v">{{model.surface}}</text></view>
-						<view class="data-item"><text class="l">包装方式</text><text class="v">{{model.package || '普通包装'}}</text></view>
-						<view class="line-split"></view>
-						<view class="data-item"><text class="l">订单长度</text><text class="v">{{model.length}} mm</text></view>
-						<view class="data-item"><text class="l">型材壁厚</text><text class="v">{{model.wallThickness || '1.2'}} mm</text></view>
-						<view class="data-item"><text class="l">需求支数</text><text class="v highlight">{{model.count}} 支</text></view>
-					</view>
-				</view>
-
-				<!-- 卡片:订单详情 -->
-				<view class="data-group-card shadow-less">
-					<view class="card-head">订单详情</view>
-					<view class="data-item"><text class="l">订单单号</text><text class="v selectable">{{order.orderNo}}</text></view>
-					<!-- 新增:ERP单号 (特定状态下显示) -->
-					<view class="data-item" v-if="[2, 3, 4].includes(order.status)">
-						<text class="l">ERP 单号</text>
-						<text class="v selectable erp-no">{{order.erpNo || 'ERP' + order.orderNo.slice(-8)}}</text>
-					</view>
-					<view class="data-item"><text class="l">下单日期</text><text class="v">{{order.time}}</text></view>
-					<view class="data-item"><text class="l">支付方式</text><text class="v">月结扣款</text></view>
-				</view>
-				
-				<!-- 底部占位 -->
-				<view class="list-bottom-placeholder"></view>
-			</view>
-		</scroll-view>
-
-		<!-- 3. 底部固定操作栏 -->
-		<view class="detail-action-bar-fixed" id="footer-bar">
-			<view class="action-btn-wrap" v-if="order.status === 1">
-				<button class="action-btn cancel" @click="doCancel">撤销该订单</button>
-				<button class="action-btn primary" @click="callSales">呼叫业务员</button>
-			</view>
-			<view class="action-btn-wrap single" v-else>
-				<button class="action-btn primary" @click="goHome">再下一单</button>
-			</view>
-			<view class="safe-area-bottom-support"></view>
-		</view>
-	</view>
-</template>
-
-<script>
-	export default {
-		data() {
-			return {
-				statusBarHeight: 20,
-				footerHeight: 80, // px
-				headerHeight: 120, // px
-				order: {
-					orderNo: '-',
-					status: 1,
-					statusName: '加载中',
-					statusType: 'pending',
-					models: [],
-					erpNo: '',
-					time: '-'
-				}
-			}
-		},
-		computed: {
-			statusSubText() {
-				const map = {
-					pending: '您的订单已提交,正在排队等待审核...',
-					process: '审核已完成,正在由相关主管签批...',
-					making: '订单已入库排产,工厂正在全力生产中...',
-					finish: '该订单生产已完成并正式入库。',
-					expired: '该订单已由客户主动撤销。'
-				};
-				return map[this.order.statusType] || '订单状态更新中';
-			},
-			scrollHeight() {
-				// 获取系统安全区域
-				const info = uni.getSystemInfoSync();
-				const safeBottom = info.safeAreaInsets ? info.safeAreaInsets.bottom : 0;
-				// 动态计算滚动区高度:屏幕总高 - 顶部高(状态栏+导航栏+横幅) - 底部固定栏(内含安全区)
-				// 顶部高度估算:statusBarHeight + 44(nav) + 120(banner)
-				return `calc(100vh - ${this.statusBarHeight + 164}px - ${80 + safeBottom}px)`;
-			}
-		},
-		onLoad(options) {
-			const info = uni.getSystemInfoSync();
-			this.statusBarHeight = info.statusBarHeight;
-			
-			if (options.data) {
-				try {
-					this.order = JSON.parse(decodeURIComponent(options.data));
-				} catch(e) { console.error('Data Error'); }
-			}
-		},
-		methods: {
-			goBack() { uni.navigateBack(); },
-			doCancel() {
-				uni.showModal({
-					title: '确认撤销',
-					content: '订单撤销后将流转至已撤销状态,确定吗?',
-					confirmColor: '#ff3b30',
-					success: (res) => {
-						if (res.confirm) {
-							this.order.status = 0;
-							this.order.statusName = '已撤销';
-							this.order.statusType = 'expired';
-							uni.showToast({ title: '撤销成功' });
-						}
-					}
-				});
-			},
-			callSales() { uni.makePhoneCall({ phoneNumber: '13888888888' }); },
-			goHome() { uni.reLaunch({ url: '/pages/order/order' }); }
-		}
-	}
-</script>
-
-<style scoped>
-	/deep/ ::-webkit-scrollbar { display: none !important; width: 0 !important; height: 0 !important; -webkit-appearance: none; background: transparent; }
-	.detail-page-container { width: 100vw; height: 100vh; background: #f8fbfd; display: flex; flex-direction: column; overflow: hidden; position: relative; }
-
-	.white-nav-section { background: #fff; width: 100%; flex-shrink: 0; }
-	.custom-nav-bar { height: 44px; display: flex; align-items: center; justify-content: space-between; padding: 0 30rpx; }
-	.back-icon { width: 60rpx; height: 44px; display: flex; align-items: center; }
-	.arrow-left { width: 20rpx; height: 20rpx; border-left: 4rpx solid #333; border-bottom: 4rpx solid #333; transform: rotate(45deg); margin-left: 10rpx; }
-	.nav-title { font-size: 34rpx; font-weight: bold; color: #1a1a1a; }
-	.placeholder-right { width: 60rpx; }
-
-	.status-banner-container { color: #fff; flex-shrink: 0; }
-	.status-banner-container.pending { background: linear-gradient(135deg, #C1001C 0%, #FF4D4F 100%); }
-	.status-banner-container.process { background: linear-gradient(135deg, #FF6A00 0%, #EE0979 100%); }
-	.status-banner-container.making { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
-	.status-banner-container.finish { background: linear-gradient(135deg, #2af598 0%, #009efd 100%); }
-	.status-banner-container.expired { background: linear-gradient(135deg, #868f96 0%, #596164 100%); }
-
-	/* 状态横幅内容 */
-	.status-banner-content { padding: 40rpx; padding-bottom: 60rpx; display: flex; justify-content: space-between; align-items: center; }
-	.header-main { flex: 1; }
-	.status-title { font-size: 48rpx; font-weight: bold; display: block; margin-bottom: 12rpx; }
-	.status-sub { font-size: 26rpx; opacity: 0.9; }
-	.status-visual-icon { width: 60rpx; height: 60rpx; border: 4rpx solid rgba(255,255,255,0.3); border-radius: 50%; opacity: 0.6; }
-
-	/* 修正:移除负边距,并明确滚动方向 */
-	.main-content-scroll { width: 100%; flex: 1; }
-	.detail-inner-box { padding: 30rpx; padding-top: 10rpx; }
-
-	.data-group-card { background: #fff; border-radius: 30rpx; padding: 40rpx; margin-bottom: 30rpx; box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.02); }
-	/* 第一张卡片增加顶部间隔(红框1优化点) */
-	.first-card { margin-top: 20rpx; }
-	
-	.card-head { font-size: 30rpx; font-weight: bold; color: #333; margin-bottom: 30rpx; border-left: 8rpx solid #C1001C; padding-left: 20rpx; }
-
-	.line-split { height: 1rpx; background: #f5f5f5; margin: 24rpx 0; }
-	.data-item { display: flex; justify-content: space-between; margin-bottom: 24rpx; font-size: 28rpx; align-items: center; }
-	.l { color: #999; }
-	.v { color: #333; font-weight: 500; }
-	.v.bold { font-weight: bold; font-size: 30rpx; }
-	.v.erp-no { color: #C1001C; font-weight: bold; }
-	.v.highlight { color: #ff3b30; font-weight: bold; font-size: 34rpx; }
-
-	.list-bottom-placeholder { height: 260rpx; }
-
-	.detail-action-bar-fixed { 
-		position: fixed; 
-		bottom: 0; 
-		left: 0; 
-		right: 0; 
-		background: #fff; 
-		padding: 30rpx 40rpx; 
-		box-shadow: 0 -10rpx 40rpx rgba(0,0,0,0.04); 
-		z-index: 999; 
-		flex-shrink: 0;
-	}
-	.action-btn-wrap { display: flex; gap: 24rpx; }
-	.action-btn { flex: 1; height: 96rpx; border-radius: 48rpx; display: flex; align-items: center; justify-content: center; font-size: 32rpx; font-weight: bold; }
-	.action-btn.primary { background: #C1001C; color: #fff; border: none; }
-	.action-btn.cancel { background: #fff1f0; color: #ff3b30; border: 1rpx solid #ffccc7; font-weight: normal; }
-	
-	.safe-area-bottom-support { 
-		height: constant(safe-area-inset-bottom); 
-		height: env(safe-area-inset-bottom); 
-	}
-</style>

+ 397 - 0
pages/order/detail/index.vue

@@ -0,0 +1,397 @@
+<template>
+	<view class="detail-page-container">
+		<!-- 1. 顶部自定义导航栏:白色背景 + 黑色文字 -->
+		<view class="white-nav-section" :style="{ paddingTop: statusBarHeight + 'px' }">
+			<view class="custom-nav-bar">
+				<view class="back-icon" @click="goBack">
+					<view class="arrow-left"></view>
+				</view>
+				<text class="nav-title">订单详情</text>
+				<view class="placeholder-right"></view>
+			</view>
+		</view>
+
+		<!-- 2. 状态横幅区域:不再包含状态栏边距 -->
+		<view class="status-banner-container" :class="order.statusType" id="nav-header">
+			<view class="status-banner-content">
+				<view class="header-main">
+					<text class="status-title">{{ order.statusName }}</text>
+					<text class="status-sub">{{ statusSubText }}</text>
+				</view>
+				<view class="header-icon-wrap">
+					<view class="status-visual-icon"></view>
+				</view>
+			</view>
+		</view>
+
+		<!-- 2. 主内容滚动区:计算锁定高度以支持 100% 滚动 -->
+		<scroll-view scroll-y class="main-content-scroll" :style="{ height: scrollHeight }" :show-scrollbar="false">
+			<view class="detail-inner-box">
+				<!-- 卡片:规格清单 (支持多个型号展现) -->
+				<view class="model-item-card-inner" v-for="(model, mIdx) in (order.models || [order])" :key="mIdx">
+					<view class="data-group-card" :class="{ 'first-card': mIdx === 0 }">
+						<view class="card-head">规格清单 #{{ mIdx + 1 }}</view>
+						<view class="data-item"><text class="l">产品型号</text><text class="v bold">{{ model.type }}</text>
+						</view>
+						<view class="data-item"><text class="l">型号名称</text><text class="v">{{ model.typeName ||
+								'铝型材主料'}}</text></view>
+						<view class="data-item"><text class="l">型材材质</text><text class="v">{{ model.material ||
+								'6063-T5'}}</text></view>
+						<view class="line-split"></view>
+						<view class="data-item"><text class="l">表面处理</text><text class="v">{{ model.surface }}</text>
+						</view>
+						<view class="data-item"><text class="l">包装方式</text><text class="v">{{ model.package ||
+								'普通包装'}}</text></view>
+						<view class="line-split"></view>
+						<view class="data-item"><text class="l">订单长度</text><text class="v">{{ model.length }} mm</text>
+						</view>
+						<view class="data-item"><text class="l">型材壁厚</text><text class="v">{{ model.wallThickness ||
+								'1.2'}} mm</text></view>
+						<view class="data-item"><text class="l">需求支数</text><text class="v highlight">{{ model.count }}
+								支</text></view>
+					</view>
+				</view>
+
+				<!-- 卡片:订单详情 -->
+				<view class="data-group-card shadow-less">
+					<view class="card-head">订单详情</view>
+					<view class="data-item"><text class="l">订单单号</text><text
+							class="v selectable">{{ order.orderNo }}</text></view>
+					<!-- 新增:ERP单号 (特定状态下显示) -->
+					<view class="data-item" v-if="[2, 3, 4].includes(order.status)">
+						<text class="l">ERP 单号</text>
+						<text class="v selectable erp-no">{{ order.erpNo || 'ERP' + order.orderNo.slice(-8) }}</text>
+					</view>
+					<view class="data-item"><text class="l">下单日期</text><text class="v">{{ order.time }}</text></view>
+					<view class="data-item"><text class="l">支付方式</text><text class="v">月结扣款</text></view>
+				</view>
+
+				<!-- 底部占位 -->
+				<view class="list-bottom-placeholder"></view>
+			</view>
+		</scroll-view>
+
+		<!-- 3. 底部固定操作栏 -->
+		<view class="detail-action-bar-fixed" id="footer-bar">
+			<view class="action-btn-wrap" v-if="order.status === 1">
+				<button class="action-btn cancel" @click="doCancel">撤销该订单</button>
+				<button class="action-btn primary" @click="callSales">呼叫业务员</button>
+			</view>
+			<view class="action-btn-wrap single" v-else>
+				<button class="action-btn primary" @click="goHome">再下一单</button>
+			</view>
+			<view class="safe-area-bottom-support"></view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			statusBarHeight: 20,
+			footerHeight: 80, // px
+			headerHeight: 120, // px
+			order: {
+				orderNo: '-',
+				status: 1,
+				statusName: '加载中',
+				statusType: 'pending',
+				models: [],
+				erpNo: '',
+				time: '-'
+			}
+		}
+	},
+	computed: {
+		statusSubText() {
+			const map = {
+				pending: '您的订单已提交,正在排队等待审核...',
+				process: '审核已完成,正在由相关主管签批...',
+				making: '订单已入库排产,工厂正在全力生产中...',
+				finish: '该订单生产已完成并正式入库。',
+				expired: '该订单已由客户主动撤销。'
+			};
+			return map[this.order.statusType] || '订单状态更新中';
+		},
+		scrollHeight() {
+			// 获取系统安全区域
+			const info = uni.getSystemInfoSync();
+			const safeBottom = info.safeAreaInsets ? info.safeAreaInsets.bottom : 0;
+			// 动态计算滚动区高度:屏幕总高 - 顶部高(状态栏+导航栏+横幅) - 底部固定栏(内含安全区)
+			// 顶部高度估算:statusBarHeight + 44(nav) + 120(banner)
+			return `calc(100vh - ${this.statusBarHeight + 164}px - ${80 + safeBottom}px)`;
+		}
+	},
+	onLoad(options) {
+		const info = uni.getSystemInfoSync();
+		this.statusBarHeight = info.statusBarHeight;
+
+		if (options.data) {
+			try {
+				this.order = JSON.parse(decodeURIComponent(options.data));
+			} catch (e) { console.error('Data Error'); }
+		}
+	},
+	methods: {
+		goBack() { uni.navigateBack(); },
+		doCancel() {
+			uni.showModal({
+				title: '确认撤销',
+				content: '订单撤销后将流转至已撤销状态,确定吗?',
+				confirmColor: '#ff3b30',
+				success: (res) => {
+					if (res.confirm) {
+						this.order.status = 0;
+						this.order.statusName = '已撤销';
+						this.order.statusType = 'expired';
+						uni.showToast({ title: '撤销成功' });
+					}
+				}
+			});
+		},
+		callSales() { uni.makePhoneCall({ phoneNumber: '13888888888' }); },
+		goHome() { uni.reLaunch({ url: '/pages/order/index' }); }
+	}
+}
+</script>
+
+<style scoped>
+/deep/ ::-webkit-scrollbar {
+	display: none !important;
+	width: 0 !important;
+	height: 0 !important;
+	-webkit-appearance: none;
+	background: transparent;
+}
+
+.detail-page-container {
+	width: 100vw;
+	height: 100vh;
+	background: #f8fbfd;
+	display: flex;
+	flex-direction: column;
+	overflow: hidden;
+	position: relative;
+}
+
+.white-nav-section {
+	background: #fff;
+	width: 100%;
+	flex-shrink: 0;
+}
+
+.custom-nav-bar {
+	height: 44px;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	padding: 0 30rpx;
+}
+
+.back-icon {
+	width: 60rpx;
+	height: 44px;
+	display: flex;
+	align-items: center;
+}
+
+.arrow-left {
+	width: 20rpx;
+	height: 20rpx;
+	border-left: 4rpx solid #333;
+	border-bottom: 4rpx solid #333;
+	transform: rotate(45deg);
+	margin-left: 10rpx;
+}
+
+.nav-title {
+	font-size: 34rpx;
+	font-weight: bold;
+	color: #1a1a1a;
+}
+
+.placeholder-right {
+	width: 60rpx;
+}
+
+.status-banner-container {
+	color: #fff;
+	flex-shrink: 0;
+}
+
+.status-banner-container.pending {
+	background: linear-gradient(135deg, #C1001C 0%, #FF4D4F 100%);
+}
+
+.status-banner-container.process {
+	background: linear-gradient(135deg, #FF6A00 0%, #EE0979 100%);
+}
+
+.status-banner-container.making {
+	background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+}
+
+.status-banner-container.finish {
+	background: linear-gradient(135deg, #2af598 0%, #009efd 100%);
+}
+
+.status-banner-container.expired {
+	background: linear-gradient(135deg, #868f96 0%, #596164 100%);
+}
+
+/* 状态横幅内容 */
+.status-banner-content {
+	padding: 40rpx;
+	padding-bottom: 60rpx;
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+}
+
+.header-main {
+	flex: 1;
+}
+
+.status-title {
+	font-size: 48rpx;
+	font-weight: bold;
+	display: block;
+	margin-bottom: 12rpx;
+}
+
+.status-sub {
+	font-size: 26rpx;
+	opacity: 0.9;
+}
+
+.status-visual-icon {
+	width: 60rpx;
+	height: 60rpx;
+	border: 4rpx solid rgba(255, 255, 255, 0.3);
+	border-radius: 50%;
+	opacity: 0.6;
+}
+
+/* 修正:移除负边距,并明确滚动方向 */
+.main-content-scroll {
+	width: 100%;
+	flex: 1;
+}
+
+.detail-inner-box {
+	padding: 30rpx;
+	padding-top: 10rpx;
+}
+
+.data-group-card {
+	background: #fff;
+	border-radius: 30rpx;
+	padding: 40rpx;
+	margin-bottom: 30rpx;
+	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.02);
+}
+
+/* 第一张卡片增加顶部间隔(红框1优化点) */
+.first-card {
+	margin-top: 20rpx;
+}
+
+.card-head {
+	font-size: 30rpx;
+	font-weight: bold;
+	color: #333;
+	margin-bottom: 30rpx;
+	border-left: 8rpx solid #C1001C;
+	padding-left: 20rpx;
+}
+
+.line-split {
+	height: 1rpx;
+	background: #f5f5f5;
+	margin: 24rpx 0;
+}
+
+.data-item {
+	display: flex;
+	justify-content: space-between;
+	margin-bottom: 24rpx;
+	font-size: 28rpx;
+	align-items: center;
+}
+
+.l {
+	color: #999;
+}
+
+.v {
+	color: #333;
+	font-weight: 500;
+}
+
+.v.bold {
+	font-weight: bold;
+	font-size: 30rpx;
+}
+
+.v.erp-no {
+	color: #C1001C;
+	font-weight: bold;
+}
+
+.v.highlight {
+	color: #ff3b30;
+	font-weight: bold;
+	font-size: 34rpx;
+}
+
+.list-bottom-placeholder {
+	height: 260rpx;
+}
+
+.detail-action-bar-fixed {
+	position: fixed;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	background: #fff;
+	padding: 30rpx 40rpx;
+	box-shadow: 0 -10rpx 40rpx rgba(0, 0, 0, 0.04);
+	z-index: 999;
+	flex-shrink: 0;
+}
+
+.action-btn-wrap {
+	display: flex;
+	gap: 24rpx;
+}
+
+.action-btn {
+	flex: 1;
+	height: 96rpx;
+	border-radius: 48rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 32rpx;
+	font-weight: bold;
+}
+
+.action-btn.primary {
+	background: #C1001C;
+	color: #fff;
+	border: none;
+}
+
+.action-btn.cancel {
+	background: #fff1f0;
+	color: #ff3b30;
+	border: 1rpx solid #ffccc7;
+	font-weight: normal;
+}
+
+.safe-area-bottom-support {
+	height: constant(safe-area-inset-bottom);
+	height: env(safe-area-inset-bottom);
+}
+</style>

+ 0 - 311
pages/order/edit_model.vue

@@ -1,311 +0,0 @@
-<template>
-	<view class="order-container">
-		<scroll-view 
-			scroll-y 
-			class="order-scroll" 
-			:show-scrollbar="false"
-			:enhanced="true">
-			<view class="form-content">
-				
-				<!-- 模块 1:型材 -->
-				<view class="section-card">
-					<view class="section-header">
-						<view class="blue-bar"></view>
-						<text class="section-title">型材</text>
-					</view>
-					<view class="form-item">
-						<text class="label required">型号</text>
-						<view class="picker-box" @click="openTypePicker">
-							<view class="picker-inner">
-								<view class="picker-val" :class="{placeholder: !formData.type}">
-									{{ formData.type || '请选择型号' }}
-								</view>
-								<view class="line-arrow-down"></view>
-							</view>
-						</view>
-					</view>
-					<view class="row-flex">
-						<view class="half-item">
-							<text class="label">名称</text>
-							<input class="input-box readonly small-font" v-model="formData.name" disabled placeholder="型号名称" />
-						</view>
-						<view class="half-item">
-							<text class="label">材质</text>
-							<input class="input-box readonly small-font" v-model="formData.material" disabled placeholder="材质" />
-						</view>
-					</view>
-				</view>
-
-				<!-- 模块 2:表面处理 -->
-				<view class="section-card">
-					<view class="section-header">
-						<view class="blue-bar"></view>
-						<text class="section-title">表面处理</text>
-					</view>
-					<view class="form-item">
-						<text class="label required">表面名称</text>
-						<view class="picker-box" @click="openSurfacePicker">
-							<view class="picker-inner">
-								<view class="picker-val" :class="{placeholder: !formData.surfaceName}">
-									{{ formData.surfaceName || '请选择表面名称' }}
-								</view>
-								<view class="line-arrow-down"></view>
-							</view>
-						</view>
-					</view>
-				</view>
-
-				<!-- 模块 3:包装 -->
-				<view class="section-card">
-					<view class="section-header">
-						<view class="blue-bar"></view>
-						<text class="section-title">包装</text>
-					</view>
-					<view class="form-item">
-						<text class="label required">包装方式</text>
-						<view class="picker-box" @click="openPackagePicker">
-							<view class="picker-inner">
-								<view class="picker-val" :class="{placeholder: !formData.packageMethod}">
-									{{ formData.packageMethod || '请选择包装方式' }}
-								</view>
-								<view class="line-arrow-down"></view>
-							</view>
-						</view>
-					</view>
-				</view>
-
-				<!-- 模块 4:壁厚 -->
-				<view class="section-card">
-					<view class="section-header">
-						<view class="blue-bar"></view>
-						<text class="section-title">壁厚</text>
-					</view>
-					<view class="row-flex">
-						<view class="half-item">
-							<text class="label required">长度</text>
-							<view class="input-wrap">
-								<input class="input-box" type="digit" v-model="formData.length" placeholder="请输入" />
-								<text class="unit">mm</text>
-							</view>
-						</view>
-						<view class="half-item">
-							<text class="label required">壁厚</text>
-							<view class="input-wrap">
-								<input class="input-box" type="digit" v-model="formData.wallThickness" placeholder="请输入" />
-								<text class="unit">mm</text>
-							</view>
-						</view>
-					</view>
-				</view>
-
-				<!-- 模块 5:数量 -->
-				<view class="section-card">
-					<view class="section-header">
-						<view class="blue-bar"></view>
-						<text class="section-title">数量</text>
-					</view>
-					<view class="form-item no-margin-bottom">
-						<text class="label required">支数</text>
-						<input class="input-box full-width" type="number" v-model="formData.count" placeholder="请输入支付支数" />
-					</view>
-				</view>
-
-				<view class="bottom-placeholder"></view>
-			</view>
-		</scroll-view>
-
-		<!-- 底部固定保存按钮 -->
-		<view class="fixed-submit-bar">
-			<button class="submit-btn" @click="saveEdit">保存</button>
-		</view>
-
-		<!-- 型号选择 -->
-		<view class="custom-picker-mask" v-if="showTypePicker" @click="closeTypePicker" @touchmove.stop.prevent>
-			<view class="picker-popup" @click.stop>
-				<view class="popup-header">
-					<text class="cancel-text" @click="closeTypePicker">取消</text>
-					<text class="popup-title">选择产品型号</text>
-					<text class="confirm-text" @click="confirmTypeSelect">确定</text>
-				</view>
-				<scroll-view scroll-y class="item-list">
-					<view class="option-item" v-for="(item, index) in typeList" :key="index" 
-						:class="{active: tempSelectedIndex === index}" @click="selectTypeItem(index)">
-						<text>{{item}}</text>
-						<icon type="success_no_circle" size="16" color="#C1001C" v-if="tempSelectedIndex === index"></icon>
-					</view>
-				</scroll-view>
-			</view>
-		</view>
-
-		<!-- 表面处理选择 -->
-		<view class="custom-picker-mask" v-if="showSurfacePicker" @click="closeSurfacePicker" @touchmove.stop.prevent>
-			<view class="picker-popup" @click.stop>
-				<view class="popup-header">
-					<text class="cancel-text" @click="closeSurfacePicker">取消</text>
-					<text class="popup-title">选择表面处理</text>
-					<text class="confirm-text" @click="confirmSurfaceSelect">确定</text>
-				</view>
-				<scroll-view scroll-y class="item-list">
-					<view class="option-item" v-for="(item, index) in surfaceList" :key="index" 
-						:class="{active: tempSurfaceIndex === index}" @click="selectSurfaceItem(index)">
-						<text>{{item}}</text>
-						<icon type="success_no_circle" size="16" color="#C1001C" v-if="tempSurfaceIndex === index"></icon>
-					</view>
-				</scroll-view>
-			</view>
-		</view>
-
-		<!-- 包装方式选择 -->
-		<view class="custom-picker-mask" v-if="showPackagePicker" @click="closePackagePicker" @touchmove.stop.prevent>
-			<view class="picker-popup" @click.stop>
-				<view class="popup-header">
-					<text class="cancel-text" @click="closePackagePicker">取消</text>
-					<text class="popup-title">选择包装方式</text>
-					<text class="confirm-text" @click="confirmPackageSelect">确定</text>
-				</view>
-				<scroll-view scroll-y class="item-list">
-					<view class="option-item" v-for="(item, index) in packageList" :key="index" 
-						:class="{active: tempPackageIndex === index}" @click="selectPackageItem(index)">
-						<text>{{item}}</text>
-						<icon type="success_no_circle" size="16" color="#C1001C" v-if="tempPackageIndex === index"></icon>
-					</view>
-				</scroll-view>
-			</view>
-		</view>
-
-	</view>
-</template>
-
-<script>
-	export default {
-		data() {
-			return {
-				itemIndex: -1,
-				showTypePicker: false, showSurfacePicker: false, showPackagePicker: false,
-				tempSelectedIndex: -1, tempSurfaceIndex: -1, tempPackageIndex: -1,
-				typeList: ['TY0018', 'TY0019', 'TY0020', 'TY0021', 'TY0022', 'TY0023', 'TY0024', 'TY0025', 'TY0026', 'TY0027', 'TY0028'],
-				surfaceList: ['PL坯料', '阳极氧化', '电泳涂漆', '粉末喷涂', '氟碳喷涂', '木纹转印'],
-				packageList: ['不贴膜+3点捆扎', '贴膜+纸箱', '气泡膜包装', '简易编织袋', '木托架包装'],
-				formData: {
-					type: '', name: '', material: '',
-					surfaceName: '', packageMethod: '', length: '',
-					wallThickness: '', count: ''
-				}
-			}
-		},
-		onLoad(options) {
-			if (options.data) {
-				try {
-					const item = JSON.parse(decodeURIComponent(options.data));
-					this.formData = item;
-					this.itemIndex = parseInt(options.index || -1);
-				} catch (e) {
-					console.error('Data parse error', e);
-				}
-			}
-		},
-		methods: {
-			openTypePicker() { if (this.formData.type) this.tempSelectedIndex = this.typeList.indexOf(this.formData.type); this.showTypePicker = true; },
-			closeTypePicker() { this.showTypePicker = false; },
-			selectTypeItem(index) { this.tempSelectedIndex = index; },
-			confirmTypeSelect() { if (this.tempSelectedIndex === -1) return; const val = this.typeList[this.tempSelectedIndex]; this.formData.type = val; this.formData.name = '工业铝材'; this.formData.material = (this.tempSelectedIndex % 2 === 0) ? '6063-T5' : '6061-T6'; this.closeTypePicker(); },
-			openSurfacePicker() { if (this.formData.surfaceName) this.tempSurfaceIndex = this.surfaceList.indexOf(this.formData.surfaceName); this.showSurfacePicker = true; },
-			closeSurfacePicker() { this.showSurfacePicker = false; },
-			selectSurfaceItem(index) { this.tempSurfaceIndex = index; },
-			confirmSurfaceSelect() { if (this.tempSurfaceIndex === -1) return; this.formData.surfaceName = this.surfaceList[this.tempSurfaceIndex]; this.closeSurfacePicker(); },
-			openPackagePicker() { if (this.formData.packageMethod) this.tempPackageIndex = this.packageList.indexOf(this.formData.packageMethod); this.showPackagePicker = true; },
-			closePackagePicker() { this.showPackagePicker = false; },
-			selectPackageItem(index) { this.tempPackageIndex = index; },
-			confirmPackageSelect() { if (this.tempPackageIndex === -1) return; this.formData.packageMethod = this.packageList[this.tempPackageIndex]; this.closePackagePicker(); },
-			saveEdit() {
-				const fields = [
-					{ key: 'type', label: '型号' },
-					{ key: 'surfaceName', label: '表面名称' },
-					{ key: 'packageMethod', label: '包装方式' },
-					{ key: 'length', label: '长度' },
-					{ key: 'wallThickness', label: '壁厚' },
-					{ key: 'count', label: '支数' }
-				];
-				for (let item of fields) {
-					if (!this.formData[item.key]) {
-						uni.showToast({ title: `请完善项目:${item.label}`, icon: 'none' });
-						return;
-					}
-				}
-				
-				uni.$emit('update_order_item', {
-					index: this.itemIndex,
-					data: JSON.parse(JSON.stringify(this.formData))
-				});
-				uni.navigateBack();
-			}
-		}
-	}
-</script>
-
-<style scoped>
-	/deep/ ::-webkit-scrollbar { display: none !important; width: 0 !important; height: 0 !important; }
-	.order-container { width: 100%; height: 100vh; background: #f7f8fa; display: flex; flex-direction: column; overflow: hidden; }
-	.order-scroll { flex: 1; height: 0; }
-	.form-content { 
-		padding: 30rpx; 
-		padding-bottom: calc(180rpx + env(safe-area-inset-bottom)); 
-	}
-	.section-card { background: #fff; border-radius: 24rpx; padding: 30rpx; margin-bottom: 30rpx; box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.02); }
-	.section-header { display: flex; align-items: center; margin-bottom: 40rpx; }
-	.blue-bar { width: 8rpx; height: 32rpx; background: #C1001C; border-radius: 4rpx; margin-right: 16rpx; }
-	.section-title { font-size: 32rpx; font-weight: bold; color: #333; }
-	.form-item { margin-bottom: 40rpx; }
-	.no-margin-bottom { margin-bottom: 0; }
-	.row-flex { display: flex; justify-content: space-between; }
-	.half-item { width: 48%; }
-	.label { font-size: 28rpx; color: #333; margin-bottom: 20rpx; display: block; font-weight: 500; }
-	.label.required::after { content: ' *'; color: #ff4d4f; font-weight: bold; margin-left: 4rpx; }
-	.picker-box { background: #f9fafc; border-radius: 12rpx; height: 100rpx; border: 1rpx solid #eee; display: flex; align-items: center; }
-	.picker-inner { width: 100%; height: 100%; display: flex; align-items: center; justify-content: space-between; padding: 0 30rpx; box-sizing: border-box; }
-	.picker-val { font-size: 30rpx; color: #333; }
-	.picker-val.placeholder { color: #ccc; font-size: 28rpx; }
-	.line-arrow-down { width: 14rpx; height: 14rpx; border-right: 3rpx solid #bbb; border-bottom: 3rpx solid #bbb; transform: rotate(45deg); margin-top: -8rpx; margin-right: 4rpx; }
-	.input-wrap { position: relative; width: 100%; }
-	.input-box { font-size: 30rpx; color: #333; width: 100%; height: 100rpx; background: #f9fafc; border-radius: 12rpx; padding: 0 80rpx 0 30rpx; box-sizing: border-box; border: 1rpx solid #eee; }
-	.input-box.readonly { background: #f8f9fa; color: #666; border-color: #f0f0f0; }
-	.input-box.full-width { padding: 0 30rpx; }
-	.unit { position: absolute; right: 24rpx; top: 50%; transform: translateY(-50%); font-size: 26rpx; color: #999; font-weight: 500; }
-	.small-font { font-size: 26rpx !important; }
-	
-	.fixed-submit-bar { 
-		position: fixed; 
-		bottom: 0; 
-		left: 0; 
-		width: 100%; 
-		background: #fff; 
-		padding: 20rpx 30rpx calc(env(safe-area-inset-bottom) + 20rpx); 
-		box-sizing: border-box; 
-		box-shadow: 0 -10rpx 30rpx rgba(0,0,0,0.05);
-		z-index: 100;
-	}
-	.submit-btn { 
-		background: #C1001C; 
-		color: #fff; 
-		height: 100rpx; 
-		border-radius: 50rpx; 
-		display: flex; 
-		align-items: center; 
-		justify-content: center; 
-		font-size: 34rpx; 
-		font-weight: bold; 
-		border: none; 
-	}
-	.submit-btn:active { opacity: 0.9; transform: scale(0.98); }
-	.custom-picker-mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.4); z-index: 1000; display: flex; align-items: flex-end; }
-	.picker-popup { width: 100%; background: #fff; border-radius: 32rpx 32rpx 0 0; padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx); animation: slideUp 0.15s ease-out; }
-	@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
-	.popup-header { display: flex; justify-content: space-between; align-items: center; padding: 30rpx 40rpx; border-bottom: 1rpx solid #f0f0f0; }
-	.popup-title { font-size: 32rpx; font-weight: bold; color: #333; }
-	.cancel-text, .confirm-text { font-size: 30rpx; padding: 10rpx; }
-	.confirm-text { color: #C1001C; font-weight: bold; }
-	.item-list { max-height: 50vh; padding: 0 40rpx; }
-	.option-item { height: 110rpx; display: flex; align-items: center; justify-content: space-between; border-bottom: 1rpx solid #f8f8f8; font-size: 32rpx; color: #333; }
-	.option-item.active { color: #C1001C; font-weight: bold; }
-	.bottom-placeholder { height: 60rpx; }
-</style>

+ 527 - 0
pages/order/edit_model/index.vue

@@ -0,0 +1,527 @@
+<template>
+	<view class="order-container">
+		<scroll-view scroll-y class="order-scroll" :show-scrollbar="false" :enhanced="true">
+			<view class="form-content">
+
+				<!-- 模块 1:型材 -->
+				<view class="section-card">
+					<view class="section-header">
+						<view class="blue-bar"></view>
+						<text class="section-title">型材</text>
+					</view>
+					<view class="form-item">
+						<text class="label required">型号</text>
+						<view class="picker-box" @click="openTypePicker">
+							<view class="picker-inner">
+								<view class="picker-val" :class="{ placeholder: !formData.type }">
+									{{ formData.type || '请选择型号' }}
+								</view>
+								<view class="line-arrow-down"></view>
+							</view>
+						</view>
+					</view>
+					<view class="row-flex">
+						<view class="half-item">
+							<text class="label">名称</text>
+							<input class="input-box readonly small-font" v-model="formData.name" disabled
+								placeholder="型号名称" />
+						</view>
+						<view class="half-item">
+							<text class="label">材质</text>
+							<input class="input-box readonly small-font" v-model="formData.material" disabled
+								placeholder="材质" />
+						</view>
+					</view>
+				</view>
+
+				<!-- 模块 2:表面处理 -->
+				<view class="section-card">
+					<view class="section-header">
+						<view class="blue-bar"></view>
+						<text class="section-title">表面处理</text>
+					</view>
+					<view class="form-item">
+						<text class="label required">表面名称</text>
+						<view class="picker-box" @click="openSurfacePicker">
+							<view class="picker-inner">
+								<view class="picker-val" :class="{ placeholder: !formData.surfaceName }">
+									{{ formData.surfaceName || '请选择表面名称' }}
+								</view>
+								<view class="line-arrow-down"></view>
+							</view>
+						</view>
+					</view>
+				</view>
+
+				<!-- 模块 3:包装 -->
+				<view class="section-card">
+					<view class="section-header">
+						<view class="blue-bar"></view>
+						<text class="section-title">包装</text>
+					</view>
+					<view class="form-item">
+						<text class="label required">包装方式</text>
+						<view class="picker-box" @click="openPackagePicker">
+							<view class="picker-inner">
+								<view class="picker-val" :class="{ placeholder: !formData.packageMethod }">
+									{{ formData.packageMethod || '请选择包装方式' }}
+								</view>
+								<view class="line-arrow-down"></view>
+							</view>
+						</view>
+					</view>
+				</view>
+
+				<!-- 模块 4:壁厚 -->
+				<view class="section-card">
+					<view class="section-header">
+						<view class="blue-bar"></view>
+						<text class="section-title">壁厚</text>
+					</view>
+					<view class="row-flex">
+						<view class="half-item">
+							<text class="label required">长度</text>
+							<view class="input-wrap">
+								<input class="input-box" type="digit" v-model="formData.length" placeholder="请输入" />
+								<text class="unit">mm</text>
+							</view>
+						</view>
+						<view class="half-item">
+							<text class="label required">壁厚</text>
+							<view class="input-wrap">
+								<input class="input-box" type="digit" v-model="formData.wallThickness"
+									placeholder="请输入" />
+								<text class="unit">mm</text>
+							</view>
+						</view>
+					</view>
+				</view>
+
+				<!-- 模块 5:数量 -->
+				<view class="section-card">
+					<view class="section-header">
+						<view class="blue-bar"></view>
+						<text class="section-title">数量</text>
+					</view>
+					<view class="form-item no-margin-bottom">
+						<text class="label required">支数</text>
+						<input class="input-box full-width" type="number" v-model="formData.count"
+							placeholder="请输入支付支数" />
+					</view>
+				</view>
+
+				<view class="bottom-placeholder"></view>
+			</view>
+		</scroll-view>
+
+		<!-- 底部固定保存按钮 -->
+		<view class="fixed-submit-bar">
+			<button class="submit-btn" @click="saveEdit">保存</button>
+		</view>
+
+		<!-- 型号选择 -->
+		<view class="custom-picker-mask" v-if="showTypePicker" @click="closeTypePicker" @touchmove.stop.prevent>
+			<view class="picker-popup" @click.stop>
+				<view class="popup-header">
+					<text class="cancel-text" @click="closeTypePicker">取消</text>
+					<text class="popup-title">选择产品型号</text>
+					<text class="confirm-text" @click="confirmTypeSelect">确定</text>
+				</view>
+				<scroll-view scroll-y class="item-list">
+					<view class="option-item" v-for="(item, index) in typeList" :key="index"
+						:class="{ active: tempSelectedIndex === index }" @click="selectTypeItem(index)">
+						<text>{{ item }}</text>
+						<icon type="success_no_circle" size="16" color="#C1001C" v-if="tempSelectedIndex === index">
+						</icon>
+					</view>
+				</scroll-view>
+			</view>
+		</view>
+
+		<!-- 表面处理选择 -->
+		<view class="custom-picker-mask" v-if="showSurfacePicker" @click="closeSurfacePicker" @touchmove.stop.prevent>
+			<view class="picker-popup" @click.stop>
+				<view class="popup-header">
+					<text class="cancel-text" @click="closeSurfacePicker">取消</text>
+					<text class="popup-title">选择表面处理</text>
+					<text class="confirm-text" @click="confirmSurfaceSelect">确定</text>
+				</view>
+				<scroll-view scroll-y class="item-list">
+					<view class="option-item" v-for="(item, index) in surfaceList" :key="index"
+						:class="{ active: tempSurfaceIndex === index }" @click="selectSurfaceItem(index)">
+						<text>{{ item }}</text>
+						<icon type="success_no_circle" size="16" color="#C1001C" v-if="tempSurfaceIndex === index">
+						</icon>
+					</view>
+				</scroll-view>
+			</view>
+		</view>
+
+		<!-- 包装方式选择 -->
+		<view class="custom-picker-mask" v-if="showPackagePicker" @click="closePackagePicker" @touchmove.stop.prevent>
+			<view class="picker-popup" @click.stop>
+				<view class="popup-header">
+					<text class="cancel-text" @click="closePackagePicker">取消</text>
+					<text class="popup-title">选择包装方式</text>
+					<text class="confirm-text" @click="confirmPackageSelect">确定</text>
+				</view>
+				<scroll-view scroll-y class="item-list">
+					<view class="option-item" v-for="(item, index) in packageList" :key="index"
+						:class="{ active: tempPackageIndex === index }" @click="selectPackageItem(index)">
+						<text>{{ item }}</text>
+						<icon type="success_no_circle" size="16" color="#C1001C" v-if="tempPackageIndex === index">
+						</icon>
+					</view>
+				</scroll-view>
+			</view>
+		</view>
+
+	</view>
+</template>
+
+<script>
+import typeList from '@/mock/type-list.json';
+import surfaceList from '@/json/surface-list.json';
+import packageList from '@/json/package-list.json';
+
+export default {
+	data() {
+		return {
+			itemIndex: -1,
+			showTypePicker: false, showSurfacePicker: false, showPackagePicker: false,
+			tempSelectedIndex: -1, tempSurfaceIndex: -1, tempPackageIndex: -1,
+			typeList,
+			surfaceList,
+			packageList,
+			formData: {
+				type: '', name: '', material: '',
+				surfaceName: '', packageMethod: '', length: '',
+				wallThickness: '', count: ''
+			}
+		}
+	},
+	onLoad(options) {
+		if (options.data) {
+			try {
+				const item = JSON.parse(decodeURIComponent(options.data));
+				this.formData = item;
+				this.itemIndex = parseInt(options.index || -1);
+			} catch (e) {
+				console.error('Data parse error', e);
+			}
+		}
+	},
+	methods: {
+		openTypePicker() { if (this.formData.type) this.tempSelectedIndex = this.typeList.indexOf(this.formData.type); this.showTypePicker = true; },
+		closeTypePicker() { this.showTypePicker = false; },
+		selectTypeItem(index) { this.tempSelectedIndex = index; },
+		confirmTypeSelect() { if (this.tempSelectedIndex === -1) return; const val = this.typeList[this.tempSelectedIndex]; this.formData.type = val; this.formData.name = '工业铝材'; this.formData.material = (this.tempSelectedIndex % 2 === 0) ? '6063-T5' : '6061-T6'; this.closeTypePicker(); },
+		openSurfacePicker() { if (this.formData.surfaceName) this.tempSurfaceIndex = this.surfaceList.indexOf(this.formData.surfaceName); this.showSurfacePicker = true; },
+		closeSurfacePicker() { this.showSurfacePicker = false; },
+		selectSurfaceItem(index) { this.tempSurfaceIndex = index; },
+		confirmSurfaceSelect() { if (this.tempSurfaceIndex === -1) return; this.formData.surfaceName = this.surfaceList[this.tempSurfaceIndex]; this.closeSurfacePicker(); },
+		openPackagePicker() { if (this.formData.packageMethod) this.tempPackageIndex = this.packageList.indexOf(this.formData.packageMethod); this.showPackagePicker = true; },
+		closePackagePicker() { this.showPackagePicker = false; },
+		selectPackageItem(index) { this.tempPackageIndex = index; },
+		confirmPackageSelect() { if (this.tempPackageIndex === -1) return; this.formData.packageMethod = this.packageList[this.tempPackageIndex]; this.closePackagePicker(); },
+		saveEdit() {
+			const fields = [
+				{ key: 'type', label: '型号' },
+				{ key: 'surfaceName', label: '表面名称' },
+				{ key: 'packageMethod', label: '包装方式' },
+				{ key: 'length', label: '长度' },
+				{ key: 'wallThickness', label: '壁厚' },
+				{ key: 'count', label: '支数' }
+			];
+			for (let item of fields) {
+				if (!this.formData[item.key]) {
+					uni.showToast({ title: `请完善项目:${item.label}`, icon: 'none' });
+					return;
+				}
+			}
+
+			uni.$emit('update_order_item', {
+				index: this.itemIndex,
+				data: JSON.parse(JSON.stringify(this.formData))
+			});
+			uni.navigateBack();
+		}
+	}
+}
+</script>
+
+<style scoped>
+/deep/ ::-webkit-scrollbar {
+	display: none !important;
+	width: 0 !important;
+	height: 0 !important;
+}
+
+.order-container {
+	width: 100%;
+	height: 100vh;
+	background: #f7f8fa;
+	display: flex;
+	flex-direction: column;
+	overflow: hidden;
+}
+
+.order-scroll {
+	flex: 1;
+	height: 0;
+}
+
+.form-content {
+	padding: 30rpx;
+	padding-bottom: calc(180rpx + env(safe-area-inset-bottom));
+}
+
+.section-card {
+	background: #fff;
+	border-radius: 24rpx;
+	padding: 30rpx;
+	margin-bottom: 30rpx;
+	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.02);
+}
+
+.section-header {
+	display: flex;
+	align-items: center;
+	margin-bottom: 40rpx;
+}
+
+.blue-bar {
+	width: 8rpx;
+	height: 32rpx;
+	background: #C1001C;
+	border-radius: 4rpx;
+	margin-right: 16rpx;
+}
+
+.section-title {
+	font-size: 32rpx;
+	font-weight: bold;
+	color: #333;
+}
+
+.form-item {
+	margin-bottom: 40rpx;
+}
+
+.no-margin-bottom {
+	margin-bottom: 0;
+}
+
+.row-flex {
+	display: flex;
+	justify-content: space-between;
+}
+
+.half-item {
+	width: 48%;
+}
+
+.label {
+	font-size: 28rpx;
+	color: #333;
+	margin-bottom: 20rpx;
+	display: block;
+	font-weight: 500;
+}
+
+.label.required::after {
+	content: ' *';
+	color: #ff4d4f;
+	font-weight: bold;
+	margin-left: 4rpx;
+}
+
+.picker-box {
+	background: #f9fafc;
+	border-radius: 12rpx;
+	height: 100rpx;
+	border: 1rpx solid #eee;
+	display: flex;
+	align-items: center;
+}
+
+.picker-inner {
+	width: 100%;
+	height: 100%;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	padding: 0 30rpx;
+	box-sizing: border-box;
+}
+
+.picker-val {
+	font-size: 30rpx;
+	color: #333;
+}
+
+.picker-val.placeholder {
+	color: #ccc;
+	font-size: 28rpx;
+}
+
+.line-arrow-down {
+	width: 14rpx;
+	height: 14rpx;
+	border-right: 3rpx solid #bbb;
+	border-bottom: 3rpx solid #bbb;
+	transform: rotate(45deg);
+	margin-top: -8rpx;
+	margin-right: 4rpx;
+}
+
+.input-wrap {
+	position: relative;
+	width: 100%;
+}
+
+.input-box {
+	font-size: 30rpx;
+	color: #333;
+	width: 100%;
+	height: 100rpx;
+	background: #f9fafc;
+	border-radius: 12rpx;
+	padding: 0 80rpx 0 30rpx;
+	box-sizing: border-box;
+	border: 1rpx solid #eee;
+}
+
+.input-box.readonly {
+	background: #f8f9fa;
+	color: #666;
+	border-color: #f0f0f0;
+}
+
+.input-box.full-width {
+	padding: 0 30rpx;
+}
+
+.unit {
+	position: absolute;
+	right: 24rpx;
+	top: 50%;
+	transform: translateY(-50%);
+	font-size: 26rpx;
+	color: #999;
+	font-weight: 500;
+}
+
+.small-font {
+	font-size: 26rpx !important;
+}
+
+.fixed-submit-bar {
+	position: fixed;
+	bottom: 0;
+	left: 0;
+	width: 100%;
+	background: #fff;
+	padding: 20rpx 30rpx calc(env(safe-area-inset-bottom) + 20rpx);
+	box-sizing: border-box;
+	box-shadow: 0 -10rpx 30rpx rgba(0, 0, 0, 0.05);
+	z-index: 100;
+}
+
+.submit-btn {
+	background: #C1001C;
+	color: #fff;
+	height: 100rpx;
+	border-radius: 50rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 34rpx;
+	font-weight: bold;
+	border: none;
+}
+
+.submit-btn:active {
+	opacity: 0.9;
+	transform: scale(0.98);
+}
+
+.custom-picker-mask {
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	background: rgba(0, 0, 0, 0.4);
+	z-index: 1000;
+	display: flex;
+	align-items: flex-end;
+}
+
+.picker-popup {
+	width: 100%;
+	background: #fff;
+	border-radius: 32rpx 32rpx 0 0;
+	padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx);
+	animation: slideUp 0.15s ease-out;
+}
+
+@keyframes slideUp {
+	from {
+		transform: translateY(100%);
+	}
+
+	to {
+		transform: translateY(0);
+	}
+}
+
+.popup-header {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding: 30rpx 40rpx;
+	border-bottom: 1rpx solid #f0f0f0;
+}
+
+.popup-title {
+	font-size: 32rpx;
+	font-weight: bold;
+	color: #333;
+}
+
+.cancel-text,
+.confirm-text {
+	font-size: 30rpx;
+	padding: 10rpx;
+}
+
+.confirm-text {
+	color: #C1001C;
+	font-weight: bold;
+}
+
+.item-list {
+	max-height: 50vh;
+	padding: 0 40rpx;
+}
+
+.option-item {
+	height: 110rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	border-bottom: 1rpx solid #f8f8f8;
+	font-size: 32rpx;
+	color: #333;
+}
+
+.option-item.active {
+	color: #C1001C;
+	font-weight: bold;
+}
+
+.bottom-placeholder {
+	height: 60rpx;
+}
+</style>

+ 576 - 0
pages/order/index.vue

@@ -0,0 +1,576 @@
+<template>
+	<view class="order-container">
+		<!-- 1. 未登录状态拦截 -->
+		<view class="not-logged-in-full" v-if="!isLogin">
+			<view class="auth-card">
+				<image class="auth-icon" src="https://img.icons8.com/clouds/200/lock.png" mode="aspectFit"></image>
+				<text class="auth-title">您还未登录</text>
+				<text class="auth-desc">请先登录账号,授权后即可查看下单权限并进行下单操作。</text>
+				<button class="contact-btn" @click="goToLogin">去登录</button>
+			</view>
+		</view>
+
+		<!-- 2. 待管理员授权状态 (已登录但无权限) -->
+		<view class="auth-waiting-full" v-else-if="!isAuthorized">
+			<view class="auth-card">
+				<image class="auth-icon" src="https://img.icons8.com/color/192/hourglass-sand-top.png" mode="aspectFit">
+				</image>
+				<text class="auth-title">待管理员授权</text>
+				<text class="auth-desc">您的账户尚未获得下单权限,请联系管理员核准授权后即可进行下单操作。</text>
+				<button class="contact-btn" @click="contactAdmin">联系管理员</button>
+				<button class="authorized-btn" @click="isAuthorized = true">我已授权</button>
+			</view>
+		</view>
+
+		<!-- 3. 已授权状态:已选型号列表 (参考草图2) -->
+		<template v-else>
+			<scroll-view scroll-y class="order-scroll-list" :show-scrollbar="false" :enhanced="true">
+				<view class="list-wrapper">
+					<!-- 列表头部:仅在有数据时显示 -->
+					<view class="list-header" v-if="selectedModels.length > 0">
+						<text class="header-text">已选型号列表:</text>
+					</view>
+
+					<!-- 1. 列表渲染 (精品化设计) -->
+					<view class="model-item-card" v-for="(item, index) in selectedModels" :key="index"
+						v-if="selectedModels.length > 0" @click="editItem(index, item)">
+						<view class="remove-icon" @click.stop="removeItem(index)">
+							<text class="x-icon">×</text>
+						</view>
+						<view class="card-line">
+							<text class="model-value">{{ item.type }}</text>
+							<view class="count-tag">
+								支数<text class="count-num">{{ item.count }}</text>
+							</view>
+						</view>
+						<view class="card-line secondary">
+							<text class="surface-label">表面名称:</text>
+							<text class="surface-text">{{ item.surfaceName }}</text>
+						</view>
+					</view>
+
+					<!-- 2. 全屏缺省状态:美化后的引导页 -->
+					<view class="empty-state-full" v-else>
+						<view class="empty-visual">
+							<image class="empty-img" src="https://img.icons8.com/clouds/200/shopping-cart.png"
+								mode="aspectFit"></image>
+							<view class="empty-bg-glow"></view>
+						</view>
+						<text class="empty-title">暂无已选型号</text>
+						<button class="empty-action-btn" @click="goToAddModel">选型下单</button>
+					</view>
+
+					<view class="bottom-safe-space"></view>
+				</view>
+			</scroll-view>
+
+			<!-- 悬浮添加按钮 (仅在有数据时显示) -->
+			<view class="floating-add-btn" @click="goToAddModel" v-if="selectedModels.length > 0">
+				<view class="plus-icon"></view>
+			</view>
+
+			<!-- 底部支付/下单汇总栏 (仅在有数据时显示) -->
+			<view class="footer-summary-bar" v-if="selectedModels.length > 0">
+				<view class="summary-info">
+					<text class="count-label">共计:</text>
+					<text class="num-highlight">{{ selectedModels.length }}</text>
+					<text class="unit">条</text>
+					<view class="split-line"></view>
+					<text class="num-highlight green">{{ totalCount }}</text>
+					<text class="unit">支</text>
+				</view>
+				<button class="submit-order-btn" :disabled="selectedModels.length === 0"
+					@click="submitFinalOrder">立即下单</button>
+			</view>
+		</template>
+
+		<!-- 底部菜单栏 -->
+		<erp-tab-bar active="order"></erp-tab-bar>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			isLogin: false,
+			isAuthorized: false,
+			selectedModels: []
+		}
+	},
+	computed: {
+		totalCount() {
+			return this.selectedModels.reduce((sum, item) => sum + parseInt(item.count || 0), 0);
+		}
+	},
+	onLoad() {
+		// 监听添加型号的事件
+		uni.$on('add_order_item', (data) => {
+			this.selectedModels.push(data);
+			uni.showToast({ title: '添加成功', icon: 'success' });
+		});
+		// 监听修改型号的事件
+		uni.$on('update_order_item', (res) => {
+			if (res.index > -1) {
+				this.$set(this.selectedModels, res.index, res.data);
+				uni.showToast({ title: '修改成功', icon: 'success' });
+			}
+		});
+	},
+	onShow() {
+		// 每次进入页面刷新登录状态
+		this.isLogin = !!uni.getStorageSync('isLogin');
+		// 如果已登录,模拟获取授权状态(实际开发中应请求接口)
+		if (this.isLogin) {
+			// 假设只要登录了就默认展示已授权,或者维持原有逻辑
+			// 这里为了演示“待授权”状态,我们手动控制它,或者根据登录状态设置
+			// this.isAuthorized = true; 
+		}
+	},
+	onUnload() {
+		uni.$off('add_order_item');
+		uni.$off('update_order_item');
+	},
+	methods: {
+		goToLogin() {
+			uni.navigateTo({
+				url: '/pages/login/index?redirect=' + encodeURIComponent('/pages/order/index')
+			});
+		},
+		contactAdmin() { uni.showModal({ title: '联系管理员', content: '管理员电话:138-0000-0000', showCancel: false, confirmColor: '#C1001C' }); },
+		goToAddModel() {
+			uni.navigateTo({
+				url: '/pages/order/add_model/index'
+			});
+		},
+		editItem(index, item) {
+			uni.navigateTo({
+				url: `/pages/order/edit_model/index?index=${index}&data=${encodeURIComponent(JSON.stringify(item))}`
+			});
+		},
+		removeItem(index) {
+			const self = this;
+			uni.showModal({
+				title: '提示',
+				content: '确定移除该型号吗?',
+				success: (res) => {
+					if (res.confirm) {
+						self.selectedModels.splice(index, 1);
+					}
+				}
+			});
+		},
+		submitFinalOrder() {
+			if (this.selectedModels.length === 0) return;
+
+			uni.showLoading({ title: '正在提交结果', mask: true });
+			setTimeout(() => {
+				uni.hideLoading();
+				uni.navigateTo({
+					url: '/pages/order/success/index'
+				});
+				// 注意:此处不再手动清空 selectedModels,防止跳转前页面出现“暂无数据”的闪现
+				// 并在 success 页面点击“再来一单”时通过 reLaunch 自动重置页面状态
+			}, 1500);
+		}
+	}
+}
+</script>
+
+<style scoped>
+/deep/ ::-webkit-scrollbar {
+	display: none !important;
+	width: 0 !important;
+	height: 0 !important;
+}
+
+.order-container {
+	width: 100%;
+	height: 100vh;
+	background: #f8fafc;
+	display: flex;
+	flex-direction: column;
+	overflow: hidden;
+}
+
+/* 授权等待/未登录样式保持一致 */
+.auth-waiting-full,
+.not-logged-in-full {
+	flex: 1;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: flex-start;
+	padding: 200rpx 40rpx 40rpx;
+	background: linear-gradient(180deg, rgba(0, 122, 255, 0.08) 0%, rgba(247, 248, 250, 1) 100%);
+}
+
+.auth-card {
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	text-align: center;
+}
+
+.auth-icon {
+	width: 200rpx;
+	height: 200rpx;
+	margin-bottom: 50rpx;
+}
+
+.auth-title {
+	font-size: 44rpx;
+	font-weight: bold;
+	color: #1a1a1a;
+	margin-bottom: 24rpx;
+}
+
+.auth-desc {
+	font-size: 28rpx;
+	color: #666;
+	line-height: 1.8;
+	margin-bottom: 80rpx;
+	padding: 0 20rpx;
+}
+
+.contact-btn {
+	width: 360rpx;
+	height: 96rpx;
+	background: linear-gradient(135deg, #C1001C 0%, #FF4D4F 100%);
+	color: #fff;
+	border-radius: 48rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 32rpx;
+	font-weight: bold;
+	border: none;
+	box-shadow: 0 12rpx 30rpx rgba(193, 0, 28, 0.2);
+}
+
+.authorized-btn {
+	width: 360rpx;
+	height: 96rpx;
+	background: #fff;
+	color: #C1001C;
+	border-radius: 48rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 32rpx;
+	font-weight: bold;
+	border: 2rpx solid #C1001C;
+	margin-top: 30rpx;
+}
+
+/* 已授权列表页样式 */
+.order-container {
+	width: 100%;
+	height: 100vh;
+	background: #f7f8fa;
+	display: flex;
+	flex-direction: column;
+	overflow: hidden;
+}
+
+.order-scroll-list {
+	flex: 1;
+	height: 0;
+}
+
+.list-wrapper {
+	padding: 30rpx;
+	/* 确保最后一条数据不被底部双层固定栏遮挡:汇总栏130 + 菜单栏110 + 安全区 + 缓冲余量 */
+	padding-bottom: calc(280rpx + env(safe-area-inset-bottom));
+}
+
+.list-header {
+	padding: 10rpx 0 20rpx;
+}
+
+.header-text {
+	font-size: 34rpx;
+	font-weight: bold;
+	color: #1a1a1a;
+	position: relative;
+	padding-left: 24rpx;
+}
+
+.header-text::before {
+	content: '';
+	position: absolute;
+	left: 0;
+	top: 10%;
+	height: 80%;
+	width: 8rpx;
+	background: #C1001C;
+	border-radius: 4rpx;
+}
+
+/* 型号卡片:大幅升级美化 */
+.model-item-card {
+	background: #fff;
+	border-radius: 24rpx;
+	padding: 36rpx;
+	margin-bottom: 30rpx;
+	position: relative;
+	box-shadow: 0 8rpx 30rpx rgba(0, 0, 0, 0.04);
+	border: 1rpx solid rgba(0, 0, 0, 0.02);
+}
+
+.remove-icon {
+	position: absolute;
+	right: 0;
+	top: 0;
+	width: 50rpx;
+	height: 50rpx;
+	background: rgba(255, 77, 79, 0.1);
+	border-radius: 0 24rpx 0 24rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	z-index: 5;
+}
+
+.x-icon {
+	font-size: 32rpx;
+	color: #ff4d4f;
+	font-weight: bold;
+}
+
+.card-line {
+	display: flex;
+	align-items: center;
+	margin-bottom: 20rpx;
+}
+
+.card-line.secondary {
+	margin-bottom: 0;
+	padding-top: 20rpx;
+	border-top: 1rpx dashed #f0f0f0;
+}
+
+.model-label {
+	font-size: 26rpx;
+	color: #999;
+}
+
+.model-value {
+	font-size: 34rpx;
+	font-weight: bold;
+	color: #333;
+	flex: 1;
+}
+
+.count-tag {
+	background: #FFF1F2;
+	color: #C1001C;
+	padding: 4rpx 16rpx;
+	border-radius: 8rpx;
+	font-size: 24rpx;
+	font-weight: bold;
+}
+
+.count-num {
+	font-size: 30rpx;
+	margin-left: 8rpx;
+}
+
+.surface-label {
+	font-size: 26rpx;
+	color: #999;
+}
+
+.surface-text {
+	font-size: 28rpx;
+	color: #666;
+}
+
+/* 悬浮添加按钮:位置上移避免拥挤 */
+.floating-add-btn {
+	position: fixed;
+	right: 40rpx;
+	bottom: calc(260rpx + env(safe-area-inset-bottom) + 40rpx);
+	width: 110rpx;
+	height: 110rpx;
+	background: #C1001C;
+	border-radius: 50%;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	box-shadow: 0 12rpx 40rpx rgba(193, 0, 28, 0.4);
+	z-index: 100;
+	transition: transform 0.2s;
+}
+
+.floating-add-btn:active {
+	transform: scale(0.9);
+}
+
+.plus-icon {
+	width: 40rpx;
+	height: 4rpx;
+	background: #fff;
+	border-radius: 2rpx;
+	position: relative;
+}
+
+.plus-icon::after {
+	content: '';
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	background: #fff;
+	transform: rotate(90deg);
+	border-radius: 2rpx;
+}
+
+/* 底部汇总栏:微调间距与样式 */
+.footer-summary-bar {
+	position: fixed;
+	bottom: calc(110rpx + env(safe-area-inset-bottom));
+	left: 0;
+	width: 100%;
+	height: 130rpx;
+	background: #fff;
+	border-top: 1rpx solid #f0f0f0;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	padding: 0 40rpx;
+	box-sizing: border-box;
+	z-index: 99;
+	box-shadow: 0 -10rpx 40rpx rgba(0, 0, 0, 0.05);
+}
+
+.summary-info {
+	display: flex;
+	align-items: center;
+}
+
+.count-label {
+	font-size: 26rpx;
+	color: #999;
+}
+
+.num-highlight {
+	font-size: 36rpx;
+	font-weight: bold;
+	color: #1a1a1a;
+	margin: 0 4rpx;
+}
+
+.num-highlight.green {
+	color: #C1001C;
+}
+
+.unit {
+	font-size: 24rpx;
+	color: #999;
+	margin-left: 2rpx;
+}
+
+.split-line {
+	width: 1rpx;
+	height: 30rpx;
+	background: #eee;
+	margin: 0 20rpx;
+}
+
+.submit-order-btn {
+	width: 220rpx;
+	height: 80rpx;
+	background: #e0e0e0;
+	color: #666;
+	font-size: 28rpx;
+	border-radius: 40rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	border: none;
+	margin: 0;
+	transition: all 0.3s;
+}
+
+.submit-order-btn:not([disabled]) {
+	background: #C1001C;
+	color: #fff;
+	font-weight: bold;
+}
+
+/* 全屏缺省页样式 */
+.empty-state-full {
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	padding-top: 120rpx;
+}
+
+.empty-visual {
+	position: relative;
+	margin-bottom: 40rpx;
+	width: 400rpx;
+	height: 400rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.empty-img {
+	width: 320rpx;
+	height: 320rpx;
+	z-index: 2;
+}
+
+.empty-bg-glow {
+	position: absolute;
+	width: 240rpx;
+	height: 240rpx;
+	background: radial-gradient(circle, rgba(193, 0, 28, 0.15) 0%, rgba(248, 250, 252, 0) 70%);
+	z-index: 1;
+	border-radius: 50%;
+}
+
+.empty-title {
+	font-size: 36rpx;
+	font-weight: bold;
+	color: #1a1a1a;
+	margin-bottom: 80rpx;
+}
+
+.empty-desc {
+	font-size: 26rpx;
+	color: #999;
+	margin-bottom: 60rpx;
+	text-align: center;
+	padding: 0 80rpx;
+	line-height: 1.6;
+}
+
+.empty-action-btn {
+	width: 320rpx;
+	height: 90rpx;
+	background: #C1001C;
+	color: #fff;
+	border-radius: 45rpx;
+	font-size: 30rpx;
+	font-weight: bold;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	box-shadow: 0 10rpx 30rpx rgba(193, 0, 28, 0.2);
+	border: none;
+}
+
+.empty-action-btn:active {
+	opacity: 0.8;
+	transform: scale(0.96);
+}
+
+.bottom-safe-space {
+	height: 100rpx;
+}
+</style>

+ 0 - 296
pages/order/list.vue

@@ -1,296 +0,0 @@
-<template>
-	<view class="list-page-container">
-		<!-- 1. 自定义顶部导航:彻底抹除红框1的原生蓝线 -->
-		<view class="custom-nav-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
-			<view class="nav-content">
-				<view class="back-icon" @click="goBack">
-					<view class="arrow-left"></view>
-				</view>
-				<text class="nav-title">全部订单</text>
-				<view class="placeholder-right"></view>
-			</view>
-		</view>
-
-		<!-- 2. 分类切换:使用翻译位移,彻底消除红框2残影 -->
-		<view class="tabs-fixed">
-			<view class="tabs-box">
-				<view v-for="(tab, index) in tabs" :key="index" 
-					class="tab-item" 
-					:class="{active: currentTab === index}"
-					@click="switchTab(index)">
-					<text class="tab-txt">{{tab}}</text>
-				</view>
-				<!-- 指示器:只负责位移,不负责显隐,彻底杜绝虚影 -->
-				<view class="indicator-track">
-					<view class="indicator-bar" :style="{transform: 'translateX(' + (currentTab * 100) + '%)'}">
-						<view class="bar-inner"></view>
-					</view>
-				</view>
-			</view>
-		</view>
-
-		<!-- 3. 固定高度的滚动区:强制启用滚动,解决不能滑动问题 -->
-		<scroll-view 
-			scroll-y 
-			class="order-scroll-view" 
-			:style="{ height: scrollHeight }"
-			@scrolltolower="onReachEnd"
-			:refresher-enabled="false"
-			:show-scrollbar="false">
-			
-			<view class="order-list-inner">
-				<view class="order-card" v-for="(item, index) in displayList" :key="index" @click="goDetail(item)">
-					<view class="card-head">
-						<text class="order-id">单号:{{item.orderNo}}</text>
-						<view class="status-badge" :class="item.statusType">{{item.statusName}}</view>
-					</view>
-					<view class="card-body">
-						<view class="model-row" v-for="(model, mIdx) in item.models.slice(0, 2)" :key="mIdx">
-							<text class="m-type">{{model.type}}</text>
-							<text class="m-spec">{{model.surface}} | {{model.length}}mm</text>
-							<text class="m-count">{{model.count}} 支</text>
-						</view>
-						<view class="more-hint" v-if="item.models.length > 2">
-							<text>查看更多 {{item.models.length - 2}} 个型号...</text>
-						</view>
-						<view class="total-summary">
-							<text class="summary-label">共计:</text>
-							<text class="summary-val">{{item.models.length}}</text>
-							<text class="summary-unit">个型号</text>
-							<view class="summary-split"></view>
-							<text class="summary-val highlight">{{item.totalCount}}</text>
-							<text class="summary-unit">支</text>
-						</view>
-					</view>
-					<view class="card-foot">
-						<text class="time">{{item.time}}</text>
-						<view class="btns">
-							<view class="btn-cancel" v-if="item.status === 1" @click.stop="onCancel(item)">撤销</view>
-							<view class="btn-view primary" @click.stop="goDetail(item)">订单详情</view>
-						</view>
-					</view>
-				</view>
-
-				<!-- 加载提示区 -->
-				<view class="list-status-info" v-if="displayList.length > 0">
-					<view class="loading-wrap" v-if="loading">
-						<view class="load-dot"></view><text>排队加载中...</text>
-					</view>
-					<view class="nomore-wrap" v-if="noMore">
-						<text class="nomore-line"></text>
-						<text class="nomore-text">已加载全部数据</text>
-						<text class="nomore-line"></text>
-					</view>
-				</view>
-
-				<!-- 缺省态 -->
-				<view class="empty-state" v-if="displayList.length === 0 && !loading">
-					<image src="https://img.icons8.com/clouds/200/open-box.png" mode="aspectFit"></image>
-					<text>暂无订单记录</text>
-				</view>
-				
-				<view class="safe-bottom"></view>
-			</view>
-		</scroll-view>
-
-		<!-- 底部菜单栏 -->
-		<erp-tab-bar active="order"></erp-tab-bar>
-	</view>
-</template>
-
-<script>
-	import ErpTabBar from '@/components/erp-tab-bar/erp-tab-bar.vue';
-	export default {
-		components: {
-			ErpTabBar
-		},
-		data() {
-			return {
-				statusBarHeight: 20,
-				navBarHeight: 44,
-				tabBarHeight: 50, // 对应 100rpx
-				currentTab: 0,
-				loading: false,
-				noMore: false,
-				tabs: ['全部', '待审核', '待签批', '生产中', '已完成'],
-				allOrders: [
-					{ 
-						orderNo: 'ORD20240428001', 
-						models: [
-							{ type: 'TY0019', length: '6000', surface: '阳极氧化', count: '100' },
-							{ type: 'TY0018', length: '6000', surface: 'PL坯料', count: '50' }
-						],
-						totalCount: 150,
-						status: 1, statusName: '待审核', statusType: 'pending', time: '2024-04-28 10:20' 
-					},
-					{ 
-						orderNo: 'ORD20240428002', 
-						models: [
-							{ type: 'TY0020', length: '5800', surface: '粉末喷涂', count: '80' }
-						],
-						totalCount: 80,
-						status: 2, statusName: '待签批', statusType: 'process', time: '2024-04-28 09:15' 
-					},
-					{ 
-						orderNo: 'ORD20240427088', 
-						models: [
-							{ type: 'TY0018', length: '6000', surface: 'PL坯料', count: '300' }
-						],
-						totalCount: 300,
-						status: 4, statusName: '已完成', statusType: 'finish', time: '2024-04-27 15:40' 
-					},
-					{ 
-						orderNo: 'ORD20240427045', 
-						models: [
-							{ type: 'TY0021', length: '3000', surface: '电泳涂漆', count: '50' },
-							{ type: 'TY0022', length: '4000', surface: '木纹转印', count: '40' },
-							{ type: 'TY0023', length: '5000', surface: '氟碳喷涂', count: '30' }
-						],
-						totalCount: 120,
-						status: 3, statusName: '生产中', statusType: 'making', time: '2024-04-27 11:05' 
-					}
-				],
-				displayList: []
-			}
-		},
-		computed: {
-			scrollHeight() {
-				// 减去状态栏、导航栏、选项卡的高度
-				return `calc(100vh - ${this.statusBarHeight + this.navBarHeight + this.tabBarHeight}px)`;
-			}
-		},
-		onLoad(options) {
-			const info = uni.getSystemInfoSync();
-			this.statusBarHeight = info.statusBarHeight;
-			// 修正选项卡高度(单位px)
-			this.tabBarHeight = info.windowWidth / 750 * 110; 
-
-			if (options.tab) this.currentTab = parseInt(options.tab);
-			this.refresh();
-		},
-		methods: {
-			goBack() { uni.navigateBack(); },
-			switchTab(i) { this.currentTab = i; this.refresh(); },
-			refresh() { this.displayList = []; this.noMore = false; this.loadData(); },
-			onReachEnd() { if (!this.loading && !this.noMore) this.loadData(); },
-			loadData() {
-				this.loading = true;
-				setTimeout(() => {
-					let raw = this.currentTab === 0 ? this.allOrders : this.allOrders.filter(o => o.status === this.currentTab);
-					this.displayList = [...this.displayList, ...raw];
-					this.noMore = true; // 模拟一次性加载完演示数据
-					this.loading = false;
-				}, 500);
-			},
-			onCancel(item) {
-				uni.showModal({
-					title: '确认撤销',
-					content: `确认要撤销订单:${item.orderNo} 吗?`,
-					confirmColor: '#ff4d4f',
-					success: (res) => {
-						if (res.confirm) {
-							uni.showLoading({ title: '撤销中' });
-							setTimeout(() => {
-								uni.hideLoading();
-								uni.showToast({ title: '已撤销' });
-								
-								// 逻辑修复:修改状态而非移除
-								const target = this.allOrders.find(o => o.orderNo === item.orderNo);
-								if (target) {
-									target.status = 0;
-									target.statusName = '已撤销';
-									target.statusType = 'expired';
-								}
-								// 再次过滤刷新当前视图
-								this.refresh();
-							}, 800);
-						}
-					}
-				});
-			},
-			goDetail(item) {
-				const dataStr = encodeURIComponent(JSON.stringify(item));
-				uni.navigateTo({
-					url: `/pages/order/detail?data=${dataStr}`
-				});
-			}
-		}
-	}
-</script>
-
-<style scoped>
-	/deep/ ::-webkit-scrollbar { display: none !important; width: 0 !important; height: 0 !important; -webkit-appearance: none; background: transparent; }
-	.list-page-container { width: 100vw; height: 100vh; background: #f8fafc; overflow: hidden; display: flex; flex-direction: column; }
-	
-	/* 1. 自定义导航栏:解决蓝线红框1 */
-	.custom-nav-bar { background: #ffffff; width: 100%; flex-shrink: 0; }
-	.nav-content { height: 44px; display: flex; align-items: center; justify-content: space-between; padding: 0 30rpx; }
-	.back-icon { width: 60rpx; height: 44px; display: flex; align-items: center; }
-	.arrow-left { width: 20rpx; height: 20rpx; border-left: 4rpx solid #333; border-bottom: 4rpx solid #333; transform: rotate(45deg); margin-left: 10rpx; }
-	.nav-title { font-size: 34rpx; font-weight: bold; color: #1a1a1a; }
-	.placeholder-right { width: 60rpx; }
-
-	/* 2. 选项卡:解决残影红框2 */
-	.tabs-fixed { background: #fff; width: 100%; flex-shrink: 0; border-bottom: 1rpx solid #f0f0f0; }
-	.tabs-box { height: 110rpx; position: relative; display: flex; width: 100%; }
-	.tab-item { flex: 1; display: flex; align-items: center; justify-content: center; z-index: 5; }
-	.tab-txt { font-size: 28rpx; color: #888; transition: all 0.2s; }
-	.tab-item.active .tab-txt { color: #C1001C; font-weight: bold; font-size: 32rpx; }
-	
-	/* 指示器轨道:通过位移消除虚影 */
-	.indicator-track { position: absolute; bottom: 10rpx; left: 0; width: 100%; height: 6rpx; display: flex; }
-	.indicator-bar { width: 20%; height: 100%; display: flex; align-items: center; justify-content: center; transition: transform 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28); }
-	.bar-inner { width: 40rpx; height: 100%; background: #C1001C; border-radius: 6rpx; }
-
-	/* 3. 滚动区:解决不可滑动问题 */
-	.order-scroll-view { width: 100%; }
-	.order-list-inner { padding: 30rpx; padding-bottom: 60rpx; }
-
-	.order-card { background: #fff; border-radius: 24rpx; padding: 36rpx; margin-bottom: 30rpx; box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.02); }
-	.card-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 30rpx; }
-	.order-id { font-size: 28rpx; color: #1a1a1a; font-weight: bold; }
-	.status-badge { font-size: 20rpx; padding: 4rpx 16rpx; border-radius: 8rpx; }
-	.status-badge.pending { background: #FFF1F2; color: #C1001C; }
-	.status-badge.expired { background: #f5f5f5; color: #999; }
-	.status-badge.process { background: #fff7e6; color: #ffa940; }
-	.status-badge.making { background: #e6fffb; color: #36cfc9; }
-	/* 已撤销样式 */
-	.status-badge.expired { background: #f5f5f5; color: #999; }
-	.status-badge.finish { background: #f6ffed; color: #52c41a; }
-
-	.card-body { padding: 24rpx 0; border-top: 1rpx dashed #f0f0f0; margin-bottom: 24rpx; }
-	.model-row { display: flex; align-items: center; margin-bottom: 12rpx; font-size: 24rpx; }
-	.m-type { font-size: 28rpx; font-weight: bold; color: #333; width: 140rpx; }
-	.m-spec { color: #888; flex: 1; padding: 0 20rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
-	.m-count { color: #555; width: 100rpx; text-align: right; font-weight: 500; }
-	
-	.more-hint { padding: 10rpx 0; font-size: 24rpx; color: #999; text-align: center; background: #fafafa; border-radius: 8rpx; margin-bottom: 16rpx; }
-	
-	.total-summary { 
-		display: flex; align-items: center; justify-content: flex-end; 
-		padding-top: 20rpx; border-top: 1rpx solid #fafafa;
-	}
-	.summary-label { font-size: 24rpx; color: #999; }
-	.summary-val { font-size: 32rpx; font-weight: bold; color: #333; margin: 0 4rpx; }
-	.summary-val.highlight { color: #C1001C; }
-	.summary-unit { font-size: 22rpx; color: #999; margin-right: 12rpx; }
-	.summary-split { width: 1rpx; height: 20rpx; background: #eee; margin: 0 16rpx; }
-
-	.card-foot { display: flex; justify-content: space-between; align-items: center; padding-top: 10rpx; }
-	.time { font-size: 24rpx; color: #bbb; }
-	.btns { display: flex; gap: 16rpx; }
-	.btn-cancel, .btn-view { padding: 12rpx 30rpx; border-radius: 30rpx; font-size: 24rpx; }
-	.btn-cancel { border: 1rpx solid #ddd; color: #666; }
-	.btn-view.primary { background: #C1001C; color: #fff; }
-
-	.list-status-info { padding: 40rpx 0; display: flex; justify-content: center; }
-	.nomore-wrap { display: flex; align-items: center; color: #ccc; font-size: 24rpx; }
-	.nomore-line { width: 40rpx; height: 1rpx; background: #eee; margin: 0 20rpx; }
-	.loading-wrap { color: #999; font-size: 24rpx; display: flex; align-items: center; }
-	.load-dot { width: 10rpx; height: 10rpx; background: #C1001C; border-radius: 50%; margin-right: 10rpx; animation: flash 0.6s infinite alternate; }
-	@keyframes flash { from { opacity: 0.3; } to { opacity: 1; } }
-
-	.empty-state { display: flex; flex-direction: column; align-items: center; padding-top: 200rpx; color: #bbb; font-size: 28rpx; }
-	.empty-state image { width: 220rpx; height: 220rpx; margin-bottom: 30rpx; opacity: 0.6; }
-	.safe-bottom { height: 40rpx; }
-</style>

+ 551 - 0
pages/order/list/index.vue

@@ -0,0 +1,551 @@
+<template>
+	<view class="list-page-container">
+		<!-- 1. 自定义顶部导航:彻底抹除红框1的原生蓝线 -->
+		<view class="custom-nav-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
+			<view class="nav-content">
+				<view class="back-icon" @click="goBack">
+					<view class="arrow-left"></view>
+				</view>
+				<text class="nav-title">全部订单</text>
+				<view class="placeholder-right"></view>
+			</view>
+		</view>
+
+		<!-- 2. 分类切换:使用翻译位移,彻底消除红框2残影 -->
+		<view class="tabs-fixed">
+			<view class="tabs-box">
+				<view v-for="(tab, index) in tabs" :key="index" class="tab-item"
+					:class="{ active: currentTab === index }" @click="switchTab(index)">
+					<text class="tab-txt">{{ tab }}</text>
+				</view>
+				<!-- 指示器:只负责位移,不负责显隐,彻底杜绝虚影 -->
+				<view class="indicator-track">
+					<view class="indicator-bar" :style="{ transform: 'translateX(' + (currentTab * 100) + '%)' }">
+						<view class="bar-inner"></view>
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<!-- 3. 固定高度的滚动区:强制启用滚动,解决不能滑动问题 -->
+		<scroll-view scroll-y class="order-scroll-view" :style="{ height: scrollHeight }" @scrolltolower="onReachEnd"
+			:refresher-enabled="false" :show-scrollbar="false">
+
+			<view class="order-list-inner">
+				<view class="order-card" v-for="(item, index) in displayList" :key="index" @click="goDetail(item)">
+					<view class="card-head">
+						<text class="order-id">单号:{{ item.orderNo }}</text>
+						<view class="status-badge" :class="item.statusType">{{ item.statusName }}</view>
+					</view>
+					<view class="card-body">
+						<view class="model-row" v-for="(model, mIdx) in item.models.slice(0, 2)" :key="mIdx">
+							<text class="m-type">{{ model.type }}</text>
+							<text class="m-spec">{{ model.surface }} | {{ model.length }}mm</text>
+							<text class="m-count">{{ model.count }} 支</text>
+						</view>
+						<view class="more-hint" v-if="item.models.length > 2">
+							<text>查看更多 {{ item.models.length - 2 }} 个型号...</text>
+						</view>
+						<view class="total-summary">
+							<text class="summary-label">共计:</text>
+							<text class="summary-val">{{ item.models.length }}</text>
+							<text class="summary-unit">个型号</text>
+							<view class="summary-split"></view>
+							<text class="summary-val highlight">{{ item.totalCount }}</text>
+							<text class="summary-unit">支</text>
+						</view>
+					</view>
+					<view class="card-foot">
+						<text class="time">{{ item.time }}</text>
+						<view class="btns">
+							<view class="btn-cancel" v-if="item.status === 1" @click.stop="onCancel(item)">撤销</view>
+							<view class="btn-view primary" @click.stop="goDetail(item)">订单详情</view>
+						</view>
+					</view>
+				</view>
+
+				<!-- 加载提示区 -->
+				<view class="list-status-info" v-if="displayList.length > 0">
+					<view class="loading-wrap" v-if="loading">
+						<view class="load-dot"></view><text>排队加载中...</text>
+					</view>
+					<view class="nomore-wrap" v-if="noMore">
+						<text class="nomore-line"></text>
+						<text class="nomore-text">已加载全部数据</text>
+						<text class="nomore-line"></text>
+					</view>
+				</view>
+
+				<!-- 缺省态 -->
+				<view class="empty-state" v-if="displayList.length === 0 && !loading">
+					<image src="https://img.icons8.com/clouds/200/open-box.png" mode="aspectFit"></image>
+					<text>暂无订单记录</text>
+				</view>
+
+				<view class="safe-bottom"></view>
+			</view>
+		</scroll-view>
+
+		<!-- 底部菜单栏 -->
+		<erp-tab-bar active="order"></erp-tab-bar>
+	</view>
+</template>
+
+<script>
+import ErpTabBar from '@/components/erp-tab-bar/erp-tab-bar.vue';
+import tabs from '@/json/order-status-tabs.json';
+import mockOrders from '@/mock/orders.json';
+
+export default {
+	components: {
+		ErpTabBar
+	},
+	data() {
+		return {
+			statusBarHeight: 20,
+			navBarHeight: 44,
+			tabBarHeight: 50, // 对应 100rpx
+			currentTab: 0,
+			loading: false,
+			noMore: false,
+			tabs,
+			allOrders: JSON.parse(JSON.stringify(mockOrders)),
+			displayList: []
+		}
+	},
+	computed: {
+		scrollHeight() {
+			// 减去状态栏、导航栏、选项卡的高度
+			return `calc(100vh - ${this.statusBarHeight + this.navBarHeight + this.tabBarHeight}px)`;
+		}
+	},
+	onLoad(options) {
+		const info = uni.getSystemInfoSync();
+		this.statusBarHeight = info.statusBarHeight;
+		// 修正选项卡高度(单位px)
+		this.tabBarHeight = info.windowWidth / 750 * 110;
+
+		if (options.tab) this.currentTab = parseInt(options.tab);
+		this.refresh();
+	},
+	methods: {
+		goBack() { uni.navigateBack(); },
+		switchTab(i) { this.currentTab = i; this.refresh(); },
+		refresh() { this.displayList = []; this.noMore = false; this.loadData(); },
+		onReachEnd() { if (!this.loading && !this.noMore) this.loadData(); },
+		loadData() {
+			this.loading = true;
+			setTimeout(() => {
+				let raw = this.currentTab === 0 ? this.allOrders : this.allOrders.filter(o => o.status === this.currentTab);
+				this.displayList = [...this.displayList, ...raw];
+				this.noMore = true; // 模拟一次性加载完演示数据
+				this.loading = false;
+			}, 500);
+		},
+		onCancel(item) {
+			uni.showModal({
+				title: '确认撤销',
+				content: `确认要撤销订单:${item.orderNo} 吗?`,
+				confirmColor: '#ff4d4f',
+				success: (res) => {
+					if (res.confirm) {
+						uni.showLoading({ title: '撤销中' });
+						setTimeout(() => {
+							uni.hideLoading();
+							uni.showToast({ title: '已撤销' });
+
+							// 逻辑修复:修改状态而非移除
+							const target = this.allOrders.find(o => o.orderNo === item.orderNo);
+							if (target) {
+								target.status = 0;
+								target.statusName = '已撤销';
+								target.statusType = 'expired';
+							}
+							// 再次过滤刷新当前视图
+							this.refresh();
+						}, 800);
+					}
+				}
+			});
+		},
+		goDetail(item) {
+			const dataStr = encodeURIComponent(JSON.stringify(item));
+			uni.navigateTo({
+				url: `/pages/order/detail/index?data=${dataStr}`
+			});
+		}
+	}
+}
+</script>
+
+<style scoped>
+/deep/ ::-webkit-scrollbar {
+	display: none !important;
+	width: 0 !important;
+	height: 0 !important;
+	-webkit-appearance: none;
+	background: transparent;
+}
+
+.list-page-container {
+	width: 100vw;
+	height: 100vh;
+	background: #f8fafc;
+	overflow: hidden;
+	display: flex;
+	flex-direction: column;
+}
+
+/* 1. 自定义导航栏:解决蓝线红框1 */
+.custom-nav-bar {
+	background: #ffffff;
+	width: 100%;
+	flex-shrink: 0;
+}
+
+.nav-content {
+	height: 44px;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	padding: 0 30rpx;
+}
+
+.back-icon {
+	width: 60rpx;
+	height: 44px;
+	display: flex;
+	align-items: center;
+}
+
+.arrow-left {
+	width: 20rpx;
+	height: 20rpx;
+	border-left: 4rpx solid #333;
+	border-bottom: 4rpx solid #333;
+	transform: rotate(45deg);
+	margin-left: 10rpx;
+}
+
+.nav-title {
+	font-size: 34rpx;
+	font-weight: bold;
+	color: #1a1a1a;
+}
+
+.placeholder-right {
+	width: 60rpx;
+}
+
+/* 2. 选项卡:解决残影红框2 */
+.tabs-fixed {
+	background: #fff;
+	width: 100%;
+	flex-shrink: 0;
+	border-bottom: 1rpx solid #f0f0f0;
+}
+
+.tabs-box {
+	height: 110rpx;
+	position: relative;
+	display: flex;
+	width: 100%;
+}
+
+.tab-item {
+	flex: 1;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	z-index: 5;
+}
+
+.tab-txt {
+	font-size: 28rpx;
+	color: #888;
+	transition: all 0.2s;
+}
+
+.tab-item.active .tab-txt {
+	color: #C1001C;
+	font-weight: bold;
+	font-size: 32rpx;
+}
+
+/* 指示器轨道:通过位移消除虚影 */
+.indicator-track {
+	position: absolute;
+	bottom: 10rpx;
+	left: 0;
+	width: 100%;
+	height: 6rpx;
+	display: flex;
+}
+
+.indicator-bar {
+	width: 20%;
+	height: 100%;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	transition: transform 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);
+}
+
+.bar-inner {
+	width: 40rpx;
+	height: 100%;
+	background: #C1001C;
+	border-radius: 6rpx;
+}
+
+/* 3. 滚动区:解决不可滑动问题 */
+.order-scroll-view {
+	width: 100%;
+}
+
+.order-list-inner {
+	padding: 30rpx;
+	padding-bottom: 60rpx;
+}
+
+.order-card {
+	background: #fff;
+	border-radius: 24rpx;
+	padding: 36rpx;
+	margin-bottom: 30rpx;
+	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.02);
+}
+
+.card-head {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	margin-bottom: 30rpx;
+}
+
+.order-id {
+	font-size: 28rpx;
+	color: #1a1a1a;
+	font-weight: bold;
+}
+
+.status-badge {
+	font-size: 20rpx;
+	padding: 4rpx 16rpx;
+	border-radius: 8rpx;
+}
+
+.status-badge.pending {
+	background: #FFF1F2;
+	color: #C1001C;
+}
+
+.status-badge.expired {
+	background: #f5f5f5;
+	color: #999;
+}
+
+.status-badge.process {
+	background: #fff7e6;
+	color: #ffa940;
+}
+
+.status-badge.making {
+	background: #e6fffb;
+	color: #36cfc9;
+}
+
+/* 已撤销样式 */
+.status-badge.expired {
+	background: #f5f5f5;
+	color: #999;
+}
+
+.status-badge.finish {
+	background: #f6ffed;
+	color: #52c41a;
+}
+
+.card-body {
+	padding: 24rpx 0;
+	border-top: 1rpx dashed #f0f0f0;
+	margin-bottom: 24rpx;
+}
+
+.model-row {
+	display: flex;
+	align-items: center;
+	margin-bottom: 12rpx;
+	font-size: 24rpx;
+}
+
+.m-type {
+	font-size: 28rpx;
+	font-weight: bold;
+	color: #333;
+	width: 140rpx;
+}
+
+.m-spec {
+	color: #888;
+	flex: 1;
+	padding: 0 20rpx;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+
+.m-count {
+	color: #555;
+	width: 100rpx;
+	text-align: right;
+	font-weight: 500;
+}
+
+.more-hint {
+	padding: 10rpx 0;
+	font-size: 24rpx;
+	color: #999;
+	text-align: center;
+	background: #fafafa;
+	border-radius: 8rpx;
+	margin-bottom: 16rpx;
+}
+
+.total-summary {
+	display: flex;
+	align-items: center;
+	justify-content: flex-end;
+	padding-top: 20rpx;
+	border-top: 1rpx solid #fafafa;
+}
+
+.summary-label {
+	font-size: 24rpx;
+	color: #999;
+}
+
+.summary-val {
+	font-size: 32rpx;
+	font-weight: bold;
+	color: #333;
+	margin: 0 4rpx;
+}
+
+.summary-val.highlight {
+	color: #C1001C;
+}
+
+.summary-unit {
+	font-size: 22rpx;
+	color: #999;
+	margin-right: 12rpx;
+}
+
+.summary-split {
+	width: 1rpx;
+	height: 20rpx;
+	background: #eee;
+	margin: 0 16rpx;
+}
+
+.card-foot {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding-top: 10rpx;
+}
+
+.time {
+	font-size: 24rpx;
+	color: #bbb;
+}
+
+.btns {
+	display: flex;
+	gap: 16rpx;
+}
+
+.btn-cancel,
+.btn-view {
+	padding: 12rpx 30rpx;
+	border-radius: 30rpx;
+	font-size: 24rpx;
+}
+
+.btn-cancel {
+	border: 1rpx solid #ddd;
+	color: #666;
+}
+
+.btn-view.primary {
+	background: #C1001C;
+	color: #fff;
+}
+
+.list-status-info {
+	padding: 40rpx 0;
+	display: flex;
+	justify-content: center;
+}
+
+.nomore-wrap {
+	display: flex;
+	align-items: center;
+	color: #ccc;
+	font-size: 24rpx;
+}
+
+.nomore-line {
+	width: 40rpx;
+	height: 1rpx;
+	background: #eee;
+	margin: 0 20rpx;
+}
+
+.loading-wrap {
+	color: #999;
+	font-size: 24rpx;
+	display: flex;
+	align-items: center;
+}
+
+.load-dot {
+	width: 10rpx;
+	height: 10rpx;
+	background: #C1001C;
+	border-radius: 50%;
+	margin-right: 10rpx;
+	animation: flash 0.6s infinite alternate;
+}
+
+@keyframes flash {
+	from {
+		opacity: 0.3;
+	}
+
+	to {
+		opacity: 1;
+	}
+}
+
+.empty-state {
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	padding-top: 200rpx;
+	color: #bbb;
+	font-size: 28rpx;
+}
+
+.empty-state image {
+	width: 220rpx;
+	height: 220rpx;
+	margin-bottom: 30rpx;
+	opacity: 0.6;
+}
+
+.safe-bottom {
+	height: 40rpx;
+}
+</style>

+ 0 - 322
pages/order/order.vue

@@ -1,322 +0,0 @@
-<template>
-	<view class="order-container">
-		<!-- 1. 未登录状态拦截 -->
-		<view class="not-logged-in-full" v-if="!isLogin">
-			<view class="auth-card">
-				<image class="auth-icon" src="https://img.icons8.com/clouds/200/lock.png" mode="aspectFit"></image>
-				<text class="auth-title">您还未登录</text>
-				<text class="auth-desc">请先登录账号,授权后即可查看下单权限并进行下单操作。</text>
-				<button class="contact-btn" @click="goToLogin">去登录</button>
-			</view>
-		</view>
-
-		<!-- 2. 待管理员授权状态 (已登录但无权限) -->
-		<view class="auth-waiting-full" v-else-if="!isAuthorized">
-			<view class="auth-card">
-				<image class="auth-icon" src="https://img.icons8.com/color/192/hourglass-sand-top.png" mode="aspectFit"></image>
-				<text class="auth-title">待管理员授权</text>
-				<text class="auth-desc">您的账户尚未获得下单权限,请联系管理员核准授权后即可进行下单操作。</text>
-				<button class="contact-btn" @click="contactAdmin">联系管理员</button>
-				<button class="authorized-btn" @click="isAuthorized = true">我已授权</button>
-			</view>
-		</view>
-
-		<!-- 3. 已授权状态:已选型号列表 (参考草图2) -->
-		<template v-else>
-			<scroll-view 
-				scroll-y 
-				class="order-scroll-list" 
-				:show-scrollbar="false"
-				:enhanced="true">
-				<view class="list-wrapper">
-					<!-- 列表头部:仅在有数据时显示 -->
-					<view class="list-header" v-if="selectedModels.length > 0">
-						<text class="header-text">已选型号列表:</text>
-					</view>
-					
-					<!-- 1. 列表渲染 (精品化设计) -->
-					<view class="model-item-card" v-for="(item, index) in selectedModels" :key="index" v-if="selectedModels.length > 0" @click="editItem(index, item)">
-						<view class="remove-icon" @click.stop="removeItem(index)">
-							<text class="x-icon">×</text>
-						</view>
-						<view class="card-line">
-							<text class="model-value">{{item.type}}</text>
-							<view class="count-tag">
-								支数<text class="count-num">{{item.count}}</text>
-							</view>
-						</view>
-						<view class="card-line secondary">
-							<text class="surface-label">表面名称:</text>
-							<text class="surface-text">{{item.surfaceName}}</text>
-						</view>
-					</view>
-					
-					<!-- 2. 全屏缺省状态:美化后的引导页 -->
-					<view class="empty-state-full" v-else>
-						<view class="empty-visual">
-							<image class="empty-img" src="https://img.icons8.com/clouds/200/shopping-cart.png" mode="aspectFit"></image>
-							<view class="empty-bg-glow"></view>
-						</view>
-						<text class="empty-title">暂无已选型号</text>
-						<button class="empty-action-btn" @click="goToAddModel">选型下单</button>
-					</view>
-					
-					<view class="bottom-safe-space"></view>
-				</view>
-			</scroll-view>
-
-			<!-- 悬浮添加按钮 (仅在有数据时显示) -->
-			<view class="floating-add-btn" @click="goToAddModel" v-if="selectedModels.length > 0">
-				<view class="plus-icon"></view>
-			</view>
-
-			<!-- 底部支付/下单汇总栏 (仅在有数据时显示) -->
-			<view class="footer-summary-bar" v-if="selectedModels.length > 0">
-				<view class="summary-info">
-					<text class="count-label">共计:</text>
-					<text class="num-highlight">{{selectedModels.length}}</text>
-					<text class="unit">条</text>
-					<view class="split-line"></view>
-					<text class="num-highlight green">{{totalCount}}</text>
-					<text class="unit">支</text>
-				</view>
-				<button class="submit-order-btn" :disabled="selectedModels.length === 0" @click="submitFinalOrder">立即下单</button>
-			</view>
-		</template>
-
-		<!-- 底部菜单栏 -->
-		<erp-tab-bar active="order"></erp-tab-bar>
-	</view>
-</template>
-
-<script>
-	export default {
-		data() {
-			return {
-				isLogin: false,
-				isAuthorized: false,
-				selectedModels: []
-			}
-		},
-		computed: {
-			totalCount() {
-				return this.selectedModels.reduce((sum, item) => sum + parseInt(item.count || 0), 0);
-			}
-		},
-		onLoad() {
-			// 监听添加型号的事件
-			uni.$on('add_order_item', (data) => {
-				this.selectedModels.push(data);
-				uni.showToast({ title: '添加成功', icon: 'success' });
-			});
-			// 监听修改型号的事件
-			uni.$on('update_order_item', (res) => {
-				if (res.index > -1) {
-					this.$set(this.selectedModels, res.index, res.data);
-					uni.showToast({ title: '修改成功', icon: 'success' });
-				}
-			});
-		},
-		onShow() {
-			// 每次进入页面刷新登录状态
-			this.isLogin = !!uni.getStorageSync('isLogin');
-			// 如果已登录,模拟获取授权状态(实际开发中应请求接口)
-			if (this.isLogin) {
-				// 假设只要登录了就默认展示已授权,或者维持原有逻辑
-				// 这里为了演示“待授权”状态,我们手动控制它,或者根据登录状态设置
-				// this.isAuthorized = true; 
-			}
-		},
-		onUnload() {
-			uni.$off('add_order_item');
-			uni.$off('update_order_item');
-		},
-		methods: {
-			goToLogin() {
-				uni.navigateTo({
-					url: '/pages/login/login?redirect=' + encodeURIComponent('/pages/order/order')
-				});
-			},
-			contactAdmin() { uni.showModal({ title: '联系管理员', content: '管理员电话:138-0000-0000', showCancel: false, confirmColor: '#C1001C' }); },
-			goToAddModel() {
-				uni.navigateTo({
-					url: '/pages/order/add_model'
-				});
-			},
-			editItem(index, item) {
-				uni.navigateTo({
-					url: `/pages/order/edit_model?index=${index}&data=${encodeURIComponent(JSON.stringify(item))}`
-				});
-			},
-			removeItem(index) {
-				const self = this;
-				uni.showModal({
-					title: '提示',
-					content: '确定移除该型号吗?',
-					success: (res) => {
-						if (res.confirm) {
-							self.selectedModels.splice(index, 1);
-						}
-					}
-				});
-			},
-			submitFinalOrder() {
-				if (this.selectedModels.length === 0) return;
-				
-				uni.showLoading({ title: '正在提交结果', mask: true });
-				setTimeout(() => {
-					uni.hideLoading();
-					uni.navigateTo({
-						url: '/pages/order/success'
-					});
-					// 注意:此处不再手动清空 selectedModels,防止跳转前页面出现“暂无数据”的闪现
-					// 并在 success 页面点击“再来一单”时通过 reLaunch 自动重置页面状态
-				}, 1500);
-			}
-		}
-	}
-</script>
-
-<style scoped>
-	/deep/ ::-webkit-scrollbar { display: none !important; width: 0 !important; height: 0 !important; }
-	.order-container { width: 100%; height: 100vh; background: #f8fafc; display: flex; flex-direction: column; overflow: hidden; }
-	
-	/* 授权等待/未登录样式保持一致 */
-	.auth-waiting-full, .not-logged-in-full { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; padding: 200rpx 40rpx 40rpx; background: linear-gradient(180deg, rgba(0, 122, 255, 0.08) 0%, rgba(247, 248, 250, 1) 100%); }
-	.auth-card { display: flex; flex-direction: column; align-items: center; text-align: center; }
-	.auth-icon { width: 200rpx; height: 200rpx; margin-bottom: 50rpx; }
-	.auth-title { font-size: 44rpx; font-weight: bold; color: #1a1a1a; margin-bottom: 24rpx; }
-	.auth-desc { font-size: 28rpx; color: #666; line-height: 1.8; margin-bottom: 80rpx; padding: 0 20rpx; }
-	.contact-btn { width: 360rpx; height: 96rpx; background: linear-gradient(135deg, #C1001C 0%, #FF4D4F 100%); color: #fff; border-radius: 48rpx; display: flex; align-items: center; justify-content: center; font-size: 32rpx; font-weight: bold; border: none; box-shadow: 0 12rpx 30rpx rgba(193, 0, 28, 0.2); }
-	.authorized-btn { width: 360rpx; height: 96rpx; background: #fff; color: #C1001C; border-radius: 48rpx; display: flex; align-items: center; justify-content: center; font-size: 32rpx; font-weight: bold; border: 2rpx solid #C1001C; margin-top: 30rpx; }
-
-	/* 已授权列表页样式 */
-	.order-container { width: 100%; height: 100vh; background: #f7f8fa; display: flex; flex-direction: column; overflow: hidden; }
-	.order-scroll-list { flex: 1; height: 0; }
-	.list-wrapper { 
-		padding: 30rpx; 
-		/* 确保最后一条数据不被底部双层固定栏遮挡:汇总栏130 + 菜单栏110 + 安全区 + 缓冲余量 */
-		padding-bottom: calc(280rpx + env(safe-area-inset-bottom)); 
-	}
-	.list-header { padding: 10rpx 0 20rpx; }
-	.header-text { font-size: 34rpx; font-weight: bold; color: #1a1a1a; position: relative; padding-left: 24rpx; }
-	.header-text::before { content: ''; position: absolute; left: 0; top: 10%; height: 80%; width: 8rpx; background: #C1001C; border-radius: 4rpx; }
-
-	/* 型号卡片:大幅升级美化 */
-	.model-item-card { 
-		background: #fff; 
-		border-radius: 24rpx; 
-		padding: 36rpx; 
-		margin-bottom: 30rpx; 
-		position: relative; 
-		box-shadow: 0 8rpx 30rpx rgba(0,0,0,0.04);
-		border: 1rpx solid rgba(0,0,0,0.02);
-	}
-	.remove-icon { 
-		position: absolute; 
-		right: 0; 
-		top: 0; 
-		width: 50rpx; 
-		height: 50rpx; 
-		background: rgba(255, 77, 79, 0.1); 
-		border-radius: 0 24rpx 0 24rpx; 
-		display: flex; 
-		align-items: center; 
-		justify-content: center; 
-		z-index: 5;
-	}
-	.x-icon { font-size: 32rpx; color: #ff4d4f; font-weight: bold; }
-	
-	.card-line { display: flex; align-items: center; margin-bottom: 20rpx; }
-	.card-line.secondary { margin-bottom: 0; padding-top: 20rpx; border-top: 1rpx dashed #f0f0f0; }
-	
-	.model-label { font-size: 26rpx; color: #999; }
-	.model-value { font-size: 34rpx; font-weight: bold; color: #333; flex: 1; }
-	
-	.count-tag { background: #FFF1F2; color: #C1001C; padding: 4rpx 16rpx; border-radius: 8rpx; font-size: 24rpx; font-weight: bold; }
-	.count-num { font-size: 30rpx; margin-left: 8rpx; }
-	
-	.surface-label { font-size: 26rpx; color: #999; }
-	.surface-text { font-size: 28rpx; color: #666; }
-
-	/* 悬浮添加按钮:位置上移避免拥挤 */
-	.floating-add-btn { 
-		position: fixed; 
-		right: 40rpx; 
-		bottom: calc(260rpx + env(safe-area-inset-bottom) + 40rpx); 
-		width: 110rpx; 
-		height: 110rpx; 
-		background: #C1001C; 
-		border-radius: 50%; 
-		display: flex; 
-		align-items: center; 
-		justify-content: center; 
-		box-shadow: 0 12rpx 40rpx rgba(193, 0, 28, 0.4);
-		z-index: 100;
-		transition: transform 0.2s;
-	}
-	.floating-add-btn:active { transform: scale(0.9); }
-	.plus-icon { width: 40rpx; height: 4rpx; background: #fff; border-radius: 2rpx; position: relative; }
-	.plus-icon::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #fff; transform: rotate(90deg); border-radius: 2rpx; }
-
-	/* 底部汇总栏:微调间距与样式 */
-	.footer-summary-bar { 
-		position: fixed; 
-		bottom: calc(110rpx + env(safe-area-inset-bottom)); 
-		left: 0; 
-		width: 100%; 
-		height: 130rpx; 
-		background: #fff; 
-		border-top: 1rpx solid #f0f0f0; 
-		display: flex; 
-		align-items: center; 
-		justify-content: space-between; 
-		padding: 0 40rpx; 
-		box-sizing: border-box; 
-		z-index: 99;
-		box-shadow: 0 -10rpx 40rpx rgba(0,0,0,0.05);
-	}
-	.summary-info { display: flex; align-items: center; }
-	.count-label { font-size: 26rpx; color: #999; }
-	.num-highlight { font-size: 36rpx; font-weight: bold; color: #1a1a1a; margin: 0 4rpx; }
-	.num-highlight.green { color: #C1001C; }
-	.unit { font-size: 24rpx; color: #999; margin-left: 2rpx; }
-	.split-line { width: 1rpx; height: 30rpx; background: #eee; margin: 0 20rpx; }
-	
-	.submit-order-btn { 
-		width: 220rpx; height: 80rpx; background: #e0e0e0; color: #666; font-size: 28rpx; 
-		border-radius: 40rpx; display: flex; align-items: center; justify-content: center; 
-		border: none; margin: 0; transition: all 0.3s;
-	}
-	.submit-order-btn:not([disabled]) {
-		background: #C1001C; color: #fff; font-weight: bold;
-	}
-	
-	/* 全屏缺省页样式 */
-	.empty-state-full { 
-		display: flex; 
-		flex-direction: column; 
-		align-items: center; 
-		justify-content: center; 
-		padding-top: 120rpx; 
-	}
-	.empty-visual { position: relative; margin-bottom: 40rpx; width: 400rpx; height: 400rpx; display: flex; align-items: center; justify-content: center; }
-	.empty-img { width: 320rpx; height: 320rpx; z-index: 2; }
-	.empty-bg-glow { 
-		position: absolute; width: 240rpx; height: 240rpx; 
-		background: radial-gradient(circle, rgba(193, 0, 28, 0.15) 0%, rgba(248, 250, 252, 0) 70%); 
-		z-index: 1; border-radius: 50%; 
-	}
-	.empty-title { font-size: 36rpx; font-weight: bold; color: #1a1a1a; margin-bottom: 80rpx; }
-	.empty-desc { font-size: 26rpx; color: #999; margin-bottom: 60rpx; text-align: center; padding: 0 80rpx; line-height: 1.6; }
-	.empty-action-btn { 
-		width: 320rpx; height: 90rpx; background: #C1001C; color: #fff; 
-		border-radius: 45rpx; font-size: 30rpx; font-weight: bold; 
-		display: flex; align-items: center; justify-content: center; 
-		box-shadow: 0 10rpx 30rpx rgba(193, 0, 28, 0.2);
-		border: none;
-	}
-	.empty-action-btn:active { opacity: 0.8; transform: scale(0.96); }
-
-	.bottom-safe-space { height: 100rpx; }
-</style>

+ 0 - 119
pages/order/success.vue

@@ -1,119 +0,0 @@
-<template>
-	<view class="success-container">
-		<view class="success-card">
-			<icon type="success" size="80" color="#C1001C" class="success-icon"></icon>
-			<text class="status-title">提交成功</text>
-			<text class="status-desc">您的订单已提交,正在等待业务员审核</text>
-			
-			<view class="btn-group">
-				<!-- 再来一单:主按钮 -->
-				<button class="primary-btn" @click="handleReorder">再来一单</button>
-				<!-- 查看订单:次按钮 -->
-				<button class="outline-btn" @click="viewOrder">查看订单</button>
-				<!-- 返回下单页面:文字/轻量化链接风格按钮 -->
-				<button class="text-btn" @click="handleReorder">返回下单页面</button>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	export default {
-		methods: {
-			// 将再来一单和返回页面功能合并:通过 reLaunch 自动重置数据
-			handleReorder() {
-				// reLaunch 会重新加载页面,彻底清空原有表单数据
-				uni.reLaunch({
-					url: '/pages/order/order'
-				});
-			},
-			viewOrder() {
-				// 跳转到订单管理或个人中心(视项目实际路径而定)
-				uni.switchTab({
-					url: '/pages/index/index'
-				});
-			}
-		}
-	}
-</script>
-
-<style scoped>
-	.success-container {
-		width: 100%;
-		min-height: 100vh;
-		background: #f7f8fa;
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		padding-top: 15vh;
-	}
-	.success-card {
-		width: 90%;
-		background: #fff;
-		border-radius: 32rpx;
-		padding: 80rpx 40rpx;
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		box-shadow: 0 4rpx 30rpx rgba(0,0,0,0.03);
-	}
-	.success-icon {
-		margin-bottom: 40rpx;
-	}
-	.status-title {
-		font-size: 40rpx;
-		font-weight: bold;
-		color: #333;
-		margin-bottom: 16rpx;
-	}
-	.status-desc {
-		font-size: 28rpx;
-		color: #999;
-		margin-bottom: 80rpx;
-	}
-	.btn-group {
-		width: 100%;
-		display: flex;
-		flex-direction: column;
-		gap: 24rpx;
-	}
-	.primary-btn {
-		width: 100%;
-		height: 96rpx;
-		background: #C1001C;
-		color: #fff;
-		border-radius: 48rpx;
-		font-size: 32rpx;
-		font-weight: bold;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		border: none;
-		box-shadow: 0 10rpx 20rpx rgba(193, 0, 28, 0.15);
-	}
-	.outline-btn {
-		width: 100%;
-		height: 96rpx;
-		background: #fff;
-		color: #C1001C;
-		border-radius: 48rpx;
-		font-size: 32rpx;
-		font-weight: bold;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		border: 2rpx solid #C1001C;
-	}
-	.text-btn {
-		margin-top: 20rpx;
-		background: transparent;
-		color: #666;
-		font-size: 28rpx;
-		border: none;
-		text-decoration: underline; /* 增加下划线提示可点击 */
-	}
-	.text-btn:active {
-		color: #333;
-		opacity: 0.8;
-	}
-</style>

+ 129 - 0
pages/order/success/index.vue

@@ -0,0 +1,129 @@
+<template>
+	<view class="success-container">
+		<view class="success-card">
+			<icon type="success" size="80" color="#C1001C" class="success-icon"></icon>
+			<text class="status-title">提交成功</text>
+			<text class="status-desc">您的订单已提交,正在等待业务员审核</text>
+
+			<view class="btn-group">
+				<!-- 再来一单:主按钮 -->
+				<button class="primary-btn" @click="handleReorder">再来一单</button>
+				<!-- 查看订单:次按钮 -->
+				<button class="outline-btn" @click="viewOrder">查看订单</button>
+				<!-- 返回下单页面:文字/轻量化链接风格按钮 -->
+				<button class="text-btn" @click="handleReorder">返回下单页面</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	methods: {
+		// 将再来一单和返回页面功能合并:通过 reLaunch 自动重置数据
+		handleReorder() {
+			// reLaunch 会重新加载页面,彻底清空原有表单数据
+			uni.reLaunch({
+				url: '/pages/order/index'
+			});
+		},
+		viewOrder() {
+			// 跳转到订单管理或个人中心(视项目实际路径而定)
+			uni.switchTab({
+				url: '/pages/index/index'
+			});
+		}
+	}
+}
+</script>
+
+<style scoped>
+.success-container {
+	width: 100%;
+	min-height: 100vh;
+	background: #f7f8fa;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	padding-top: 15vh;
+}
+
+.success-card {
+	width: 90%;
+	background: #fff;
+	border-radius: 32rpx;
+	padding: 80rpx 40rpx;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	box-shadow: 0 4rpx 30rpx rgba(0, 0, 0, 0.03);
+}
+
+.success-icon {
+	margin-bottom: 40rpx;
+}
+
+.status-title {
+	font-size: 40rpx;
+	font-weight: bold;
+	color: #333;
+	margin-bottom: 16rpx;
+}
+
+.status-desc {
+	font-size: 28rpx;
+	color: #999;
+	margin-bottom: 80rpx;
+}
+
+.btn-group {
+	width: 100%;
+	display: flex;
+	flex-direction: column;
+	gap: 24rpx;
+}
+
+.primary-btn {
+	width: 100%;
+	height: 96rpx;
+	background: #C1001C;
+	color: #fff;
+	border-radius: 48rpx;
+	font-size: 32rpx;
+	font-weight: bold;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	border: none;
+	box-shadow: 0 10rpx 20rpx rgba(193, 0, 28, 0.15);
+}
+
+.outline-btn {
+	width: 100%;
+	height: 96rpx;
+	background: #fff;
+	color: #C1001C;
+	border-radius: 48rpx;
+	font-size: 32rpx;
+	font-weight: bold;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	border: 2rpx solid #C1001C;
+}
+
+.text-btn {
+	margin-top: 20rpx;
+	background: transparent;
+	color: #666;
+	font-size: 28rpx;
+	border: none;
+	text-decoration: underline;
+	/* 增加下划线提示可点击 */
+}
+
+.text-btn:active {
+	color: #333;
+	opacity: 0.8;
+}
+</style>

+ 203 - 0
utils/request.js

@@ -0,0 +1,203 @@
+/**
+ * 微信小程序统一请求封装
+ * 参考 ruoyi-admin/src/utils/request.ts 结构
+ */
+
+// -------------------- 配置 --------------------
+const BASE_URL = 'http://localhost:8080'
+const TIMEOUT = 30000
+const TOKEN_KEY = 'token'
+
+// 防止 401 弹窗重复弹出
+let isReloginPending = false
+
+// -------------------- 工具 --------------------
+function getToken() {
+	return uni.getStorageSync(TOKEN_KEY) || ''
+}
+
+/**
+ * 将对象序列化为 query string
+ */
+function toQueryString(params) {
+	return Object.entries(params)
+		.filter(([, v]) => v !== undefined && v !== null)
+		.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
+		.join('&')
+}
+
+// -------------------- 响应处理 --------------------
+/**
+ * 处理业务响应码,统一返回 { data, total, rows }(按实际字段存在)
+ */
+function handleResponse(responseData) {
+	return new Promise((resolve, reject) => {
+		const code = responseData.code
+		const msg = responseData.msg || '系统异常'
+
+		if (code === 200) {
+			const result = {}
+			if (responseData.data !== undefined)  result.data  = responseData.data
+			if (responseData.total !== undefined) result.total = responseData.total
+			if (responseData.rows  !== undefined) result.rows  = responseData.rows
+			resolve(result)
+
+		} else if (code === 401) {
+			if (!isReloginPending) {
+				isReloginPending = true
+				uni.removeStorageSync(TOKEN_KEY)
+				uni.showModal({
+					title: '登录已过期',
+					content: '登录状态已过期,请重新登录',
+					showCancel: false,
+					confirmText: '重新登录',
+					confirmColor: '#C1001C',
+					success: () => {
+						isReloginPending = false
+						const pages = getCurrentPages()
+						const currentRoute = pages.length ? '/' + pages[pages.length - 1].route : ''
+						uni.reLaunch({
+							url: '/pages/login/index' + (currentRoute
+								? '?redirect=' + encodeURIComponent(currentRoute)
+								: '')
+						})
+					}
+				})
+			}
+			reject(new Error('无效的会话,或者会话已过期,请重新登录。'))
+
+		} else if (code === 500) {
+			uni.showToast({ title: msg, icon: 'none', duration: 2500 })
+			reject(new Error(msg))
+
+		} else {
+			uni.showToast({ title: msg, icon: 'none', duration: 2500 })
+			reject(new Error(msg))
+		}
+	})
+}
+
+// -------------------- 核心请求 --------------------
+/**
+ * 统一请求方法
+ * @param {object} options
+ * @param {string}  options.url        接口路径,如 '/system/user/list'
+ * @param {string}  [options.method]   请求方法,默认 'GET'
+ * @param {object}  [options.data]     请求体(POST / PUT)
+ * @param {object}  [options.params]   URL 查询参数(GET 也可用此字段)
+ * @param {object}  [options.header]   额外请求头
+ * @param {boolean} [options.isToken]  是否携带 Token,默认 true
+ * @returns {Promise<{data?, total?, rows?}>}
+ */
+function request({ url, method = 'GET', data = {}, params = {}, header = {}, isToken = true } = {}) {
+	return new Promise((resolve, reject) => {
+		const upperMethod = method.toUpperCase()
+
+		// 拼接 query string
+		let finalUrl = BASE_URL + url
+		if (Object.keys(params).length) {
+			finalUrl += '?' + toQueryString(params)
+		}
+
+		// 组装请求头
+		const requestHeader = {
+			'Content-Type': 'application/json',
+			...header
+		}
+		if (isToken) {
+			const token = getToken()
+			if (token) {
+				requestHeader['Authorization'] = 'Bearer ' + token
+			}
+		}
+
+		uni.request({
+			url: finalUrl,
+			method: upperMethod,
+			data: upperMethod === 'GET' ? undefined : data,
+			header: requestHeader,
+			timeout: TIMEOUT,
+			success: (res) => {
+				const { statusCode, data: responseData } = res
+				// HTTP 层异常
+				if (statusCode !== 200) {
+					const httpMsg = `系统接口 ${statusCode} 异常`
+					uni.showToast({ title: httpMsg, icon: 'none' })
+					return reject(new Error(httpMsg))
+				}
+				// 业务层处理
+				handleResponse(responseData).then(resolve).catch(reject)
+			},
+			fail: (err) => {
+				let message = '请求失败,请检查网络'
+				if (err.errMsg) {
+					if (err.errMsg.includes('timeout')) {
+						message = '系统接口请求超时'
+					} else if (err.errMsg.toLowerCase().includes('network') || err.errMsg.includes('连接')) {
+						message = '后端接口连接异常'
+					}
+				}
+				uni.showToast({ title: message, icon: 'none' })
+				reject(new Error(message))
+			}
+		})
+	})
+}
+
+// -------------------- 下载文件 --------------------
+/**
+ * 下载文件并自动打开
+ * @param {string} url          接口路径
+ * @param {object} [params]     URL 查询参数
+ * @param {string} [fileName]   保存文件名(仅做备注,小程序由系统决定)
+ * @returns {Promise<string>}   临时文件路径
+ */
+function download(url, params = {}, fileName = '') {
+	return new Promise((resolve, reject) => {
+		let finalUrl = BASE_URL + url
+		if (Object.keys(params).length) {
+			finalUrl += '?' + toQueryString(params)
+		}
+
+		const header = {}
+		const token = getToken()
+		if (token) {
+			header['Authorization'] = 'Bearer ' + token
+		}
+
+		uni.showLoading({ title: '正在下载...', mask: true })
+
+		uni.downloadFile({
+			url: finalUrl,
+			header,
+			success: (res) => {
+				uni.hideLoading()
+				if (res.statusCode === 200) {
+					uni.openDocument({
+						filePath: res.tempFilePath,
+						showMenu: true,
+						success: () => {
+							resolve(res.tempFilePath)
+						},
+						fail: () => {
+							uni.showToast({ title: '文件打开失败', icon: 'none' })
+							reject(new Error('文件打开失败'))
+						}
+					})
+				} else {
+					uni.showToast({ title: '下载失败', icon: 'none' })
+					reject(new Error('下载失败'))
+				}
+			},
+			fail: () => {
+				uni.hideLoading()
+				uni.showToast({ title: '下载文件出现错误,请联系管理员', icon: 'none' })
+				reject(new Error('下载文件出现错误,请联系管理员'))
+			}
+		})
+	})
+}
+
+// -------------------- 导出 --------------------
+export { request, download }
+export default request