Compare commits

..

145 Commits

Author SHA1 Message Date
赵毅
a1971a418e Merge branch 'master' of https://git.hshuishang.com/maguodong/uniapp-ZHSQ 2025-10-28 15:08:02 +08:00
赵毅
b2b56f4c02 修改商家入驻bug 2025-10-28 14:40:35 +08:00
赵毅
71b2bc1d6b 优化商品加减数量的作用范围,减少误触可能 2025-10-28 10:40:36 +08:00
赵毅
3115b45600 修改首页搜索框数据异常的问题 2025-10-28 10:35:28 +08:00
赵毅
c8c4cd6bd4 完成物业缴费是否允许跳付的逻辑 2025-10-28 10:25:25 +08:00
赵毅
f0189c6f2c 优化我的小区页面代码,使控制台不会出现报错 2025-10-27 16:09:33 +08:00
赵毅
def0aef656 优化净水小程序的跳转 2025-10-27 11:01:15 +08:00
赵毅
a6eebd287c 跳转到净水小程序 2025-10-27 10:04:07 +08:00
赵毅
4df3526466 优化详情页进入购物车页面的逻辑 2025-10-27 09:43:53 +08:00
赵毅
0cac04e0db 优化首页搜索框样式 2025-10-25 17:44:45 +08:00
赵毅
5a97172f36 优化易购商品详情页代码 2025-10-25 14:30:58 +08:00
赵毅
a665e924cc 修改搜索商品中页面数量不显示0个的bug 2025-10-25 14:06:28 +08:00
赵毅
884b7e5b38 修改首页搜索商品的数量不实时更新的bug 2025-10-24 17:26:58 +08:00
赵毅
a139ec38c9 修改搜索商品的详情页加入购物车按钮的显示逻辑 2025-10-24 16:11:20 +08:00
赵毅
56e0d60f34 修改活动商品详情页加入购物车数量不实时更新的问题 2025-10-24 15:46:37 +08:00
赵毅
042ce47b28 修复活动商品详情页加入购物车金额异常问题 2025-10-24 14:19:08 +08:00
赵毅
681c577a00 11 2025-10-24 09:58:40 +08:00
赵毅
6bfda4993e 添加商家入驻页面 商家分类信息 2025-10-24 09:30:56 +08:00
赵毅
414ea79463 优化首页搜索框跳转逻辑 2025-10-22 14:44:06 +08:00
赵毅
d3c1ab9a99 修改我的小区文字显示 2025-10-22 10:55:47 +08:00
赵毅
fad29dd656 完成商家模块小程序部分的修改 2025-10-22 10:55:11 +08:00
赵毅
7d6cff8a62 完成商品买一赠一的功能 2025-10-21 16:40:41 +08:00
赵毅
1f7eebd66a 优化巡检提交的提示信息 2025-10-20 15:53:02 +08:00
赵毅
15288eaa10 优化物业缴费点击去抵扣物业账单后页面的数据请求逻辑 2025-10-20 11:50:56 +08:00
赵毅
f2acabac3f 优化首页顶部搜索功能 2025-10-20 11:17:09 +08:00
赵毅
06bcc516d0 改为物业费 2025-10-18 16:57:36 +08:00
赵毅
564085bf52 物业公积金改为物业币 2025-10-18 16:35:48 +08:00
赵毅
d41bd5d543 优化物业缴费页面下拉刷新 的逻辑 2025-10-18 16:16:18 +08:00
赵毅
6bfc147b86 修改绑定房源切换城市之后的数据展示逻辑 2025-10-18 16:09:43 +08:00
赵毅
770d53a51b 优化绑定房源操作中的页面效果 2025-10-18 15:50:31 +08:00
赵毅
c58d7cd2ba 11 2025-10-17 16:28:58 +08:00
赵毅
a6b35c3a2e 判断用户巡检权限,修改操作按钮点击逻辑 2025-10-17 16:16:45 +08:00
赵毅
31dc706eed 优化易购页面的页面布局 2025-10-17 11:19:32 +08:00
赵毅
295872ccf1 修改物业端切换小区的逻辑 2025-10-17 09:50:01 +08:00
赵毅
e4a21804b0 修改湖畔社区页面显示数据的逻辑 2025-10-17 09:18:49 +08:00
赵毅
71332e070a 修改好店支付的本页二维码逻辑 2025-10-16 15:43:04 +08:00
赵毅
a0b51c8e9f 优化个人中心页面布局 2025-10-16 15:41:37 +08:00
赵毅
26d427eb52 修改物业端默认选中小区的逻辑 2025-10-16 15:26:59 +08:00
赵毅
cf3234b7d5 优化物业缴费的缴费记录的数据展示逻辑 2025-10-16 10:28:12 +08:00
赵毅
7961d4a5a2 优化线上环境和测试环境的接口调用判断 2025-10-15 15:28:26 +08:00
赵毅
5121c23802 修复团购订单支付后报错的bug 2025-10-15 09:01:05 +08:00
赵毅
17698bf1b8 修改商家端的内容展示 2025-10-14 17:38:00 +08:00
赵毅
c055dba6d4 修复个人中心钱包详情订单号显示异常问题 2025-10-14 11:00:20 +08:00
赵毅
0dafebbb3b 修复好店评价详情页星星不展示的bug 2025-10-14 09:59:34 +08:00
赵毅
30a2765505 修改商家端客服列表的数据展示逻辑 2025-10-14 09:47:50 +08:00
赵毅
244b6dea60 修复物业端查看变动记录页面时报错的bug 2025-10-13 18:03:09 +08:00
赵毅
372950b774 修复个人中心积分变动金额显示异常问题 2025-10-13 18:02:28 +08:00
赵毅
e0abdd3b15 修改各页面中的钱包模块的显示内容 2025-10-13 16:28:13 +08:00
赵毅
1bc846be31 优化好店中点击显示二维码的显示逻辑 2025-10-13 16:25:35 +08:00
赵毅
bd1d95db52 修改快捷支付请求逻辑 2025-10-13 09:50:49 +08:00
赵毅
2030e5e84d 修改好店支付物业公积金和积分的数据显示异常问题 2025-10-11 14:40:19 +08:00
赵毅
3c26c8c1a0 完成湖畔好店的搜索功能 2025-10-11 11:16:23 +08:00
赵毅
c765dd65da 修改图片地址 2025-10-11 09:32:56 +08:00
赵毅
8d60cb6200 完成钱包模块 2025-10-10 11:41:43 +08:00
赵毅
61c15f5d67 修改活动商品的提交订单页面的金额等数据异常问题 2025-10-10 10:56:55 +08:00
赵毅
a4a233f175 修改线上环境我的小区金刚区默认图标不显示的bug 2025-10-10 10:56:02 +08:00
赵毅
2046ab60f0 添加我的小区模块的默认公告内容 2025-10-09 17:35:57 +08:00
赵毅
9be3eecd0f 易购商品搜索部分添加库存校验 2025-10-09 15:44:37 +08:00
赵毅
41c389743e 修复易购商品加入购物车错误的问题 2025-10-09 11:29:24 +08:00
赵毅
24d6593f42 修改花馍详情页加入购物车的逻辑 2025-10-09 10:49:47 +08:00
赵毅
dcfcfaf91f 实现提交订单配送 - 切换收货地址的功能 2025-10-09 09:52:27 +08:00
赵毅
89d39117ba 优化修改收货地址的地区选择县时的逻辑 2025-10-09 09:46:13 +08:00
赵毅
4169e76f53 修改配送地址删除不了的问题 2025-10-08 17:30:45 +08:00
赵毅
b191357f4c 修复好店 是否开启线下快捷买单配置 的逻辑问题 2025-10-08 17:30:01 +08:00
赵毅
924c3bb2fb 修复修改配送地址报错的bug 2025-10-08 17:18:56 +08:00
赵毅
60cf499f38 易购商品改为配送 2025-10-08 17:04:12 +08:00
赵毅
13a271d806 修改活动商品的点击触发逻辑 2025-10-08 16:53:58 +08:00
赵毅
a5d5e3557a 11 2025-10-08 16:32:09 +08:00
赵毅
1d7fbd9f5b 编写首页的搜索商品页面 2025-10-08 16:30:39 +08:00
赵毅
6738f0e5c9 11 2025-10-08 15:15:02 +08:00
赵毅
afd6b44644 修改快捷买单按钮显示异常问题 2025-10-08 14:59:19 +08:00
赵毅
b8a0a13ad3 修改活动商品价格显示不对的问题 2025-10-08 14:56:12 +08:00
赵毅
12f43b2dff 实现店铺管理的选择店铺的功能 2025-10-08 10:28:32 +08:00
赵毅
6f655bed0b 对接个人中心物业费和积分的接口 2025-10-08 10:14:37 +08:00
赵毅
631ef8154e 优化根据登录环境判断请求接口的逻辑 2025-10-08 08:28:08 +08:00
赵毅
6fe1869a00 活动商品改为自提 2025-09-30 16:07:22 +08:00
赵毅
b8dc69905e 根据小程序登录规范调整代码 2025-09-30 16:07:03 +08:00
赵毅
5aa1f18448 修改易购提交订单报错的bug 2025-09-29 17:30:43 +08:00
赵毅
4b175d400d 优化快捷支付页面 2025-09-29 17:18:37 +08:00
赵毅
7817333cf8 修改缴费记录数据显示不全的bug 2025-09-29 17:17:12 +08:00
赵毅
34e8c05b91 修改物业缴费的缴费记录显示问题 2025-09-29 16:47:34 +08:00
赵毅
f5d3cd79de 修改小程序无法更改定位的问题 2025-09-29 16:38:57 +08:00
赵毅
e13b06ece0 修改好店商家页面的付款记录的数据显示逻辑 2025-09-29 16:12:33 +08:00
赵毅
94a17c7107 修改物业缴费支付成功后的逻辑 2025-09-29 15:44:48 +08:00
赵毅
c118145c8b 完成物业模块的钱包页面 2025-09-29 15:12:08 +08:00
赵毅
c87d3dfb5d 巡检页面,提交之后重新请求数据,使禁用状态实时刷新 2025-09-29 11:46:11 +08:00
赵毅
c54b0dd1ad 完成本地生活模块的钱包页面 2025-09-29 11:45:37 +08:00
赵毅
1fbb9bddb8 完成个人中心的钱包页面 2025-09-29 10:17:17 +08:00
赵毅
43f35f517a 修改湖畔社区数据展示逻辑 2025-09-28 15:37:59 +08:00
赵毅
c9270f2cb6 优化代码,规范代码格式 2025-09-27 17:44:44 +08:00
赵毅
8e62a47125 重写活动商品的购物车页面 修改数据展示逻辑 2025-09-27 17:19:59 +08:00
赵毅
b3a65335db 易购花馍洗衣液商品只支持配送 2025-09-27 17:17:10 +08:00
赵毅
00c5364e19 完成活动商品的详情页 2025-09-27 15:52:01 +08:00
赵毅
fdd5900c99 易购商品只支持配送 2025-09-27 14:55:58 +08:00
赵毅
76ba1351e0 添加物业公积金支付成功提示 2025-09-27 10:48:24 +08:00
赵毅
e03aed53a5 修改物业缴费支付报错 2025-09-26 17:41:03 +08:00
赵毅
a0c040e3af 巡检 - 已提交的点位禁用 2025-09-26 16:40:51 +08:00
赵毅
06f9b79012 修改巡检模块提交之后后台数据图片不显示的问题 2025-09-26 16:14:34 +08:00
赵毅
d0f448789a 完善快捷支付记录 2025-09-26 15:33:55 +08:00
赵毅
1c01a7dcb7 修改巡检模块状态错误问题 2025-09-26 15:30:32 +08:00
赵毅
aee000cd6b 修改湖畔好店的评价显示逻辑 2025-09-26 14:58:35 +08:00
赵毅
0fdfc3ca41 Merge branch 'feature/yi' of https://git.hshuishang.com/maguodong/uniapp-ZHSQ into feature/yi 2025-09-26 14:26:27 +08:00
0d226b19ea Merge remote-tracking branch 'origin/feature/yi' into feature/yi 2025-09-26 14:26:01 +08:00
febc3e82f3 优化聊天历史消息加载与MQTT连接配置
- 修改utils引用路径为绝对路径
- loadHistoryMessages方法添加await关键字确保异步执行
- 重构历史消息处理逻辑,直接更新消息列表
- MQTT连接配置增加SSL支持
- 更新MQTT连接地址为wxs协议
- 添加MQTT断开连接方法
- 关闭生产环境代码压缩以便调试
- 开启开发环境URL校验
2025-09-26 14:25:49 +08:00
赵毅
54d017c618 修复巡检提交失败的问题 2025-09-26 11:47:06 +08:00
赵毅
1f47945c98 优化物业缴费模块的逻辑和数据展示 2025-09-26 11:42:35 +08:00
赵毅
0bc9cace0c 完成物业缴费中的组合支付逻辑 2025-09-26 10:11:39 +08:00
赵毅
3324598637 个人中心功能服务 2025-09-26 08:52:44 +08:00
赵毅
59bf3fdb7a 修改功能导航区(物业管理等)的显示逻辑 2025-09-25 17:42:06 +08:00
赵毅
8d072bde1e 添加好店快捷支付订单页面 2025-09-25 16:03:45 +08:00
赵毅
292a74351e 物业缴费未支付成功的订单请求删除接口 2025-09-25 15:57:59 +08:00
赵毅
e59eab06f9 修复物业缴费页面金额显示异常问题 2025-09-25 15:37:04 +08:00
赵毅
af606e5727 修复物业公积金显示错误的问题 2025-09-25 15:32:09 +08:00
赵毅
62ddc43aa2 客服模块优化 2025-09-25 14:53:00 +08:00
95ab7bee52 更新页面组件引用和客服功能
- 更新 ID
- 新多个组件的引用增 headerServerClick了首页 index.js 中 和 toAdvertisingView 方法处理广告点击
- 修改了 serverLeftList 数据属性和相关逻辑
- 更新了预约页面 reservation/index.js 的模块引用 ID
- 优化了客服切换页面 changeService/index.vue 的模板和逻辑
- 修复了聊天记录页面 chattingRecords/index.vue 的图片引用顺序
- 调整了多个页面的数据加载和组件渲染逻辑
2025-09-25 14:21:11 +08:00
赵毅
c5d4eba244 客服模块优化 2025-09-25 11:42:52 +08:00
赵毅
dbae8b4a5a 11 2025-09-24 18:09:16 +08:00
赵毅
9b6a3c9bce 解决手机端解码报错的问题 2025-09-24 17:55:52 +08:00
赵毅
088891bdbb 完善客服模块功能 2025-09-24 17:24:22 +08:00
赵毅
e20e9a3552 修改个人中心物业公积金的数据显示 2025-09-24 16:55:41 +08:00
赵毅
8a4b3d9f69 修改支付界面支付报错的bug 2025-09-24 16:36:25 +08:00
赵毅
d6b758a6bc 修改花馍广告模块的购物车不显示数据的bug 2025-09-24 16:17:24 +08:00
赵毅
b37a945e42 Merge branch 'feature/yi' of https://git.hshuishang.com/maguodong/uniapp-ZHSQ into feature/yi 2025-09-24 15:38:16 +08:00
3b31071e13 修复MQTT连接与消息收发逻辑- 修复发送按钮禁用状态判断条件
- 添加selfClientId存储与使用
- 完善MQTT消息订阅与接收处理-优化消息发送逻辑与数据格式
- 调整MQTT配置获取与clientId绑定
- 清理冗余代码与注释
- 修复消息列表滚动定位问题
- 完善错误处理与连接状态提示
2025-09-24 15:37:34 +08:00
赵毅
60ad675362 添加支付后获取石榴金等的展示 2025-09-24 15:35:31 +08:00
赵毅
9083312649 Merge branch 'feature/yi' of https://git.hshuishang.com/maguodong/uniapp-ZHSQ into feature/yi 2025-09-24 14:29:15 +08:00
42386a201f 添加新的页面路由配置
- 在 app.json 中新增了 routingInspection 和 addRoutingInspection 页面路径
- 新增了 customerService 包下的多个页面配置
- 在 myOrders 包中添加了 groupOrders 页面
- 新增了 smartDevice 和 advertising 包的页面配置
- 更新了 kitchen 页面的 webpack 模块路径引用
2025-09-24 14:28:26 +08:00
赵毅
cc7215d836 完成首页花馍模块 2025-09-24 11:23:32 +08:00
赵毅
da59430dd9 修复商家分类页面数据展示不完整的bug 2025-09-24 09:32:26 +08:00
赵毅
2b90922cc3 修改好店支付返回的积分的逻辑 2025-09-24 09:24:09 +08:00
赵毅
d4c774522e 修改好店支付,完善支付时物业公积金的逻辑 2025-09-24 09:04:03 +08:00
赵毅
5f6e76ea71 客服部分 2025-09-24 08:37:16 +08:00
赵毅
6b9ad175d6 修改湖畔好店页面商家数据显示不全的问题 2025-09-22 18:03:13 +08:00
赵毅
cc30b85288 修复好店的支付bug 2025-09-22 17:09:04 +08:00
赵毅
ed3a8f6e55 完成扫一扫功能 2025-09-22 15:16:24 +08:00
赵毅
845e9bafce 对图片路径做处理 线上环境使用加速域名 2025-09-22 11:35:37 +08:00
赵毅
3209e7e26a 修改因为商家分类接口报错的bug 2025-09-22 11:34:52 +08:00
赵毅
0eed1e96bb 取消地区的限制 2025-09-22 11:34:00 +08:00
赵毅
c3174d2809 修改到家服务的顶部分类逻辑 2025-09-22 10:20:33 +08:00
赵毅
86c74c27b0 完成巡检模块 2025-09-20 18:26:36 +08:00
赵毅
a4c0c42c29 巡检模块页面 2025-09-20 16:45:33 +08:00
赵毅
58e8e9681b 修改员工工单列表部分的显示逻辑 2025-09-20 11:35:00 +08:00
赵毅
dffe1c1c55 修改项目启动报错 2025-09-20 10:41:56 +08:00
赵毅
db223d2a8c 湖畔社区顶部添加图片 更改登录页图片 2025-09-20 10:39:17 +08:00
赵毅
4baca916e0 修改细节名称 2025-09-20 10:38:25 +08:00
121 changed files with 32182 additions and 10036 deletions

View File

@ -1,6 +1,6 @@
<style lang="scss"> <style lang="scss">
/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */ /* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
@import "uview-ui/index.scss"; @import "uni_modules/uview-ui/index.scss";
</style> </style>

View File

@ -52,4 +52,9 @@ export const apiArr = {
tradeQuery: "/api/v2/wechat/community-order-pay/trade-query", //缴费查单 tradeQuery: "/api/v2/wechat/community-order-pay/trade-query", //缴费查单
checkComm: "/api/v2/wechat/community/check-comm", //检查小区是否属于当前用户 checkComm: "/api/v2/wechat/community/check-comm", //检查小区是否属于当前用户
delPay: "/api/v2/wechat/community-order-pay/del", //检查小区是否属于当前用户
getShopList: "/api/v2/wechat/merchant-crud-list/by-user", //根据用户获取商家列表
}; };

6
api/customerService.js Normal file
View File

@ -0,0 +1,6 @@
export const apiArr = {
csGetMsgList: "/api/v2/wechat/contactServer/getMsgList", //获取联系客服消息列表
csGetMsgRecord: "/api/v2/wechat/contactServer/getMsgRecord", //获取联系客服消息记录
csGetToClientId: "/api/v2/wechat/contactServer/getToClientId", //获取联系客服客户端ID
csGetMchContactList: "/api/v2/wechat/contactServer/mchContactList", //商户客服列表
};

View File

@ -1,4 +1,5 @@
export const apiPay = { export const apiPay = {
pay: '/api/v1/lakala/preorder', //预下单 pay: '/api/v1/lakala/preorder', //预下单
queryPay: '/api/v1/lakala/trade-query' //查询交易结果 queryPay: '/api/v1/lakala/trade-query', //查询交易结果
qrcode: '/api/v2/wechat/quick-payment-record-crud/qrcode' //快捷支付二维码
} }

5
api/routingInspection.js Normal file
View File

@ -0,0 +1,5 @@
export const apiArr = {
routingInspectionList: "/api/v2/wechat/inspection-task/list", //巡检任务列表
routingInspectionInfo: "/api/v2/wechat/inspection-task/info", //巡检任务详情
routingInspectionSubmit: "/api/v2/wechat/inspection-task/submit", //巡检任务提交
};

View File

@ -12,6 +12,7 @@ export const apiArr = {
payOrder: "/api/v2/wechat/commodity/order/pay",//支付订单 payOrder: "/api/v2/wechat/commodity/order/pay",//支付订单
settingDefaultAddress: '/api/v2/wechat/commodity/receiving_address/default', // 收货地址设置默认 settingDefaultAddress: '/api/v2/wechat/commodity/receiving_address/default', // 收货地址设置默认
updateAddress: '/api/v2/wechat/commodity/receiving_address/update', // 收货地址修改 updateAddress: '/api/v2/wechat/commodity/receiving_address/update', // 收货地址修改
deleteAddress: '/api/v2/wechat/commodity/receiving_address/delete', // 收货地址删除
addAddress: '/api/v2/wechat/commodity/receiving_address/add', // 收货地址添加 addAddress: '/api/v2/wechat/commodity/receiving_address/add', // 收货地址添加
addAddressList: '/api/v2/wechat/commodity/receiving_address', // 收货地址列表 addAddressList: '/api/v2/wechat/commodity/receiving_address', // 收货地址列表
queryOrder: '/api/v2/wechat/commodity/order/trade_query', // 查询订单 queryOrder: '/api/v2/wechat/commodity/order/trade_query', // 查询订单
@ -21,4 +22,7 @@ export const apiArr = {
goodsSearch: '/api/v2/wechat/commodity/search', // 商品搜索 goodsSearch: '/api/v2/wechat/commodity/search', // 商品搜索
cancelPay: '/api/v2/wechat/commodity/order/cancel_pay', // 用户取消支付 cancelPay: '/api/v2/wechat/commodity/order/cancel_pay', // 用户取消支付
adverGoodsList: '/api/v2/wechat/commodity/adver-goods-list', // 广告货品列表
} }

View File

@ -1,4 +1,6 @@
export const apiArr = { export const apiArr = {
getUserInfo: '/api/v2/wechat/mpuser-crud/info', // 获取城市列表 getUserInfo: '/api/v2/wechat/mpuser-crud/info', // 获取城市列表
userInfoUpdate: '/api/v2/wechat/mpuser-crud/update', // 会员信息更新 userInfoUpdate: '/api/v2/wechat/mpuser-crud/update', // 会员信息更新
getAccumulationFund: '/api/v2/wechat/government-housing-fund-flow-crud/page', // 物业费
getPoints: '/api/v2/wechat/member-points-flow-crud/page', // 积分
} }

View File

@ -21,6 +21,8 @@ export const apiArr = {
createPay:"/api/v2/wechat/quick-payment-record-crud/creat",//创建支付信息 createPay:"/api/v2/wechat/quick-payment-record-crud/creat",//创建支付信息
getPayInfo:"/api/v2/wechat/quick-payment-record-crud/info", //支付记录 getPayInfo:"/api/v2/wechat/quick-payment-record-crud/info", //支付记录
getPreOrderInfo:"/api/v2/wechat/quick-payment-record-crud/preorder", //预下单
tradeQuery:"/api/v2/wechat/quick-payment-record-crud/trade-query", //查单
createStore:"/api/v2/wechat/store-info-crud/creat",//门店信息创建 createStore:"/api/v2/wechat/store-info-crud/creat",//门店信息创建

4
api/wallet.js Normal file
View File

@ -0,0 +1,4 @@
export const apiArr = {
walletList: "/api/v2/wechat/wallet/list", // 商户钱包
walletChangeList: "/api/v2/wechat/wallet/change/list", // 商户钱包变更详情
};

View File

@ -1,32 +1,17 @@
<template> <template>
<view class="foot-fixed"> <view class="foot-fixed">
<view v-for="(item, index) in navList" :key="index"> <view v-for="(item, index) in navList" :key="index">
<view <view id="navIndex" :style="{ width: foot_width }" @click="jump" :data-idx="index" :data-url="item.url"
id="navIndex" :class="{ 'foot-item': true, 'scan-item': item.isScan }">
:style="{ width: foot_width }"
@click="jump"
:data-idx="index"
:data-url="item.url"
:class="{ 'foot-item': true, 'scan-item': item.isScan }"
>
<view class="foot-icon-box"> <view class="foot-icon-box">
<image <image class="foot-icon" :src="item.photo" mode="widthFix" v-if="current != index" :style="{
class="foot-icon" width: item.photo.includes('footer_localLife.png')
:src="item.photo" ? '70rpx'
mode="widthFix" : '',
v-if="current != index" }"></image>
:style="{
width: item.photo.includes('footer_localLife.png')
? '70rpx'
: '',
}"
></image>
<image <image
:class="{ 'foot-icon3': item.photo.includes('footer_richScan.png'), 'foot-icon2': !item.photo.includes('footer_richScan.png') }" :class="{ 'foot-icon3': item.photo.includes('footer_richScan.png'), 'foot-icon2': !item.photo.includes('footer_richScan.png') }"
:src="item.photoAc" :src="item.photoAc" mode="widthFix" v-if="current == index"></image>
mode="widthFix"
v-if="current == index"
></image>
</view> </view>
<text class="foot-label" id="navIndexLabel">{{ item.nav_name }}</text> <text class="foot-label" id="navIndexLabel">{{ item.nav_name }}</text>
@ -36,6 +21,9 @@
</template> </template>
<script> <script>
import { NavgateTo } from "../../utils";
export default { export default {
name: "nav", name: "nav",
props: { props: {
@ -163,15 +151,36 @@ export default {
const url = e.currentTarget.dataset.url; const url = e.currentTarget.dataset.url;
const index = e.currentTarget.dataset.idx; const index = e.currentTarget.dataset.idx;
const item = this.navList[index]; const item = this.navList[index];
// 检查是否为扫码功能 // 检查是否为扫码功能
if (item.isScan) { if (item.isScan) {
// 调用uni-app的扫码API // 调用uni-app的扫码API
uni.scanCode({ uni.scanCode({
success: (res) => { success: (res) => {
// 扫码成功后的处理逻辑 // 扫码成功后的处理逻辑
console.log('扫码结果:', res.result); console.log('扫码结果:', res);
// 可以根据实际需求对扫码结果进行处理
// 检查res中是否包含path字段
if (res.path) {
console.log('扫码结果中的path:', res.path);
// 解析path字段,提取scene参数的值
const pathParts = res.path.split('?');
if (pathParts.length > 1) {
const queryParams = pathParts[1].split('&');
for (const param of queryParams) {
const [key, value] = param.split('=');
if (key === 'scene') {
const params = {
id: value
}
uni.setStorageSync('merchantInfo', params);
NavgateTo('/packages/localLife/detail/index')
break;
}
}
}
}
}, },
fail: (err) => { fail: (err) => {
console.log('扫码失败:', err); console.log('扫码失败:', err);
@ -179,7 +188,7 @@ export default {
}); });
return; return;
} }
// 检查url是否存在且不为空 // 检查url是否存在且不为空
if (!url || url.trim() === '') { if (!url || url.trim() === '') {
this.NotOpen(); this.NotOpen();
@ -190,6 +199,7 @@ export default {
const authen = [ const authen = [
"/pages/index/index", "/pages/index/index",
"/pages/user/index", "/pages/user/index",
"/packages/smartDevice/index/index",
]; ];
// 除首页及个人中心页不需要鉴定ctoken, 其他tab页均需存在登录态才可访问 // 除首页及个人中心页不需要鉴定ctoken, 其他tab页均需存在登录态才可访问
if (authen.includes(url)) { if (authen.includes(url)) {

View File

@ -1,5 +1,5 @@
<template> <template>
<view class="container" @click="headerEnterClick" :data-id="item.community_id":data-name="item.name" > <view class="container" @click="headerEnterClick" :data-id="item.community_id" :data-name="item.name" >
<image class="left_logo" :src="item.pic" mode="aspectFill" /> <image class="left_logo" :src="item.pic" mode="aspectFill" />
<view :class="['right', isLast && 'no_bottom']"> <view :class="['right', isLast && 'no_bottom']">
<view class="header"> <view class="header">

View File

@ -1,11 +1,11 @@
{ {
"ios": { "ios": {
"name": "石榴九九" "name": "湖畔生活家"
}, },
"android": { "android": {
"name": "石榴九九" "name": "湖畔生活家"
}, },
"common": { "common": {
"name": "石榴九九" "name": "湖畔生活家"
} }
} }

25
main.js
View File

@ -7,9 +7,22 @@ import './uni.promisify.adaptor'
App.mpType = 'app' App.mpType = 'app'
Vue.config.productionTip = false Vue.config.productionTip = false
import uView from 'uview-ui'; import uView from 'uni_modules/uview-ui';
Vue.use(uView); Vue.use(uView);
// 导入工具函数
import { processImageUrl } from './utils/index.js'
// 添加全局方法 - Vue 2
Vue.prototype.$processImage = (url) => {
return processImageUrl(url)
}
// 添加全局过滤器 - Vue 2
Vue.filter('processImage', function(url) {
return processImageUrl(url)
})
const app = new Vue({ const app = new Vue({
...App ...App
@ -21,11 +34,19 @@ app.$mount()
// #ifdef VUE3 // #ifdef VUE3
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import uView from 'uview-ui'; import uView from 'uni_modules/uview-ui';
const app = createApp(App) const app = createApp(App)
// 安装 uView // 安装 uView
app.use(uView) app.use(uView)
// 导入工具函数
import { processImageUrl } from './utils/index.js'
// 添加全局方法 - Vue 3
app.config.globalProperties.$processImage = (url) => {
return processImageUrl(url)
}
// 挂载多个全局方法 // 挂载多个全局方法
app.config.globalProperties.$toast = $toast app.config.globalProperties.$toast = $toast
app.config.globalProperties.$modal = $modal app.config.globalProperties.$modal = $modal

5537
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -15,5 +15,11 @@
"前端组件", "前端组件",
"通用组件" "通用组件"
] ]
},
"dependencies": {
"abort-controller": "^3.0.0",
"buffer": "^6.0.3",
"mqtt": "^3.0.0",
"vue": "^3.5.21"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,830 @@
<template>
<view>
<view class="header">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_left" @click="back">
<u-icon name="arrow-left" size="20px" color="#000"></u-icon>
</view>
</view>
</view>
<view class="swiper">
<view class="tag2 tag-img" v-if="
currentGG.is_same_day
">当日达</view>
<swiper :indicator-dots="false" :autoplay="true" :interval="3000" :duration="1000" @change="changeIndex">
<swiper-item v-for="(item, index) in currentGG.commodity_pic" :key="index">
<image :src="picUrl + item"></image>
</swiper-item>
</swiper>
<view class="NumDot" v-if="currentGG.goods_carousel && currentGG.goods_carousel.length > 0">
{{ currentIndex }} /{{ currentGG.goods_carousel.length }}
</view>
</view>
<view class="Money">
<view class="MoneyMark">¥</view>
{{ currentGG.sales_price }}
<view class="MoneyUnit">/{{ currentGG.goods_unit }}</view>
<view class="num">已售{{ soldOutNum }} | 剩余{{ currentGG.stock_quantity }}</view>
</view>
<!-- 规格 -->
<!-- @click="changeGG2(item, index)" :class="index == currentGGIndex ? 'active' : ''"> -->
<view class="GGBox">
<view class="GG_left">
<view class="GG_Item" v-for="(item, index) in info.commodity_goods_info_list" :key="item.id"
@click="changeGG(item, index)" :class="index == currentGGIndex ? 'active' : ''">
{{ item.goods_spec }} / {{ item.goods_unit }}
</view>
</view>
<view class="GG_rigth" v-if="info.commodity_goods_info_list && info.commodity_goods_info_list.length > 0">
共{{ info.commodity_goods_info_list.length }}款
</view>
</view>
<view class="Tit">
<view class="tag tag-text" v-if="
currentGG.is_same_day
">当日达</view>
{{ currentGG.goods_name }}
</view>
<view class="Msg">{{ currentGG.commodity_brief }}</view>
<view class="fenge"></view>
<!-- 已购买区域 -->
<view>
<view class="purchase-area">
<view class="purchase-count">{{ totalCount }}人已购买</view>
<view class="view-more" @click="showPurchaseRecords">查看更多 &gt;</view>
</view>
<view class="record-list">
<view class="record-item" v-for="(record, index) in purchaseRecords" :key="index">
<view class="record-user">
<image :src="record.avatar" class="user-avatar"></image>
<view class="user-name">{{ record.nick_name }}</view>
</view>
<view class="record-amount">
{{ formatDate(record.buy_time) }}买了{{ record.count }}件
</view>
<view class="record-time">
<button class="buy-btn" @click="goSubmit">去下单</button>
</view>
</view>
</view>
</view>
<view class="fenge"></view>
<h3 class="GoodsMsg">商品详情</h3>
<view class="Msg_Item">
<view class="Msg_ItemTit">货号</view>
<view class="Msg_ItemCon" @click="copys(currentGG.goods_no)">
{{ currentGG.goods_no }}
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_copy.png"></image>
</view>
</view>
<view class="Msg_Item">
<view class="Msg_ItemTit">规格说明</view>
<view class="Msg_ItemCon">{{ currentGG.goods_spec }}</view>
</view>
<view class="Msg_Item">
<view class="Msg_ItemTit">售卖单位</view>
<view class="Msg_ItemCon">{{ currentGG.goods_unit }}</view>
</view>
<view class="GoosMsg">
<image v-for="item in currentGG.goods_detail_pic" :src="picUrl + item" :key="item" mode="widthFix"></image>
</view>
<view class="priceInfo">
<h3 class="priceInfo-title">价格说明</h3>
<view class="priceInfo-content">
<view>
<text class="priceInfo-content-title">划线价格:</text>
指商品的厂商指导价、正品零售价、市面常见价或该商品曾经展示过的销售价等,并非原价。仅供参考。
</view>
<view>
<text class="priceInfo-content-title">未划线价格:</text>
指商品的实时价格,不因表述的差异改变性质,具体成交价格根据商品参加活动,或使用优惠券等发生变化最终以订单结算价格为准。
</view>
</view>
</view>
<!-- 底部购物车 -->
<view class="Car">
<view class="car_left">
<view class="share" @click="share">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share.png"
mode="widthFix"></image>
分享
</view>
<view class="cars" @click="car">
<u-badge numberType="limit" :type="type" max="99" :value="carNum"></u-badge>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_car.png"
mode="widthFix"></image>
购物车
</view>
</view>
<view class="car_right2" v-if="info.commodity_goods_info_list[currentGGIndex].stock_quantity < 1">
已售罄
</view>
<view class="car_right" v-if="
info.commodity_goods_info_list[currentGGIndex].stock_quantity > 0 &&
(!info.commodity_goods_info_list[currentGGIndex].cart_count ||
info.commodity_goods_info_list[currentGGIndex].cart_count.count == 0)
" @click="addCar">
加入购物车
</view>
<view class="car_right" @click="changeCar" v-if="
info.commodity_goods_info_list[currentGGIndex].cart_count.count > 0
&& info.commodity_goods_info_list[currentGGIndex].stock_quantity > 0
">
加入购物车
</view>
</view>
<!-- 分享 -->
<view class="shadow" @click.stop="changeShadow" v-if="boxshadow1">
<view class="shadowBox1">
<view class="shadowBox1Item" @click="shareFriend">
<button class="shadowBox1Item_btn" open-type="share" bindtap="onShareButtonClick">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png"
mode="aspectFill"></image>
微信好友
</button>
</view>
<view class="shadowBox1Item" @click="openSave">
<button class="shadowBox1Item_btn">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_saveImg.png"
mode="aspectFill"></image>
生成海报
</button>
</view>
</view>
</view>
<!-- 海报 -->
<view class="shadow" @click="changeShadow2" v-if="boxshadow2">
<view class="shadowBox2">
<view class="shadowBox_img">
<view class="boxshadow_tit">今日商品推荐</view>
<view class="boxshadow_img">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png">
</image>
</view>
<view class="line"></view>
<view class="shadowBoxInfo">
<view class="shadowboxInfo_left">二维码</view>
<view class="shadowboxInfo_right">
<view class="shadowboxInfo_right_1">正鲜生</view>
<view class="shadowboxInfo_right_2">
长按识别小程序 <br />
数量有限马上抢购
</view>
</view>
</view>
</view>
<view class="shadowBox_btn" @click.stop="saveImg">保存海报</view>
</view>
</view>
<!-- 评价 查看详情 -->
<!-- <u-popup :show="show" round="20rpx" mode="bottom" @close="close" @open="open" :z-index="10070">
<view class="reviews-section">
<view class="popup-header">
<h3 class="popup-header-h3">评价</h3>
<view class="popup-header-view" @click="close">取消</view>
</view>
<view class="temp">
<view class="temp1">
<img class="temp_img" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/pingjia.png" />
为你展示真实评价
</view>
<view class="temp1" @click="showSizePopup">
款式
<img class="temp_img1" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/kuanshi.png" />
</view>
</view>
<view class="reviews-list" v-if="comments.length > 0">
<view class="review-item" v-for="(comment, index) in comments" :key="index">
<view class="review-user">
<image :src="comment.avatar" class="user-avatar"></image>
<view class="user-info">
<view class="user-name">{{ comment.username }}</view>
</view>
<view class="review-time">{{ comment.time }}</view>
</view>
<view class="user-purchase">已购 {{ comment.product }}</view>
<view class="review-content">{{ comment.content }}</view>
<view class="review-images" v-if="comment.images.length > 0">
<image :src="img" class="review-img" v-for="(img, idx) in comment.images" :key="idx"></image>
</view>
</view>
</view>
</view>
</u-popup> -->
<!-- 团购记录弹窗 -->
<u-popup :show="showPurchase" round="20rpx" mode="bottom" @close="closePurchase">
<view class="purchase-popup">
<view class="popup-header">
<h3 class="popup-header-h3">团购记录</h3>
<view class="popup-header-view" @click="closePurchase">取消</view>
</view>
<view class="purchase-records">
<view class="record-header">
<view class="record-header-item">买家</view>
<view class="record-header-item">数量</view>
<view class="record-header-item">购买时间</view>
</view>
<view class="record-list">
<view class="record-item" v-for="(record, index) in purchaseRecords" :key="index">
<view class="record-user">
<image :src="record.avatar" class="user-avatar"></image>
<view class="user-name">{{ record.nick_name }}</view>
</view>
<view class="record-amount">+{{ record.count }}</view>
<view class="record-time">{{ record.buy_time }}</view>
</view>
</view>
</view>
</view>
</u-popup>
<!-- 选择款式 -->
<u-popup :show="showSize" round="20rpx" mode="bottom" @close="closeSize">
<view class="popup-header">
<h3 class="popup-header-h3">选择款式</h3>
<view class="popup-header-view" @click="closeSize">取消</view>
</view>
<view class="itemSize_top">
<image :src="changeImg" class="itemSize-img"></image>
<view class="itemSize_info">
<view class="itemSize_name">{{ changeName }}</view>
<view class="itemSize_price">¥{{ changePrice }}/袋</view>
</view>
</view>
<view class="itemSize" v-for="(item, index) in info.commodity_goods_info_list" :key="item.id"
@click="changeGG(item, index)" :class="index == currentGGIndex ? 'itemSize_active' : ''">
{{ item.goods_name }} {{ item.goods_spec }} / {{ item.goods_unit }}
</view>
</u-popup>
</view>
</template>
<script>
import { apiArr } from "../../../api/shop";
import { apiArr as apiArr2 } from "../../../api/groupPurchase";
import { picUrl, menuButtonInfo, request, NavgateTo } from "../../../utils";
export default {
data() {
return {
itemObj: {},
picUrl,
top: "",
localHeight: "",
carNum: "",
prevCarNum: "",
currentNum: "0", //当前商品的数量
type: "error",
boxshadow1: false,
boxshadow2: false,
id: "",
groupById: "",
promotional_price: "", //活动价
info: "",
currentIndex: "1", //当前轮播图
currentGG: "", //当前选中规格
currentGGIndex: "", //当前规格index
carOrderList: [],
// 新增评论数据
showReviewPopup: false,
soldOutNum: 0,
show: false,
showSize: false,
showPurchase: false,
purchaseRecords: [],
totalCount: 0,
changeImg: "",
changeName: "",
changePrice: "",
endTime: "",
endTheCountdownDay: '',
endTheCountdownHour: '',
endTheCountdownMinute: '',
endTheCountdownSecond: '',
timer: null, // 定时器ID
};
},
methods: {
// 显示团购记录
showPurchaseRecords() {
if (this.purchaseRecords.length > 0) {
this.showPurchase = true;
} else {
uni.showToast({
title: '没有更多数据',
icon: 'none'
})
}
},
// 关闭团购记录
closePurchase() {
this.showPurchase = false;
},
//去下单
goSubmit() {
NavgateTo('/packages/shop/groupPurchaseSubmit/index')
},
changeIndex(e) {
this.currentIndex = e.detail.current + 1;
},
back() {
uni.navigateBack({
delta: 1,
});
},
// 分享给微信好友方法 - 触发分享给好友的聊天框
shareFriend() {
this.boxshadow1 = false; // 关闭分享弹窗
// 获取当前商品的分享信息
const shareInfo = {
title: this.currentGG.goods_name || '商品分享', // 分享标题
desc: this.currentGG.commodity_brief || '快来看看这款商品吧', // 分享描述
link: `${window.location.origin}/pages/goodsDetail/index?id=${this.id}`, // 商品详情页链接
imageUrl: this.picUrl + (this.currentGG.goods_carousel && this.currentGG.goods_carousel[0] || '') // 分享图片
};
// 判断环境是否支持微信分享
if (typeof WeixinJSBridge === 'undefined') {
// 尝试使用uni的分享API作为备选方案
if (typeof uni.share !== 'undefined') {
uni.share({
provider: 'weixin',
scene: 'WXSceneSession',
type: 0,
title: shareInfo.title,
summary: shareInfo.desc,
href: shareInfo.link,
imageUrl: shareInfo.imageUrl,
success: () => {
uni.showToast({
title: '分享成功',
icon: 'success',
duration: 2000
});
},
fail: (err) => {
console.error('分享失败', err);
uni.showToast({
title: '分享失败,请重试',
icon: 'none',
duration: 2000
});
}
});
} else {
uni.showToast({
title: '请在微信客户端打开',
icon: 'none'
});
}
return;
}
try {
// 主动触发微信分享给好友聊天框
WeixinJSBridge.invoke('sendAppMessage', {
title: shareInfo.title,
desc: shareInfo.desc,
link: shareInfo.link,
img_url: shareInfo.imageUrl,
img_width: '120',
img_height: '120',
type: 'link',
data_url: ''
}, (res) => {
if (res.err_msg === 'sendAppMessage:ok') {
uni.showToast({
title: '分享成功',
icon: 'success',
duration: 2000
});
} else if (res.err_msg === 'sendAppMessage:cancel') {
uni.showToast({
title: '已取消分享',
icon: 'none',
duration: 2000
});
} else {
console.error('分享失败', res);
uni.showToast({
title: '分享失败,请重试',
icon: 'none',
duration: 2000
});
}
});
} catch (error) {
console.error('调用微信分享接口失败', error);
// 降级处理:使用wx.ready方式作为备选
if (typeof wx !== 'undefined') {
wx.ready(() => {
// 设置分享给微信好友的回调
wx.onMenuShareAppMessage({
title: shareInfo.title,
desc: shareInfo.desc,
link: shareInfo.link,
imgUrl: shareInfo.imageUrl,
type: 'link',
success: () => {
uni.showToast({
title: '分享成功',
icon: 'success',
duration: 2000
});
},
cancel: () => {
uni.showToast({
title: '已取消分享',
icon: 'none',
duration: 2000
});
},
fail: (err) => {
console.error('分享失败', err);
uni.showToast({
title: '分享失败,请重试',
icon: 'none',
duration: 2000
});
}
});
// 提示用户点击右上角分享
uni.showToast({
title: '请点击右上角分享按钮',
icon: 'none'
});
});
wx.error((err) => {
console.error('微信JS-SDK初始化失败', err);
uni.showToast({
title: '分享功能加载失败',
icon: 'none'
});
});
}
}
},
changeShadow() {
this.boxshadow1 = false;
},
openSave() {
this.boxshadow1 = false;
this.boxshadow2 = true;
},
// 保存海报
saveImg() {
this.boxshadow2 = false;
// 微信小程序保存图片
uni.downloadFile({
url: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png",
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: (res) => {
uni.showToast({
title: "保存成功",
icon: "success",
duration: 2000,
});
},
fail: (err) => {
console.log("保存失败", err);
},
});
}
},
fail: (err) => {
console.log("下载失败", err);
},
});
},
changeShadow2() {
this.boxshadow2 = false;
},
// 点分享按钮
share() {
this.boxshadow1 = true;
},
//商品详情
getGoodsInfo() {
const params = {
id: this.id,
}
request(apiArr.getGoodsInfo, "POST", params).then((res) => {
// 分割图片
res.commodity_goods_info_list.forEach((item) => {
item.goods_detail_pic = item.goods_detail_pic ? item.goods_detail_pic.split(",") : [];
item.goods_carousel = item.goods_carousel ? item.goods_carousel.split(",") : [];
item.commodity_pic = item.commodity_pic ? item.commodity_pic.split(",") : [];
});
//根据购物车列表 和 当前商品列表 来更新当前商品列表在购物车中的数量
if (this.carOrderList) {
this.carOrderList.forEach((items) => {
res.commodity_goods_info_list.forEach((item) => {
if (items.goods_id == item.id) {
item.cart_count = { count: 0 };
item.cart_count.count = items.count;
}
});
});
}
const currentTime = new Date().getTime();
this.info = res;
// 确保商品列表不为空
if (this.info && this.info.commodity_goods_info_list && this.info.commodity_goods_info_list.length > 0) {
// 根据itemObj在商品列表中找到对应的索引
this.currentGGIndex = this.itemObj && this.info.commodity_goods_info_list
? this.info.commodity_goods_info_list.findIndex(item => item.id === this.itemObj.id)
: 0;
// 如果没找到匹配项,默认为0
if (this.currentGGIndex === -1) {
this.currentGGIndex = 0;
}
// 使用完整的商品数据对象,而不是itemObj
this.currentGG = this.info.commodity_goods_info_list[this.currentGGIndex];
// 将promotional_price赋值给sales_price
this.currentGG.sales_price = this.promotional_price;
// 设置相关属性
this.changeImg = this.currentGG.commodity_pic[0];
this.changeName = this.currentGG.goods_alias;
this.changePrice = this.currentGG.sales_price;
} else {
// 商品列表为空时的处理
this.currentGG = null;
this.currentGGIndex = 0;
this.changeImg = '';
this.changeName = '';
this.changePrice = '';
}
});
},
copys(e) {
uni.setClipboardData({
data: e,
success: (res) => {
uni.showToast({
title: "复制成功",
icon: "success",
duration: 2000,
});
},
});
},
// 切换规格
changeGG(item, index) {
this.currentGG = item;
// 将promotional_price赋值给sales_price
this.currentGG.sales_price = this.promotional_price;
this.currentGGIndex = index;
if (this.currentGG.cart_count) {
this.currentNum = this.currentGG.cart_count.count;
} else {
this.currentGG.cart_count = { count: 0 };
}
this.changeImg = item.commodity_pic[0]
this.changeName = item.goods_alias
this.changePrice = this.currentGG.sales_price
},
car() {
const item = {
is_adver: 1,
}
NavgateTo("../shopCar/index?item=" + JSON.stringify(item));
},
getShopCarList() {
const params = {
is_adver: 1,
}
return request(apiArr.getCar, "POST", params).then((res) => {
// 合并当日达和普通商品数据
this.carOrderList = [].concat(res.same_day_cart_list, res.normal_cart_list)
.flatMap(supplier => supplier.commodity_cart_and_goods_model);
this.carNum = res.total;
return res;
});
},
addCar() {
let that = this;
this.info.commodity_goods_info_list[this.currentGGIndex].cart_count = {
count: this.itemObj.one_one === 1 ? 2 : 1,
};
// this.info.commodity_goods_info_list.forEach((item) => {
// console.log(item.cart_count);
// goods_id_and_count.push({
// goods_id: item.id,
// count: item.cart_count ? item.cart_count.count : 0,
// });
// });
let countVal = this.itemObj.one_one === 1 ? 2 : 1;
const params = {
goods_id_and_count: [
{
goods_id:
this.info.commodity_goods_info_list[this.currentGGIndex].id,
count: countVal,
price: this.changePrice
},
],
adver_id: this.itemObj.adver_id,
}
request(apiArr.updateCar, "POST", params).then((res) => {
// that.getShopCar();
that.getShopCarList();
});
},
// 购物车更改
changeCar() {
// 获取当前商品的购物车数量,如果不存在则设为0
const currentCount = this.info.commodity_goods_info_list[this.currentGGIndex].cart_count?.count;
// 新的数量为当前数量加一
const newCount = this.itemObj.one_one === 1 ? currentCount + 2 : currentCount + 1;
const params = {
user_id: uni.getStorageSync("userId"),
goods_id_and_count: [
{
goods_id: this.info.commodity_goods_info_list[this.currentGGIndex].id,
count: newCount,
price: this.changePrice
},
],
adver_id: this.itemObj.adver_id,
};
request(apiArr.updateCar, "POST", params).then((res) => {
return this.getShopCarList();
}).then(() => {
uni.showToast({
title: "操作成功!",
success() { },
});
this.getGoodsInfo();
});
},
showPopup() {
this.show = true;
},
showSizePopup() {
this.showSize = true;
},
close() {
this.show = false;
},
closeSize() {
this.showSize = false;
},
// 购买记录
getBuyRecord() {
const params = {
activity_id: 47,
goods_id: this.id
}
request(apiArr2.groupBuyRecord, 'POST', params).then(res => {
const record = res.group_buy_record.map(item => {
return {
...item,
avatar: picture + item.avatar
}
})
this.purchaseRecords = record
this.totalCount = res.total_count
// 计算所有item.count的总和并赋值给soldOutNum
this.soldOutNum = record.reduce((total, item) => total + (item.count || 0), 0)
})
},
formatDate(dateStr) {
if (!dateStr) return '';
const date = new Date(dateStr);
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${month}月${day}日`;
},
// 计算距离结束日期的剩余时间
getEndTheCountdown(endTime) {
// 获取当前时间和结束时间的时间戳
const now = new Date().getTime();
const end = new Date(endTime).getTime();
// 计算时间差(毫秒)
let diff = end - now;
// 如果已经结束,返回提示
if (diff <= 0) {
return '团购已结束';
}
// 计算距离结束时间
this.endTheCountdownDay = Math.floor(diff / (1000 * 60 * 60 * 24));
diff -= this.endTheCountdownDay * (1000 * 60 * 60 * 24);
this.endTheCountdownHour = Math.floor(diff / (1000 * 60 * 60));
diff -= this.endTheCountdownHour * (1000 * 60 * 60);
this.endTheCountdownMinute = Math.floor(diff / (1000 * 60));
diff -= this.endTheCountdownMinute * (1000 * 60);
this.endTheCountdownSecond = Math.floor(diff / (1000));
}
},
onLoad(options) {
this.itemObj = JSON.parse(decodeURIComponent(options.item));
const meun = menuButtonInfo();
this.top = meun.top;
this.localHeight = meun.height;
this.id = this.itemObj.commodity_id ? this.itemObj.commodity_id : this.itemObj.id;
this.groupById = this.itemObj.groupById
this.promotional_price = this.itemObj.promotional_price
this.getBuyRecord()
this.getEndTheCountdown(this.endTime)
// 启动定时器,每秒更新一次倒计时
this.timer = setInterval(() => {
this.getEndTheCountdown(this.endTime)
}, 1000)
},
onReachBottom() { },
onShow() {
// 确保getShopCarList完成后再执行getGoodsInfo
this.getShopCarList().then(() => {
this.getGoodsInfo();
});
},
//离开页面的时候直接更新购物车数量(目前接口是 传入商品id 数量。如果有当前商品就更新数量。如果没有就增加商品。如果删除某个商品 count 为0 就删除)
onHide() {
// 清除定时器
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
let goods_id_and_count = [];
this.info.commodity_goods_info_list.forEach((item) => {
goods_id_and_count.push({
goods_id: item.id,
count: item.cart_count ? item.cart_count.count : 0,
});
});
// request(apiArr.updateCar, "POST", {
// goods_id_and_count,
// }).then((res) => {
// console.log("Cart updated on hide");
// });
return;
},
};
</script>
<style>
@import url("./index.css");
</style>

View File

@ -0,0 +1,608 @@
page {
background-color: #f5f7fb;
}
.container {
padding: 0;
margin: 0;
font-size: 28rpx;
color: #333;
}
/* 顶部切换栏 */
.tab-bar {
display: flex;
background-color: #fff;
padding: 20rpx 0;
}
.tab-item {
width: 180rpx;
height: 70rpx;
line-height: 70rpx;
text-align: center;
border-radius: 15rpx;
margin: 0 20rpx;
font-size: 28rpx;
border: 1rpx solid #ddd;
}
.tab-item.active {
background-color: #ff370b;
color: #fff;
}
/* 分隔线 */
.divider {
height: 20rpx;
background-color: #f5f5f5;
}
/* 公共标题样式 */
.section-title {
font-size: 32rpx;
color: #333;
font-weight: bold;
padding: 20rpx 30rpx;
}
/* 收货地址区域 */
.info-section {
background: repeating-linear-gradient(to right,
#fe5355,
#fe5355 20px,
#549aff 20px,
#549aff 40px);
padding: 10rpx 0;
}
.address-section {
background-color: #fff;
}
.address-info {
padding: 30rpx;
display: flex;
justify-content: space-between;
align-items: flex-start;
border-bottom: 1rpx solid #eee;
}
.address-main {
flex: 1;
}
.address-name-phone {
display: flex;
align-items: center;
margin-bottom: 10rpx;
}
.name {
font-size: 32rpx;
margin-right: 20rpx;
}
.phone {
font-size: 30rpx;
color: #666;
}
.address-detail {
font-size: 28rpx;
color: #666;
line-height: 40rpx;
display: flex;
align-items: center;
}
.address-arrow {
color: #333;
}
.addNewAddress {
font-size: 32rpx;
color: #999999;
float: right;
}
/* 商品信息区域 */
.goods-section {
background-color: #fff;
margin-bottom: 20rpx;
}
.goods-item {
border-radius: 10rpx;
padding: 15rpx;
display: flex;
background-color: #fff;
}
.goods-image {
width: 140rpx;
height: 140rpx;
border-radius: 15rpx;
overflow: hidden;
margin-right: 15rpx;
}
.goods-image image {
width: 100%;
height: 100%;
object-fit: cover;
}
.goods-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
}
.goods-name {
font-size: 28rpx;
font-weight: bold;
margin-bottom: 8rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.goods-desc {
font-size: 22rpx;
color: #666;
margin-bottom: 10rpx;
}
.price-container {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10rpx;
}
.group-price {
font-size: 28rpx;
color: #e63946;
margin-right: 10rpx;
border-radius: 4rpx;
/* display: flex; */
}
.group-price-box {
display: flex;
}
.group-price1 {
width: 100rpx;
padding: 10rpx 15rpx;
color: #ffffff;
background-color: #fc5d15;
border-radius: 15rpx 0 0 15rpx;
}
.group-price2 {
width: auto;
padding: 10rpx 15rpx;
background: linear-gradient(to bottom, #fef6d6, #fee8a9);
border-radius: 0 15rpx 15rpx 0;
}
.original-price {
font-size: 26rpx;
color: #999;
}
.countdown {
width: 250rpx;
font-size: 22rpx;
padding: 10rpx 15rpx;
color: #ffffff;
margin-bottom: 15rpx;
border-radius: 50rpx;
background-color: #fe2f01;
position: absolute;
top: 150rpx;
right: 0;
}
.quantity-control {
display: flex;
align-items: center;
justify-content: flex-end;
}
.decrease-btn {
width: 40rpx;
height: 40rpx;
background-color: #f5f5f5;
border: 1rpx solid #ccc;
border-radius: 50%;
line-height: 33rpx;
text-align: center;
font-size: 28rpx;
color: #333;
}
.increase-btn {
width: 40rpx;
height: 40rpx;
background-color: #ff502a;
border-radius: 50%;
line-height: 33rpx;
text-align: center;
font-size: 28rpx;
color: #ffffff;
}
.quantity {
margin: 0 15rpx;
font-size: 24rpx;
width: 40rpx;
text-align: center;
}
/* 运费和总金额区域 */
.fee-section,
.total-section {
background-color: #fff;
padding: 30rpx;
display: flex;
justify-content: space-between;
border-bottom: 1rpx solid #eee;
}
.fee-name,
.total-name {
font-size: 30rpx;
}
.fee-value,
.total-value {
font-size: 30rpx;
color: #333;
}
.total-value {
font-weight: bold;
color: #FF7658;
}
/* 复制 */
.copy-icon {
width: 30rpx;
height: 30rpx;
background-image: url('https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/copy.png');
background-size: cover;
margin-left: 10rpx;
}
/* 支付方式区域 */
.payment-section {
background-color: #fff;
margin-bottom: 20rpx;
margin-top: 15rpx;
}
.payment-item {
padding: 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1rpx solid #eee;
}
.payment-icon {
width: 60rpx;
height: 60rpx;
margin-right: 20rpx;
}
.payment-icon image {
width: 100%;
height: 100%;
}
.payment-content {
flex: 1;
}
.payment-name {
font-size: 32rpx;
margin-bottom: 5rpx;
}
.payment-desc {
font-size: 26rpx;
color: #333;
}
.payment-select {
color: #FF7658;
}
/* 立即支付按钮 */
.pay-button {
height: 100rpx;
line-height: 100rpx;
text-align: center;
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
color: #fff;
font-size: 36rpx;
font-weight: bold;
border-radius: 50rpx;
position: fixed;
bottom: 50rpx;
left: 15%;
width: 70%;
/* z-index: 99; */
}
/* 自提样式 */
.pickup-info {
padding: 30rpx;
background-color: #fff;
}
.pickup-address {
font-size: 30rpx;
margin-bottom: 10rpx;
}
.pickup-time {
font-size: 28rpx;
color: #999;
}
/* 弹窗 */
.shadow {
background: rgba(0, 0, 0, 0.4);
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 9;
}
.shadowBox2 {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: auto;
height: auto;
}
.shadowBox_img {
width: 600rpx;
height: 800rpx;
background-color: #fff;
border-radius: 20rpx;
position: relative;
}
.boxshadow_tit {
font-size: 32rpx;
color: #222222;
padding-top: 40rpx;
display: flex;
justify-content: center;
align-items: center;
}
.boxshadow_tit_img {
width: 70rpx;
height: 70rpx;
margin-right: 10rpx;
}
.boxshadow_img {
/* width: 300rpx;
height: 300rpx; */
margin: 0 auto;
margin-top: 40rpx;
text-align: center;
}
.wealBoxTit {
display: flex;
align-items: flex-end;
margin-top: 30rpx;
margin-left: 20rpx;
}
.wealBoxTit1 {
color: #fe1535;
font-size: 32rpx;
font-weight: bold;
}
.wealBoxTit2 {
color: #fe1535;
font-size: 26rpx;
margin-left: 15rpx;
}
.wealBox {
width: 93%;
height: 170rpx;
margin: 15rpx auto;
display: flex;
}
.wealBoxItem {
width: 150rpx;
height: 150rpx;
margin: 0 10rpx;
border-radius: 15rpx;
padding: 20rpx 10rpx;
text-align: center;
display: flex;
/* 添加 flex 布局 */
flex-direction: column;
/* 设置主轴为垂直方向 */
justify-content: space-between;
/* 垂直方向上平均分布 */
align-items: center;
/* 水平方向居中 */
}
.wealBoxItem1 {
background-color: #fff4f1;
}
.wealBoxItem2 {
background-color: #fff7f1;
}
.wealBoxItem3 {
background-color: #fffaf0;
}
.wealBoxItemTop {
display: flex;
align-items: center;
justify-content: center;
}
.wealBoxItemTop image {
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
.wealBoxItemBottom {
font-size: 26rpx;
color: #999999;
}
.bottom {
width: 100%;
position: absolute;
bottom: 30rpx;
}
.boxbottom1 {
margin: 0 auto;
}
.boxbottom {
width: 100%;
margin-bottom: 50rpx;
display: flex;
justify-content: center;
align-items: center;
}
.line1 {
width: 80rpx;
height: 1rpx;
margin: 0 10rpx;
background: linear-gradient(to left, #333, #fff);
}
.line2 {
width: 80rpx;
height: 1rpx;
margin: 0 10rpx;
background: linear-gradient(to right, #333, #fff);
}
.shadowBox1 {
width: 100%;
display: flex;
margin-bottom: 30rpx;
}
.shadowBox1Item_btn {
width: 110rpx;
height: 150rpx;
border: 1rpx solid red;
position: absolute;
left: 100rpx;
opacity: 0;
}
.shadowBox2Item_btn {
width: 110rpx;
height: 150rpx;
border: 1rpx solid red;
position: absolute;
right: 100rpx;
opacity: 0;
}
.shadowBox1Item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: #000000;
}
.shadowBox1Item image {
width: 100rpx;
height: 100rpx;
margin-bottom: 26rpx;
}
.shadowBoxInfo {
display: flex;
align-items: center;
margin-left: 62rpx;
margin-top: 11rpx;
}
.shadowboxInfo_left {
width: 130rpx;
height: 130rpx;
background: #EFEFEF;
border-radius: 50%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
margin-right: 36rpx;
}
.shadowboxInfo_right_1 {
font-size: 32rpx;
color: #222222;
margin-bottom: 10rpx;
}
.shadowboxInfo_right_2 {
font-size: 26rpx;
color: #999999;
}
.shadowBox_btn {
font-size: 36rpx;
color: #FFFFFF;
width: 600rpx;
height: 90rpx;
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
border-radius: 100rpx 100rpx 100rpx 100rpx;
display: flex;
align-items: center;
justify-content: center;
margin-top: 60rpx;
}
.empty-tip {
height: 200rpx;
font-size: 28rpx;
color: #999999;
text-align: center;
line-height: 200rpx;
background-color: #fff;
}

View File

@ -0,0 +1,827 @@
<template>
<view class="container">
<!-- 顶部切换栏 -->
<view class="tab-bar">
<!-- <view :class="{ active: activeTab === 'delivery' }" class="tab-item" @click="switchTab('delivery')">配送
</view> -->
<view :class="{ active: activeTab === 'pickup' }" class="tab-item" @click="switchTab('pickup')">自提</view>
</view>
<!-- 分隔线 -->
<view class="divider"></view>
<!-- 配送/自提信息 -->
<view class="info-section" v-if="activeTab === 'delivery'">
<view class="address-section">
<view class="section-title">收货地址</view>
<view class="address-info" @click="chooseAddress" v-if="defAddress">
<view class="address-main">
<view class="address-name-phone">
<text class="name">{{ defAddress.name }}</text>
<text class="phone">{{ defAddress.phone }}</text>
</view>
<view class="address-detail">
{{ defAddress.address }}{{ defAddress.house_number }}
<view class="copy-icon" @click.stop="copyAddress" />
</view>
</view>
<view class="address-arrow"><u-icon name="arrow-right" size="25"></u-icon></view>
</view>
</view>
</view>
<!-- 分隔线 -->
<view class="divider"></view>
<!-- 商品信息 -->
<view v-if="activeTab === 'delivery' && orderList1.length > 0">
<view class="goods-list">
<view class="goods-item" v-for="(item, index) in orderList1" :key="index">
<view class="goods-image">
<image :src="item.commodity_goods_info.commodity_pic" mode="aspectFill"></image>
</view>
<view class="goods-info">
<view class="goods-name">{{ item.commodity_goods_info.goods_name }}</view>
<view class="goods-desc">{{ item.commodity_goods_info.goods_spec }}</view>
<view class="price-container">
<view class="group-price">
<view>¥{{ item.commodity_goods_info.sales_price }}/{{
item.commodity_goods_info.goods_unit
}}</view>
<!-- 运费 -->
<view class="goods-desc" style="margin-top: 10rpx;">运费 ¥{{
item.commodity_goods_info.freight }}</view>
</view>
<view class="quantity-control">
<view class="decrease-btn" @tap.stop="decreaseQuantity(item)">-</view>
<view class="quantity">{{ item.count }}</view>
<view class="increase-btn" @tap.stop="increaseQuantity(item)">+</view>
</view>
</view>
</view>
</view>
</view>
<!-- 运费 -->
<!-- <view class="fee-section">
<view class="fee-name">运费</view>
<view class="fee-value">¥{{ item.commodity_goods_info.freight }}</view>
</view> -->
<!-- 总金额 -->
<view class="total-section">
<view class="total-name">总金额</view>
<view class="total-value">¥{{ calculateTotal('order1') }}</view>
</view>
<!-- 支付方式 -->
<view class="payment-section">
<view class="payment-item" @click="selectPayment('wechat')">
<view class="payment-icon">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_wechat.png"
mode="aspectFit"></image>
</view>
<view class="payment-content">
<view class="payment-name">微信支付</view>
<view class="payment-desc"><text
style="color: #f03d0e;margin-right: 15rpx;">可用优惠券</text>单笔支付限额:¥10000.00</view>
</view>
<view class="payment-select" v-if="selectedPayment === 'wechat'">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png"
mode="aspectFit" style="width: 40rpx; height: 40rpx;"></image>
</view>
<view class="payment-select" v-else>
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png"
mode="aspectFit" style="width: 40rpx; height: 40rpx;"></image>
</view>
</view>
</view>
</view>
<view v-if="activeTab === 'delivery' && orderList1.length == 0" class="empty-tip">
暂无商品数据
</view>
<view v-if="activeTab === 'pickup' && orderList2.length > 0">
<!-- 按供应商分组 -->
<view v-for="(group, supplierId) in supplierGroups" :key="supplierId">
<view class="goods-list">
<view class="info-section">
<view class="address-section">
<view class="section-title">自提点</view>
<view @click="editAddress(group[0])">
<view v-if="defZTAddress.length > 0">
<view v-for="(adItem, adIndex) in defZTAddress" :key="adIndex">
<view class="address-info" v-if="adItem.id == supplierId">
<view class="address-main">
<view class="address-name-phone">
<text class="name">{{ adItem.name }}</text>
<text class="phone">{{ adItem.phone }}</text>
</view>
<view class="address-detail">
{{ adItem.address }}
<view class="copy-icon" @click.stop="copyZTAddress" />
</view>
</view>
<view class="address-arrow"><u-icon name="arrow-right" size="25"></u-icon>
</view>
</view>
</view>
<view class="address-info"
v-if="!defZTAddress.some(adItem => adItem.id == supplierId)">
<view class="address-main">
<view class="address-name-phone">
<text class="name">请选择自提点</text>
</view>
</view>
<view class="address-arrow"><u-icon name="arrow-right" size="25"></u-icon>
</view>
</view>
</view>
<view class="address-info" v-else>
<view class="address-main">
<view class="address-name-phone">
<text class="name">请选择自提点</text>
</view>
</view>
<view class="address-arrow"><u-icon name="arrow-right" size="25"></u-icon></view>
</view>
</view>
</view>
</view>
</view>
<!-- 该供应商下的所有商品 -->
<view class="goods-item" v-for="(item, index) in group" :key="index">
<view class="goods-image">
<image :src="item.commodity_goods_info.commodity_pic" mode="aspectFill"></image>
</view>
<view class="goods-info">
<view class="goods-name">{{ item.commodity_goods_info.goods_name }}</view>
<view class="goods-desc">{{ item.commodity_goods_info.goods_spec }}</view>
<view class="price-container">
<view class="group-price">
<view>
<view v-if="isWithinActivityTime(item)" class="group-price-box">
<view class="group-price1">团购价</view>
<view class="group-price2">
{{ '¥' + item.commodity_goods_info.group_buy_price }}
/{{ item.commodity_goods_info.goods_unit }}
</view>
</view>
<view v-else>
{{ '¥' + item.price }}
/{{ item.commodity_goods_info.goods_unit }}
</view>
</view>
<!-- 运费 -->
<!-- <view class="goods-desc" style="margin-top: 10rpx;">运费 ¥{{
item.commodity_goods_info.freight }}</view> -->
</view>
<view class="quantity-control">
<view class="decrease-btn" @tap.stop="decreaseQuantity(item)">-</view>
<view class="quantity">{{ item.count }}</view>
<view class="increase-btn" @tap.stop="increaseQuantity(item)">+</view>
</view>
</view>
</view>
</view>
</view>
<!-- 运费 -->
<!-- <view class="fee-section">
<view class="fee-name">运费</view>
<view class="fee-value">¥{{ item.commodity_goods_info.freight }}</view>
</view> -->
<!-- 总金额 -->
<view class="total-section">
<view class="total-name">总金额</view>
<view class="total-value">¥{{ calculateTotal('order2') }}</view>
</view>
<!-- 支付方式 -->
<view class="payment-section">
<view class="payment-item" @click="selectPayment('wechat')">
<view class="payment-icon">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_wechat.png"
mode="aspectFit"></image>
</view>
<view class="payment-content">
<view class="payment-name">微信支付</view>
<view class="payment-desc"><text
style="color: #f03d0e;margin-right: 15rpx;">可用优惠券</text>单笔支付限额:¥10000.00</view>
</view>
<view class="payment-select" v-if="selectedPayment === 'wechat'">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png"
mode="aspectFit" style="width: 40rpx; height: 40rpx;"></image>
</view>
<view class="payment-select" v-else>
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png"
mode="aspectFit" style="width: 40rpx; height: 40rpx;"></image>
</view>
</view>
</view>
</view>
<view v-if="activeTab === 'pickup' && orderList2.length == 0" class="empty-tip">
暂无商品数据
</view>
<!-- 立即支付按钮 -->
<view class="pay-button" @click="submitPayment">立即支付</view>
<!-- 弹窗 - 支付成功 -->
<view class="shadow" @click="changeShadow" v-if="boxshadow1">
<view class="shadowBox2">
<view class="shadowBox_img">
<view class="boxshadow_tit">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/af_√.png"
class="boxshadow_tit_img">
</image>
已支付成功
</view>
<view class="boxshadow_img">
<view v-if="verifyCode">核销码:{{ verifyCode }}</view>
<!-- <image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png">
</image> -->
</view>
<view>
<view class="wealBoxTit">
<view class="wealBoxTit1">下单福利</view>
<view class="wealBoxTit2">已获得</view>
</view>
<view class="wealBox">
<view class="wealBoxItem wealBoxItem1">
<view class="wealBoxItemTop">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/activity_fen.png"
mode="aspectFit">
</image>
<view>石榴分</view>
</view>
<view>
{{ slFen }}
</view>
<view class="wealBoxItemBottom">
可抵扣 ¥{{ slFen }}
</view>
</view>
<view class="wealBoxItem wealBoxItem2">
<view class="wealBoxItemTop">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/activity_zi.png"
mode="aspectFit">
</image>
<view>石榴籽</view>
</view>
<view>
{{ slZi }}
</view>
<view class="wealBoxItemBottom">
可抵扣 ¥{{ slZi }}
</view>
</view>
<view class="wealBoxItem wealBoxItem3">
<view class="wealBoxItemTop">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/activity_jin.png"
mode="aspectFit" />
<view>石榴金</view>
</view>
<view>
{{ slJin }}
</view>
<view class="wealBoxItemBottom">
可抵扣 ¥{{ slJin }}
</view>
</view>
</view>
</view>
<view class="bottom">
<view class="boxbottom1">
<view class="boxbottom">
<view class="line1"></view>
赶快邀请好友来下单吧
<view class="line2"></view>
</view>
<view @click.stop="changeShadow">
<view class="shadowBox1">
<button class="shadowBox1Item_btn" open-type="share" bindtap="onShareButtonClick" />
<view class="shadowBox1Item">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png"
mode="aspectFill"></image>
微信好友
</view>
<button class="shadowBox2Item_btn" open-type="share" bindtap="onShareButtonClick" />
<view class="shadowBox1Item" @click="shareFriend">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png"
mode="aspectFill"></image>
小程序链接
</view>
<!-- <view class="shadowBox1Item" @click="openSave">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_saveImg.png"
mode="aspectFill"></image>
二维码海报
</view> -->
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 海报 -->
<view class="shadow" @click="changeShadow2" v-if="boxshadow2">
<view class="shadowBox2">
<view class="shadowBox_img">
<view class="boxshadow_tit">今日商品推荐</view>
<view class="boxshadow_img">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png">
</image>
</view>
<view class="shadowBoxInfo">
<view class="shadowboxInfo_left">二维码</view>
<view class="shadowboxInfo_right">
<view class="shadowboxInfo_right_1">正鲜生</view>
<view class="shadowboxInfo_right_2">
长按识别小程序 <br />
数量有限马上抢购
</view>
</view>
</view>
</view>
<view class="shadowBox_btn" @click.stop="saveImg">保存海报</view>
</view>
</view>
</view>
</template>
<script>
import { picUrl, menuButtonInfo, request, NavgateTo } from "../../../utils";
import { apiArr } from "../../../api/shop";
export default {
data() {
return {
activeTab: 'pickup', // 默认选中自提
quantity: 1, // 商品数量
selectedPayment: 'wechat',
boxshadow1: false,
boxshadow2: false,
defAddress: {},
defZTAddress: [],
orderList1: [],
orderList2: [],
carList: [],
slJin: 0,
slFen: 0,
slZi: 0,
// 团购活动id
group_buy_activity_id: 0,
// 核销码
verifyCode: '',
totalPrice: 0,
};
},
computed: {
// 按供应商id分组商品
supplierGroups() {
const groups = {};
this.orderList2.forEach(item => {
const supplierId = item.supplier_id || 'default';
if (!groups[supplierId]) {
groups[supplierId] = [];
}
groups[supplierId].push(item);
});
return groups;
},
},
onLoad(options) {
this.carList = JSON.parse(options.shopCarList)
},
onShow() {
this.getUserAddress()
this.getZTAddress()
this.getGoodsList()
},
onUnload() {
uni.removeStorageSync('changeZTAddress')
},
methods: {
switchTab(tab) {
this.activeTab = tab;
},
//用户收货地址
getUserAddress() {
request(apiArr.getUserDefAddress, "POST", {}).then(res => {
this.defAddress = res.default_address
})
},
// 商品列表
getGoodsList() {
this.orderList1 = []
this.orderList2 = []
this.carList.forEach(item => {
// 如果图片URL不是以https开头,则拼接picUrl
if (item.commodity_goods_info.commodity_pic && item.commodity_goods_info.commodity_pic.indexOf('https') !== 0) {
item.commodity_goods_info.commodity_pic = picUrl + item.commodity_goods_info.commodity_pic
}
// const list = item.commodity_goods_info.group_buy_activity_info
const list = true
if (list) {
this.orderList2.push(item)
} else {
this.orderList1.push(item)
}
})
},
getZTAddress() {
setTimeout(() => {
let changeAddress = uni.getStorageSync('changeZTAddress')
if (changeAddress) {
this.defZTAddress = changeAddress
}
}, 100)
},
chooseAddress() {
NavgateTo('../address/index')
},
editAddress(item) {
NavgateTo('/packages/shop/ztLocation/index?item=' + JSON.stringify(item));
},
decreaseQuantity(item) {
const currentTime = new Date().getTime();
const startTime = new Date(item.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(item.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (item.count > 0) {
if (currentTime >= startTime && currentTime <= endTime) {
if (item.count == item.commodity_goods_info.min_order_quantity) {
uni.showToast({
title: '最少购买' + item.commodity_goods_info.min_order_quantity + '件',
icon: 'none'
});
item.count = 0
} else {
item.count -= item.is_one_one === 1 ? 2 : 1;
}
} else {
item.count -= item.is_one_one === 1 ? 2 : 1;
}
// 当数量减到0时,从carList中删除该商品
if (item.count === 0) {
const index = this.carList.findIndex(carItem => carItem.goods_id === item.goods_id);
if (index > -1) {
this.carList.splice(index, 1);
// 重新加载商品列表以更新页面显示
this.getGoodsList();
}
}
this.changeCart(item)
}
},
increaseQuantity(item) {
const currentTime = new Date().getTime();
const startTime = new Date(item.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(item.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (item.count >= item.commodity_goods_info.stock_quantity) {
uni.showToast({
title: '库存不足',
icon: 'none'
});
return
}
if (currentTime >= startTime && currentTime <= endTime) {
if (item.count == 0) {
item.count += item.is_one_one === 1 ? 2 : 1;
} else {
if (item.count >= item.purchase_limit) {
uni.showToast({
title: '您选择的数量已达到最大限购量',
icon: 'none'
});
return
}
if (item.count == item.commodity_goods_info.max_limit_quantity) {
uni.showToast({
title: '一次最多购买' + item.commodity_goods_info.max_limit_quantity + '件',
icon: 'none'
});
return
}
}
}
item.count += item.is_one_one === 1 ? 2 : 1;
this.changeCart(item);
},
// 更改购物车
changeCart(item) {
const params = {
goods_id_and_count: [
{
goods_id: item.goods_id,
count: item.count,
price: item.price,
},
],
adver_id: item.adver_id,
}
request(apiArr.updateCar, "POST", params).then(res => {
uni.showToast({
title: "操作成功!",
success() { },
});
})
},
// 计算总金额
calculateTotal(order) {
if (order === 'order1') {
let total = 0;
this.orderList1.forEach(goods => {
// 直接使用item.price进行计算
total += goods.price * (goods.is_one_one === 1 ? goods.count / 2 : goods.count);
});
// 加运费
return total.toFixed(2);
} else {
let total = 0;
this.orderList2.forEach(goods => {
// 直接使用item.price进行计算
total += goods.price * (goods.is_one_one === 1 ? goods.count / 2 : goods.count);
this.totalPrice = total.toFixed(2);
});
// 加运费
return total.toFixed(2);
}
},
selectPayment(payment) {
this.selectedPayment = payment;
},
submitPayment() {
// 检查所有供应商是否都选择了自提点
const supplierIds = [...new Set(this.orderList2.map(item =>
item.supplier_id || 'default'
))];
const allHaveZTAddress = supplierIds.every(supplierId => {
const ztAddress = this.defZTAddress.find(adItem => adItem.id == supplierId);
return !!ztAddress;
});
if (!allHaveZTAddress) {
uni.showToast({
title: '请选择所有货品的自提点',
icon: 'none'
});
return;
}
// 团购活动时间判断
const currentTime = new Date().getTime();
let isGroupBuyValid = true;
// 检查所有商品是否在团购活动时间内
for (let supplierId in this.supplierGroups) {
const group = this.supplierGroups[supplierId];
for (let item of group) {
const activityInfo = item.commodity_goods_info.group_buy_activity_info;
// 如果没有团购活动信息,或者不在活动时间内,则isGroupBuyValid设为false
if (!activityInfo) {
isGroupBuyValid = false;
break;
}
const startTime = new Date(activityInfo.start_time).getTime();
const endTime = new Date(activityInfo.end_time).getTime();
if (!(currentTime >= startTime && currentTime <= endTime)) {
isGroupBuyValid = false;
break;
}
}
if (!isGroupBuyValid) break;
}
// 检查是否存在isafterSale属性且值为true
const hasAfterSaleItem = this.carList.some(item => item.isafterSale === true);
const orderIdFromAfterSale = hasAfterSaleItem ? this.carList.find(item => item.isafterSale === true)?.orderId : null;
// 根据平台设置不同的trans_type值
// 小程序: 71, App: 51
const systemInfo = uni.getSystemInfoSync();
let trans_type = 51; // 默认App环境
// 运行时判断是否为小程序环境
if (systemInfo.platform === 'devtools' || systemInfo.platform === 'unknown') {
trans_type = 71; // 开发工具或未知环境默认为小程序
}
// 条件编译:针对不同平台设置不同值
// #ifdef MP
trans_type = 71; // 所有小程序平台
// #endif
// #ifdef APP-PLUS
trans_type = 51; // App平台
// #endif
// 如果存在isafterSale属性且为true,则跳过createOrder接口调用
if (hasAfterSaleItem && orderIdFromAfterSale) {
const param = {
order_id: orderIdFromAfterSale,
user_id: uni.getStorageSync('userId'),
trans_type: trans_type
}
request(apiArr.mergePreorder, "POST", param).then(res => {
this.handleMergePreorderResponse(res, orderIdFromAfterSale);
})
} else {
// 原始逻辑:创建订单后再进行支付
const params = {
user_id: uni.getStorageSync('userId'),
// 先判断shopCarList数据中是否包含isAdver且为true
order_cate: this.carList.some(item => item.isAdver === true) ? 3 : (isGroupBuyValid ? 2 : 1),
goods_list: Object.keys(this.supplierGroups).map(supplierId => {
const group = this.supplierGroups[supplierId];
const firstItem = group[0];
// 团购活动id
this.group_buy_activity_id = firstItem.commodity_goods_info.group_buy_activity_id;
// 根据供应商id获取自提点信息
const ztAddress = this.defZTAddress.find(adItem => adItem.id == supplierId) || {};
return {
supplier_id: firstItem.supplier_id,
supplier_name: firstItem.supplier_name || '',
is_same_day: firstItem.commodity_goods_info.is_same_day,
receiving_name: ztAddress.name || '',
receiving_phone: ztAddress.phone || '',
receiving_address: ztAddress.address || '',
merchant_id: ztAddress.address_id,
group_buy_activity_id: firstItem.commodity_goods_info.group_buy_activity_id,
goods_and_count: group.map(item => {
return {
goods_id: item.goods_id,
count: item.is_one_one === 1 ? item.count / 2 : item.count,
price: item.price,
freight: item.commodity_goods_info.freight,
}
})
}
})
}
request(apiArr.createOrder, "POST", params).then(resVal => {
const param = {
order_id: resVal.order_id,
user_id: uni.getStorageSync('userId'),
trans_type: trans_type
}
request(apiArr.mergePreorder, "POST", param).then(res => {
this.handleMergePreorderResponse(res, resVal.order_id);
})
})
}
},
// 处理mergePreorder接口的响应
handleMergePreorderResponse(res, orderId) {
if (res && res.timeStamp && res.nonceStr && res.package && res.signType && res.paySign) {
// 调用微信支付
uni.requestPayment({
timeStamp: res.timeStamp,
nonceStr: res.nonceStr,
package: res.package,
signType: res.signType,
paySign: res.paySign,
success: (payRes) => {
const params = {
order_id: orderId,
from: this.carList.some(item => item.isAdver === true) ? 3 : (isGroupBuyValid ? 2 : 1),
group_buy_activity_id: this.group_buy_activity_id,
adver_id: this.carList.some(item => item.isAdver === true) ? this.carList.find(item => item.isAdver === true).adver_id : ''
}
request(apiArr.queryOrder, "POST", params).then(res => {
this.verifyCode = res.verification_code
this.slJin = res.shiliu_money
this.boxshadow1 = true
})
},
fail: (payErr) => {
uni.showToast({
title: payErr.errMsg == 'requestPayment:fail cancel' ? '已取消支付' : '支付失败',
icon: 'none'
})
const params = {
order_ids: orderId,
}
request(apiArr.cancelPay, "POST", params).then(res => {
})
},
complete: () => {
// 支付完成后的回调,无论成功失败都会执行
}
})
} else {
console.error("获取支付参数失败,缺少必要参数")
uni.showToast({
title: '获取支付信息失败',
icon: 'none'
})
}
},
// 复制收货地址
copyAddress() {
// 使用uni-app的复制API
uni.setClipboardData({
data: this.defAddress.address + this.defAddress.house_number,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
},
copyZTAddress() {
// 使用uni-app的复制API
uni.setClipboardData({
data: this.defZTAddress.address,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
},
openSave() {
this.boxshadow1 = false;
this.boxshadow2 = true;
},
changeShadow() {
this.boxshadow1 = false;
},
changeShadow2() {
this.boxshadow2 = false;
},
// 保存海报
saveImg() {
this.boxshadow2 = false;
// 微信小程序保存图片
uni.downloadFile({
url: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png",
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: (res) => {
uni.showToast({
title: "保存成功",
icon: "success",
duration: 2000,
});
},
fail: (err) => {
console.log("保存失败", err);
},
});
}
},
fail: (err) => {
console.log("下载失败", err);
},
});
},
// 判断当前日期是否在团购活动时间范围内
isWithinActivityTime(item) {
if (!item || !item.commodity_goods_info || !item.commodity_goods_info.group_buy_activity_info) {
return false;
}
const now = new Date();
const startTime = new Date(item.commodity_goods_info.group_buy_activity_info?.start_time);
const endTime = new Date(item.commodity_goods_info.group_buy_activity_info?.end_time);
return now >= startTime && now <= endTime;
},
}
};
</script>
<style>
@import url('./index.css');
</style>

View File

@ -0,0 +1,294 @@
.group-purchase-container {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
max-width: 750rpx;
margin: 0 auto;
background-color: #ffffff;
}
/* 顶部横幅 */
.banner-content {
z-index: 1;
}
.banner-title {
font-size: 36rpx;
font-weight: bold;
margin-bottom: 10rpx;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
}
.banner-subtitle {
font-size: 18rpx;
background-color: rgba(255, 255, 255, 0.2);
padding: 5rpx 10rpx;
border-radius: 4rpx;
display: inline-block;
}
/* 商品列表 */
.goods-list {
background-color: #ffffff;
padding: 30rpx 20rpx;
height: 80vh;
overflow-y: auto;
}
.goods-item {
border-radius: 10rpx;
padding: 15rpx;
margin-bottom: 25rpx;
display: flex;
}
.goods-item2 {
border-radius: 10rpx;
padding: 15rpx;
margin-bottom: 25rpx;
display: flex;
}
.goods-image {
width: 140rpx;
height: 140rpx;
border-radius: 15rpx;
overflow: hidden;
margin-right: 15rpx;
}
.goods-image image {
width: 100%;
height: 100%;
object-fit: cover;
}
.goods-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
}
.goods-name {
font-size: 28rpx;
font-weight: bold;
margin-bottom: 8rpx;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.goods-desc {
font-size: 22rpx;
color: #666;
margin-bottom: 10rpx;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.goods-price {
font-size: 28rpx;
color: #e63946;
margin-bottom: 10rpx;
}
.price-container {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10rpx;
}
.group-price {
font-size: 28rpx;
color: #e63946;
margin-right: 10rpx;
border-radius: 4rpx;
display: flex;
}
.group-price1{
width: 100rpx;
padding: 10rpx 15rpx;
color: #ffffff;
background-color: #fc5d15;
border-radius: 15rpx 0 0 15rpx;
display: flex;
align-items: center;
justify-content: center;
}
.group-price2{
width: auto;
padding: 10rpx 15rpx;
background: linear-gradient(to bottom, #fef6d6, #fee8a9);
border-radius: 0 15rpx 15rpx 0;
}
.original-price {
font-size: 26rpx;
color: #999;
}
.countdown {
width: auto;
font-size: 22rpx;
padding: 10rpx 20rpx;
color: #ffffff;
margin-bottom: 15rpx;
border-radius: 50rpx;
background-color: #fe2f01;
position: absolute;
/* top: 120rpx; */
bottom: -30rpx;
right: 0;
}
.quantity-control {
display: flex;
align-items: center;
justify-content: flex-end;
}
.decrease-btn {
width: 40rpx;
height: 40rpx;
background-color: #f5f5f5;
border: 1rpx solid #ccc;
border-radius: 50%;
line-height: 33rpx;
text-align: center;
font-size: 28rpx;
color: #333;
}
.increase-btn {
width: 40rpx;
height: 40rpx;
background-color: #ff502a;
border-radius: 50%;
line-height: 33rpx;
text-align: center;
font-size: 28rpx;
color: #ffffff;
}
.quantity {
margin: 0 15rpx;
font-size: 24rpx;
width: 40rpx;
text-align: center;
}
/* 购物车按钮 */
.shop_car {
width: 140rpx;
height: 140rpx;
position: fixed;
right: 33rpx;
bottom: 80rpx;
z-index: 10;
}
.shop_car image {
width: 100%;
height: 100%;
}
.u-badge {
position: absolute;
right: 0;
top: -10rpx;
}
/* 规格标签样式 */
.specification-tag {
width: 130rpx;
display: flex;
align-items: center;
justify-content: center;
background-color: #feeceb;
padding: 10rpx 20rpx;
border-radius: 40rpx;
margin: 15rpx 0;
font-size: 26rpx;
color: #dd4020;
}
.specification-tag text {
margin-right: 5rpx;
}
/* 货品列表样式 */
.sku-list {
margin-top: 10rpx;
padding: 15rpx;
background-color: #f9f9f9;
border-radius: 10rpx;
}
.sku-item{
position: relative;
margin-bottom: 30rpx;
}
.sku-info{
display: flex;
align-items: center;
justify-content: center;
}
.sku-image{
width: 100rpx;
height: 100rpx;
border-radius: 15rpx;
overflow: hidden;
margin-right: 15rpx;
}
.sku-price {
font-size: 26rpx;
color: #e63946;
margin-right: 10rpx;
border-radius: 4rpx;
display: flex;
margin-top: 15rpx;
}
.sku-price1{
width: auto;
padding: 10rpx 15rpx;
color: #ffffff;
background-color: #fc5d15;
border-radius: 15rpx 0 0 15rpx;
}
.sku-price2{
width: auto;
padding: 10rpx 15rpx;
background: linear-gradient(to bottom, #fef6d6, #fee8a9);
border-radius: 0 15rpx 15rpx 0;
}
.sku-control {
display: flex;
align-items: center;
justify-content: flex-end;
margin-top: 15rpx;
}
.sku-countdown {
width: auto;
font-size: 22rpx;
padding: 5rpx 20rpx;
color: #ffffff;
margin-bottom: 15rpx;
border-radius: 50rpx;
background-color: #fe2f01;
position: absolute;
top: 170rpx;
right: 0;
}

View File

@ -0,0 +1,271 @@
<template>
<view class="group-purchase-container">
<!-- 商品列表 -->
<view class="goods-list">
<!-- 商品项 -->
<view v-for="(item, index) in goodsList" :key="index">
<view>
<view class="goods-item2" @click="toDetail(item)">
<view class="goods-image">
<image :src="item.commodity_pic" mode="aspectFill"></image>
</view>
<view class="goods-info">
<view class="goods-name">{{ item.goods_name }}</view>
<view class="goods-desc">{{ item.goods_spec }}</view>
<view class="price-container">
<view class="group-price">
<view class="group-price1">活动价</view>
<view class="group-price2">¥{{ item.promotional_price }}/{{ item.goods_unit }}
</view>
</view>
<view class="quantity-control">
<view class="decrease-btn" @tap.stop="decreaseQuantity(index)">-</view>
<view class="quantity">{{ item.quantity }}</view>
<view class="increase-btn" @tap.stop="increaseQuantity(index)">+</view>
</view>
</view>
<view class="original-price">零售价 ¥{{ item.retail_price }}/{{ item.goods_unit }}</view>
</view>
</view>
</view>
</view>
</view>
<!-- 购物车按钮 -->
<view class="shop_car" @click="shopCar">
<u-badge numberType="limit" type="error" max="99" :value="carNum"></u-badge>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_car_num.png"></image>
</view>
</view>
</template>
<script>
import { picUrl, menuButtonInfo, request, NavgateTo } from "../../../utils";
import { apiArr } from '@/api/groupPurchase.js'
import { apiArr as shopApi } from "../../../api/shop.js";
export default {
data() {
return {
goodsList: [],
carNum: 0,
quantity: 0,
timer: null, // 定时器ID
endTime: '', // 初始化结束时间
updateTime: Date.now(), // 用于触发倒计时更新的时间戳
goodsDetail: [],
idVal: '',
};
},
onLoad(options) {
this.idVal = Number(options.id)
// this.getGoodsList()
},
onShow() {
// 在页面显示时启动定时器
if (!this.timer) {
this.timer = setInterval(() => {
// 更新时间戳,触发页面重新渲染
this.updateTime = Date.now();
}, 1000);
}
// 确保getGoodsList和getShopdetail都执行完毕后再执行getGoodsNum
Promise.all([
// 确保getGoodsList已完成
this.goodsList.length > 0 ? Promise.resolve() : this.getGoodsList(),
// 调用getShopdetail并等待其完成
this.getShopdetail()
]).then(() => {
this.getGoodsNum();//获取货品在购物车中的数量
});
},
methods: {
getGoodsList() {
if (!uni.getStorageSync('userId')) {
uni.showToast({
title: '请先登录',
icon: 'none'
})
return
}
const params = {
adver_id: this.idVal,
}
return request(shopApi.adverGoodsList, 'POST', params).then(res => {
const list = res.adver_goods_list.map(item => {
// 为每个商品初始化quantity
return {
...item,
commodity_pic: picUrl + item.goods_pic,
quantity: 0
}
})
this.goodsList = list
return res;
})
},
getShopdetail() {
const params = {
is_adver: 1,
}
return request(shopApi.getCar, "POST", params).then((res) => {
this.carNum = res.total;
// 合并当日达和普通商品数据
this.goodsDetail = [].concat(res.same_day_cart_list, res.normal_cart_list)
.flatMap(supplier => supplier.commodity_cart_and_goods_model);
return res;
});
},
getGoodsNum() {
if (!this.goodsDetail || !this.goodsList || this.goodsList.length === 0) {
return;
}
// 遍历所有商品,直接对item进行处理
this.goodsList.forEach(goods => {
// 在购物车数据中查找对应的商品
const matchedItem = this.goodsDetail.find(item => item.goods_id === goods.goods_id);
// 如果找到匹配项,更新quantity
if (matchedItem) {
goods.quantity = matchedItem.count;
} else {
// 如果没有找到,设置为0
goods.quantity = 0;
}
});
},
toDetail(itemObj) {
const item = {
...itemObj,
groupById: itemObj.group_buy_activity_info ? itemObj.group_buy_activity_info.id : ''
};
NavgateTo(`/packages/advertising/goodsDetail/index?item=${JSON.stringify(item)}`)
},
// 增加商品数量
increaseQuantity(index) {
const item = this.goodsList[index]
if (item.quantity == 0) {
if (item.one_one === 1) {
item.quantity += 2
this.carNum += 2
} else {
item.quantity += 1
this.carNum += 1
}
} else {
if (item.quantity == (item.one_one === 1 ? item.purchase_limit * 2 : item.purchase_limit)) {
uni.showToast({
title: '您选择的数量已达到最大限购量',
icon: 'none'
});
return
}
item.quantity = item.one_one === 1 ? item.quantity + 2 : item.quantity + 1;
this.carNum = item.one_one === 1 ? this.carNum + 2 : this.carNum + 1;
}
const params = {
goods_id_and_count: [
{
goods_id: item.goods_id,
count: item.quantity,
price: item.promotional_price,
is_one_one: item.one_one,
purchase_limit: item.purchase_limit,
},
],
adver_id: item.adver_id
}
this.updateCar(params);
},
// 减少商品数量
decreaseQuantity(index) {
const item = this.goodsList[index]
if (item.quantity > 0) {
if (item.one_one === 1) {
item.quantity = item.quantity - 2
this.carNum = this.carNum - 2
} else {
item.quantity--;
this.carNum--;
}
const params = {
goods_id_and_count: [
{
goods_id: item.goods_id,
count: item.quantity,
price: item.promotional_price,
is_one_one: item.one_one,
purchase_limit: item.purchase_limit,
},
],
adver_id: item.adver_id
}
this.updateCar(params);
} else {
uni.showToast({
title: '已经没有了...',
icon: 'none'
});
}
},
// 请求更改购物车接口
async updateCar(params) {
return request(shopApi.updateCar, "POST", params).then((res) => {
this.getShopdetail();
uni.showToast({
title: "操作成功!",
success() { },
});
});
},
// 跳转到购物车
shopCar() {
const item = {
is_adver: 1,
}
NavgateTo("/packages/advertising/shopCar/index?item=" + JSON.stringify(item));
},
// 计算距离结束日期的剩余时间
getEndTheCountdown(endTime) {
// 获取当前时间和结束时间的时间戳
const now = new Date().getTime();
const end = new Date(endTime).getTime();
// 计算时间差(毫秒)
let diff = end - now;
// 如果已经结束,返回提示
if (diff <= 0) {
return '团购已结束';
}
// 计算天、小时、分钟
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
diff -= days * (1000 * 60 * 60 * 24);
const hours = Math.floor(diff / (1000 * 60 * 60));
diff -= hours * (1000 * 60 * 60);
const minutes = Math.floor(diff / (1000 * 60));
diff -= minutes * (1000 * 60);
// 返回格式化的字符串
return `${days}天${hours}小时${minutes}分钟后结束`;
}
},
onHide() {
// 清除定时器
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
}
};
</script>
<style>
@import url("./index.css");
</style>

View File

@ -0,0 +1,258 @@
.main {
height: 77vh;
overflow-y: auto;
}
.searchBox {
display: flex;
align-items: center;
z-index: 2;
padding-bottom: 30rpx;
}
.searchBox_mid {
font-size: 40rpx;
color: #222222;
flex: 1;
text-align: center;
}
.searchBox_left {
box-sizing: border-box;
padding-left: 20rpx;
flex: 1;
}
.searchBox_right {
opacity: 0;
flex: 1;
}
.isDay {
position: absolute;
}
.tag {
background-color: #ff7d00;
color: white;
font-size: 22rpx;
padding: 5rpx 10rpx;
border-radius: 20rpx 0 20rpx 20rpx;
}
.tag-img {
position: absolute;
/* top: 1; */
bottom: 1;
left: 10;
z-index: 1;
}
.is_day {
margin-left: 20rpx;
}
.empty {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-top: 160rpx;
}
.empty image {
width: 500rpx;
height: 500rpx;
}
.empty div {
font-size: 26rpx;
color: #999999;
margin-top: -40rpx;
text-align: center;
}
.deleteIcon {
margin: 0 40rpx;
box-sizing: border-box;
margin-top: 36rpx;
display: flex;
justify-content: flex-end;
}
.goodsItem_supplier {
display: flex;
align-items: center;
margin: 20rpx;
}
.goodsItem_tit {
font-size: 35rpx;
font-weight: bold;
}
.goodsItem {
display: flex;
align-items: center;
margin: 0 20rpx;
padding: 30rpx 0;
box-sizing: border-box;
border-bottom: 1rpx solid #EBEBEB;
}
.goodsItem_left {
width: 32rpx;
height: 32rpx;
margin-right: 32rpx;
}
.goodsItem_right {
flex: 1;
}
.goodsItem_msg {
display: flex;
align-items: center;
}
.goodsItem_msg_right {
flex: 1;
}
.goodsItem_msg_img {
width: 140rpx;
height: 140rpx;
border-radius: 20rpx 20rpx 20rpx 20rpx;
margin-right: 20rpx;
}
.goodsItem_msg_right {
flex: 1;
}
.goodsItem_msg_right_msg_left {
display: flex;
align-items: center;
font-size: 34rpx;
color: #FF370B;
margin-top: 26rpx;
}
.goodsItem_msg_right_tit {
font-size: 30rpx;
color: #000000;
font-weight: 700;
}
.goodsItem_msg_right_subTit {
font-size: 26rpx;
color: #999999;
margin-top: 10rpx;
}
.goodsItem_msg_right_msg {
display: flex;
align-items: center;
justify-content: space-between;
}
.goodsItem_msg_right_msg_left span {
font-size: 28rpx;
}
.goodsItem_msg_right_msg_right {
display: flex;
align-items: center;
}
.minus {
width: 22px;
height: 22px;
border-width: 1px;
border-color: #E6E6E6;
border-style: solid;
border-top-left-radius: 100px;
border-top-right-radius: 100px;
border-bottom-left-radius: 100px;
border-bottom-right-radius: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.input {
padding: 0 10px;
}
.plus {
width: 22px;
height: 22px;
background-color: #FF0000;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.footer {
width: 750rpx;
background: #FFFFFF;
box-shadow: 3rpx -3rpx 15rpx 0rpx rgba(255, 27, 27, 0.05);
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding: 40rpx 20rpx;
position: fixed;
left: 0;
right: 0;
bottom: 0;
justify-content: space-between;
}
.footer_left {
display: flex;
align-items: center;
}
.footer_all {
font-size: 28rpx;
color: #000000;
display: flex;
align-items: center;
}
.footer_all image {
width: 28rpx;
height: 28rpx;
margin-right: 16rpx;
}
.footer_total {
font-weight: bold;
font-size: 40rpx;
color: #FF370B;
margin-left: 90rpx;
}
.footer_total span {
font-size: 32rpx;
color: #222222;
font-weight: 400;
}
.footer_right {
font-size: 36rpx;
color: #FFFFFF;
font-weight: 700;
width: 230rpx;
height: 70rpx;
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
border-radius: 100rpx 100rpx 100rpx 100rpx;
display: flex;
align-items: center;
justify-content: center;
}

View File

@ -0,0 +1,777 @@
<template>
<view>
<view class="header">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_left" @click="back">
<u-icon name="arrow-left" size="20px" color="#000"></u-icon>
</view>
<view class="searchBox_mid">购物车({{ shopCarTotal }})</view>
<view class="searchBox_right">
<u-icon name="arrow-left" size="20px" color="#000"></u-icon>
</view>
</view>
</view>
<view class="empty" v-if="shopCarTotal == 0">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/shopCar_no.png"></image>
</view>
<view class="main" v-else>
<view class="deleteIcon" @click="deleteItem">
<u-icon name="trash" size="50rpx"></u-icon>
</view>
<view class="is_day " v-if="isDayshow">
<view class="footer_all" @click="is_day_checked"
style="color: orange; font-size: 35rpx; font-weight: bolder;">
<image v-if="!isDaychecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
</image>
<image v-if="isDaychecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
当日达
</view>
<view class="goodsList">
<view v-for="(carItem, carIndex) in isDayCarList" :key="carItem.id" :index="carIndex">
<view class="goodsItem_supplier">
<view class="goodsItem_left" @click="supplierCheck(carItem, true)">
<image v-if="!carItem.supplierChecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
</image>
<image v-if="carItem.supplierChecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
</view>
<view class="goodsItem_tit">
{{ carItem.supplier_name }}
</view>
</view>
<view class="goodsItem" v-for="(item, index) in carItem.commodity_cart_and_goods_model"
:key="item.id">
<view class="goodsItem_left" @click="DayChecked(item)">
<image v-if="!item.checked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
</image>
<image v-if="item.checked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
</view>
<view class="goodsItem_right">
<view class="goodsItem_msg">
<view class="goodsItem_msg_img">
<view class="tag tag-img">当日达</view>
<image :src="picUrl + item.commodity_goods_info.commodity_pic">
</image>
</view>
<view class="goodsItem_msg_right">
<view class="goodsItem_msg_right_tit">
{{ item.commodity_goods_info.goods_name }}
</view>
<view class="goodsItem_msg_right_subTit">
{{ item.commodity_goods_info.goods_intro }}
</view>
<view class="goodsItem_msg_right_msg">
<view class="goodsItem_msg_right_msg_left">
<span>¥</span>{{ item.price }}
<!-- {{ item.commodity_goods_info.group_buy_price ?
item.commodity_goods_info.group_buy_price :
item.commodity_goods_info.sales_price }} -->
<span>/{{ item.commodity_goods_info.goods_unit }}</span>
</view>
<view class="goodsItem_msg_right_msg_right">
<u-number-box v-model="item.count" :asyncChange="true" min="0">
<template #minus>
<view class="minus"
@click="minus(carItem, index, carItem.commodity_cart_and_goods_model)">
<u-icon name="minus" size="32" bold></u-icon>
</view>
</template>
<template #input><text style="width: 80rpx; text-align: center"
class="input">{{ item.count }}</text>
</template>
<template #plus>
<view class="plus" @click="add(carItem, index)">
<u-icon name="plus" color="#FFFFFF" size="32" bold></u-icon>
</view>
</template>
</u-number-box>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="is_day" v-if="parcelPostshow" style="margin-top: 20rpx;">
<view class="footer_all" @click="parcel_post_checked"
style="color: orange; font-size: 35rpx; font-weight: bolder;">
<image v-if="!isParcelPostchecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
</image>
<image v-if="isParcelPostchecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
包邮
</view>
<view class="goodsList">
<view v-for="(carItem, carIndex) in shopCarList" :key="carItem.id" :index="carIndex">
<view class="goodsItem_supplier">
<view class="goodsItem_left" @click="supplierCheck(carItem, false)">
<image v-if="!carItem.supplierChecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
</image>
<image v-if="carItem.supplierChecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
</view>
<view class="goodsItem_tit">
{{ carItem.supplier_name }}
</view>
</view>
<view class="goodsItem" v-for="(item, index) in carItem.commodity_cart_and_goods_model"
:key="item.id">
<view class="goodsItem_left" @click="changeChecked(item)">
<image v-if="!item.checked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
</image>
<image v-if="item.checked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
</view>
<view class="goodsItem_right">
<view class="goodsItem_msg">
<view class="goodsItem_msg_img">
<image :src="picUrl + item.commodity_goods_info.commodity_pic">
</image>
</view>
<view class="goodsItem_msg_right">
<view class="goodsItem_msg_right_tit">
{{ item.commodity_goods_info.goods_name }}
</view>
<view class="goodsItem_msg_right_subTit">
{{ item.commodity_goods_info.goods_intro }}
</view>
<view class="goodsItem_msg_right_msg">
<view class="goodsItem_msg_right_msg_left">
<span>¥</span>{{ item.price }}
<!-- {{ item.commodity_goods_info.group_buy_price ?
item.commodity_goods_info.group_buy_price :
item.commodity_goods_info.sales_price }} -->
<span>/{{ item.commodity_goods_info.goods_unit }}</span>
</view>
<view class="goodsItem_msg_right_msg_right">
<u-number-box v-model="item.count" :asyncChange="true" min="0">
<template #minus>
<view class="minus"
@click="minus(item, index, carItem.commodity_cart_and_goods_model)">
<u-icon name="minus" size="32" bold></u-icon>
</view>
</template>
<template #input>
<text style="width: 80rpx; text-align: center"
class="input">{{
item.count }}</text>
</template>
<template #plus>
<view class="plus" @click="add(item, index)">
<u-icon name="plus" color="#FFFFFF" size="32" bold></u-icon>
</view>
</template>
</u-number-box>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="footer">
<view class="footer_left">
<view class="footer_all" @click="allChecked">
<image v-if="!isAllchecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
</image>
<image v-if="isAllchecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
全选
</view>
<view class="footer_total">
<span>合计</span>
¥{{ shopMoney }}
</view>
</view>
<view class="footer_right" @click="submitOrder">结算</view>
</view>
</view>
</view>
</template>
<script>
import {
apiArr
} from "../../../api/shop";
import {
picUrl,
menuButtonInfo,
request,
NavgateTo
} from "../../../utils";
export default {
data() {
return {
picUrl,
top: "",
localHeight: "",
value: 3,
type: "error",
shopCarList: [],
isDayCarList: [],
shopCarTotal: 0,
shopMoney: 0,
isAllchecked: false, // 全选
isDaychecked: false, // 当日达
isDayshow: false,
isParcelPostchecked: false,
parcelPostshow: false,
is_group_buy: '',
is_adver: ''
};
},
// watch: {
// // console.log(this.isDaychecked);
// isDaychecked(e) {
// console.log('当日达状态', e);
// },
// isParcelPostchecked(e) {
// console.log('包邮状态', e);
// }
// isAllchecked(e) {
// console.log('全选状态', e);
// }
// },
methods: {
back() {
NavgateTo("1");
},
// 商家单选框全选/取消全选
supplierCheck(carItem, isDay) {
carItem.supplierChecked = !carItem.supplierChecked;
carItem.commodity_cart_and_goods_model.forEach(goods => {
goods.checked = carItem.supplierChecked;
});
this.calcTotal();
// 更新当日达或包邮全选状态
if (isDay) {
this.isDaychecked = this.isDayCarList.every(item =>
item.commodity_cart_and_goods_model.every(goods => goods.checked)
);
} else {
this.isParcelPostchecked = this.shopCarList.every(item =>
item.commodity_cart_and_goods_model.every(goods => goods.checked)
);
}
// 更新全选状态
this.isAllchecked = this.isDaychecked && this.isParcelPostchecked;
},
// 结算
submitOrder() {
let arr = [];
// 收集包邮购物车中选中的商品
this.shopCarList.forEach((item) => {
item.commodity_cart_and_goods_model.forEach((ite) => {
if (ite.checked) {
ite.supplier_name = item.supplier_name;
arr.push(ite);
}
})
});
// 收集当日达购物车中选中的商品
this.isDayCarList.forEach((item) => {
item.commodity_cart_and_goods_model.forEach((ite) => {
if (ite.checked) {
ite.supplier_name = item.supplier_name;
arr.push(ite);
}
})
});
if (arr.length == 0) {
this.$u.toast("请选择商品");
return;
}
// 给每个商品添加isAdver=true参数
const updatedArr = arr.map(item => ({
...item,
isAdver: item.adver_id ? true : ''
}));
// NavgateTo(`../submitOrder/index?shopCarList=${JSON.stringify(arr)}`);
NavgateTo(`../goodsSubmit/index?shopCarList=${JSON.stringify(updatedArr)}`);
},
// 获取购物车列表
getShopCar() {
const params = {
is_group_buy: this.is_group_buy,
is_adver: this.is_adver
}
request(apiArr.getCar, "POST", params).then((res) => {
if (res.normal_cart_list.length > 0) {
res.normal_cart_list.forEach((item) => {
item.checked = false;
item.supplierChecked = false;
})
this.parcelPostshow = true;
this.shopCarList = res.normal_cart_list
} else {
res.normal_cart_list.forEach((item) => {
item.checked = false;
item.supplierChecked = false;
})
this.parcelPostshow = false;
this.shopCarList = []
}
if (res.same_day_cart_list.length > 0) {
res.same_day_cart_list.forEach((item) => {
item.checked = false;
item.supplierChecked = false;
})
this.isDayshow = true;
this.isDayCarList = res.same_day_cart_list
} else {
res.normal_cart_list.forEach((item) => {
item.checked = false;
item.supplierChecked = false;
})
this.isDayshow = false;
this.isDayCarList = []
}
// res.normal_cart_list.forEach((item) => {
// if (item.is_support_same_day == false) {
// this.isDayshow = false;
// this.parcelPostshow = true;
// this.shopCarList = item.commodity_cart_and_goods_model;
// item.checked = false;
// } else {
// this.isDayshow = true;
// this.parcelPostshow = false;
// this.isDayCarList = item.commodity_cart_and_goods_model;
// item.checked = false;
// }
// });
this.shopCarTotal = res.total;
});
},
// 单个修改
changeChecked(item) {
item.checked = !item.checked;
this.calcTotal();
// 找到对应的商家并更新商家选中状态
this.shopCarList.forEach(carItem => {
if (carItem.commodity_cart_and_goods_model.includes(item)) {
carItem.supplierChecked = carItem.commodity_cart_and_goods_model.every(goods => goods.checked);
}
});
// 检查当日达是否全选
this.isDaychecked = this.isDayCarList.every(carItem =>
carItem.commodity_cart_and_goods_model.every(goods => goods.checked)
);
// 检查包邮是否全选
this.isParcelPostchecked = this.shopCarList.every(carItem =>
carItem.commodity_cart_and_goods_model.every(goods => goods.checked)
);
// 检查全选状态
this.isAllchecked = this.isDaychecked && this.isParcelPostchecked;
},
DayChecked(item) {
item.checked = !item.checked;
this.calcTotal();
// 找到对应的商家并更新商家选中状态
this.isDayCarList.forEach(carItem => {
if (carItem.commodity_cart_and_goods_model.includes(item)) {
carItem.supplierChecked = carItem.commodity_cart_and_goods_model.every(goods => goods.checked);
}
});
// 检查当日达是否全选
this.isDaychecked = this.isDayCarList.every(carItem =>
carItem.commodity_cart_and_goods_model.every(goods => goods.checked)
);
// 检查包邮是否全选
this.isParcelPostchecked = this.shopCarList.every(carItem =>
carItem.commodity_cart_and_goods_model.every(goods => goods.checked)
);
// 检查全选状态
this.isAllchecked = this.isDaychecked && this.isParcelPostchecked;
},
// 全选
allChecked() {
this.isAllchecked = !this.isAllchecked;
this.isDaychecked = this.isAllchecked;
this.isParcelPostchecked = this.isAllchecked;
// 设置当日达购物车商品和商家选中状态
this.isDayCarList.forEach(carItem => {
carItem.supplierChecked = this.isAllchecked;
carItem.commodity_cart_and_goods_model.forEach(goods => {
goods.checked = this.isAllchecked;
});
});
// 设置包邮购物车商品和商家选中状态
this.shopCarList.forEach(carItem => {
carItem.supplierChecked = this.isAllchecked;
carItem.commodity_cart_and_goods_model.forEach(goods => {
goods.checked = this.isAllchecked;
});
});
this.calcTotal();
},
// 全选当日达
is_day_checked() {
this.isDaychecked = !this.isDaychecked;
// 设置当日达购物车商品和商家选中状态
this.isDayCarList.forEach(carItem => {
carItem.supplierChecked = this.isDaychecked;
carItem.commodity_cart_and_goods_model.forEach(goods => {
goods.checked = this.isDaychecked;
});
});
// 更新全选状态
this.isAllchecked = this.isDaychecked && this.isParcelPostchecked;
this.calcTotal();
},
// 全选包邮
parcel_post_checked() {
this.isParcelPostchecked = !this.isParcelPostchecked;
// 设置包邮购物车商品和商家选中状态
this.shopCarList.forEach(carItem => {
carItem.supplierChecked = this.isParcelPostchecked;
carItem.commodity_cart_and_goods_model.forEach(goods => {
goods.checked = this.isParcelPostchecked;
});
});
// 更新全选状态
this.isAllchecked = this.isDaychecked && this.isParcelPostchecked;
this.calcTotal();
},
// 计算金额
calcTotal() {
let total = 0;
const currentTime = new Date().getTime();
// 计算当日达购物车金额
this.isDayCarList.forEach(carItem => {
carItem.commodity_cart_and_goods_model.forEach(goods => {
if (goods.checked) {
// // 团购活动时间判断
// const startTime = new Date(goods.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
// const endTime = new Date(goods.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
// if (currentTime >= startTime && currentTime <= endTime) {
// total += goods.commodity_goods_info.group_buy_price * goods.count;
// } else {
// total += goods.commodity_goods_info.sales_price * goods.count;
// }
total += goods.price * goods.count
}
});
});
// 计算包邮购物车金额
this.shopCarList.forEach(carItem => {
carItem.commodity_cart_and_goods_model.forEach(goods => {
if (goods.checked) {
// // 团购活动时间判断
// const startTime = new Date(goods.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
// const endTime = new Date(goods.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
// if (currentTime >= startTime && currentTime <= endTime) {
// total += goods.commodity_goods_info.group_buy_price * goods.count;
// } else {
// total += goods.commodity_goods_info.sales_price * goods.count;
// }
if(goods.is_one_one === 1) {
total += goods.price * (goods.count / 2)
} else {
total += goods.price * goods.count
}
}
});
});
this.shopMoney = total.toFixed(2);
},
// 减少数量
// 删除商品的通用方法
deleteCarItem(carItem, goodsIndex, item) {
const that = this;
request(apiArr.deleteCar, "POST", {
ids: [carItem.id],
}).then((res) => {
// 从商品列表中移除该商品
item.splice(goodsIndex, 1);
// 如果商家没有商品了,移除该商家
if (item.length === 0) {
// 分别检查并移除当日达和普通购物车中的商家
const dayCarIndex = that.isDayCarList.findIndex(dayItem =>
dayItem.commodity_cart_and_goods_model === item
);
const normalCarIndex = that.shopCarList.findIndex(normalItem =>
normalItem.commodity_cart_and_goods_model === item
);
if (dayCarIndex !== -1) {
that.isDayCarList.splice(dayCarIndex, 1);
// 如果当日达购物车为空,更新显示状态
if (that.isDayCarList.length === 0) {
that.isDayshow = false;
}
}
if (normalCarIndex !== -1) {
that.shopCarList.splice(normalCarIndex, 1);
// 如果普通购物车为空,更新显示状态
if (that.shopCarList.length === 0) {
that.parcelPostshow = false;
}
}
}
that.calcTotal();
}).catch(error => {
console.error('删除商品失败:', error);
uni.showToast({
title: '删除失败,请重试',
icon: 'none'
});
});
},
// 减少商品数量
minus(carItem, goodsIndex, item) {
const that = this;
const currentTime = new Date().getTime();
// 检查商品是否有团购活动且在活动时间内
const isGroupBuyActive = carItem.commodity_goods_info.group_buy_activity_info &&
currentTime >= new Date(carItem.commodity_goods_info.group_buy_activity_info?.start_time).getTime() &&
currentTime <= new Date(carItem.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (carItem.count > 0) {
if (isGroupBuyActive && carItem.count === carItem.commodity_goods_info.min_order_quantity) {
// 团购商品达到最小购买数量,提示用户并删除商品
uni.showToast({
title: '最少购买' + carItem.commodity_goods_info.min_order_quantity + '件',
icon: 'none'
});
// 更新购物车总数
that.shopCarTotal = Math.max(0, that.shopCarTotal - carItem.commodity_goods_info.min_order_quantity);
// 删除商品
that.deleteCarItem(carItem, goodsIndex, item);
} else {
// 正常减少数量
this.shopCarTotal = carItem.is_one_one === 1 ? Math.max(0, that.shopCarTotal - 2) : Math.max(0, that.shopCarTotal - 1);
carItem.count = carItem.is_one_one === 1 ? carItem.count - 2 : carItem.count - 1;
this.handleQuantityChange(carItem.count, carItem);
// 如果数量减为0,删除商品
if (carItem.count === 0) {
that.deleteCarItem(carItem, goodsIndex, item);
} else {
// 只在数量不为0时计算总价
this.calcTotal();
}
}
}
},
// 添加数量
add(carItem, goodsIndex) {
const currentTime = new Date().getTime();
const isGroupBuyActive = carItem.commodity_goods_info.group_buy_activity_info &&
currentTime >= new Date(carItem.commodity_goods_info.group_buy_activity_info?.start_time).getTime() &&
currentTime <= new Date(carItem.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (isGroupBuyActive) {
if (carItem.count == 0) {
carItem.count = carItem.is_one_one === 1 ? 2 : 1
this.shopCarTotal += carItem.is_one_one === 1 ? 2 : 1;
} else {
if (carItem.count == carItem.purchase_limit) {
uni.showToast({
title: '您选择的数量已达到最大限购量',
icon: 'none'
});
return
}
if (carItem.count == carItem.commodity_goods_info.max_limit_quantity) {
uni.showToast({
title: '一次最多购买' + carItem.commodity_goods_info.max_limit_quantity + '件',
icon: 'none'
});
return
}
carItem.count += carItem.is_one_one === 1 ? 2 : 1;
this.shopCarTotal += carItem.is_one_one === 1 ? 2 : 1;
}
} else {
if (carItem.count >= carItem.purchase_limit) {
uni.showToast({
title: '您选择的数量已达到最大限购量',
icon: 'none'
});
return
}
carItem.count += carItem.is_one_one === 1 ? 2 : 1;
this.shopCarTotal += carItem.is_one_one === 1 ? 2 : 1;
}
const item = carItem.commodity_cart_and_goods_model;
this.handleQuantityChange(carItem.count, carItem);
this.calcTotal();
},
// 删除
deleteItem() {
let that = this;
uni.showModal({
title: "提示",
content: "确定删除所选商品吗",
success: function (res) {
if (res.confirm) {
let ids = [];
// 收集当日达购物车中选中的商品ID
that.isDayCarList.forEach(carItem => {
carItem.commodity_cart_and_goods_model.forEach(goods => {
if (goods.checked) {
ids.push(goods.id);
goods.checked = false;
}
});
});
// 收集包邮购物车中选中的商品ID
that.shopCarList.forEach(carItem => {
carItem.commodity_cart_and_goods_model.forEach(goods => {
if (goods.checked) {
ids.push(goods.id);
goods.checked = false;
}
});
});
if (ids.length === 0) {
uni.showToast({
title: "请选择要删除的商品",
icon: "none",
duration: 2000,
});
return;
}
request(apiArr.deleteCar, "POST", {
ids,
})
.then((res) => {
uni.showToast({
title: "删除成功",
duration: 2000,
});
that.getShopCar();
that.calcTotal();
})
.catch((err) => {
console.log(err);
});
} else if (res.cancel) {
console.log("用户点击取消");
}
},
});
},
//商品数量变化
handleQuantityChange(val, item) {
const params = {
user_id: uni.getStorageSync("userId"),
goods_id_and_count: [{
goods_id: item.goods_id,
count: val,
price: item.price,
},],
};
request(apiArr.updateCar, "POST", params).then((res) => {
console.log(res);
uni.showToast({
title: "操作成功!",
success() { },
});
return Promise.resolve();
});
},
//获取价格 - 该显示团购价还是正常价
getPrice(item) {
const currentTime = new Date().getTime();
const startTime = new Date(item.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(item.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (currentTime >= startTime && currentTime <= endTime) {
return item.commodity_goods_info.group_buy_price;
} else {
return item.commodity_goods_info.sales_price;
}
},
},
onLoad(options) {
const meun = menuButtonInfo();
this.top = meun.top;
this.localHeight = meun.height;
this.is_group_buy = options.item ? JSON.parse(options.item).is_group_buy : ''
this.is_adver = options.item ? JSON.parse(options.item).is_adver : ''
this.getShopCar();
},
onShow() {
this.getShopCar();
// 取消所有选中状态并重置金额
this.isAllchecked = false;
this.isDaychecked = false;
this.isParcelPostchecked = false;
this.shopMoney = 0.00;
},
onReachBottom() { },
};
</script>
<style>
@import url("./index.css");
</style>

View File

@ -107,7 +107,7 @@
<div class="roomList"> <div class="roomList">
<!-- <div class="roomItem" v-for="(item,index) in 5" :class="index == 1?'active2':''"> --> <!-- <div class="roomItem" v-for="(item,index) in 5" :class="index == 1?'active2':''"> -->
<div @click="nextStep(item, index, 'room')" :class="{ active2: index === selectedRoomIndex }" class="roomItem" <div @click="nextStep(item, index, 'room')" :class="{ active2: index === selectedFinalRoomIndex }" class="roomItem"
v-for="(item, index) in filteredFloorsList" :key="index"> v-for="(item, index) in filteredFloorsList" :key="index">
{{ item.label }} {{ item.label }}
</div> </div>
@ -152,6 +152,7 @@ export default {
return { return {
selectedFloorIndex: -1, selectedFloorIndex: -1,
selectedRoomIndex: -1, selectedRoomIndex: -1,
selectedFinalRoomIndex: -1, // 添加新的选中索引变量
show: false, show: false,
step: "1", step: "1",
communityName: "", communityName: "",
@ -188,6 +189,13 @@ export default {
region: val.confirmDist.ad_name.split(",").join(""), region: val.confirmDist.ad_name.split(",").join(""),
...val.confirmDist, ...val.confirmDist,
}; };
// 切换城市后重置step为1
this.step = "1";
// 重置选中状态
this.selectedFloorIndex = -1;
this.selectedRoomIndex = -1;
this.selectedFinalRoomIndex = -1;
// 调用搜索方法加载对应城市的数据
this.searchByName(); this.searchByName();
this.show = false; this.show = false;
}, },
@ -209,7 +217,12 @@ export default {
}, },
async nextStep(item, index, type = "") { async nextStep(item, index, type = "") {
if (type === "room") { if (type === "room") {
this.selectedRoomIndex = index; // 根据当前步骤设置不同的选中索引
if (this.step == 3) {
this.selectedRoomIndex = index;
} else if (this.step == 4) {
this.selectedFinalRoomIndex = index;
}
} else { } else {
this.selectedFloorIndex = index; this.selectedFloorIndex = index;
} }

View File

@ -0,0 +1,307 @@
page {
background-color: #F6F6FA;
}
.container {
display: flex;
flex-direction: column;
min-height: calc(100vh - 120rpx);
width: 100%;
}
.searchBox {
display: flex;
align-items: center;
padding: 0 20rpx;
/* margin-top: 35rpx; */
justify-content: space-between;
background-color: #fff;
}
.searchBox_add {
display: flex;
align-items: center;
font-weight: 400;
font-size: 30rpx;
color: #000000;
}
.searchBox_add image {
width: 30rpx;
height: 30rpx;
margin-right: 16rpx;
}
.myRealEstate {
font-weight: 700;
padding-top: 36rpx;
font-weight: normal;
font-size: 36rpx;
color: #222222;
text-align: center;
background-color: #fff;
padding-bottom: 27rpx;
}
.myRealEstate .btn {
width: 600rpx;
height: 90rpx;
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
border-radius: 100rpx 100rpx 100rpx 100rpx;
font-weight: normal;
font-size: 36rpx;
color: #FFFFFF;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
margin-top: 30rpx;
}
.nearby {
padding: 0 20rpx;
margin-top: 20rpx;
background-color: #fff;
padding-top: 20rpx;
box-sizing: border-box;
flex: 1;
}
.nearbyTit {
display: flex;
justify-content: space-between;
}
.nearbyTit_left {
font-size: 36rpx;
color: #222222;
font-weight: 700;
}
.nearbyTit_right {
font-size: 26rpx;
color: #999999;
display: flex;
align-items: center;
}
.nearbyTit_right image {
width: 30rpx;
height: 30rpx;
}
.empty {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-weight: normal;
font-size: 28rpx;
color: #999999;
margin-top: 110rpx;
width: 100%;
}
.empty image {
width: 366rpx;
height: 226rpx;
margin-bottom: 27rpx;
}
.communityItem {
border-bottom: 1rpx solid #EBEBEB;
margin-top: 32rpx;
}
.communityItem_msg {
font-size: 26rpx;
color: #999999;
margin-top: 20rpx;
padding-bottom: 30rpx;
}
.communityItem_Box {
display: flex;
}
.communityItem_Box_left {
width: 180rpx;
overflow: hidden;
height: 180rpx;
border-radius: 20rpx 20rpx 20rpx 20rpx;
margin-right: 20rpx;
}
.communityItem_Box_left image {
width: 100%;
height: 100%;
}
.communityItem_Box_right {
flex: 1;
}
.communityItem_Box_right_tit {
font-size: 32rpx;
color: #222222;
margin-bottom: 8rpx;
}
.communityItem_Box_right_com {
font-size: 26rpx;
color: #555555;
margin-top: 8rpx;
height: 72rpx;
line-height: 36rpx;
-webkit-line-clamp: 2;
/* 限制显示 2 行 */
-webkit-box-orient: vertical;
/* 垂直排列 */
overflow: hidden;
/* 超出部分隐藏 */
text-overflow: ellipsis;
display: -webkit-box;
}
.communityItem_Box_right_msg {
margin-top: 14rpx;
}
.communityItem_Box_right_msg_right {
width: 140rpx;
height: 40rpx;
background: #FF370B;
border-radius: 100rpx 100rpx 100rpx 100rpx;
font-size: 26rpx;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
}
.communityItem_Box_right_msg {
display: flex;
align-items: center;
justify-content: space-between;
}
.communityItem_Box_right_msg_left {
display: flex;
align-items: center;
}
.communityItem_Box_right_msg_left1 {
width: 110rpx;
height: 40rpx;
background: rgba(255, 81, 42, 0.1);
border-radius: 100rpx 100rpx 100rpx 100rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 22rpx;
color: #555555;
margin-right: 20rpx;
}
.communityItem_Box_right_msg_left1 image {
width: 24rpx;
height: 24rpx;
margin-right: 10rpx;
}
.communityItem_Box_right_msg_left2 {
width: 110rpx;
height: 40rpx;
background: #FFF2DA;
border-radius: 100rpx 100rpx 100rpx 100rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 22rpx;
color: #555555;
}
.communityItem_Box_right_msg_left2 image {
width: 24rpx;
height: 24rpx;
margin-right: 10rpx;
}
.myRealEstateEmpty {
display: flex;
}
.myRealEstates {
width: 710rpx;
height: 200rpx;
margin: 0 auto;
position: relative;
}
.myRealEstates image {
width: 100%;
height: 100%;
object-fit: cover;
position: absolute;
z-index: 1;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.name {
font-size: 50rpx;
color: #FFFFFF;
text-shadow: 0px 2px 2px rgba(0, 0, 0, 0.6);
text-align: center;
position: relative;
z-index: 2;
padding-top: 24rpx;
}
.Visitor {
font-weight: normal;
font-size: 24rpx;
color: #FFFFFF;
width: 380rpx;
display: flex;
align-items: center;
justify-content: center;
height: 52rpx;
margin: 0 auto;
margin-top: 30rpx;
position: relative;
z-index: 2;
background: rgba(0, 0, 0, 0.3);
border-radius: 10rpx 10rpx 10rpx 10rpx;
}
.Tit {
font-size: 40rpx;
color: #222222;
text-align: center;
margin-top: 20rpx;
margin-bottom: 5rpx;
}
.subTit {
font-size: 24rpx;
color: #999999;
text-align: center;
margin-bottom: 30rpx;
}
.Con{
padding: 0 20rpx;
box-sizing: border-box;
line-height: 1.8;
}

View File

@ -0,0 +1,83 @@
<template>
<view class="container">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_add">
<u-icon bold color="#000" size="40" name="arrow-left" @click="back"></u-icon>
</view>
</view>
<view class="Tit">{{ Info.title }}</view>
<!-- <view class="subTit" v-if="Info.author || Info.publish_time">{{ Info.author }} {{ Info.publish_time }}</view>
<view class="subTit" v-else>
<text>发布时间:{{ new Date().toLocaleDateString() }}</text>
</view> -->
<view class="Con">
<rich-text :nodes="Info.content"></rich-text>
</view>
</view>
</template>
<script>
import {
picUrl,
uniqueByField,
menuButtonInfo
} from '../../../utils';
// 引入数据文件
import dataJson from '../index/data.json';
export default {
data() {
return {
top: "",
localHeight: "",
id: "",
Info: {},
defaultNoticeList: dataJson.defaultNoticeList
}
},
onLoad(options) {
const meun = menuButtonInfo();
this.top = meun.top;
// this.top = meun.height + meun.top;
this.localHeight = meun.height;
this.id = options.id;
this.getInfo();
},
methods: {
// 获取公告详情
getInfo() {
console.log("🚀 ~ getInfo ~ this.defaultNoticeList:", this.defaultNoticeList)
// 从本地数据中查找对应ID的内容
const detailData = this.defaultNoticeList.find(item => item.id === Number(this.id));
console.log("🚀 ~ getInfo ~ detailData:", detailData)
if (detailData) {
// 复制数据以避免修改原始数据
const info = { ...detailData };
// 将换行符转换为HTML的<br>标签,确保rich-text正确渲染换行
if (info.content) {
info.content = info.content.replace(/\n/g, '<br>');
}
this.Info = info;
}
},
back() {
uni.navigateBack({
delta: 1
});
},
},
}
</script>
<style>
@import url("./index.css");
</style>

View File

@ -0,0 +1,64 @@
{
"defaultCategoryList": [
{
"id": 1,
"category_name": "物业介绍"
},
{
"id": 2,
"category_name": "物业缴费"
},
{
"id": 3,
"category_name": "物业费"
},
{
"id": 4,
"category_name": "报事报修"
}
],
"defaultInfoList": [
{
"id": 1,
"title": "物业介绍",
"pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/Group_3677.png"
},
{
"id": 2,
"title": "物业缴费",
"pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/Group_3680.png"
},
{
"id": 3,
"title": "物业费",
"pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/Group_3679.png"
},
{
"id": 4,
"title": "报事报修",
"pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/Group_3678.png"
}
],
"defaultNoticeList": [
{
"id": 1,
"title": "物业介绍",
"content": "您好!\n &nbsp;&nbsp;&nbsp;&nbsp;物业服务中心是小区专属服务团队,核心服务包括:物业费收缴、公共区域清洁维护、设施设备(电梯/水电/绿化)检修、秩序安全管理,及应急事件响应、活动组织等日常事务。\n &nbsp;&nbsp;&nbsp;&nbsp;我们始终以\"用心服务、共建美好\"为宗旨,欢迎大家监督并提出改进建议。感谢您的理解与配合,让我们携手维护舒心的园区环境!"
},
{
"id": 2,
"title": "物业缴费",
"content": "各位业主:\n &nbsp;&nbsp;&nbsp;&nbsp;为简化缴费流程,提升服务效率,物业已上线\"线上+线下\"一体化缴费功能,支持物业费、车位费、公共能耗费等各类费用便捷缴纳,具体使用说明如下:\n一、线上缴费(推荐)\n &nbsp;&nbsp;&nbsp;&nbsp;1. 小程序端操作:打开物业专属小程序,进入\"我的-物业缴费\"页面,系统将自动展示您需缴纳的费用账单(含费用类型、金额、缴费周期等明细);确认账单无误后,选择微信支付,点击\"确认缴费\"即可完成。\n &nbsp;&nbsp;&nbsp;&nbsp;2. 账单查询:在缴费页面点击\"缴费记录\",可查看缴费明细(含缴费时间、金额、凭证号)。\n二、线下缴费(备用)\n若您偏好线下办理,可前往物业前台,通过现金、银行卡、移动支付(微信/支付宝扫码)完成缴费。"
},
{
"id": 3,
"title": "物业费",
"content": "各位业主:\n &nbsp;&nbsp;&nbsp;&nbsp;上线\"物业费\"功能,其核心规则与使用方式如下,覆盖所有房产通用场景:\n一、物业费的获取方式\n &nbsp;&nbsp;&nbsp;&nbsp;通过周边合作门店消费,即可获得物业费;\n二、跨房产通用:一份公积金,多房产可用\n &nbsp;&nbsp;&nbsp;&nbsp;您的个人物业费不绑定单一房产,可通用至您已加入的所有房产。例如:您的个人公积金,既可抵扣A小区的物业费,也可抵扣您加入的B小区的水电费、C小区的燃气费,无需额外转移或申请。\n三、查询与透明化\n &nbsp;&nbsp;&nbsp;&nbsp;在物业平台\"我的-物业费\"页面,可实时查看:个人公积金余额、所属房产的总额、抵扣记录(含抵扣房产、金额、个人扣除份额),确保每笔使用清晰可溯。"
},
{
"id": 4,
"title": "报事报修",
"content": "各位业主:\n &nbsp;&nbsp;&nbsp;&nbsp;小程序\"报事报修\"功能,覆盖全物业类型通用场景,操作简单、响应高效,具体介绍如下:\n一、报修流程\n1、进入功能:打开物业小程序,点击\"报事报修\"图标,选择报修页面;\n2、填写信息:选择\"详细地址\"、\"报修类型\"(水电故障/家电维修/公共设施损坏等),补充问题描述(如\"厨房水龙头漏水\"\"办公室空调不制冷\"),可上传现场照片(便于维修人员预判问题);\n3、提交确认:核对信息后点击\"提交报修\",系统自动生成报修单号,同步推送至物业维修部。\n二、报修范围:室内水电、家电、门窗、厨卫设施维修等;\n三、进度追踪\n1、实时查进度:在\"我的报修\"页面,可查看报修单状态,维修人员接单后会主动联系确认上门时间;\n2、紧急情况(如水管爆裂、断电)可先拨打物业24小时热线,再补填在线报修单,确保问题快速解决!"
}
]
}

View File

@ -43,6 +43,26 @@
</u-grid-item> </u-grid-item>
</u-grid> </u-grid>
</view> </view>
<view class="tabs" v-if="defaultCategoryList.length > 0">
<view v-for="(item, index) in defaultCategoryList" :key="index"
:class="['tabItem', selectedTab === index ? 'active2' : '']" @click="selectTab(index, item)">
{{ item.category_name }}
</view>
</view>
<view class="newsList" v-if="defaultCategoryList.length > 0">
<view class="newsItem" v-for="item in defaultInfoList" @click="defaultDetail(item)" :key="item.id">
<view class="newsItem_left">
<view class="newsItem_left_tit">{{ item.title }}</view>
<view class="newsItem_left_sub">{{ item.author }}</view>
</view>
<view class="newsItem_right">
<image :src="item.pic" mode="aspectFill" />
</view>
</view>
</view>
</view> </view>
<view v-else> <view v-else>
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }"> <view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
@ -96,6 +116,13 @@
</view> </view>
</view> </view>
<view class="tabs" v-else>
<view v-for="(item, index) in defaultCategoryList" :key="index"
:class="['tabItem', selectedTab === index ? 'active2' : '']" @click="selectTab(index, item)">
{{ item.category_name }}
</view>
</view>
<view class="newsList" v-if="categoryList.length > 0"> <view class="newsList" v-if="categoryList.length > 0">
<view class="newsItem" v-for="item in infoList" @click="detail(item)" :key="item.id"> <view class="newsItem" v-for="item in infoList" @click="detail(item)" :key="item.id">
<view class="newsItem_left"> <view class="newsItem_left">
@ -108,6 +135,18 @@
</view> </view>
</view> </view>
<view class="newsList" v-else>
<view class="newsItem" v-for="item in defaultInfoList" @click="defaultDetail(item)" :key="item.id">
<view class="newsItem_left">
<view class="newsItem_left_tit">{{ item.title }}</view>
<view class="newsItem_left_sub">{{ item.author }}</view>
</view>
<view class="newsItem_right">
<image :src="item.pic" mode="aspectFill" />
</view>
</view>
</view>
<view class="tips">{{ loadMoreText }}</view> <view class="tips">{{ loadMoreText }}</view>
<view class="bigAds" v-if="ads1Show"> <view class="bigAds" v-if="ads1Show">
@ -158,6 +197,9 @@ import {
import { apiArr } from "../../../api/v2Community"; import { apiArr } from "../../../api/v2Community";
import { apiArr as apiArr2 } from "../../../api/community"; import { apiArr as apiArr2 } from "../../../api/community";
// 引入数据文件
import dataJson from './data.json';
export default { export default {
data() { data() {
return { return {
@ -185,11 +227,11 @@ export default {
}, },
{ {
nav_icon: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/noValFunction3.png', nav_icon: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/noValFunction3.png',
nav_name: "物业公积金", nav_name: "物业费",
}, },
{ {
nav_icon: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/noValFunction1.png', nav_icon: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/noValFunction1.png',
nav_name: "物业保修", nav_name: "物业报修",
}, },
{ {
nav_icon: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/noValFunction4.png', nav_icon: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/noValFunction4.png',
@ -242,6 +284,12 @@ export default {
isShowBill: false, isShowBill: false,
houseVal: "", houseVal: "",
// 从JSON文件中获取默认数据
defaultCategoryList: dataJson.defaultCategoryList,
defaultInfoList: dataJson.defaultInfoList,
// 用于存储原始的defaultInfoList数据
originalDefaultInfoList: null
}; };
}, },
async onLoad(options) { async onLoad(options) {
@ -269,7 +317,7 @@ export default {
is_published: 1, is_published: 1,
jump_target: 1, jump_target: 1,
mini_program_url: "/packages/community/repairList/index", mini_program_url: "/packages/community/repairList/index",
nav_icon: picUrl + "/static/images/2025-07-05/db3s1b1lyxawt8cnke.png", nav_icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/noValFunction1.png",
nav_name: "报事报修", nav_name: "报事报修",
other_appid: "", other_appid: "",
other_path: "", other_path: "",
@ -283,7 +331,7 @@ export default {
is_published: 1, is_published: 1,
jump_target: 1, jump_target: 1,
mini_program_url: "/packages/community/propertyPayment/index", mini_program_url: "/packages/community/propertyPayment/index",
nav_icon: picUrl + "/static/images/2025-07-05/db3s1t7d1k0qmuha61.png", nav_icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/noValFunction2.png",
nav_name: "物业缴费", nav_name: "物业缴费",
other_appid: "", other_appid: "",
other_path: "", other_path: "",
@ -297,8 +345,8 @@ export default {
is_published: 1, is_published: 1,
jump_target: 1, jump_target: 1,
mini_program_url: "/packages/community/providentFund/index", mini_program_url: "/packages/community/providentFund/index",
nav_icon: picUrl + "/static/images/2025-07-05/db3s29e33rd7rsrecf.png", nav_icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/noValFunction3.png",
nav_name: "物业公积金", nav_name: "物业费",
other_appid: "", other_appid: "",
other_path: "", other_path: "",
sort: 2, sort: 2,
@ -315,6 +363,18 @@ export default {
this.getfunctionNum(); this.getfunctionNum();
this.getAdvertising(); this.getAdvertising();
this.getCategoryList(); this.getCategoryList();
// 初始化默认数据,确保在没有绑定社区时选中第一个分类
setTimeout(() => {
if (this.categoryList.length === 0 && this.defaultCategoryList.length > 0) {
this.selectedTab = 0;
if (!this.originalDefaultInfoList) {
this.originalDefaultInfoList = JSON.parse(JSON.stringify(dataJson.defaultInfoList));
}
// 默认选中第一个分类并展示对应数据
this.defaultInfoList = this.originalDefaultInfoList.filter(info => info.id === this.defaultCategoryList[0].id);
}
}, 100);
}, },
//上拉刷新 //上拉刷新
@ -382,7 +442,7 @@ export default {
if (targetItem.front_end_display == 1) { if (targetItem.front_end_display == 1) {
uni.removeStorageSync("changeCommData"); uni.removeStorageSync("changeCommData");
} }
}else{ } else {
uni.removeStorageSync("changeCommData"); uni.removeStorageSync("changeCommData");
} }
@ -667,11 +727,23 @@ export default {
}, },
async selectTab(index, item) { async selectTab(index, item) {
// 检查是否使用的是默认数据(没有绑定社区时)
if (this.categoryList.length === 0) {
this.selectedTab = index;
if (!this.originalDefaultInfoList) {
this.originalDefaultInfoList = JSON.parse(JSON.stringify(dataJson.defaultInfoList));
}
// 根据选中的分类ID筛选数据
this.defaultInfoList = this.originalDefaultInfoList.filter(info => info?.id === item?.id);
return;
}
// 原有逻辑(有绑定社区时)
const isTabChange = this.selectedTab !== index; const isTabChange = this.selectedTab !== index;
if (isTabChange) { if (isTabChange) {
this.page_num = 1; this.page_num = 1;
this.infoList = []; this.infoList = [];
// this.loadMoreText = "下拉加载后续10条,共计30条";
} }
this.selectedTab = index; this.selectedTab = index;
@ -729,6 +801,11 @@ export default {
console.log(e); console.log(e);
NavgateTo("../noticeDesc/index?id=" + e.id); NavgateTo("../noticeDesc/index?id=" + e.id);
}, },
defaultDetail(e) {
console.log(e);
NavgateTo("../defaultNotice/index?id=" + e.id);
},
}, },
}; };
</script> </script>

View File

@ -7,6 +7,16 @@ page {
background-color: #f6f7fb; background-color: #f6f7fb;
} }
.top{
height: 300rpx;
width: 100%;
margin-bottom: 20rpx;
}
.top image {
border-radius: 12rpx;
}
.community-list-container { .community-list-container {
padding: 20rpx; padding: 20rpx;
} }

View File

@ -1,5 +1,8 @@
<template> <template>
<view class="community-list-container"> <view class="community-list-container">
<view class="top">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/communityTopImg.png" mode=""></image>
</view>
<view class="community-list"> <view class="community-list">
<view class="community-item-box" v-for="(item, index) in communityList" :key="index"> <view class="community-item-box" v-for="(item, index) in communityList" :key="index">
<view class="community-item"> <view class="community-item">
@ -121,9 +124,9 @@ export default {
return item; return item;
}); });
// 过滤出距离1km以内的数据 // 过滤出距离1km以内的数据,确保距离为0的值也能被正确保留
processedList = processedList.filter(item => processedList = processedList.filter(item =>
item.distanceValue && item.distanceValue <= 1 item.distanceValue !== undefined && item.distanceValue !== null && item.distanceValue <= 1
); );
// 调用腾讯地图API获取附近1km的小区(包含图片信息) // 调用腾讯地图API获取附近1km的小区(包含图片信息)
@ -160,17 +163,26 @@ export default {
}; };
}); });
// 过滤腾讯地图数据,只保留那些name不在接口返回数据中的小区
// 创建一个包含接口返回数据所有name的Set
const processedNames = new Set(processedList.map(item => item.name));
// 过滤腾讯地图数据
const filteredTencentCommunities = tencentCommunities.filter(item =>
!processedNames.has(item.name)
);
// 合并数据 // 合并数据
mergedList = [...processedList, ...tencentCommunities]; mergedList = [...processedList, ...filteredTencentCommunities];
// 根据community_id去重 // 根据community_id去重
mergedList = uniqueByField(mergedList, 'community_id'); mergedList = uniqueByField(mergedList, 'community_id');
} }
// 根据距离排序 // 根据距离排序,确保距离为0的值也能正确排序
mergedList.sort((a, b) => { mergedList.sort((a, b) => {
const distanceA = a.distanceValue || Infinity; const distanceA = a.distanceValue !== undefined && a.distanceValue !== null ? a.distanceValue : Infinity;
const distanceB = b.distanceValue || Infinity; const distanceB = b.distanceValue !== undefined && b.distanceValue !== null ? b.distanceValue : Infinity;
return distanceA - distanceB; return distanceA - distanceB;
}); });

View File

@ -130,7 +130,7 @@ export default {
localHeight: "", localHeight: "",
roomList: [], roomList: [],
columns: [], columns: [],
category: {}, // 保修类型信息 category: {}, // 报修类型信息
repairInfo: '', // 问题描述 repairInfo: '', // 问题描述
contactName: '', // 联系人名称 contactName: '', // 联系人名称
contactPhone: '', // 联系人电话 contactPhone: '', // 联系人电话

View File

@ -214,6 +214,7 @@ image {
.payItem_money{ .payItem_money{
width: auto; width: auto;
margin-right: 10rpx;
} }
.bottom { .bottom {

View File

@ -35,7 +35,7 @@
<view class="homeMoney" v-if="active == 0"> <view class="homeMoney" v-if="active == 0">
<view class="homeMoney_box"> <view class="homeMoney_box">
<view class="homeMoney_box_left"> <view class="homeMoney_box_left">
<view class="homeMoney_box_left1">物业公积金</view> <view class="homeMoney_box_left1">物业费</view>
<view class="homeMoney_box_left2">可抵扣账户金额</view> <view class="homeMoney_box_left2">可抵扣账户金额</view>
</view> </view>
<view class="homeMoney_box_right"> <view class="homeMoney_box_right">
@ -56,7 +56,10 @@
<view class="payItem" v-for="(item, index) in Bill" :key="index"> <view class="payItem" v-for="(item, index) in Bill" :key="index">
<view class="payItem_tit"> <view class="payItem_tit">
<view class="payItem_left"> <view class="payItem_left">
<checkbox :checked="item.check" @click="checkChange(item, index)"></checkbox> <checkbox :checked="item.check" @click="checkChange(item, index)"
v-if="item.community_order_rows.some(itemObj => itemObj.pay_status == 1)"
:disabled="!canSelectBill(index)">
</checkbox>
<view style="margin-left: 24rpx">{{ item.order_date }}年</view> <view style="margin-left: 24rpx">{{ item.order_date }}年</view>
</view> </view>
<view class="payItem_right"> <view class="payItem_right">
@ -72,7 +75,8 @@
</view> </view>
<view v-if="item.more"> <view v-if="item.more">
<view class="payItem_List" v-for="(items, indes) in item.community_order_rows" :key="items.order_id"> <view class="payItem_List" v-for="(items, indes) in item.community_order_rows" :key="items.order_id">
<checkbox :checked="items.check" @click="itemsCheckChange(items, indes, index)"></checkbox> <checkbox :checked="items.check" @click="itemsCheckChange(items, indes, index)" v-if="items.pay_status == 1"
:disabled="!canSelectItem(indes, index)"></checkbox>
<view class="Item_time" v-if="items.billing_cycle == 1"> <view class="Item_time" v-if="items.billing_cycle == 1">
{{ items.order_date }}年 {{ items.order_date }}年
</view> </view>
@ -83,8 +87,8 @@
{{ items.community_fee_type ? items.community_fee_type.type_name : '' }} {{ items.community_fee_type ? items.community_fee_type.type_name : '' }}
</view> </view>
<view class="Item_money">¥{{ items.money }}</view> <view class="Item_money">¥{{ items.money }}</view>
<view class="Item_status" v-if="items.status == 0">未付款</view> <view class="Item_status" v-if="items.pay_status == 1">未付款</view>
<view class="Item_status sucess" v-if="items.status == 1"> <view class="Item_status sucess" v-if="items.pay_status == 2">
已付款 已付款
</view> </view>
</view> </view>
@ -118,7 +122,7 @@
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_homeMoney.png" alt="" /> src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_homeMoney.png" alt="" />
</view> </view>
<view class="PayTypeItem_con"> <view class="PayTypeItem_con">
<view class="PayTypeItem_con_tit">物业公积金支付</view> <view class="PayTypeItem_con_tit">物业费支付</view>
<view class="PayTypeItem_con_msg"> <view class="PayTypeItem_con_msg">
可用公积金:<span>¥</span>{{ balanceMoney }} 可用公积金:<span>¥</span>{{ balanceMoney }}
<view class="PayTypeItem_con_msg2" @click="changeShow2"> <view class="PayTypeItem_con_msg2" @click="changeShow2">
@ -147,7 +151,7 @@
<view class="payHisItem" v-for="item in payOrderList" :key="item.id"> <view class="payHisItem" v-for="item in payOrderList" :key="item.id">
<view class="row"> <view class="row">
<view class="row_label">缴费金额</view> <view class="row_label">缴费金额</view>
<view class="row_con1">¥{{ item.money }}</view> <view class="row_con1">¥{{ item.money + item.property_housing_fund }}</view>
</view> </view>
<view class="row"> <view class="row">
<view class="row_label2"></view> <view class="row_label2"></view>
@ -155,23 +159,23 @@
</view> </view>
<view class="line4"></view> <view class="line4"></view>
<view class="row"> <view class="row">
<view class="row_label">绑定房源</view> <view class="row_label">缴费账单数量</view>
<view class="row_con3"> <view class="row_con3">
<view class="row_con3_1"> <view class="row_con3_1">
{{ item.community_order.length }}个账单 {{ item.community_order ? item.community_order.length : 0 }}个账单
</view> </view>
<view class="row_con3_2">明细可从收据查看</view> <!-- <view class="row_con3_2">明细可从收据查看</view> -->
</view> </view>
</view> </view>
<view class="row"> <view class="row">
<view class="row_label">应缴费金额</view> <view class="row_label">应缴费金额</view>
<view class="row_con4">¥{{ item.money }}</view> <view class="row_con4">¥{{ item.money + item.property_housing_fund }}</view>
</view> </view>
<view class="row"> <view class="row">
<view class="row_label">物业费公积金抵扣金额</view> <view class="row_label">物业费抵扣金额</view>
<view class="row_con4">-¥{{ item.reduction_money }}</view> <view class="row_con4">-¥{{ item.property_housing_fund }}</view>
</view> </view>
<view class="row"> <view class="row">
@ -179,7 +183,7 @@
<view class="row_con4">{{ item.order_pay_no }}</view> <view class="row_con4">{{ item.order_pay_no }}</view>
</view> </view>
<view class="line4"></view> <view class="line4"></view>
<view class="Receipt">收据</view> <!-- <view class="Receipt">收据</view> -->
</view> </view>
</view> </view>
@ -228,7 +232,7 @@
微信支付 微信支付
</view> </view>
<view class="banlenceItem_right"> <view class="banlenceItem_right">
<span>¥</span>{{ (currentMoney - balanceMoney).toFixed(2) }} <span>¥</span>{{ balanceMoney > currentMoney ? 0.00 : (currentMoney - balanceMoney).toFixed(2) }}
</view> </view>
</view> </view>
<view class="line3"></view> <view class="line3"></view>
@ -236,16 +240,16 @@
<view class="banlenceItem_left"> <view class="banlenceItem_left">
<image mode="aspectFill" <image mode="aspectFill"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_homeMoney.png" alt="" /> src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_homeMoney.png" alt="" />
物业公积金支付 物业费支付
</view> </view>
<view class="banlenceItem_right"> <view class="banlenceItem_right">
<span>¥</span>{{ balanceMoney }} <span>¥</span>{{ balanceMoney > currentMoney ? currentMoney : balanceMoney }}
</view> </view>
</view> </view>
</view> </view>
<view class="btn" @click="createPay"> <view class="btn" @click="createPay">
物业公积金+微信支付 <span>¥</span>{{ currentMoney }} 物业费+微信支付 <span>¥</span>{{ currentMoney }}
</view> </view>
</view> </view>
</view> </view>
@ -277,6 +281,7 @@ export default {
currentCommunity: "", //当前房源 currentCommunity: "", //当前房源
currentCommunityAddr: "", //当前房源地址 currentCommunityAddr: "", //当前房源地址
Bill: "", //账单 Bill: "", //账单
Bill2: "", //未支付账单
balanceMoney: 0, //公积金 balanceMoney: 0, //公积金
currentMoney: 0, //所选金额 currentMoney: 0, //所选金额
@ -287,6 +292,7 @@ export default {
page_num: 1, page_num: 1,
payOrderList: [], payOrderList: [],
flag: false, flag: false,
isAllow: false,
}; };
}, },
onLoad(options) { onLoad(options) {
@ -296,15 +302,66 @@ export default {
this.localHeight = meun.height; this.localHeight = meun.height;
this.currentCommunity = uni.getStorageSync("changeCommData"); this.currentCommunity = uni.getStorageSync("changeCommData");
this.currentCommunityAddr = uni.getStorageSync("currentCommunityAddr"); this.currentCommunityAddr = uni.getStorageSync("currentCommunityAddr");
// 解析从providentFund页面传递过来的房源信息
if (options.item) {
try {
const item = JSON.parse(decodeURIComponent(options.item));
this.currentRoom = item;
} catch (error) {
console.error("解析房源信息失败:", error);
}
}
this.getRoomSelect(); this.getRoomSelect();
this.getUserGovenmentMoney(); this.getUserGovenmentMoney();
}, },
// 下拉刷新生命周期函数
onPullDownRefresh() {
// 根据当前激活的标签页,重新加载对应的数据
if (this.active === 0) {
// 账单页面,重新获取公积金和账单数据,不重置已选择的小区
Promise.all([
this.getUserGovenmentMoney(),
this.getOrderList()
]).then(() => {
// 数据加载完成后停止下拉刷新
uni.stopPullDownRefresh();
}).catch(() => {
// 加载失败也需要停止下拉刷新
uni.stopPullDownRefresh();
});
} else if (this.active === 1) {
// 缴费记录页面,重新获取缴费记录
this.page_num = 1;
this.page_size = 10;
this.getPayList().then(() => {
// 数据加载完成后停止下拉刷新
uni.stopPullDownRefresh();
}).catch(() => {
// 加载失败也需要停止下拉刷新
uni.stopPullDownRefresh();
});
}
},
// 滑动到底部生命周期函数
onReachBottom() {
// 只有在缴费记录页面且还有更多数据时才触发加载更多
if (this.active === 1 && this.flag) {
// 增加page_size的值
this.page_size += 10;
// 重新获取缴费记录
this.getPayList();
}
},
methods: { methods: {
changeTab(index) { changeTab(index) {
this.active = index; this.active = index;
if (index == 1) { if (index == 1) {
// 重置分页参数
this.page_num = 1; this.page_num = 1;
this.page_size = 10;
this.getPayList(); this.getPayList();
} }
}, },
@ -328,20 +385,32 @@ export default {
}, },
//获取房源 //获取房源
getRoomSelect() { getRoomSelect() {
request(apiArr.getCommunityRoomList, "POST", { return new Promise((resolve, reject) => {
community_id: this.currentCommunity.id, request(apiArr.getCommunityRoomList, "POST", {
page_num: 1, community_id: this.currentCommunity.id,
page_size: 50, page_num: 1,
}).then((res) => { page_size: 50,
this.roomList = res.rows; }).then((res) => {
this.currentRoom = this.roomList[0]; this.isAllow = res.rows[0].community.bill_allow_skip_payment === 1;
this.selectedRoomId = this.currentRoom.room_id; this.roomList = res.rows;
this.getOrderList(); if (!this.currentRoom.room_id) {
this.currentRoom = this.roomList[0]
}
this.selectedRoomId = this.currentRoom.room_id;
this.getOrderList().then(() => {
resolve();
}).catch((error) => {
reject(error);
});
}).catch((error) => {
reject(error);
});
}); });
}, },
// 选择房源 // 选择房源
selectRoom(item) { selectRoom(item) {
this.getRoomSelect()
// 更新选中的房源ID // 更新选中的房源ID
this.selectedRoomId = item.room_id; this.selectedRoomId = item.room_id;
// 在控制台输出选中的数据 // 在控制台输出选中的数据
@ -349,83 +418,180 @@ export default {
this.currentRoom = item; this.currentRoom = item;
this.getOrderList(); this.getOrderList();
// 如果当前是缴费记录标签页,重新请求缴费记录数据
if (this.active === 1) {
// 重置分页参数
this.page_num = 1;
this.page_size = 10;
this.getPayList();
}
}, },
//获取用户公积金 //获取用户公积金
async getUserGovenmentMoney() { getUserGovenmentMoney() {
request(apiArr.getUserGovenmentMoney, "POST", {}).then((res) => { return new Promise((resolve, reject) => {
console.log(res, "公积金"); request(apiArr.getUserGovenmentMoney, "POST", {}).then((res) => {
this.balanceMoney = res.balance_after; console.log(res, "公积金");
this.balanceMoney = res.balance_after;
resolve();
}).catch((error) => {
reject(error);
});
}); });
}, },
//获取账单 //获取账单
async getOrderList() { getOrderList() {
await request(apiArr.getOrderList, "POST", { return new Promise((resolve, reject) => {
room_id: this.currentRoom.room_id, request(apiArr.getOrderList, "POST", {
page_num: 1, room_id: this.currentRoom.room_id,
page_size: 50, page_num: 1,
}).then((res) => { page_size: 50,
console.log(res, "账单"); }).then((res) => {
res.rows.forEach((item) => { console.log(res, "账单");
item.check = false; res.rows.forEach((item) => {
item.more = false; item.check = false;
item.community_order_rows.forEach((ite) => { item.more = false;
ite.check = false; item.community_order_rows.forEach((ite) => {
ite.check = false;
});
}); });
// 按照年份和月份进行排序
res.rows.sort((a, b) => {
// 首先获取年份(从community_order_rows中第一个元素的order_date提取)
const yearA = a.community_order_rows && a.community_order_rows.length > 0 ? parseInt(a.community_order_rows[0].order_date) : 0;
const yearB = b.community_order_rows && b.community_order_rows.length > 0 ? parseInt(b.community_order_rows[0].order_date) : 0;
// 如果年份不同,按照年份排序
if (yearA !== yearB) {
return yearA - yearB;
}
// 如果年份相同,获取月份进行比较
const monthA = a.community_order_rows && a.community_order_rows.length > 0 ? parseInt(a.community_order_rows[0].order_datetime) : 0;
const monthB = b.community_order_rows && b.community_order_rows.length > 0 ? parseInt(b.community_order_rows[0].order_datetime) : 0;
return monthA - monthB;
});
this.Bill = res.rows;
this.Bill2 = res.rows.reduce((result, item) => {
const paidOrders = item.community_order_rows.filter(ite => ite.pay_status == 1);
return result.concat(paidOrders);
}, []);
resolve();
}).catch((error) => {
reject(error);
}); });
this.Bill = res.rows;
}); });
}, },
//账单详情切换展示显示 //账单详情切换展示显示
changeCheck(e, index) { changeCheck(e, index) {
this.Bill[index].more = !this.Bill[index].more; this.Bill[index].more = !this.Bill[index].more;
}, },
// 判断是否可以选择该年份的账单
canSelectBill(index) {
if (this.isAllow) return true;
// 如果是第一条账单,总是可以选择
if (index === 0) return true;
// 检查前面所有年份的账单是否都已支付
for (let i = 0; i < index; i++) {
const yearBill = this.Bill[i];
// 检查该年份是否有未支付的账单
const hasUnpaid = yearBill.community_order_rows.some(item => item.pay_status === 1);
if (hasUnpaid) {
return false;
}
}
return true;
},
// 判断是否可以选择该具体的账单项
canSelectItem(indes, index) {
if (this.isAllow) return true;
// 首先检查该年份是否可以选择
if (!this.canSelectBill(index)) {
return false;
}
// 如果是该年份的第一项,总是可以选择
if (indes === 0) return true;
// 检查该年份前面的月份是否都已支付
const yearBill = this.Bill[index];
for (let i = 0; i < indes; i++) {
if (yearBill.community_order_rows[i].pay_status === 1) {
return false;
}
}
return true;
},
//整体选择 //整体选择
checkChange(e, index) { checkChange(e, index) {
this.Bill[index].check = !this.Bill[index].check; // 只针对没有禁用的多选框操作
this.Bill[index].community_order_rows.forEach((item) => { if (this.canSelectBill(index)) {
if (this.Bill[index].check) { this.Bill[index].check = !this.Bill[index].check;
item.check = true; this.Bill[index].community_order_rows.forEach((item, indes) => {
} else { // 子项也只针对没有禁用的多选框操作
item.check = false; if (item.pay_status == 1 && this.canSelectItem(indes, index)) {
} item.check = this.Bill[index].check;
});
// 重新计算选中金额
let money = 0;
this.Bill.forEach((item) => {
item.community_order_rows.forEach((ite) => {
if (ite.check) {
money += ite.money;
} }
}); });
});
this.currentMoney = money; // 重新计算选中金额
let money = 0;
this.Bill.forEach((item) => {
item.community_order_rows.forEach((ite) => {
if (ite.check && ite.pay_status == 1) {
money += ite.money;
}
});
});
this.currentMoney = money ? money.toFixed(2) : 0.00;
}
}, },
//具体选择 //具体选择
itemsCheckChange(e, indes, index) { itemsCheckChange(e, indes, index) {
this.Bill[index].community_order_rows[indes].check = // 只针对没有禁用的多选框操作
!this.Bill[index].community_order_rows[indes].check; if (this.canSelectItem(indes, index)) {
//判断是否全部选中 this.Bill[index].community_order_rows[indes].check =
let isAll = this.Bill[index].community_order_rows.every((item) => { !this.Bill[index].community_order_rows[indes].check;
return item.check;
}); //判断是否全部选中(只检查可选中的项)
if (isAll) { let isAll = this.Bill[index].community_order_rows.every((item, idx) => {
this.Bill[index].check = true; // 只考虑可选中的项(未支付且可以选择)
} else { if (item.pay_status === 1 && this.canSelectItem(idx, index)) {
this.Bill[index].check = false; return item.check;
}
//帮我计算所有Bill的的community_order_rows 所选中的金额 现在取消选择金额没有减
let money = 0;
this.Bill.forEach((item) => {
item.community_order_rows.forEach((ite) => {
if (ite.check) {
money += ite.money;
} }
// 对于已支付或不可选择的项,不影响全选状态
return true;
}); });
});
this.currentMoney = money; if (isAll) {
this.Bill[index].check = true;
} else {
this.Bill[index].check = false;
}
// 计算所有选中的金额
let money = 0;
this.Bill.forEach((item) => {
item.community_order_rows.forEach((ite) => {
if (ite.check && ite.pay_status == 1) {
money += ite.money;
}
});
});
this.currentMoney = money ? money.toFixed(2) : 0.00;
}
}, },
//切换支付方式 //切换支付方式
changePayType(e) { changePayType(e) {
@ -445,9 +611,9 @@ export default {
if (this.payType == 1) { if (this.payType == 1) {
name_mini = "微信"; name_mini = "微信";
} else if (this.payType == 2) { } else if (this.payType == 2) {
name_mini = "物业公积金"; name_mini = "物业费";
} else { } else {
name_mimi = "微信 + 物业公积金"; name_mini = "微信 + 物业费";
} }
if (!this.currentMoney) { if (!this.currentMoney) {
return uni.showToast({ return uni.showToast({
@ -455,22 +621,97 @@ export default {
duration: 2000, duration: 2000,
}); });
} }
await request(apiArr.createPayOrder, "POST", {
// 构建支付参数,根据支付类型决定传递哪些字段
const payParams = {
order_ids: order_ids, order_ids: order_ids,
community_id: this.currentCommunity.id, community_id: this.currentCommunity.id,
room_id: this.currentRoom.room_id, room_id: this.currentRoom.room_id,
pay_user_id: uni.getStorageSync("userId"), pay_user_id: uni.getStorageSync("userId"),
user_name: uni.getStorageSync("nickName"), user_name: uni.getStorageSync("nickName"),
pay_user_name: uni.getStorageSync("nickName"), pay_user_name: uni.getStorageSync("nickName"),
//格式化年月日 时分秒
pay_time: formatDate(new Date()), pay_time: formatDate(new Date()),
money: this.currentMoney,
name_mini, name_mini,
}).then((res) => { };
console.log(res);
this.payInfoId = res.id; // 判断是否是组合支付
this.OrderPay(); const isComboPay = this.show2;
});
if (this.payType == 1 || isComboPay) {
//微信支付或组合支付
if (isComboPay) {
payParams.money = this.currentMoney - Number(this.balanceMoney).toFixed(2) > 0 ? this.currentMoney - Number(this.balanceMoney).toFixed(2) : 0.00;
if (payParams.money == 0.00) {
this.payType = 2;
}
} else {
payParams.money = this.currentMoney;
}
}
if (this.payType == 2 || isComboPay) {
// 公积金支付或组合支付
const fundAmount = Math.min(Number(this.balanceMoney), Number(this.currentMoney));
payParams.property_housing_fund = fundAmount.toFixed(2);
if (isComboPay && payParams.money == 0) {
this.payType = 2;
}
// 仅公积金支付 公积金不足
if (this.payType == 2 && !isComboPay) {
if (Number(this.balanceMoney) < Number(this.currentMoney)) {
uni.showToast({
title: '可用公积金不足,可选择组合支付',
icon: 'none',
duration: 3000
});
return;
}
}
}
// 组合支付
if (isComboPay && (payParams.money != 0.00 || payParams.money != 0)) {
this.payType = 3;
name_mini = "微信 + 物业费";
}
payParams.name_mini = name_mini;
if (this.payType == 2) {
uni.showModal({
title: '提示',
content: '确定使用物业费支付?',
success: async (res) => {
if (res.confirm) {
await request(apiArr.createPayOrder, "POST", payParams).then((res) => {
const params = {
order_pay_id: res.id,
}
request(apiArr.tradeQuery, "POST", params).then(res => {
uni.showToast({
title: '支付成功',
icon: 'success',
duration: 2000
});
setTimeout(() => {
this.getRoomSelect();
this.getUserGovenmentMoney();
}, 1500);
})
});
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
} else {
await request(apiArr.createPayOrder, "POST", payParams).then((res) => {
this.payInfoId = res.id;
this.OrderPay();
});
}
}, },
//根据支付订单查询交易信息 //根据支付订单查询交易信息
async getPayInfo() { async getPayInfo() {
@ -485,38 +726,80 @@ export default {
// this.payInfoId // this.payInfoId
await request(apiArr.OrderPay, "POST", { order_pay_id: this.payInfoId }).then( await request(apiArr.OrderPay, "POST", { order_pay_id: this.payInfoId }).then(
async (res) => { async (res) => {
const params = { if (res && res.timeStamp && res.nonceStr && res.package && res.signType && res.paySign) {
order_pay_id: this.payInfoId, // 调用微信支付
uni.requestPayment({
timeStamp: res.timeStamp,
nonceStr: res.nonceStr,
package: res.package,
signType: res.signType,
paySign: res.paySign,
success: (payRes) => {
const params = {
order_pay_id: this.payInfoId,
}
request(apiArr.tradeQuery, "POST", params).then(res => {
this.getRoomSelect();
this.getUserGovenmentMoney();
})
},
fail: (payErr) => {
uni.showToast({
title: payErr.errMsg == 'requestPayment:fail cancel' ? '已取消支付' : '支付失败',
icon: 'none'
})
const params = {
order_pay_id: this.payInfoId,
}
request(apiArr.delPay, "POST", params).then(res => {
})
},
complete: () => {
// 支付完成后的回调,无论成功失败都会执行
}
})
} else {
console.error("获取支付参数失败,缺少必要参数")
uni.showToast({
title: '获取支付信息失败',
icon: 'none'
})
} }
await request(apiArr.OrderPay, "POST", params).then(
(res) => {
}
);
} }
); );
}, },
//支付记录 //支付记录
getPayList() { getPayList() {
return new Promise((resolve, reject) => {
request(apiArr.getPayOrderList, "POST", {
room_id: this.currentRoom.room_id,
page_num: this.page_num,
page_size: this.page_size,
}).then((res) => {
// 判断是否还有更多数据
let flag = false;
if (res.rows && res.rows.length === this.page_size) {
flag = true;
} else {
flag = false;
}
this.flag = flag;
request(apiArr.getPayOrderList, "POST", { // 如果是第一页,直接替换数据;如果是加载更多,追加数据
room_id: this.currentRoom.room_id, if (this.page_num === 1) {
page_num: this.page_num, this.payOrderList = res.rows || [];
page_size: this.page_size, } else {
}).then((res) => { this.payOrderList = [...this.payOrderList, ...(res.rows || [])];
console.log(res); }
let flag = false; resolve();
if (res.rows && res.rows.length == this.page_size) { }).catch((error) => {
flag = true; reject(error);
} else { });
flag = false;
}
this.flag = flag;
this.payOrderList = res.rows;
}); });
}, },
//物业公积金详情 //物业费详情
more(item) { more(item) {
NavgateTo(`../providentFund/index?item=${JSON.stringify(item)}`); NavgateTo(`../providentFund/index?item=${JSON.stringify(item)}`);
}, },

View File

@ -8,9 +8,9 @@
:autoBack="true" :autoBack="true"
/> />
<view class="container_body" :style="{ paddingTop: top + 'px' }"> <view class="container_body" :style="{ paddingTop: top + 'px' }">
<view class="title">物业公积金</view> <view class="title">物业费</view>
<view class="title_bottom"> <view class="title_bottom">
<view>¥{{ moeny }}</view> <view>¥{{ getTotal(list.owners) }}</view>
<u-icon <u-icon
name="info-circle" name="info-circle"
size="30rpx" size="30rpx"
@ -49,7 +49,7 @@
</view> </view>
<view class="item"> <view class="item">
<view class="label fix"> <view class="label fix">
<text>物业费公积金总余额</text> <text>物业费总余额</text>
<u-icon <u-icon
name="info-circle-fill" name="info-circle-fill"
size="30rpx" size="30rpx"
@ -124,8 +124,8 @@ export default {
moeny: "0.00", moeny: "0.00",
show: false, show: false,
ownerDesc: ownerDesc:
"本房产的物业公积金为该房产的所有成员物业公积金总和。无需经过成员同意便可用于本房产的物业费抵扣,一旦成功抵扣,成员所拥有的物业公积金将自动进行扣除。", "本房产的物业费为该房产的所有成员物业费总和。无需经过成员同意便可用于本房产的物业费抵扣,一旦成功抵扣,成员所拥有的物业费将自动进行扣除。",
desc: "物业公积金可通用至您加入的所有房产,任一房产的物业相关费用均可用该物业公积金抵扣。", desc: "物业费可通用至您加入的所有房产,任一房产的物业相关费用均可用该物业费抵扣。",
defaultName: "", defaultName: "",
list: [], list: [],
houseList: [], houseList: [],
@ -155,6 +155,10 @@ export default {
}, },
methods: { methods: {
// 计算总金额
getTotal(owners) {
return owners.reduce((total, owner) => total + owner.property_fund_balance, 0).toFixed(2);
},
headerConfirmClick(item) { headerConfirmClick(item) {
this.defaultName = { this.defaultName = {
...item, ...item,
@ -215,7 +219,7 @@ export default {
}); });
}, },
goPay() { goPay() {
NavgateTo("../propertyPayment/index"); NavgateTo("../propertyPayment/index?item=" + encodeURIComponent(JSON.stringify(this.defaultName)));
}, },
}, },
}; };

View File

@ -96,7 +96,7 @@ export default {
}, },
{ {
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_serverIcon5.png", icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_serverIcon5.png",
name: "物业公积金", name: "物业费",
url: "" url: ""
}, },
{ {
@ -106,7 +106,7 @@ export default {
}, },
{ {
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_serverIcon7.png", icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_serverIcon7.png",
name: "物业公积金", name: "物业费",
url: "" url: ""
}, },
{ {

View File

@ -0,0 +1,160 @@
page{
background-color: #f6f7fb;
}
/* 切换客服页面样式 */
.change-service-container {
display: flex;
flex-direction: column;
}
/* 头部 */
.change-service-header {
display: flex;
align-items: center;
justify-content: space-between;
height: 50px;
padding: 0 15px;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding-bottom: 15rpx;
}
.back-btn {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
}
.page-title {
font-size: 16px;
font-weight: 500;
color: #333;
}
.empty-header {
width: 40px;
}
/* 客服列表 */
.service-list {
flex: 1;
padding: 10px;
overflow-y: auto;
}
/* 加载状态 */
.loading {
display: flex;
align-items: center;
justify-content: center;
height: 100px;
font-size: 14px;
color: #999;
}
/* 空状态 */
.empty-service {
display: flex;
align-items: center;
justify-content: center;
height: 200px;
font-size: 14px;
color: #999;
}
/* 客服项 */
.service-item {
display: flex;
align-items: center;
padding: 15px;
margin-bottom: 10px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.service-item:active {
background-color: #f0f0f0;
}
.service-item.selected {
border: 2px solid #07c160;
}
/* 客服头像 */
.service-avatar {
width: 60px;
height: 60px;
border-radius: 50%;
margin-right: 15px;
}
/* 客服信息 */
.service-info {
flex: 1;
}
.service-name {
display: block;
font-size: 16px;
font-weight: 500;
color: #333;
margin-bottom: 5px;
}
.service-desc {
font-size: 14px;
color: #666;
line-height: 1.4;
}
/* 选中图标 */
.selected-icon {
margin-left: 10px;
}
/* 确认按钮区域 */
.confirm-section {
padding: 15px;
background-color: #fff;
border-top: 1px solid #eee;
}
.confirm-btn {
width: 100%;
height: 45px;
background-color: #07c160;
color: #fff;
font-size: 16px;
border-radius: 25px;
display: flex;
align-items: center;
justify-content: center;
}
.confirm-btn:disabled {
background-color: #ccc;
color: #fff;
}
/* 滚动条样式 */
.service-list::-webkit-scrollbar {
width: 6px;
}
.service-list::-webkit-scrollbar-track {
background-color: #f1f1f1;
border-radius: 3px;
}
.service-list::-webkit-scrollbar-thumb {
background-color: #c1c1c1;
border-radius: 3px;
}
.service-list::-webkit-scrollbar-thumb:hover {
background-color: #a8a8a8;
}

View File

@ -0,0 +1,117 @@
<template>
<view class="change-service-container">
<view :style="{ paddingTop: top + 'px', height: localHeight + 'px' }" class="change-service-header">
<view class="back-btn" @tap="goBack">
<uni-icons color="#333" size="28" type="left"></uni-icons>
</view>
<view class="page-title">选择客服</view>
<view class="empty-header"></view>
</view>
<!-- 客服列表 -->
<view class="service-list">
<view v-if="isLoading" class="loading">加载中...</view>
<view v-else-if="serviceList.length === 0" class="empty-service">暂无客服</view>
<view v-else>
<view v-for="service in serviceList" :key="service.id">
<view class="service-item" @tap="confirmChange(service)">
<image :src="service.employee_image" class="service-avatar" mode="aspectFill"></image>
<view class="service-info">
<text class="service-name">{{ service.employee_name }}</text>
<text class="service-desc">{{ service.expertise || '专业客服为您服务' }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { menuButtonInfo, picUrl, request } from '@/utils'
import { apiArr } from '@/api/customerService'
export default {
data(){
return {
localHeight: '',
top: '',
// 客服列表
serviceList: [],
// 是否加载中
isLoading: false,
// 当前选中的客服ID
selectedServiceId: ''
}
},
onLoad(options){
const meun = menuButtonInfo()
this.top = meun.top
this.localHeight = meun.height
// 从选项中获取当前选中的客服ID(如果有)
if (options.currentMchId) {
this.selectedServiceId = options.currentMchId
}
// 加载客服列表
this.loadServiceList()
},
methods: {
// 加载客服列表
async loadServiceList(){
try {
this.isLoading = true
request(apiArr.csGetMchContactList, 'POST', {
mch_id: uni.getStorageSync('merchantInfo').id
}).then((res) => {
if (res.rows && res.rows.length > 0) {
res.rows.map(item => {
item.employee_image = picUrl + item.employee_image
})
this.serviceList = res.rows
} else {
console.log('没有获取到客服列表数据')
}
})
} catch (error) {
console.error('加载客服列表失败', error)
} finally {
this.isLoading = false
}
},
// 选择客服
selectService(service){
this.selectedServiceId = service.mchId
},
// 确认切换客服
confirmChange(item){
if (!item) {
uni.showToast({
title: '请选择客服',
icon: 'none'
})
return
}
// 存储当前聊天对象的信息
// uni.setStorageSync('currentChatTarget', item);
item.type = 1
// 跳转到聊天页面
uni.navigateTo({
url: '/packages/customerService/index/index?item=' + JSON.stringify(item)
})
},
// 返回上一页
goBack(){
uni.navigateBack()
}
}
}
</script>
<style>
@import url("./index.css");
</style>

View File

@ -0,0 +1,136 @@
/* 聊天记录页面样式 */
page{
background-color: #f6f7fb;
}
/* 聊天记录容器 */
.chatting-records-container {
display: flex;
flex-direction: column;
background-color: #f6f7fb;
}
/* 聊天记录头部 */
.records-header {
height: 50px;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
font-weight: 500;
color: #333;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
/* 聊天记录列表 */
.records-list {
flex: 1;
padding: 10px;
overflow-y: auto;
}
/* 加载状态 */
.loading {
display: flex;
align-items: center;
justify-content: center;
height: 100px;
font-size: 14px;
color: #999;
}
/* 空状态 */
.empty-records {
display: flex;
align-items: center;
justify-content: center;
height: 200px;
font-size: 14px;
color: #999;
}
/* 聊天记录项 */
.record-item {
display: flex;
padding: 12px;
margin-bottom: 10px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.record-item:active {
background-color: #f0f0f0;
}
/* 头像 */
.record-avatar {
width: 50px;
height: 50px;
border-radius: 50%;
margin-right: 12px;
}
/* 记录信息 */
.record-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 50px;
}
/* 标题行 */
.record-title-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 4px;
}
/* 标题 */
.record-title {
font-size: 15px;
font-weight: 500;
color: #333;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-right: 8px;
}
/* 时间 */
.record-time {
font-size: 12px;
color: #999;
}
/* 最后一条消息 */
.record-last-msg {
font-size: 14px;
color: #666;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 滚动条样式 */
.records-list::-webkit-scrollbar {
width: 6px;
}
.records-list::-webkit-scrollbar-track {
background-color: #f1f1f1;
border-radius: 3px;
}
.records-list::-webkit-scrollbar-thumb {
background-color: #c1c1c1;
border-radius: 3px;
}
.records-list::-webkit-scrollbar-thumb:hover {
background-color: #a8a8a8;
}

View File

@ -0,0 +1,123 @@
<template>
<view class="chatting-records-container">
<!-- 聊天记录列表 -->
<view class="records-list">
<view v-if="isLoading" class="loading">加载中...</view>
<view v-else-if="recordsList.length === 0" class="empty-records">暂无聊天记录</view>
<view v-else>
<view v-for="record in recordsList" :key="record.id">
<view class="record-item" @tap="goToChatPage(record)">
<image :src="getAvatarUrl(record)" class="record-avatar" mode="aspectFill"></image>
<view class="record-info">
<view class="record-title-row">
<text class="record-title">{{ record.contact_name }}</text>
<text class="record-time">{{ record.update_time }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { menuButtonInfo, picUrl, request } from '../../../utils'
import { apiArr } from '../../../api/customerService'
export default {
data(){
return {
// 聊天记录列表
recordsList: [],
// 是否加载中
isLoading: false,
page_num: 1,
page_size: 10,
itemObj: {},
merchantId: ''
}
},
onLoad(options){
this.merchantId = JSON.parse(options.merchant_id)
},
onShow(){
// 页面显示时重新加载聊天记录
this.loadChattingRecords()
},
methods: {
// 加载聊天记录列表
async loadChattingRecords(){
try {
this.isLoading = true
// 获取聊天记录列表
request(apiArr.csGetMsgList, 'POST', {
open_id: uni.getStorageSync('openId'),
page_num: this.page_num,
page_size: this.page_size
}).then((res) => {
this.recordsList = res.msg_list.filter(item => item.client_id_one !== item.client_id_two && item.mch_id == this.merchantId)
})
} catch (error) {
console.error('加载聊天记录失败', error)
} finally {
this.isLoading = false
}
},
getAvatarUrl(record){
if(record.client_id_one == uni.getStorageSync('openId')){
return record.two.avatar ? picUrl + record.two.avatar : 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/defaultTx.png'
}else{
return record.one.avatar ? picUrl + record.one.avatar : 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/defaultTx.png'
}
},
// 格式化时间
formatTime(time){
const date = new Date(time)
const now = new Date()
const diff = now - date
// 小于1分钟显示"刚刚"
if (diff < 60 * 1000) {
return '刚刚'
}
// 小于1小时显示"XX分钟前"
if (diff < 60 * 60 * 1000) {
return Math.floor(diff / (60 * 1000)) + '分钟前'
}
// 小于24小时显示"XX小时前"
if (diff < 24 * 60 * 60 * 1000) {
return Math.floor(diff / (60 * 60 * 1000)) + '小时前'
}
// 小于7天显示"XX天前"
if (diff < 7 * 24 * 60 * 60 * 1000) {
return Math.floor(diff / (24 * 60 * 60 * 1000)) + '天前'
}
// 其他情况显示具体日期
const month = date.getMonth() + 1
const day = date.getDate()
return month + '-' + day
},
// 跳转到聊天页面
goToChatPage(record){
this.$set(record, 'type', 2)
// 跳转到聊天页面
uni.navigateTo({
url: '/packages/customerService/index/index?item=' + JSON.stringify(record)
})
}
}
}
</script>
<style>
@import url("./index.css");
</style>

View File

@ -0,0 +1,197 @@
/* 客服聊天页面样式 */
page {
background-color: #f6f7fb;
height: 100vh;
overflow: hidden;
}
/* 聊天容器 */
.chat-container {
display: flex;
flex-direction: column;
height: 100vh;
background-color: #f6f7fb;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 1;
}
/* 聊天头部 */
.chat-header {
display: flex;
align-items: center;
justify-content: space-between;
height: 50px;
padding: 0 15px;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding-bottom: 15rpx;
position: relative;
z-index: 2;
}
.back-btn {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
}
.chat-title {
font-size: 16px;
font-weight: 500;
color: #333;
}
.empty-header {
width: 40px;
}
/* 切换客服按钮 */
.change-service-btn {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
}
/* 连接状态提示 */
.connecting-status {
padding: 5px 15px;
background-color: #fff3cd;
color: #856404;
font-size: 14px;
text-align: center;
}
/* 聊天消息区域 */
.chat-messages {
width: 97%;
margin: 0 auto;
flex: 1;
padding: 10px;
overflow-y: auto;
}
/* 时间分割线 */
.message-time {
margin: 10px 0;
text-align: center;
font-size: 12px;
color: #999;
}
/* 消息项 */
.message-item {
display: flex;
margin-bottom: 15px;
align-items: flex-start;
}
.message-item.self {
flex-direction: row-reverse;
}
/* 头像 */
.message-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
margin: 0 10px;
}
/* 消息内容 */
.message-content {
max-width: 70%;
padding: 10px 15px;
border-radius: 10px;
word-break: break-word;
font-size: 15px;
line-height: 1.5;
}
.message-item.self .message-content {
background-color: #91d5ff;
color: #333;
border-bottom-right-radius: 4px;
}
.message-item.other .message-content {
background-color: #fff;
color: #333;
border-bottom-left-radius: 4px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
/* 加载状态 */
.message-item.loading .message-content {
opacity: 0.7;
}
/* 输入区域 */
.chat-input-area {
background-color: #fff;
padding: 10px 15px;
border-top: 1px solid #eee;
margin-bottom: 20rpx;
position: relative;
z-index: 2;
}
.input-container {
display: flex;
align-items: flex-end;
}
.message-input {
flex: 1;
height: 20px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 20px;
font-size: 15px;
line-height: 1.5;
resize: none;
background-color: #f9f9f9;
}
.send-btn {
margin-left: 10px;
padding: 0 20px;
height: 40px;
background-color: #07c160;
color: #fff;
font-size: 15px;
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.send-btn:disabled {
background-color: #ccc;
color: #fff;
}
/* 滚动条样式 */
.chat-messages::-webkit-scrollbar {
width: 6px;
}
.chat-messages::-webkit-scrollbar-track {
background-color: #f1f1f1;
border-radius: 3px;
}
.chat-messages::-webkit-scrollbar-thumb {
background-color: #c1c1c1;
border-radius: 3px;
}
.chat-messages::-webkit-scrollbar-thumb:hover {
background-color: #a8a8a8;
}

View File

@ -0,0 +1,517 @@
<template>
<view class="chat-container">
<!-- 聊天头部 -->
<view :style="{ paddingTop: top + 'px', height: localHeight + 'px' }" class="chat-header">
<view class="back-btn" @tap="goBack">
<uni-icons color="#333" size="28" type="left"></uni-icons>
</view>
<view class="chat-title">{{ chatTarget.title || '客服' }}</view>
<view class="change-service-btn" @tap="goToChangeService">
<uni-icons color="#333" size="22" type="switch"></uni-icons>
</view>
</view>
<!-- 连接状态提示 -->
<view v-if="connectingStatus" class="connecting-status">{{ connectingStatus }}</view>
<!-- 聊天消息区域 -->
<scroll-view :scroll-into-view="scrollToView" class="chat-messages" lower-threshold="100" scroll-y="true"
upper-threshold="100" @scrolltolower="loadMoreHistory" @scrolltoupper="loadMoreHistory">
<!-- 加载历史消息提示 -->
<view v-if="isLoadingHistory" class="message-time">加载历史消息...</view>
<!-- 消息列表 -->
<block v-for="(message, index) in messages" :key="index">
<!-- 时间分割线 -->
<view v-if="needShowTime(index)" class="message-time">{{ formatTime(message.time) }}</view>
<!-- 消息项 -->
<view :id="'msg-' + index" :class="{
'self': message.isSelf,
'other': !message.isSelf,
'loading': message.isLoading
}" class="message-item">
<image :src="message.isSelf ? userAvatar : getAvatarUrl(message)" class="message-avatar" mode="aspectFill">
</image>
<view class="message-content">
{{ message.content }}
</view>
</view>
</block>
</scroll-view>
<!-- 输入区域 -->
<view class="chat-input-area">
<view class="input-container">
<textarea v-model="inputMessage" :adjust-position="true" auto-height class="message-input" cursor-spacing="10"
enable-keyboard-accessory-view="true" hold-keyboard="true" maxlength="500" placeholder="请输入消息..."
@blur="onInputBlur" @confirm="sendMessage" @focus="onInputFocus" @input="handleInput"></textarea>
<button :disabled="inputMessage.trim() === ''" class="send-btn" @tap="sendMessage">
发送
</button>
</view>
</view>
</view>
</template>
<script>
import { menuButtonInfo, picUrl, request } from '@/utils'
import { apiArr } from '@/api/customerService'
import mqttTool from '@/utils/mqtt'
export default {
data() {
return {
localHeight: '',
top: '',
// 聊天目标信息
chatTarget: {
mchId: '',
bindId: 0,
title: '',
avatar: '',
openId: '' // 接收方的open_id
},
// 用户头像
userAvatar: '',
// 消息列表
messages: [],
// 输入的消息
inputMessage: '',
// 是否可以发送消息
canSend: false,
// 连接状态
isConnected: false,
// 连接状态文本
connectingStatus: '',
// 滚动到指定视图
scrollToView: '',
// 是否加载历史消息
isLoadingHistory: false,
// 心跳包定时器
keepaliveTimer: null,
selfClientId: uni.getStorageSync('openId'),
// MQTT工具实例
client: null,
// 重连失败提示定时器
reconnectFailedTimer: null,
// 分页参数
pageNum: 1,
pageSize: 10,
// 是否还有更多历史消息
hasMoreHistory: true,
// 滚动到底部的标记
scrollToBottomFlag: false
}
},
onLoad(options) {
const meun = menuButtonInfo()
this.top = meun.top
this.localHeight = meun.height
// 获取聊天对象信息
if (options.item) {
const item = JSON.parse(options.item)
console.log('参数接收:', item)
if (Number(item.type) === 1) {
// 客户选择客服跳转进来
this.chatTarget = item
console.log('客户找客服跳转:', this.chatTarget)
this.chatTarget.title = this.chatTarget.employee_name
this.getMqttConfig().then(() => {
// 获取配置后再初始化聊天
this.initChat()
})
} else {
// 客服选择聊天列表进来
this.chatTarget = item
console.log('客服找客户进来:', this.chatTarget)
this.chatTarget.title = this.chatTarget.server_name
this.chatTarget.bindId = this.chatTarget.id
if (this.chatTarget.client_id_one === this.selfClientId) {
this.chatTarget.openId = this.chatTarget.client_id_two
} else {
this.chatTarget.openId = this.chatTarget.client_id_one
}
// 初始化MQTT连接
this.initChat()
}
}
// 初始化用户头像
this.userAvatar = picUrl + uni.getStorageSync('headPhoto')
},
onShow() {
},
methods: {
getAvatarUrl(record) {
return this.chatTarget.employee_image ? this.chatTarget.employee_image : 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/defaultTx.png'
},
async connect() {
this.client = null
const options = {
clientId: this.selfClientId
}
// 添加连接状态回调
const callbacks = {
onConnect: () => {
console.log('客服连接成功')
this.isConnected = true
this.connectingStatus = ''
},
onDisconnect: this.onDisconnect.bind(this),
onError: (error) => {
console.error('客服连接错误:', error)
this.isConnected = false
this.connectingStatus = '连接错误,请重试'
},
onReconnect: () => {
console.log('客服正在重连...')
this.isConnected = false
this.connectingStatus = '连接已断开,正在重连...'
}
}
this.client = mqttTool.connect(options, callbacks)
this.isConnected = !!this.client
await this.subscribe()
this.client.on('message', (topic, message) => {
const msgStr = Buffer.from(message).toString('utf8') // 二进制转UTF-8字符串
const msg = JSON.parse(msgStr) // 后续解析逻辑不变
let jsMsg = msg // 直接使用已解析的对象,无需再次解析
console.log('收到消息', topic, msg)
if (jsMsg.send_client === this.selfClientId || jsMsg.receive_client === this.selfClientId) {
console.log('接收或发送人是我')
if (jsMsg.send_client === this.chatTarget.openId || jsMsg.receive_client === this.chatTarget.openId) {
console.log('接收或发送人是我的聊天对象')
this.messages.push({
content: jsMsg.content,
time: Date.now(),
isSelf: jsMsg.send_client === this.selfClientId,
isLoading: false
})
console.log('收到我的消息', this.messages)
this.scrollToView = 'msg-' + (this.messages.length - 1)
}
}
})
},
async subscribe() {
if (this.isConnected && this.client) {
this.client.subscribe('contact/message/receive_msg', { qos: 0 }, (err) => {
if (!err) {
console.log('订阅成功', 'contact/message/receive_msg', { qos: 0 })
this.connectingStatus = ''
} else {
console.log('订阅失败:', err)
this.connectingStatus = '订阅失败,请重试'
}
})
} else {
console.log('连接失败', this.isConnected, this.client)
this.connectingStatus = '连接失败,请重试'
}
},
// 初始化聊天
async initChat() {
try {
// 显示连接状态
this.connectingStatus = '正在连接客服...'
await this.connect()
// 连接成功后启动心跳包
this.startKeepalive()
// 连接成功后立即加载历史消息
await this.loadHistoryMessages()
} catch (error) {
console.error('初始化聊天失败', error)
this.connectingStatus = '连接失败,请检查网络'
// 失败后尝试重新连接
this.reconnectFailedTimer = setTimeout(() => {
this.initChat()
}, 3000)
}
},
// 获取MQTT连接配置
async getMqttConfig() {
console.log('🚀 ~ onLoad ~ this.chatTarget.open_id:', this.chatTarget.open_id)
try {
// 如果没有已创建的实例或clientId,则通过API获取
return new Promise((resolve, reject) => {
const params = {
worker_id: this.chatTarget.id || '',
open_id: this.selfClientId || ''
}
request(apiArr.csGetToClientId, 'POST', params).then((res) => {
console.log('聊天列表:', res)
// 检查响应数据格式是否正确
if (res && res.client_bind && res.client_bind.client_id_one && res.client_bind.client_id_two) {
if (res.client_bind.client_id_one === this.selfClientId) {
this.chatTarget.openId = res.client_bind.client_id_two
} else {
this.chatTarget.openId = res.client_bind.client_id_one
}
this.chatTarget.bindId = res.client_bind.id
resolve()
} else {
console.error('MQTT配置响应格式不正确:', res)
reject(new Error('未获取到有效的MQTT配置'))
}
}).catch(error => {
console.error('获取MQTT配置失败', error)
reject(error)
})
})
} catch (error) {
console.error('获取MQTT配置失败', error)
throw error
}
},
// MQTT断开连接回调
onDisconnect(packet) {
console.log('MQTT连接断开', packet)
this.isConnected = false
this.client = null
// 根据断开原因设置不同的连接状态文本
if (packet && packet.error) {
// 连接失败的情况
this.connectingStatus = '连接失败,请检查网络'
} else {
// 其他断开连接的情况
this.connectingStatus = '连接已断开,正在重连...'
}
// 停止心跳包
this.stopKeepalive()
},
// 加载历史消息
async loadHistoryMessages() {
if (!this.hasMoreHistory || this.isLoadingHistory) {
return
}
try {
this.isLoadingHistory = true
// 确保已经获取了mqttConfig.bindId
if (!this.chatTarget.bindId) {
await this.getMqttConfig()
}
const params = {
bindId: this.chatTarget.bindId,
order: 'desc', // 按时间降序排列
page_num: this.pageNum,
page_size: this.pageSize
}
console.log('请求历史消息参数:', params)
const res = await request(apiArr.csGetMsgRecord, 'POST', params)
console.log('历史消息返回结果:', res)
if (res && res.code === 1 && res.data && res.data.msg_record) {
const historyMessages = res.data.msg_record
// 如果没有更多历史消息了
if (historyMessages.length === 0) {
this.hasMoreHistory = false
return
}
// 处理历史消息,转换为需要的格式
const formattedMessages = historyMessages.map(msg => ({
content: msg.content,
time: new Date(msg.create_time).getTime(),
isSelf: msg.send_client === this.selfClientId, // 修正判断条件
isLoading: false
})).reverse(); // 反转消息顺序,确保最早的消息在最前面
// 将格式化后的历史消息添加到消息列表开头
this.messages = [...formattedMessages, ...this.messages]
// 增加页码
this.pageNum++
}
} catch (error) {
console.error('加载历史消息失败', error)
} finally {
this.isLoadingHistory = false
}
},
// 加载更多历史消息
loadMoreHistory(e) {
// 当滚动到顶部时加载更多历史消息
if (e && e.detail.direction === 'top') {
if (!this.isLoadingHistory && this.hasMoreHistory) {
this.loadHistoryMessages()
}
}
},
// 发送消息
sendMessage() {
const content = this.inputMessage.trim()
console.log('发送消息', content)
if (!content || !this.client || !this.isConnected) return
// 滚动到底部
this.scrollToBottom()
console.log('需要发送的对象', this.chatTarget)
// 按照用户提供的格式构建发送消息
const msgData = {
bind_id: this.chatTarget.bindId, // 聊天列表的ID
send_client: this.selfClientId, // 消息发送方open_id
receive_client: this.chatTarget.openId, // 消息接收方open_id
type: 1, // 消息类型,1表示文字消息
content: content, // 消息内容
receive_read_status: 2 // 接收方阅读状态
}
console.log('发送消息', msgData)
this.client.publish(
'contact/message/send_msg', // 使用指定的发送消息主题
JSON.stringify(msgData),
{ Qos: 0 },
(err) => {
if (err) {
console.error('发送消息失败', err)
// 可以在这里添加消息发送失败的处理逻辑
} else {
console.log('发送消息成功')
}
}
)
// 清空输入框
this.inputMessage = ''
},
// 处理输入事件
handleInput() {
this.canSend = this.inputMessage.trim().length > 0
},
onInputFocus() {
// 输入框获取焦点时,设置滚动到底部的标记
this.scrollToBottomFlag = true
setTimeout(() => {
if (this.scrollToBottomFlag) {
this.scrollToBottom()
}
}, 300)
},
onInputBlur() {
// 输入框失去焦点时,重置滚动标记
this.scrollToBottomFlag = false
},
// 是否需要显示时间分割线
needShowTime(index) {
if (index === 0) return true
const currentMsg = this.messages[index]
const prevMsg = this.messages[index - 1]
// 如果两条消息间隔超过5分钟,则显示时间分割线
return (currentMsg.time - prevMsg.time) > 5 * 60 * 1000
},
// 格式化时间
formatTime(time) {
const date = new Date(time)
const hours = date.getHours().toString().padStart(2, '0')
const minutes = date.getMinutes().toString().padStart(2, '0')
return `${hours}:${minutes}`
},
// 滚动到底部
scrollToBottom() {
setTimeout(() => {
this.scrollToView = 'msg-' + (this.messages.length - 1)
}, 100)
},
// 返回上一页
goBack() {
uni.navigateBack()
},
// 启动心跳包 - 增强版:添加错误处理和状态检查
startKeepalive() {
// 停止之前的定时器
this.stopKeepalive()
// 每30秒发送一次心跳包
this.keepaliveTimer = setInterval(() => {
if (this.client && this.isConnected) {
const keepaliveData = {
client_id: this.selfClientId // 自己的client_id
}
this.client.publish(
'contact/message/keep_time',
JSON.stringify(keepaliveData),
{},
(err) => {
if (err) {
console.error('发送心跳包失败', err)
// 心跳包发送失败可能表示连接有问题,可以考虑触发重连
if (!this.isConnected) {
return
}
console.log('心跳包发送失败,尝试检查连接状态')
// 这里可以添加额外的连接检查逻辑
}
}
)
} else {
console.warn('MQTT未连接,停止心跳包')
this.stopKeepalive()
}
}, 30000)
},
// 停止心跳包
stopKeepalive() {
if (this.keepaliveTimer) {
clearInterval(this.keepaliveTimer)
this.keepaliveTimer = null
}
},
// 跳转到切换客服页面
goToChangeService() {
uni.navigateTo({
url: '/packages/customerService/changeService/index?currentMchId=' + this.chatTarget.mchId
})
}
},
// 页面卸载时停止心跳包
onUnload() {
// 断开MQTT连接
if (this.client) {
this.client.end()
}
// 停止心跳包
this.stopKeepalive()
// 清除重连失败提示定时器
if (this.reconnectFailedTimer) {
clearTimeout(this.reconnectFailedTimer)
this.reconnectFailedTimer = null
}
}
}
</script>
<style>
@import url("./index.css");
</style>

View File

@ -393,4 +393,78 @@
.toUp image { .toUp image {
width: 100%; width: 100%;
height: 100%; height: 100%;
}
/* swiperBox 样式 - 与 localLife 页面保持一致 */
/* swiperBox 样式 - 每行展示5个,平均分配空间 */
.swiperBox {
height: 350rpx;
width: 100%;
position: relative;
}
.swiper {
height: 350rpx;
width: 100%;
}
.navList {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
height: 350rpx;
width: 100%;
padding: 30rpx 20rpx;
background-color: #fff;
margin-top: 20rpx;
}
.navItem {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 20%; /* 每行5个,平均分配宽度 */
height: 105rpx;
margin-bottom: 43rpx;
box-sizing: border-box;
}
.navItemImg {
width: 70rpx;
height: 70rpx;
display: flex;
justify-content: center;
align-items: center;
}
.navItem image {
width: 70rpx;
height: 70rpx;
}
.dot {
display: flex;
align-items: center;
justify-content: center;
margin-top: 20rpx;
position: absolute;
left: 50%;
bottom: 25rpx;
transform: translateX(-50%);
}
.dotItem {
width: 8rpx;
height: 8rpx;
border-radius: 50%;
background-color: #E6E6E6;
margin-right: 5rpx;
}
.actives {
width: 20rpx;
height: 8rpx;
background: #FF370B;
border-radius: 10rpx 10rpx 10rpx 10rpx;
} }

View File

@ -13,25 +13,30 @@
<u-icon name="arrow-down" color="#999999" size="28"></u-icon> <u-icon name="arrow-down" color="#999999" size="28"></u-icon>
</view> </view>
<view class="search-box" @click="searchService"> <view class="search-box" @click="searchService">
<image <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png" class="search-icon" mode="aspectFit"></image>
class="search-icon"
mode="aspectFit"
></image>
<text class="search-placeholder">请输入您要找的服务</text> <text class="search-placeholder">请输入您要找的服务</text>
</view> </view>
</view> </view>
<!-- 服务分类 --> <!-- 服务分类 - 修改为 swiper 形式 -->
<view class="service-category"> <view class="swiperBox">
<view <swiper class="swiper" @change="swiperChange" :current="currentIndex">
class="category-item" <swiper-item v-for="(page, pageIndex) in swiperList" :key="pageIndex">
v-for="(item, index) in serviceCategories" <view class="navList">
:key="index" <view class="navItem" v-for="(item, itemIndex) in page" :key="itemIndex" @click="changeNav(item)">
@click="navigateToService(item)" <view class="navItemImg">
> <image :src="picUrl + item.cate_image" mode="widthFix"></image>
<image :src="item.icon" class="category-icon"></image> </view>
<text class="category-name">{{ item.name }}</text> <view class="navName">{{ item.cate_name }}</view>
</view>
</view>
</swiper-item>
</swiper>
<view class="dot">
<view class="dotItem" v-for="(page, index) in swiperList" :key="index"
:class="currentIndex == index ? 'actives' : ''"></view>
</view> </view>
</view> </view>
@ -40,41 +45,29 @@
<view class="announcement-flex"> <view class="announcement-flex">
到家 到家
<text class="announcement-title"> 公告</text> <text class="announcement-title"> 公告</text>
<image <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_notice1.png"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_notice1.png" class="announcement-img" mode="aspectFit"></image>
class="announcement-img"
mode="aspectFit"
></image>
</view> </view>
<view class="hrStyle">|</view> <view class="hrStyle">|</view>
<text class="announcement-content" <text class="announcement-content">公告内容公告内容公告内容公告内容...</text>
>公告内容公告内容公告内容公告内容...</text <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_notice2.png"
> class="arrow-right" @click="lookNotice" mode="aspectFit"></image>
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_notice2.png"
class="arrow-right"
@click="lookNotice"
mode="aspectFit"
></image>
</view> </view>
<!-- 广告横幅 --> <!-- 广告横幅 -->
<view class="serverList"> <view class="serverList">
<view class="serverList_left"> <view class="serverList_left">
<!-- <view> --> <!-- <view> -->
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/guanggao1.png" mode="aspectFit"/> <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/guanggao1.png"
mode="aspectFit" />
<!-- <swiper-item v-for="(item, index) in homeLeftList" :key="index"> <!-- <swiper-item v-for="(item, index) in homeLeftList" :key="index">
<image :src="item.pic_src" alt="" mode="aspectFit" /> <image :src="item.pic_src" alt="" mode="aspectFit" />
</swiper-item> --> </swiper-item> -->
<!-- </view> --> <!-- </view> -->
</view> </view>
<view class="serverList_right"> <view class="serverList_right">
<view <view :class="['serverItem', `serverItem${index + 1}`]" @tap="headerServerClick(item)"
:class="['serverItem', `serverItem${index + 1}`]" v-for="(item, index) in homeRightList" :key="index">
@tap="headerServerClick(item)"
v-for="(item, index) in homeRightList"
:key="index"
>
<image :src="item.pic_src" mode="" /> <image :src="item.pic_src" mode="" />
</view> </view>
</view> </view>
@ -82,49 +75,35 @@
<!-- 立即联系 --> <!-- 立即联系 -->
<view class="contact-section" @click="contactService"> <view class="contact-section" @click="contactService">
<image <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_kefu1.png"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_kefu1.png" class="contact-icon"></image>
class="contact-icon"
></image>
<view class="contact-text"> <view class="contact-text">
<text class="contact-title">立即联系</text> <text class="contact-title">立即联系</text>
<br /> <br />
<text class="contact-subtitle">未找到您需要的服务?</text> <text class="contact-subtitle">未找到您需要的服务?</text>
</view> </view>
<image <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_kefu2.png"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_kefu2.png" class="contact-icon2"></image>
class="contact-icon2"
></image>
</view> </view>
<view class="interval"></view> <view class="interval"></view>
<!-- 推荐热门服务 --> <!-- 推荐热门服务 -->
<view class="hot-services"> <view class="hot-services">
<view class="section-header"> <view class="section-header">
<image <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_bottom1.png"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_bottom1.png" class="section-arrow"></image>
class="section-arrow"
></image>
<text class="section-title">推荐热门服务</text> <text class="section-title">推荐热门服务</text>
</view> </view>
<view class="service-list"> <view class="service-list">
<view <view class="service-card" v-for="(service, index) in hotServiceList" :key="index">
class="service-card" <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/ceshi.png"
v-for="(service, index) in hotServiceList" class="service-image"></image>
:key="index"
>
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/ceshi.png"
class="service-image"
></image>
<view class="service-info"> <view class="service-info">
<view class="service-info-left"> <view class="service-info-left">
<view class="service-info-left-top"> <view class="service-info-left-top">
<text class="service-name">{{ service.name }}</text> <text class="service-name">{{ service.name }}</text>
<image <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_bottom2.png"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_bottom2.png" class="service-image2"></image>
class="service-image2"
></image>
<text class="service-tag">{{ service.tag }}</text> <text class="service-tag">{{ service.tag }}</text>
</view> </view>
<br /> <br />
@ -132,10 +111,7 @@
</view> </view>
<view class="service-info-right"> <view class="service-info-right">
<view class="service-footer"> <view class="service-footer">
<view <view class="service-button" @click="navigateToReservation(service)">
class="service-button"
@click="navigateToReservation(service)"
>
<text class="button-text">去预约</text> <text class="button-text">去预约</text>
</view> </view>
<text class="service-count">{{ service.count }}</text> <text class="service-count">{{ service.count }}</text>
@ -150,12 +126,7 @@
<!-- 回到顶部 --> <!-- 回到顶部 -->
<div class="toUp" @click="scrollToTop"> <div class="toUp" @click="scrollToTop">
<u-badge <u-badge numberType="limit" type="error" max="99" :value="value"></u-badge>
numberType="limit"
type="error"
max="99"
:value="value"
></u-badge>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/toUp.png"></image> <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/toUp.png"></image>
</div> </div>
</view> </view>
@ -168,7 +139,7 @@ import {
NavgateTo, NavgateTo,
menuButtonInfo, menuButtonInfo,
} from "../../../utils/index"; } from "../../../utils/index";
import { apiArr } from "../../../api/reservation"; import { apiArr } from "../../../api/v2local";
import nav from "../../../components/nav/nav"; import nav from "../../../components/nav/nav";
export default { export default {
@ -177,51 +148,13 @@ export default {
}, },
data() { data() {
return { return {
picUrl,
// 当前位置 // 当前位置
currentLocation: "衡水市桃城区", currentLocation: "衡水市桃城区",
// 服务分类数据 // 服务分类数据
serviceCategories: [ serviceCategories: [],
{ swiperList: [],
name: "家电维修", currentIndex: 0,
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_top1.png",
},
{
name: "数码维修",
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_top2.png",
},
{
name: "电器清洗",
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_top3.png",
},
{
name: "洗衣洗鞋",
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_top4.png",
},
{
name: "精细擦窗",
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_top5.png",
},
{
name: "整理收纳",
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_top6.png",
},
{
name: "家庭保姆",
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_top7.png",
},
{
name: "母婴服务",
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_top8.png",
},
{
name: "管道疏通",
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_top9.png",
},
{
name: "家庭保洁",
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/index_top10.png",
},
],
homeLeftList: [ homeLeftList: [
{ {
title: "", title: "",
@ -252,6 +185,30 @@ export default {
}; };
}, },
methods: { methods: {
// 获取服务分类
async getServiceCategories() {
const that = this;
const params = {
isShop: 2
}
const res = await request(apiArr.getMerChantCateList, "POST", params, { silent: true });
// 过滤出可见的分类
res.rows = res.rows.filter((item) => item.is_visible == 1);
// 将数据分成每10个一组
const chunkSize = 10;
that.swiperList = [];
for (let i = 0; i < res.rows.length; i += chunkSize) {
that.swiperList.push(res.rows.slice(i, i + chunkSize));
}
},
// swiper 切换事件
swiperChange(e) {
this.currentIndex = e.detail.current;
},
// 导航到分类页面
changeNav(item) {
NavgateTo(`/packages/localLife/classify/index?item=${JSON.stringify(item)}`);
},
// 选择位置 // 选择位置
chooseLocation() { chooseLocation() {
// uni.navigateTo({ // uni.navigateTo({
@ -264,7 +221,7 @@ export default {
// url: "/packages/homeServer/search/index", // url: "/packages/homeServer/search/index",
// }); // });
}, },
// 导航到服务详情 // 导航到服务详情(保留原方法但修改为与changeNav一致)
navigateToService(item) { navigateToService(item) {
// uni.navigateTo({ // uni.navigateTo({
// url: "/packages/homeServer/classify/index", // url: "/packages/homeServer/classify/index",
@ -309,6 +266,7 @@ export default {
}, },
onLoad() { onLoad() {
this.getCurrentLocation(); this.getCurrentLocation();
this.getServiceCategories();
}, },
}; };
</script> </script>

View File

@ -1,40 +1,40 @@
<template> <template>
<div class="container"> <view class="container">
<div class="Msg"> <view class="Msg">
<div class="Msg_Tit"> <view class="Msg_Tit">
<div class="Msg_Tit_left"> <view class="Msg_Tit_left">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/user_ava.png" <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/user_ava.png"
v-if="!info.user.avatar" mode="aspectFill"> v-if="!info.user.avatar" mode="aspectFill">
</image> </image>
<image :src="picUrl + info.user.avatar" v-if="info.user.avatar" mode="aspectFill"></image> <image :src="picUrl + info.user.avatar" v-if="info.user.avatar" mode="aspectFill"></image>
{{ info.user.nick_name }} {{ info.user.nick_name }}
</div> </view>
<div class="Msg_Tit_right"> <view class="Msg_Tit_right">
<image v-for="(item, index) in 5" :key="index" <image v-for="(item, index) in 5" :key="index"
:src="indez < info.satisfaction ? 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_start1.png' : 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_start2.png'" :src="index < info.satisfaction ? 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_start1.png' : 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_start2.png'"
mode="aspectFill"></image> mode="aspectFill"></image>
</div> </view>
</div> </view>
<div class="Msg_con"> <view class="Msg_con">
{{ info.comment }} {{ info.comment }}
<div class="Msg_con_img" v-if="info.image_url"> <view class="Msg_con_img" v-if="info.image_url">
<image v-for="(img, index) in info.image_url.split(',')" :key="index" :src="picUrl + img" <image v-for="(img, index) in info.image_url.split(',')" :key="index" :src="picUrl + img"
mode="aspectFill"></image> mode="aspectFill"></image>
<video class="Msg_con_video" v-if="info.video_url" :src="picUrl + info.video_url" controls></video> <video class="Msg_con_video" v-if="info.video_url" :src="picUrl + info.video_url" controls></video>
</div> </view>
</div> </view>
<div class="Msg_iconList"> <view class="Msg_iconList">
<div class="Msg_iconList_left"> <view class="Msg_iconList_left">
<div class="Msg_iconList_leftIcon"> <view class="Msg_iconList_leftIcon">
<image <image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_review.png" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_review.png"
mode="widthFix"></image> mode="widthFix"></image>
{{ info.merchant_evaluation_reply_list ? info.merchant_evaluation_reply_list.length : 0 }} {{ info.merchant_evaluation_reply_list ? info.merchant_evaluation_reply_list.length : 0 }}
</div> </view>
<div class="Msg_iconList_leftIcon"> <view class="Msg_iconList_leftIcon">
<image v-if="info.is_like == 2" <image v-if="info.is_like == 2"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_likeIcon.png" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_likeIcon.png"
mode="widthFix" @click="like(info)"></image> mode="widthFix" @click="like(info)"></image>
@ -42,42 +42,42 @@
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_likeIcon2.png" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_likeIcon2.png"
mode="widthFix" @click="unlike(info)"></image> mode="widthFix" @click="unlike(info)"></image>
{{ info.merchant_evaluation_like_list ? info.merchant_evaluation_like_list.length : 0 }} {{ info.merchant_evaluation_like_list ? info.merchant_evaluation_like_list.length : 0 }}
</div> </view>
</div> </view>
<div class="Msg_iconList_right"> <view class="Msg_iconList_right">
<div class="Msg_iconList_leftIcon" @click="deletes" v-if="isDelte"> <view class="Msg_iconList_leftIcon" @click="deletes" v-if="isDelte">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_del.png" <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_del.png"
mode="widthFix"></image> mode="widthFix"></image>
</div> </view>
</div> </view>
</div> </view>
<!-- 回复列表 --> <!-- 回复列表 -->
<div class="reply" v-for="(item, index) in replyList" :key="index"> <view class="reply" v-for="(item, index) in replyList" :key="index">
<div class="reply_tit"> <view class="reply_tit">
<div class="reply_tit_left"> <view class="reply_tit_left">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/user_ava.png" <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/user_ava.png"
v-if="!item.user.avatar" mode="aspectFill"> v-if="!item.user.avatar" mode="aspectFill">
</image> </image>
<image :src="picUrl + item.user.avatar" v-if="item.user.avatar" mode="aspectFill"></image> <image :src="picUrl + item.user.avatar" v-if="item.user.avatar" mode="aspectFill"></image>
{{ item.user.nick_name }} {{ item.user.nick_name }}
</div> </view>
<div class="reply_tit_right">{{ item.reply_time }}</div> <view class="reply_tit_right">{{ item.reply_time }}</view>
</div> </view>
<div class="reply_con">{{ item.reply_content }}</div> <view class="reply_con">{{ item.reply_content }}</view>
</div> </view>
</div> </view>
<div class="comment"> <view class="comment">
<div class="comment_con"> <view class="comment_con">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_send.png" <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_send.png"
mode="aspectFill"></image> mode="aspectFill"></image>
<input type="text" v-model="reply_content" placeholder="说点什么"> <input type="text" v-model="reply_content" placeholder="说点什么">
<button id="send" @click="sendComment">发送</button> <button id="send" @click="sendComment">发送</button>
</div> </view>
</div> </view>
</div> </view>
</template> </template>
<script> <script>
@ -141,7 +141,7 @@ export default {
request(apiArr.createUserReply, "POST", { request(apiArr.createUserReply, "POST", {
evaluation_id: that.info.id, evaluation_id: that.info.id,
reply_content: that.reply_content, reply_content: that.reply_content,
reply_user_type: "1" reply_user_type: 1
}).then(res => { }).then(res => {
uni.showToast({ uni.showToast({
title: "发送成功", title: "发送成功",

View File

@ -81,7 +81,7 @@
到店服务券 到店服务券
</view> --> </view> -->
<view class="line"></view> <view class="line"></view>
<view class="btn_right"> <view class="btn_right" @click="toPayInfo">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/lcoal_payIcon.png" <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/lcoal_payIcon.png"
mode="aspectFill"></image> mode="aspectFill"></image>
快捷支付记录 快捷支付记录
@ -116,8 +116,8 @@ export default {
currentIndex: 0, currentIndex: 0,
checkedItems: [false, false, false, false], checkedItems: [false, false, false, false],
address: "", address: "",
page_size: "10", page_size: 10,
page_num: "1", page_num: 1,
flag: false, flag: false,
merchatList: [], merchatList: [],
@ -145,6 +145,10 @@ export default {
}, },
methods: { methods: {
// 跳转快捷支付记录
toPayInfo(){
NavgateTo("/packages/localLife/payInfo/index")
},
back() { back() {
NavgateTo("1"); NavgateTo("1");
}, },
@ -158,7 +162,10 @@ export default {
//查询商家分类 //查询商家分类
async getCateList() { async getCateList() {
let that = this; let that = this;
await request(apiArr.getMerChantCateList, "POST").then((res) => { const params = {
isShop: 1,
}
await request(apiArr.getMerChantCateList, "POST",params).then((res) => {
res.rows = res.rows.filter((item) => item.is_visible == 1) res.rows = res.rows.filter((item) => item.is_visible == 1)
console.log(res); console.log(res);
// 将数据分成每10个一组 // 将数据分成每10个一组
@ -210,7 +217,7 @@ export default {
}); });
if (res.rows.length == this.page_size) { if (res.rows.length == this.page_size) {
this.page_num = this.page_num + 1; this.page_num = this.page_size + 10;
this.flag = true; this.flag = true;
} else { } else {
this.flag = false; this.flag = false;

View File

@ -83,6 +83,7 @@ page {
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
box-shadow: 3rpx -3rpx 15rpx 0rpx rgba(255,27,27,0.05); box-shadow: 3rpx -3rpx 15rpx 0rpx rgba(255,27,27,0.05);
padding-bottom: 30rpx;
} }
.left { .left {

View File

@ -1,11 +1,12 @@
<template> <template>
<view class="container"> <view class="container">
<view class="white_container"> <view class="white_container">
<swiper class="swiper" autoplay> <image class="pic" :src="picUrl + info.album_images" />
<!-- <swiper class="swiper" autoplay>
<swiper-item v-for="(item, pageIndex) in info.bigImg" :key="pageIndex"> <swiper-item v-for="(item, pageIndex) in info.bigImg" :key="pageIndex">
<image class="pic" :src="picUrl + item" /> <image class="pic" :src="picUrl + item" />
</swiper-item> </swiper-item>
</swiper> </swiper> -->
<view class="main"> <view class="main">
<view class="title">{{ info.merchant_name }}</view> <view class="title">{{ info.merchant_name }}</view>
@ -28,7 +29,8 @@
</view> </view>
<view class="table"> <view class="table">
<view class="label">营业地址</view> <view class="label">营业地址</view>
<view class="desc">{{ info.comAddress }}</view> <view class="desc" v-if="info.ad">{{ info.ad.ad_name ? info.ad.ad_name.replace(/,/g, "") : "" }}{{
info.address }}</view>
</view> </view>
<view class="table mb32"> <view class="table mb32">
<view class="label">特色服务</view> <view class="label">特色服务</view>
@ -97,7 +99,7 @@
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/Index_add.png" mode="" /> <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/Index_add.png" mode="" />
<view>导航</view> <view>导航</view>
</view> </view>
<view class="left_label" @click="handlePhoneClick"> <view class="left_label" @click="handlePhoneClick" v-if="info.phone">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/localLife_detail_Frame.png" <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/localLife_detail_Frame.png"
mode="" /> mode="" />
<view>电话</view> <view>电话</view>
@ -108,6 +110,10 @@
mode="" /> mode="" />
<view>点评</view> <view>点评</view>
</view> </view>
<view class="left_label" @click="handleKfClick">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/kefu0.png" mode="" />
<view>客服</view>
</view>
</view> </view>
<text v-if="isShow" class="btn" @click="handleQuickPayClick">快捷买单</text> <text v-if="isShow" class="btn" @click="handleQuickPayClick">快捷买单</text>
</view> </view>
@ -136,13 +142,24 @@ export default {
}; };
}, },
onLoad(options) { onLoad(options) {
this.info = uni.getStorageSync("merchantInfo") const params = {
id: Number(uni.getStorageSync("merchantInfo").id)
}
request(apiArr.getMerchantInfo, "POST", params).then(res => {
this.info = res
uni.setStorageSync('merchantInfo', res)
// 确保onLoad执行完后再执行这两个方法
this.page_num = 1
this.flag = false
this.commentList = []
this.getCommentList()
})
}, },
onShow() { onShow() {
this.page_num = 1 if (this.info.id) {
this.flag = false this.getCommentList()
this.commentList = [] }
this.getCommentList()
this.getMerchantInfo() this.getMerchantInfo()
}, },
onReachBottom() { onReachBottom() {
@ -169,15 +186,16 @@ export default {
} else { } else {
this.flag = false; this.flag = false;
} }
this.isShow = res.rows[0].merchant_info.quick_purchase_enabled == 1
const list = res.rows.filter((item) => { const list = res.rows.filter((item) => {
return item.status == 2; return item.status == 2;
}); });
list.forEach(item => { list.forEach(item => {
item.merchant_evaluation_reply_list = item.merchant_evaluation_reply_list.filter((item) => { if (item.merchant_evaluation_reply_list) {
return item.status == 2; item.merchant_evaluation_reply_list = item.merchant_evaluation_reply_list.filter((item) => {
}) return item.status == 2;
})
}
}) })
this.commentList = this.commentList.concat(list); this.commentList = this.commentList.concat(list);
@ -224,6 +242,11 @@ export default {
NavgateTo('../comment/index'); NavgateTo('../comment/index');
}, },
// 客服
handleKfClick() {
NavgateTo('/packages/customerService/changeService/index');
},
like(e) { like(e) {
request(apiArr.merChantCommentLike, "POST", { request(apiArr.merChantCommentLike, "POST", {
evaluation_id: e.id, evaluation_id: e.id,

View File

@ -5,12 +5,12 @@
<u-icon bold color="#fff" size="40" name="arrow-left" @click="back"></u-icon> <u-icon bold color="#fff" size="40" name="arrow-left" @click="back"></u-icon>
</view> </view>
</view> </view>
<div class="text1">物业费公积金</div> <div class="text1">物业费</div>
<div class="text2">¥{{banlance}}</div> <div class="text2">¥{{banlance}}</div>
<div class="total">全部房源合计</div> <div class="total">全部房源合计</div>
<div class="text3"> <div class="text3">
<span>全部房源</span> <span>全部房源</span>
物业费公积金流水 物业费流水
</div> </div>
<div class="orderList"> <div class="orderList">

View File

@ -15,7 +15,7 @@
<image <image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"
mode="aspectFill"></image> mode="aspectFill"></image>
<input type="text" placeholder="请输入您想搜索的内容" /> <input type="text" v-model="searchText" placeholder="请输入您想搜索的内容" @confirm="handleSearch" />
</view> </view>
</view> </view>
</view> </view>
@ -103,7 +103,7 @@
到店服务券 到店服务券
</view> --> </view> -->
<view class="line"></view> <view class="line"></view>
<view class="btn_right"> <view class="btn_right" @click="toPayInfo">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/lcoal_payIcon.png" <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/lcoal_payIcon.png"
mode="aspectFill"></image> mode="aspectFill"></image>
快捷支付记录 快捷支付记录
@ -137,10 +137,11 @@ export default {
currentIndex: 0, currentIndex: 0,
checkedItems: [false, false, false, false], checkedItems: [false, false, false, false],
address: "", address: "",
page_size: "10", page_size: 10,
page_num: "1", page_num: 1,
flag: false, flag: false,
merchatList: [], merchatList: [],
searchText: ''
}; };
}, },
onLoad(options) { onLoad(options) {
@ -161,12 +162,16 @@ export default {
}, },
methods: { methods: {
// 跳转快捷支付记录
toPayInfo(){
NavgateTo("/packages/localLife/payInfo/index")
},
swiperChange(e) { swiperChange(e) {
this.currentIndex = e.detail.current; this.currentIndex = e.detail.current;
}, },
changeNav(item) { changeNav(item) {
console.log("🚀 ~ changeNav ~ item:", item)
NavgateTo(`/packages/localLife/classify/index?item=${JSON.stringify(item)}`) NavgateTo(`/packages/localLife/classify/index?item=${JSON.stringify(item)}`)
}, },
@ -178,7 +183,10 @@ export default {
//查询商家分类 //查询商家分类
async getCateList() { async getCateList() {
let that = this; let that = this;
await request(apiArr.getMerChantCateList, "POST").then((res) => { const params = {
isShop: 1
}
await request(apiArr.getMerChantCateList, "POST", params).then((res) => {
res.rows = res.rows.filter((item) => item.is_visible == 1) res.rows = res.rows.filter((item) => item.is_visible == 1)
console.log(res); console.log(res);
// 将数据分成每10个一组 // 将数据分成每10个一组
@ -189,12 +197,19 @@ export default {
} }
}); });
}, },
//搜索商家
handleSearch() {
this.page_num = 1;
this.merchatList = [];
this.getMechantList();
},
//查询商家列表 //查询商家列表
async getMechantList() { async getMechantList() {
let that = this; let that = this;
await request(apiArr.getMerchantList, "POST", { await request(apiArr.getMerchantList, "POST", {
page_num: that.page_num, page_num: that.page_num,
page_size: that.page_size, page_size: that.page_size,
merchant_name: that.searchText
}).then((res) => { }).then((res) => {
let latitude = uni.getStorageSync("location").lat; let latitude = uni.getStorageSync("location").lat;
let longitude = uni.getStorageSync("location").lng; let longitude = uni.getStorageSync("location").lng;
@ -228,7 +243,7 @@ export default {
}); });
if (res.rows.length == this.page_size) { if (res.rows.length == this.page_size) {
this.page_num = this.page_num + 1; this.page_size = this.page_size + 10;
this.flag = true; this.flag = true;
} else { } else {
this.flag = false; this.flag = false;

View File

@ -18,8 +18,8 @@
<view class="Msg"> <view class="Msg">
<view class="payMony"> <view class="payMony">
¥<input type="number" v-model="Money" placeholder="付款金额" placeholder-style="font-size: 50rpx;" @blur="handleMoneyInput" @focus="showKeyboard" step="0.01" min="0.01"> ¥<input type="digit" v-model="Money" placeholder="付款金额" placeholder-style="font-size: 50rpx;"
<cu-keyboard ref="cukeyboard" @change="change" @confirm="keyboardConfirm" @hide="hide"></cu-keyboard> @blur="handleMoneyInput" step="0.01" min="0.01">
</view> </view>
<view class="payRemark"> <view class="payRemark">
<input type="text" v-model="remarks" placeholder="付款备注"> <input type="text" v-model="remarks" placeholder="付款备注">
@ -28,7 +28,7 @@
<view class="Msg2"> <view class="Msg2">
<view class="Msg2_tit"> <view class="Msg2_tit">
<view class="Msg2_tit_left">获得物业公积金</view> <view class="Msg2_tit_left">获得物业费</view>
<!-- <view class="Msg2_tit_right" @click="choseComminty"> <!-- <view class="Msg2_tit_right" @click="choseComminty">
绑定房源 绑定房源
<u-icon name="arrow-right" color="#999999" size="28"></u-icon> <u-icon name="arrow-right" color="#999999" size="28"></u-icon>
@ -58,10 +58,10 @@
<view class="btnList"> <view class="btnList">
<view class="btnItem" @click="payList">付款记录</view> <view class="btnItem" @click="payList">付款记录</view>
<view class="line"></view> <!-- <view class="btnItem" @click="homeMoneList">物业费</view> -->
<view class="btnItem" @click="homeMoneList">物业费公积金</view>
<view class="line"></view> <view class="line"></view>
<view class="btnItem" @click="home">首页</view> <view class="btnItem" @click="home">首页</view>
<view class="line"></view>
<view class="btnItem2" @click="changeBoxshadow"> <view class="btnItem2" @click="changeBoxshadow">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_qrcode.png" <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_qrcode.png"
mode="aspectFill"></image> mode="aspectFill"></image>
@ -121,8 +121,10 @@ export default {
}, },
watch: { watch: {
Money(newVal) { Money(newVal) {
this.homeMoney = Math.round(newVal * (this.info.refund_property_fee_ratio || 0)); const homeMoney1 = newVal * (this.info.refund_property_fee_ratio || 0)
this.integral = Math.round(newVal * (this.info.refund_user_points_ratio || 0)); this.homeMoney = homeMoney1.toFixed(2);
const integral1 = newVal * (this.info.refund_user_points_ratio || 0)
this.integral = integral1.toFixed(2);
}, },
}, },
@ -137,48 +139,7 @@ export default {
methods: { methods: {
showKeyboard() {
this.$refs.cukeyboard.open();
},
// 键盘输入内容变化时触发
change(value) {
// 先进行基本的输入格式化
let formattedValue = value.toString().replace(/[^\d.]/g, '');
// 如果第一个数字是0且后面还有其他数字,则删除这个0
if (formattedValue.length >= 2 && formattedValue[0] === '0' && formattedValue[1] !== '.') {
formattedValue = formattedValue.substring(1);
}
// 限制只能有一个小数点
formattedValue = formattedValue.replace(/\.{2,}/g, '.');
// 确保小数点后最多两位
const parts = formattedValue.split('.');
if (parts.length > 1) {
formattedValue = parts[0] + '.' + parts[1].substring(0, 2);
}
// 处理开头是小数点的情况
if (formattedValue.startsWith('.')) {
formattedValue = '0' + formattedValue;
}
this.Money = formattedValue;
},
// 点击键盘确认按钮时触发
keyboardConfirm(value) {
// 如果最后一位是小数点,则删除小数点
if (value && value.endsWith('.')) {
value = value.slice(0, -1);
}
this.Money = value;
this.$refs.cukeyboard.close();
},
// 键盘隐藏时触发
hide() {
// 可以在这里添加键盘隐藏后的处理逻辑
},
handleMoneyInput() { handleMoneyInput() {
// 清除非数字和非小数点的字符 // 清除非数字和非小数点的字符
let value = this.Money.toString().replace(/[^\d.]/g, ''); let value = this.Money.toString().replace(/[^\d.]/g, '');
@ -203,57 +164,37 @@ export default {
this.Money = value; this.Money = value;
}, },
createQrcode() {
uni.showLoading({
title: '加载中',
mask: true
});
uni.request({
url: 'https://api.weixin.qq.com/cgi-bin/token',
data: {
grant_type: 'client_credential',
appid: "wx1addb25675dd8e70",
secret: "1c153a91d0558b4c3834a4399ebc7496"
},
header: {
// 'custom-header': 'hello' //自定义请求头信息
},
success: (res) => {
this.createQrcode2(res.data.access_token)
}
});
},
createQrcode2(e) {
let that = this
uni.request({
url: `https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=${e}`,
method: 'post',
data: {
path: '/packages/localLife/pay/index'
},
header: {
// 'custom-header': 'hello' //自定义请求头信息
'content-type': 'application/json'
},
responseType: 'arraybuffer',
success: (res) => {
uni.hideLoading();
// this.text = 'request success';
let data = uni.arrayBufferToBase64(res.data)
console.log(data);
that.myCode = 'data:image/png;base64,' + data
this.boxShow = !this.boxShow
},
fail: (res) => {
uni.hideLoading();
}
});
},
changeBoxshadow2() { changeBoxshadow2() {
this.boxShow = !this.boxShow this.boxShow = !this.boxShow
}, },
changeBoxshadow() { changeBoxshadow() {
this.createQrcode() uni.showLoading({
title: '加载中',
mask: true
});
const params = {
merchant_id: this.info.id,
}
request(apiPay.qrcode, "POST", params).then(res => {
uni.hideLoading();
if (res && res.qrcode_image_url) {
this.myCode = picUrl + res.qrcode_image_url;
this.boxShow = !this.boxShow;
} else {
uni.showToast({
title: '获取二维码失败,请重试',
icon: 'none'
});
}
}).catch(err => {
console.error('获取二维码失败:', err);
uni.hideLoading();
uni.showToast({
title: '获取二维码失败,请重试',
icon: 'none'
});
});
}, },
confirm(e) { confirm(e) {
@ -297,7 +238,7 @@ export default {
} }
request(apiArr.createPay, "POST", { request(apiArr.createPay, "POST", {
merchant_id: that.info.id, merchant_id: that.info.id,
order_amount: Number((that.Money) * 100), //金额 order_amount: Number((that.Money)), //金额
refund_property_fee: that.homeMoney, //物业费 refund_property_fee: that.homeMoney, //物业费
refund_member_points: that.integral, //积分 refund_member_points: that.integral, //积分
remark: that.remarks, remark: that.remarks,
@ -309,7 +250,7 @@ export default {
}, },
payList() { payList() {
NavgateTo("../payInfo/index") NavgateTo("../payInfo/index?id=" + this.info.id)
}, },
homeMoneList() { homeMoneList() {
NavgateTo("../houseProvident/index") NavgateTo("../houseProvident/index")
@ -331,38 +272,46 @@ export default {
async LakaLaPrePay() { async LakaLaPrePay() {
let that = this let that = this
request(apiPay.pay, "POST", { request(apiArr.getPreOrderInfo, "POST", {
total_amount: that.OrderMsg.order_amount, id: that.payId,
subject: '快捷支付订单',
goods_id: that.payId,
address: "",
out_trade_no: that.OrderMsg.order_no,
remark: that.OrderMsg.remark,
quantity: '1',
user: uni.getStorageSync('userId'),
user_id: uni.getStorageSync('openId')
}).then(res => { }).then(res => {
console.log(res, 'res'); if (res && res.timeStamp && res.nonceStr && res.package && res.signType && res.paySign) {
// 调用微信支付
const { resp_data, msg } = res uni.requestPayment({
timeStamp: res.timeStamp,
wx.requestPayment({ nonceStr: res.nonceStr,
timeStamp: String(resp_data.acc_resp_fields.time_stamp), package: res.package,
nonceStr: String(resp_data.acc_resp_fields.nonce_str), signType: res.signType,
package: String(resp_data.acc_resp_fields.package), paySign: res.paySign,
signType: String(resp_data.acc_resp_fields.sign_type), success: (payRes) => {
paySign: String(resp_data.acc_resp_fields.pay_sign), const params = {
success(res) { id: this.OrderMsg.id,
that.queryPay(resp_data) back_wygjj: this.homeMoney,
}, back_points: this.integral,
fail(fal) { }
if (fal.errMsg == 'requestPayment:fail cancel') { request(apiArr.tradeQuery, "POST", params).then(res => {
// that.payFail(2) })
} else { },
// that.payFail(1) fail: (payErr) => {
uni.showToast({
title: payErr.errMsg == 'requestPayment:fail cancel' ? '已取消支付' : '支付失败',
icon: 'none'
})
const params = {
order_ids: orderId,
}
},
complete: () => {
// 支付完成后的回调,无论成功失败都会执行
} }
} })
}) } else {
console.error("获取支付参数失败,缺少必要参数")
uni.showToast({
title: '获取支付信息失败',
icon: 'none'
})
}
}) })
}, },

View File

@ -1,26 +1,26 @@
<template> <template>
<view class="container"> <view class="container">
<view class="payInfoList"> <view class="payInfoList">
<view class="PayInfoItem" v-for="item in payList"> <view class="PayInfoItem" v-for="item in payList" :key="item.order_no">
<view class="row"> <view class="row">
<view class="row_label">付款金额</view> <view class="row_label">付款金额</view>
<view class="row_con">¥{{ item.order_amount }}</view> <view class="row_con">¥{{ item.order_amount }}</view>
</view> </view>
<view class="row"> <view class="row">
<view class="row_label2">{{item.create_time}}</view> <view class="row_label2">{{ item.create_time }}</view>
<view class="row_label2" v-if="false">Adapay微信小程序支付</view> <view class="row_label2" v-if="false">Adapay微信小程序支付</view>
<view class="row_label2">{{item.payment_method}}</view> <view class="row_label2">{{ item.payment_method }}</view>
</view> </view>
<view class="line"></view> <view class="line"></view>
<view class="row2"> <view class="row2">
<view class="label">订单号</view> <view class="label">订单号</view>
<view class="con3">{{item.order_no}}</view> <view class="con3">{{ item.order_no }}</view>
</view> </view>
<view class="row2"> <view class="row2">
<view class="label">消费门店</view> <view class="label">消费门店</view>
<view class="con3">{{item.merchant_info.merchant_name}}</view> <view class="con3">{{ item.merchant_info.merchant_name }}</view>
</view> </view>
<view class="row2"> <view class="row2">
@ -31,7 +31,7 @@
<view class="con3" v-else>未知</view> <view class="con3" v-else>未知</view>
</view> </view>
<view class="line"></view> <!-- <view class="line"></view>
<view class="row3"> <view class="row3">
<view class="label">返物业费</view> <view class="label">返物业费</view>
@ -45,7 +45,7 @@
<view class="con3" @click="points">{{ item.refund_member_points }} <view class="con3" @click="points">{{ item.refund_member_points }}
<u-icon name="arrow-right" color="#999999" size="40" style="max-lines: 10rpx;"></u-icon> <u-icon name="arrow-right" color="#999999" size="40" style="max-lines: 10rpx;"></u-icon>
</view> </view>
</view> </view> -->
</view> </view>
</view> </view>
@ -74,14 +74,16 @@ export default {
localHeight: "", localHeight: "",
page_num: 1, page_num: 1,
page_size: 10, page_size: 10,
flag:false, flag: false,
payList:[] payList: [],
id: "",
} }
}, },
onLoad(options) { onLoad(options) {
const meun = menuButtonInfo(); const meun = menuButtonInfo();
this.top = meun.top; this.top = meun.top;
this.localHeight = meun.height; this.localHeight = meun.height;
this.id = options.id
this.getPayList() this.getPayList()
}, },
@ -97,12 +99,13 @@ export default {
getPayList() { getPayList() {
let that = this let that = this
request(apiArr.getPayList, "POST", { request(apiArr.getPayList, "POST", {
page_num:that.page_num, merchant_id: that.id,
page_size:that.page_size page_num: that.page_num,
}).then(res=>{ page_size: that.page_size
if(res.rows.length == that.page_size){ }).then(res => {
if (res.rows.length == that.page_size) {
that.flag = true that.flag = true
}else{ } else {
that.flag = false that.flag = false
} }
that.payList = that.payList.concat(res.rows) that.payList = that.payList.concat(res.rows)

View File

@ -9,7 +9,7 @@
<div class="msg"> <div class="msg">
<div class="msgItem"> <div class="msgItem">
<div class="msgItem_left">获得物业公积金</div> <div class="msgItem_left">获得物业费</div>
<div class="msgItem_right"> <div class="msgItem_right">
¥53.1 ¥53.1
<u-icon name="arrow-right" color="#999999" size="40" style="max-lines: 10rpx;"></u-icon> <u-icon name="arrow-right" color="#999999" size="40" style="max-lines: 10rpx;"></u-icon>

View File

@ -161,23 +161,24 @@ export default {
console.log('省份没变,查市跟区', this.cityList) console.log('省份没变,查市跟区', this.cityList)
let newDist = this.cityList[sq]; let newDist = this.cityList[sq];
console.log('新的市信息', newDist); console.log('新的市信息', newDist);
if (this.xsq.ad_code !== newDist.ad_code) { if (!this.xsq || this.xsq.ad_code !== newDist.ad_code) {
console.log('新市区跟旧市区不一直') console.log('新市区跟旧市区不一致')
this.xsq = newDist; this.xsq = newDist;
this.confirmCity = newDist;
this.getDistList(newDist, x); this.getDistList(newDist, x);
} else { } else {
console.log('新市区跟旧市区一直'); console.log('新市区跟旧市区一致');
this.confirmDist = this.defaultDist[x] this.confirmDist = this.defaultDist[x]
} }
return return
} }
const res = await request(apiArr.getArea, 'POST', { parent_ad_code: this.confirmProv1.ad_code }, { silent: false }); const res = await request(apiArr.getArea, 'POST', { parent_ad_code: this.confirmProv1.ad_code }, { silent: false });
this.cityList = res.rows; this.cityList = res.rows;
let newDist;
this.defaultCity = res.rows; this.defaultCity = res.rows;
this.confirmCity = res.rows[0]; // 拿市的第一条区查区 this.confirmCity = res.rows[0]; // 拿市的第一条区查区
this.getDistList(newDist, x); this.xsq = res.rows[0]; // 初始化xsq为第一个城市
this.getDistList(this.xsq, x);
}, },
// 获取 县/区 信息 // 获取 县/区 信息
async getDistList(xsq, x) { async getDistList(xsq, x) {
@ -222,10 +223,9 @@ export default {
}) })
return return
} }
console.log("🚀 ~ headerSubmitClick ~ type:", this.type)
if(this.type === 'edit') { if(this.type === 'edit') {
const res = await request(apiArr2.updateAddress, "POST", { const res = await request(apiArr2.updateAddress, "POST", {
user_id: this.id, id: this.id,
name: this.name, name: this.name,
phone: this.phone, phone: this.phone,
address: this.tab === 0 ? this.orientation.region + this.orientation.district : `${confirmProv1.short_name}${xsq.short_name ? xsq.short_name : confirmCity.short_name}${confirmDist.short_name}`, address: this.tab === 0 ? this.orientation.region + this.orientation.district : `${confirmProv1.short_name}${xsq.short_name ? xsq.short_name : confirmCity.short_name}${confirmDist.short_name}`,
@ -294,16 +294,18 @@ export default {
bindChange(e) { bindChange(e) {
console.log('[1231331], e', e); console.log('[1231331], e', e);
const { value } = e.detail; const { value } = e.detail;
// // 每次切换时,根据当前点击的省过滤出所属市区,并且变化县/区
let newCrty = this.provList[value[0]]; let newCrty = this.provList[value[0]];
console.log('新的省份信息', newCrty); console.log('新的省份信息', newCrty);
console.log('旧的省信息', this.confirmProv1); console.log('旧的省信息', this.confirmProv1);
// 判断省份是否变化
if (newCrty.ad_code === this.confirmProv1.ad_code) { if (newCrty.ad_code === this.confirmProv1.ad_code) {
console.log('省份信息没变'); console.log('省份信息没变');
this.sf = false; this.sf = false;
} else { } else {
this.sf = true; this.sf = true;
} }
console.log('this.cityListthis.cityList', this.cityList); console.log('this.cityListthis.cityList', this.cityList);
this.confirmProv1 = newCrty this.confirmProv1 = newCrty
this.getCityList(value[1], value[2]) this.getCityList(value[1], value[2])

View File

@ -54,6 +54,10 @@
margin-right: 10rpx; margin-right: 10rpx;
} }
.addressItem_footer_left2 {
display: flex;
}
.addressItem_footer_right { .addressItem_footer_right {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -3,27 +3,29 @@
<view class="hasAddress"> <view class="hasAddress">
<view class="addressList"> <view class="addressList">
<view class="addressItem" v-for="item, index in list" :key="index" :class="{ 'addressItem_def': index == 0 }"> <view class="addressItem" v-for="item, index in list" :key="index"
:class="{ 'addressItem_def': index == 0 }" @click="selectAddress(item)">
<view class="addressItem_top"> <view class="addressItem_top">
{{item.name}} {{item.phone}} <view v-if="item.is_default === 1" class="is_def">默认</view> {{ item.name }} {{ item.phone }} <view v-if="item.is_default === 1" class="is_def">默认</view>
</view> </view>
<view class="addressItem_mid">{{item.address}}{{ item.house_number }}</view> <view class="addressItem_mid">{{ item.address }}{{ item.house_number }}</view>
<view class="addressItem_footer"> <view class="addressItem_footer">
<view class="addressItem_footer_left"> <view class="addressItem_footer_left">
<view v-if="item.is_default !== 1" @click="headerSettingDefault(item.id)"> <view v-if="item.is_default !== 1" @click.stop="headerSettingDefault(item.id)"
<image src="http://192.168.0.172:5500/7.15/shop_checked1.png"></image> class="addressItem_footer_left2">
<view class="checkbox"></view>
设为默认 设为默认
</view> </view>
<view v-if="item.is_default === 1"> <view v-if="item.is_default === 1" class="addressItem_footer_left2">
<image src="http://192.168.0.172:5500/7.15/shop_checked2.png"></image> <view class="checkbox checkbox-checked"></view>
已默认 已默认
</view> </view>
</view> </view>
<view class="addressItem_footer_right"> <view class="addressItem_footer_right">
<view class="btn1" @click="deleteItem(item.id )">删除</view> <view class="btn1" @click.stop="deleteItem(item.id)">删除</view>
<view class="btn2" @click="editItem(item)">修改</view> <view class="btn2" @click.stop="editItem(item)">修改</view>
</view> </view>
</view> </view>
</view> </view>
@ -61,7 +63,7 @@ export default {
} }
}, },
methods: { methods: {
addAddress(){ addAddress() {
NavgateTo("../addAddress/index") NavgateTo("../addAddress/index")
}, },
@ -71,7 +73,7 @@ export default {
async headerSettingDefault(id) { async headerSettingDefault(id) {
const res = await request(apiArr.settingDefaultAddress, 'POST', { id }, { silent: true, nested: true }); const res = await request(apiArr.settingDefaultAddress, 'POST', { id }, { silent: true, nested: true });
if(res.code === 1){ if (res.code === 1) {
uni.showToast({ uni.showToast({
title: '设置成功', title: '设置成功',
icon: 'success', icon: 'success',
@ -81,7 +83,7 @@ export default {
} }
}, },
deleteItem(id){ deleteItem(id) {
const _this = this; const _this = this;
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
@ -89,7 +91,7 @@ export default {
success: async function (res) { success: async function (res) {
if (res.confirm) { if (res.confirm) {
console.log('用户点击确定'); console.log('用户点击确定');
const res = await request(apiArr.addressDel, 'POST', { id }); const res = await request(apiArr.deleteAddress, 'POST', { id });
uni.showToast({ uni.showToast({
title: '删除成功', title: '删除成功',
icon: 'success', icon: 'success',
@ -103,6 +105,14 @@ export default {
}); });
}, },
// 选择地址
selectAddress(item) {
// 存储选中的地址信息
uni.setStorageSync('selectedAddress', item);
// 返回上一页
uni.navigateBack();
},
async init() { async init() {
const res = await request(apiArr.addAddressList, 'POST', {}); const res = await request(apiArr.addAddressList, 'POST', {});
this.list = res.address_list; this.list = res.address_list;
@ -125,4 +135,32 @@ export default {
<style> <style>
@import url("./index.css"); @import url("./index.css");
/* 多选框样式 */
.checkbox {
width: 32rpx;
height: 32rpx;
border: 2rpx solid #D1D1D1;
border-radius: 6rpx;
margin-right: 10rpx;
display: flex;
align-items: center;
justify-content: center;
background-color: #FFFFFF;
}
.checkbox-checked {
border-color: #FF370B;
background-color: #FF370B;
}
.checkbox-checked::after {
content: "";
display: block;
width: 16rpx;
height: 8rpx;
border-left: 2rpx solid #FFFFFF;
border-bottom: 2rpx solid #FFFFFF;
transform: rotate(-45deg);
}
</style> </style>

View File

@ -284,6 +284,11 @@ image {
margin-top: 26rpx; margin-top: 26rpx;
} }
.car_right_disabled {
background: #CCCCCC;
color: #FFFFFF;
}
.cars { .cars {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -18,7 +18,7 @@
</swiper> </swiper>
<view class="NumDot"> <view class="NumDot">
{{ currentIndex }} / {{ currentGG.goods_carousel.length }} {{ currentIndex }} / {{ currentGG.goods_carousel ? currentGG.goods_carousel.length : 0 }}
</view> </view>
</view> </view>
@ -40,7 +40,8 @@
</view> </view>
</view> </view>
<view class="GG_rigth" @click="showSizePopup"> <view class="GG_rigth" @click="showSizePopup">
共{{ info.commodity_goods_info_list.length }}款<u-icon size="26rpx" name="arrow-right"></u-icon> 共{{ info.commodity_goods_info_list ? info.commodity_goods_info_list.length : 0 }}款<u-icon size="26rpx"
name="arrow-right"></u-icon>
</view> </view>
</view> </view>
@ -107,10 +108,12 @@
</view> </view>
<view class="review-time">{{ comment.create_time }}</view> <view class="review-time">{{ comment.create_time }}</view>
</view> </view>
<view class="user-purchase">已购 {{ comment.goods_name.goods_name }}{{ comment.goods_name.goods_spec }}</view> <view class="user-purchase">已购 {{ comment.goods_name.goods_name }}{{ comment.goods_name.goods_spec
}}</view>
<view class="review-content">{{ comment.user_review }}</view> <view class="review-content">{{ comment.user_review }}</view>
<view class="review-images" v-if="comment.review_image.length > 0"> <view class="review-images" v-if="comment.review_image.length > 0">
<image :src="img" class="review-img" v-for="(img, idx) in comment.review_image" :key="idx"></image> <image :src="img" class="review-img" v-for="(img, idx) in comment.review_image" :key="idx">
</image>
</view> </view>
</view> </view>
</view> </view>
@ -173,37 +176,30 @@
</view> </view>
<view class="car_right" v-if=" <view class="car_right" v-if="
!info.commodity_goods_info_list[currentGGIndex].cart_count || info.commodity_goods_info_list[currentGGIndex].stock_quantity > 0 &&
info.commodity_goods_info_list[currentGGIndex].cart_count.count == 0 (!info.commodity_goods_info_list[currentGGIndex].cart_count ||
info.commodity_goods_info_list[currentGGIndex].cart_count.count == 0)
" @click="addCar"> " @click="addCar">
加入购物车 加入购物车
</view> </view>
<view class="car_right" v-if="info.commodity_goods_info_list[currentGGIndex].cart_count.count > 0"> <view class="car_right" @click="changeCar" v-if="
<!-- <view class="car_right"> --> info.commodity_goods_info_list[currentGGIndex].cart_count.count > 0
<u-number-box v-model="info.commodity_goods_info_list[currentGGIndex].cart_count.count" && info.commodity_goods_info_list[currentGGIndex].stock_quantity > 0
@change="changeCar" min="0"> ">
<!-- <u-number-box > --> 加入购物车
<view slot="minus" class="minus"> </view>
<u-icon name="minus" size="36" bold></u-icon>
</view> <view class="car_right car_right_disabled"
<text slot="input" style="width: 200rpx; text-align: center" class="input"> v-if="info.commodity_goods_info_list[currentGGIndex].stock_quantity < 1">
{{ info.commodity_goods_info_list[currentGGIndex].cart_count.count }} 已售罄
</text>
<!-- text slot="input" style="width: 200rpx; text-align: center" class="input">
{{info.commodity_goods_info_list[currentGGIndex]}}
</text> -->
<view slot="plus" class="plus">
<u-icon name="plus" color="#FFFFFF" size="36" bold></u-icon>
</view>
</u-number-box>
</view> </view>
</view> </view>
<!-- 分享 --> <!-- 分享 -->
<view class="shadow" @click.stop="changeShadow" v-if="boxshadow1"> <view class="shadow" @click.stop="changeShadow" v-if="boxshadow1">
<view class="shadowBox1"> <view class="shadowBox1">
<button class="shadowBox1Item_btn" open-type="share" bindtap="onShareButtonClick"/> <button class="shadowBox1Item_btn" open-type="share" bindtap="onShareButtonClick" />
<view class="shadowBox1Item" @click="shareFriend"> <view class="shadowBox1Item" @click="shareFriend">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png" <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png"
mode="aspectFill"></image> mode="aspectFill"></image>
@ -231,9 +227,12 @@
</view> </view>
<view class="line"></view> <view class="line"></view>
<view class="shadowBoxInfo"> <view class="shadowBoxInfo">
<image class="shadowboxInfo_left" :src="qrcodePath || 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/qrcode_placeholder.png'" mode="aspectFill"></image> <image class="shadowboxInfo_left"
:src="qrcodePath || 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/qrcode_placeholder.png'"
mode="aspectFill"></image>
<view class="shadowboxInfo_right"> <view class="shadowboxInfo_right">
<view class="shadowboxInfo_right_1">{{ currentGG && currentGG.goods_name ? currentGG.goods_name : '' }}</view> <view class="shadowboxInfo_right_1">{{ currentGG && currentGG.goods_name ?
currentGG.goods_name : '' }}</view>
<view class="shadowboxInfo_right_2"> <view class="shadowboxInfo_right_2">
长按识别小程序 <br /> 长按识别小程序 <br />
数量有限马上抢购 数量有限马上抢购
@ -271,7 +270,8 @@
</view> </view>
<view class="review-time">{{ comment.create_time }}</view> <view class="review-time">{{ comment.create_time }}</view>
</view> </view>
<view class="user-purchase">已购 {{ comment.goods_name.goods_name }}{{ comment.goods_name.goods_spec }}</view> <view class="user-purchase">已购 {{ comment.goods_name.goods_name }}{{
comment.goods_name.goods_spec }}</view>
<view class="review-content">{{ comment.user_review }}</view> <view class="review-content">{{ comment.user_review }}</view>
<view class="review-images" v-if="comment.review_image.length > 0"> <view class="review-images" v-if="comment.review_image.length > 0">
<image :src="img" class="review-img" v-for="(img, idx) in comment.review_image" :key="idx"> <image :src="img" class="review-img" v-for="(img, idx) in comment.review_image" :key="idx">
@ -303,7 +303,8 @@
</view> </view>
<view class="itemSizeBox" v-for="(item, index) in info.commodity_goods_info_list" :key="item.id" <view class="itemSizeBox" v-for="(item, index) in info.commodity_goods_info_list" :key="item.id"
@click="changeGG(item, index)"> @click="changeGG(item, index)">
<text class="itemSize" :class="index == currentGGIndex ? 'itemSize_active' : ''">{{ item.goods_name }} {{ item.goods_spec }} / {{ item.goods_unit }}</text> <text class="itemSize" :class="index == currentGGIndex ? 'itemSize_active' : ''">{{ item.goods_name }}
{{ item.goods_spec }} / {{ item.goods_unit }}</text>
</view> </view>
</u-popup> </u-popup>
</view> </view>
@ -321,36 +322,36 @@ import {
} from "../../../utils"; } from "../../../utils";
export default { export default {
data() { data() {
return { return {
picUrl, picUrl,
top: "", top: "",
localHeight: "", localHeight: "",
carNum: "", carNum: "",
prevCarNum: "", prevCarNum: "",
currentNum: "0", //当前商品的数量 currentNum: "0", //当前商品的数量
type: "error", type: "error",
boxshadow1: false, boxshadow1: false,
boxshadow2: false, boxshadow2: false,
id: "184", id: "184",
info: "", info: "",
currentIndex: "1", //当前轮播图 currentIndex: "1", //当前轮播图
currentGG: "", //当前选中规格 currentGG: "", //当前选中规格
currentGGIndex: "", //当前规格index currentGGIndex: "", //当前规格index
carOrderList: [], carOrderList: [],
// 新增评论数据 // 新增评论数据
showReviewPopup: false, showReviewPopup: false,
comments: [], comments: [],
show: false, show: false,
showSize: false, showSize: false,
changeImg: "", changeImg: "",
changeName: "", changeName: "",
changePrice: "", changePrice: "",
selectedGoods: null, // 保存传入的商品规格信息 selectedGoods: null, // 保存传入的商品规格信息
qrcodePath: null, // 存储当前页面的二维码路径 qrcodePath: null, // 存储当前页面的二维码路径
}; };
}, },
methods: { methods: {
changeIndex(e) { changeIndex(e) {
@ -436,7 +437,6 @@ export default {
request(apiArr.getGoodsInfo, "POST", { request(apiArr.getGoodsInfo, "POST", {
id: this.id, id: this.id,
}).then((res) => { }).then((res) => {
console.log(res);
// 分割图片 // 分割图片
res.commodity_goods_info_list.forEach((item) => { res.commodity_goods_info_list.forEach((item) => {
@ -459,8 +459,7 @@ export default {
}); });
} }
this.info = res; this.info = res;
console.log("this.info", this.info.commodity_goods_info_list);
// 检查是否有传入的选中商品信息,如果有则设置为默认选中 // 检查是否有传入的选中商品信息,如果有则设置为默认选中
let selectedIndex = 0; let selectedIndex = 0;
if (this.selectedGoods) { if (this.selectedGoods) {
@ -471,7 +470,7 @@ export default {
} }
} }
} }
this.currentGG = res.commodity_goods_info_list[selectedIndex]; this.currentGG = res.commodity_goods_info_list[selectedIndex];
console.log("this.currentGG", this.currentGG); console.log("this.currentGG", this.currentGG);
this.currentGGIndex = selectedIndex; this.currentGGIndex = selectedIndex;
@ -518,14 +517,17 @@ export default {
//获取购物车数量 //获取购物车数量
getShopCar() { getShopCar() {
request(apiArr.getCarCount, "POST", {}).then((res) => { request(apiArr.getCarCount, "POST", {}).then((res) => {
this.carNum = res.total;
this.prevCarNum = res.total; this.prevCarNum = res.total;
}); });
}, },
getShopCarList() { getShopCarList() {
request(apiArr.getCar, "POST", {}).then((res) => { return request(apiArr.getCar, "POST", {}).then((res) => {
this.carOrderList = res.commodity_cart_list; // 合并当日达和普通商品数据
this.carOrderList = [].concat(res.same_day_cart_list, res.normal_cart_list)
.flatMap(supplier => supplier.commodity_cart_and_goods_model);
this.carNum = res.total;
return res;
}); });
}, },
@ -533,11 +535,11 @@ export default {
let that = this; let that = this;
// 获取当前商品 // 获取当前商品
const currentGoods = this.info.commodity_goods_info_list[this.currentGGIndex]; const currentGoods = this.info.commodity_goods_info_list[this.currentGGIndex];
// 获取当前购物车数量和库存数量 // 获取当前购物车数量和库存数量
const currentQuantity = currentGoods.cart_count ? currentGoods.cart_count.count : 0; const currentQuantity = currentGoods.cart_count ? currentGoods.cart_count.count : 0;
const stockQuantity = currentGoods.stock_quantity || 0; const stockQuantity = currentGoods.stock_quantity || 0;
// 检查库存是否充足 // 检查库存是否充足
if (currentQuantity >= stockQuantity) { if (currentQuantity >= stockQuantity) {
uni.showToast({ uni.showToast({
@ -547,55 +549,61 @@ export default {
}); });
return; return;
} }
//如果没有当前商品 直接添加一个 //如果没有当前商品 直接添加一个
let goods_id_and_count = [];
this.info.commodity_goods_info_list[this.currentGGIndex].cart_count = { this.info.commodity_goods_info_list[this.currentGGIndex].cart_count = {
count: currentQuantity + 1, count: currentQuantity + 1,
}; };
this.info.commodity_goods_info_list.forEach((item) => { const params = {
goods_id_and_count.push({ goods_id_and_count: [
goods_id: item.id, {
count: item.cart_count ? item.cart_count.count : 0, goods_id: this.info.commodity_goods_info_list[this.currentGGIndex].id,
}); count: this.info.commodity_goods_info_list[this.currentGGIndex].cart_count.count,
}); },
],
};
//因为是当前商品没有 调用update就是增加商品。增加商品之后再获取购物车数量 //因为是当前商品没有 调用update就是增加商品。增加商品之后再获取购物车数量
request(apiArr.updateCar, "POST", { request(apiArr.updateCar, "POST", params).then((res) => {
goods_id_and_count,
}).then((res) => {
that.getShopCar(); that.getShopCar();
that.getShopCarList(); that.getShopCarList();
}); });
}, },
// 购物车更改 // 购物车更改
changeCar(newValue) { changeCar() {
// // 修改当前商品在购物车中的数量 // 直接增加商品数量,与addCar逻辑类似
// this.info.commodity_goods_info_list[this.currentGGIndex].cart_count.count = newValue.value const currentGoods = this.info.commodity_goods_info_list[this.currentGGIndex];
// // 修改购物车列表中的数量 const currentQuantity = currentGoods.cart_count ? currentGoods.cart_count.count : 0;
// this.carOrderList.forEach(item => { const stockQuantity = currentGoods.stock_quantity || 0;
// if (item.commodity_goods_info.id == this.info.commodity_goods_info_list[this.currentGGIndex].id) {
// item.count = newValue.value // 检查库存是否充足
// } if (currentQuantity >= stockQuantity) {
// }) uni.showToast({
// // 计算购物车数量 title: "库存不足",
// let carNum = 0 icon: "none",
// this.carOrderList.forEach(item => { duration: 2000
// carNum += item.count });
// }) return;
// this.carNum = carNum }
//商品数量变化
// 增加商品数量
currentGoods.cart_count = {
count: currentQuantity + 1,
};
const params = { const params = {
user_id: uni.getStorageSync("userId"), user_id: uni.getStorageSync("userId"),
goods_id_and_count: [{ goods_id_and_count: [{
goods_id: this.info.commodity_goods_info_list[this.currentGGIndex].id, goods_id: currentGoods.id,
count: newValue.value, count: currentGoods.cart_count.count,
},], }],
}; };
request(apiArr.updateCar, "POST", params).then((res) => { request(apiArr.updateCar, "POST", params).then((res) => {
console.log(res); console.log(res);
this.getShopCarList(); this.getShopCarList();
this.getShopCar();
uni.showToast({ uni.showToast({
title: "操作成功!", title: "操作成功!",
success() { }, success() { },
@ -638,7 +646,7 @@ export default {
})); }));
}); });
} }
},onLoad(options) { }, onLoad(options) {
const itemObj = JSON.parse(decodeURIComponent(options.item)); const itemObj = JSON.parse(decodeURIComponent(options.item));
const meun = menuButtonInfo(); const meun = menuButtonInfo();
this.top = meun.top; this.top = meun.top;
@ -650,20 +658,23 @@ export default {
}, },
onReachBottom() { }, onReachBottom() { },
onShow() { onShow() {
this.getShopCarList(); this.getShopCarList().then(() => {
this.getGoodsInfo(); this.getGoodsInfo();
this.getShopCar(); this.getShopCar();
this.getComment(); this.getComment();
});
}, },
//离开页面的时候直接更新购物车数量(目前接口是 传入商品id 数量。如果有当前商品就更新数量。如果没有就增加商品。如果删除某个商品 count 为0 就删除) //离开页面的时候直接更新购物车数量(目前接口是 传入商品id 数量。如果有当前商品就更新数量。如果没有就增加商品。如果删除某个商品 count 为0 就删除)
onHide() { onHide() {
let goods_id_and_count = []; let goods_id_and_count = [];
this.info.commodity_goods_info_list.forEach((item) => { this.info.commodity_goods_info_list.forEach((item) => {
goods_id_and_count.push({ if (item.cart_count) {
goods_id: item.id, goods_id_and_count.push({
count: item.cart_count ? item.cart_count.count : 0, goods_id: item.id,
}); count: item.cart_count.count,
});
}
}); });
request(apiArr.updateCar, "POST", { request(apiArr.updateCar, "POST", {

View File

@ -0,0 +1,608 @@
page {
background-color: #f5f7fb;
}
.container {
padding: 0;
margin: 0;
font-size: 28rpx;
color: #333;
}
/* 顶部切换栏 */
.tab-bar {
display: flex;
background-color: #fff;
padding: 20rpx 0;
}
.tab-item {
width: 180rpx;
height: 70rpx;
line-height: 70rpx;
text-align: center;
border-radius: 15rpx;
margin: 0 20rpx;
font-size: 28rpx;
border: 1rpx solid #ddd;
}
.tab-item.active {
background-color: #ff370b;
color: #fff;
}
/* 分隔线 */
.divider {
height: 20rpx;
background-color: #f5f5f5;
}
/* 公共标题样式 */
.section-title {
font-size: 32rpx;
color: #333;
font-weight: bold;
padding: 20rpx 30rpx;
}
/* 收货地址区域 */
.info-section {
background: repeating-linear-gradient(to right,
#fe5355,
#fe5355 20px,
#549aff 20px,
#549aff 40px);
padding: 10rpx 0;
}
.address-section {
background-color: #fff;
}
.address-info {
padding: 30rpx;
display: flex;
justify-content: space-between;
align-items: flex-start;
border-bottom: 1rpx solid #eee;
}
.address-main {
flex: 1;
}
.address-name-phone {
display: flex;
align-items: center;
margin-bottom: 10rpx;
}
.name {
font-size: 32rpx;
margin-right: 20rpx;
}
.phone {
font-size: 30rpx;
color: #666;
}
.address-detail {
font-size: 28rpx;
color: #666;
line-height: 40rpx;
display: flex;
align-items: center;
}
.address-arrow {
color: #333;
}
.addNewAddress {
font-size: 32rpx;
color: #999999;
float: right;
}
/* 商品信息区域 */
.goods-section {
background-color: #fff;
margin-bottom: 20rpx;
}
.goods-item {
border-radius: 10rpx;
padding: 15rpx;
display: flex;
background-color: #fff;
}
.goods-image {
width: 140rpx;
height: 140rpx;
border-radius: 15rpx;
overflow: hidden;
margin-right: 15rpx;
}
.goods-image image {
width: 100%;
height: 100%;
object-fit: cover;
}
.goods-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
}
.goods-name {
font-size: 28rpx;
font-weight: bold;
margin-bottom: 8rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.goods-desc {
font-size: 22rpx;
color: #666;
margin-bottom: 10rpx;
}
.price-container {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10rpx;
}
.group-price {
font-size: 28rpx;
color: #e63946;
margin-right: 10rpx;
border-radius: 4rpx;
/* display: flex; */
}
.group-price-box {
display: flex;
}
.group-price1 {
width: 100rpx;
padding: 10rpx 15rpx;
color: #ffffff;
background-color: #fc5d15;
border-radius: 15rpx 0 0 15rpx;
}
.group-price2 {
width: auto;
padding: 10rpx 15rpx;
background: linear-gradient(to bottom, #fef6d6, #fee8a9);
border-radius: 0 15rpx 15rpx 0;
}
.original-price {
font-size: 26rpx;
color: #999;
}
.countdown {
width: 250rpx;
font-size: 22rpx;
padding: 10rpx 15rpx;
color: #ffffff;
margin-bottom: 15rpx;
border-radius: 50rpx;
background-color: #fe2f01;
position: absolute;
top: 150rpx;
right: 0;
}
.quantity-control {
display: flex;
align-items: center;
justify-content: flex-end;
}
.decrease-btn {
width: 40rpx;
height: 40rpx;
background-color: #f5f5f5;
border: 1rpx solid #ccc;
border-radius: 50%;
line-height: 33rpx;
text-align: center;
font-size: 28rpx;
color: #333;
}
.increase-btn {
width: 40rpx;
height: 40rpx;
background-color: #ff502a;
border-radius: 50%;
line-height: 33rpx;
text-align: center;
font-size: 28rpx;
color: #ffffff;
}
.quantity {
margin: 0 15rpx;
font-size: 24rpx;
width: 40rpx;
text-align: center;
}
/* 运费和总金额区域 */
.fee-section,
.total-section {
background-color: #fff;
padding: 30rpx;
display: flex;
justify-content: space-between;
border-bottom: 1rpx solid #eee;
}
.fee-name,
.total-name {
font-size: 30rpx;
}
.fee-value,
.total-value {
font-size: 30rpx;
color: #333;
}
.total-value {
font-weight: bold;
color: #FF7658;
}
/* 复制 */
.copy-icon {
width: 30rpx;
height: 30rpx;
background-image: url('https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/copy.png');
background-size: cover;
margin-left: 10rpx;
}
/* 支付方式区域 */
.payment-section {
background-color: #fff;
margin-bottom: 20rpx;
margin-top: 15rpx;
}
.payment-item {
padding: 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1rpx solid #eee;
}
.payment-icon {
width: 60rpx;
height: 60rpx;
margin-right: 20rpx;
}
.payment-icon image {
width: 100%;
height: 100%;
}
.payment-content {
flex: 1;
}
.payment-name {
font-size: 32rpx;
margin-bottom: 5rpx;
}
.payment-desc {
font-size: 26rpx;
color: #333;
}
.payment-select {
color: #FF7658;
}
/* 立即支付按钮 */
.pay-button {
height: 100rpx;
line-height: 100rpx;
text-align: center;
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
color: #fff;
font-size: 36rpx;
font-weight: bold;
border-radius: 50rpx;
position: fixed;
bottom: 50rpx;
left: 15%;
width: 70%;
/* z-index: 99; */
}
/* 自提样式 */
.pickup-info {
padding: 30rpx;
background-color: #fff;
}
.pickup-address {
font-size: 30rpx;
margin-bottom: 10rpx;
}
.pickup-time {
font-size: 28rpx;
color: #999;
}
/* 弹窗 */
.shadow {
background: rgba(0, 0, 0, 0.4);
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 9;
}
.shadowBox2 {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: auto;
height: auto;
}
.shadowBox_img {
width: 600rpx;
height: 800rpx;
background-color: #fff;
border-radius: 20rpx;
position: relative;
}
.boxshadow_tit {
font-size: 32rpx;
color: #222222;
padding-top: 40rpx;
display: flex;
justify-content: center;
align-items: center;
}
.boxshadow_tit_img {
width: 70rpx;
height: 70rpx;
margin-right: 10rpx;
}
.boxshadow_img {
/* width: 300rpx;
height: 300rpx; */
margin: 0 auto;
margin-top: 40rpx;
text-align: center;
}
.wealBoxTit {
display: flex;
align-items: flex-end;
margin-top: 30rpx;
margin-left: 20rpx;
}
.wealBoxTit1 {
color: #fe1535;
font-size: 32rpx;
font-weight: bold;
}
.wealBoxTit2 {
color: #fe1535;
font-size: 26rpx;
margin-left: 15rpx;
}
.wealBox {
width: 93%;
height: 170rpx;
margin: 15rpx auto;
display: flex;
}
.wealBoxItem {
width: 150rpx;
height: 150rpx;
margin: 0 10rpx;
border-radius: 15rpx;
padding: 20rpx 10rpx;
text-align: center;
display: flex;
/* 添加 flex 布局 */
flex-direction: column;
/* 设置主轴为垂直方向 */
justify-content: space-between;
/* 垂直方向上平均分布 */
align-items: center;
/* 水平方向居中 */
}
.wealBoxItem1 {
background-color: #fff4f1;
}
.wealBoxItem2 {
background-color: #fff7f1;
}
.wealBoxItem3 {
background-color: #fffaf0;
}
.wealBoxItemTop {
display: flex;
align-items: center;
justify-content: center;
}
.wealBoxItemTop image {
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
.wealBoxItemBottom {
font-size: 26rpx;
color: #999999;
}
.bottom {
width: 100%;
position: absolute;
bottom: 30rpx;
}
.boxbottom1 {
margin: 0 auto;
}
.boxbottom {
width: 100%;
margin-bottom: 50rpx;
display: flex;
justify-content: center;
align-items: center;
}
.line1 {
width: 80rpx;
height: 1rpx;
margin: 0 10rpx;
background: linear-gradient(to left, #333, #fff);
}
.line2 {
width: 80rpx;
height: 1rpx;
margin: 0 10rpx;
background: linear-gradient(to right, #333, #fff);
}
.shadowBox1 {
width: 100%;
display: flex;
margin-bottom: 30rpx;
}
.shadowBox1Item_btn {
width: 110rpx;
height: 150rpx;
border: 1rpx solid red;
position: absolute;
left: 100rpx;
opacity: 0;
}
.shadowBox2Item_btn {
width: 110rpx;
height: 150rpx;
border: 1rpx solid red;
position: absolute;
right: 100rpx;
opacity: 0;
}
.shadowBox1Item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: #000000;
}
.shadowBox1Item image {
width: 100rpx;
height: 100rpx;
margin-bottom: 26rpx;
}
.shadowBoxInfo {
display: flex;
align-items: center;
margin-left: 62rpx;
margin-top: 11rpx;
}
.shadowboxInfo_left {
width: 130rpx;
height: 130rpx;
background: #EFEFEF;
border-radius: 50%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
margin-right: 36rpx;
}
.shadowboxInfo_right_1 {
font-size: 32rpx;
color: #222222;
margin-bottom: 10rpx;
}
.shadowboxInfo_right_2 {
font-size: 26rpx;
color: #999999;
}
.shadowBox_btn {
font-size: 36rpx;
color: #FFFFFF;
width: 600rpx;
height: 90rpx;
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
border-radius: 100rpx 100rpx 100rpx 100rpx;
display: flex;
align-items: center;
justify-content: center;
margin-top: 60rpx;
}
.empty-tip {
height: 200rpx;
font-size: 28rpx;
color: #999999;
text-align: center;
line-height: 200rpx;
background-color: #fff;
}

View File

@ -0,0 +1,478 @@
<template>
<view class="container">
<!-- 顶部切换栏 -->
<view class="tab-bar">
<view :class="{ active: activeTab === 'delivery' }" class="tab-item" @click="switchTab('delivery')">配送
</view>
</view>
<!-- 分隔线 -->
<view class="divider"></view>
<!-- 配送信息 -->
<view class="info-section" v-if="activeTab === 'delivery'">
<view class="address-section">
<view class="section-title">
收货地址
<view v-if="!defAddress" class="addNewAddress" @click="chooseAddress">添加新地址 &gt;</view>
</view>
<view class="address-info" @click="chooseAddress" v-if="defAddress">
<view class="address-main">
<view class="address-name-phone">
<text class="name">{{ defAddress.name }}</text>
<text class="phone">{{ defAddress.phone }}</text>
</view>
<view class="address-detail">
{{ defAddress.address }}{{ defAddress.house_number }}
<view class="copy-icon" @click.stop="copyAddress" />
</view>
</view>
<view class="address-arrow"><u-icon name="arrow-right" size="25"></u-icon></view>
</view>
</view>
</view>
<!-- 分隔线 -->
<view class="divider"></view>
<!-- 商品信息 -->
<view v-if="activeTab === 'delivery' && orderList.length > 0">
<view class="goods-list">
<view class="goods-item" v-for="(item, index) in orderList" :key="index">
<view class="goods-image">
<image :src="item.commodity_goods_info.commodity_pic" mode="aspectFill"></image>
</view>
<view class="goods-info">
<view class="goods-name">{{ item.commodity_goods_info.goods_name }}</view>
<view class="goods-desc">{{ item.commodity_goods_info.goods_spec }}</view>
<view class="price-container">
<view class="group-price">
<view>¥{{ item.commodity_goods_info.sales_price }}/{{
item.commodity_goods_info.goods_unit
}}</view>
<!-- 运费 -->
<view class="goods-desc" style="margin-top: 10rpx;">运费 ¥{{
item.commodity_goods_info.freight ? item.commodity_goods_info.freight : 0
}}</view>
</view>
<view class="quantity-control">
<view class="decrease-btn" @tap.stop="decreaseQuantity(item)">-</view>
<view class="quantity">{{ item.count }}</view>
<view class="increase-btn" @tap.stop="increaseQuantity(item)">+</view>
</view>
</view>
</view>
</view>
</view>
<!-- 总金额 -->
<view class="total-section">
<view class="total-name">总金额</view>
<view class="total-value">¥{{ calculateTotal() }}</view>
</view>
<!-- 支付方式 -->
<view class="payment-section">
<view class="payment-item" @click="selectPayment('wechat')">
<view class="payment-icon">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_wechat.png"
mode="aspectFit"></image>
</view>
<view class="payment-content">
<view class="payment-name">微信支付</view>
<view class="payment-desc"><text
style="color: #f03d0e;margin-right: 15rpx;">可用优惠券</text>单笔支付限额:¥10000.00</view>
</view>
<view class="payment-select" v-if="selectedPayment === 'wechat'">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png"
mode="aspectFit" style="width: 40rpx; height: 40rpx;"></image>
</view>
<view class="payment-select" v-else>
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png"
mode="aspectFit" style="width: 40rpx; height: 40rpx;"></image>
</view>
</view>
</view>
</view>
<view v-if="activeTab === 'delivery' && orderList.length == 0" class="empty-tip">
暂无商品数据
</view>
<!-- 立即支付按钮 -->
<view class="pay-button" @click="submitPayment">立即支付</view>
<!-- 弹窗 - 支付成功 -->
<view class="shadow" @click="changeShadow" v-if="boxshadow1">
<view class="shadowBox2">
<view class="shadowBox_img">
<view class="boxshadow_tit">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/af_√.png"
class="boxshadow_tit_img">
</image>
已支付成功
</view>
<view class="boxshadow_img">
<view v-if="verifyCode">核销码:{{ verifyCode }}</view>
</view>
<view>
<view class="wealBoxTit">
<view class="wealBoxTit1">下单福利</view>
<view class="wealBoxTit2">已获得</view>
</view>
<view class="wealBox">
<view class="wealBoxItem wealBoxItem1">
<view class="wealBoxItemTop">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/activity_fen.png"
mode="aspectFit">
</image>
<view>石榴分</view>
</view>
<view>
{{ slFen }}
</view>
<view class="wealBoxItemBottom">
可抵扣 ¥{{ slFen }}
</view>
</view>
<view class="wealBoxItem wealBoxItem2">
<view class="wealBoxItemTop">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/activity_zi.png"
mode="aspectFit">
</image>
<view>石榴籽</view>
</view>
<view>
{{ slZi }}
</view>
<view class="wealBoxItemBottom">
可抵扣 ¥{{ slZi }}
</view>
</view>
<view class="wealBoxItem wealBoxItem3">
<view class="wealBoxItemTop">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/activity_jin.png"
mode="aspectFit" />
<view>石榴金</view>
</view>
<view>
{{ slJin }}
</view>
<view class="wealBoxItemBottom">
可抵扣 ¥{{ slJin }}
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { picUrl, menuButtonInfo, request, NavgateTo } from "../../../utils";
import { apiArr } from "../../../api/shop";
export default {
data() {
return {
activeTab: 'delivery', // 默认选中配送
quantity: 1, // 商品数量
selectedPayment: 'wechat',
boxshadow1: false,
boxshadow2: false,
defAddress: {},
orderList: [],
carList: [],
slJin: 0,
slFen: 0,
slZi: 0,
// 核销码
verifyCode: '',
};
},
onLoad(options) {
this.carList = JSON.parse(options.shopCarList)
},
onShow() {
// 检查是否有选中的地址
const selectedAddress = uni.getStorageSync('selectedAddress');
if (selectedAddress && Object.keys(selectedAddress).length > 0) {
this.defAddress = selectedAddress;
// 清除选中状态,避免重复应用
uni.removeStorageSync('selectedAddress');
} else {
// 如果没有选中的地址,则获取默认地址
this.getUserAddress();
}
this.getGoodsList()
},
onUnload() {
uni.removeStorageSync('changeZTAddress')
},
methods: {
switchTab(tab) {
this.activeTab = tab;
},
//用户收货地址
getUserAddress() {
request(apiArr.getUserDefAddress, "POST", {}).then(res => {
this.defAddress = res.default_address
})
},
// 商品列表
getGoodsList() {
this.orderList = []
this.carList.forEach(item => {
// 如果图片URL不是以https开头,则拼接picUrl
if (item.commodity_goods_info.commodity_pic && item.commodity_goods_info.commodity_pic.indexOf('https') !== 0) {
item.commodity_goods_info.commodity_pic = picUrl + item.commodity_goods_info.commodity_pic
}
this.orderList.push(item)
})
},
chooseAddress() {
NavgateTo('/packages/shop/address/index')
},
decreaseQuantity(item) {
if (item.count > 0) {
item.count--
// 当数量减到0时,从carList中删除该商品
if (item.count === 0) {
const index = this.carList.findIndex(carItem => carItem.goods_id === item.goods_id);
if (index > -1) {
this.carList.splice(index, 1);
// 重新加载商品列表以更新页面显示
this.getGoodsList();
}
}
this.changeCart(item)
}
},
increaseQuantity(item) {
if (item.count >= item.commodity_goods_info.stock_quantity) {
uni.showToast({
title: '库存不足',
icon: 'none'
});
return
}
item.count++;
this.changeCart(item);
},
// 更改购物车
changeCart(item) {
const params = {
goods_id_and_count: [
{
goods_id: item.goods_id,
count: item.count,
},
],
}
request(apiArr.updateCar, "POST", params).then(res => {
uni.showToast({
title: "操作成功!",
success() { },
});
})
},
// 计算总金额
calculateTotal() {
let total = 0;
this.orderList.forEach(goods => {
total += goods.commodity_goods_info.sales_price * goods.count + (goods.commodity_goods_info.freight || 0);
});
return total.toFixed(2);
},
selectPayment(payment) {
this.selectedPayment = payment;
},
submitPayment() {
// 检查是否有收货地址
if (!this.defAddress || Object.keys(this.defAddress).length === 0) {
uni.showToast({
title: '请选择收货地址',
icon: 'none'
});
return;
}
// 检查是否存在isafterSale属性且值为true
const hasAfterSaleItem = this.carList.some(item => item.isafterSale === true);
const orderIdFromAfterSale = hasAfterSaleItem ? this.carList.find(item => item.isafterSale === true)?.orderId : null;
// 根据平台设置不同的trans_type值
// 小程序: 71, App: 51
const systemInfo = uni.getSystemInfoSync();
let trans_type = 51; // 默认App环境
// 运行时判断是否为小程序环境
if (systemInfo.platform === 'devtools' || systemInfo.platform === 'unknown') {
trans_type = 71; // 开发工具或未知环境默认为小程序
}
// 条件编译:针对不同平台设置不同值
// #ifdef MP
trans_type = 71; // 所有小程序平台
// #endif
// #ifdef APP-PLUS
trans_type = 51; // App平台
// #endif
// 如果存在isafterSale属性且为true,则跳过createOrder接口调用
if (hasAfterSaleItem && orderIdFromAfterSale) {
const param = {
order_id: orderIdFromAfterSale,
user_id: uni.getStorageSync('userId'),
trans_type: trans_type
}
request(apiArr.mergePreorder, "POST", param).then(res => {
this.handleMergePreorderResponse(res, orderIdFromAfterSale);
})
} else {
// 原始逻辑:创建订单后再进行支付
const params = {
user_id: uni.getStorageSync('userId'),
// 先判断shopCarList数据中是否包含isAdver且为true
order_cate: this.carList.some(item => item.isAdver === true) ? 3 : 1,
goods_list: [{
supplier_id: this.orderList[0].supplier_id,
supplier_name: this.orderList[0].supplier_name || '',
is_same_day: this.orderList[0].commodity_goods_info.is_same_day,
receiving_name: this.defAddress.name,
receiving_phone: this.defAddress.phone,
receiving_address: this.defAddress.address + this.defAddress.house_number,
merchant_id: this.defAddress.address_id,
goods_and_count: this.orderList.map(item => ({
goods_id: item.goods_id,
count: item.count,
price: item.commodity_goods_info.sales_price,
freight: item.commodity_goods_info.freight,
}))
}]
}
request(apiArr.createOrder, "POST", params).then(resVal => {
const param = {
order_id: resVal.order_id,
user_id: uni.getStorageSync('userId'),
trans_type: trans_type
}
request(apiArr.mergePreorder, "POST", param).then(res => {
this.handleMergePreorderResponse(res, resVal.order_id);
})
})
}
},
// 处理mergePreorder接口的响应
handleMergePreorderResponse(res, orderId) {
if (res && res.timeStamp && res.nonceStr && res.package && res.signType && res.paySign) {
// 调用微信支付
uni.requestPayment({
timeStamp: res.timeStamp,
nonceStr: res.nonceStr,
package: res.package,
signType: res.signType,
paySign: res.paySign,
success: (payRes) => {
const params = {
order_id: orderId,
from: this.carList.some(item => item.isAdver === true) ? 3 : 1,
adver_id: this.carList.some(item => item.isAdver === true) ? this.carList.find(item => item.isAdver === true).adver_id : ''
}
request(apiArr.queryOrder, "POST", params).then(res => {
this.verifyCode = res.verification_code
this.slJin = res.shiliu_money
this.boxshadow1 = true
})
},
fail: (payErr) => {
uni.showToast({
title: payErr.errMsg == 'requestPayment:fail cancel' ? '已取消支付' : '支付失败',
icon: 'none'
})
const params = {
order_ids: orderId,
}
request(apiArr.cancelPay, "POST", params).then(res => {
})
},
complete: () => {
// 支付完成后的回调,无论成功失败都会执行
}
})
} else {
console.error("获取支付参数失败,缺少必要参数")
uni.showToast({
title: '获取支付信息失败',
icon: 'none'
})
}
},
// 复制收货地址
copyAddress() {
// 使用uni-app的复制API
uni.setClipboardData({
data: this.defAddress.address + this.defAddress.house_number,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
},
openSave() {
this.boxshadow1 = false;
this.boxshadow2 = true;
},
changeShadow() {
this.boxshadow1 = false;
},
changeShadow2() {
this.boxshadow2 = false;
},
// 保存海报
saveImg() {
this.boxshadow2 = false;
// 微信小程序保存图片
uni.downloadFile({
url: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png",
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: (res) => {
uni.showToast({
title: "保存成功",
icon: "success",
duration: 2000,
});
},
fail: (err) => {
console.log("保存失败", err);
},
});
}
},
fail: (err) => {
console.log("下载失败", err);
},
});
},
}
};
</script>
<style>
@import url('./index.css');
</style>

View File

@ -375,9 +375,10 @@ page {
.shadowBox_img { .shadowBox_img {
width: 600rpx; width: 600rpx;
height: 500rpx; height: 800rpx;
background-color: #fff; background-color: #fff;
border-radius: 20rpx; border-radius: 20rpx;
position: relative;
} }
.boxshadow_tit { .boxshadow_tit {
@ -403,9 +404,88 @@ page {
text-align: center; text-align: center;
} }
.wealBoxTit {
display: flex;
align-items: flex-end;
margin-top: 30rpx;
margin-left: 20rpx;
}
.wealBoxTit1 {
color: #fe1535;
font-size: 32rpx;
font-weight: bold;
}
.wealBoxTit2 {
color: #fe1535;
font-size: 26rpx;
margin-left: 15rpx;
}
.wealBox{
width: 93%;
height: 170rpx;
margin: 15rpx auto;
display: flex;
}
.wealBoxItem{
width: 150rpx;
height: 150rpx;
margin: 0 10rpx;
border-radius: 15rpx;
padding: 20rpx 10rpx;
text-align: center;
display: flex; /* 添加 flex 布局 */
flex-direction: column; /* 设置主轴为垂直方向 */
justify-content: space-between; /* 垂直方向上平均分布 */
align-items: center; /* 水平方向居中 */
}
.wealBoxItem1{
background-color: #fff4f1;
}
.wealBoxItem2{
background-color: #fff7f1;
}
.wealBoxItem3{
background-color: #fffaf0;
}
.wealBoxItemTop{
display: flex;
align-items: center;
justify-content: center;
}
.wealBoxItemTop image{
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
.wealBoxItemBottom{
font-size: 26rpx;
color: #999999;
}
.bottom {
width: 100%;
position: absolute;
bottom: 30rpx;
}
.boxbottom1 {
margin: 0 auto;
}
.boxbottom { .boxbottom {
width: 100%; width: 100%;
margin-top: 50rpx; margin-bottom: 50rpx;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -428,25 +508,25 @@ page {
.shadowBox1 { .shadowBox1 {
width: 100%; width: 100%;
display: flex; display: flex;
margin-top: 30rpx; margin-bottom: 30rpx;
} }
.shadowBox1Item_btn{ .shadowBox1Item_btn {
width: 110rpx; width: 110rpx;
height: 150rpx; height: 150rpx;
border: 1rpx solid red; border: 1rpx solid red;
position: absolute; position: absolute;
left: 100rpx; left: 100rpx;
opacity:0; opacity: 0;
} }
.shadowBox2Item_btn{ .shadowBox2Item_btn {
width: 110rpx; width: 110rpx;
height: 150rpx; height: 150rpx;
border: 1rpx solid red; border: 1rpx solid red;
position: absolute; position: absolute;
right: 100rpx; right: 100rpx;
opacity:0; opacity: 0;
} }
.shadowBox1Item { .shadowBox1Item {
@ -508,7 +588,7 @@ page {
margin-top: 60rpx; margin-top: 60rpx;
} }
.empty-tip{ .empty-tip {
height: 200rpx; height: 200rpx;
font-size: 28rpx; font-size: 28rpx;
color: #999999; color: #999999;

View File

@ -43,7 +43,7 @@
<view class="group-price"> <view class="group-price">
<view>¥{{ item.commodity_goods_info.sales_price }}/{{ <view>¥{{ item.commodity_goods_info.sales_price }}/{{
item.commodity_goods_info.goods_unit item.commodity_goods_info.goods_unit
}}</view> }}</view>
<!-- 运费 --> <!-- 运费 -->
<view class="goods-desc" style="margin-top: 10rpx;">运费 ¥{{ <view class="goods-desc" style="margin-top: 10rpx;">运费 ¥{{
item.commodity_goods_info.freight }}</view> item.commodity_goods_info.freight }}</view>
@ -233,38 +233,88 @@
已支付成功 已支付成功
</view> </view>
<view class="boxshadow_img"> <view class="boxshadow_img">
<view>核销码:{{ verifyCode }}</view> <view v-if="verifyCode">核销码:{{ verifyCode }}</view>
<!-- <image <!-- <image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png"> src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png">
</image> --> </image> -->
</view> </view>
<view class="boxbottom"> <view>
<view class="line1"></view> <view class="wealBoxTit">
赶快邀请好友来下单吧 <view class="wealBoxTit1">下单福利</view>
<view class="line2"></view> <view class="wealBoxTit2">已获得</view>
</view>
<view class="wealBox">
<view class="wealBoxItem wealBoxItem1">
<view class="wealBoxItemTop">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/activity_fen.png" mode="aspectFit">
</image>
<view>石榴分</view>
</view>
<view>
{{ slFen }}
</view>
<view class="wealBoxItemBottom">
可抵扣 ¥{{ slFen }}
</view>
</view>
<view class="wealBoxItem wealBoxItem2">
<view class="wealBoxItemTop">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/activity_zi.png" mode="aspectFit">
</image>
<view>石榴籽</view>
</view>
<view>
{{ slZi }}
</view>
<view class="wealBoxItemBottom">
可抵扣 ¥{{ slZi }}
</view>
</view>
<view class="wealBoxItem wealBoxItem3">
<view class="wealBoxItemTop">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/activity_jin.png" mode="aspectFit"/>
<view>石榴金</view>
</view>
<view>
{{ slJin }}
</view>
<view class="wealBoxItemBottom">
可抵扣 ¥{{ slJin }}
</view>
</view>
</view>
</view> </view>
<view @click.stop="changeShadow"> <view class="bottom">
<view class="shadowBox1"> <view class="boxbottom1">
<button class="shadowBox1Item_btn" open-type="share" bindtap="onShareButtonClick" /> <view class="boxbottom">
<view class="shadowBox1Item"> <view class="line1"></view>
<image 赶快邀请好友来下单吧
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png" <view class="line2"></view>
mode="aspectFill"></image>
微信好友
</view> </view>
<button class="shadowBox2Item_btn" open-type="share" bindtap="onShareButtonClick" /> <view @click.stop="changeShadow">
<view class="shadowBox1Item" @click="shareFriend"> <view class="shadowBox1">
<image <button class="shadowBox1Item_btn" open-type="share" bindtap="onShareButtonClick" />
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png" <view class="shadowBox1Item">
mode="aspectFill"></image> <image
小程序链接 src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png"
</view> mode="aspectFill"></image>
<!-- <view class="shadowBox1Item" @click="openSave"> 微信好友
</view>
<button class="shadowBox2Item_btn" open-type="share" bindtap="onShareButtonClick" />
<view class="shadowBox1Item" @click="shareFriend">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png"
mode="aspectFill"></image>
小程序链接
</view>
<!-- <view class="shadowBox1Item" @click="openSave">
<image <image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_saveImg.png" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_saveImg.png"
mode="aspectFill"></image> mode="aspectFill"></image>
二维码海报 二维码海报
</view> --> </view> -->
</view>
</view>
</view> </view>
</view> </view>
</view> </view>
@ -315,11 +365,18 @@ export default {
orderList2: [], orderList2: [],
carList: [], carList: [],
slJin: 0,
slFen: 0,
slZi: 0,
// 团购活动id // 团购活动id
group_buy_activity_id: 0, group_buy_activity_id: 0,
// 核销码 // 核销码
verifyCode: '', verifyCode: '',
// 是否在团购活动时间内
isGroupBuyValid: true
}; };
}, },
computed: { computed: {
@ -338,7 +395,6 @@ export default {
}, },
onLoad(options) { onLoad(options) {
this.carList = JSON.parse(options.shopCarList) this.carList = JSON.parse(options.shopCarList)
console.log("🚀 ~ onLoad ~ JSON.parse(options.shopCarList):", JSON.parse(options.shopCarList))
}, },
onShow() { onShow() {
this.getUserAddress() this.getUserAddress()
@ -425,7 +481,6 @@ export default {
} }
}, },
increaseQuantity(item) { increaseQuantity(item) {
console.log("🚀 ~ increaseQuantity ~ item:", item)
const currentTime = new Date().getTime(); const currentTime = new Date().getTime();
const startTime = new Date(item.commodity_goods_info.group_buy_activity_info?.start_time).getTime(); const startTime = new Date(item.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(item.commodity_goods_info.group_buy_activity_info?.end_time).getTime(); const endTime = new Date(item.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
@ -540,7 +595,7 @@ export default {
// 团购活动时间判断 // 团购活动时间判断
const currentTime = new Date().getTime(); const currentTime = new Date().getTime();
let isGroupBuyValid = true; this.isGroupBuyValid = true;
// 检查所有商品是否在团购活动时间内 // 检查所有商品是否在团购活动时间内
for (let supplierId in this.supplierGroups) { for (let supplierId in this.supplierGroups) {
@ -549,18 +604,18 @@ export default {
const activityInfo = item.commodity_goods_info.group_buy_activity_info; const activityInfo = item.commodity_goods_info.group_buy_activity_info;
// 如果没有团购活动信息,或者不在活动时间内,则isGroupBuyValid设为false // 如果没有团购活动信息,或者不在活动时间内,则isGroupBuyValid设为false
if (!activityInfo) { if (!activityInfo) {
isGroupBuyValid = false; this.isGroupBuyValid = false;
break; break;
} }
const startTime = new Date(activityInfo.start_time).getTime(); const startTime = new Date(activityInfo.start_time).getTime();
const endTime = new Date(activityInfo.end_time).getTime(); const endTime = new Date(activityInfo.end_time).getTime();
if (!(currentTime >= startTime && currentTime <= endTime)) { if (!(currentTime >= startTime && currentTime <= endTime)) {
isGroupBuyValid = false; this.isGroupBuyValid = false;
break; break;
} }
} }
if (!isGroupBuyValid) break; if (!this.isGroupBuyValid) break;
} }
// 检查是否存在isafterSale属性且值为true // 检查是否存在isafterSale属性且值为true
@ -600,7 +655,8 @@ export default {
// 原始逻辑:创建订单后再进行支付 // 原始逻辑:创建订单后再进行支付
const params = { const params = {
user_id: uni.getStorageSync('userId'), user_id: uni.getStorageSync('userId'),
is_group_buy: isGroupBuyValid, // 先判断shopCarList数据中是否包含isAdver且为true
order_cate : this.carList.some(item => item.isAdver === true) ? 3 : (this.isGroupBuyValid ? 2 : 1),
goods_list: Object.keys(this.supplierGroups).map(supplierId => { goods_list: Object.keys(this.supplierGroups).map(supplierId => {
const group = this.supplierGroups[supplierId]; const group = this.supplierGroups[supplierId];
const firstItem = group[0]; const firstItem = group[0];
@ -662,11 +718,13 @@ export default {
success: (payRes) => { success: (payRes) => {
const params = { const params = {
order_id: orderId, order_id: orderId,
from: 2, from: this.carList.some(item => item.isAdver === true) ? 3 : (this.isGroupBuyValid ? 2 : 1),
group_buy_activity_id: this.group_buy_activity_id, group_buy_activity_id: this.group_buy_activity_id,
adver_id: this.carList.some(item => item.isAdver === true) ? this.carList.find(item => item.isAdver === true).adver_id : ''
} }
request(apiArr.queryOrder, "POST", params).then(res => { request(apiArr.queryOrder, "POST", params).then(res => {
this.verifyCode = res.verification_code this.verifyCode = res.verification_code
this.slJin = res.shiliu_money
this.boxshadow1 = true this.boxshadow1 = true
}) })
}, },

View File

@ -315,11 +315,11 @@ page {
} }
.CateList_Box { .CateList_Box {
width: 71.5%; width: 95%;
display: flex; display: flex;
overflow: hidden; overflow: hidden;
/* position: relative; */ position: relative;
position: fixed; /* position: fixed; */
z-index: 15; z-index: 15;
padding: 20rpx 10rpx; padding: 20rpx 10rpx;
background-color: #ffffff; background-color: #ffffff;
@ -368,7 +368,7 @@ page {
} }
.CateIte { .CateIte {
margin-top: 80rpx; /* margin-top: 80rpx; */
} }
.CateInfo { .CateInfo {

View File

@ -63,7 +63,8 @@
{{ item.category_name }} {{ item.category_name }}
</view> </view>
</view> </view>
<view class="Con_right" v-if="tagList1.length > 0"> <view class="Con_right" v-if="tagList1.length > 0" ref="conRightRef"
:style="{ overflow: cateListShow ? 'hidden' : 'auto' }">
<view class="CateList_Box" :class="cateListShow ? 'bgf' : ''"> <view class="CateList_Box" :class="cateListShow ? 'bgf' : ''">
<view class="CateList" ref="cateListRef"> <view class="CateList" ref="cateListRef">
<view class="CateList_Item" v-for="(item, index) in tagList" :key="item.id" <view class="CateList_Item" v-for="(item, index) in tagList" :key="item.id"
@ -135,14 +136,14 @@
</view> </view>
</view> </view>
<view class="gg" @click="chooseGG(item,items)" v-if=" <view class="gg" @click="chooseGG(item, items)" v-if="
items.commodity_goods_info_list.length > 1 && !items.isShow items.commodity_goods_info_list.length > 1 && !items.isShow
"> ">
选择规格 选择规格
<u-icon name="arrow-down" size="26rpx" color="#FF370B"></u-icon> <u-icon name="arrow-down" size="26rpx" color="#FF370B"></u-icon>
</view> </view>
<view class="gg" @click="chooseGG(item,items)" v-if=" <view class="gg" @click="chooseGG(item, items)" v-if="
items.commodity_goods_info_list.length > 1 && items.isShow items.commodity_goods_info_list.length > 1 && items.isShow
"> ">
收起 收起
@ -152,7 +153,8 @@
</view> </view>
<view class="GGList" v-if="items.isShow"> <view class="GGList" v-if="items.isShow">
<view class="GGItem" v-for="ite in items.commodity_goods_info_list" :key="ite.id" @click="goods(ite,items)"> <view class="GGItem" v-for="ite in items.commodity_goods_info_list" :key="ite.id"
@click="goods(ite, items)">
<view class="GGItem_Image"> <view class="GGItem_Image">
<view class="tag tag-img" v-if="ite.is_same_day">当日达</view> <view class="tag tag-img" v-if="ite.is_same_day">当日达</view>
<image :src="picUrl + ite.commodity_pic" mode="aspectFill"></image> <image :src="picUrl + ite.commodity_pic" mode="aspectFill"></image>
@ -227,6 +229,7 @@ export default {
search: "", search: "",
value: "1", value: "1",
cateListShow: false, cateListShow: false,
scrollTop: 0,
conRightElement: null, conRightElement: null,
iconList: [ iconList: [
{ {
@ -325,6 +328,20 @@ export default {
//顶部分类点击 //顶部分类点击
changeCateListShow() { changeCateListShow() {
this.cateListShow = !this.cateListShow; this.cateListShow = !this.cateListShow;
// 当cateListShow展开时,禁止Con_right滚动
if (this.conRightRef) {
if (this.cateListShow) {
// 保存当前滚动位置
this.scrollTop = this.conRightRef.scrollTop;
} else {
// 恢复滚动位置
setTimeout(() => {
if (this.conRightRef) {
this.conRightRef.scrollTop = this.scrollTop || 0;
}
}, 0);
}
}
}, },
//选择右下角分类 //选择右下角分类
checkItem(index) { checkItem(index) {
@ -338,7 +355,7 @@ export default {
this.topShow = !this.topShow; this.topShow = !this.topShow;
}, },
// 选择商品规格 // 选择商品规格
chooseGG(item,targetItems) { chooseGG(item, targetItems) {
// 根据两个参数的id判断点击的数据 // 根据两个参数的id判断点击的数据
if (item && targetItems && item.id) { if (item && targetItems && item.id) {
for (let i = 1; i < this.tagList.length; i++) { for (let i = 1; i < this.tagList.length; i++) {
@ -362,7 +379,7 @@ export default {
NavgateTo("../search/index"); NavgateTo("../search/index");
}, },
//商品详情页 //商品详情页
goods(ite,items) { goods(ite, items) {
NavgateTo(`../goods/index?item=${JSON.stringify(ite)}`); NavgateTo(`../goods/index?item=${JSON.stringify(ite)}`);
}, },
@ -447,7 +464,7 @@ export default {
let currentQuantity = 0; let currentQuantity = 0;
let stockQuantity = 0; let stockQuantity = 0;
let goodsToUpdate = null; let goodsToUpdate = null;
// 对于有规格的主商品(绑定到items.commodity_goods_info_list[0].quantity) // 对于有规格的主商品(绑定到items.commodity_goods_info_list[0].quantity)
if ( if (
item.commodity_goods_info_list && item.commodity_goods_info_list &&
@ -465,7 +482,7 @@ export default {
stockQuantity = item.stock_quantity || 0; stockQuantity = item.stock_quantity || 0;
goodsToUpdate = item; goodsToUpdate = item;
} }
// 判断是否增加数量且库存不足 // 判断是否增加数量且库存不足
if (quantity > currentQuantity && currentQuantity >= stockQuantity) { if (quantity > currentQuantity && currentQuantity >= stockQuantity) {
uni.showToast({ uni.showToast({
@ -474,7 +491,7 @@ export default {
}); });
return; return;
} }
// 使用$set确保响应式更新 // 使用$set确保响应式更新
this.$set(goodsToUpdate, 'quantity', quantity); this.$set(goodsToUpdate, 'quantity', quantity);

View File

@ -38,12 +38,12 @@
<!-- 未搜索到 --> <!-- 未搜索到 -->
<view class="empty" v-if="isSearched && searchGoodsLisat.length == 0"> <view class="empty" v-if="isSearched && !searchGoodsLisat">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_noSearch.png"></image> <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_noSearch.png"></image>
对不起没有找到您想要的商品 对不起没有找到您想要的商品
</view> </view>
<view class="searchList" v-if="isSearched && searchGoodsLisat.length > 0"> <view class="searchList" v-if="isSearched && searchGoodsLisat && searchGoodsLisat.length > 0">
<!-- <view class="searchSubTit"> <!-- <view class="searchSubTit">
<view class="searchSubItem">综合</view> <view class="searchSubItem">综合</view>
<view class="searchSubItem"> <view class="searchSubItem">
@ -78,7 +78,7 @@
{{ getPriceRange(item.commodity_goods_info_list) }} {{ getPriceRange(item.commodity_goods_info_list) }}
</view> </view>
<view class="CateInfo_Item_Money_right" v-if="!(item.commodity_goods_info_list.length > 1)"> <view class="CateInfo_Item_Money_right" v-if="!(item.commodity_goods_info_list.length > 1)">
<u-number-box :min="0" v-model="item.commodity_goods_info_list[0].quantity" <u-number-box :value="item.commodity_goods_info_list[0].quantity || 0" :min="0"
@change="(value) => handleQuantityChange(value, item)"> @change="(value) => handleQuantityChange(value, item)">
<view slot="minus" class="minus"> <view slot="minus" class="minus">
<u-icon name="minus" size="20"></u-icon> <u-icon name="minus" size="20"></u-icon>
@ -112,24 +112,23 @@
</view> </view>
<view class="GGList" v-if="item.isShow"> <view class="GGList" v-if="item.isShow">
<view class="GGItem" v-for="ite in item.commodity_goods_info_list" :key="ite.id" <view class="GGItem" v-for="ite in item.commodity_goods_info_list" :key="ite.id">
@click="goods(item)"> <view class="GGItem_Image" @click="goods(item)">
<view class="GGItem_Image">
<view class="tag tag-img" v-if="ite.is_same_day">当日达</view> <view class="tag tag-img" v-if="ite.is_same_day">当日达</view>
<image :src="handleImageUrl(ite.commodity_pic)" mode="aspectFill"></image> <image :src="handleImageUrl(ite.commodity_pic)" mode="aspectFill"></image>
</view> </view>
<view class="GGItem_Con"> <view class="GGItem_Con">
<view class="GGItem_Con_Tit"> <view class="GGItem_Con_Tit" @click="goods(item)">
<view class="tag tag-text" v-if="ite.is_same_day">当日达</view> <view class="tag tag-text" v-if="ite.is_same_day">当日达</view>
{{ ite.goods_name }} {{ ite.goods_name }}
</view> </view>
<view class="GGItem_Con_Msg"> <view class="GGItem_Con_Msg">
<view class="GGItem_Con_Msg_left"> <view class="GGItem_Con_Msg_left" @click="goods(item)">
<span>¥</span>{{ ite.sales_price }} <span>¥</span>{{ ite.sales_price }}
</view> </view>
<view class="GGItem_Con_Msg_right"> <view class="GGItem_Con_Msg_right">
<u-number-box v-model="ite.quantity" :min="0" <u-number-box :value="ite.quantity || 0" :min="0"
@change="(value) => handleQuantityChange(value, ite)"> @change="(value) => handleQuantityChange.stop(value, ite)">
<view slot="minus" class="minus"> <view slot="minus" class="minus">
<u-icon name="minus" size="20"></u-icon> <u-icon name="minus" size="20"></u-icon>
</view> </view>
@ -185,7 +184,7 @@ export default {
}, },
// 获取购物车数据 // 获取购物车数据
getShopCarList() { getShopCarList() {
request(apiArr.getCar, "POST").then((res) => { return request(apiArr.getCar, "POST").then((res) => {
this.value = res.total; this.value = res.total;
// 合并当日达和普通商品数据 // 合并当日达和普通商品数据
this.goodsDetail = [].concat(res.same_day_cart_list || [], res.normal_cart_list || []) this.goodsDetail = [].concat(res.same_day_cart_list || [], res.normal_cart_list || [])
@ -207,7 +206,7 @@ export default {
request(apiArr.goodsSearch, "POST", params).then((res) => { request(apiArr.goodsSearch, "POST", params).then((res) => {
// 深拷贝接口数据,避免引用问题 // 深拷贝接口数据,避免引用问题
const commodityList = JSON.parse(JSON.stringify(res.commodity_list)); const commodityList = JSON.parse(JSON.stringify(res.commodity_list));
commodityList.forEach((item) => { commodityList?.forEach((item) => {
// 初始化isShow为响应式属性 // 初始化isShow为响应式属性
this.$set(item, 'isShow', false); this.$set(item, 'isShow', false);
item.commodity_goods_info_list.forEach((param) => { item.commodity_goods_info_list.forEach((param) => {
@ -215,7 +214,7 @@ export default {
const goods = this.goodsDetail.find(g => g.goods_id === param.id); const goods = this.goodsDetail.find(g => g.goods_id === param.id);
this.$set(param, 'quantity', goods ? goods.count : 0); this.$set(param, 'quantity', goods ? goods.count : 0);
}); });
}); }) || [];
this.searchGoodsLisat = commodityList; this.searchGoodsLisat = commodityList;
}); });
} }
@ -293,25 +292,49 @@ export default {
}, },
// 处理商品数量变化 // 处理商品数量变化
handleQuantityChange(val, item) { handleQuantityChange(val, item) {
// 先在前端直接更新数量,确保页面显示及时变化
// 注意:这里的val可能是直接的数值,也可能是包含value属性的对象
const quantity = typeof val === 'object' && val !== null && 'value' in val ? val.value : val; const quantity = typeof val === 'object' && val !== null && 'value' in val ? val.value : val;
// 检查库存数量
let currentQuantity = 0;
let stockQuantity = 0;
let goodsToUpdate = null;
// 对于有规格的主商品(绑定到items.commodity_goods_info_list[0].quantity) // 对于有规格的主商品(绑定到items.commodity_goods_info_list[0].quantity)
if (item.commodity_goods_info_list && item.commodity_goods_info_list.length) { if (
item.commodity_goods_info_list &&
item.commodity_goods_info_list.length
) {
this.goodsId = item.commodity_goods_info_list[0].id; this.goodsId = item.commodity_goods_info_list[0].id;
// 使用$set确保响应式更新 currentQuantity = item.commodity_goods_info_list[0].quantity || 0;
this.$set(item.commodity_goods_info_list[0], 'quantity', quantity); stockQuantity = item.commodity_goods_info_list[0].stock_quantity || 0;
goodsToUpdate = item.commodity_goods_info_list[0];
} }
// 对于规格列表中的商品(绑定到ite.quantity) // 对于规格列表中的商品(绑定到ite.quantity)
else { else {
this.goodsId = item.id; this.goodsId = item.id;
// 使用$set确保响应式更新 currentQuantity = item.quantity || 0;
this.$set(item, 'quantity', quantity); stockQuantity = item.stock_quantity || 0;
goodsToUpdate = item;
} }
// 直接检查新数量是否超过库存,如果超过则不允许修改
if (quantity > stockQuantity) {
uni.showToast({
title: "库存不足",
icon: 'none'
});
// 强制重置数量为当前值或库存值,确保UI上显示的数量不会超过库存
this.$nextTick(() => {
this.$set(goodsToUpdate, 'quantity', Math.min(currentQuantity, stockQuantity));
});
return;
}
// 使用$set确保响应式更新
this.$set(goodsToUpdate, 'quantity', quantity);
const params = { const params = {
user_id: uni.getStorageSync('userId'), user_id: uni.getStorageSync("userId"),
goods_id_and_count: [ goods_id_and_count: [
{ {
goods_id: this.goodsId, goods_id: this.goodsId,
@ -319,32 +342,36 @@ export default {
}, },
], ],
}; };
request(apiArr.updateCar, 'POST', params).then((res) => { // 发送请求更新后端数据
request(apiArr.updateCar, "POST", params).then((res) => {
console.log(res); console.log(res);
// 更新购物车数据 // 先更新购物车数据
this.getShopCarList(); this.getShopCarList();
// 延迟时间,确保goodsDetail已经更新 // 延迟一小段时间,确保goodsDetail已经更新
setTimeout(() => { setTimeout(() => {
// 重新同步商品列表中的数量 // 重新同步商品列表中的数量
this.syncGoodsQuantities(); this.syncGoodsQuantities();
}, 100); }, 100);
uni.showToast({ uni.showToast({
title: '操作成功!', title: "操作成功!",
success() { }, success() { },
}); });
}); });
}, },
// 同步商品列表中的数量与购物车数据 // 同步商品列表中的数量与购物车数据
syncGoodsQuantities() { syncGoodsQuantities() {
// 遍历所有商品,同步数量 // 遍历所有商品,同步数量
this.searchGoodsLisat.forEach((item) => { this.searchGoodsLisat?.forEach((item) => {
item.commodity_goods_info_list.forEach((param) => { item.commodity_goods_info_list.forEach((param) => {
const goods = this.goodsDetail.find(g => g.goods_id === param.id); const goods = this.goodsDetail.find(g => g.goods_id === param.id);
if (goods) { if (goods) {
this.$set(param, 'quantity', goods.count); this.$set(param, 'quantity', goods.count);
}else{
this.$set(param, 'quantity', 0);
} }
}); });
}); });
@ -382,7 +409,12 @@ export default {
this.isSearched = false; this.isSearched = false;
}, },
onShow() { onShow() {
this.getShopCarList(); this.getShopCarList().then(() => {
// 延迟一小段时间确保购物车数据已完全更新,然后同步商品数量
setTimeout(() => {
this.syncGoodsQuantities();
}, 100);
});
}, },
onReachBottom() { onReachBottom() {
if (this.flag) { if (this.flag) {

View File

@ -228,7 +228,8 @@ export default {
isDayshow: false, isDayshow: false,
isParcelPostchecked: false, isParcelPostchecked: false,
parcelPostshow: false, parcelPostshow: false,
is_group_buy: '' is_group_buy: '',
is_adver: ''
}; };
}, },
// watch: { // watch: {
@ -297,14 +298,24 @@ export default {
this.$u.toast("请选择商品"); this.$u.toast("请选择商品");
return; return;
} }
// 给每个商品添加isAdver=true参数
const updatedArr = arr.map(item => ({
...item,
isAdver: item.adver_id ? true : ''
}));
// NavgateTo(`../submitOrder/index?shopCarList=${JSON.stringify(arr)}`); // NavgateTo(`../submitOrder/index?shopCarList=${JSON.stringify(arr)}`);
NavgateTo(`../groupPurchaseSubmit/index?shopCarList=${JSON.stringify(arr)}`); if(this.is_group_buy){
NavgateTo(`../groupPurchaseSubmit/index?shopCarList=${JSON.stringify(updatedArr)}`);
}else{
NavgateTo(`../goodsSubmit/index?shopCarList=${JSON.stringify(updatedArr)}`);
}
}, },
// 获取购物车列表 // 获取购物车列表
getShopCar() { getShopCar() {
const params = { const params = {
is_group_buy: this.is_group_buy is_group_buy: this.is_group_buy,
is_adver: this.is_adver
} }
request(apiArr.getCar, "POST", params).then((res) => { request(apiArr.getCar, "POST", params).then((res) => {
if (res.normal_cart_list.length > 0) { if (res.normal_cart_list.length > 0) {
@ -728,6 +739,7 @@ export default {
this.top = meun.top; this.top = meun.top;
this.localHeight = meun.height; this.localHeight = meun.height;
this.is_group_buy = options.item ? JSON.parse(options.item).is_group_buy : '' this.is_group_buy = options.item ? JSON.parse(options.item).is_group_buy : ''
this.is_adver = options.item ? JSON.parse(options.item).is_adver : ''
this.getShopCar(); this.getShopCar();
}, },
onShow() { onShow() {

View File

@ -46,6 +46,13 @@
<input type="text" v-model="contact_phone" placeholder="请输入联系方式"> <input type="text" v-model="contact_phone" placeholder="请输入联系方式">
</view> </view>
</view> </view>
<view class="row">
<view class="row_label">商家分类</view>
<view class="row_con" @click="chooseClassify">
<input type="text" disabled v-model="confirmClassify.cate_name" placeholder="请选择商家分类">
<u-icon name="arrow-right" color="#999999" size="28"></u-icon>
</view>
</view>
<view class="row"> <view class="row">
<view class="row_label">银行卡号</view> <view class="row_label">银行卡号</view>
<view class="row_con nonebor"> <view class="row_con nonebor">
@ -61,7 +68,9 @@
<u-upload :fileList="imgList" @afterRead="afterReadImg" @delete="deletePic" name="1" multiple <u-upload :fileList="imgList" @afterRead="afterReadImg" @delete="deletePic" name="1" multiple
:maxCount="10"> :maxCount="10">
<view class="imgCon"> <view class="imgCon">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png" mode="widthFix"></image> <image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png"
mode="widthFix"></image>
上传图片 上传图片
</view> </view>
</u-upload> </u-upload>
@ -74,7 +83,9 @@
<u-upload :fileList="imgList3" @afterRead="afterReadImg2" @delete="deletePic2" name="1" multiple <u-upload :fileList="imgList3" @afterRead="afterReadImg2" @delete="deletePic2" name="1" multiple
:maxCount="10"> :maxCount="10">
<view class="imgCon"> <view class="imgCon">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png" mode="widthFix"></image> <image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png"
mode="widthFix"></image>
上传图片 上传图片
</view> </view>
</u-upload> </u-upload>
@ -87,7 +98,9 @@
<u-upload :fileList="imgList5" @afterRead="afterReadImg3" @delete="deletePic3" name="1" multiple <u-upload :fileList="imgList5" @afterRead="afterReadImg3" @delete="deletePic3" name="1" multiple
:maxCount="1"> :maxCount="1">
<view class="imgCon"> <view class="imgCon">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png" mode="widthFix"></image> <image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png"
mode="widthFix"></image>
上传图片 上传图片
</view> </view>
</u-upload> </u-upload>
@ -102,6 +115,8 @@
@cancel="cancelCity"></u-picker> @cancel="cancelCity"></u-picker>
<u-picker :show="show3" :columns="[buss]" keyName="short_name" @confirm="clickBuss" <u-picker :show="show3" :columns="[buss]" keyName="short_name" @confirm="clickBuss"
@cancel="cancelBuss"></u-picker> @cancel="cancelBuss"></u-picker>
<u-picker :show="show4" :columns="[classify]" keyName="cate_name" @confirm="clickClassify"
@cancel="cancelClassify"></u-picker>
</view> </view>
</template> </template>
@ -140,15 +155,18 @@ export default {
store_name: "", store_name: "",
address: "", address: "",
confirmProv:"", confirmProv: "",
confirmCity:"", confirmCity: "",
confirmBusiness:"", confirmBusiness: "",
confirmClassify: "",
pro: [], pro: [],
show: false, show: false,
city: [], city: [],
show2: false, show2: false,
buss: [], buss: [],
show3: false, show3: false,
classify: [],
show4: false,
} }
}, },
methods: { methods: {
@ -181,6 +199,14 @@ export default {
this.getCity(e.value[0].ad_code) this.getCity(e.value[0].ad_code)
this.confirmProv = e.value[0] this.confirmProv = e.value[0]
}, },
cancelClassify() {
this.show4 = false;
},
clickClassify(e) {
this.show4 = false;
this.confirmClassify = e.value[0]
console.log("🚀 ~ this.confirmClassify:", this.confirmClassify)
},
chooseCity() { chooseCity() {
this.show = true; this.show = true;
}, },
@ -190,6 +216,9 @@ export default {
chooseCity3() { chooseCity3() {
this.show3 = true; this.show3 = true;
}, },
chooseClassify() {
this.show4 = true;
},
afterReadImg(e) { afterReadImg(e) {
e.file.forEach(item => { e.file.forEach(item => {
upload(item.url, res => { upload(item.url, res => {
@ -254,24 +283,30 @@ export default {
duration: 2000 duration: 2000
}); });
} }
if(!that.confirmProv.ad_code){ if (!that.confirmProv.ad_code) {
return uni.showToast({ return uni.showToast({
title: '请选择所在省', title: '请选择所在省',
duration: 2000 duration: 2000
}); });
} }
if(!that.confirmCity.ad_code){ if (!that.confirmCity.ad_code) {
return uni.showToast({ return uni.showToast({
title: '请选择所在市', title: '请选择所在市',
duration: 2000 duration: 2000
}); });
} }
if(!that.confirmBusiness.ad_code){ if (!that.confirmBusiness.ad_code) {
return uni.showToast({ return uni.showToast({
title: '请选择所在区', title: '请选择所在区',
duration: 2000 duration: 2000
}); });
} }
if (!that.confirmClassify.id) {
return uni.showToast({
title: '请选择商家分类',
duration: 2000
});
}
if (!that.imgList6.length) { if (!that.imgList6.length) {
return uni.showToast({ return uni.showToast({
title: '请上传营业执照', title: '请上传营业执照',
@ -284,14 +319,15 @@ export default {
let license_photo = that.imgList6.join(",") let license_photo = that.imgList6.join(",")
request(apiArr.createStore, "POST", { request(apiArr.createStore, "POST", {
contact_name: that.contact_name, contact_name: that.contact_name,
contact_phone: that.contact_phone, phone: that.contact_phone,
bank_card: that.bank_card, bank_card: that.bank_card,
store_name: that.store_name, merchant_name: that.store_name,
address: that.address, address: that.address,
ad_code:that.confirmBusiness.ad_code, ad_code: that.confirmBusiness.ad_code,
facade_photo, facade_photo,
interior_photo, interior_photo,
license_photo, license_photo,
merchant_cate_id: that.confirmClassify.id,
}).then(res => { }).then(res => {
that.contact_name = '' that.contact_name = ''
that.contact_phone = '' that.contact_phone = ''
@ -307,6 +343,7 @@ export default {
that.imgList4 = [] that.imgList4 = []
that.imgList5 = [] that.imgList5 = []
that.imgList6 = [] that.imgList6 = []
that.confirmClassify = ''
NavgateTo("../sucess/index") NavgateTo("../sucess/index")
}) })
}, },
@ -332,10 +369,16 @@ export default {
this.buss = res.rows this.buss = res.rows
}) })
}, },
getClassify(e) {
request(apiArr.getMerChantCateList, "POST", {}).then(res => {
this.classify = res.rows
})
},
}, },
onLoad() { onLoad() {
this.getPro() this.getPro()
this.getClassify()
} }
} }
</script> </script>

View File

@ -40,11 +40,17 @@ image {
margin-right: 16rpx; margin-right: 16rpx;
} }
.content { .content {
margin-top: 30rpx;
height: 1100rpx; height: 1100rpx;
padding: 20rpx; padding: 30rpx;
margin-top: 20rpx;
width: 100%;
box-sizing: border-box;
background-color: #fff;
}
.content2 {
height: 1100rpx;
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
background-color: #fff; background-color: #fff;
@ -603,4 +609,40 @@ image {
text-align: center; text-align: center;
margin-top: 30rpx; margin-top: 30rpx;
padding-bottom: 20rpx; padding-bottom: 20rpx;
} }
.walletBox {
flex: 1;
background: linear-gradient(to right, #fbf1db, #f4d7b3);
border-radius: 25rpx;
padding: 30rpx;
margin-bottom: 20rpx;
}
.walletBox_top {
font-size: 32rpx;
color: #222222;
font-weight: 600;
padding-bottom: 20rpx;
position: relative;
}
.walletBox_content{
display: flex;
justify-content: space-between;
padding: 0 80rpx;
}
.walletBox_item{
margin: 20rpx 30rpx;
display: block;
text-align: center;
font-size: 35rpx;
}
.walletBox_item_text{
color: #8d5017;
text-align: center;
font-size: 28rpx;
margin-top: 10rpx;
}

View File

@ -8,27 +8,44 @@
<view class="community"> <view class="community">
<view class="community_left"> <view class="community_left">
<image mode="aspectFill" src="../../../static/logo.png" alt="" /> <image mode="aspectFill" :src="selectedShop.album_images" alt="" />
</view> </view>
<view class="community_right" @click="changeShow"> <view class="community_right" @click="changeShow">
<view class="community_right_text"> <view class="community_right_text">
<view class="community_right_text1">七个2锁城</view> <view class="community_right_text1">{{ selectedShop.merchant_name }}</view>
<view class="community_right_text2">衡水市上海公馆6A</view> <view class="community_right_text2">{{ selectedShop.address }}</view>
</view> </view>
<view class="community_right_more"> <view class="community_right_more">
<u-icon bold color="#999999" size="30" name="arrow-right" @click="back"></u-icon> <u-icon bold color="#999999" size="30" name="arrow-right"></u-icon>
</view> </view>
</view> </view>
</view> </view>
<view class="content"> <view class="content">
<view class="iconStyle"> <view class="walletBox">
<view class="walletBox_top">钱包</view>
<view class="walletBox_content">
<view class="walletBox_item" @click="goWallet(1, walletInfo.guarantee.toFixed(2))">
<view>{{ walletInfo.guarantee ? walletInfo.guarantee.toFixed(2) : "0.00" }}元</view>
<view class="walletBox_item_text">保证金</view>
</view>
<view class="walletBox_item" @click="goWallet(2, walletInfo.receivable.toFixed(2))">
<view>{{ walletInfo.receivable ? walletInfo.receivable.toFixed(2) : "0.00" }}元</view>
<view class="walletBox_item_text">应收</view>
</view>
<!-- <view class="walletBox_item" @click="goWallet(3, walletInfo.handling_fee.toFixed(2))">
<view>{{ walletInfo.handling_fee ? walletInfo.handling_fee.toFixed(2) : "0.00" }}元</view>
<view class="walletBox_item_text">手续费</view>
</view> -->
</view>
</view>
<view class="iconStyle content2">
<u-grid col="6" :border="false"> <u-grid col="6" :border="false">
<u-grid-item v-for="(item, index) in baseList" :key="index" @click="click(item)"> <u-grid-item v-for="(item, index) in baseList" :key="index" @click="click(item)">
<view class="grid-item"> <view class="grid-item">
<image class="nav_icon" :src="item.image" mode=""></image> <image class="nav_icon" :src="item.image" mode=""></image>
</view> </view>
<text class="grid-text">{{ item.name }}</text> <text class="grid-text">{{ item.name }}</text>
</u-grid-item> </u-grid-item>
</u-grid> </u-grid>
</view> </view>
@ -45,20 +62,20 @@
</view> </view>
<view class="lines"></view> <view class="lines"></view>
<view class="communityList"> <view class="communityList">
<view class="boxshadowCon_Text2">您有n个店铺的管理权限</view> <view class="boxshadowCon_Text2">您有{{ shopList.length }}个店铺的管理权限</view>
<view style="width: 100%;height: 200rpx;"> <view style="width: 100%;height: 200rpx;">
<view class="communityItem" v-for="(item, index) in 8" :key="index"> <view class="communityItem" v-for="(item, index) in shopList" :key="index">
<view class="community_left"> <view class="community_left">
<image mode="aspectFill" src="../../../static/logo.png" alt="" /> <image mode="aspectFill" :src="item.album_images" alt="" />
</view> </view>
<view class="community_right" @click="changeShow2"> <view class="community_right" @click="changeShow2(item)">
<view class="community_right_text"> <view class="community_right_text">
<view class="community_right_text1">七个2锁城</view> <view class="community_right_text1">{{ item.merchant_name }}</view>
<view class="community_right_text2">衡水市上海公馆6A</view> <view class="community_right_text2">{{ item.address }}</view>
</view> </view>
</view> </view>
<view class="communityItem_radio"> <view class="communityItem_radio" @click="changeShow2(item)">
<radio></radio> <radio :checked="selectedShop.merchant_name === item.merchant_name"></radio>
</view> </view>
</view> </view>
</view> </view>
@ -81,6 +98,7 @@ import {
import { import {
apiArr apiArr
} from '../../../api/community'; } from '../../../api/community';
import { apiArr as walletApi } from '../../../api/wallet';
export default { export default {
@ -91,17 +109,26 @@ export default {
active: 1, active: 1,
show: false, show: false,
show2: false, show2: false,
shopList: [],
selectedShop: {},
baseList: [ baseList: [
// {
// image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/page_user_Group_1568.png",
// name: "订单",
// url: "/packages/storeManagement/order/index",
// },
{ {
image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/page_user_Group_1568.png",
name: "订单",
url: "",
}, {
image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/gp_cancelAfterVerification.png", image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/gp_cancelAfterVerification.png",
name: "到店核销", name: "到店核销",
url: "", url: "/packages/storeManagement/orderVerification/index",
},
{
image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/kefu0.png",
name: "客服",
url: "/packages/customerService/chattingRecords/index",
} }
], ],
walletInfo: {},
} }
}, },
onLoad(options) { onLoad(options) {
@ -109,10 +136,37 @@ export default {
this.top = meun.top; this.top = meun.top;
// this.top = meun.height + meun.top; // this.top = meun.height + meun.top;
this.localHeight = meun.height; this.localHeight = meun.height;
this.getShopList();
}, },
methods: { methods: {
// 获取钱包信息
getWalletInfo() {
const params = {
merchant_id: this.selectedShop.id,
}
request(walletApi.walletList, 'POST', params, { silent: false }).then(res => {
this.walletInfo = res;
})
},
// 获取商家列表
getShopList() {
request(apiArr.getShopList, 'POST', {}, { silent: false }).then(res => {
res.rows.map(item => {
item.album_images = picUrl + item.album_images;
})
this.shopList = res.rows;
if (this.shopList.length > 0) {
this.selectedShop = this.shopList[0];
// 确保selectedShop有值后再调用getWalletInfo()
this.getWalletInfo();
}
})
},
// 跳转钱包页面
goWallet(type, amount) {
NavgateTo('/packages/storeManagement/wallet/index?type=' + type + '&merchant_id=' + this.selectedShop.id + '&amount=' + amount);
},
changeTab(index) { changeTab(index) {
this.active = index; this.active = index;
}, },
@ -124,15 +178,17 @@ export default {
changeShow() { changeShow() {
this.show = !this.show this.show = !this.show
}, },
changeShow2() { changeShow2(item) {
this.show2 = !this.show this.selectedShop = item;
this.show = false;
}, },
click(item) { click(item) {
console.log("🚀 ~ click ~ item:", item) // 根据item中的url进行跳转
if(item.name === '到店核销'){ if (item.url) {
NavgateTo('/packages/storeManagement/orderVerification/index') NavgateTo(item.url + '?merchant_id=' + this.selectedShop.id)
}else{ } else {
NavgateTo('/packages/storeManagement/order/index') console.warn('未配置跳转URL');
// 可添加默认跳转或提示
} }
} }
}, },

View File

@ -0,0 +1,196 @@
page {
background-color: #f6f7fb;
}
.header {
width: 750rpx;
padding-bottom: 20rpx;
background-color: #ffffff;
}
.searchBox {
display: flex;
align-items: center;
z-index: 2;
}
.searchBox_left {
box-sizing: border-box;
padding-left: 20rpx;
position: absolute;
left: 0;
}
.searchBox_mid {
font-size: 32rpx;
color: #222222;
flex: 1;
text-align: center;
}
/* 余额显示部分样式 */
.balance-container {
width: 93%;
height: 250rpx;
background-color: #ffffff;
margin-bottom: 15rpx;
padding: 25rpx;
}
.balance-content {
height: 100%;
display: flex;
position: relative;
align-items: center;
padding-left: 50rpx;
color: #894b11;
background: linear-gradient(to top right, #f6e2b7, #eab16a);
border-radius: 25rpx;
}
.balance-title {
font-size: 45rpx;
font-weight: 500;
margin-bottom: 20rpx;
}
.balance-amount {
font-size: 70rpx;
font-weight: 500;
}
.balance-icon {
position: absolute;
right: 50rpx;
top: 50%;
transform: translateY(-50%);
width: 200rpx;
height: 200rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
}
.balance-icon image {
width: 200rpx;
height: 200rpx;
}
.balance-text {
position: absolute;
right: 50rpx;
top: 50%;
transform: translateY(-50%);
width: 150rpx;
height: 70rpx;
border-radius: 20rpx;
border: 1rpx solid #8b4e13;
display: flex;
align-items: center;
justify-content: center;
}
/* 余额变动记录样式 */
.records-container {
margin-top: 30rpx;
padding: 0 40rpx;
background-color: #ffffff;
padding: 25rpx;
}
.tabs {
display: flex;
align-items: center;
height: 100rpx;
box-sizing: border-box;
overflow-x: auto;
white-space: nowrap;
border-bottom: 1rpx solid #EEEEEE;
}
.tabItem {
font-size: 30rpx;
color: #222222;
margin-right: 60rpx;
white-space: nowrap;
}
.active2 {
font-size: 30rpx;
font-weight: 700;
position: relative;
}
.active2::after {
content: '';
background: url(https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_active.png) no-repeat;
background-size: 100% 100%;
width: 52rpx;
height: 22rpx;
position: absolute;
left: 50%;
bottom: -16rpx;
transform: translateX(-50%);
}
.records-title {
font-size: 36rpx;
font-weight: bold;
color: #222222;
margin-bottom: 30rpx;
}
.records-list {
width: 100%;
}
.record-item {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding: 30rpx 0;
border-bottom: 1rpx solid #EEEEEE;
}
.record-info {
flex: 1;
}
.record-name {
font-size: 32rpx;
color: #222222;
margin-bottom: 10rpx;
}
.record-time {
font-size: 26rpx;
color: #999999;
}
.record-amount {
text-align: right;
}
.amount-sign {
font-size: 28rpx;
}
.amount-value {
font-size: 36rpx;
font-weight: bold;
}
.positive {
color: #51c651;
}
.negative {
color: #FF4444;
}
.record-balance {
font-size: 26rpx;
color: #999999;
margin-top: 10rpx;
}

View File

@ -0,0 +1,149 @@
<template>
<view>
<view class="header">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_left" @click="back">
<u-icon name="arrow-left" size="20px" color="#000"></u-icon>
</view>
<view class="searchBox_mid">{{ topVal }}</view>
</view>
</view>
<!-- 余额显示部分 -->
<view class="balance-container">
<view class="balance-content">
<view>
<view class="balance-title">{{ topVal }}(元)</view>
<view class="balance-amount">{{ balance }}</view>
<!-- <view v-if="topVal == '保证金'" class="balance-text">
去充值
</view> -->
<view class="balance-icon">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com//user_wallet2.png" mode="widthFix" />
</view>
</view>
</view>
</view>
<!-- 变动记录 -->
<view class="records-container">
<!-- <view class="tabs" v-if="topVal == '保证金' && records.length > 0">
<view v-for="(item, index) in tabList" :key="index"
:class="['tabItem', selectedTab === item.id ? 'active2' : '']" @click="selectTab(index, item)">
{{ item.tabName }}
</view>
</view> -->
<view v-if="records.length == 0">
<view class="records-list">暂无变动记录</view>
</view>
<view class="records-list" v-else>
<view class="record-item" v-for="(record, index) in records" :key="index">
<view class="record-info">
<view class="record-name">{{ record.change_reason == 1 ? '下单' : '退单' }} - {{
record.related_order }}</view>
<view class="record-time">{{ record.change_time }}</view>
</view>
<view class="record-amount" v-if="topVal == '保证金'">
<view>
<text :class="['amount-sign', record.change_reason == 1 ? 'positive' : 'negative']">{{
record.change_reason == 1 ? '+' : '-' }}</text>
<text :class="['amount-value', record.change_reason == 1 ? 'positive' : 'negative']">¥{{
record.amount_change }}</text>
</view>
<view class="record-balance">余:¥{{ record.balance_after }}</view>
</view>
<view class="record-amount" v-else-if="topVal == '应收'">
<view :class="['amount-sign', record.change_reason == 1 ? 'positive' : 'negative']">{{
record.change_reason == 1 ? '收款' : '退款' }}</view>
<view>
<text :class="['amount-sign', record.change_reason == 1 ? 'positive' : 'negative']">{{
record.change_reason == 1 ? '+' : '-' }}</text>
<text :class="['amount-value', record.change_reason == 1 ? 'positive' : 'negative']">¥{{
record.amount_change }}</text>
</view>
</view>
<view class="record-amount" v-else>
<view class="record-balance">手续费</view>
<view>
<text class="amount-sign">{{ record.change_reason == 1 ? '+' : '-' }}</text>
<text class="amount-sign">¥{{ record.amount_change }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { menuButtonInfo, NavgateTo, picUrl, request } from '../../../utils/index';
import { apiArr as walletApi } from '../../../api/wallet';
export default {
data() {
return {
top: "",
localHeight: "",
topVal: "",
balance: "",
records: [],
tabList: [
{
id: 0,
tabName: '全部'
},
{
id: 1,
tabName: '充值记录'
},
{
id: 2,
tabName: '消费记录'
}
],
selectedTab: 0,
merchant_id: "",
}
},
onLoad(options) {
const meun = menuButtonInfo();
this.top = meun.top;
this.localHeight = meun.height;
this.topVal = options.type == 1 ? '保证金' : (options.type == 2 ? '应收' : '手续费');
this.balance = options.amount;
this.merchant_id = options.merchant_id;
this.getWalletInfo();
},
methods: {
back() {
uni.navigateBack({
delta: 1
});
},
selectTab(index, item) {
this.selectedTab = item.id;
},
// 获取钱包信息
getWalletInfo() {
const params = {
merchant_id: this.merchant_id,
}
request(walletApi.walletChangeList, 'POST', params, { silent: false }).then(res => {
let filteredRows = res.rows;
if (this.topVal == '保证金') {
filteredRows = res.rows.filter(item => item.change_category == 5);
} else if (this.topVal == '应收') {
filteredRows = res.rows.filter(item => item.change_category == 2);
} else {
filteredRows = res.rows.filter(item => item.change_category == 3);
}
this.records = filteredRows;
})
}
}
}
</script>
<style>
@import url("./index.css");
</style>

View File

@ -120,6 +120,7 @@ export default {
uni.removeStorageSync('is_deal'); uni.removeStorageSync('is_deal');
uni.removeStorageSync('is_dev'); uni.removeStorageSync('is_dev');
uni.removeStorageSync('is_shop'); uni.removeStorageSync('is_shop');
uni.removeStorageSync('is_merchant');
uni.removeStorageSync('is_worker'); uni.removeStorageSync('is_worker');
uni.removeStorageSync('shopId'); uni.removeStorageSync('shopId');
uni.removeStorageSync('order_dispatch_permission'); uni.removeStorageSync('order_dispatch_permission');
@ -147,6 +148,7 @@ export default {
uni.setStorageSync('is_deal', loginRes.is_deal); uni.setStorageSync('is_deal', loginRes.is_deal);
uni.setStorageSync('is_dev', loginRes.is_dev); uni.setStorageSync('is_dev', loginRes.is_dev);
uni.setStorageSync('is_shop', loginRes.is_shop); uni.setStorageSync('is_shop', loginRes.is_shop);
uni.setStorageSync('is_merchant', loginRes.is_merchant);
uni.setStorageSync('is_worker', loginRes.is_worker); uni.setStorageSync('is_worker', loginRes.is_worker);

View File

@ -109,6 +109,7 @@
icon: 'success', icon: 'success',
mask: true mask: true
}) })
uni.setStorageSync('headPhoto', this.avatarInfo.picUrl)
setTimeout(() => { setTimeout(() => {
uni.navigateBack({ delta: 1 }) uni.navigateBack({ delta: 1 })
}, 2000) }, 2000)

View File

@ -0,0 +1,147 @@
page {
background-color: #f6f7fb;
}
.header {
width: 750rpx;
padding-bottom: 20rpx;
background-color: #ffffff;
}
.searchBox {
display: flex;
align-items: center;
z-index: 2;
}
.searchBox_left {
box-sizing: border-box;
padding-left: 20rpx;
position: absolute;
left: 0;
}
.searchBox_mid {
font-size: 32rpx;
color: #222222;
flex: 1;
text-align: center;
}
/* 余额显示部分样式 */
.balance-container {
width: 93%;
height: 250rpx;
background-color: #ffffff;
margin-bottom: 15rpx;
padding: 25rpx;
}
.balance-content {
height: 100%;
display: flex;
position: relative;
align-items: center;
padding-left: 50rpx;
color: #894b11;
background: linear-gradient(to top right, #f6e2b7, #eab16a);
border-radius: 25rpx;
}
.balance-title {
font-size: 45rpx;
font-weight: 500;
margin-bottom: 20rpx;
}
.balance-amount {
font-size: 70rpx;
font-weight: 500;
}
.balance-icon {
position: absolute;
right: 50rpx;
top: 50%;
transform: translateY(-50%);
width: 200rpx;
height: 200rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
}
.balance-icon image {
width: 200rpx;
height: 200rpx;
}
/* 余额变动记录样式 */
.records-container {
margin-top: 30rpx;
padding: 0 40rpx;
background-color: #ffffff;
padding: 25rpx;
}
.records-title {
font-size: 36rpx;
font-weight: bold;
color: #222222;
margin-bottom: 30rpx;
}
.records-list {
width: 100%;
}
.record-item {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding: 30rpx 0;
border-bottom: 1rpx solid #EEEEEE;
}
.record-info {
flex: 1;
}
.record-name {
font-size: 32rpx;
color: #222222;
margin-bottom: 10rpx;
}
.record-time {
font-size: 26rpx;
color: #999999;
}
.record-amount {
text-align: right;
}
.amount-sign {
font-size: 28rpx;
}
.amount-value {
font-size: 36rpx;
font-weight: bold;
}
.positive {
color: #51c651;
}
.negative {
color: #FF4444;
}
.record-balance {
font-size: 26rpx;
color: #999999;
margin-top: 10rpx;
}

View File

@ -0,0 +1,117 @@
<template>
<view>
<view class="header">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_left" @click="back">
<u-icon name="arrow-left" size="20px" color="#000"></u-icon>
</view>
<view class="searchBox_mid">{{ topVal }}</view>
</view>
</view>
<!-- 余额显示部分 -->
<view class="balance-container">
<view class="balance-content">
<view>
<view class="balance-title">{{ topVal }}余额(元)</view>
<view class="balance-amount">{{ balance }}</view>
<view class="balance-icon">
<image :src="photoVal" mode="widthFix" />
</view>
</view>
</view>
</view>
<!-- 余额变动记录 -->
<view class="records-container">
<view class="records-title">{{ topVal }}变动记录</view>
<view class="records-list">
<view v-if="records.length > 0">
<view class="record-item" v-for="(record, index) in records" :key="index">
<view class="record-info">
<view class="record-name" v-if="topVal == '积分'">{{ record.change_reason }} - {{
record.community_order_pay ? record.community_order_pay.order_pay_no :
record.quick_payment_record.order_no }}</view>
<view class="record-name" v-else>{{ record.change_reason }} - {{ record.related_order }}</view>
<view class="record-time">{{ record.create_time }}</view>
</view>
<view class="record-amount">
<view>
<text
:class="['amount-sign', record.change_reason == '下单' ? 'positive' : 'negative']">{{
record.change_reason == '下单' ? '+' : '-' }}</text>
<text v-if="topVal == '积分'"
:class="['amount-value', record.change_reason == '下单' ? 'positive' : 'negative']">¥{{
record.change_value }}</text>
<text v-else
:class="['amount-value', record.change_reason == '下单' ? 'positive' : 'negative']">¥{{
record.amount_change }}</text>
</view>
<view class="record-balance">余:¥{{ record.balance_after }}</view>
</view>
</view>
</view>
<view v-else>
<view class="no-record">暂无变动记录</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { apiArr } from '../../../api/v2User';
import { menuButtonInfo, NavgateTo, picUrl, request } from '../../../utils/index';
export default {
data() {
return {
top: "",
localHeight: "",
topVal: "",
photoVal: '',
balance: "",
records: [],
itemObj: {},
itemType: '',
page_num: 1,
page_size: 10,
}
},
onLoad(options) {
const meun = menuButtonInfo();
this.top = meun.top;
this.localHeight = meun.height;
this.topVal = options.type == 1 ? '积分' : (options.type == 2 ? '物业费' : '红包卡券');
this.photoVal = options.type == 1 ? 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com//user_wallet1.png' : (options.type == 2 ? 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com//user_wallet2.png' : 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com//user_wallet3.png');
this.itemObj = JSON.parse(options.item);
this.itemType = options.type;
this.balance = options.type == 1 ? this.itemObj.points : (options.type == 2 ? this.itemObj.property_housing_fund : 0)
this.getWalletInfo();
},
methods: {
back() {
uni.navigateBack({
delta: 1
});
},
// 获取钱包信息
getWalletInfo() {
const params = {
page_num: this.page_num,
page_size: this.page_size,
}
if (this.itemType == 1) {
request(apiArr.getPoints, 'POST', params, { silent: false }).then(res => {
this.records = res.rows;
})
} else if (this.itemType == 2) {
request(apiArr.getAccumulationFund, 'POST', params, { silent: false }).then(res => {
this.records = res.rows;
})
}
}
}
}
</script>
<style>
@import url("./index.css");
</style>

View File

@ -0,0 +1,159 @@
.container {
padding: 30rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.select-container {
margin-bottom: 40rpx;
position: relative;
}
.select-label {
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
display: block;
}
.search-input {
width: 100%;
height: 80rpx;
border: 1rpx solid #ddd;
border-radius: 10rpx;
padding: 0 20rpx;
font-size: 28rpx;
box-sizing: border-box;
}
.options-container {
margin-top: 10rpx;
max-height: 400rpx;
width: 100%;
overflow-y: auto;
border: 1rpx solid #ddd;
border-radius: 10rpx;
background-color: #fff;
position: absolute;
z-index: 10;
}
.option-item {
height: 80rpx;
line-height: 80rpx;
padding: 0 20rpx;
font-size: 28rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.option-item:last-child {
border-bottom: none;
}
.option-item:hover {
background-color: #f5f5f5;
}
.option-item.selected {
background-color: #e6f7ff;
color: #1890ff;
}
.disabled {
opacity: 0.6;
cursor: not-allowed;
pointer-events: none;
}
.camera-section {
flex: 1;
}
.camera-container {
text-align: center;
padding: 40rpx;
}
.camera-icon-container{
width: 130rpx;
height: 130rpx;
border: 5rpx solid #333;
border-radius: 50%;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
}
.camera-icon {
width: 90rpx;
height: 90rpx;
margin: 0 auto;
}
.camera-text {
margin-top: 20rpx;
font-size: 28rpx;
color: #666;
}
.photos-container {
display: flex;
flex-wrap: wrap;
margin-top: 20rpx;
}
.photo-item {
width: 150rpx;
height: 150rpx;
margin: 20rpx 20rpx 0 0;
position: relative;
border: 1rpx solid #ddd;
}
.photo-preview {
width: 100%;
height: 100%;
}
.delete-icon {
position: absolute;
top: -10rpx;
right: -10rpx;
width: 40rpx;
height: 40rpx;
background-color: rgba(255, 0, 0, 0.8);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 24rpx;
}
.footer {
padding: 30rpx;
background-color: #fff;
border-top: 1rpx solid #eee;
margin-top: 20rpx;
}
.submit-button {
width: 100%;
height: 90rpx;
background-color: #1890ff;
color: white;
border: none;
border-radius: 45rpx;
font-size: 32rpx;
margin-top: 50rpx;
}
.no-options {
padding: 30rpx 20rpx;
text-align: center;
color: #999;
font-size: 28rpx;
background-color: #fff;
}

View File

@ -0,0 +1,219 @@
<template>
<view class="container">
<!-- 点位选择下拉菜单 -->
<view class="select-container">
<label class="select-label">选择点位</label>
<input type="text" class="search-input" v-model="searchKeyword" @focus="showOptions = !showOptions"
placeholder="请输入点位名称搜索" readonly />
<!-- 下拉选项 -->
<view class="options-container" v-if="showOptions">
<!-- 为空时显示提示 -->
<view v-if="pointsList.length === 0" class="no-options">
暂无数据
</view>
<!-- 有选项时显示选项列表 -->
<view v-else>
<view v-for="option in pointsList" :key="option.id" class="option-item"
@click="option.exec_status != 3 && selectPointHandler(option)"
:class="{ 'disabled': option.exec_status == 3 }">
<view>
{{ option.point_info.point_name }}
</view>
</view>
</view>
</view>
</view>
<!-- 拍照功能和图片预览 -->
<view class="camera-section">
<!-- 拍照按钮,当图片数量达到12张时隐藏 -->
<view class="camera-container" v-if="images.length < 12">
<image class="camera-icon" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/zhaoxiangji.png"
mode="aspectFit" @click="takePhoto"></image>
<view class="camera-text">点击拍照上传</view>
</view>
<!-- 照片列表 -->
<view class="photos-container">
<view v-for="(image, index) in images" :key="index" class="photo-item">
<image class="photo-preview" :src="image" mode="aspectFit"></image>
<!-- 删除图标 -->
<view class="delete-icon" @click="deleteImage(index)">×</view>
</view>
</view>
</view>
<!-- 底部提交按钮 -->
<view class="footer">
<button class="submit-button" @click="submitForm">确认提交</button>
</view>
</view>
</template>
<script>
import {
request,
picUrl,
uniqueByField,
menuButtonInfo,
NavgateTo,
upload
} from "../../../utils";
import { apiArr } from "../../../api/routingInspection";
export default {
data() {
return {
searchKeyword: '',
showOptions: false,
selectedPoint: '',
selectedPointInfo: null, // 存储完整的点位信息
pointsList: [],
images: [], // 存储多张图片路径
taskId: '',
}
},
onLoad(options) {
if (options.item) {
const item = JSON.parse(options.item)
this.taskId = item.id
this.getInfo(this.taskId)
}
},
methods: {
async getInfo(id) {
const res = await request(apiArr.routingInspectionInfo, "POST", {
task_id: id,
});
this.pointsList = res.task_point_info
},
selectPointHandler(option) {
// 安全检查,确保必要的属性存在
if (option && option.point_info && option.point_info.point_name) {
// 根据实际数据结构选择正确的id属性
this.selectedPoint = option.location_info && option.id
? option.id
: option.id || option.point_info.point_name
this.selectedPointInfo = option // 保存完整的点位信息
this.searchKeyword = option.point_info.point_name
this.showOptions = false
// 切换点位时清空图片数据
this.images = []
} else {
console.warn('选择的点位信息不完整', option)
}
},
takePhoto() {
// 调起手机拍照功能,不允许从相册选择
const that = this
// 计算还可以拍摄的图片数量
const remainingCount = 12 - that.images.length
uni.chooseImage({
count: remainingCount > 0 ? remainingCount : 1, // 最多选择的图片数量
sizeType: ['original', 'compressed'],
sourceType: ['camera'], // 只允许拍照
success: function (res) {
const tempFilePaths = res.tempFilePaths
// 将新拍摄的图片添加到列表中
that.images = [...that.images, ...tempFilePaths]
console.log('拍照成功,当前图片数量:', that.images.length)
},
fail: function (err) {
console.error('拍照失败', err)
uni.showToast({
title: '拍照失败',
icon: 'none'
})
}
})
},
deleteImage(index) {
// 删除指定索引的图片
this.images.splice(index, 1)
},
async submitForm() {
// 验证是否选择了点位
if (!this.selectedPoint) {
uni.showToast({
title: '请选择点位',
icon: 'none'
})
return
}
// 验证是否上传了图片
if (this.images.length === 0) {
uni.showToast({
title: '请至少上传一张照片',
icon: 'none'
})
return
}
try {
// 上传所有图片到服务器
uni.showLoading({
title: '正在上传图片...',
mask: true
})
// 使用Promise.all并行上传所有图片
const uploadPromises = this.images.map(imagePath => {
return new Promise((resolve, reject) => {
upload(imagePath, (res) => {
if (res.code === 1 && res.data && res.data.path) {
resolve(res.data.path); // 上传成功,返回服务器返回的图片URL
} else {
reject(new Error('图片上传失败'));
}
});
});
});
// 等待所有图片上传完成
const uploadedImageUrls = await Promise.all(uploadPromises);
uni.hideLoading();
// 准备提交数据,使用服务器返回的图片URL
const params = {
task_id: parseInt(this.taskId), // 巡检任务ID
task_point_id: parseInt(this.selectedPoint), // 巡检点ID
image: uploadedImageUrls // 巡检图片,使用服务器返回的URL数组
}
console.log('上传成功的图片URL:', uploadedImageUrls)
// 调用正确的接口
const res = await request(apiArr.routingInspectionSubmit, "POST", params);
// 输出提交的数据
console.log('提交数据:', params)
// 显示提交成功提示
uni.showToast({
title: '提交成功',
icon: 'success'
})
// 提交成功后,延迟1秒再重置表单
setTimeout(() => {
this.getInfo(this.taskId);
}, 1000);
} catch (error) {
uni.hideLoading();
console.error('提交失败', error)
uni.showToast({
title: '提交失败',
icon: 'none'
})
}
}
}
}
</script>
<style>
@import url("./index.css");
</style>

View File

@ -112,4 +112,40 @@
max-width: 768px; max-width: 768px;
margin: 0 auto; margin: 0 auto;
} }
}
.walletBox {
flex: 1;
background: linear-gradient(to right, #fbf1db, #f4d7b3);
border-radius: 25rpx;
padding: 30rpx;
margin: 20rpx;
}
.walletBox_top {
font-size: 32rpx;
color: #222222;
font-weight: 600;
padding-bottom: 20rpx;
position: relative;
}
.walletBox_content{
display: flex;
justify-content: space-between;
}
.walletBox_item{
/* margin: 20rpx 30rpx; */
width: 32%;
display: block;
text-align: center;
font-size: 35rpx;
}
.walletBox_item_text{
color: #8d5017;
text-align: center;
font-size: 28rpx;
margin-top: 10rpx;
} }

View File

@ -2,23 +2,52 @@
<view class="container"> <view class="container">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }"> <view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_add" @click="addCommunity"> <view class="searchBox_add" @click="addCommunity">
<image class="top-image" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/workOrder_community.png" mode="aspectFill"></image> <image class="top-image"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/workOrder_community.png" mode="aspectFill">
</image>
<view class="emptyCommunity"> <view class="emptyCommunity">
{{ communityVal }} {{ communityVal }}
</view> </view>
</view> </view>
</view> </view>
<!-- 背景图片区域 --> <!-- 背景图片区域 -->
<view class="bg-image-container"> <!-- <view class="bg-image-container">
<image class="bg-image" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/workOrderDashboardImg.png" mode=""></image> <image class="bg-image" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/workOrderDashboardImg.png" mode=""></image>
</view> -->
<view class="walletBox">
<view class="walletBox_top">钱包</view>
<view class="walletBox_content">
<view class="walletBox_item" @click="goWallet(1, walletInfo.receivable ? walletInfo.receivable.toFixed(2) : '0.00')">
<view>{{ walletInfo.receivable ? walletInfo.receivable.toFixed(2) : "0.00" }}元</view>
<view class="walletBox_item_text">应收</view>
</view>
<view class="walletBox_item" @click="goWallet(2, walletInfo.received ? walletInfo.received.toFixed(2) : '0.00')">
<view>{{ walletInfo.received ? walletInfo.received.toFixed(2) : "0.00" }}元</view>
<view class="walletBox_item_text">已收</view>
</view>
<view class="walletBox_item" @click="goWallet(3, walletInfo.pending ? walletInfo.pending.toFixed(2) : '0.00')">
<view>{{ walletInfo.pending ? walletInfo.pending.toFixed(2) : "0.00" }}元</view>
<view class="walletBox_item_text">待收物业费</view>
</view>
<!-- <view class="walletBox_item" @click="goWallet(4, walletInfo.handling_fee.toFixed(2))">
<view>{{ walletInfo.handling_fee ? walletInfo.handling_fee.toFixed(2) : "0.00" }}元</view>
<view class="walletBox_item_text">手续费</view>
</view> -->
</view>
</view> </view>
<view class="work-order-section"> <view class="work-order-section">
<view v-for="(item, index) in 9" :key="index"> <view v-for="(item, index) in 9" :key="index">
<view class="work-order-card" v-if="index == 0 && showWorkOrderSection" <view class="work-order-card" v-if="index == 1 && showWorkOrderSection"
@click="navigateToWorkOrderDashboard"> @click="navigateToWorkOrderDashboard">
<image class="work-order-icon" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/workOrder.png" mode="aspectFill" /> <image class="work-order-icon"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/workOrder.png" mode="aspectFill" />
<text class="work-order-text">工单台</text> <text class="work-order-text">工单台</text>
</view> </view>
<view class="work-order-card" v-if="index == 0" @click="navigateToRoutingInspection">
<image class="work-order-icon" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/polling.png"
mode="aspectFill" />
<text class="work-order-text">巡更巡检</text>
</view>
<view class="work-order-card" v-else></view> <view class="work-order-card" v-else></view>
</view> </view>
</view> </view>
@ -35,20 +64,22 @@ import {
} from "../../../utils"; } from "../../../utils";
import { apiArr } from "../../../api/community"; import { apiArr } from "../../../api/community";
import { apiArr as walletApi } from '../../../api/wallet';
export default { export default {
data() { data() {
return { return {
communityVal: "切换小区", communityVal: "切换小区",
showWorkOrderSection: false, showWorkOrderSection: false,
communityList: [] communityList: [],
walletInfo: {},
} }
}, },
async onLoad() { async onLoad() {
const workOrderPermission = uni.getStorageSync('work_order_permission'); const workOrderPermission = uni.getStorageSync('work_order_permission');
const orderDispatchPermission = uni.getStorageSync('order_dispatch_permission'); const orderDispatchPermission = uni.getStorageSync('order_dispatch_permission');
this.showWorkOrderSection = !(workOrderPermission === false && orderDispatchPermission === false); this.showWorkOrderSection = !(workOrderPermission === false && orderDispatchPermission === false);
// 获取小区列表并设置默认选中第一个 // 获取小区列表并设置默认选中第一个
await request(apiArr.workCommunityList, "POST", { await request(apiArr.workCommunityList, "POST", {
user_id: uni.getStorageSync('userId'), user_id: uni.getStorageSync('userId'),
@ -57,18 +88,33 @@ export default {
item.pic = item.pic.startsWith('http') ? item.pic : picUrl + item.pic item.pic = item.pic.startsWith('http') ? item.pic : picUrl + item.pic
}); });
this.communityList = res.rows; this.communityList = res.rows;
// 如果没有选中的小区且有小区列表,则默认选中第一个 const changeCommData = uni.getStorageSync('changeWorkOrderData');
if (!uni.getStorageSync('changeWorkOrderData') && res.rows.length > 0) { // 检查本地存储的小区是否存在于返回的列表中
if (changeCommData) {
const exists = res.rows.some(item => item.community_id === changeCommData.id);
// 如果不存在,则清除数据并设置为第一个
if (!exists && res.rows.length > 0) {
uni.setStorageSync('changeWorkOrderData', { id: res.rows[0].community_id, name: res.rows[0].name });
this.communityVal = res.rows[0].name;
} else if (!exists) {
// 如果列表为空,则清除数据
uni.removeStorageSync('changeWorkOrderData');
this.communityVal = "切换小区";
}
} else if (res.rows.length > 0) {
// 如果没有选中的小区且有小区列表,则默认选中第一个
uni.setStorageSync('changeWorkOrderData', { id: res.rows[0].community_id, name: res.rows[0].name }); uni.setStorageSync('changeWorkOrderData', { id: res.rows[0].community_id, name: res.rows[0].name });
this.communityVal = res.rows[0].name; this.communityVal = res.rows[0].name;
} }
// 获取钱包信息
this.getWalletInfo();
}); });
}, },
async onShow() { async onShow() {
const changeCommData = uni.getStorageSync('changeWorkOrderData'); const changeCommData = uni.getStorageSync('changeWorkOrderData');
this.communityVal = changeCommData ? changeCommData.name : "切换小区"; this.communityVal = changeCommData ? changeCommData.name : "切换小区";
if (changeCommData) { if (changeCommData) {
const params = { const params = {
community_id: changeCommData.id, community_id: changeCommData.id,
@ -78,6 +124,33 @@ export default {
} }
}, },
methods: { methods: {
// 获取钱包信息
getWalletInfo() {
const changeCommData = uni.getStorageSync('changeWorkOrderData');
if (!changeCommData) {
return;
}
const params = {
community_id: changeCommData.id,
}
request(walletApi.walletList, 'POST', params, { silent: false }).then(res => {
this.walletInfo = res;
})
},
goWallet(type, amount) {
const changeCommData = uni.getStorageSync('changeWorkOrderData');
if (!changeCommData) {
uni.showToast({
title: '请先选择小区',
icon: 'none'
});
return;
}
// if (type == 2) {
// return
// }
NavgateTo('/packages/workOrderDashboard/wallet/index?type=' + type + '&community_id=' + changeCommData.id + '&amount=' + amount);
},
addCommunity() { addCommunity() {
NavgateTo("/packages/workOrderDashboard/myCommunity/index"); NavgateTo("/packages/workOrderDashboard/myCommunity/index");
}, },
@ -92,10 +165,26 @@ export default {
}); });
return; return;
} }
uni.navigateTo({ uni.navigateTo({
url: '/packages/workOrderDashboard/index/index?communityId=' + changeCommData.id url: '/packages/workOrderDashboard/index/index?communityId=' + changeCommData.id
}); });
},
// 跳转到巡更巡检
navigateToRoutingInspection() {
const changeCommData = uni.getStorageSync('changeWorkOrderData');
if (!changeCommData) {
uni.showToast({
title: '请先选择小区',
icon: 'none'
});
return;
}
uni.navigateTo({
url: '/packages/workOrderDashboard/routingInspection/index?communityId=' + changeCommData.id
});
} }
} }
} }

View File

@ -145,6 +145,7 @@ export default {
status: this.active, status: this.active,
page_num: this.page_num, page_num: this.page_num,
page_size: this.page_size, page_size: this.page_size,
user_id: ''
}); });
if (res.rows) { if (res.rows) {
@ -166,6 +167,7 @@ export default {
status: status, status: status,
page_num: this.page_num, page_num: this.page_num,
page_size: this.page_size, page_size: this.page_size,
user_id: ''
}); });
return res.total; return res.total;
}, },

View File

@ -0,0 +1,57 @@
page {
background-color: #f6f7fb;
padding: 15rpx;
}
.item {
width: 96%;
margin: 10rpx 0;
border-radius: 15rpx;
background-color: #ffffff;
font-size: 28rpx;
}
.item-top {
display: flex;
justify-content: space-between;
align-items: center;
color: #333;
padding: 20rpx;
border-bottom: 1rpx solid #eeeeee;
}
.item-content {
display: flex;
justify-content: space-between;
align-items: center;
color: #333;
padding: 20rpx;
}
.Btn {
width: 150rpx;
height: 70rpx;
color: #ffffff;
background-color: #169bd5;
text-align: center;
line-height: 70rpx;
font-size: 26rpx;
}
.empty {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-weight: normal;
font-size: 28rpx;
color: #999999;
margin-top: 200rpx;
width: 100%;
}
.empty image {
width: 366rpx;
height: 226rpx;
margin-bottom: 27rpx;
}

View File

@ -0,0 +1,87 @@
<template>
<view>
<view v-if="list.length > 0">
<view v-for="(item, index) in list" :key="index">
<view class="item">
<view class="item-top">
<view>任务编号:{{ item.task_no }}</view>
<view>任务类型:{{ getStatusName(item.execution_status) }}</view>
</view>
<view class="item-content">
<view class="item-content-left">
<view>任务名称:{{ item.inspection_plan_info.plan_name }}</view>
<view>路线编号:{{ item.inspection_plan_info.inspection_route_info.route_code }}</view>
<view>路线名称:{{ item.inspection_plan_info.inspection_route_info.route_name }}</view>
<view>任务开始时间:{{ item.start_time }}</view>
<view>任务结束时间:{{ item.end_time }}</view>
<view>巡检人:{{ item.inspection_plan_info.community_worker_info.name }}</view>
</view>
<view class="item-content-right">
<button class="Btn" @click="goInspection(item)" :disabled="item.inspection_plan_info.community_worker_info.inspection_permission != 1">去巡检</button>
</view>
</view>
</view>
</view>
</view>
<view v-else>
<view class="empty">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_nearbyList_empty.png"
mode="aspectFill"></image>
暂无数据
</view>
</view>
</view>
</template>
<script>
import {
request,
picUrl,
uniqueByField,
menuButtonInfo,
NavgateTo,
} from "../../../utils";
import { apiArr } from "../../../api/routingInspection";
export default {
data() {
return {
list: []
}
},
onLoad(options) {
this.communityId = JSON.parse(options.communityId);
// this.getList();
},
onShow() {
this.getList();
},
methods: {
async getList() {
const res = await request(apiArr.routingInspectionList, "POST", {
community_id: this.communityId,
});
this.list = res.rows;
},
goInspection(item) {
NavgateTo('/packages/workOrderDashboard/addRoutingInspection/index?item=' + JSON.stringify(item),)
},
// 将任务状态数字代码转换为中文名称
getStatusName(status) {
const statusMap = {
1: '待开始',
2: '进行中',
3: '已超时',
4: '已完成'
};
return statusMap[status] || status;
}
},
}
</script>
<style>
@import url("./index.css");
</style>

View File

@ -0,0 +1,147 @@
page {
background-color: #f6f7fb;
}
.header {
width: 750rpx;
padding-bottom: 20rpx;
background-color: #ffffff;
}
.searchBox {
display: flex;
align-items: center;
z-index: 2;
}
.searchBox_left {
box-sizing: border-box;
padding-left: 20rpx;
position: absolute;
left: 0;
}
.searchBox_mid {
font-size: 32rpx;
color: #222222;
flex: 1;
text-align: center;
}
/* 余额显示部分样式 */
.balance-container {
width: 93%;
height: 250rpx;
background-color: #ffffff;
margin-bottom: 15rpx;
padding: 25rpx;
}
.balance-content {
height: 100%;
display: flex;
position: relative;
align-items: center;
padding-left: 50rpx;
color: #894b11;
background: linear-gradient(to top right, #f6e2b7, #eab16a);
border-radius: 25rpx;
}
.balance-title {
font-size: 45rpx;
font-weight: 500;
margin-bottom: 20rpx;
}
.balance-amount {
font-size: 70rpx;
font-weight: 500;
}
.balance-icon {
position: absolute;
right: 50rpx;
top: 50%;
transform: translateY(-50%);
width: 200rpx;
height: 200rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
}
.balance-icon image {
width: 200rpx;
height: 200rpx;
}
/* 余额变动记录样式 */
.records-container {
margin-top: 30rpx;
padding: 0 40rpx;
background-color: #ffffff;
padding: 25rpx;
}
.records-title {
font-size: 36rpx;
font-weight: bold;
color: #222222;
margin-bottom: 30rpx;
}
.records-list {
width: 100%;
}
.record-item {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding: 30rpx 0;
border-bottom: 1rpx solid #EEEEEE;
}
.record-info {
flex: 1;
}
.record-name {
font-size: 32rpx;
color: #222222;
margin-bottom: 10rpx;
}
.record-time {
font-size: 26rpx;
color: #999999;
}
.record-amount {
text-align: right;
}
.amount-sign {
font-size: 28rpx;
}
.amount-value {
font-size: 36rpx;
font-weight: bold;
}
.positive {
color: #51c651;
}
.negative {
color: #FF4444;
}
.record-balance {
font-size: 26rpx;
color: #999999;
margin-top: 10rpx;
}

View File

@ -0,0 +1,128 @@
<template>
<view>
<view class="header">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_left" @click="back">
<u-icon name="arrow-left" size="20px" color="#000"></u-icon>
</view>
<view class="searchBox_mid">{{ topVal }}</view>
</view>
</view>
<!-- 余额显示部分 -->
<view class="balance-container">
<view class="balance-content">
<view>
<view class="balance-title">{{ topVal }}(元)</view>
<view class="balance-amount">{{ balance }}</view>
<view class="balance-icon">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com//user_wallet2.png" mode="widthFix" />
</view>
</view>
</view>
</view>
<!-- 余额变动记录 -->
<view class="records-container">
<view class="records-title" v-if="topVal == '待收物业费'">物业费变动记录</view>
<view v-if="records.length == 0">
<view class="records-list">暂无变动记录</view>
</view>
<view class="records-list" v-else>
<view class="record-item" v-for="(record, index) in records" :key="index">
<view class="record-info">
<view class="record-name">{{ record.change_reason == 1 ? '下单' : '退单' }} - {{
record.related_order }}</view>
<view class="record-time">{{ record.change_time }}</view>
</view>
<view class="record-amount">
<view class="record-balance" v-if="topVal == '应收' || topVal == '已收'">{{ record.change_reason ==
1 ? '收款' :
'退款' }}</view>
<view class="record-balance" v-else-if="topVal == '待收物业费'">待收</view>
<view class="record-balance" v-else-if="topVal == '手续费'">手续费</view>
<view>
<text :class="['amount-sign', record.change_reason == 1 ? 'positive' : 'negative']">{{
record.change_reason == 1 ? '+' : '-' }}</text>
<text :class="['amount-value', record.change_reason == 1 ? 'positive' : 'negative']">¥{{
record.amount_change }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { menuButtonInfo, NavgateTo, picUrl, request } from '../../../utils/index';
import { apiArr as walletApi } from '../../../api/wallet';
export default {
data() {
return {
top: "",
localHeight: "",
topVal: "",
balance: "",
records: [],
community_id: "",
}
},
onLoad(options) {
const meun = menuButtonInfo();
this.top = meun.top;
this.localHeight = meun.height;
this.getTypeName(options.type);
this.balance = options.amount;
this.community_id = options.community_id;
this.getWalletInfo();
},
methods: {
back() {
uni.navigateBack({
delta: 1
});
},
// 获取钱包类型名称
getTypeName(type) {
const numType = parseInt(type);
switch (numType) {
case 1:
this.topVal = '应收';
break;
case 2:
this.topVal = '已收';
break;
case 3:
this.topVal = '待收物业费';
break;
case 4:
this.topVal = '手续费';
break;
}
},
// 获取钱包信息
getWalletInfo() {
const params = {
community_id: this.community_id,
}
request(walletApi.walletChangeList, 'POST', params, { silent: false }).then(res => {
let filteredRows = res.rows;
if (this.topVal == '应收') {
filteredRows = res.rows.filter(item => item.change_category == 2);
} else if (this.topVal == '已收') {
filteredRows = res.rows.filter(item => item.change_category == 1);
} else if (this.topVal == '待收物业费') {
filteredRows = res.rows.filter(item => item.change_category == 4);
} else {
filteredRows = res.rows.filter(item => item.change_category == 3);
}
this.records = filteredRows;
})
}
}
}
</script>
<style>
@import url("./index.css");
</style>

View File

@ -109,6 +109,55 @@
"navigationBarTitleText": "选择小区", "navigationBarTitleText": "选择小区",
"navigationBarBackgroundColor": "#fff" "navigationBarBackgroundColor": "#fff"
} }
},
{
"path": "routingInspection/index",
"style": {
"navigationBarTitleText": "巡更巡检",
"navigationBarBackgroundColor": "#fff"
}
},
{
"path": "addRoutingInspection/index",
"style": {
"navigationBarTitleText": "任务详情",
"navigationBarBackgroundColor": "#fff"
}
},
{
"path": "wallet/index",
"style": {
"navigationBarBackgroundColor": "#fff",
"navigationStyle": "custom"
}
}
]
},
{
"root": "packages/customerService",
"pages": [
{
"path": "index/index",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#F9F9F9"
}
},
{
"path": "chattingRecords/index",
"style": {
"navigationBarTitleText": "客服聊天记录",
"navigationBarBackgroundColor": "#fff"
}
},
{
"path": "changeService/index",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#F9F9F9"
}
} }
] ]
}, },
@ -202,6 +251,13 @@
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },
{
"path": "defaultNotice/index",
"style": {
"navigationBarTitleText": "公告详情",
"navigationStyle": "custom"
}
},
{ {
"path": "applyOwer/index", "path": "applyOwer/index",
"style": { "style": {
@ -277,7 +333,8 @@
"style": { "style": {
"navigationBarTitleText": "", "navigationBarTitleText": "",
"navigationStyle": "custom", "navigationStyle": "custom",
"navigationBarBackgroundColor": "#fff" "navigationBarBackgroundColor": "#fff",
"enablePullDownRefresh": true
} }
}, },
{ {
@ -393,6 +450,13 @@
{ {
"path": "customerService/index", "path": "customerService/index",
"style": {} "style": {}
},
{
"path": "wallet/index",
"style": {
"navigationBarBackgroundColor": "#fff",
"navigationStyle": "custom"
}
} }
] ]
}, },
@ -581,6 +645,13 @@
"navigationBarTitleText": "订单核销", "navigationBarTitleText": "订单核销",
"navigationBarBackgroundColor": "#F9F9F9" "navigationBarBackgroundColor": "#F9F9F9"
} }
},
{
"path": "wallet/index",
"style": {
"navigationBarBackgroundColor": "#fff",
"navigationStyle": "custom"
}
} }
] ]
}, },
@ -660,6 +731,13 @@
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },
{
"path": "goodsSubmit/index",
"style": {
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "提交团单"
}
},
{ {
"path": "groupPurchaseSubmit/index", "path": "groupPurchaseSubmit/index",
"style": { "style": {
@ -682,7 +760,7 @@
{ {
"path": "index/index", "path": "index/index",
"style": { "style": {
"navigationBarTitleText": "榴园到家 服务至上", "navigationBarTitleText": "湖畔到家 服务至上",
"navigationBarBackgroundColor": "#fff" "navigationBarBackgroundColor": "#fff"
} }
}, },
@ -960,6 +1038,39 @@
} }
} }
] ]
},
{
"root": "packages/advertising",
"pages": [
{
"path": "index/index",
"style": {
"navigationBarTitleText": "推荐商品",
"navigationBarBackgroundColor": "#ffffff"
}
},
{
"path": "shopCar/index",
"style": {
"navigationBarBackgroundColor": "#fff",
"navigationStyle": "custom"
}
},
{
"path": "goodsSubmit/index",
"style": {
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "提交团单"
}
},
{
"path": "goodsDetail/index",
"style": {
"navigationBarBackgroundColor": "#fff",
"navigationStyle": "custom"
}
}
]
} }
], ],
"globalStyle": { "globalStyle": {

View File

@ -49,7 +49,7 @@ page {
} }
.hot-word-container { .hot-word-container {
width: 60%; width: 90%;
height: 50rpx; height: 50rpx;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
@ -64,7 +64,7 @@ page {
.hot-word-item { .hot-word-item {
height: 50rpx; height: 50rpx;
line-height: 50rpx; line-height: 53rpx;
padding: 0 15rpx; padding: 0 15rpx;
color: #666; color: #666;
} }
@ -73,9 +73,12 @@ page {
background-color: #f5f5f5; background-color: #f5f5f5;
} }
.searchBox2 { .search_input {
display: flex; width: 55%;
align-items: center; height: 50rpx;
line-height: 50rpx;
padding: 0 15rpx;
color: #666;
} }
.white_container { .white_container {
@ -162,6 +165,8 @@ page {
} }
.searchBox2 { .searchBox2 {
display: flex;
align-items: center;
width: 100%; width: 100%;
height: 60rpx; height: 60rpx;
background-color: #f6f7fb; background-color: #f6f7fb;
@ -175,7 +180,7 @@ page {
} }
.searchBox2 image { .searchBox2 image {
width: 40rpx; width: 30rpx;
height: 28rpx; height: 28rpx;
margin-right: 16rpx; margin-right: 16rpx;
} }

View File

@ -21,7 +21,7 @@
<!-- 搜索框 --> <!-- 搜索框 -->
<view class="search2" v-if="isShowSearch"> <view class="search2" v-if="isShowSearch">
<view class="searchBox2"> <view class="searchBox2" @click="goSearchView">
<image <image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"
mode="aspectFill"></image> mode="aspectFill"></image>
@ -33,15 +33,15 @@
</view> </view>
</view> </view>
</view> </view>
<input class="search_input" placeholder='请输入内容' confirm-type='search' @input="searchInput" <!-- <input class="search_input" placeholder='请输入内容' confirm-type='search' @input="searchInput"
@confirm="searchInput" :value="selectKeyWord" /> @confirm="searchInput" :value="selectKeyWord" @click="goSearchView"/> -->
</view> </view>
</view> </view>
</view> </view>
<view class="mainBox" ref="mainBox"> <view class="mainBox" ref="mainBox">
<view class="white_container"> <view class="white_container">
<!-- 功能导航区 --> <!-- 功能导航区 -->
<view class="function-nav" v-if="showNav"> <!-- <view class="function-nav" v-if="showNav">
<view class="function-item" @click="goToShop"> <view class="function-item" @click="goToShop">
<view class="icon-box"> <view class="icon-box">
<image class="iconImg" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/index_shop.png" <image class="iconImg" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/index_shop.png"
@ -63,7 +63,7 @@
</view> </view>
<text>物业管理</text> <text>物业管理</text>
</view> </view>
</view> </view> -->
<!-- 轮播图 --> <!-- 轮播图 -->
<view class="swiper"> <view class="swiper">
<swiper @animationfinish="swipers" autoplay circular> <swiper @animationfinish="swipers" autoplay circular>
@ -93,13 +93,13 @@
<!-- 广告横幅 --> <!-- 广告横幅 -->
<view class="serverList1"> <view class="serverList1">
<view class="serverList1_left" @click="toAdvertisingView"> <view class="serverList1_left" v-if="serverLeftList.length > 0">
<image :src="serverLeft" mode="aspectFill" /> <image :src="serverLeft" mode="aspectFill" @tap="toAdvertisingView(serverLeftList)"/>
</view> </view>
<view class="serverList1_right"> <view class="serverList1_right" v-if="serverRightList.length > 0">
<view :class="['serverItemRight', `serverItemRight${index + 1}`]" @tap="headerServerClick(item)" <view :class="['serverItemRight', `serverItemRight${index + 1}`]"
v-for="(item, index) in serverRightList" :key="index"> v-for="(item, index) in serverRightList" :key="index">
<image :src="item.pic_src" mode="" /> <image :src="item.pic_src" mode="" @tap="index === 0 ? toAdvertisingView(serverRightList) : goToPurify(item)"/>
</view> </view>
</view> </view>
</view> </view>
@ -114,7 +114,7 @@
<view class="serverList_left"> <view class="serverList_left">
<swiper> <swiper>
<swiper-item v-for="(item, index) in homeLeftList" :key="index" @click="headerServerClick(item)"> <swiper-item v-for="(item, index) in homeLeftList" :key="index" @click="headerServerClick(item)">
<image :src="item.pic_src" alt="" class="serverList_left_img"/> <image :src="item.pic_src" alt="" class="serverList_left_img" />
<!-- <view>{{ item.ad_position }}</view> --> <!-- <view>{{ item.ad_position }}</view> -->
</swiper-item> </swiper-item>
</swiper> </swiper>
@ -172,7 +172,7 @@
</view> </view>
</view> </view>
</u-sticky> </u-sticky>
<!-- 商家列表展示 --> <!-- 商家列表展示 -->
<view class="merchantList" :class="{ merchantList2: merchatList.length < 3 }"> <view class="merchantList" :class="{ merchantList2: merchatList.length < 3 }">
<view class="overlay" v-if="showDropdown"></view> <view class="overlay" v-if="showDropdown"></view>
@ -205,8 +205,7 @@
</view> </view>
</view> </view>
<view class="merchantItem_right_con_right" @click="toJump(item)"> <view class="merchantItem_right_con_right" @click="toJump(item)">
<image <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_review.png"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_review.png"
mode="aspectFill"></image> mode="aspectFill"></image>
点评 点评
</view> </view>
@ -217,9 +216,9 @@
</view> </view>
</view> </view>
</view> </view>
<view class="more" v-if="flag">下拉加载后续10条,共计{{ bottomTotal }}条</view> <view class="more" v-if="flag">下拉加载后续10条,共计{{ bottomTotal }}条</view>
<nav-footer /> <nav-footer />
</view> </view>
</view> </view>
</view> </view>
@ -309,6 +308,7 @@ export default {
// 中部1左侧广告 // 中部1左侧广告
serverLeft: '', serverLeft: '',
serverLeftList: [],
// 中部1右侧广告 // 中部1右侧广告
serverRightList: [], serverRightList: [],
@ -325,6 +325,9 @@ export default {
}, },
methods: { methods: {
goSearchView(){
NavgateTo('/packages/shop/search/index');
},
goToShop() { goToShop() {
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
@ -352,8 +355,21 @@ export default {
}, },
// 广告商品跳转 // 广告商品跳转
toAdvertisingView(item) { toAdvertisingView(itemArry) {
NavgateTo('/packages/advertising/index/index') const item = itemArry[0]
NavgateTo('/packages/advertising/index/index?id=' + item.id, { isLogin: false })
},
//跳转到净水小程序
goToPurify() {
uni.navigateToMiniProgram({
appId: 'wx77b22c0a0018e580',
path: 'pages/newLogin/newLogin',
envVersion: 'release',
success(res) {
// 打开成功
}
})
}, },
async goToWuye() { async goToWuye() {
@ -553,7 +569,7 @@ export default {
async headerServerClick2(e) { async headerServerClick2(e) {
if (e.title == '更多') { if (e.title == '更多') {
NavgateTo('/packages/localLife/index/index') NavgateTo('/packages/localLife/index/index', { isLogin: false })
} }
const cate_id = this.categoryList.find(item => item.cate_name == e.title)?.id; const cate_id = this.categoryList.find(item => item.cate_name == e.title)?.id;
if (cate_id) { if (cate_id) {
@ -596,7 +612,7 @@ export default {
} }
}) })
} else { } else {
NavgateTo(e.link_url) NavgateTo(e.link_url, { isLogin: false })
// NavgateTo('/packages/localLife/index/index') // NavgateTo('/packages/localLife/index/index')
} }
// 小程序中可能需要用户手动复制链接或使用web-view // 小程序中可能需要用户手动复制链接或使用web-view
@ -678,8 +694,12 @@ export default {
page_num: 1, page_num: 1,
page_size: 10 page_size: 10
}, { silent: false }); }, { silent: false });
if (!res.rows.length) {
this.serverLeftList = []
}
if (res.rows.length) { if (res.rows.length) {
this.serverLeftList = res.rows
let filterRes = this.filterShowList(res?.rows, 1); let filterRes = this.filterShowList(res?.rows, 1);
filterRes.forEach(item => { filterRes.forEach(item => {
item.pic_src = picUrl + item.pic_src item.pic_src = picUrl + item.pic_src
@ -702,6 +722,9 @@ export default {
page_num: 1, page_num: 1,
page_size: 10 page_size: 10
}, { silent: false }); }, { silent: false });
if (!res.rows.length) {
this.serverRightList = []
}
if (res.rows.length) { if (res.rows.length) {
let filterRes = this.filterShowList(res?.rows, 1); let filterRes = this.filterShowList(res?.rows, 1);
filterRes.forEach(item => { filterRes.forEach(item => {
@ -954,8 +977,10 @@ export default {
// 分类查询 // 分类查询
async getCateList() { async getCateList() {
const res = await request(apiArr2.getCateList, "POST", { const params = {
}, { slice: false }); isShop: 1,
}
const res = await request(apiArr2.getCateList, "POST", params, { slice: false });
if (res.rows.length) { if (res.rows.length) {
this.currentCategoryId = res.rows[0].id this.currentCategoryId = res.rows[0].id
this.activeCategoryId = `category-${this.currentCategoryId}` this.activeCategoryId = `category-${this.currentCategoryId}`

View File

@ -3,10 +3,11 @@
width: 100%; width: 100%;
height: 1334rpx; height: 1334rpx;
position: fixed; position: fixed;
background-repeat: no-repeat;
} }
.login-title { .login-title {
margin-top: 655rpx; margin-top: 550rpx;
} }
.login-tip { .login-tip {
@ -52,6 +53,7 @@
align-items: center; align-items: center;
margin-top: 30rpx; margin-top: 30rpx;
} }
.input { .input {
border: 1px solid #EFEFEF; border: 1px solid #EFEFEF;
width: 550rpx; width: 550rpx;
@ -59,10 +61,12 @@
line-height: 60rpx; line-height: 60rpx;
margin-bottom: 30rpx; margin-bottom: 30rpx;
} }
.tips { .tips {
font-size: 24rpx; font-size: 24rpx;
color: #FD4529; color: #FD4529;
} }
.app_login_btn { .app_login_btn {
width: 550rpx; width: 550rpx;
font-weight: 400; font-weight: 400;

View File

@ -1,6 +1,6 @@
<template> <template>
<view class="login" <view class="login"
style="background-image: url(https://wechat-img-file.oss-cn-beijing.aliyuncs.com/login/Group_491.png);"> style="background-image: url(https://wechat-img-file.oss-cn-beijing.aliyuncs.com/loginMainImg.png);">
<view class="login-title"> <view class="login-title">
<view class="login-tip" style="font-size: 40rpx; color: #000000;">欢迎来到【湖畔生活家】</view> <view class="login-tip" style="font-size: 40rpx; color: #000000;">欢迎来到【湖畔生活家】</view>
@ -78,6 +78,7 @@ export default {
uni.setStorageSync('is_deal', loginRes.is_deal); uni.setStorageSync('is_deal', loginRes.is_deal);
uni.setStorageSync('is_dev', loginRes.is_dev); uni.setStorageSync('is_dev', loginRes.is_dev);
uni.setStorageSync('is_shop', loginRes.is_shop); uni.setStorageSync('is_shop', loginRes.is_shop);
uni.setStorageSync('is_merchant', loginRes.is_merchant);
uni.setStorageSync('is_worker', loginRes.is_worker); uni.setStorageSync('is_worker', loginRes.is_worker);
@ -90,6 +91,7 @@ export default {
uni.setStorageSync('userId', res2.user_id); uni.setStorageSync('userId', res2.user_id);
uni.setStorageSync('openId', res2.open_id); uni.setStorageSync('openId', res2.open_id);
uni.setStorageSync('shopId', res2.wshop_id); uni.setStorageSync('shopId', res2.wshop_id);
uni.setStorageSync('headPhoto', res2.img);
this.isLogin = true; this.isLogin = true;
that.getUserInfo(); that.getUserInfo();
@ -147,6 +149,7 @@ export default {
uni.removeStorageSync('is_deal'); uni.removeStorageSync('is_deal');
uni.removeStorageSync('is_dev'); uni.removeStorageSync('is_dev');
uni.removeStorageSync('is_shop'); uni.removeStorageSync('is_shop');
uni.removeStorageSync('is_merchant');
uni.removeStorageSync('is_worker'); uni.removeStorageSync('is_worker');
uni.removeStorageSync('shopId'); uni.removeStorageSync('shopId');
uni.removeStorageSync('order_dispatch_permission'); uni.removeStorageSync('order_dispatch_permission');
@ -196,6 +199,7 @@ export default {
uni.setStorageSync('is_deal', loginRes.is_deal); uni.setStorageSync('is_deal', loginRes.is_deal);
uni.setStorageSync('is_dev', loginRes.is_dev); uni.setStorageSync('is_dev', loginRes.is_dev);
uni.setStorageSync('is_shop', loginRes.is_shop); uni.setStorageSync('is_shop', loginRes.is_shop);
uni.setStorageSync('is_merchant', loginRes.is_merchant);
uni.setStorageSync('is_worker', loginRes.is_worker); uni.setStorageSync('is_worker', loginRes.is_worker);
// 获取用户信息 // 获取用户信息

View File

@ -2,35 +2,19 @@
<view class="city-select-page" v-if="loading"> <view class="city-select-page" v-if="loading">
<view class="white_container padding_bottom40"> <view class="white_container padding_bottom40">
<!-- 搜索框 --> <!-- 搜索框 -->
<u-search <u-search placeholder="输入城市进行搜索" :value="searchValue" @search="handleSearch" @change="handleSearch"
placeholder="输入城市进行搜索" :showAction="false" height="70" searchIconSize="40" shape="round"></u-search>
:value="searchValue"
@search="handleSearch"
@change="handleSearch"
:showAction="false"
height="70"
searchIconSize="40"
shape="round"
></u-search>
<view v-if="searchValue" class="search_popup"> <view v-if="searchValue" class="search_popup">
<view v-if="searchRes.length === 0" class="list-item">暂无搜索结果</view> <view v-if="searchRes.length === 0" class="list-item">暂无搜索结果</view>
<view <view v-else v-for="(item, index) in searchRes" :key="index"
v-else :class="['list-item', index === searchRes.length - 1 && 'no_border']" @click="headerSelectMapClick(item)">
v-for="(item, index) in searchRes"
:key="index"
:class="['list-item', index === searchRes.length - 1 && 'no_border']"
@click="headerSelectMapClick(item)"
>
{{ item.name }} {{ item.name }}
</view> </view>
</view> </view>
<view v-if="!searchValue"> <view v-if="!searchValue">
<!-- 当前定位城市 --> <!-- 当前定位城市 -->
<view class="current-city"> <view class="current-city">
<image <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/Index_add.png" mode="widthFix" />
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/Index_add.png"
mode="widthFix"
/>
<text>当前定位城市 {{ location.cityName }}</text> <text>当前定位城市 {{ location.cityName }}</text>
</view> </view>
@ -38,13 +22,8 @@
<view class="hot-cities"> <view class="hot-cities">
<text class="title">国内热门城市</text> <text class="title">国内热门城市</text>
<view class="city-list"> <view class="city-list">
<view <view v-for="(item, index) in hotCityList" class="city_name" :key="index"
v-for="(item, index) in hotCityList" @click="headerSelectMapClick(item)">{{ item.name }}</view>
class="city_name"
:key="index"
@click="headerSelectMapClick(item)"
>{{ item.name }}</view
>
</view> </view>
</view> </view>
</view> </view>
@ -52,28 +31,15 @@
<view v-if="!searchValue" class="container"> <view v-if="!searchValue" class="container">
<!-- 左侧列表 --> <!-- 左侧列表 -->
<scroll-view <scroll-view class="list-scroll" scroll-y :scroll-into-view="activeId" @scroll="handleScroll">
class="list-scroll" <view v-for="(group, index) in groupedData" :key="index" class="white_container" :id="'group-' + group.letter">
scroll-y
:scroll-into-view="activeId"
@scroll="handleScroll"
>
<view
v-for="(group, index) in groupedData"
:key="index"
class="white_container"
:id="'group-' + group.letter"
>
<!-- 字母标题 --> <!-- 字母标题 -->
<view class="letter-title">{{ group.letter }}</view> <view class="letter-title">{{ group.letter }}</view>
<!-- 列表项 --> <!-- 列表项 -->
<!-- TODO: 小程序编译避坑指南: --> <!-- TODO: 小程序编译避坑指南: -->
<view <view v-for="(item, ind) in group.list" :key="item.id"
v-for="(item, ind) in group.list"
:key="item.id"
:class="['list-item', ind === group.list.length - 1 && 'no_border']" :class="['list-item', ind === group.list.length - 1 && 'no_border']"
@click="() => { headerSelectMapClick(item) }" @click="() => { headerSelectMapClick(item) }">
>
{{ item.name }} {{ item.name }}
</view> </view>
</view> </view>
@ -81,12 +47,7 @@
<!-- 右侧索引栏 --> <!-- 右侧索引栏 -->
<view class="index-bar"> <view class="index-bar">
<view <view v-for="(letter, index) in letters" :key="index" class="index-item" @tap="scrollToLetter(letter)">
v-for="(letter, index) in letters"
:key="index"
class="index-item"
@tap="scrollToLetter(letter)"
>
{{ letter }} {{ letter }}
</view> </view>
</view> </view>
@ -96,7 +57,7 @@
<script> <script>
import { apiArr } from "../../api/area.js"; import { apiArr } from "../../api/area.js";
import { request, debounce } from "../../utils/index.js"; import { request, debounce, NavgateTo } from "../../utils/index.js";
export default { export default {
data() { data() {
@ -182,14 +143,38 @@ export default {
return; return;
} }
// 更新页面数据,如标记点等 // 更新页面数据,如标记点等
// 提取城市名称,添加防御性检查
let cityName = '';
let district = '';
let region = '';
// 提取城市名
const cityMatch = res.address.match(/(.*?(?:省|自治区)|^)(.*?)(?:市|地区|盟|州|县|区)?$/);
if (cityMatch && cityMatch[2]) {
const cityMatch2 = cityMatch[2].match(/(.*市)/);
if (cityMatch2 && cityMatch2[1]) {
cityName = cityMatch2[1];
}
}
// 提取区县
const districtMatch = res.address.match(/市(.*)/);
if (districtMatch && districtMatch[1]) {
district = districtMatch[1];
}
// 提取省市区
const regionMatch = res.address.match(/^(.*?省.*?(?:市|自治州|盟).*?(?:县|区|旗))/);
if (regionMatch && regionMatch[1]) {
region = regionMatch[1];
}
const selectLocation = { const selectLocation = {
cityName: res.address cityName: cityName,
.match(/(.*?(?:省|自治区)|^)(.*?)(?:市|地区|盟|州|县|区)?$/)[2] district: district,
.match(/(.*市)/)[1],
district: res.address.match(/市(.*)/)[1],
lat: res.latitude, lat: res.latitude,
lng: res.longitude, lng: res.longitude,
region: res.address.match(/^(.*?省.*?(?:市|自治州|盟).*?(?:县|区|旗))/)[1], // 省市区 region: region,
}; };
uni.setStorageSync("location", selectLocation); // 缓存数据信息 uni.setStorageSync("location", selectLocation); // 缓存数据信息
// uni.setStorageSync('city', selectLocation.cityName); // 缓存数据信息 // uni.setStorageSync('city', selectLocation.cityName); // 缓存数据信息
@ -203,13 +188,13 @@ export default {
}, },
}); });
}, },
handleSearch: debounce(function(keyword) { handleSearch: debounce(function (keyword) {
if(keyword === '') { if (keyword === '') {
this.searchValue = ''; this.searchValue = '';
this.searchRes = []; this.searchRes = [];
return; return;
} }
uni.showLoading({ uni.showLoading({
title: '加载中', title: '加载中',
mask: true mask: true
@ -227,7 +212,7 @@ export default {
}, 500), }, 500),
groupData(item) { groupData(item) {
console.log('123. item', item); console.log('123. item', item);
const map = {}; const map = {};
this.letters.forEach((letter) => { this.letters.forEach((letter) => {
map[letter] = { map[letter] = {
@ -266,9 +251,9 @@ export default {
mask: true mask: true
}) })
const params = { const params = {
ad_level:2 ad_level: 2
} }
const res = await request(apiArr.getRegionList, 'POST', params, { silent: false }); const res = await request(apiArr.getRegionList, 'POST', params, { silent: false });
// TODO: 数据量返回过于庞大,只获取所需信息,其他内容舍弃 // TODO: 数据量返回过于庞大,只获取所需信息,其他内容舍弃
const newRes = res.rows.map((item) => { const newRes = res.rows.map((item) => {
return { return {
@ -279,7 +264,7 @@ export default {
} }
}) })
console.log('111', newRes) console.log('111', newRes)
// this.cityList = newRes; // this.cityList = newRes;
const hotsList = res.rows.filter((item) => item.hot === 2).map((item) => { const hotsList = res.rows.filter((item) => item.hot === 2).map((item) => {
return { return {
lat: item.lat, lat: item.lat,
@ -289,7 +274,7 @@ export default {
}); });
console.log('热门城市信息', hotsList); console.log('热门城市信息', hotsList);
this.hotCityList = hotsList; this.hotCityList = hotsList;
await this.groupData(newRes); await this.groupData(newRes);
}, },
// 滚动时监听当前位置 // 滚动时监听当前位置

View File

@ -1,6 +1,7 @@
page { page {
background: #F6F7FB; background: #F6F7FB;
} }
.conatiner { .conatiner {
/* height: 100%; */ /* height: 100%; */
/* height: 578rpx; */ /* height: 578rpx; */
@ -22,6 +23,7 @@ page {
margin-bottom: 35rpx; margin-bottom: 35rpx;
/* pointer-events: none; */ /* pointer-events: none; */
} }
/* 头像 */ /* 头像 */
.avatar-container { .avatar-container {
display: flex; display: flex;
@ -35,6 +37,7 @@ page {
align-items: center; align-items: center;
pointer-events: auto; pointer-events: auto;
} }
/* 头像图片 */ /* 头像图片 */
.avatar { .avatar {
width: 130rpx; width: 130rpx;
@ -43,23 +46,38 @@ page {
border-radius: 50%; border-radius: 50%;
overflow: hidden; overflow: hidden;
} }
.avatar_right { .avatar_right {
flex: 1; flex: 1;
} }
.avatar_title { .avatar_title {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
} }
.avatar_setting {
.avatar_setting {
display: flex; display: flex;
pointer-events: auto; pointer-events: auto;
} }
.avatar_setting > image {
.avatar_setting_box{
width: 70rpx;
height: 50rpx;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
margin: 0 5rpx;
}
.avatar_setting_box image {
width: 34rpx; width: 34rpx;
height: 34rpx; height: 34rpx;
} }
.avatar_setting > image:first-child {
.avatar_setting>image:first-child {
margin-right: 40rpx; margin-right: 40rpx;
} }
@ -68,9 +86,11 @@ page {
font-size: 36rpx; font-size: 36rpx;
pointer-events: auto; pointer-events: auto;
} }
.avater_mobile { .avater_mobile {
margin-top: 10rpx; margin-top: 10rpx;
} }
.center { .center {
position: relative; position: relative;
margin: 0 20rpx; margin: 0 20rpx;
@ -80,23 +100,26 @@ page {
.gold_container { .gold_container {
/* width: 710rpx; */ /* width: 710rpx; */
height: 127rpx; height: 127rpx;
background: linear-gradient( 90deg, #FFE9A3 0%, rgba(232,127,0,0.8) 100%); background: linear-gradient(90deg, #FFE9A3 0%, rgba(232, 127, 0, 0.8) 100%);
box-shadow: inset 0rpx 1rpx 2rpx 0rpx #E2C47C; box-shadow: inset 0rpx 1rpx 2rpx 0rpx #E2C47C;
border-radius: 30rpx 30rpx 30rpx 30rpx; border-radius: 30rpx 30rpx 30rpx 30rpx;
margin: 37rpx 0 0; margin: 37rpx 0 0;
position: relative; position: relative;
} }
.gold_title { .gold_title {
display: flex; display: flex;
align-items: center; align-items: center;
padding-top: 16rpx; padding-top: 16rpx;
} }
.gold { .gold {
margin-left: 37rpx; margin-left: 37rpx;
font-weight: normal; font-weight: normal;
font-size: 34rpx; font-size: 34rpx;
color: #7F3907; color: #7F3907;
} }
.monenyt { .monenyt {
margin-left: 17rpx; margin-left: 17rpx;
margin-right: 37rpx; margin-right: 37rpx;
@ -104,13 +127,15 @@ color: #7F3907;
font-size: 40rpx; font-size: 40rpx;
color: #7F3907; color: #7F3907;
} }
.price { .price {
margin-left: 37rpx; margin-left: 37rpx;
font-weight: normal; font-weight: normal;
font-size: 26rpx; font-size: 26rpx;
color: #7F3907; color: #7F3907;
margin-right: 20rpx; margin-right: 20rpx;
} }
.gold_pic { .gold_pic {
width: 140rpx; width: 140rpx;
height: 113rpx; height: 113rpx;
@ -118,17 +143,20 @@ margin-right: 20rpx;
top: 0; top: 0;
right: 39rpx; right: 39rpx;
} }
.main { .main {
margin: 0 20rpx; margin: 0 20rpx;
border-radius: 20rpx 20rpx 20rpx 20rpx; border-radius: 20rpx 20rpx 20rpx 20rpx;
background: #FFFFFF; background: #FFFFFF;
} }
.main1 { .main1 {
width: 100%; width: 100%;
margin: 0; margin: 0;
position: absolute; position: absolute;
top: 80rpx; top: 80rpx;
} }
.main_title { .main_title {
padding-top: 25rpx; padding-top: 25rpx;
margin: 0 0 40rpx 30rpx; margin: 0 0 40rpx 30rpx;
@ -136,6 +164,7 @@ margin-right: 20rpx;
font-size: 36rpx; font-size: 36rpx;
color: #222222; color: #222222;
} }
.margin20 { .margin20 {
margin-top: 20rpx; margin-top: 20rpx;
} }
@ -148,22 +177,25 @@ margin-right: 20rpx;
margin-right: 20rpx; margin-right: 20rpx;
margin-bottom: 21rpx; margin-bottom: 21rpx;
} }
.section1 { .section1 {
justify-content: space-around; justify-content: space-around;
} }
.section_label { .section_label {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
} }
.nav_icon { .nav_icon {
width: 50rpx; width: 50rpx;
height: 50rpx; height: 50rpx;
margin-bottom: 20rpx; margin-bottom: 20rpx;
} }
.grid-text { .grid-text {
font-size: 28rpx; font-size: 28rpx;
font-weight: bold; font-weight: bold;
} }
@ -176,6 +208,14 @@ margin-right: 20rpx;
border-radius: 20rpx; border-radius: 20rpx;
padding-bottom: 25rpx; padding-bottom: 25rpx;
} }
.item2 {
display: grid;
place-items: center;
/* 同时实现水平和垂直居中 */
}
.padding_bottom0 { .padding_bottom0 {
padding-bottom: 0; padding-bottom: 0;
} }
@ -205,24 +245,26 @@ margin-right: 20rpx;
position: fixed; position: fixed;
right: 0; right: 0;
bottom: 212rpx; bottom: 212rpx;
background: rgba(255,55,11,0.6); background: rgba(255, 55, 11, 0.6);
border-radius: 50%; border-radius: 50%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
font-weight: normal; font-weight: normal;
font-size: 28rpx; font-size: 28rpx;
color: #FFFFFF; color: #FFFFFF;
} }
.customer > image {
.customer>image {
width: 50rpx; width: 50rpx;
height: 55rpx; height: 55rpx;
} }
.uicon-volume { .uicon-volume {
font-size: 28rpx !important; font-size: 28rpx !important;
} }
.u-grid-item { .u-grid-item {
margin-bottom: 36rpx; margin-bottom: 36rpx;
} }

View File

@ -10,33 +10,37 @@
<view class="avatar_title"> <view class="avatar_title">
<view class="login-btn">{{ userInfo.nick_name ? userInfo.nick_name : '登录/注册' }}</view> <view class="login-btn">{{ userInfo.nick_name ? userInfo.nick_name : '登录/注册' }}</view>
<view class="avatar_setting"> <view class="avatar_setting">
<image <view class="avatar_setting_box">
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/page_user_Vector13.png" <image
mode="" @click.stop="headerRefreshClick" /> src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/page_user_Vector13.png"
<button class="login-btn" open-type="getPhoneNumber" style="display: none;" mode="" @click.stop="headerRefreshClick" />
@click="headerLoginClick" @getphonenumber="getPhoneNumber" id="hiddenLoginBtn"></button> </view>
<image <!-- <button class="login-btn" open-type="getPhoneNumber" style="display: none;"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/page_user_Vector14.png" @click="headerLoginClick" @getphonenumber="getPhoneNumber" id="hiddenLoginBtn"></button> -->
mode="" @click.stop="headerSettingsClick" /> <view class="avatar_setting_box">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/page_user_Vector14.png"
mode="" @click.stop="headerSettingsClick" />
</view>
</view> </view>
</view> </view>
<view class="avater_mobile">{{ userInfo.mobile }}</view> <view class="avater_mobile">{{ userInfo.mobile }}</view>
</view> </view>
</view> </view>
<view class="section section1"> <view class="section section1">
<view class="section_label"> <view class="section_label" @click="goWallet(1, userInfo)">
<view>{{ userInfo.balance }}</view> <view>{{ userInfo.points }}</view>
<view>积分</view> <view>积分</view>
</view> </view>
<view class="section_label"> <view class="section_label">
<view>0.00</view> <view>0.00</view>
<view>繁华币</view> <view>繁华币</view>
</view> </view>
<view class="section_label"> <view class="section_label" @click="goWallet(2, userInfo)">
<view>0.00元</view> <view>{{ userInfo.property_housing_fund }}元</view>
<view>物业费公积金</view> <view>物业费</view>
</view> </view>
<view class="section_label"> <view class="section_label" @click="goWallet(3)">
<view>0元</view> <view>0元</view>
<view>红包卡券</view> <view>红包卡券</view>
</view> </view>
@ -113,14 +117,16 @@
</u-grid> </u-grid>
</view> </view>
</view> </view>
<view class="main margin20" v-if="isShop"> <view class="main margin20" v-if="shopManagementList.some(item => item.isShow)">
<view class="main_title">商家端</view> <view class="main_title">功能服务</view>
<view class="item1 padding_bottom0"> <view class="item1 padding_bottom0">
<u-grid col="4" :border="false"> <u-grid col="4" :border="false">
<u-grid-item @click="headerOrderClick(item)" v-for="(item, index) in shopManagementList" <u-grid-item @click="headerOrderClick(item)" v-for="(item, index) in shopManagementList"
:key="index"> :key="index">
<image class="nav_icon" :src="item.image" mode=""></image> <view v-if="item.isShow" class="item2">
<text class="grid-text">{{ item.name }}</text> <image class="nav_icon" :src="item.image" mode=""></image>
<text class="grid-text">{{ item.name }}</text>
</view>
</u-grid-item> </u-grid-item>
</u-grid> </u-grid>
</view> </view>
@ -217,11 +223,26 @@ export default {
url: "", url: "",
} }
], ],
shopManagementList: [{ shopManagementList: [
image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/user_page_Group_1782.png", {
name: "店铺管理", image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/user_page_Group_1782.png",
url: "/packages/storeManagement/index/index", name: "商家端",
}], url: "/packages/storeManagement/index/index",
isShow: uni.getStorageSync('is_merchant'),
},
{
image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/userPageGys.png",
name: "供应商端",
url: "",
isShow: uni.getStorageSync('is_worker'),
},
{
image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/userPageWuye.png",
name: "物业端",
url: "/packages/workOrderDashboard/guide/index",
isShow: uni.getStorageSync("is_worker"),
}
],
parkList: [ parkList: [
{ {
image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/park/parkIndex_icon1.png", image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/park/parkIndex_icon1.png",
@ -250,6 +271,9 @@ export default {
}, },
methods: { methods: {
goWallet(type, item) {
NavgateTo('/packages/user/wallet/index?type=' + type + '&item=' + JSON.stringify(item));
},
// 头像点击 // 头像点击
toLogin() { toLogin() {
NavgateTo('/packages/user/replenishInfo/index'); NavgateTo('/packages/user/replenishInfo/index');
@ -269,6 +293,7 @@ export default {
uni.removeStorageSync('is_deal'); uni.removeStorageSync('is_deal');
uni.removeStorageSync('is_dev'); uni.removeStorageSync('is_dev');
uni.removeStorageSync('is_shop'); uni.removeStorageSync('is_shop');
uni.removeStorageSync('is_merchant');
uni.removeStorageSync('is_worker'); uni.removeStorageSync('is_worker');
uni.removeStorageSync('shopId'); uni.removeStorageSync('shopId');
uni.removeStorageSync('order_dispatch_permission'); uni.removeStorageSync('order_dispatch_permission');
@ -296,6 +321,7 @@ export default {
uni.setStorageSync('is_deal', loginRes.is_deal); uni.setStorageSync('is_deal', loginRes.is_deal);
uni.setStorageSync('is_dev', loginRes.is_dev); uni.setStorageSync('is_dev', loginRes.is_dev);
uni.setStorageSync('is_shop', loginRes.is_shop); uni.setStorageSync('is_shop', loginRes.is_shop);
uni.setStorageSync('is_merchant', loginRes.is_merchant);
uni.setStorageSync('is_worker', loginRes.is_worker); uni.setStorageSync('is_worker', loginRes.is_worker);

View File

@ -75,4 +75,4 @@ $uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色 $uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px; $uni-font-size-paragraph:15px;
@import 'uview-ui/theme.scss'; @import 'uni_modules/uview-ui/theme.scss';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More