Browse Source

feat:小程序所有功能

颜琼丽 12 hours ago
parent
commit
55e2eee72a
47 changed files with 688 additions and 3289 deletions
  1. 11 37
      jd_logistics-app/api/address.js
  2. 0 25
      jd_logistics-app/api/ai.js
  3. 7 0
      jd_logistics-app/api/mine.js
  4. 5 25
      jd_logistics-app/api/user.js
  5. 2 2
      jd_logistics-app/config/env.js
  6. 50 148
      jd_logistics-app/pages.json
  7. 90 30
      jd_logistics-app/pages/address/address_list.vue
  8. 185 317
      jd_logistics-app/pages/address/edit.vue
  9. 0 716
      jd_logistics-app/pages/ai/ai.vue
  10. 0 60
      jd_logistics-app/pages/ai/components/agentCheck.vue
  11. 0 145
      jd_logistics-app/pages/ai/components/messagesInfo.vue
  12. 0 72
      jd_logistics-app/pages/ai/components/messagesInfoDefault.vue
  13. 0 37
      jd_logistics-app/pages/ai/components/tools.vue
  14. 0 156
      jd_logistics-app/pages/historyList/historyList.vue
  15. 32 7
      jd_logistics-app/pages/index/components/PersonalExpressDialog.vue
  16. 31 30
      jd_logistics-app/pages/index/index.vue
  17. 4 2
      jd_logistics-app/pages/logistics/index.vue
  18. 56 181
      jd_logistics-app/pages/mine/mine.vue
  19. 0 252
      jd_logistics-app/pages/mine/mine1.vue
  20. 58 8
      jd_logistics-app/pages/mine/settlementCode.vue
  21. 0 37
      jd_logistics-app/pages/order/components/OrderFeesInfo.vue
  22. 26 16
      jd_logistics-app/pages/order/components/OrderItem.vue
  23. 1 1
      jd_logistics-app/pages/order/components/TimePopup.vue
  24. 28 25
      jd_logistics-app/pages/order/create_order.vue
  25. 92 92
      jd_logistics-app/pages/order/index.vue
  26. 0 71
      jd_logistics-app/pages/policy/ad_detail.vue
  27. 0 23
      jd_logistics-app/pages/policy/recharge_policy.vue
  28. 0 23
      jd_logistics-app/pages/policy/vip_policy.vue
  29. 0 144
      jd_logistics-app/pages/recharge/recharge.vue
  30. 0 98
      jd_logistics-app/pages/recharge/success_pay.vue
  31. 0 295
      jd_logistics-app/pages/recharge/vip.vue
  32. 0 100
      jd_logistics-app/pages/recharge/wallet.vue
  33. 3 1
      jd_logistics-app/pages/search/search.vue
  34. 0 110
      jd_logistics-app/pages/user/user.vue
  35. 6 0
      jd_logistics-app/pages/webView/webView.vue
  36. BIN
      jd_logistics-app/static/img/index-bg.png
  37. BIN
      jd_logistics-app/static/img/service/aijiqiren.png
  38. BIN
      jd_logistics-app/static/img/service/assistant-avatar.png
  39. BIN
      jd_logistics-app/static/img/service/maikefengyuyin.png
  40. BIN
      jd_logistics-app/static/img/service/send-icon.png
  41. BIN
      jd_logistics-app/static/img/service/tupian.png
  42. BIN
      jd_logistics-app/static/img/service/user-avatar.png
  43. BIN
      jd_logistics-app/static/img/service/xiaoxi.png
  44. BIN
      jd_logistics-app/static/img/voice/cancel.png
  45. BIN
      jd_logistics-app/static/img/voice/recording.gif
  46. BIN
      jd_logistics-app/static/img/voice/recording.png
  47. 1 3
      jd_logistics-app/utils/util.js

+ 11 - 37
jd_logistics-app/api/address.js

@@ -2,43 +2,6 @@ import request from "@/utils/request.js";
 
 
 
 
 
 
-/**
- * 广告轮播图
- * 
- */
-export function adList(data) {
-  return request.get('mini/ad/list', data, {noAuth:true});
-}
-/**
- * 广告轮播图
- * 
- */
-export function getAgentList(data) {
-  return request.get('mini/agent/list', data, {noAuth:true});
-}
-/**
- * 热搜
- * 
- */
-export function getAdSearch(id='') {
-  return request.get(`mini/ad/search/${id}`, {}, {noAuth:true});
-}
-/**
- * 获取客服电话
- * 
- */
-export function getAdServicePhone() {
-  return request.get(`mini/ad/servicePhone`, {}, {noAuth:true});
-}
-/**
- * 广告详情
- * 
- */
-export function getAdDetails({dictCode}) {
-  return request.get(`mini/ad/details/${dictCode}`, {}, {noAuth:true});
-}
-
-
 // 查询地址簿管理列表
 // 查询地址簿管理列表
 export function listBook(query) {
 export function listBook(query) {
   return request.get('system/front/book/list',query)
   return request.get('system/front/book/list',query)
@@ -63,8 +26,19 @@ export function updateBook(data) {
 export function delBook(addressId) {
 export function delBook(addressId) {
   return request.delete('system/front/book/' + addressId)
   return request.delete('system/front/book/' + addressId)
 }
 }
+
+/**
+ * 获取默认地址
+ */
 export function getDefaultAddress() {
 export function getDefaultAddress() {
   return request.get('system/book/getDefaultAddress')
   return request.get('system/book/getDefaultAddress')
 }
 }
 
 
 
 
+/**
+ * 获取最近使用地址
+ */
+export function getLastAddress() {
+  return request.get('system/front/book/getRecentAddresses')
+}
+

+ 0 - 25
jd_logistics-app/api/ai.js

@@ -1,25 +0,0 @@
-import request from "@/utils/request.js";
-
-
-/**
- * 智能体聊天记录列表
- * 
- */
-export function chatHistoryList(data) {
-  return request.get('mini/ai/chatHistoryList', data);
-}
-/**
- * 批量删除会话
- * 
- */
-export function delChatHistoryList(data) {
-  return request.delete('mini/ai/delete', data);
-}
-/**
- * 智能体聊天记录详情
- * 
- */
-export function chatHistoryDetails(data) {
-  return request.get('mini/ai/chatHistoryDetails', data);
-}
-

+ 7 - 0
jd_logistics-app/api/mine.js

@@ -10,6 +10,13 @@ export function getQrcode(data) {
   return request.get('system/front/qrcode', data);
   return request.get('system/front/qrcode', data);
 }
 }
 
 
+/**
+ * 月结码
+ * 
+ */
+export function getSettlementCode(data) {
+  return request.get('system/front/qrcode/getMonthCard', data);
+}
 
 
 
 
 
 

+ 5 - 25
jd_logistics-app/api/user.js

@@ -37,31 +37,11 @@ export function userLogout(data) {
 export function getUserInfoApi(data) {
 export function getUserInfoApi(data) {
   return request.get('system/front/wxmini/getInfo', data);
   return request.get('system/front/wxmini/getInfo', data);
 }
 }
+
 /**
 /**
- * 修改用户信息
- * 
- */
-export function userEdit(data) {
-  return request.put('mini/user/userEdit', data);
-}
-/**
- * 会员套餐列表
- * 
- */
-export function getPlanList(data) {
-  return request.get('mini/plan/list', data);
-}
-/**
- * 查询充值规则列表
- * 
- */
-export function getRuleList(data) {
-  return request.get('mini/rule/list', data);
-}
-/**
- * 钱包流水记录
+ * 根据token获取用户信息
  * 
  * 
  */
  */
-export function getRecordList(data) {
-  return request.get('mini/record/list', data);
-}
+export function getLoginByPwdApi(data) {
+  return request.post('auth/wxmini/pdlogin', data);
+}

+ 2 - 2
jd_logistics-app/config/env.js

@@ -4,9 +4,9 @@
 // let domain = 'http://192.168.100.14:8081' // 赵乔功IP
 // let domain = 'http://192.168.100.14:8081' // 赵乔功IP
 // let domain = 'http://192.168.100.146:8079' // 马二勇
 // let domain = 'http://192.168.100.146:8079' // 马二勇
  // let domain = 'http://192.168.100.92:8080' // 朝龙
  // let domain = 'http://192.168.100.92:8080' // 朝龙
- let domain = 'http://192.168.101.213:8080' // 小明
+  //let domain = 'http://192.168.101.213:8080' // 小明
  
  
-// let domain = 'https://www.bjwdys.com/prod-api' //线上环境
+ let domain = 'https://rjsd.mychery.com/prod-api' //线上环境
 
 
 const getBaseUrl = () => {
 const getBaseUrl = () => {
   // 获取小程序账户信息(包含环境版本)
   // 获取小程序账户信息(包含环境版本)

+ 50 - 148
jd_logistics-app/pages.json

@@ -8,192 +8,94 @@
 			}
 			}
 		},
 		},
 		{
 		{
-			"path" : "pages/mine/mine",
-			"style" : 
-			{
-				"navigationBarTitleText" : "我的",
+			"path": "pages/mine/mine",
+			"style": {
+				"navigationBarTitleText": "我的",
 				"navigationStyle": "custom"
 				"navigationStyle": "custom"
 			}
 			}
 		},
 		},
 		{
 		{
-			"path" : "pages/logistics/index",
-			"style" : 
-			{
-				"navigationBarTitleText" : "物流轨迹"
-				
+			"path": "pages/logistics/index",
+			"style": {
+				"navigationBarTitleText": "物流轨迹"
+
 			}
 			}
 		},
 		},
 		{
 		{
-			"path" : "pages/search/search",
-			"style" : 
-			{
-				"navigationBarTitleText" : "",
+			"path": "pages/search/search",
+			"style": {
+				"navigationBarTitleText": "",
 				"transparentTitle": "always",
 				"transparentTitle": "always",
 				"navigationStyle": "custom"
 				"navigationStyle": "custom"
 			}
 			}
 		},
 		},
 		{
 		{
-			"path" : "pages/mine/settlementCode",
-			"style" : 
-			{
-				"navigationBarTitleText" : "到付月结码"
+			"path": "pages/mine/settlementCode",
+			"style": {
+				"navigationBarTitleText": "到付月结码"
+			}
+		},
+		{
+			"path": "pages/mine/login",
+			"style": {
+				"navigationBarTitleText": "登录"
 			}
 			}
 		},
 		},
 		{
 		{
 			"path": "pages/about/index",
 			"path": "pages/about/index",
-			"style" : 
-			{
-				"navigationBarTitleText" : "关于我们"
+			"style": {
+				"navigationBarTitleText": "关于我们"
 			}
 			}
 		}
 		}
 	],
 	],
 	"subPackages": [
 	"subPackages": [
-		{
-			"root": "pages/user",
-      "name": "user",
-			"pages": [
-				{
-					"path" : "user",
-					"style" : 
-					{
-						"navigationBarTitleText" : "个人资料"
-					}
-				}
-			]
-		},
 		{
 		{
 			"root": "pages/webView",
 			"root": "pages/webView",
-      "name": "webView",
-			"pages": [
-				{
-					"path" : "webView",
-					"style" : 
-					{
-						"navigationBarTitleText" : "个人寄件"
-					}
+			"name": "webView",
+			"pages": [{
+				"path": "webView",
+				"style": {
+					"navigationBarTitleText": ""
 				}
 				}
-			]
-		},
-		{
-			"root": "pages/historyList",
-      "name": "historyList",
-			"pages": [
-				{
-					"path" : "historyList",
-					"style" : 
-					{
-						"navigationBarTitleText" : "历史对话记录"
-					}
-				}
-			]
-		},
-		{
-			"root": "pages/recharge",
-      "name": "recharge",
-			"pages": [
-				{
-					"path" : "recharge",
-					"style" : 
-					{
-						"navigationBarTitleText" : "充值"
-					}
-				},
-				{
-					"path" : "vip",
-					"style" : 
-					{
-						"navigationBarTitleText" : "会员中心",
-						"navigationStyle": "custom",
-						"transparentTitle": "always"
-					}
-				},
-				{
-					"path" : "wallet",
-					"style" : 
-					{
-						"navigationBarTitleText" : "我的钱包"
-					}
-				},
-				{
-					"path" : "success_pay",
-					"style" : 
-					{
-						"navigationBarTitleText" : "支付结果"
-					}
-				}
-			]
-		},
-		{
-			"root": "pages/policy",
-      "name": "policy",
-			"pages": [
-				{
-					"path" : "recharge_policy",
-					"style" : 
-					{
-						"navigationBarTitleText" : "充值协议"
-					}
-				},
-				{
-					"path" : "vip_policy",
-					"style" : 
-					{
-						"navigationBarTitleText" : "VIP会员开通协议"
-					}
-				},
-				{
-					"path" : "ad_detail",
-					"style" : 
-					{
-						"navigationBarTitleText" : "详情"
-					}
-				}
-			]
+			}]
 		},
 		},
 		{
 		{
 			"root": "pages/order",
 			"root": "pages/order",
-      "name": "order",
-			"pages": [
-				{
-					"path" : "index",
-					"style" : 
-					{
-						"navigationBarTitleText" : "订单列表"
+			"name": "order",
+			"pages": [{
+					"path": "index",
+					"style": {
+						"navigationBarTitleText": "订单列表"
 					}
 					}
 				},
 				},
 				{
 				{
-					"path" : "order_detail",
-					"style" : 
-					{
-						"navigationBarTitleText" : "订单详情"
+					"path": "order_detail",
+					"style": {
+						"navigationBarTitleText": "订单详情"
 					}
 					}
 				},
 				},
 				{
 				{
-					"path" : "create_order",
-					"style" : 
-					{
-						"navigationBarTitleText" : "创建订单"
+					"path": "create_order",
+					"style": {
+						"navigationBarTitleText": "创建订单"
 					}
 					}
 				}
 				}
 			]
 			]
 		},
 		},
 		{
 		{
 			"root": "pages/address",
 			"root": "pages/address",
-      "name": "address",
-			"pages": [
-				{
-					"path" : "address_list",
-					"style" : 
-					{
-						"navigationBarTitleText" : "地址薄",
+			"name": "address",
+			"pages": [{
+					"path": "address_list",
+					"style": {
+						"navigationBarTitleText": "地址薄",
 						"enablePullDownRefresh": true
 						"enablePullDownRefresh": true
 					}
 					}
 				},
 				},
 				{
 				{
-					"path" : "edit",
-					"style" : 
-					{
-						"navigationBarTitleText" : "新增地址"
+					"path": "edit",
+					"style": {
+						"navigationBarTitleText": "新增地址"
 					}
 					}
 				}
 				}
 			]
 			]
@@ -205,7 +107,7 @@
 		"navigationBarBackgroundColor": "#fff",
 		"navigationBarBackgroundColor": "#fff",
 		"backgroundColor": "#F5F7FA"
 		"backgroundColor": "#F5F7FA"
 	},
 	},
-		"tabBar": {
+	"tabBar": {
 		"color": "#333333",
 		"color": "#333333",
 		"selectedColor": "#1B64F0",
 		"selectedColor": "#1B64F0",
 		"borderStyle": "black",
 		"borderStyle": "black",
@@ -215,12 +117,12 @@
 			"selectedIconPath": "static/img/tabs/home_active.png",
 			"selectedIconPath": "static/img/tabs/home_active.png",
 			"iconPath": "static/img/tabs/home.png",
 			"iconPath": "static/img/tabs/home.png",
 			"text": "首页"
 			"text": "首页"
-		},{
+		}, {
 			"pagePath": "pages/search/search",
 			"pagePath": "pages/search/search",
 			"selectedIconPath": "static/img/tabs/search_active.png",
 			"selectedIconPath": "static/img/tabs/search_active.png",
 			"iconPath": "static/img/tabs/search.png",
 			"iconPath": "static/img/tabs/search.png",
 			"text": "查快递"
 			"text": "查快递"
-		},{
+		}, {
 			"pagePath": "pages/mine/mine",
 			"pagePath": "pages/mine/mine",
 			"selectedIconPath": "static/img/tabs/user_active.png",
 			"selectedIconPath": "static/img/tabs/user_active.png",
 			"iconPath": "static/img/tabs/user.png",
 			"iconPath": "static/img/tabs/user.png",
@@ -228,4 +130,4 @@
 		}]
 		}]
 	},
 	},
 	"uniIdRouter": {}
 	"uniIdRouter": {}
-}
+}

+ 90 - 30
jd_logistics-app/pages/address/address_list.vue

@@ -2,8 +2,6 @@
 	<view class="address-page">
 	<view class="address-page">
 		<!-- 地址列表 -->
 		<!-- 地址列表 -->
 		<view class="address-list">
 		<view class="address-list">
-
-
 			<!-- 地址项组件 -->
 			<!-- 地址项组件 -->
 			<address-item v-if="addressList.length > 0" v-for="(item, index) in addressList" :key="item.id"
 			<address-item v-if="addressList.length > 0" v-for="(item, index) in addressList" :key="item.id"
 				:address="item" :is-default="item.isDefault" @set-default="handleSetDefault(index)"
 				:address="item" :is-default="item.isDefault" @set-default="handleSetDefault(index)"
@@ -31,7 +29,6 @@
 				<text class="add-btn-text">添加新地址</text>
 				<text class="add-btn-text">添加新地址</text>
 			</button>
 			</button>
 		</view>
 		</view>
-
 	</view>
 	</view>
 </template>
 </template>
 
 
@@ -48,10 +45,10 @@
 	import AddressItem from '@/components/AddressItem.vue'
 	import AddressItem from '@/components/AddressItem.vue'
 	import {
 	import {
 		listBook,
 		listBook,
-		delBook
+		delBook,
+		updateBook
 	} from '../../api/address'
 	} from '../../api/address'
 
 
-
 	const pageNum = ref(1)
 	const pageNum = ref(1)
 	const pageSize = ref(10)
 	const pageSize = ref(10)
 	const recordTotal = ref(0)
 	const recordTotal = ref(0)
@@ -60,7 +57,7 @@
 
 
 	// 模拟地址数据
 	// 模拟地址数据
 	const addressList = ref([])
 	const addressList = ref([])
-	const pages = ref(0) //数据总条
+	const pages = ref(0) // 总页
 
 
 	// 当前要操作的地址索引
 	// 当前要操作的地址索引
 	const currentIndex = ref(-1)
 	const currentIndex = ref(-1)
@@ -75,6 +72,7 @@
 		pageNum.value = 1
 		pageNum.value = 1
 		getAddressList()
 		getAddressList()
 	})
 	})
+
 	// 下拉刷新
 	// 下拉刷新
 	onPullDownRefresh(() => {
 	onPullDownRefresh(() => {
 		pageNum.value = 1
 		pageNum.value = 1
@@ -90,27 +88,70 @@
 	})
 	})
 
 
 	const onSelectAddress = (address) => {
 	const onSelectAddress = (address) => {
-		console.log('-------address---',address)
+		console.log('-------address---', address)
 		if (!addType.value) {
 		if (!addType.value) {
 			return
 			return
 		}
 		}
 		uni.$emit('addressSelected', {
 		uni.$emit('addressSelected', {
-			type:addType.value, // 'sender' 或 'receiver'
+			type: addType.value, // 'sender' 或 'receiver'
 			address // 选中的地址对象
 			address // 选中的地址对象
 		})
 		})
 		uni.navigateBack() // 返回上一页
 		uni.navigateBack() // 返回上一页
 	}
 	}
 
 
 	// 设置默认地址
 	// 设置默认地址
-	const handleSetDefault = (index) => {
-		addressList.value.forEach((item, i) => {
-			item.isDefault = i === index
-		})
+	const handleSetDefault = async (index) => {
+		const currentAddress = addressList.value[index];
+		// 如果已经是默认地址,则无需操作
+		if (currentAddress.defaultFlag === 1) {
+			uni.showToast({
+				title: '已是默认地址',
+				icon: 'none'
+			});
+			return;
+		}
+
+		uni.showLoading({
+			title: '设置中...',
+			mask: true
+		});
+
+		try {
+			// 调用接口设置为默认地址(后端应自动处理其他地址的非默认状态)
+			const res = await updateBook({
+				...currentAddress,
+				defaultFlag: 1
+			});
+
+			if (res.code === 200) {
+				// 更新本地数据:将所有地址的 defaultFlag 设为 0,再将当前项设为 1
+				addressList.value.forEach(item => item.defaultFlag = 0);
+				currentAddress.defaultFlag = 1;
+
+				uni.showToast({
+					title: '设置成功',
+					icon: 'success'
+				});
+			} else {
+				uni.showToast({
+					title: res.msg || '设置失败',
+					icon: 'none'
+				});
+			}
+		} catch (error) {
+			uni.showToast({
+				title: '网络错误,请重试',
+				icon: 'none'
+			});
+			console.error('设置默认地址失败', error);
+		} finally {
+			uni.hideLoading();
+		}
 	}
 	}
 
 
 	// 编辑地址
 	// 编辑地址
 	const handleEdit = (index) => {
 	const handleEdit = (index) => {
-		// 这里可以跳转到编辑页面
+		// 跳转到编辑页面
 		uni.navigateTo({
 		uni.navigateTo({
 			url: '/pages/address/edit?id=' + addressList.value[index].addressId
 			url: '/pages/address/edit?id=' + addressList.value[index].addressId
 		})
 		})
@@ -122,21 +163,40 @@
 		uni.showModal({
 		uni.showModal({
 			title: '确认删除',
 			title: '确认删除',
 			content: '是否确认删除这个地址',
 			content: '是否确认删除这个地址',
-			// showCancel:false,
 			success: async (res) => {
 			success: async (res) => {
 				if (res.confirm) {
 				if (res.confirm) {
-
-					let res = await delBook(addressList.value[index].addressId)
-
-					if (res.code == 200) {
-						addressList.value.splice(currentIndex.value, 1)
-						currentIndex.value = -1
+					uni.showLoading({
+						title: '删除中...',
+						mask: true
+					});
+					try {
+						const delRes = await delBook(addressList.value[index].addressId)
+						if (delRes.code == 200) {
+							// 移除本地数据
+							addressList.value.splice(currentIndex.value, 1)
+							currentIndex.value = -1
+
+							// 如果删除的是默认地址,且列表不为空,可考虑自动将第一个地址设为默认(根据业务需求可选)
+							// 此处不做自动处理,由用户手动设置
+
+							uni.showToast({
+								title: '删除成功',
+								icon: 'success'
+							})
+						} else {
+							uni.showToast({
+								title: delRes.msg || '删除失败',
+								icon: 'none'
+							})
+						}
+					} catch (error) {
 						uni.showToast({
 						uni.showToast({
-							title: '删除成功',
-							icon: 'success'
+							title: '网络错误',
+							icon: 'none'
 						})
 						})
+					} finally {
+						uni.hideLoading()
 					}
 					}
-
 				} else if (res.cancel) {
 				} else if (res.cancel) {
 					console.log('用户点击取消');
 					console.log('用户点击取消');
 				}
 				}
@@ -156,8 +216,6 @@
 		getAddressList(true)
 		getAddressList(true)
 	}
 	}
 
 
-
-
 	// 获取地址列表
 	// 获取地址列表
 	const getAddressList = () => {
 	const getAddressList = () => {
 		const params = {
 		const params = {
@@ -176,12 +234,14 @@
 				const list = res.rows || []
 				const list = res.rows || []
 				addressList.value = pageNum.value == 1 ? list : [...addressList.value, ...list]
 				addressList.value = pageNum.value == 1 ? list : [...addressList.value, ...list]
 				pages.value = Math.ceil(res.total / pageSize.value) || 0
 				pages.value = Math.ceil(res.total / pageSize.value) || 0
-
-
-
 			}
 			}
 		}, err => {
 		}, err => {
 			uni.hideLoading()
 			uni.hideLoading()
+			uni.stopPullDownRefresh()
+			uni.showToast({
+				title: '加载失败',
+				icon: 'none'
+			})
 		})
 		})
 	}
 	}
 </script>
 </script>
@@ -195,7 +255,6 @@
 	}
 	}
 
 
 	.address-list {
 	.address-list {
-
 		padding: 20rpx 30rpx 152rpx;
 		padding: 20rpx 30rpx 152rpx;
 		box-sizing: border-box;
 		box-sizing: border-box;
 	}
 	}
@@ -207,7 +266,6 @@
 		color: #999;
 		color: #999;
 	}
 	}
 
 
-
 	.empty-state {
 	.empty-state {
 		display: flex;
 		display: flex;
 		flex-direction: column;
 		flex-direction: column;
@@ -229,12 +287,14 @@
 		padding: 32rpx;
 		padding: 32rpx;
 		background-color: #fff;
 		background-color: #fff;
 		border-top: 1rpx solid #eee;
 		border-top: 1rpx solid #eee;
+		box-sizing: border-box;
 	}
 	}
 
 
 	.add-btn {
 	.add-btn {
 		height: 88rpx;
 		height: 88rpx;
 		background: #1B64F0;
 		background: #1B64F0;
 		border-radius: 44rpx;
 		border-radius: 44rpx;
+		border: none;
 	}
 	}
 
 
 	.add-btn-text {
 	.add-btn-text {

+ 185 - 317
jd_logistics-app/pages/address/edit.vue

@@ -4,66 +4,55 @@
 		<!-- 物品信息 -->
 		<!-- 物品信息 -->
 		<view class="form-card">
 		<view class="form-card">
 
 
-			<view class="form-item">
-				<view class="item-label">
-					<input class="input-field" placeholder="姓名" placeholder-class="placeholder" maxlength="10"
-						v-model="formData.contactName" />
-				</view>
-				<view class="item-control">
-					<input class="input-field" placeholder="电话" placeholder-class="placeholder" maxlength="11"
-						v-model="formData.contactPhone" />
-				</view>
+			<!-- 姓名 + 电话 并排 -->
+			<view class="form-item row">
+				<input class="input-field flex-item" placeholder="姓名" placeholder-class="placeholder" maxlength="20"
+					v-model="formData.contactName" />
+				<input class="input-field flex-item" placeholder="电话" placeholder-class="placeholder" maxlength="11"
+					v-model="formData.contactPhone" />
 			</view>
 			</view>
 
 
+			<!-- 省市区选择 -->
 			<picker mode="region" @change="changeAddress">
 			<picker mode="region" @change="changeAddress">
-				<view class="form-item form-items">
-					<text
-						class="time-value placeholder">{{ formData.provinceName ? formData.provinceName + formData.cityName + formData.countyName : '省市区' }}</text>
-					<text class="time-value value">{{ selectedTime }}</text>
+				<view class="form-item">
+					<text :class="['address-text', formData.provinceName ? '' : 'placeholder']">
+						{{ formData.provinceName ? formData.provinceName + ' ' + formData.cityName + ' ' + formData.countyName : '省市区' }}
+					</text>
 					<u-icon class="arrow" name='arrow-right' size="18"></u-icon>
 					<u-icon class="arrow" name='arrow-right' size="18"></u-icon>
 				</view>
 				</view>
 			</picker>
 			</picker>
+
+			<!-- 详细地址 -->
 			<view class="form-item">
 			<view class="form-item">
-				<view class="item-control">
-					<input class="input-field" placeholder="详细地址" placeholder-class="placeholder"
-						v-model="formData.detailedAddress" />
-				</view>
+				<input class="input-field full-width" placeholder="详细地址" placeholder-class="placeholder"
+					v-model="formData.detailedAddress" />
 			</view>
 			</view>
 
 
-
-			<view class="form-item">
-				<!-- 设置默认和清空 -->
-				<view class="form-actions">
-					<view class="action-left">
-						<switch :checked="formData.defaultFlag == 1" color="#007AFF" @change="onDefaultChange" />
-						<text class="action-text">设为默认寄件地址</text>
-					</view>
-					<view class="action-right" @click="clearForm">
-						<text class="clear-text">清空</text>
-					</view>
+			<!-- 设置默认和清空 -->
+			<view class="form-item actions">
+				<view class="action-left">
+					<switch :checked="formData.defaultFlag == 1" color="#007AFF" @change="onDefaultChange" />
+					<text class="action-text">设为默认寄件地址</text>
+				</view>
+				<view class="action-right" @click="clearForm">
+					<text class="clear-text">清空</text>
 				</view>
 				</view>
 			</view>
 			</view>
 		</view>
 		</view>
 
 
-
-		<view class="section-title" v-if="false">最近使用地址</view>
+		<view class="section-title"  v-if="addressList.length > 0">最近使用地址</view>
 
 
 		<!-- 最近使用地址 -->
 		<!-- 最近使用地址 -->
-		<view class="recent-address" v-if="false">
-			<!-- 地址项1 -->
-			<view class="address-item" @click="onSelectAddress(addressItem)">
-
-				<AddressInfo v-if="formData.id" :address="addressSend" />
-				
+		<view class="recent-address"  v-if="addressList.length > 0">
+			<view class="address-item" v-for="(item, index) in addressList" :key="item.id"
+			 @click="onSelectAddress(item)">
+				<AddressInfo :address="item" />
 			</view>
 			</view>
-
-		
-		</view>
-		<!-- 下单按钮 -->
-		<view class="submit-btn" @click="onConfirm">
-			确定
 		</view>
 		</view>
 
 
+		<!-- 确定按钮 -->
+		<view class="submit-btn" @click="onConfirm">确定</view>
+
 		<!-- 安全区域占位 -->
 		<!-- 安全区域占位 -->
 		<view class="safe-area"></view>
 		<view class="safe-area"></view>
 	</view>
 	</view>
@@ -78,55 +67,44 @@
 		onLoad
 		onLoad
 	} from '@dcloudio/uni-app'
 	} from '@dcloudio/uni-app'
 	import AddressInfo from '@/components/AddressInfo.vue'
 	import AddressInfo from '@/components/AddressInfo.vue'
-
 	import {
 	import {
 		addBook,
 		addBook,
 		updateBook,
 		updateBook,
-		getBook
+		getBook,getLastAddress
 	} from '@/api/address.js'
 	} from '@/api/address.js'
 
 
-	const addType = ref('') //1 表示从创建订单过来  2 表示编辑  3表示创建
+	const addType = ref('') // 'sender' 或 'receiver',表示从下单页面哪个字段进入
+	
+	const addressList = ref([])
 
 
 	// 表单数据
 	// 表单数据
 	const formData = reactive({
 	const formData = reactive({
-		contactName: '', //姓名
-		contactPhone: '', //电话
-		provinceName: '', //省
-		cityName: '', //市
-		countyName: '', //区
-		addressId: null, //地址ID
-		detailedAddress: '', //详细地址
-		defaultFlag: 0 //是否默认 0非默认1默认
+		addressId:undefined,
+		contactName: '',
+		contactPhone: '',
+		provinceName: '',
+		cityName: '',
+		countyName: '',
+		addressId: null,
+		detailedAddress: '',
+		defaultFlag: 0
 	})
 	})
 
 
-	// 最近地址列表
-	const recentAddresses = ref([{
-			name: '袁添昊',
-			phone: '13344642161',
-			address: '湖北省荆州市新石南路747号'
-		},
-		{
-			name: '袁添昊',
-			phone: '13344642161',
-			address: '湖北省荆州市新石南路747号'
-		}
-	])
-
 	onLoad((option) => {
 	onLoad((option) => {
 		if (option.id) {
 		if (option.id) {
 			formData.addressId = option.id;
 			formData.addressId = option.id;
-			getAddress()
+			getAddress();
 			uni.setNavigationBarTitle({
 			uni.setNavigationBarTitle({
-				title:'编辑地址'
-			})
+				title: '编辑地址'
+			});
 		}
 		}
-		
-		addType.value = option.addType
-		
-	})
+		addType.value = option.addType || '';
+		getAddressList()
+	});
+
+	// 获取地址详情
 	const getAddress = async () => {
 	const getAddress = async () => {
 		let res = await getBook(formData.addressId);
 		let res = await getBook(formData.addressId);
-		console.log(res.data, formData);
 		let {
 		let {
 			addressId,
 			addressId,
 			contactName,
 			contactName,
@@ -137,8 +115,6 @@
 			provinceName,
 			provinceName,
 			cityName
 			cityName
 		} = res.data;
 		} = res.data;
-
-		// formData = {addressId,contactName,contactPhone,countyName,defaultFlag,detailedAddress,provinceName}
 		Object.assign(formData, {
 		Object.assign(formData, {
 			addressId,
 			addressId,
 			contactName,
 			contactName,
@@ -149,83 +125,111 @@
 			detailedAddress,
 			detailedAddress,
 			provinceName
 			provinceName
 		});
 		});
-	}
-	// 选择地址
-	const changeAddress = (e) => {
-		formData.provinceName = e.detail.value[0]
-		formData.cityName = e.detail.value[1]
-		formData.countyName = e.detail.value[2]
-	}
-
+	};
 
 
-	// 省市区选择
-	const onRegionChange = (e) => {
-		formData.region = e.detail.value
-	}
+	// 选择省市区
+	const changeAddress = (e) => {
+		formData.provinceName = e.detail.value[0];
+		formData.cityName = e.detail.value[1];
+		formData.countyName = e.detail.value[2];
+	};
 
 
 	// 默认地址切换
 	// 默认地址切换
 	const onDefaultChange = (e) => {
 	const onDefaultChange = (e) => {
-		formData.defaultFlag = e.detail.value ? 1 : 0
-	}
+		formData.defaultFlag = e.detail.value ? 1 : 0;
+	};
 
 
 	// 清空表单
 	// 清空表单
 	const clearForm = () => {
 	const clearForm = () => {
-		formData.contactName = ''
-		formData.contactPhone = ''
-		formData.provinceName = ''
-		formData.cityName = ''
-		formData.countyName = ''
-		formData.detailedAddress = ''
-		formData.defaultFlag = 0
-	}
-
-	// 确定提交
+		formData.contactName = '';
+		formData.contactPhone = '';
+		formData.provinceName = '';
+		formData.cityName = '';
+		formData.countyName = '';
+		formData.detailedAddress = '';
+		formData.defaultFlag = 0;
+		formData.addressId = null; // 清空ID,避免残留
+	};
+
+	// 校验手机号
+	const isValidPhone = (phone) => /^1[3-9]\d{9}$/.test(phone);
+
+	// 提交
 	const onConfirm = async () => {
 	const onConfirm = async () => {
-		// 这里可以添加表单验证
-		if (!formData.contactName || !formData.contactPhone || !formData.detailedAddress) {
-			uni.showToast({
-				title: '请填写完整信息',
-				icon: 'none'
-			})
-			return
+		// 姓名校验
+		if (!formData.contactName || formData.contactName.trim() === '') {
+			return uni.showToast({ title: '请输入姓名', icon: 'none' });
+		}
+		if (formData.contactName.length > 20) {
+			return uni.showToast({ title: '姓名不能超过20个字符', icon: 'none' });
 		}
 		}
-		
-		if (!formData.provinceName) return uni.showToast({
-				title: '请选择省市区',
-				icon: 'none'
-			})
 
 
-		// 提交逻辑
-		let api = formData.addressId ? updateBook(formData) : addBook(formData)
-		let res = await api;
+		// 电话校验
+		if (!formData.contactPhone) {
+			return uni.showToast({ title: '请输入联系电话', icon: 'none' });
+		}
+		if (!isValidPhone(formData.contactPhone)) {
+			return uni.showToast({ title: '请输入正确的手机号码', icon: 'none' });
+		}
 
 
-		console.log('提交数据:', formData)
-		uni.showToast({
-			title: '提交成功',
-			icon: 'success'
+		// 省市区校验
+		if (!formData.provinceName) {
+			return uni.showToast({ title: '请选择省市区', icon: 'none' });
+		}
+
+		// 详细地址校验
+		if (!formData.detailedAddress || formData.detailedAddress.trim() === '') {
+			return uni.showToast({ title: '请输入详细地址', icon: 'none' });
+		}
+		if (formData.detailedAddress.length > 100) {
+			return uni.showToast({ title: '详细地址不能超过100个字符', icon: 'none' });
+		}
+		uni.showLoading({
+			title:'正在保存',
+			mask: true
 		})
 		})
-		
-		if(res.code == 200){
-			setTimeout(() => {
-				// 返回上一页或执行其他操作
-				formData.addressId = '-1'
-				onSelectAddress(formData)				
-				uni.navigateBack() // 返回上一页
-			}, 400)
+
+		// 提交
+		let api = formData.addressId ? updateBook(formData) : addBook(formData);
+		let res = await api;
+
+		if (res.code === 200) {
+			uni.showToast({ title: '保存成功', icon: 'success' });
+			debugger
+			// 如果接口返回了新地址数据,更新到formData(特别是新增时的ID)
+			if (!formData.addressId) {
+				formData.addressId = res.data
+			}
+			debugger
+			onSelectAddress(formData);
+			uni.hideLoading()
+		} else {
+			uni.hideLoading()
+			uni.showToast({ title: res.msg || '保存失败', icon: 'none' });
 		}
 		}
+	};
 
 
-	}
-	
+	// 选择地址(用于返回数据给上一页)
 	const onSelectAddress = (address) => {
 	const onSelectAddress = (address) => {
-		console.log('-------address---',address)
-		if (addType.value != 'sender' && addType.value != 'receiver') {
-			return
+		if (addType.value !== 'sender' && addType.value !== 'receiver') {
+			return;
 		}
 		}
 		uni.$emit('addressSelected', {
 		uni.$emit('addressSelected', {
-			type:addType.value, // 'sender' 或 'receiver'
+			type: addType.value,
 			address
 			address
+		});
+		
+		uni.navigateBack() // 返回上一页
+	};
+	
+	// 获取地址列表
+	const getAddressList = () => {
+		getLastAddress().then(res => {
+			addressList.value = res.data
+		}, err => {
 		})
 		})
 	}
 	}
+	
 </script>
 </script>
 
 
 <style scoped lang="less">
 <style scoped lang="less">
@@ -238,172 +242,71 @@
 	.form-card {
 	.form-card {
 		background-color: #fff;
 		background-color: #fff;
 		border-radius: 32rpx;
 		border-radius: 32rpx;
-		padding: 0rpx 20rpx;
+		padding: 0 20rpx;
 	}
 	}
 
 
-	.form-title {
-		font-size: 32rpx;
-		font-weight: 600;
-		color: #333;
-		margin-bottom: 32rpx;
-	}
-
-
 	.form-item {
 	.form-item {
 		display: flex;
 		display: flex;
-		justify-content: space-between;
 		align-items: center;
 		align-items: center;
-		height: 100rpx;
+		min-height: 100rpx;
 		border-bottom: 1rpx solid #F1F3F8;
 		border-bottom: 1rpx solid #F1F3F8;
+		padding: 0 0;
 
 
-		&:last-child {
-			border-bottom: none;
-			margin-bottom: 0;
+		&.row {
+			gap: 20rpx;
 		}
 		}
 
 
-		.item-label {
-			font-size: 28rpx;
-			color: #666;
-			font-weight: 400;
-
-			&.required::before {
-				content: '*';
-				color: #ff4444;
-				margin-right: 8rpx;
-			}
+		&:last-child {
+			border-bottom: none;
 		}
 		}
+	}
 
 
-		.item-control {
-			display: flex;
-			align-items: center;
-
-			&.btn {
-				background: #fff;
-				border: 1rpx solid #dcdfe6;
-				border-radius: 5rpx;
-				height: 59rpx;
-				width: 266rpx;
-				box-sizing: border-box;
-			}
+	/* 输入框通用样式 */
+	.input-field {
+		height: 100rpx;
+		line-height: 100rpx;
+		font-size: 28rpx;
+		color: #333;
+		background: transparent;
+		padding: 0;
 
 
+		&.flex-item {
+			flex: 1;
+			width: auto;
+			min-width: 0; // 防止溢出
 		}
 		}
 
 
-		.input-field {
+		&.full-width {
 			width: 100%;
 			width: 100%;
-			height: 100rpx;
-			line-height: 100rpx;
-			padding: 0 24rpx;
-			font-size: 28rpx;
-			color: #333;
-			text-align: left;
-
-
-			&::placeholder {
-				color: #999;
-			}
-		}
-
-		.time-value {
-			display: flex;
-			align-items: center;
-			font-size: 28rpx;
-			color: #333;
-			line-height: 88rpx;
-			height: 88rpx;
-			padding: 0 24rpx;
-
-			&.placeholder {
-				color: #999;
-			}
-
-			.value {
-				margin-right: 16rpx;
-			}
-
-			.arrow {
-				margin-left: 32rpx;
-				color: #999;
-				font-size: 28rpx;
-				font-weight: bold;
-			}
 		}
 		}
-	}
 
 
-	.form-items {
-		&:last-child {
-			border-bottom: 1rpx solid #F1F3F8;
+		.placeholder {
+			color: #999;
 		}
 		}
 	}
 	}
 
 
-	/* 寄件标识 */
-	.send-tag {
-		padding: 40rpx 30rpx 20rpx;
-		background-color: #fff;
-	}
-
-	.send-circle {
-		width: 60rpx;
-		height: 60rpx;
-		border-radius: 50%;
-		background-color: #007AFF;
-		color: #fff;
-		display: flex;
-		align-items: center;
-		justify-content: center;
+	/* 省市区文字样式 */
+	.address-text {
+		flex: 1;
 		font-size: 28rpx;
 		font-size: 28rpx;
-		font-weight: bold;
-	}
-
-	/* 表单区域 */
-	.form-container {
-		background-color: #fff;
-		padding: 0 30rpx;
-		margin-bottom: 20rpx;
-	}
-
-	.form-title {
-		font-size: 18px;
-		font-weight: 500;
+		line-height: 100rpx;
 		color: #333;
 		color: #333;
-		padding: 30rpx 0 20rpx;
-		border-bottom: 1rpx solid #eee;
-	}
-
-	.form-item {
-		width: 100%;
-		padding: 30rpx 0;
-		border-bottom: 1rpx solid #eee;
-	}
 
 
-	.form-input {
-		font-size: 16px;
-		height: 40rpx;
-		line-height: 40rpx;
-		color: #333;
-	}
-
-	.form-input::placeholder {
-		color: #999;
+		&.placeholder {
+			color: #999;
+		}
 	}
 	}
 
 
-	.picker-placeholder {
-		font-size: 16px;
-		height: 40rpx;
-		line-height: 40rpx;
+	.arrow {
+		margin-left: 16rpx;
 		color: #999;
 		color: #999;
+		font-size: 28rpx;
 	}
 	}
 
 
-	.picker-placeholder.has-value {
-		color: #333;
-	}
-
-	/* 表单操作 */
-	.form-actions {
-		width: 100%;
-		display: flex;
+	/* 操作按钮行 */
+	.actions {
 		justify-content: space-between;
 		justify-content: space-between;
-		align-items: center;
-		padding: 30rpx 0;
+		padding: 20rpx 0;
 	}
 	}
 
 
 	.action-left {
 	.action-left {
@@ -417,70 +320,33 @@
 		margin-left: 10rpx;
 		margin-left: 10rpx;
 	}
 	}
 
 
-	.action-right {
-		padding: 10rpx 20rpx;
-	}
-
 	.clear-text {
 	.clear-text {
-		height: 44rpx;
-		font-weight: 400;
 		font-size: 28rpx;
 		font-size: 28rpx;
 		color: #1B64F0;
 		color: #1B64F0;
 		line-height: 44rpx;
 		line-height: 44rpx;
 	}
 	}
 
 
-	/* 最近地址 */
-	.recent-address {
-		background-color: #fff;
-		padding: 0 30rpx;
-	}
-
+	/* 最近地址(隐藏) */
 	.section-title {
 	.section-title {
 		height: 48rpx;
 		height: 48rpx;
 		font-size: 32rpx;
 		font-size: 32rpx;
 		color: #333333;
 		color: #333333;
 		line-height: 48rpx;
 		line-height: 48rpx;
-		margin: 20rpx 0rpx;
+		margin: 20rpx 0;
 		font-weight: bold;
 		font-weight: bold;
 	}
 	}
 
 
+	.recent-address {
+		background-color: #fff;
+		padding: 0 30rpx;
+	}
+
 	.address-item {
 	.address-item {
-		display: flex;
-		justify-content: space-between;
-		align-items: center;
 		padding: 30rpx 0;
 		padding: 30rpx 0;
 		border-bottom: 1rpx solid #eee;
 		border-bottom: 1rpx solid #eee;
 	}
 	}
 
 
-	.address-info {
-		flex: 1;
-	}
-
-	.address-name {
-		font-size: 16px;
-		color: #333;
-		margin-bottom: 10rpx;
-	}
-
-	.address-detail {
-		font-size: 14px;
-		color: #666;
-		line-height: 1.4;
-	}
-
-	.address-select {
-		width: 40rpx;
-		height: 40rpx;
-		border: 1rpx solid #007AFF;
-		border-radius: 50%;
-		margin-left: 20rpx;
-	}
-
-
-	.safe-area {
-		height: 140rpx;
-	}
-
+	/* 确定按钮 */
 	.submit-btn {
 	.submit-btn {
 		position: fixed;
 		position: fixed;
 		bottom: 40rpx;
 		bottom: 40rpx;
@@ -493,11 +359,13 @@
 		display: flex;
 		display: flex;
 		justify-content: center;
 		justify-content: center;
 		align-items: center;
 		align-items: center;
-
 		font-size: 32rpx;
 		font-size: 32rpx;
 		color: #FFFFFF;
 		color: #FFFFFF;
 		line-height: 88rpx;
 		line-height: 88rpx;
-		text-align: center;
 		z-index: 10;
 		z-index: 10;
 	}
 	}
+
+	.safe-area {
+		height: 140rpx;
+	}
 </style>
 </style>

+ 0 - 716
jd_logistics-app/pages/ai/ai.vue

@@ -1,716 +0,0 @@
-<template>
-  <view class="chat-container"  :style="{ 
-    paddingTop: appStore.navbarHeight + 'px',
-  }">
-		<view class="mine_ybt_title flex-center bg_color_fff" 
-		:style="{ height: appStore.navbarHeight + 'px',
-    paddingTop: appStore.statusBarHeight + 'px'}"
-		>
-			<!-- <text class="font_size35 bold">AI客服</text> -->
-     <agentCheck ref="agentCheckRef"></agentCheck>
-		</view>
-    <!-- 聊天消息区域 -->
-    <view class="chat-messages flex-column">
-			<!-- 工具栏 -->
-			<tools @addHuiHuaFn="addHuiHuaFn"></tools>
-			<!-- 消息列表 -->
-      <scroll-view
-        class="scrollViewRef flex_1"
-        scroll-y="true" 
-        :scroll-top="scrollTop"
-        ref="scrollViewRef"
-        :scroll-with-animation="true"
-        @refresherrefresh="handlePullDownRefresh"
-        :refresher-enabled="true"
-        :refresher-triggered="triggered"
-      >
-        <messagesInfoDefault v-if="messages.length==0" 
-        @sendMessage="sendMessage"
-        ref="messagesInfoDefaultRef" key="messagesInfoDefaultRef">
-        </messagesInfoDefault>
-        <messagesInfo 
-        :messages="messages" 
-        :isLoading="isLoading" 
-        @imageLoaded="scrollToBottom"
-        :id="`msg-${messagesKey}`">
-        </messagesInfo>
-      </scroll-view>
-    </view>
-    <!-- 输入区域 -->
-    <view class="input-area">
-      <button class="image-btn" :disabled="isLoading" @click.stop.prevent="uploadImage">
-        <image class="image-icon" src="/static/img/service/tupian.png" model="aspectFit"></image>
-      </button>
-      <button v-if="isvoice"
-        class="record-btn"
-        :class="{ recording: isRecording }"
-        @touchstart="startRecord"
-        @touchend="stopRecord"
-        @touchmove="handleTouchMove"
-        @touchcancel="cancelRecord"
-        :disabled="isRecording && isCancel"
-      >
-        <view v-if="!isRecording">按住说话</view>
-        <view v-if="isRecording && !isCancel">松手发送,上移取消</view>
-        <view v-if="isRecording && isCancel">松手取消</view>
-        <text v-if="recordDuration>0"></text>
-      </button>
-      <input v-else
-        class="input-box"
-        :placeholder="isLoading?'努力回答中...':'发消息或按住说话'"
-        placeholder-style="color: #999"
-        v-model.trim="inputText"
-        :disabled="isLoading"
-        @confirm="sendMessage({chatType:0,msgContent:inputText})"
-      />
-      <button class="isvoice-btn" @click.stop.prevent="isvoice=!isvoice;authorizeRecord()" :disabled="isLoading">
-        <image class="mic-icon" src="/static/img/service/xiaoxi.png" v-if="isvoice" model="aspectFit"></image>
-        <image class="mic-icon" src="/static/img/service/maikefengyuyin.png" v-else model="aspectFit"></image>
-      </button>
-      <button class="send-btn" @click.stop.prevent="sendMessage({chatType:0,msgContent:inputText})" :disabled="isLoading" v-if="!isvoice">
-        <image class="send-icon" src="/static/img/service/send-icon.png"></image>
-      </button>
-      <view class="ai-tip">内容由AI生成,仅供参考</view>
-    </view>
-     <!-- 录音动画/提示 -->
-      <view 
-        class="record-toast" 
-        v-if="isRecording"
-        :class="{ cancel: isCancel }"
-      >
-        <image 
-          v-if="!isCancel"
-          src="/static/img/voice/recording.gif" 
-          class="toast-icon"
-          alt="录音中动画"
-        ></image>
-        <image 
-          v-if="isCancel"
-          src="/static/img/voice/cancel.png" 
-          class="toast-icon"
-          alt="取消录音图标"
-        ></image>
-        <text v-if="!isCancel">正在录音...({{60-recordDuration}})</text>
-        <text v-if="isCancel">松手取消发送</text>
-      </view>
-  </view>
-</template>
-
-<script setup>
-import { ref, nextTick, watch } from 'vue';
-import { onShow,onHide,onLoad } from "@dcloudio/uni-app"
-import { chatHistoryDetails } from '@/api/ai.js';
-import messagesInfo from "./components/messagesInfo.vue";
-import messagesInfoDefault from "./components/messagesInfoDefault.vue";
-import tools from "./components/tools.vue";
-import agentCheck from "./components/agentCheck.vue";
-import {
-	HTTP_REQUEST_URL,
-	HTTP_REQUEST_URL_WS,
-  TOKENNAME
-} from '@/config/app';
-import { chooseImageOne,checkLoginShowModal,checkAiQuotaDailyModal,getUserInfo } from "@/utils/util.js";
-// 封装的websocket
-import WSClient from '@/utils/wsUtil.js';
-import { useAppStore } from '@/stores/app'
-import { useToast } from '@/hooks/useToast'
-import dayjs from "dayjs";
-const appStore = useAppStore();
-const { Toast } = useToast();
-const agentCheckRef = ref(null);
-const messagesInfoDefaultRef = ref(null);
-const newSession = ref(false);//是否新会话
-const historySession = ref('');//是否新会话
-
-// 添加滚动相关变量
-const scrollTimeout = ref(null);
-const scrollViewRef = ref(null);
-const scrollTop = ref(0);
-const messagesKey = ref(0);
-const triggered = ref(false);
-
-// 底部发送功能
-const inputText = ref('');
-const isLoading = ref(false);//思考中
-const isvoice = ref(false);//是否语音输入
-const wsClient = ref(null);
-
-// 模拟聊天消息数据
-const messages = ref([]);
-
-watch(() => appStore.agentId, (state) => {
-  messages.value = [];
-  getAdSearchFn()
-});
-
-onLoad((e)=>{
-  console.log('ai onLoad',e);
-})
-onShow(async()=>{
-  if(!await checkLoginShowModal())return;
-  nextTick(async ()=>{
-    // 初始化选择智能体
-    await agentCheckRef.value.initAgentId();
-     // 初始化完成后获取 agentId
-    console.log('agentId:', agentCheckRef.value.agentId);
-    if(appStore.msgContent){
-      sendMessage({chatType:0,msgContent:appStore.msgContent});
-      appStore.UPDATE_msgContent('');
-    }else if(appStore.sessionId){
-      handlePullDownRefresh();
-    }else{
-      // getAdSearchFn()
-    }
-    
-  })
-
-	aiStartChatFn();
-});
-onHide(()=>{
-  isLoading.value = false;
-  cleanupResources();
-});
-// 新增:添加回话功能
-function addHuiHuaFn(){
-  newSession.value = true;
-  messages.value = [];
-  getAdSearchFn();
-}
-function getAdSearchFn(){
-  nextTick(()=>{
-    setTimeout(()=>{
-      messagesInfoDefaultRef.value.getAdSearchFn();
-    },50)
-  })
-}
-
-function authorizeRecord() { 
-    uni.authorize({
-    scope: 'scope.record',
-    success() {
-      // uni.getRecorderManager();
-    }
-  })
-}
-function aiStartChatFn(){ 
-  cleanupResources();
-  wsClient.value = new WSClient({
-    url: `${HTTP_REQUEST_URL_WS}/api/websocket`,
-    method: 'POST',
-    headers: {
-      "Authorization": 'Bearer '+appStore.token
-    }
-  });
-  // 注册SSE事件
-  registerEvents();
-  wsClient.value.open({type:0,message:inputText.value})
-}
-
-// 
-async function sendMessage({chatType,msgContent=""}){
-  console.log('sendMessage',wsClient.value);
-  // 登录检测
-  if(!await checkLoginShowModal())return;
-  // 今日免费提问次数检测
-  if(!await checkAiQuotaDailyModal())return;
-  if (!msgContent) {
-    Toast({title:'请输入内容'});
-    return;
-  }
-  isLoading.value = true
-  messages.value.push({
-    msgContent,
-    chatType,// 0 (文本),1 (图片)
-    speakerType:0//0用户消息1AI消息
-  });
-  messages.value.push({
-    msgContent: "",
-    event: "start",//sse长链接的返回状态
-    chatType,
-    speakerType:1,
-    messageTimeNow:dayjs().format('HH:mm')
-  });
-  //type  0 (文本),1 (图片)
-  wsClient.value.send({
-    type:chatType,
-    message:msgContent,
-    agentId:agentCheckRef.value.agentId,
-    useBalance:true,
-    newSession:newSession.value,
-    historySession:historySession.value
-  });
-  messagesKey.value++;
-  inputText.value = '';
-  newSession.value = false;
-  // 每次收到新消息时滚动到底部
-  // 如果是图片,子组件里图片加载成功后触发
-  if(chatType!=1)scrollToBottom();
-}
-async function uploadImage(){
-  if(!await checkLoginShowModal())return;
-  const res = await chooseImageOne();
-  console.log('uploadImage',res);
-  if(res){
-    // userInfo.value[key] = res.fileName
-    sendMessage({chatType:1,msgContent:res.data})
-  }
-}
-function cleanupResources(closeSSE=true) {
-  // 关闭SSE连接
-  if (wsClient.value) {
-    // 移除所有事件监听
-    if (wsClient.value.callbacks) {
-      Object.keys(wsClient.value.callbacks).forEach(event => {
-        wsClient.value.callbacks[event] = [];
-      });
-    }
-    wsClient.value.close('clean');
-    wsClient.value = null;
-  }
-}
-function registerEvents(){
-  wsClient.value.on('open', (data) => {
-    console.log('ws连接成功',data);
-  });
-  wsClient.value.on('answer', (data) => {
-    console.log('answer',data.segment,messages.value.length - 1);
-    isLoading.value = false;
-    const lastIndex = messages.value.length - 1;
-    // 保存完整内容(累加片段)
-    // const newFullAnswer = messages.value[lastIndex].msgContent + data.segment;
-    messages.value[lastIndex].msgContent = messages.value[lastIndex].msgContent + data.segment;
-    messagesKey.value++;
-    console.log('answer',messages);
-    // 每次收到新消息时滚动到底部
-    scrollToBottom();
-    nextTick(()=>{
-      // 获取用户信息
-      getUserInfo();
-    })
-  });
-  wsClient.value.on('error', (err) => {
-    isLoading.value = false;
-    console.log('error',err);
-    // aiStartChatFn();
-    Toast({ title: JSON.stringify(err) || "服务器异常" });
-  });
-  wsClient.value.on('close', (data) => {
-    isLoading.value = false;
-    let lastIndex = messages.value.length - 1;
-    console.log('close',data,lastIndex);
-    // 判断关闭原因,取消,删除当前聊天内容,超时提示请求超时
-    switch (data.reason) {
-      case 'timeout': {
-        // 提示超时
-        // uni.showToast({
-        //   title: '请求超时,请重试',
-        //   icon: 'none'
-        // });
-        if(lastIndex>-1)messages.value[lastIndex].msgContent = messages.value[lastIndex].msgContent || "请求超时,请重试";
-        aiStartChatFn();
-        break;
-      }
-      default:
-        break;
-    }
-  });
-}
-
-// 新增:滚动到底部的方法
-function scrollToBottom() {
-  nextTick(() => {
-    // if (scrollTimeout.value) return;
-    // scrollTimeout.value = setTimeout(() => {
-      uni.createSelectorQuery()
-      .select(`#msg-${messagesKey.value}`)
-      .boundingClientRect(rect => {
-        if (rect) {
-          scrollTop.value = rect.height;
-          // 使用更平滑的滚动方式
-          uni.pageScrollTo({
-            scrollTop: rect.bottom,
-            duration: 100
-          })
-        }
-      })
-      .exec();
-      // scrollTimeout.value = null;
-    // }, 80); // 延长节流间隔至80ms,减少冲突
-  });
-}
-
-/*******************************************历史数据********************************************************/ 
-
-const hitstoryParams = ref({
-  pageNum: 0,
-  pageSize: 10,
-  sessionId:appStore.sessionId,
-});
-// 重命名方法,避免与小程序生命周期冲突
-function handlePullDownRefresh() {
-  console.log('下拉刷新触发');
-  triggered.value = true;
-  hitstoryParams.value.pageNum++;
-  chatHistoryDetailsFn();
-}
-function chatHistoryDetailsFn(){
-  hitstoryParams.value.sessionId = appStore.sessionId;
-  chatHistoryDetails(hitstoryParams.value).then(res=>{ 
-    triggered.value = false;
-    console.log('chatHistoryFn',res);
-    const rows = res?.rows || [];
-    if(rows.length==0 && hitstoryParams.value.pageNum>0){
-      hitstoryParams.value.pageNum--;
-      // Toast({title:'没有更多历史记录了'});
-      return;
-    }
-    if(messages.value.length==res.total){
-      Toast({title:'没有更多历史记录了'});
-      return;
-    }
-    messages.value = [...rows, ...messages.value]
-  })
-}
-
-
-/*******************************************语音功能********************************************************/ 
-
-const isRecording = ref(false);// 是否正在录音
-const isCancel = ref(false);         // 是否取消录音
-const recordDuration = ref(0);       // 录音时长(秒)
-const tempFilePath = ref('');        // 录音临时文件路径
-const recordTimer = ref(null);       // 录音计时定时器
-const recorderManager = uni.getRecorderManager();  // 录音管理
-// 开始录音(触摸开始)
-const startRecord = async (e) => {
-  if(!await checkLoginShowModal())return;
-  // 防止冒泡导致的异常
-  e.stopPropagation();
-  
-  // 初始化录音参数
-  const options = {
-    format: 'mp3',       // 录音格式
-    sampleRate: 44100,   // 采样率
-    numberOfChannels: 1, // 声道数
-    encodeBitRate: 96000 // 编码比特率
-  };
-
-  // 开始录音
-  recorderManager.start(options);
-  isRecording.value = true;
-  isCancel.value = false;
-  recordDuration.value = 0;
-
-  // 计时逻辑
-  recordTimer.value = setInterval(() => {
-    recordDuration.value++;
-    // 限制最大录音时长(如60秒)
-    if (recordDuration.value >= 60) {
-      stopRecord();
-    }
-  }, 1000);
-
-  // 监听录音错误
-  recorderManager.onError((err) => {
-    console.error('录音错误:', err);
-    cancelRecord();
-    uni.showToast({ title: '录音失败', icon: 'none' });
-  });
-};
-
-// 停止录音(触摸结束)
-const stopRecord = () => {
-  if (!isRecording.value) return;
-
-  // 清除计时
-  clearInterval(recordTimer.value);
-  
-  // 停止录音
-  recorderManager.stop();
-  recorderManager.onStop((res) => {
-    tempFilePath.value = res.tempFilePath;
-    console.log('recorderManager',res.tempFilePath);
-    
-    // 判断是否取消或录音过短
-    if (isCancel.value) {
-      uni.showToast({ title: '已取消发送', icon: 'none' });
-    } else if (recordDuration.value < 1) {
-      uni.showToast({ title: '录音时间太短', icon: 'none' });
-    } else {
-      // 上传录音并添加到列表
-      uploadVoice(res.tempFilePath);
-    }
-    // 重置状态
-    resetRecordState();
-  });
-
- 
-};
-
-// 处理触摸移动(用于判断是否取消)
-const handleTouchMove = (e) => {
-  if (!isRecording.value) return;
-
-  // 获取按钮位置和触摸位置
-  const buttonRect = uni.createSelectorQuery().select('.record-btn').boundingClientRect();
-  buttonRect.exec((rects) => {
-    const rect = rects[0];
-    if (!rect) return;
-
-    // 计算触摸点与按钮的垂直距离(向上移动超过50px视为取消)
-    const touchY = e.touches[0].clientY;
-    const buttonTop = rect.top;
-    if (touchY < buttonTop - 50) {
-      isCancel.value = true;
-    } else {
-      isCancel.value = false;
-    }
-  });
-};
-
-// 取消录音(触摸中断)
-const cancelRecord = () => {
-  if (!isRecording.value) return;
-  
-  clearInterval(recordTimer.value);
-  recorderManager.stop();
-  resetRecordState();
-  uni.showToast({ title: '已取消发送', icon: 'none' });
-};
-
-// 重置录音状态
-const resetRecordState = () => {
-  isRecording.value = false;
-  isCancel.value = false;
-  recordDuration.value = 0;
-  tempFilePath.value = '';
-};
-
-// 上传录音到服务器
-const uploadVoice = (filePath) => {
-  if (!filePath) return;
-
-  uni.showLoading({ title: '发送中...' });
-  
-  // 调用上传接口
-  uni.uploadFile({
-    url: `${HTTP_REQUEST_URL}/mini/chat/file/voiceUpload`, // 替换为你的后端接口
-    filePath,
-    name: 'file',        // 后端接收文件的参数名
-    formData: {
-      duration: recordDuration.value // 携带录音时长
-    },
-    method: 'POST',
-    header: {
-      "Authorization": appStore.token
-    },
-    success: (res) => {
-      console.log('上传结果:', res);
-      const result = JSON.parse(res.data);
-      if (result.code === 200) {
-        // 上传成功,添加到消息列表
-        sendMessage({ chatType:0,msgContent:result.data });
-        // messages.value.push({
-        //   id: Date.now(),
-        //   isMine: true,
-        //   avatar: '/static/avatar/user.png',
-        //   duration: recordDuration.value,
-        //   url: result.data.url, // 服务器返回的音频地址
-        //   isPlaying: false
-        // });
-      } else {
-        uni.showToast({ title: '发送失败', icon: 'none' });
-      }
-    },
-    fail: (err) => {
-      console.error('语音上传失败:', err);
-      uni.showToast({ title: '发送失败', icon: 'none' });
-    },
-    complete: () => {
-      uni.hideLoading();
-    }
-  });
-};
-</script>
-
-<style scoped lang="scss">
-.mine_ybt_title{
-  position: fixed;
-  top: 0;
-  left: 0;
-  width: 100%;
-  z-index: 1;
-}
-/* 录音区域 */
-.record-btn{
-  flex: 1;
-  height: 70rpx;
-  line-height: 70rpx;
-  font-size: 30rpx;
-  color: #333;
-
-}
-.record-area {
-  padding: 30rpx;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-}
-
-.record-btn {
-  flex: 1;
-  height: 70rpx;
-  line-height: 70rpx;
-  font-size: 30rpx;
-  color: #333;
-  background-color: #f2f2f2;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  border: none;
-}
-
-.record-btn.recording {
-  background-color: #ff4d4f;
-  color: #fff;
-}
-
-.record-btn.cancel {
-  background-color: #999;
-}
-/* 整体容器样式 */
-.chat-container {
-  display: flex;
-  flex-direction: column;
-  height: 100vh;
-  // padding-bottom: 200rpx;
-  /* background-color: #f5f5f5; */
-}
-
-/* 聊天消息区域样式 */
-.chat-messages {
-  flex: 1;
-  overflow-y: auto;
-  .scrollViewRef{
-    // height: 100%;
-     padding: 16rpx;
-     overflow-y: auto;
-  }
-  // height: calc(100vh - 200rpx);
-}
-
-
-
-/* 输入区域样式 */
-.input-area {
-  // position: fixed;
-  // left: 0;
-  // bottom: 0;
-  // width: 100%;
-  display: flex;
-  align-items: center;
-  background-color: #fff;
-  padding: 30rpx 40rpx;
-  border-top: 1rpx solid #e0e0e0;
-  position: relative;
-}
-.ai-tip{
-  position: absolute;
-  bottom: 5rpx;
-  width: calc(100% - 80rpx);
-  text-align: center;
-  font-size: 20rpx;
-  color: #999;
-}
-
-/* 图片图标样式 */
-.image-btn{
-  margin-right: 30rpx;
-  width: 40rpx;
-  height: 40rpx;
-  &[disabled]{
-    .image-icon{
-      opacity: 0.4;
-    }
-  }
-  .image-icon {
-    width: 100%;
-    height:100%;
-  }
-}
-
-/* 输入框样式 */
-.input-box {
-  flex: 1;
-  height: 70rpx;
-  font-size: 30rpx;
-  color: #333;
-  background-color: transparent;
-}
-
-/* 麦克风图标样式 */
-.isvoice-btn{
-  width: 40rpx;
-  height: 40rpx;
-  margin: 0 40rpx;
-  &[disabled]{
-    .mic-icon{
-      opacity: 0.4;
-    }
-  }
-  .mic-icon {
-    width: 100%;
-    height:100%;
-  }
-}
-
-/* 发送按钮样式 */
-.send-btn {
-  width: 60rpx;
-  height: 60rpx;
-  border-radius: 50%;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  padding: 0;
-  &[disabled]{
-    .send-icon{
-      opacity: 0.4;
-    }
-  }
-}
-
-/* 发送图标样式 */
-.send-icon {
-  width: 100%;
-  height: 100%;
-}
-
-/* 录音提示 */
-.record-toast {
-  position: fixed;
-  top: 50%;
-  left: 50%;
-  transform: translate(-50%, -50%);
-  width: 300rpx;
-  height: 300rpx;
-  border-radius: 20rpx;
-  background-color: rgba(0, 0, 0, 0.7);
-  color: #fff;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  z-index: 999;
-}
-
-.record-toast.cancel {
-  background-color: rgba(255, 77, 79, 0.8);
-}
-
-.toast-icon {
-  width: 200rpx;
-  height: 200rpx;
-  margin-bottom: 20rpx;
-}
-</style>

+ 0 - 60
jd_logistics-app/pages/ai/components/agentCheck.vue

@@ -1,60 +0,0 @@
-<template>
- 	<view class="agentCheck">
-    <u-dropdown class="up-dropdown">
-      <u-dropdown-item v-model="agentId" @change="changeAgentId" :title="agentName" :options="agentList"></u-dropdown-item>
-    </u-dropdown>
-  </view>
-</template>
-<script setup>
-import { ref, computed } from "vue";
-import { useAppStore } from "@/stores/app";
-import { getAgentList } from "@/api/home.js";
-import { onLoad } from '@dcloudio/uni-app'
-const appStore = useAppStore();
-const agentId = ref('');
-const agentList = ref([]);
-defineExpose({
-  initAgentId,
-  agentId
-});
-
-//计算属性
-const agentName = computed(()=>{
-  return agentList.value.find(item=>item.value == agentId.value)?.label || '';
-})
-onLoad(()=>{
-  // agentListFn();
-});
-async function agentListFn(){
-	await getAgentList().then(res=>{
-		if(res.code == 200){
-      let rows = res.rows || [];
-			agentList.value = rows.map(item=>{
-        return {
-          label: item.agentName,
-          value: item.agentId
-        }
-      });
-		}
-	})
-}
-async function initAgentId(){
-  await agentListFn();
-  console.log('initAgentId',agentList.value,appStore.agentId);
-  agentId.value = appStore.agentId || agentList.value[0].value;
-  appStore.agentId = agentId.value;
-}
-function changeAgentId(){
-  console.log('changeAgentId',agentId.value);
-  appStore.agentId = agentId.value;
-  appStore.sessionId = '';
-}
-
-</script>
-<style lang="scss" scoped>
-.agentCheck{
-  width: 100vw;
-  position: relative;
-  z-index: 20;
-}
-</style>

+ 0 - 145
jd_logistics-app/pages/ai/components/messagesInfo.vue

@@ -1,145 +0,0 @@
-<template>
-<view class="messagesInfo">
-  <view 
-      v-for="(msg, index) in props.messages" 
-      :key="index" 
-      :class="['message-item', msg.speakerType==0? 'is-mine' : '']"
-    >
-      <image v-if="msg.speakerType==1"
-        src="/static/img/service/aijiqiren.png" 
-        class="message-avatar"
-        mode="aspectFill"
-      />
-      <view class="message-content">
-        <view class="typing-indicator" 
-        v-if="props.isLoading && msg.speakerType==1 && index== props.messages.length-1"
-        >
-          <view class="dot"></view>
-          <view class="dot"></view>
-          <view class="dot"></view>
-        </view>
-        <!-- 0用户消息1AI消息 -->
-        <view v-if="msg.speakerType==0">
-          <!-- 0 (文本),1 (图片) -->
-          <image v-if="msg.chatType==1"
-            :src="msg.msgContent" 
-            class="content-image"
-            mode="widthFix"
-            @load="onImageLoad"
-            @error="onImageLoad"
-            
-          />
-          <text v-else>{{ msg.msgContent }}</text>
-        </view>
-        <zero-markdown-view v-else
-          :markdown="msg.msgContent" 
-          themeColor="#000000" 
-          :aiMode='false' 
-        >
-        </zero-markdown-view>
-        <view v-if="msg.messageTime" class="gray font_size20">{{msg.messageTime}}</view>
-        <view v-else-if="msg.speakerType==1 && msg.messageTimeNow" class="gray font_size20 text_align_right">
-          {{props.isLoading && index== props.messages.length-1?'':msg.messageTimeNow}}
-        </view>
-      </view>
-      <image v-if="msg.speakerType==0"
-        :src="appStore?.userInfo?.userAvatar || appStore.logo || '/static/img/service/user-avatar.png'" 
-        class="message-avatar mine-avatar"
-        mode="aspectFill"
-      />
-    </view>
-</view>
-</template>
-<script setup>
-import { ref } from 'vue'
-import { useAppStore } from "@/stores/app";
-const appStore = useAppStore();
-const emit = defineEmits(['imageLoaded'])
-const props = defineProps({
-  messages: {
-    type: Array,
-    default: [],
-  },
-  isLoading: {
-    type: Boolean,
-    default: false,
-  }
-});
-function onImageLoad() {
-  emit('imageLoaded')
-}
-</script>
-<style lang="scss" scoped>
-.messagesInfo{
-  .content-image{
-    width: 200rpx;
-  }
-    /* 单个消息样式 */
-  .message-item {
-    display: flex;
-    align-items: flex-start;
-    margin-bottom: 16rpx;
-  }
-
-  /* 用户自己发送的消息样式 */
-  .is-mine {
-    justify-content: flex-end;
-  }
-
-  /* 头像样式 */
-  .message-avatar {
-    width: 60rpx;
-    height: 60rpx;
-    border-radius: 50%;
-    margin-right: 16rpx;
-    &.mine-avatar{
-      margin-left: 16rpx;
-      margin-right: 0;
-    }
-  }
-
-  /* 消息内容样式 */
-  .message-content {
-    max-width: 70%;
-    min-width: 100rpx;
-    padding: 16rpx;
-    border-radius: 16rpx;
-    background-color: #fff;
-    box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
-    position: relative;
-  }
-
-  /* 用户自己发送的消息内容样式 */
-  .is-mine.message-content {
-    background-color: #00c853;
-    color: #fff;
-  }
-    /* 打字指示器(加载动画) */
-  .typing-indicator {
-    // position: absolute;
-    // top: 20rpx;
-    // left: 20rpx;
-    display: flex;
-    align-items: center;
-    gap: 8rpx;
-    padding: 5rpx 0;
-  }
-  /* 加载动画关键帧 */
-  @keyframes typing {
-    0% { transform: scale(0); }
-    40% { transform: scale(1); }
-    80% { transform: scale(0); }
-    100% { transform: scale(0); }
-  }
-
-  /* 加载动画的点 */
-  .dot {
-    width: 12rpx;
-    height: 12rpx;
-    background-color: #666;
-    border-radius: 50%;
-    animation: typing 1.4s infinite ease-in-out both;
-  }
-
-}
-</style>

+ 0 - 72
jd_logistics-app/pages/ai/components/messagesInfoDefault.vue

@@ -1,72 +0,0 @@
-<template>
- <view class=" messagesInfoDefault">
-  <view class="flex_1 flex-column-center">
-    <image 
-      src="/static/img/service/aijiqiren.png" 
-      class="service-avatar"
-      mode="widthFix"
-    />
-    <view class="bold font_size40 mt20">Hi~,我是财税小助手!</view>
-  </view>
-  <view class="padding30 border_radius_20 bg_color_fff mt20" v-if="adSearchList.length>0">
-    <view class="font_size30 bold">AI赋能,专业解答财税问题</view>
-    <view class="font_size25 mt20 padding20 bg_color_f5 border_radius_20"
-     @click="sendMessage(item.dictValue)"
-    v-for="(item,index) in adSearchList" :key="index">
-      #{{item.dictValue}}
-    </view>
-    <view class="flex-center mt20">
-      <view class="flex-center-between gray" @click="getAdSearchFn">
-        <img src="/static/img/shuaxin.png" alt="" class="mr20" style="width:40rpx;height:40rpx;"/>
-        <text>换一批</text>
-      </view>
-    </view>
-  </view>
-  <!-- <view class="gray mt20 font_size25 flex-center">( 下拉获取历史数据 )</view> -->
-</view>
-</template>
-<script setup>
-import { ref,watch,nextTick } from "vue";
-import { getAdSearch } from "@/api/home";
-import { useAppStore } from "@/stores/app";
-import { onLoad } from '@dcloudio/uni-app'
-const appStore = useAppStore();
-const adSearchList = ref([]);
-const emit = defineEmits(['sendMessage']);
-
-defineExpose({
-  getAdSearchFn
-});
-
-// watch(() => appStore.agentId, (state) => {
-//   nextTick(()=>{
-//     setTimeout(()=>{ 
-//       getAdSearchFn();
-//     },500)
-//   })
-// });
-
-function getAdSearchFn(){
-  getAdSearch(appStore.agentId).then(res=>{
-    if(res.code == 200){
-      adSearchList.value = res.data || [];
-    }
-  })
-}
-function sendMessage(msgContent){
-  emit('sendMessage',{chatType:0,msgContent});
-}
-
-</script>
-<style lang="scss" scoped>
-.messagesInfoDefault{
-  position: fixed;
-  width: 100%;
-  top: 40rpx;
-  left: 0;
-  padding: 30rpx;
-  .service-avatar{
-    width: 200rpx;
-  }
-}
-</style>

+ 0 - 37
jd_logistics-app/pages/ai/components/tools.vue

@@ -1,37 +0,0 @@
-<template>
- 	<view class="bg_color_fff tools flex-center-between">
-    <view class="font_size25 nowrap">今日次数 <text class="color_price">{{appStore.userInfo?.aiQuotaDaily}}</text> 次</view>
-    <view class="font_size25 nowrap">余额 <text class="color_price">{{appStore.userInfo?.rechargeBalance}}</text> {{appStore.moneyUnit}}</view>
-    <view>
-      <image src="/static/img/wenhua.png" mode="" class="mr20 tool-icon" @click="tohistoryList"/>
-      <image src="/static/img/addHuiHua.png" mode="" class="mr20 ml20 tool-icon" @click="addHuiHuaFn"/>
-    </view>
-  </view>
-</template>
-<script setup>
-import { ref } from "vue";
-import { useAppStore } from "@/stores/app";
-import { onShow} from '@dcloudio/uni-app'
-const appStore = useAppStore();
-const emit = defineEmits(['addHuiHuaFn'])
-// 新增:添加回话功能
-function addHuiHuaFn(){
-  appStore.sessionId = '';
-  emit('addHuiHuaFn');
-}
-function tohistoryList(){
-  uni.navigateTo({
-    url: '/pages/historyList/historyList',
-  })
-}
-
-</script>
-<style lang="scss" scoped>
-.tools{
-  padding: 0 20rpx 20rpx;
-  .tool-icon{
-    width: 50rpx;
-    height: 50rpx;
-  }
-}
-</style>

+ 0 - 156
jd_logistics-app/pages/historyList/historyList.vue

@@ -1,156 +0,0 @@
-<template>
-<view class="historyList padding30">
-  <z-paging
-    ref="pagingRef"
-    class="paginng-contaner"
-    :default-page-size="20"
-    :use-refresher-status-bar-placeholder="true"
-    v-model="list"
-    @query="handleQuery"
-  >
-		<view class="bg_color_fff padding20 border_radius_20">
-			<u-search placeholder="查找对话内容" v-model="keyword" 
-      @search="reloadList" @custom="reloadList" @clear="reloadList"
-      :showAction="false" borderColor="#ffffff"></u-search>
-		</view>
-    <view class="padding20" v-for="group in groupedList" :key="group.date">
-      <view>{{group.date}}</view>
-      <view class="flex-between padding20 bg_color_fff border_radius_20 mt10" 
-      v-for="message in group.messages" :key="message.sessionId">
-        <view class="payment-radio  mr20" @click="checkboxChange(message.sessionId)">
-            <view
-						class="radio-circle"
-						:class="{ checked: selected.includes(message.sessionId) }"
-					></view>
-				</view>
-        <image src="/static/img/wenhua.png" class="mr20" mode="" style="width: 40rpx;height: 40rpx;"/>
-        <view class="flex_1 mr20" @click="add(message.sessionId)">{{message.firstMessageContent}}</view>
-        <text class="gray font_size20">{{message.HS}}</text>
-      </view>
-    </view>
-    <view class="footplaceholder"></view>
-     <!-- foot -->
-    <view class="foot bg_color_fff flex-center-between">
-			<view class="order_btn paddingTB20 flex_1 text_align_center mr20 plain" @click="del">删除</view>
-			<view class="order_btn paddingTB20 flex_1 text_align_center" @click="add">新增会话</view>
-		</view>
-  </z-paging>
-</view>
-</template>
-<script setup> 
-import { ref, computed } from 'vue'
-import dayjs from 'dayjs'
-import { chatHistoryList, delChatHistoryList } from '@/api/ai'
-import { useAppStore } from '@/stores/app'
-const appStore = useAppStore();
-
-const pagingRef = ref();
-const keyword = ref('');
-const list = ref([]);
-const selected = ref([]);
-
-function checkboxChange(sessionId){
-  if(selected.value.includes(sessionId)){
-    selected.value = selected.value.filter(item => item !== sessionId);
-  }else{
-    selected.value.push(sessionId);
-  }
-}
-function del(){
-  if(selected.value.length==0){
-    uni.showToast({
-      title: '请选择要删除的会话',
-      icon: 'none'
-    });
-    return;
-  }
-  uni.showModal({
-    title: '提示',
-    content: '确定要删除吗?',
-    success: function (res) {
-      if (res.confirm) {
-        delChatHistoryList(selected.value).then(res => {
-          if(res.code == 200){
-            uni.showToast({
-              title: '删除成功',
-              icon: 'success'
-            });
-            selected.value = [];
-            reloadList();
-          }
-        })
-      } else if (res.cancel) {
-        console.log('用户点击取消');
-      }
-    }
-  });
-}
-//跳转ai页面
-function add(sessionId){
-  if(sessionId) appStore.sessionId = sessionId;
-  uni.switchTab({
-    url: '/pages/ai/ai'
-  });
-}
-function reloadList(item) {
-  pagingRef.value.reload();
-}
-// 下拉刷新和滚动底部会自动触发此方法
-async function handleQuery(page, pageSize, from) {
-  try {
-    const params = {
-      pageNum: page,
-      pageSize,
-			agentId:appStore.agentId,
-    };
-    const { rows } = await chatHistoryList(params);
-    pagingRef.value.complete(rows);
-  } catch (e) {
-		console.log('msg-comment',e)
-    pagingRef.value.complete(false);
-  }
-}
-const groupedList = computed(() => {
-  const groups = {};
-  
-  list.value.forEach(message => {
-    const date = dayjs(message.firstMessageTime);
-    const today = dayjs().startOf('day');
-    const yesterday = today.subtract(1, 'day');
-    message.HS=date.format('HH:mm');
-    
-    let groupKey;
-    if (date.isSame(today, 'day')) {
-      groupKey = '今天';
-    } else if (date.isSame(yesterday, 'day')) {
-      groupKey = '昨天';
-    } else {
-      groupKey = date.format('YYYY-MM-DD');
-    }
-    
-    if (!groups[groupKey]) {
-      groups[groupKey] = [];
-    }
-    groups[groupKey].push(message);
-  });
-  
-  // 转换并排序
-  return Object.keys(groups)
-    .map(key => ({
-      date: key,
-      messages: groups[key]
-    }))
-    .sort((a, b) => {
-      // 按日期倒序排列
-      if (a.date === '今天') return -1;
-      if (b.date === '今天') return 1;
-      if (a.date === '昨天') return -1;
-      if (b.date === '昨天') return 1;
-      return new Date(b.date) - new Date(a.date);
-    });
-});
-</script>
-<style lang="less" scoped>
-.historyList{
-}
-</style>

+ 32 - 7
jd_logistics-app/pages/index/components/PersonalExpressDialog.vue

@@ -29,16 +29,18 @@
 			</view>
 			</view>
 
 
 			<!-- 取消按钮 -->
 			<!-- 取消按钮 -->
-			<!-- <view class="popup-footer">
+			<view class="popup-footer">
 				<button class="cancel-btn" @click="handleClose">取消</button>
 				<button class="cancel-btn" @click="handleClose">取消</button>
-			</view> -->
+			</view>
 		</view>
 		</view>
 	</u-popup>
 	</u-popup>
 </template>
 </template>
 
 
 <script setup>
 <script setup>
 	import {
 	import {
-		ref
+		ref,
+		watch,
+		onUnmounted
 	} from 'vue'
 	} from 'vue'
 
 
 	const props = defineProps({
 	const props = defineProps({
@@ -52,18 +54,41 @@
 
 
 	const selectedExpress = ref('')
 	const selectedExpress = ref('')
 
 
+	// 监听弹框显示状态,控制底部 tabBar
+	watch(() => props.visible, (newVal) => {
+		if (newVal) {
+			// 弹框打开:隐藏 tabBar(忽略失败回调,防止重复调用报错)
+			uni.hideTabBar({
+				fail: () => {}
+			})
+		} else {
+			// 弹框关闭:显示 tabBar
+			uni.showTabBar({
+				fail: () => {}
+			})
+		}
+	}, { immediate: true }) // immediate 确保组件初始化时如果 visible 为 true 也能正确隐藏
+
+	// 组件卸载时恢复 tabBar 显示(避免状态残留)
+	onUnmounted(() => {
+		uni.showTabBar({
+			fail: () => {}
+		})
+	})
+
 	const selectExpress = (company) => {
 	const selectExpress = (company) => {
 		selectedExpress.value = company
 		selectedExpress.value = company
+	
+		emit('select', company)
+		emit('update:visible', false)
 		// 延时关闭并传递选择结果
 		// 延时关闭并传递选择结果
 		setTimeout(() => {
 		setTimeout(() => {
-			emit('select', company)
-			emit('update:visible', false)
 			const url = encodeURIComponent(company == '京东' ? "https://www.jdl.com/" : "https://www.sf-express.com/chn/sc")
 			const url = encodeURIComponent(company == '京东' ? "https://www.jdl.com/" : "https://www.sf-express.com/chn/sc")
 			uni.navigateTo({
 			uni.navigateTo({
-				url:'/pages/webView/webView?url=' + url
+				url: '/pages/webView/webView?title=个人寄件&url=' + url
 			})
 			})
 			selectedExpress.value = ''
 			selectedExpress.value = ''
-		}, 300)
+		}, 50)
 	}
 	}
 
 
 	const handleClose = () => {
 	const handleClose = () => {

+ 31 - 30
jd_logistics-app/pages/index/index.vue

@@ -5,7 +5,7 @@
 			<swiper class="swiper" :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000"
 			<swiper class="swiper" :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000"
 				:circular="true" indicator-active-color="#1B64F0" indicator-color="rgba(255, 255, 255, 0.6)"
 				:circular="true" indicator-active-color="#1B64F0" indicator-color="rgba(255, 255, 255, 0.6)"
 				indicator-class="swiper-indicator" active-class="swiper-indicator-active">
 				indicator-class="swiper-indicator" active-class="swiper-indicator-active">
-				<swiper-item v-for="(item, index) in swiperList" :key="index">
+				<swiper-item v-for="(item, index) in swiperList" :key="index" @click="handleBannerClick(item)">
 					<view class="swiper-item">
 					<view class="swiper-item">
 						<image class="swiper-img" :src="item.imageUrl" mode="aspectFill" />
 						<image class="swiper-img" :src="item.imageUrl" mode="aspectFill" />
 					</view>
 					</view>
@@ -14,22 +14,24 @@
 		</view>
 		</view>
 
 
 		<view class="btn-container">
 		<view class="btn-container">
-			<view class="btn-item" @click="handleExpress('2')">
-				<image class="button-icon" src="/static/img/index-time.png" />
-				<view class="button-right">
-					<view class="button-title">瑞鲸速达(顺丰)</view>
-					<view class="button-desc">一小时下单取件</view>
-				</view>
-
-			</view>
+			
 			<view class="btn-item" @click="handleExpress('1')">
 			<view class="btn-item" @click="handleExpress('1')">
 				<image class="button-icon" src="/static/img/index-un-time.png" />
 				<image class="button-icon" src="/static/img/index-un-time.png" />
 				<view class="button-right">
 				<view class="button-right">
 					<view class="button-title">瑞鲸速达(京东)</view>
 					<view class="button-title">瑞鲸速达(京东)</view>
 					<view class="button-desc">下单当日取件</view>
 					<view class="button-desc">下单当日取件</view>
 				</view>
 				</view>
-
 			</view>
 			</view>
+			
+	<!-- 		<view class="btn-item" @click="handleExpress('2')">
+				<image class="button-icon" src="/static/img/index-time.png" />
+				<view class="button-right">
+					<view class="button-title">瑞鲸速达(顺丰)</view>
+					<view class="button-desc">一小时下单取件</view>
+				</view>
+
+			</view> -->
+			
 			<view class="btn-item" @click="showExpressDialog">
 			<view class="btn-item" @click="showExpressDialog">
 				<image class="button-icon" src="/static/img/index-personal.png" />
 				<image class="button-icon" src="/static/img/index-personal.png" />
 				<view class="button-right">
 				<view class="button-right">
@@ -88,26 +90,11 @@
 	}
 	}
 
 
 	const handleExpressSelect = (company) => {
 	const handleExpressSelect = (company) => {
-		uni.showToast({
-			title: `已选择${company}物流`,
-			icon: 'success',
-			duration: 1500
-		})
-
-		// 模拟跳转到下单页面
-		setTimeout(() => {
-			uni.showLoading({
-				title: '正在跳转...'
-			})
-
-			setTimeout(() => {
-				uni.hideLoading()
-				// 实际跳转代码
-				// uni.navigateTo({ 
-				//   url: `/pages/order/create?company=${company}` 
-				// })
-			}, 800)
-		}, 500)
+		// uni.showToast({
+		// 	title: `已选择${company}物流`,
+		// 	icon: 'success',
+		// 	duration: 1500
+		// })
 	}
 	}
 
 
 	const handleExpress = async (company) => {
 	const handleExpress = async (company) => {
@@ -116,6 +103,20 @@
 			url: `/pages/order/create_order?product=${company}`
 			url: `/pages/order/create_order?product=${company}`
 		})
 		})
 	}
 	}
+	
+	const handleBannerClick = (item) => {
+	  if (!item.linkUrl) {
+	    // uni.showToast({ title: '暂无跳转链接', icon: 'none' });
+	    return;
+	  }
+	 if (item.linkUrl.startsWith('http://') || item.linkUrl.startsWith('https://')) {
+		uni.navigateTo({
+		  url: `/pages/webview/webview?url=${encodeURIComponent(item.linkUrl)}`
+		})
+	  } else {
+		uni.showToast({ title: '链接格式不支持', icon: 'none' })
+	  }
+	};
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>

+ 4 - 2
jd_logistics-app/pages/logistics/index.vue

@@ -2,9 +2,9 @@
 	<view class="logistics-container">
 	<view class="logistics-container">
 		<!-- 头部快递信息 -->
 		<!-- 头部快递信息 -->
 		<view class="logistics-header">
 		<view class="logistics-header">
-			<image class="logo" src="/static/img/icon-logo-jd.png"></image>
+			<!-- <image class="logo" src="/static/img/icon-logo-jd.png"></image> -->
 			<view class="company-info">
 			<view class="company-info">
-				<text class="company-name">京东物流</text>
+				<text class="company-name">{{compamyName}}</text>
 				<view class="tracking-number">
 				<view class="tracking-number">
 					<text class="number">{{ orderNo }}</text>
 					<text class="number">{{ orderNo }}</text>
 					<text class="copy-btn" @click="copyTrackingNumber(orderNo)">复制</text>
 					<text class="copy-btn" @click="copyTrackingNumber(orderNo)">复制</text>
@@ -63,6 +63,7 @@
 
 
 	// 响应式数据
 	// 响应式数据
 	const orderNo = ref('')
 	const orderNo = ref('')
+	const compamyName = ref('')
 	const scrollHeight = ref(600)
 	const scrollHeight = ref(600)
 	const deliverTraceList = ref([])
 	const deliverTraceList = ref([])
 	const loading = ref(false)
 	const loading = ref(false)
@@ -104,6 +105,7 @@
 		}
 		}
 		queryDeliverTrace(params).then(response => {
 		queryDeliverTrace(params).then(response => {
 			if (response.code === 200 && response.data) {
 			if (response.code === 200 && response.data) {
+				compamyName.value = response.data.compamyName
 				// 按时间倒序排列(最新的在前)
 				// 按时间倒序排列(最新的在前)
 				const list = response.data.data.map((item, index) => ({
 				const list = response.data.data.map((item, index) => ({
 					...item,
 					...item,

+ 56 - 181
jd_logistics-app/pages/mine/mine.vue

@@ -30,14 +30,12 @@
 									账号:{{ userAccount }}
 									账号:{{ userAccount }}
 								</view>
 								</view>
 							</view>
 							</view>
+							<!-- 修改点:去掉 open-type,改为点击跳转登录页 -->
 							<button v-else
 							<button v-else
 								class="login-button"
 								class="login-button"
-								open-type="getPhoneNumber"
-								@getphonenumber="handleGetPhoneNumber"
-								:loading="isLogging"
-								:disabled="isLogging || isProcessing"
+								@click="goToLogin"
 							>
 							>
-								{{ loginButtonText }}
+								请点击登录
 							</button>
 							</button>
 						</view>
 						</view>
 					</view>
 					</view>
@@ -45,7 +43,7 @@
 			</view>
 			</view>
 		</view>
 		</view>
 
 
-		<!-- 菜单功能区域 -->
+		<!-- 菜单功能区域(保持不变) -->
 		<view class="menu-section">
 		<view class="menu-section">
 			<view class="menu-card">
 			<view class="menu-card">
 				<!-- 订单列表 -->
 				<!-- 订单列表 -->
@@ -86,6 +84,15 @@
 
 
 				<!-- 隐私政策 -->
 				<!-- 隐私政策 -->
 				<view class="menu-item" @click="toPrivacyPolicy">
 				<view class="menu-item" @click="toPrivacyPolicy">
+					<view class="menu-item-left">
+						<image src="/static/img/mine/icon-mine-policy.png" class="menu-icon"></image>
+						<text class="menu-text">用户协议</text>
+					</view>
+					<image src="/static/img/arrow-right.png" class="arrow-icon"></image>
+				</view>
+				
+				<!-- 隐私政策 -->
+				<view class="menu-item" @click="toPrivacyPolicy1">
 					<view class="menu-item-left">
 					<view class="menu-item-left">
 						<image src="/static/img/mine/icon-mine-policy.png" class="menu-icon"></image>
 						<image src="/static/img/mine/icon-mine-policy.png" class="menu-icon"></image>
 						<text class="menu-text">隐私政策</text>
 						<text class="menu-text">隐私政策</text>
@@ -122,21 +129,19 @@ import { ref, computed, onMounted } from "vue";
 import headerInfo from "@/components/headerInfo.vue";
 import headerInfo from "@/components/headerInfo.vue";
 import { userLogout } from "@/api/user.js";
 import { userLogout } from "@/api/user.js";
 import { getAdServicePhone } from "@/api/home.js";
 import { getAdServicePhone } from "@/api/home.js";
-import { checkLoginShowModal, quickLogin } from "@/utils/util.js";
+import { checkLoginShowModal } from "@/utils/util.js";  // 移除 quickLogin 导入
 import { onLoad, onShow, onShareAppMessage } from '@dcloudio/uni-app'
 import { onLoad, onShow, onShareAppMessage } from '@dcloudio/uni-app'
 import { useAppStore } from "@/stores/app";
 import { useAppStore } from "@/stores/app";
 
 
 const appStore = useAppStore();
 const appStore = useAppStore();
 
 
-// 响应式数据
-const isLogging = ref(false);
-const isProcessing = ref(false);
+// 响应式数据(移除了 isLogging, isProcessing)
 const pageLoading = ref(false);
 const pageLoading = ref(false);
 const phoneNumber = ref('');
 const phoneNumber = ref('');
 
 
 // 计算属性
 // 计算属性
 const isLoggedIn = computed(() => {
 const isLoggedIn = computed(() => {
-	return !!(appStore.userInfo?.phonenumber && appStore.token);
+	return appStore.token;
 });
 });
 
 
 const userAvatar = computed(() => {
 const userAvatar = computed(() => {
@@ -154,25 +159,17 @@ const userAccount = computed(() => {
 	return  appStore.userInfo?.userName || appStore.userInfo?.phonenumber || '';
 	return  appStore.userInfo?.userName || appStore.userInfo?.phonenumber || '';
 });
 });
 
 
-const loginButtonText = computed(() => {
-	if (isLogging.value) return '登录中...';
-	if (isProcessing.value) return '处理中...';
-	return '请点击登录';
-});
-
 onShareAppMessage((res) => {
 onShareAppMessage((res) => {
 	return appStore.onShareAppMessageObj;
 	return appStore.onShareAppMessageObj;
 });
 });
 
 
 onLoad(() => {
 onLoad(() => {
 	getAdServicePhoneFn();
 	getAdServicePhoneFn();
-	// 检查用户登录状态
 	checkUserStatus();
 	checkUserStatus();
 });
 });
 
 
 onShow(() => {
 onShow(() => {
-	// 页面显示时检查是否需要重新获取用户信息
-	if (appStore.token && !appStore.userInfo?.userPhone) {
+	if (appStore.token) {
 		appStore.USERINFO();
 		appStore.USERINFO();
 	}
 	}
 });
 });
@@ -200,147 +197,63 @@ function getAdServicePhoneFn() {
 	});
 	});
 }
 }
 
 
-// 跳转到用户信息页
-async function toUser() {
-	if (!await checkLoginShowModal()) return;
+// 跳转到登录页(新增)
+function goToLogin() {
 	uni.navigateTo({
 	uni.navigateTo({
-		url: '/pages/user/user'
+		url: '/pages/mine/login'
 	});
 	});
 }
 }
 
 
+// 跳转到用户信息页(保留原有逻辑)
+async function toUser() {
+	// if (!await checkLoginShowModal()) return;
+	// uni.navigateTo({ url: '/pages/user/user' });
+}
+
 // 跳转到订单列表
 // 跳转到订单列表
 async function toOrderList() {
 async function toOrderList() {
 	if (!await checkLoginShowModal()) return;
 	if (!await checkLoginShowModal()) return;
-	uni.navigateTo({
-		url: '/pages/order/index'
-	});
+	uni.navigateTo({ url: '/pages/order/index' });
 }
 }
 
 
 // 跳转到地址簿
 // 跳转到地址簿
 async function toAddressBook() {
 async function toAddressBook() {
 	if (!await checkLoginShowModal()) return;
 	if (!await checkLoginShowModal()) return;
-	uni.navigateTo({
-		url: '/pages/address/address_list'
-	});
+	uni.navigateTo({ url: '/pages/address/address_list' });
 }
 }
 
 
 // 跳转到月结码
 // 跳转到月结码
 async function toSettlementCode() {
 async function toSettlementCode() {
 	if (!await checkLoginShowModal()) return;
 	if (!await checkLoginShowModal()) return;
-	uni.navigateTo({
-		url: '/pages/mine/settlementCode'
-	});
+	uni.navigateTo({ url: '/pages/mine/settlementCode' });
 }
 }
 
 
 // 跳转到隐私政策
 // 跳转到隐私政策
 async function toPrivacyPolicy() {
 async function toPrivacyPolicy() {
 	uni.navigateTo({
 	uni.navigateTo({
-		url: '/pages/webview/webview?url=' + encodeURIComponent('https://your-domain.com/privacy')
+		url: '/pages/webView/webView?title=用户协议&url=' + encodeURIComponent('https://rjsd.mychery.com/user_agreement.html')
 	});
 	});
 }
 }
 
 
-// 跳转到关于我们
-async function toAboutUs() {
+// 跳转到隐私政策
+async function toPrivacyPolicy1() {
 	uni.navigateTo({
 	uni.navigateTo({
-		url: '/pages/about/index'
+		url: '/pages/webView/webView?title=隐私政策&url=' + encodeURIComponent('https://rjsd.mychery.com/privacy_policy.html')
 	});
 	});
 }
 }
 
 
-// 处理获取手机号登录 - 使用优化后的quickLogin
-async function handleGetPhoneNumber(e) {
-	if (isLogging.value || isProcessing.value) return;
-	
-	isLogging.value = true;
-	isProcessing.value = true;
-	
-	// 先隐藏loading(如果有)
-	uni.hideLoading();
-	
-	try {
-		// 显示加载提示
-		uni.showLoading({
-			title: '登录中...',
-			mask: true
-		});
-		
-		// 调用快速登录,并传入自定义回调
-		await quickLogin(e, {
-			onSuccess: (result) => {
-				console.log('页面登录成功回调:', result);
-		        appStore.UPDATE_USERINFO(result.data)
-			},
-			onFail: (error) => {
-				console.log('页面登录失败回调:', error);
-				// 页面特定的失败逻辑
-				let errorMessage = error.message || '登录失败,请重试';
-				
-				if (error.type === 'auth_denied') {
-					errorMessage = '您拒绝了授权,无法登录';
-					// 如果是授权拒绝,可以显示引导重新授权的提示
-					uni.showModal({
-						title: '提示',
-						content: '需要手机号授权才能正常使用,请点击右上角菜单,选择「重新进入小程序」后重新授权',
-						showCancel: false,
-						confirmText: '知道了'
-					});
-				} else if (error.type === 'auth_code_missing') {
-					errorMessage = '授权信息不完整';
-				} else if (error.type === 'login_failed') {
-					errorMessage = error.originalError || error.message;
-				}
-				
-				// 只在需要时显示Toast(非授权拒绝的情况)
-				if (error.type !== 'auth_denied') {
-					uni.showToast({
-						title: errorMessage,
-						icon: 'none',
-						duration: 3000
-					});
-				}
-			},
-			redirectUrl: '/pages/mine/mine'
-		});
-		
-	} catch (error) {
-		console.error('登录处理异常:', error);
-		// 这里是未在onFail中捕获的错误(应该是很少出现的)
-		uni.showToast({
-			title: error,
-			icon: 'none'
-		});
-	} finally {
-		isLogging.value = false;
-		isProcessing.value = false;
-		// 确保loading被隐藏
-		setTimeout(() => {
-			uni.hideLoading();
-		}, 300);
-	}
+// 跳转到关于我们
+async function toAboutUs() {
+	uni.navigateTo({ url: '/pages/about/index' });
 }
 }
 
 
 // 拨打电话
 // 拨打电话
 const makePhoneCall = () => {
 const makePhoneCall = () => {
 	if (!phoneNumber.value) {
 	if (!phoneNumber.value) {
-		uni.showToast({
-			title: '客服电话暂时无法接通',
-			icon: 'none'
-		});
+		uni.showToast({ title: '客服电话暂时无法接通', icon: 'none' });
 		return;
 		return;
 	}
 	}
-	
-	uni.makePhoneCall({
-		phoneNumber: phoneNumber.value,
-		success: () => {
-			console.log('成功唤起拨号界面');
-		},
-		fail: (err) => {
-			console.error('唤起拨号界面失败', err);
-			uni.showToast({
-				title: '拨号失败',
-				icon: 'none'
-			});
-		}
-	});
+	uni.makePhoneCall({ phoneNumber: phoneNumber.value });
 };
 };
 
 
 // 退出登录
 // 退出登录
@@ -350,29 +263,7 @@ function userLogoutFn() {
 		content: '确认要退出登录吗?',
 		content: '确认要退出登录吗?',
 		success: function(res) {
 		success: function(res) {
 			if (res.confirm) {
 			if (res.confirm) {
-				// uni.showLoading({
-				// 	title: '正在退出...'
-				// });
 				appStore.LOGOUT();
 				appStore.LOGOUT();
-				// userLogout({}).then(res => {
-				// 	appStore.LOGOUT();
-				// 	uni.hideLoading();
-				// 	uni.showToast({
-				// 		title: '已退出登录',
-				// 		icon: 'success'
-				// 	});
-					
-				// 	// 延迟刷新页面状态
-				// 	setTimeout(() => {
-				// 		uni.$emit('userLogoutSuccess');
-				// 	}, 500);
-				// }).catch(err => {
-				// 	uni.hideLoading();
-				// 	uni.showToast({
-				// 		title: '退出失败',
-				// 		icon: 'none'
-				// 	});
-				// });
 			}
 			}
 		}
 		}
 	});
 	});
@@ -380,12 +271,12 @@ function userLogoutFn() {
 </script>
 </script>
 
 
 <style lang="less" scoped>
 <style lang="less" scoped>
+/* 样式优化:昵称和部门自适应布局,部门背景完整 */
 .mine-container {
 .mine-container {
 	height: 100vh;
 	height: 100vh;
 	background: linear-gradient(135deg, #CFE9FF 0%, #F5F7FA 50.86%);
 	background: linear-gradient(135deg, #CFE9FF 0%, #F5F7FA 50.86%);
 	position: relative;
 	position: relative;
 
 
-	// 用户信息区域
 	.user-header {
 	.user-header {
 		padding: 0rpx 24rpx;
 		padding: 0rpx 24rpx;
 
 
@@ -398,40 +289,42 @@ function userLogoutFn() {
 			.avatar-section {
 			.avatar-section {
 				display: flex;
 				display: flex;
 				align-items: center;
 				align-items: center;
-				min-height: 144rpx; // 添加最小高度防止闪烁
+				min-height: 144rpx;
 
 
 				.user-text-info {
 				.user-text-info {
 					flex: 1;
 					flex: 1;
 					display: flex;
 					display: flex;
 					flex-direction: column;
 					flex-direction: column;
 					justify-content: center;
 					justify-content: center;
-					min-height: 144rpx; // 添加最小高度防止闪烁
+					min-height: 144rpx;
+					overflow: hidden; /* 防止内部内容溢出 */
 				}
 				}
 
 
 				.user-name-section {
 				.user-name-section {
 					margin-left: 16rpx;
 					margin-left: 16rpx;
-					min-height: 100rpx; // 固定高度防止闪烁
+					min-height: 100rpx;
 					display: flex;
 					display: flex;
 					flex-direction: column;
 					flex-direction: column;
 					justify-content: center;
 					justify-content: center;
+					width: 100%; /* 确保占满父容器宽度 */
 					
 					
 					.name-section {
 					.name-section {
-						width: 530rpx;
-						height: 52rpx;
 						display: flex;
 						display: flex;
 						align-items: center;
 						align-items: center;
 						margin-bottom: 8rpx;
 						margin-bottom: 8rpx;
+						width: 540rpx;
+						overflow: hidden; /* 隐藏超出部分,避免影响布局 */
 					}
 					}
 					
 					
 					.user-name {
 					.user-name {
+						min-width: 0; /* 允许截断 */
 						font-weight: bold;
 						font-weight: bold;
 						font-size: 36rpx;
 						font-size: 36rpx;
 						color: #333333;
 						color: #333333;
-						text-align: center;
+						white-space: nowrap;
+						overflow: hidden;
+						text-overflow: ellipsis;
 						line-height: 1;
 						line-height: 1;
-						white-space: nowrap; // 强制文本在一行内显示
-						overflow: hidden; // 隐藏溢出部分
-						text-overflow: ellipsis; // 用省略号代替被隐藏的文本
 					}
 					}
 
 
 					.login-button {
 					.login-button {
@@ -452,10 +345,6 @@ function userLogoutFn() {
 						&::after {
 						&::after {
 							border: none;
 							border: none;
 						}
 						}
-						
-						&[disabled] {
-							opacity: 0.7;
-						}
 					}
 					}
 				}
 				}
 
 
@@ -478,16 +367,13 @@ function userLogoutFn() {
 				margin-left: 8rpx;
 				margin-left: 8rpx;
 				padding: 7rpx 16rpx;
 				padding: 7rpx 16rpx;
 				line-height: 1;
 				line-height: 1;
-				flex-shrink: 0;
-				max-width: 250rpx;
-				white-space: nowrap; // 强制文本在一行内显示
-				overflow: hidden; // 隐藏溢出部分
-				text-overflow: ellipsis; // 用省略号代替被隐藏的文本
+				white-space: nowrap;
+				overflow: hidden;
+				text-overflow: ellipsis;
 			}
 			}
 		}
 		}
 	}
 	}
 
 
-	// 菜单区域
 	.menu-section {
 	.menu-section {
 		padding: 0 20rpx;
 		padding: 0 20rpx;
 		margin-top: 20rpx;
 		margin-top: 20rpx;
@@ -504,12 +390,7 @@ function userLogoutFn() {
 			background: #FFFFFF;
 			background: #FFFFFF;
 			border-radius: 24rpx;
 			border-radius: 24rpx;
 			margin-bottom: 20rpx;
 			margin-bottom: 20rpx;
-			min-height: 112rpx; // 固定高度防止闪烁
-
-			&:last-child {
-				border-bottom: none;
-				margin-bottom: 0;
-			}
+			min-height: 112rpx;
 
 
 			.menu-item-left {
 			.menu-item-left {
 				display: flex;
 				display: flex;
@@ -540,7 +421,7 @@ function userLogoutFn() {
 
 
 			&.logout-item {
 			&.logout-item {
 				height: 88rpx;
 				height: 88rpx;
-				background: #F52929;
+				background: #FEEAEA;
 				border-radius: 32rpx;
 				border-radius: 32rpx;
 				display: flex;
 				display: flex;
 				justify-content: center;
 				justify-content: center;
@@ -548,7 +429,7 @@ function userLogoutFn() {
 				.logout-text {
 				.logout-text {
 					font-weight: 400;
 					font-weight: 400;
 					font-size: 32rpx;
 					font-size: 32rpx;
-					color: #FFFFFF;
+					color: #F52929;
 					text-align: center;
 					text-align: center;
 				}
 				}
 			}
 			}
@@ -556,7 +437,6 @@ function userLogoutFn() {
 	}
 	}
 }
 }
 
 
-// 动画效果
 .menu-item {
 .menu-item {
 	transition: all 0.3s ease;
 	transition: all 0.3s ease;
 	opacity: 1;
 	opacity: 1;
@@ -574,28 +454,23 @@ function userLogoutFn() {
 
 
 .department-badge {
 .department-badge {
 	transition: all 0.3s ease;
 	transition: all 0.3s ease;
-
 	&:active {
 	&:active {
 		transform: scale(0.95);
 		transform: scale(0.95);
 	}
 	}
 }
 }
 
 
-// 响应式适配
 @media (max-width: 375px) {
 @media (max-width: 375px) {
 	.menu-section {
 	.menu-section {
 		padding: 0 20rpx !important;
 		padding: 0 20rpx !important;
 	}
 	}
-
 	.menu-card {
 	.menu-card {
 		padding: 0 20rpx !important;
 		padding: 0 20rpx !important;
 	}
 	}
-
 	.menu-text {
 	.menu-text {
 		font-size: 30rpx !important;
 		font-size: 30rpx !important;
 	}
 	}
 }
 }
 
 
-// 防止闪烁的全局样式
 view, text, image {
 view, text, image {
 	will-change: auto;
 	will-change: auto;
 	backface-visibility: hidden;
 	backface-visibility: hidden;

+ 0 - 252
jd_logistics-app/pages/mine/mine1.vue

@@ -1,252 +0,0 @@
-<template>
-	<view class="mine_ybt bg_color_primary">
-		<view class="mine_ybt_top pad30">
-			<headerInfo title="个人中心"></headerInfo>
-			 <view class="flex-center-between color_fff mg20">
-				<u-avatar  @click="toUser"
-					size="100rpx"
-					shape="circle"
-					:src="appStore?.userInfo?.avatar"
-					mode="aspectFill"
-				></u-avatar>
-				<view class="flex_1 flex-center-between ml20">
-					<view class="">
-						<view class="font_size35">
-							<text v-if="appStore.userInfo?.userPhone" class="mr20"  @click="toUser">{{appStore.userInfo?.nickName}}</text>
-							<!-- <text v-else @click="toLogin()">请点击登录</text> -->
-							<button v-else
-								class="login-btn" 
-								open-type="getPhoneNumber"
-								@getphonenumber="getPhoneNumberFn"
-							>
-								请点击登录
-							</button>
-							<text v-if="appStore.userInfo?.memberStatus==1" class="memberPlanName">{{appStore.userInfo?.memberPlanName}}</text>
-						</view>
-						<view class="font_size25 mt20" v-if="appStore.userInfo?.memberExpire">
-							<!-- <text>{{appStore.userInfo?.memberPlanName}}</text> -->
-							<text class="vipTime">到期时间:{{appStore.userInfo?.memberExpire}}</text>
-						</view>
-					</view>
-					<view class="order_btn flex-center share_btn" @click="toUser">
-						<view class="flex-center border_radius_20">
-							<text>编辑资料</text>
-						</view>
-					</view>
-				</view>
-			 </view>
-			<view class="border_radius_20 padding20 vipCar flex-center-between">
-				<view class="flex_1 flex-center-flex-start mr20">
-					<image src="/static/img/mine/vipcard.png" mode="" class="vipcard-img mr10"></image>
-					<text style="color: rgb(246, 223, 185);">开通会员解锁更多权益</text>
-				</view>
-				<view class="order_btns jiesuo border_radius_20 font_size25" @click="toVip">
-					{{appStore.userInfo?.memberStatus==1?'查看权益' : '立即解锁'}}
-				</view>
-			</view>
-		</view>
-		<view class="mine_content padding30 mt20">
-			<!-- 我的订单 -->
-			<view class="font_size25 padding20 border_radius_20 bg_color_fff mb20">
-				<view class="flex-center-between paddingTB20 border-bottom menuList"
-				@click="toPage(item)"
-				 v-for="(item, index) in menuList" :key="index">
-					<view class="flex-center-flex-start mr20 flex_1">
-						<image :src="item.img" mode="" class="order-img mr20"></image>
-						<text>{{item.name}}</text>
-					</view>
-					<image src="/static/img/arrow-right.png" mode="widthFix" class="menu_img"></image>
-				</view>
-				<view class="flex-center-between paddingTB20 border-bottom menuList" @click="makePhoneCall">
-					<view class="flex-center-flex-start mr20 flex_1">
-						<image src="/static/img/mine/kefu.png" mode="" class="order-img mr20"></image>
-						<text>服务热线</text>
-					</view>
-					<image src="/static/img/arrow-right.png" mode="widthFix" class="menu_img"></image>
-				</view>
-				<view class="flex-center-between paddingTB20 border-bottom menuList" v-if="appStore.userInfo?.userPhone"
-				@click="userLogoutFn(item)">
-					<view class="flex-center-flex-start mr20 flex_1">
-						<image src="/static/img/mine/Logout.png" mode="" class="order-img mr20"></image>
-						<text>退出登录</text>
-					</view>
-					<image src="/static/img/arrow-right.png" mode="widthFix" class="menu_img"></image>
-				</view>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script setup>
-import { ref } from "vue";
-import { userLogout } from "@/api/user.js";
-import { getAdServicePhone } from "@/api/home.js";
-import headerInfo from "@/components/headerInfo.vue";
-import { telEncrypt,checkLoginShowModal, getPhoneNumber } from "@/utils/util.js";
-import { onLoad, onShareAppMessage} from '@dcloudio/uni-app'
-import { useAppStore } from "@/stores/app";
-const appStore = useAppStore();
-
-onShareAppMessage((res) => {
-  return appStore.onShareAppMessageObj
-})
-
-	const menuList = ref([
-		{
-			name: '我的钱包',
-			img: "/static/img/mine/money.png",
-			url: '/pages/recharge/wallet'
-		},
-		{
-			name: '去充值',
-			img: "/static/img/mine/vip.png",
-			url: '/pages/recharge/recharge'
-		},
-		// {
-		// 	name: '会员充值记录',
-		// 	img: "/static/img/mine/chongzhijulu.png",
-		// 	url: ''
-		// },
-		{
-			name: '我的订单',
-			img: "/static/img/mine/order.png",
-			url: '/pages/order/order_list'
-		}
-	]);
-
-onLoad(() => {
-	getAdServicePhoneFn();
-});
-async function toUser(){
-	if(!await checkLoginShowModal())return;
-	uni.navigateTo({
-		url: '/pages/user/user'
-	});
-}
-async function toVip(){
-	if(!await checkLoginShowModal())return;
-	uni.navigateTo({
-		url: '/pages/recharge/vip'
-	});
-}
-async function toPage(item){
-	if(!await checkLoginShowModal())return;
-	if(!item.url) return;
-	uni.navigateTo({
-		url: item.url
-	});
-}
-function getPhoneNumberFn(e){
-  getPhoneNumber(e)
-};
-// 退出登录
-function userLogoutFn(){
-	//确认退出登录吗
-	uni.showModal({
-		title: '提示',
-		content: '确认要退出登录吗?',
-		success: function (res) {
-			if (res.confirm) {
-				userLogout({}).then(res=>{ 
-					appStore.LOGOUT();
-				})
-			}
-		}
-	})
-}
-// 获取客服电话
-const phoneNumber = ref('');
-function getAdServicePhoneFn() {
-  getAdServicePhone({}).then(res => {
-    phoneNumber.value = res.data?.servicePhone || '';
-  }).catch(err => {
-    console.log(err);
-  });
-}
-// 拨打电话方法
-const makePhoneCall = () => {
-  if(!phoneNumber.value){
-    Toast({title:'请先配置客服电话'})
-    return;
-  }
-  uni.makePhoneCall({
-    phoneNumber:phoneNumber.value,
-    success: () => {
-      console.log('成功唤起拨号界面');
-    },
-    fail: (err) => {
-      console.error('唤起拨号界面失败', err);
-    }
-  });
-};
-</script>
-
-<style lang="less" scoped>
-.mine_ybt{
-	height: 100vh;
-	.vipCar{
-		margin-top: 30rpx;
-    background: linear-gradient(97.4139deg, rgb(137, 153, 191) 4.58393%, rgb(89, 88, 103) 97.8314%);
-		.jiesuo{
-			background: linear-gradient(94.5323deg, rgb(251, 239, 216) 10.1217%, rgb(241, 210, 164) 94.0504%);
-		}
-		.vipcard-img{
-			width: 80rpx;
-			height: 80rpx;
-		}
-	}
-	// background-size: 100% 100%;
-	.order_btns{
-		padding: 8rpx 20rpx;
-		display: inline-block;
-		&.active{
-			background: #fc4f1d;
-		}
-	}
-	.share_btn{
-		border:1px solid #ffffff;
-		padding: 10rpx 20rpx;
-		background: transparent;
-		.share_img{
-			width: 30rpx;
-		}
-	}
-	.mine_content{
-		border-radius: 30rpx 30rpx 0 0;
-		background: #f5f5f5;
-		min-height: calc(100vh - 200rpx);
-	}
-	.order-img{
-		width: 40rpx;
-		height: 40rpx;
-	}
-	.menu_img{
-		width: 50rpx;
-		height: 50rpx;
-	}
-	.menuList{
-		&:last-child{
-			border-bottom: none;
-		}
-	}
-	.vipTime{
-		opacity: .7;
-	}
-	/* 登录按钮 */
-	.login-btn {
-		background-color: transparent;
-		color: #fff;
-		font-size: 35rpx;
-		font-weight: bold;
-		text-align: left;
-	}
-  .memberPlanName{
-		background: linear-gradient(90deg, #FDE492    0%, #FDB85D  100%);
-		color: #874605 ;
-    padding: 5rpx 10rpx;
-    border-radius: 20rpx;
-    font-size: 24rpx;
-  }
-	
-}
-</style>

+ 58 - 8
jd_logistics-app/pages/mine/settlementCode.vue

@@ -3,12 +3,12 @@
 
 
 		<!-- Tab切换 - 平均分配宽度 -->
 		<!-- Tab切换 - 平均分配宽度 -->
 		<view class="custom-tabs">
 		<view class="custom-tabs">
-			<view class="tab-item" :class="{ active: currentTab === 0 }" @click="switchTab(0)">
+			<view class="tab-item" :class="{ active: currentTab === 1 }" @click="switchTab(1)">
 				<text class="tab-text">京东月结码</text>
 				<text class="tab-text">京东月结码</text>
 			</view>
 			</view>
-			<view class="tab-item" :class="{ active: currentTab === 1 }" @click="switchTab(1)">
+		<!-- 	<view class="tab-item" :class="{ active: currentTab === 2 }" @click="switchTab(2)">
 				<text class="tab-text">顺丰月结码</text>
 				<text class="tab-text">顺丰月结码</text>
-			</view>
+			</view> -->
 		</view>
 		</view>
 
 
 		<!-- 二维码邀请内容 -->
 		<!-- 二维码邀请内容 -->
@@ -18,10 +18,23 @@
 					<view class="store-name">月结卡号</view>
 					<view class="store-name">月结卡号</view>
 					<view class="store">
 					<view class="store">
 						
 						
-						<text class="store-address">12345444</text>
+						<text class="store-address">{{settlementCode}}</text>
 						<!-- <u-icon name="arrow-right"></u-icon> -->
 						<!-- <u-icon name="arrow-right"></u-icon> -->
 					</view>
 					</view>
 				</view>
 				</view>
+				
+				<view class="store-info" v-if="currentTab == 1">
+					<view class="store-name">快递类型</view>
+					<view class="store">
+						<picker :range="expressTypes" :range-key="'label'" @change="onExpressTypeChange"
+							:value="expressTypeIndex" :disabled="!expressTypes.length">
+							<view class="picker-text">
+								{{ expressTypes[expressTypeIndex]?.label || (expressTypes.length ? '请选择快递类型' : '加载中...') }}
+							</view>
+						</picker>
+						<u-icon class="arrow" name='arrow-right' size="18"></u-icon>
+					</view>
+				</view>
 			
 			
 				<!-- 二维码区域 -->
 				<!-- 二维码区域 -->
 				<view class="qrcode-container">
 				<view class="qrcode-container">
@@ -58,18 +71,36 @@
 		onLoad,
 		onLoad,
 		onShow
 		onShow
 	} from '@dcloudio/uni-app' // 导入 UniApp 的生命周期
 	} from '@dcloudio/uni-app' // 导入 UniApp 的生命周期
-	import {getQrcode} from '@/api/mine.js'
+	import {getQrcode,getSettlementCode} from '@/api/mine.js'
 
 
 	// 当前选中的tab
 	// 当前选中的tab
-	const currentTab = ref(0)
+	const currentTab = ref(1)
 
 
 	const qrCodeUrl = ref('')
 	const qrCodeUrl = ref('')
 	
 	
+	const settlementCode = ref('')
 
 
-
+	const expressTypeIndex = ref(0)
+	
+	const expressTypes = ref([{
+		label:'京东快递',
+		value:1
+	},
+	{
+		label:'京东快运',
+		value:2
+	}]) // 当前显示的快递类型列表(已转换为 {label, value} 格式)
+
+	// 快递类型
+	const onExpressTypeChange = (e) => {
+		expressTypeIndex.value = e.detail.value
+		getCode()
+		searchSettlementCode()
+	}
 
 
 	onLoad(() => {
 	onLoad(() => {
 		getCode()
 		getCode()
+		searchSettlementCode()
 	})
 	})
 
 
 	onShow(() => {
 	onShow(() => {
@@ -78,14 +109,33 @@
 	
 	
 	// 获取月结码
 	// 获取月结码
 	const getCode = async () =>{
 	const getCode = async () =>{
-		let res = await getQrcode({source:1});
+		qrCodeUrl.value = ''
+		let params = {source:currentTab.value}
+		if(currentTab.value == 1){
+			params = {source:currentTab.value,type:expressTypes.value[expressTypeIndex.value].value}
+		}
+		let res = await getQrcode(params);
 		console.log(res.data.qrCodeImage)
 		console.log(res.data.qrCodeImage)
 		qrCodeUrl.value = res.data.qrCodeImage;
 		qrCodeUrl.value = res.data.qrCodeImage;
 	}
 	}
+	
+	const searchSettlementCode = async () =>{
+		settlementCode.value = ''
+		let params = {source:currentTab.value}
+		if(currentTab.value == 1){
+			params = {source:currentTab.value,type:expressTypes.value[expressTypeIndex.value].value}
+		}
+		let res = await getSettlementCode(params);
+		console.log(res.msg)
+		settlementCode.value = res.msg;
+	}
 	// 切换Tab
 	// 切换Tab
 	const switchTab = (index) => {
 	const switchTab = (index) => {
 		currentTab.value = index
 		currentTab.value = index
+		getCode()
+		searchSettlementCode()
 	}
 	}
+
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>

+ 0 - 37
jd_logistics-app/pages/order/components/OrderFeesInfo.vue

@@ -5,30 +5,6 @@
 				<text class="info-label">{{ item.feeName }}:</text>
 				<text class="info-label">{{ item.feeName }}:</text>
 				<text class="info-value price">¥{{item.rateAmount}}</text>
 				<text class="info-value price">¥{{item.rateAmount}}</text>
 			</view>
 			</view>
-			<!-- <view class="info-row">
-				<text class="info-label">保价{{orderDetail.platformShopCommissionPercent}}%:</text>
-				<text class="info-value">{{orderDetail.platformServiceFee}}</text>
-			</view>
-			<view class="info-row">
-				<text class="info-label">全额保:</text>
-				<text class="info-value price">{{commission}}</text>
-			</view>
-			<view class="info-row">
-				<text class="info-label">签单返还:</text>
-				<text class="info-value">{{orderDetail.memberPromotionFee}}</text>
-			</view>
-			<view class="info-row">
-				<text class="info-label">包装服务:</text>
-				<text class="info-value">{{orderDetail.actualIncomeAmount}}</text>
-			</view>
-			<view class="info-row">
-				<text class="info-label">预约派送:</text>
-				<text class="info-value">{{orderDetail.actualIncomeAmount}}</text>
-			</view>
-			<view class="info-row">
-				<text class="info-label">指定签收:</text>
-				<text class="info-value">{{orderDetail.actualIncomeAmount}}</text>
-			</view> -->
 		</view>
 		</view>
 	</view>
 	</view>
 
 
@@ -59,19 +35,6 @@
 	
 	
 	// formData.commissionType === '0' ? '%' : '元'
 	// formData.commissionType === '0' ? '%' : '元'
 	const commission = computed(() => {
 	const commission = computed(() => {
-		//bs_service_user_task.serivce_commission > bs_service_user_grab.service_commission > bs_shop_goods.service_commission
-		// if(props.orderDetail.serviceTaskInfo && props.orderDetail.serviceTaskInfo.serviceCommission){
-		// 	return props.orderDetail.serviceTaskInfo.serviceCommission
-		// }
-		// if(props.orderDetail.grabInfo && props.orderDetail.grabInfo.serviceCommission){
-		// 	return props.orderDetail.grabInfo.serviceCommission
-		// }
-		// // if(props.orderDetail.goodsInfo && props.orderDetail.goodsInfo.serviceCommission){
-		// // 	// commissionUnit.value =  props.orderDetail.goodsInfo.serviceCommission === '0' ? '%' : '元'
-		// // 	return props.orderDetail.goodsInfo.serviceCommission
-		// // }
-		// // platformPercent()
-		// return props.orderDetail.serviceCommission || props.orderDetail.goodsCommission || ''
 		return ''
 		return ''
 	})
 	})
 	
 	

+ 26 - 16
jd_logistics-app/pages/order/components/OrderItem.vue

@@ -16,6 +16,7 @@
 				<view class="status">{{ getStatusText(orderDetail.orderStatus) }}</view>
 				<view class="status">{{ getStatusText(orderDetail.orderStatus) }}</view>
 
 
 				<image v-if="orderDetail.orderStatus == 5" src="/static/img/translte-1.png"></image>
 				<image v-if="orderDetail.orderStatus == 5" src="/static/img/translte-1.png"></image>
+				<image v-if="orderDetail.orderStatus == 6" src="/static/img/translte-3.png"></image>
 				<image v-else src="/static/img/translte-2.png"></image>
 				<image v-else src="/static/img/translte-2.png"></image>
 			</view>
 			</view>
 
 
@@ -124,22 +125,31 @@
 	}
 	}
 	// 取消订单
 	// 取消订单
 	const cancel = async () => {
 	const cancel = async () => {
-		let res = await cancelOrder({
-			waybillId: props.orderDetail.waybillId,
-			cancelReason: "取消",
-			externalWaybillNo: props.orderDetail.externalWaybillNo,
-			orderType: props.orderDetail.orderType,
-			productCode: props.orderDetail.productCode,
-
-			waybillNo: props.orderDetail.waybillNo,
-		})
-		if (res.code == 200) {
-			uni.showToast({
-				title: res.msg,
-				icon: 'success'
-			})
-			emit('success')
-		}
+		uni.showModal({
+			content:'是否取消运单(' + props.orderDetail.externalWaybillNo + ')',
+			cancelText:'否',
+			confirmText:'是',
+			success: async (res) => {if(res.confirm){
+					let res = await cancelOrder({
+						waybillId: props.orderDetail.waybillId,
+						cancelReason: "取消",
+						externalWaybillNo: props.orderDetail.externalWaybillNo,
+						orderType: props.orderDetail.orderType,
+						productCode: props.orderDetail.productCode,
+					
+						waybillNo: props.orderDetail.waybillNo,
+					})
+					if (res.code == 200) {
+						uni.showToast({
+							title: res.msg,
+							icon: 'success'
+						})
+						emit('success')
+					}
+				}
+			}
+				
+		})		
 	}
 	}
 
 
 	// 获取订单状态
 	// 获取订单状态

+ 1 - 1
jd_logistics-app/pages/order/components/TimePopup.vue

@@ -130,7 +130,7 @@ const oneHourLater = computed(() => {
 
 
 const twentyMinutesLater = computed(() => {
 const twentyMinutesLater = computed(() => {
   const now = new Date(currentTime.value)
   const now = new Date(currentTime.value)
-  now.setMinutes(now.getMinutes() + 10)
+  now.setMinutes(now.getMinutes() + 3)
   return now
   return now
 })
 })
 
 

+ 28 - 25
jd_logistics-app/pages/order/create_order.vue

@@ -9,6 +9,7 @@
 				<view class="user-info">
 				<view class="user-info">
 					<AddressInfo v-if="addressSend.addressId" :address="addressSend" />
 					<AddressInfo v-if="addressSend.addressId" :address="addressSend" />
 					<view v-else class="create-btn" @click="handleAddAddress('sender')">新建寄件人</view>
 					<view v-else class="create-btn" @click="handleAddAddress('sender')">新建寄件人</view>
+					
 				</view>
 				</view>
 				<view class="img-status-text right" @click="openAddressBook('sender')">
 				<view class="img-status-text right" @click="openAddressBook('sender')">
 					<image src="/static/img/create-order-address.png" mode="" class="address-image"></image>
 					<image src="/static/img/create-order-address.png" mode="" class="address-image"></image>
@@ -115,7 +116,7 @@
 
 
 		<!-- 增值服务卡片 -->
 		<!-- 增值服务卡片 -->
 		<view class="goods-card">
 		<view class="goods-card">
-			<view class="goods-item">
+			<view class="goods-item" v-if="product === '1'">
 				<view class="item-label">包装服务</view>
 				<view class="item-label">包装服务</view>
 				<view class="item-control">
 				<view class="item-control">
 					<switch color="#007AFF" :checked="valueServices.isPack" @change="onPackagingChange" />
 					<switch color="#007AFF" :checked="valueServices.isPack" @change="onPackagingChange" />
@@ -125,11 +126,11 @@
 			<view class="goods-item">
 			<view class="goods-item">
 				<view class="item-label">保价</view>
 				<view class="item-label">保价</view>
 				<view class="item-control">
 				<view class="item-control">
-					<switch color="#007AFF" :checked="!!insuranceAmount" @change="onInsuranceChange" />
+					<switch color="#007AFF" :checked="insuranceAmountChecked" @change="onInsuranceChange" />
 				</view>
 				</view>
 			</view>
 			</view>
 
 
-			<view v-if="insuranceAmount !== '' && insuranceAmount !== null" class="goods-item">
+			<view v-if="insuranceAmountChecked" class="goods-item">
 				<view class="item-label">保价金额(元)</view>
 				<view class="item-label">保价金额(元)</view>
 				<view class="item-control">
 				<view class="item-control">
 					<input class="input-field" placeholder="请输入保价金额" placeholder-class="placeholder"
 					<input class="input-field" placeholder="请输入保价金额" placeholder-class="placeholder"
@@ -138,15 +139,15 @@
 			</view>
 			</view>
 
 
 			<!-- 超长超重(顺丰/京东) -->
 			<!-- 超长超重(顺丰/京东) -->
-			<view class="goods-item">
+		<!-- 	<view class="goods-item" v-if="product === '2'">
 				<view class="item-label">超长超重</view>
 				<view class="item-label">超长超重</view>
 				<view class="item-control">
 				<view class="item-control">
 					<switch color="#007AFF" :checked="valueServices.isOverLongWeight" @change="onOverweightChange" />
 					<switch color="#007AFF" :checked="valueServices.isOverLongWeight" @change="onOverweightChange" />
 				</view>
 				</view>
-			</view>
+			</view> -->
 
 
 			<!-- 签单返还 -->
 			<!-- 签单返还 -->
-			<view class="goods-item" >
+			<view class="goods-item"  v-if="product === '1'">
 				<view class="item-label">签单返还</view>
 				<view class="item-label">签单返还</view>
 				<view class="item-control">
 				<view class="item-control">
 					<switch color="#007AFF" :checked="valueServices.isReceiptCollect" @change="onSignReturnChange" />
 					<switch color="#007AFF" :checked="valueServices.isReceiptCollect" @change="onSignReturnChange" />
@@ -167,12 +168,12 @@
 			</view>
 			</view>
 
 
 			<!-- 打木架(仅顺丰) -->
 			<!-- 打木架(仅顺丰) -->
-			<view v-if="product === '2'" class="goods-item">
+		<!-- 	<view v-if="product === '2'" class="goods-item">
 				<view class="item-label">打木架</view>
 				<view class="item-label">打木架</view>
 				<view class="item-control">
 				<view class="item-control">
 					<switch color="#007AFF" :checked="valueServices.isWoodenCrate" @change="onWoodenFrameChange" />
 					<switch color="#007AFF" :checked="valueServices.isWoodenCrate" @change="onWoodenFrameChange" />
 				</view>
 				</view>
-			</view>
+			</view> -->
 		</view>
 		</view>
 
 
 		<!-- 协议同意 -->
 		<!-- 协议同意 -->
@@ -329,6 +330,7 @@
 	})
 	})
 
 
 	// 保价金额
 	// 保价金额
+	const insuranceAmountChecked = ref(false)
 	const insuranceAmount = ref('')
 	const insuranceAmount = ref('')
 	const insuranceAmountError = ref('')
 	const insuranceAmountError = ref('')
 
 
@@ -428,6 +430,7 @@
 	}
 	}
 
 
 	const onInsuranceChange = (e) => {
 	const onInsuranceChange = (e) => {
+		insuranceAmountChecked.value = e.detail.value
 		if (e.detail.value) {
 		if (e.detail.value) {
 			insuranceAmount.value = '0'
 			insuranceAmount.value = '0'
 		} else {
 		} else {
@@ -452,13 +455,13 @@
 		if (!insuranceAmount.value) return true
 		if (!insuranceAmount.value) return true
 		const amount = parseFloat(insuranceAmount.value)
 		const amount = parseFloat(insuranceAmount.value)
 		if (isNaN(amount) || amount < 0) {
 		if (isNaN(amount) || amount < 0) {
-			insuranceAmountError.value = '保价金额必须为数字且≥0'
-			return false
-		}
-		if (amount > 1000000) {
-			insuranceAmountError.value = '保价金额不能超过100万'
+			insuranceAmountError.value = '保价金额必须为数字且大于0'
 			return false
 			return false
 		}
 		}
+		// if (amount > 1000000) {
+		// 	insuranceAmountError.value = '保价金额不能超过100万'
+		// 	return false
+		// }
 		const decimal = insuranceAmount.value.toString().split('.')[1]
 		const decimal = insuranceAmount.value.toString().split('.')[1]
 		if (decimal && decimal.length > 2) {
 		if (decimal && decimal.length > 2) {
 			insuranceAmountError.value = '最多两位小数'
 			insuranceAmountError.value = '最多两位小数'
@@ -612,23 +615,23 @@
 		}
 		}
 
 
 		// 重量/体积/件数范围
 		// 重量/体积/件数范围
-		if (weight.value < 0.1 || weight.value > 100) {
+		if (weight.value < 0) {
 			uni.showToast({
 			uni.showToast({
-				title: '重量范围0.1-100KG',
+				title: '请输入正确的重量',
 				icon: 'none'
 				icon: 'none'
 			});
 			});
 			return false
 			return false
 		}
 		}
-		if (volume.value < 0.001 || volume.value > 10) {
+		if (volume.value < 0) {
 			uni.showToast({
 			uni.showToast({
-				title: '体积范围0.001-10m³',
+				title: '请输入正确的体积',
 				icon: 'none'
 				icon: 'none'
 			});
 			});
 			return false
 			return false
 		}
 		}
-		if (quantity.value < 1 || quantity.value > 99) {
+		if (quantity.value < 1) {
 			uni.showToast({
 			uni.showToast({
-				title: '件数范围1-99件',
+				title: '请输入正确的件数',
 				icon: 'none'
 				icon: 'none'
 			});
 			});
 			return false
 			return false
@@ -724,7 +727,7 @@
 		})
 		})
 		try {
 		try {
 			const res = await createOrder(orderData)
 			const res = await createOrder(orderData)
-			// uni.hideLoading()
+			uni.hideLoading()
 			if (res.code === 200) {
 			if (res.code === 200) {
 				uni.showToast({
 				uni.showToast({
 					title: '下单成功',
 					title: '下单成功',
@@ -743,14 +746,13 @@
 			}
 			}
 		} catch (error) {
 		} catch (error) {
 			isSubmit.value = false
 			isSubmit.value = false
-			uni.hideLoading()
 			uni.showToast({
 			uni.showToast({
-				title: '网络错误,请重试',
+				title: error,
 				icon: 'none'
 				icon: 'none'
 			})
 			})
 			console.error('订单提交失败', error)
 			console.error('订单提交失败', error)
 		} finally{
 		} finally{
-			uni.hideLoading()
+			// uni.hideLoading()
 		}
 		}
 	}
 	}
 
 
@@ -840,9 +842,10 @@
 
 
 			.create-btn {
 			.create-btn {
 				height: 88rpx;
 				height: 88rpx;
+				font-weight: 400;
+				font-size: 40rpx;
+				color: #999999;
 				line-height: 88rpx;
 				line-height: 88rpx;
-				font-size: 28rpx;
-				color: #1B64F0;
 			}
 			}
 		}
 		}
 
 

+ 92 - 92
jd_logistics-app/pages/order/index.vue

@@ -1,22 +1,30 @@
 <template>
 <template>
 	<view class="container">
 	<view class="container">
-		<!-- 搜索框 -->
+		<!-- 搜索框(原生 input 实现,兼容微信小程序) -->
 		<view class="search-section">
 		<view class="search-section">
-			<u-search v-model="searchKeyword" placeholder="请输入订单编号或用户名称" :show-action="false" shape="square"
-				bg-color="#F5F7FA" @search="handleSearch" @clear="handleSearch"></u-search>
-		</view>
-
-		<!-- Tab切换 -->
-		<!-- <view class="tabs-section"> -->
-		<!-- 	<view class="custom-tabs">
-				<view class="tab-item" :class="{ active: currentTab == index }" v-for="(tab, index) in tabList"
-					:key="index" @click="switchTab(index)">
-					{{ tab.name }}
+			<view class="search-box">
+				<!-- 搜索图标 -->
+				<view class="search-icon">
+					<u-icon name="search" size="22" color="#999"></u-icon>
 				</view>
 				</view>
-			</view> -->
-		<!-- </view> -->
+				<!-- 输入框 -->
+				<input 
+					class="search-input" 
+					type="text" 
+					v-model="searchKeyword" 
+					placeholder="请输入订单编号或用户名称手机号"
+					placeholder-class="placeholder-style"
+					confirm-type="search"
+					@confirm="handleSearch"
+				/>
+				<!-- 自定义清除按钮 -->
+				<view v-if="searchKeyword" class="search-clear" @click.stop="handleClear">
+					<u-icon name="close-circle" size="22" color="#999"></u-icon>
+				</view>
+			</view>
+		</view>
 
 
-		<!-- 订单列表 -->
+		<!-- 订单列表(保持不变) -->
 		<view class="order-list" @scrolltolower="loadMore">
 		<view class="order-list" @scrolltolower="loadMore">
 			<view v-if="ordersList.length" v-for="order in ordersList" :key="order.id">
 			<view v-if="ordersList.length" v-for="order in ordersList" :key="order.id">
 				<OrderItem :order-detail="order" @success="getOrderList()"></OrderItem>
 				<OrderItem :order-detail="order" @success="getOrderList()"></OrderItem>
@@ -29,28 +37,22 @@
 			<view class="load-more-status" v-if="loadFinished && ordersList.length !== 0">
 			<view class="load-more-status" v-if="loadFinished && ordersList.length !== 0">
 				<text>没有更多数据了</text>
 				<text>没有更多数据了</text>
 			</view>
 			</view>
-
-			<!-- 加载状态提示 -->
 			<view class="load-more-status" v-if="loadState">
 			<view class="load-more-status" v-if="loadState">
 				<text>加载中...</text>
 				<text>加载中...</text>
 			</view>
 			</view>
-
 		</view>
 		</view>
-
-
 	</view>
 	</view>
 </template>
 </template>
 
 
 <script setup>
 <script setup>
 	import {
 	import {
-		ref,
-		computed
+		ref
 	} from 'vue'
 	} from 'vue'
 	import {
 	import {
 		onShow,
 		onShow,
 		onLoad,
 		onLoad,
 		onReachBottom
 		onReachBottom
-	} from '@dcloudio/uni-app' // 导入 UniApp 的生命周期
+	} from '@dcloudio/uni-app'
 	import OrderItem from './components/OrderItem.vue'
 	import OrderItem from './components/OrderItem.vue'
 	import { getOrderListApi } from '../../api/order'
 	import { getOrderListApi } from '../../api/order'
 
 
@@ -62,22 +64,15 @@
 	const loadState = ref(false)
 	const loadState = ref(false)
 	const loadFinished = ref(false)
 	const loadFinished = ref(false)
 
 
-	// Tab数据
-	const tabList = ref([{
-			name: '全部订单'
-		},
-		{
-			name: '待确认'
-		},
-		{
-			name: '已完成'
-		},
-		{
-			name: '申请退款'
-		}
+	// Tab数据(保留,未启用)
+	const tabList = ref([
+		{ name: '全部订单' },
+		{ name: '待确认' },
+		{ name: '已完成' },
+		{ name: '申请退款' }
 	])
 	])
-	// 1-全部订单, 2-待确认,  4-已完成, 5-申请退款
-	//orderType: 订单类型(1-全部订单, 2-待确认, 3-待核销, 4-已完成, 5-申请退款, 6-服务中)
+	
+	// 订单类型映射
 	const orderTypeMap = {
 	const orderTypeMap = {
 		0: 1, // 全部订单
 		0: 1, // 全部订单
 		1: 2, // 待确认 
 		1: 2, // 待确认 
@@ -85,29 +80,9 @@
 		3: 5, // 申请退款  
 		3: 5, // 申请退款  
 	}
 	}
 
 
-	// 当前选中的Tab
 	const currentTab = ref(0)
 	const currentTab = ref(0)
-
-	// 订单数据
 	const ordersList = ref([])
 	const ordersList = ref([])
 
 
-
-	// 获取状态类名
-	const getStatusClass = (status) => {
-		switch (status) {
-			case 0:
-				return 'status-pending' // 待派单
-			case 1:
-				return 'status-assigned' // 已派单
-			case 2:
-				return 'status-completed' // 已完成
-			case 3:
-				return 'status-market' // 抢单市场
-			default:
-				return 'status-pending'
-		}
-	}
-
 	onLoad((option) => {
 	onLoad((option) => {
 		if (option.orderStatusType) {
 		if (option.orderStatusType) {
 			currentTab.value = option.orderStatusType
 			currentTab.value = option.orderStatusType
@@ -115,65 +90,55 @@
 	})
 	})
 
 
 	onShow(() => {
 	onShow(() => {
-		// 可以在这里初始化数据
+		pageNum.value = 1
 		getOrderList()
 		getOrderList()
 	})
 	})
 
 
-	// Tab切换事件
-	const switchTab = (index) => {
-		currentTab.value = index
-		getOrderList(false)
-	}
-
+	// 搜索(点击键盘搜索或清除后调用)
 	const handleSearch = () => {
 	const handleSearch = () => {
+		pageNum.value = 1
 		getOrderList()
 		getOrderList()
 	}
 	}
 
 
-	// 获取收益明细列表
+	// 清除按钮点击
+	const handleClear = () => {
+		searchKeyword.value = ''
+		handleSearch()
+	}
+
+	// 获取订单列表
 	const getOrderList = async () => {
 	const getOrderList = async () => {
-		//orderType: 订单类型(1-全部订单, 2-待确认,  4-已完成, 5-申请退款)
 		try {
 		try {
-			uni.showLoading({
-				mask: true
-			})
+			uni.showLoading({ mask: true })
+			loadState.value = true
+			
 			const orderType = orderTypeMap[currentTab.value]
 			const orderType = orderTypeMap[currentTab.value]
 			const params = {
 			const params = {
 				pageNum: pageNum.value,
 				pageNum: pageNum.value,
 				pageSize: pageSize.value,
 				pageSize: pageSize.value,
-				// orderType: orderType,
-				keyword: searchKeyword.value
+				searchKeyword: searchKeyword.value
 			}
 			}
-			var res = await getOrderListApi(params)
+			const res = await getOrderListApi(params)
 			if (res.code === 200) {
 			if (res.code === 200) {
 				const list = res.rows || []
 				const list = res.rows || []
-
-				ordersList.value = pageNum.value == 1 ? list : [...ordersList.value, ...list]
-				
+				ordersList.value = pageNum.value === 1 ? list : [...ordersList.value, ...list]
 				recordTotal.value = Math.ceil(res.total / pageSize.value) || 0
 				recordTotal.value = Math.ceil(res.total / pageSize.value) || 0
-				
 			}
 			}
 		} catch (error) {
 		} catch (error) {
-
+			console.error('获取订单列表失败', error)
 		} finally {
 		} finally {
-			
 			uni.hideLoading()
 			uni.hideLoading()
+			loadState.value = false
 		}
 		}
 	}
 	}
 
 
 	// 触底加载更多
 	// 触底加载更多
 	onReachBottom(() => {
 	onReachBottom(() => {
 		if (pageNum.value < recordTotal.value) {
 		if (pageNum.value < recordTotal.value) {
-			pageNum.value++;
+			pageNum.value++
 			getOrderList()
 			getOrderList()
 		}
 		}
 	})
 	})
-	// 查看订单详情
-	const viewOrderDetail = (order) => {
-		uni.showToast({
-			title: `查看订单详情 - ${order.orderNumber}`,
-			icon: 'none'
-		})
-	}
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
@@ -181,13 +146,51 @@
 		background-color: #fff;
 		background-color: #fff;
 		padding: 16rpx;
 		padding: 16rpx;
 		margin-left: 14rpx;
 		margin-left: 14rpx;
+	}
 
 
-		:deep .u-search__content {
-			border-radius: 36rpx !important;
-		}
+	.search-box {
+		display: flex;
+		align-items: center;
+		background-color: #F5F7FA;
+		border-radius: 36rpx;
+		padding: 0 20rpx;
+		height: 72rpx; /* 与 u-search 高度一致 */
+	}
+
+	.search-icon {
+		margin-right: 16rpx;
+		display: flex;
+		align-items: center;
+	}
+
+	.search-input {
+		flex: 1;
+		height: 100%;
+		font-size: 28rpx;
+		color: #333;
+		background-color: transparent;
+		border: none;
+		outline: none;
+	}
+
+	.placeholder-style {
+		color: #999;
+		font-size: 28rpx;
+	}
 
 
+	.search-clear {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		margin-left: 16rpx;
+		padding: 8rpx;
+		
+		&:active {
+			opacity: 0.6;
+		}
 	}
 	}
 
 
+	/* 以下样式与之前一致,无需改动 */
 	.page-title {
 	.page-title {
 		font-size: 36rpx;
 		font-size: 36rpx;
 		font-weight: bold;
 		font-weight: bold;
@@ -310,7 +313,6 @@
 		background: #F5F7FA;
 		background: #F5F7FA;
 		border-radius: 16rpx;
 		border-radius: 16rpx;
 
 
-
 		.customer-info {
 		.customer-info {
 			display: flex;
 			display: flex;
 			align-items: center;
 			align-items: center;
@@ -329,7 +331,6 @@
 			color: #333333;
 			color: #333333;
 			font-weight: bold;
 			font-weight: bold;
 		}
 		}
-
 	}
 	}
 
 
 	.load-more-status {
 	.load-more-status {
@@ -342,7 +343,6 @@
 		height: 100%;
 		height: 100%;
 	}
 	}
 
 
-
 	.empty-state {
 	.empty-state {
 		display: flex;
 		display: flex;
 		flex-direction: column;
 		flex-direction: column;

+ 0 - 71
jd_logistics-app/pages/policy/ad_detail.vue

@@ -1,71 +0,0 @@
-<template> 
-<view class="padding20 ad_detail">
-  <image :src="HTTP_ADMIN_URL+imageUrl" mode="" class="swiper_img border_radius_20"></image>
-  <view v-html="remark" class="padding20 border_radius_20 bg_color_fff mt20"></view>
-  <view class="mt20">
-    <view v-for="(item, index) in aiAgents" :key="index" 
-    @click="toAi({agentId:item.agentId})"
-    class="flex-center-between padding20 border_radius_20 bg_color_fff mt20">
-      <image :src="HTTP_ADMIN_URL+item.imageUrl" mode="" class="aiAgents_img border_radius_20 mr20"></image>
-      <view class="ml20 flex_1 flex-center-between">
-        <view class="flex_1 mr20">
-          <view class="bold font_size35 line2">{{item.agentName}}</view>
-          <view class="gray font_size25 line2">{{item.agentDesc}}</view>
-        </view>
-        <image src="/static/img/arrow-right.png" mode="widthFix" class="menu_img"></image>
-      </view>
-    </view>
-  </view>
-</view>
-</template>
-<script setup> 
-import { ref } from "vue";
-import { HTTP_ADMIN_URL } from "@/config/app.js";
-import { getAdDetails } from "@/api/home";
-import { onLoad } from "@dcloudio/uni-app";
-import { useAppStore } from "@/stores/app";
-const appStore = useAppStore();
-
-const imageUrl = ref('');
-const remark = ref('');
-const aiAgents = ref([]);
-
-onLoad(({dictCode}) => { 
-  getAdDetailsFn(dictCode);
-})
-function getAdDetailsFn(dictCode) { 
-  getAdDetails({dictCode}).then(res => {
-    if (res.code == 200) {
-      imageUrl.value = res.data?.sysDictData?.dictValue ||  '';
-      remark.value = res.data?.sysDictData?.remark || '';
-      aiAgents.value = res.data?.aiAgents || [];
-    }
-  })
-}
-function toAi({agentId='', msgContent=''}){
-	if(agentId) appStore.UPDATE_agentId(agentId);
-	if(msgContent)appStore.UPDATE_msgContent(msgContent);
-	uni.switchTab({
-		url: '/pages/ai/ai'
-	});
-}
-
-</script>
-<style lang="scss" scoped>
-  .ad_detail{
-    height: 100%;
-    .swiper_img{
-      width: 100%;
-      height: 350rpx;
-      background-color: #ffffff;
-    }
-    .aiAgents_img{
-      width: 100rpx;
-      height: 100rpx;
-    }
-    .menu_img{
-      width: 40rpx;
-      height: 40rpx;
-    } 
-  }
-</style>

+ 0 - 23
jd_logistics-app/pages/policy/recharge_policy.vue

@@ -1,23 +0,0 @@
-<template> 
-<view class="padding30">
-  <view v-html="info.content" class="padding30 border_radius_20 bg_color_fff"></view>
-</view>
-</template>
-<script setup> 
-import { ref } from "vue";
-import { agreementRecharge } from "@/api/agreement";
-import { onLoad } from "@dcloudio/uni-app";
-const info = ref({});
-
-onLoad(() => { 
-  agreementRechargeFn();
-})
-function agreementRechargeFn() { 
-  agreementRecharge().then(res => {
-    if (res.code == 200) {
-      info.value = res.data;
-    }
-  })
-}
-
-</script>

+ 0 - 23
jd_logistics-app/pages/policy/vip_policy.vue

@@ -1,23 +0,0 @@
-<template> 
-<view class="padding30">
-  <view v-html="info.content" class="padding30 border_radius_20 bg_color_fff"></view>
-</view>
-</template>
-<script setup> 
-import { ref } from "vue";
-import { agreementMember } from "@/api/agreement";
-import { onLoad } from "@dcloudio/uni-app";
-const info = ref({});
-
-onLoad(() => { 
-  agreementMemberFn();
-})
-function agreementMemberFn() { 
-  agreementMember().then(res => {
-    if (res.code == 200) {
-      info.value = res.data;
-    }
-  })
-}
-
-</script>

+ 0 - 144
jd_logistics-app/pages/recharge/recharge.vue

@@ -1,144 +0,0 @@
-<template>
-	<view class="recharge padding30">
-		<!-- 余额 -->
-		<view class="blance color_fff border_radius_20">
-			<view class="flex-center-between">
-				<view class="font_size30 mr20">余额 ( {{appStore.moneyUnit}} )</view>
-				<view class="font_size30" @click="toWallet">账户明细</view>
-			</view>
-			<view class="font_size60 bold mt30">{{appStore.userInfo?.rechargeBalance}}</view>
-		</view>
-		<!-- 充值金额 -->
-    <view class="padding30 border_radius_20 bg_color_fff mt20">
-      <view class="font_size30 bold">充值金额</view>
-      <view class="grid-container mt30">
-        <view class="flex-column-center bg_color_f5 border_radius_20 paddingTB20 rePrice"
-				:class="{active: ruleId==item.ruleId }"
-				@click="ruleId = item.ruleId;orderAmt = item.rechargeAmount"
-				 v-for="(item, index) in ruleList" :key="index">
-          <view class="bold font_size40 color_price">{{item.rechargeAmount}}</view>
-          <view class="font_size20 mt10 gray">{{item.offerTag}}</view>
-					<image src="/static/img/check.png" mode="widthFix" class="checked_img" v-if="ruleId==item.ruleId"></image>
-        </view>
-      </view>
-			<view class="mt30">
-				<view class="bold font_size25">{{rechargeRuleInfo.agreementName}}</view>
-				<view class="mt10 gary font_size25">
-					1.活动有效期为 {{ruleList[0]?.startTime}} 至 {{ruleList[0]?.endTime}}。
-				</view>
-				<view class="mt20 gary font_size25" v-html="rechargeRuleInfo.content"></view>
-			</view>
-    </view>
-		<agreeRecharge ref="agreeRecharge" @setAloneChecked="setAloneChecked"></agreeRecharge>
-		<!-- foot -->
-    <view class="foot bg_color_fff">
-			<view class="order_btn paddingTB20 flex_1 text_align_center" @click="submitForm">充值</view>
-		</view>
-	</view>
-</template>
-<script setup>
-import { ref } from "vue";
-import { getRuleList } from "@/api/user";
-import { createOrder } from "@/api/order";
-import { wxPay,getUserInfo } from "@/utils/util.js";
-import { agreementRechargeRule } from "@/api/agreement";
-import { agreeRecharge } from "@/components/agreeRecharge.vue"
-import { useToast } from "@/hooks/useToast";
-const { Toast } = useToast();
-import { onLoad } from "@dcloudio/uni-app";
-import { useAppStore } from "@/stores/app";
-const appStore = useAppStore();
-const ruleList = ref([]);
-const orderId = ref('');
-const rechargeRuleInfo = ref('');
-const ruleId = ref('');
-const orderAmt = ref('');
-const aloneChecked = ref(false);
-
-onLoad(() => {
-	getRuleListFn();
-	agreementRechargeRuleFn();
-});
-async function submitForm(){
-	if(!aloneChecked.value){
-		Toast({ title: "请先阅读并同意充值协议", icon: 'none' });
-		return;
-	}
-	const res = await createOrder({
-		payMethod:0,//支付方式 0微信 1余额
-		productType:1,//商品类型 0购买会员 1充值
-		productId:ruleId.value,
-		orderNum:1,//订单数量
-		orderAmt:orderAmt.value//订单金额
-	});
-	//payData
-	orderId.value = res.data.orderId;
-	const payInfo = res.data.payData.prepayWithRequestPaymentResponse
-	wxPay({
-		timeStamp:payInfo.timeStamp,
-		nonceStr:payInfo.nonceStr,
-		packageVal:payInfo.packageVal,
-		signType:payInfo.signType,
-		paySign:payInfo.paySign,
-	},to_success_pay);
-}
-function to_success_pay({isSuccess}){
-	console.log('to_success_pay',isSuccess);
-	uni.navigateTo({
-    url: `/pages/recharge/success_pay?orderId=${orderId.value}&isSuccess=${isSuccess}&payMethod=0`
-  })
-}
-function toWallet(){
-	uni.navigateTo({
-		url: '/pages/recharge/wallet'
-	});
-}
-function getRuleListFn(){ 
-	getRuleList().then(res => {
-		if(res.code == 200){
-			ruleList.value = res.data || [];
-			if(ruleList.value.length > 0){
-				ruleId.value = ruleList.value[0].ruleId || '';
-				orderAmt.value = ruleList.value[0].rechargeAmount || '';
-			}
-		}
-	})
-}
-function agreementRechargeRuleFn(){ 
-	agreementRechargeRule().then(res => {
-		if(res.code == 200){
-			rechargeRuleInfo.value = res.data || {};
-		}
-	})
-}
-function setAloneChecked(value){
-  aloneChecked.value = value;
-}
-</script>
-<style lang="less" scoped>
-.recharge{
-  background: #f5f5f5;
-	.blance{
-		background-color: #fb7145;
-		padding: 30rpx 30rpx 60rpx;
-	}
-	.rePrice{
-		position: relative;
-		border: 1rpx solid transparent;
-		&.active{
-			border: 1rpx solid #fb7145;
-		}
-		.checked_img{
-			width: 40rpx;
-			height: 40rpx;
-			position: absolute;
-			top: 50%;
-			right: 20rpx;
-			transform: translateY(-50%);
-		}
-	}
-	.order_btn{
-		background-color: #fb7145;
-	}
-}
-</style>

+ 0 - 98
jd_logistics-app/pages/recharge/success_pay.vue

@@ -1,98 +0,0 @@
-<template>
-  <view class="pay-success-container">
-    <!-- 支付成功图标及状态 -->
-    <view class="icon-circle">
-      <image class="success-icon" src="/static/success_card.png"></image> 
-    </view>
-    <text class="title">{{title}}</text>
-    <text class="desc gray">{{msg}}</text>
-    <!-- 查看订单按钮 -->
-    <button class="check-order-btn bg_color_primary" @click="goBack">返回</button>
-  </view>
-</template>
-
-<script setup>
-import { ref,computed } from 'vue';
-import { payResult } from "@/api/order.js";
-import { getUserInfo } from "@/utils/util.js";
-import { onLoad } from "@dcloudio/uni-app";
-const orderId = ref('');
-const isSuccess = ref(1);//1成功 0失败;
-const payMethod = ref('');//支付方式 0微信 1余额
-
-const title = computed(()=>{
-	return isSuccess.value==1 ? '支付成功' : '支付失败'
-})
-const msg = computed(()=>{
-	return isSuccess.value==1 ? '非常感谢您购买我们的服务~' : '抱歉,支付失败,请稍后再试~'
-})
-
-onLoad((e)=>{
-	orderId.value = e.orderId || 0;
-	isSuccess.value = e.isSuccess;
-	payMethod.value = e.payMethod;
-  console.log("pay-success-onload",e);
-  getUserInfo();
-  if(payMethod.value == 0)payResultFn();
-})
-// 导航到订单详情页面
-function goBack() {
-  uni.navigateBack({
-    delta: 1
-  });
-}
-function payResultFn() {
-  payResult({
-    orderId: orderId.value,
-  }).then(res => {
-    console.log("payResult", res);
-  });
-}
-</script>
-
-<style scoped>
-.pay-success-container {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: start;
-  min-height: 100vh;
-  background-color: #f5f5f5;
-  padding: 0 20rpx;
-}
-.icon-circle {
-  width: 160rpx;
-  height: 160rpx;
-  border-radius: 50%;
-  background-color: #ffd9d1;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  margin: 120rpx 0 40rpx;
-}
-.success-icon {
-  width: 80rpx;
-  height: 80rpx;
-}
-.title {
-  font-size: 36rpx;
-  font-weight: bold;
-  color: #333;
-  margin-bottom: 20rpx;
-}
-.desc {
-  font-size: 28rpx;
-  text-align: center;
-  margin-bottom: 60rpx;
-  line-height: 44rpx;
-}
-.check-order-btn {
-  /* width: 320rpx; */
-	width: 100%;
-  height: 88rpx;
-  line-height: 88rpx;
-  color: #fff;
-  font-size: 32rpx;
-  border-radius: 44rpx;
-}
-</style>

+ 0 - 295
jd_logistics-app/pages/recharge/vip.vue

@@ -1,295 +0,0 @@
-<template>
-	<view class="vip">
-    <view class="vip_top">
-      <headerInfo title="会员中心" :isBack="true"></headerInfo>
-      <view class="flex-center-between color_fff mg20">
-        <u-avatar  @click="toUser"
-					size="100rpx"
-					shape="circle"
-					:src="appStore?.userInfo?.avatar"
-					mode="aspectFill"
-				></u-avatar>
-        <view class="flex_1 flex-center-between ml20">
-          <view class="flex-column flex_1">
-            <view>
-              <text class="font_size32 nickName bold mr20">{{appStore.userInfo?.nickName}}</text>
-              <text class="memberPlanName" v-if="appStore.userInfo?.memberStatus==1">{{appStore.userInfo?.memberPlanName}}</text>
-            </view>
-            <text class="font_size32 nickName mt10" v-if="appStore.userInfo?.memberStatus==1">
-							<text class="vipTime">到期时间: {{appStore.userInfo?.memberExpire}}</text>
-            </text>
-            <text class="font_size32 nickName mt10" v-else>未开通VIP,无法享受会员</text>
-          </view>
-          <image src="/static/img/vip/vip.png" mode="" style="width:204rpx;height:204rpx;"/>
-        </view>
-      </view>
-    </view>
-    <view class="padding20 vip_content">
-      <!-- 会员充值 -->
-      <view class="flex-center mt10">
-        <view class="flex-center-between">
-          <view class="line_vip"></view>
-            <text class="title_vip font_size32 bold">会员充值</text>
-          <view class="line_vip reverse"></view>
-        </view>
-      </view>
-      <view class="mt20 vip_pay">
-        <view class="grid-container3 mt30">
-          <view class="flex-column-center border_radius_20 paddingTB20 plan" 
-          :class="{'active':planId==item.planId}"
-          @click="planId=item.planId;orderAmt=item.price;"
-          v-for="(item, index) in planList" :key="index">
-            <view class="bold font_size28 planName">{{item.planName}}</view>
-            <view class="font_size35 mt20 color_price"><text class="font_size20">¥</text>{{item.price}}</view>
-            <view class="font_size20 mt20 gray line_through">¥{{item.originalPrice}}</view>
-            <view class="bold font_size28 planName mt20">{{item.durationUnit=='lifetime'?'':item.duration}}{{item.durationUnitName}}</view>
-            <view class="hot" v-if="item.durationUnit=='lifetime'">
-              <image src="/static/img/vip/fire.png" mode="" style="width:20rpx;height:20rpx"/>
-              <text class="font_size20 color_fff">推荐</text>
-            </view>
-          </view>
-        </view>
-      </view>
-      <!-- 会员专享4大权益 -->
-      <view class="flex-center mt30">
-        <view class="flex-center-between">
-          <view class="line_vip"></view>
-            <text class="title_vip font_size32 bold">会员专享4大权益</text>
-          <view class="line_vip reverse"></view>
-        </view>
-      </view>
-      <view class="grid-container mt30">
-        <view class="flex-center-between border_radius_20 bg_color_fff padding20" v-for="(item, index) in quanyilList" :key="index">
-          <image :src="item.icon" class="icon mr20" mode="" />
-          <view class="flex_1">
-            <view class="bold font_size28">{{item.title}}</view>
-            <view class="font_size24 mt10 gray">{{item.content}}</view>
-          </view>
-        </view>
-      </view>
-     
-      <!-- 付款方式 -->
-      <view class="padding30 border_radius_20 bg_color_fff mt20"  v-if="isEdit!=1">
-        <view class="font_size32 bold mb20">付款方式</view>
-        <view class="flex-center-between mt20 paddingTB20" v-for="(item, index) in payments" :key="index" @click="payType=item.value">
-          <view class="flex-center-between">
-            <image :src="item.icon" mode="widthFix" class="weixin_img mr20"></image>
-            <text>{{item.label}}</text>
-            <text class="color_price ml20 font_size24" v-if="index==1"> 余额:{{appStore.userInfo?.rechargeBalance}} ({{appStore.moneyUnit}})</text>
-          </view>
-          <view class="payment-radio">
-            <view
-              class="radio-circle"
-              :class="{ checked: payType === item.value }"
-            ></view>
-          </view>
-        </view>
-      </view>
-      <agreeVip ref="agreeVip" @setAloneChecked="setAloneChecked"></agreeVip>
-    </view>
-    <!-- foot -->
-    <view class="foot bg_color_fff">
-			<view class="order_btn paddingTB20 flex_1 text_align_center" @click="submitForm">
-        <text>{{appStore.userInfo?.memberStatus==1?'续费':'立即解锁'}}</text>
-        <text>¥{{orderAmt}}</text>
-      </view>
-		</view>
-	</view>
-</template>
-<script setup>
-import { ref } from "vue";
-import { wxPay,getUserInfo } from "@/utils/util.js";
-import headerInfo from "@/components/headerInfo.vue";
-import { createOrder } from "@/api/order";
-import { useToast } from "@/hooks/useToast";
-const { Toast } = useToast();
-import { getPlanList } from "@/api/user";
-import { agreeVip } from "@/components/agreeVip"
-import { onLoad } from '@dcloudio/uni-app'
-import { useAppStore } from "@/stores/app"
-const appStore = useAppStore();
-const aloneChecked = ref(false);
-const planId = ref('');
-const orderId = ref('');
-const orderAmt = ref('');
-const planList = ref([]);
-const payType = ref(0);
-const payments = ref([
-  {
-    value: 0,
-    label: "微信支付",
-		icon: "/static/img/weixin.png"
-  },
-  {
-    value: 1,
-    label: "钱包支付",
-		icon: "/static/img/qianbao.png"
-  },
-]);
-const quanyilList = ref([
-  {
-    title: "问答无限制",
-    content: "最新AI聊天模型接口",
-    icon: "/static/img/vip/question.png"
-  },
-  {
-    title: "学习帮手",
-    content: "帮您提高创作效率",
-    icon: "/static/img/vip/xuexi.png"
-  },
-  {
-    title: "疑问解答",
-    content: "互动性聊天体验",
-    icon: "/static/img/vip/yiwen.png"
-  },
-  {
-    title: "私人助理",
-    content: "提供最优解决方案",
-    icon: "/static/img/vip/siren.png"
-  },
-]);
-async function submitForm(){
-  if(!aloneChecked.value){
-		Toast({ title: "请先阅读并同意VIP会员开通协议", icon: 'none' });
-		return;
-	}
-  const res = await createOrder({
-		payMethod:payType.value,//支付方式 0微信 1余额
-		productType:0,//商品类型 0购买会员 1充值
-		productId:planId.value,
-		orderNum:1,//订单数量
-		orderAmt:orderAmt.value//订单金额
-	});
-  orderId.value = res.data.orderId;
-  // 余额支付
-  if(payType.value==1){
-    //1成功 0失败;
-    const paySuccess = res.data.paySuccess;
-    to_success_pay({isSuccess:paySuccess?1:0});
-  }else{ 
-    const payInfo = res.data.payData.prepayWithRequestPaymentResponse
-    wxPay({
-      timeStamp:payInfo.timeStamp,
-      nonceStr:payInfo.nonceStr,
-      packageVal:payInfo.packageVal,
-      signType:payInfo.signType,
-      paySign:payInfo.paySign,
-    },to_success_pay);
-  }
-}
-function to_success_pay({isSuccess}){
-	console.log('to_success_pay',isSuccess);
-	uni.navigateTo({
-    url: `/pages/recharge/success_pay?orderId=${orderId.value}&isSuccess=${isSuccess}&payMethod=${payType.value}`
-  })
-}
-onLoad(() => {
-	getPlanListFn();
-});
-function getPlanListFn(){
-	getPlanList().then(res => {
-		if(res.code == 200){
-			planList.value = res.data || [];
-      //默认单位是durationUnit=='lifetime'
-      if(planList.value.length>0){
-        let plan = planList.value.find(item=>item.durationUnit=='lifetime');
-        planId.value = plan?.planId || planList.value[0].planId;
-        orderAmt.value = plan?.price || planList.value[0].price;
-      }
-		}
-	})
-}
-function setAloneChecked(value){
-  aloneChecked.value = value;
-}
-async function toUser(){
-	uni.navigateTo({
-		url: '/pages/user/user'
-	});
-}
-</script>
-<style lang="less" scoped>
-.vip{
-  height: 100vh;
-  background: #f5f5f5;
-  
-  .vip_top{
-    //#51402E #2B2724 渐变色,从上向下
-    background: linear-gradient(90deg, #51402E 0%, #2B2724 100%);
-    padding: 0 0 50rpx 30rpx;
-    .nickName{
-      color: #DDD3D0;
-    }
-  }
-  .vip_content{
-    position: relative;
-    top: -40rpx;
-    border-radius: 48rpx 48rpx 0 0;
-    background: #f5f5f5;
-    padding-bottom: 100rpx;
-    .title_vip{
-      color: #333333 ;
-      margin: 0 30rpx;
-    }
-    .line_vip{
-      width: 92rpx;
-      height: 6rpx;
-      background: linear-gradient(90deg, #D8D8D8  0%, #333333 100%);
-      &.reverse{
-        transform: rotate(180deg);
-      }
-    }
-  }
-  .gray{
-    color: #999;
-  }
-  .grid-container{
-    gap: 20rpx;
-    .icon{
-      width: 70rpx;
-      height: 70rpx;
-    }
-  }
-  .vip_pay{
-    .plan{
-      padding: 30rpx 20rpx 40rpx;
-      border:1px solid #CCCCCC ;
-      position: relative;
-      background-color: #ffffff;
-      &.active{
-        background-color: #FEF7EA ;
-        border-color: #874605 
-      }
-      .color_price{
-        color: #874605;
-      }
-      .planName{
-        color: #333333;
-      }
-      .hot{
-        position: absolute;
-        top: -20rpx;
-        left: 0rpx;
-        background: linear-gradient(90deg, #2B2724   0%, #503F2E  100%);
-        color: #fff;
-        font-size: 20rpx;
-        padding: 5rpx 10rpx;
-        border-radius: 10rpx 0 10rpx 0;
-      }
-    }
-  }
-  .weixin_img{
-    width: 60rpx;
-    height: 60rpx;
-  }
-  .order_btn ,.memberPlanName{
-		background: linear-gradient(90deg, #FDE492    0%, #FDB85D  100%);
-    color: #874605 ;
-	}
-  .memberPlanName{
-    padding: 5rpx 10rpx;
-    border-radius: 20rpx;
-    font-size: 24rpx;
-  }
-}
-</style>

+ 0 - 100
jd_logistics-app/pages/recharge/wallet.vue

@@ -1,100 +0,0 @@
-<template>
-<view class="wallet">
-	<z-paging
-	ref="pagingRef"
-	class="paginng-contaner"
-	:default-page-size="20"
-	:use-refresher-status-bar-placeholder="true"
-	v-model="list"
-	@query="handleQuery"
-	>
-		<!-- 余额 -->
-		<view class="blance">
-			<view class="flex-center-between">
-				<view class="color_fff">
-					<text class="font_size60 bold mr20">{{appStore.userInfo?.rechargeBalance}}</text>
-					<text class="font_size30">{{appStore.moneyUnit}}</text>
-				</view>
-				<view class="order_btn plain chongzhi font_size30" @click="toRecharge">充值</view>
-			</view>
-			<view class="color_fff font_size25 mt20">账户余额 ( {{appStore.moneyUnit}} )</view>
-		</view>
-		<!-- 账户明细 -->
-		<view class="padding30 accountDetails bg_color_f5">
-			<view class="flex-center-flex-start mb20">
-				<view class="line_vertical"></view>
-				<view class="font_size30 bold">账户明细</view>
-			</view>
-			<view class="bg_color_fff border_radius_20 padding30">
-				<view class="flex-center-between paddingTB20 border_bottom" v-for="item in list" :key="item.recordId">
-					<view class="flex_1">
-						<!-- 交易类型(0=充值,1=消费,2=退款) -->
-						<view class="font_size25 bold">
-							{{item.transactionTypeName}}
-						</view>
-						<view class="font_size20 color_999 mt10">{{item.createTime}}</view>
-					</view>
-					<!-- 交易金额(充值/退款为正,消费为负) -->
-					<view class="flex-column-end">
-						<text class="font_size40 color_price">{{item.amount}}</text>
-						<text class="font_size25 gray">余额{{item.balanceAfter}}</text>
-					</view>
-				</view>
-			</view>
-		</view>
-	</z-paging>
-</view>
-</template>
-<script setup>
-import { ref } from "vue";
-import { getRecordList } from "@/api/user";
-import { useAppStore } from "@/stores/app"
-const appStore = useAppStore();
-const pagingRef = ref();
-const list = ref([]);
-// 下拉刷新和滚动底部会自动触发此方法
-async function handleQuery(page, pageSize, from) {
-  try {
-    const params = {
-      pageNum: page,
-      pageSize,
-			reasonable:false,
-			orderByColumn: 'createTime',
-			isAsc: 'desc'
-    };
-    const { rows } = await getRecordList(params);
-    pagingRef.value.complete(rows);
-  } catch (e) {
-		console.log('msg-comment',e)
-    pagingRef.value.complete(false);
-  }
-}
-function toRecharge(){
-	uni.navigateTo({
-		url: '/pages/recharge/recharge'
-	});
-}
-</script>
-<style lang="less" scoped>
-.wallet{
-	.blance{
-		padding: 80rpx 60rpx;
-		background-color: #fb7145;
-	}
-	.chongzhi{
-		color: #fb7145;
-		padding: 10rpx 40rpx;
-		border-radius: 50rpx;
-	}
-	.line_vertical{
-		background-color: #fb7145;
-		margin-right: 20rpx;
-	}
-	.accountDetails{
-		border-radius: 30rpx 30rpx 0 0;
-		position: relative;
-		top: -30rpx;
-		padding-bottom: 0;
-	}
-}
-</style>

+ 3 - 1
jd_logistics-app/pages/search/search.vue

@@ -39,6 +39,7 @@
 	import {
 	import {
 		ref
 		ref
 	} from 'vue'
 	} from 'vue'
+	import { checkLoginShowModal } from "@/utils/util.js";
 
 
 	const trackingNumber = ref('')
 	const trackingNumber = ref('')
 	const isInputFocused = ref(false)
 	const isInputFocused = ref(false)
@@ -51,7 +52,8 @@
 		isInputFocused.value = false
 		isInputFocused.value = false
 	}
 	}
 
 
-	const handleSearch = () => {
+	const handleSearch = async () => {
+		if (!await checkLoginShowModal()) return;
 		if (!trackingNumber.value.trim()) {
 		if (!trackingNumber.value.trim()) {
 			uni.showToast({
 			uni.showToast({
 				title: '请输入运单号',
 				title: '请输入运单号',

+ 0 - 110
jd_logistics-app/pages/user/user.vue

@@ -1,110 +0,0 @@
-<template>
-	<view class="user padding30">
-		
-		<view class="padding30 bg_color_fff border_radius_20">
-			<u-form labelPosition="left" :model="userInfo" :rules="rules" ref="formRef" labelWidth="auto">
-				
-				<u-form-item label="头像" prop="avatar" :borderBottom="true" required>
-					<view class="avatar flex-center-flex-end">
-						<button class="chooseAvatar" open-type="chooseAvatar" @chooseavatar="chooseAvatar">
-									<u-avatar 
-									size="120rpx"
-									shape="circle"
-									:src="userInfo.avatar"
-									mode="aspectFill"
-								></u-avatar>
-						</button>
-					</view>
-						
-				</u-form-item>
-				<u-form-item label="昵称" prop="nickName" :borderBottom="true" required>
-					<u-input v-model="userInfo.nickName" placeholder="请输入昵称" border="none" clearable inputAlign="right" type="nickname"></u-input>
-				</u-form-item>
-				<u-form-item label="手机号" :borderBottom="false" required>
-					<u-input v-model="userInfo.userPhone" placeholder="账号" border="none" clearable inputAlign="right" readonly></u-input>
-				</u-form-item>
-			</u-form>
-		</view>
-		<view class="foot bg_color_fff">
-			<view class="order_btn paddingTB20 flex_1 text_align_center" @click="submitForm">提交</view>
-		</view>
-	</view>
-</template>
-<script setup>
-import { ref,reactive } from 'vue'
-import { userEdit } from "@/api/user.js";
-import { telEncrypt,chooseImageOne,uploadFile } from "@/utils/util.js";
-import { useToast } from "@/hooks/useToast";
-const { Toast } = useToast();
-import { useAppStore } from "@/stores/app";
-const appStore = useAppStore();
-
-const formRef = ref(null);
-const dgtPopupRef = ref(null);
-const userInfo = ref({
-  userPhone: telEncrypt(appStore.userInfo?.userPhone),
-  nickName: appStore.userInfo?.nickName,
-  avatar: appStore.userInfo?.avatar,
-});
-const rules = reactive({
-  "avatar": [
-    { required: true, message: '请上传头像', trigger: ['blur', 'change'] },
-  ],
-  "nickName": [
-    { required: true, message: '请输入昵称', trigger: ['blur', 'change'] },
-  ]
-});
-// 提交表单
-async function submitForm(){
-  formRef.value
-	.validate()
-	.then((valid) => {
-		console.log('submitForm',valid);
-		if (valid) {
-			userEdit(userInfo.value).then(async res=>{ 
-				await appStore.USERINFO();
-				uni.navigateBack();
-			})
-		} else {
-			Toast({ title: "请完善个人资料" });
-		}
-	})
-	.catch((e) => {
-		console.log('error submit!!',e[0].message);
-		Toast({ title: e[0]?.message || "请完善个人资料!" });
-	});
-};
-
-async function uploadImage(){
-  const res = await chooseImageOne('user/userAvatarUpload');
-  console.log('uploadImage',res);
-  if(res){
-  	userInfo.value.avatar= res.data
-  }
-}
-async function chooseAvatar(e){
-	console.log('chooseAvatar',e);
-	if(e.detail?.avatarUrl){
-		const res = await uploadFile(e.detail?.avatarUrl,'user/userAvatarUpload');
-		console.log('uploadImage',res);
-		if(res){
-			userInfo.value.avatar= res.data
-		}
-	}
-	
-
-}
-</script>
-
-<style lang="scss">
-.user{ 
-	.foot{
-		.order_btn{
-			border-radius: 50rpx;
-		}
-	}
-	.avatar{
-		width: 100%;
-	}
-}
-</style>

+ 6 - 0
jd_logistics-app/pages/webView/webView.vue

@@ -10,6 +10,7 @@ import { onBackPress,onLoad } from '@dcloudio/uni-app';
 
 
 // 页面参数
 // 页面参数
 const webUrl = ref('');
 const webUrl = ref('');
+const title = ref('');
 
 
 // 页面加载时接收参数
 // 页面加载时接收参数
 onLoad((options) => {
 onLoad((options) => {
@@ -21,6 +22,11 @@ onLoad((options) => {
     // 默认地址,可以根据实际需求修改
     // 默认地址,可以根据实际需求修改
     webUrl.value = 'about:blank';
     webUrl.value = 'about:blank';
   }
   }
+  if(options.title){
+	  uni.setNavigationBarTitle({
+	  	title:options.title
+	  })
+  }
 });
 });
 
 
 // 返回上一页
 // 返回上一页

BIN
jd_logistics-app/static/img/index-bg.png


BIN
jd_logistics-app/static/img/service/aijiqiren.png


BIN
jd_logistics-app/static/img/service/assistant-avatar.png


BIN
jd_logistics-app/static/img/service/maikefengyuyin.png


BIN
jd_logistics-app/static/img/service/send-icon.png


BIN
jd_logistics-app/static/img/service/tupian.png


BIN
jd_logistics-app/static/img/service/user-avatar.png


BIN
jd_logistics-app/static/img/service/xiaoxi.png


BIN
jd_logistics-app/static/img/voice/cancel.png


BIN
jd_logistics-app/static/img/voice/recording.gif


BIN
jd_logistics-app/static/img/voice/recording.png


+ 1 - 3
jd_logistics-app/utils/util.js

@@ -17,9 +17,7 @@ import {
 let isLoggingIn = false;
 let isLoggingIn = false;
 
 
 export function telEncrypt(tel = '') {
 export function telEncrypt(tel = '') {
-  let str = tel + "";
-  let enStr = str.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2")
-  return enStr
+  return /^1[3-9]\d{9}$/.test(tel);
 }
 }
 
 
 export function uniLogin() {
 export function uniLogin() {