From 21112173f2dda788b5f86c666caefbec8418a804 Mon Sep 17 00:00:00 2001 From: XingQue Date: Sat, 27 Jun 2026 01:26:11 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=9F=E4=B8=80=E6=8E=92=E8=A1=8C=E6=A6=9C?= =?UTF-8?q?=E5=AF=B9=E9=BD=90=E6=98=9F=E9=9B=80UI=EF=BC=8C=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E8=B5=84=E6=BA=90=E5=90=8E=E5=8F=B0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=AE=9E=E6=97=B6=E5=88=B7=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- miniprogram/app.js | 1 + miniprogram/app.json | 107 + miniprogram/app.wxss | 10 + .../components/chenghao-tag/chenghao-tag.js | 73 + .../components/chenghao-tag/chenghao-tag.json | 4 + .../components/chenghao-tag/chenghao-tag.wxml | 20 + .../components/chenghao-tag/chenghao-tag.wxss | 90 + .../global-notification.js | 366 + .../global-notification.json | 4 + .../global-notification.wxml | 49 + .../global-notification.wxss | 215 + .../navigation-bar/navigation-bar.js | 102 + .../navigation-bar/navigation-bar.json | 5 + .../navigation-bar/navigation-bar.wxml | 64 + .../navigation-bar/navigation-bar.wxss | 96 + .../components/order-card/order-card.js | 102 + .../components/order-card/order-card.json | 4 + .../components/order-card/order-card.wxml | 20 + .../components/order-card/order-card.wxss | 39 + .../components/order-sender/order-sender.js | 16 + .../components/order-sender/order-sender.json | 4 + .../components/order-sender/order-sender.wxml | 12 + .../components/order-sender/order-sender.wxss | 45 + .../components/popup-notice/popup-notice.js | 324 + .../components/popup-notice/popup-notice.json | 4 + .../components/popup-notice/popup-notice.wxml | 110 + .../components/popup-notice/popup-notice.wxss | 295 + miniprogram/config/roles.js | 144 + miniprogram/custom-tab-bar/index.js | 194 + miniprogram/custom-tab-bar/index.json | 4 + miniprogram/custom-tab-bar/index.wxml | 42 + miniprogram/custom-tab-bar/index.wxss | 165 + miniprogram/images/dingdan.png | Bin 0 -> 15163 bytes miniprogram/images/fenlei.png | Bin 0 -> 2859 bytes miniprogram/images/gonggao.png | Bin 0 -> 8795 bytes miniprogram/images/goumai.png | Bin 0 -> 7689 bytes miniprogram/images/jiedanchi.png | Bin 0 -> 25039 bytes miniprogram/images/jieshao.png | Bin 0 -> 13399 bytes miniprogram/images/jinpaidashou.png | Bin 0 -> 5385 bytes miniprogram/images/role-switch.png | Bin 0 -> 5301 bytes miniprogram/images/shuaxin.png | Bin 0 -> 7937 bytes miniprogram/images/sousuo.png | Bin 0 -> 8059 bytes miniprogram/images/tiaoxuan.png | Bin 0 -> 10125 bytes miniprogram/images/tuichu.png | Bin 0 -> 5846 bytes miniprogram/images/weixinzhifu.png | Bin 0 -> 7924 bytes miniprogram/images/wode.png | Bin 0 -> 10677 bytes miniprogram/images/xiaoxi.png | Bin 0 -> 4055 bytes miniprogram/images/yituikuan.png | Bin 0 -> 17098 bytes miniprogram/images/yiwancheng.png | Bin 0 -> 12372 bytes miniprogram/images/zhuanqu.png | Bin 0 -> 17777 bytes miniprogram/images/zhuye.png | Bin 0 -> 6269 bytes miniprogram/pages/cfss/cfss/cfss.js | 100 + miniprogram/pages/cfss/cfss/cfss.json | 10 + miniprogram/pages/cfss/cfss/cfss.wxml | 68 + miniprogram/pages/cfss/cfss/cfss.wxss | 121 + .../components/fakuan-list/fakuan-list.js | 317 + .../components/fakuan-list/fakuan-list.json | 6 + .../components/fakuan-list/fakuan-list.wxml | 116 + .../components/fakuan-list/fakuan-list.wxss | 77 + .../cfss/components/fakuan-pay/fakuan-pay.js | 178 + .../components/fakuan-pay/fakuan-pay.json | 3 + .../components/fakuan-pay/fakuan-pay.wxml | 61 + .../components/fakuan-pay/fakuan-pay.wxss | 59 + .../cfss/components/jifen-list/jifen-list.js | 220 + .../components/jifen-list/jifen-list.json | 3 + .../components/jifen-list/jifen-list.wxml | 105 + .../components/jifen-list/jifen-list.wxss | 86 + miniprogram/pages/czjilu/czjilu.js | 288 + miniprogram/pages/czjilu/czjilu.json | 11 + miniprogram/pages/czjilu/czjilu.wxml | 119 + miniprogram/pages/czjilu/czjilu.wxss | 506 + .../pages/dashouchongzhi/dashouchongzhi.js | 975 ++ .../pages/dashouchongzhi/dashouchongzhi.json | 12 + .../pages/dashouchongzhi/dashouchongzhi.wxml | 514 + .../pages/dashouchongzhi/dashouchongzhi.wxss | 1705 ++ .../pages/dashoudingdan/dashoudingdan.js | 344 + .../pages/dashoudingdan/dashoudingdan.json | 8 + .../pages/dashoudingdan/dashoudingdan.wxml | 111 + .../pages/dashoudingdan/dashoudingdan.wxss | 273 + miniprogram/pages/dashouduan/dashouduan.js | 543 + miniprogram/pages/dashouduan/dashouduan.json | 14 + miniprogram/pages/dashouduan/dashouduan.wxml | 212 + miniprogram/pages/dashouduan/dashouduan.wxss | 860 + miniprogram/pages/dashouguize/dashouguize.js | 103 + .../pages/dashouguize/dashouguize.json | 11 + .../pages/dashouguize/dashouguize.wxml | 12 + .../pages/dashouguize/dashouguize.wxss | 15 + .../pages/dashoupaihang/dashoupaihang.js | 40 +- .../pages/dashoupaihang/dashoupaihang.wxss | 23 +- .../pages/dashouxiaoxi/dashouxiaoxi.js | 684 + .../pages/dashouxiaoxi/dashouxiaoxi.json | 10 + .../pages/dashouxiaoxi/dashouxiaoxi.wxml | 316 + .../pages/dashouxiaoxi/dashouxiaoxi.wxss | 963 ++ .../pages/dashouxiugai/dashouxiugai.js | 422 + .../pages/dashouxiugai/dashouxiugai.json | 11 + .../pages/dashouxiugai/dashouxiugai.wxml | 103 + .../pages/dashouxiugai/dashouxiugai.wxss | 197 + miniprogram/pages/dingdan/dingdan.js | 287 + miniprogram/pages/dingdan/dingdan.json | 5 + miniprogram/pages/dingdan/dingdan.wxml | 111 + miniprogram/pages/dingdan/dingdan.wxss | 262 + .../dingdanxiangqing/dingdanxiangqing.js | 412 + .../dingdanxiangqing/dingdanxiangqing.json | 5 + .../dingdanxiangqing/dingdanxiangqing.wxml | 202 + .../dingdanxiangqing/dingdanxiangqing.wxss | 422 + miniprogram/pages/dsddxq/dsddxq.js | 730 + miniprogram/pages/dsddxq/dsddxq.json | 5 + miniprogram/pages/dsddxq/dsddxq.wxml | 478 + miniprogram/pages/dsddxq/dsddxq.wxss | 589 + miniprogram/pages/fenlei/fenlei.js | 452 + miniprogram/pages/fenlei/fenlei.json | 6 + miniprogram/pages/fenlei/fenlei.wxml | 217 + miniprogram/pages/fenlei/fenlei.wxss | 1215 ++ miniprogram/pages/guanshiduan/guanshiduan.js | 548 + .../pages/guanshiduan/guanshiduan.json | 11 + .../pages/guanshiduan/guanshiduan.wxml | 122 + .../pages/guanshiduan/guanshiduan.wxss | 367 + .../pages/guanshipaihang/guanshipaihang.json | 12 + .../pages/guanshipaihang/guanshipaihang.wxml | 2 + .../pages/guanshipaihang/guanshipaihang.wxss | 5 + miniprogram/pages/guanzhual/guanzhual.js | 90 + miniprogram/pages/guanzhual/guanzhual.json | 8 + miniprogram/pages/guanzhual/guanzhual.wxml | 39 + miniprogram/pages/guanzhual/guanzhual.wxss | 95 + miniprogram/pages/haibao/haibao.js | 281 + miniprogram/pages/haibao/haibao.json | 8 + miniprogram/pages/haibao/haibao.wxml | 71 + miniprogram/pages/haibao/haibao.wxss | 269 + miniprogram/pages/index/index.js | 494 + miniprogram/pages/index/index.json | 12 + miniprogram/pages/index/index.wxml | 172 + miniprogram/pages/index/index.wxss | 585 + miniprogram/pages/jiedan/jiedan.js | 528 + miniprogram/pages/jiedan/jiedan.json | 12 + miniprogram/pages/jiedan/jiedan.wxml | 208 + miniprogram/pages/jiedan/jiedan.wxss | 762 + miniprogram/pages/jiedanchi/jiedanchi.js | 467 + miniprogram/pages/jiedanchi/jiedanchi.json | 9 + miniprogram/pages/jiedanchi/jiedanchi.wxml | 263 + miniprogram/pages/jiedanchi/jiedanchi.wxss | 655 + miniprogram/pages/jiedanchi2/jiedanchi2.js | 66 + miniprogram/pages/jiedanchi2/jiedanchi2.json | 3 + miniprogram/pages/jiedanchi2/jiedanchi2.wxml | 2 + miniprogram/pages/jiedanchi2/jiedanchi2.wxss | 1 + miniprogram/pages/jinpaids/jinpaids.js | 346 + miniprogram/pages/jinpaids/jinpaids.json | 9 + miniprogram/pages/jinpaids/jinpaids.wxml | 193 + miniprogram/pages/jinpaids/jinpaids.wxss | 610 + miniprogram/pages/jisufd/jisufd.js | 618 + miniprogram/pages/jisufd/jisufd.json | 12 + miniprogram/pages/jisufd/jisufd.wxml | 230 + miniprogram/pages/jisufd/jisufd.wxss | 222 + miniprogram/pages/kaohe_dafen/kaohe_dafen.js | 237 + .../pages/kaohe_dafen/kaohe_dafen.json | 10 + .../pages/kaohe_dafen/kaohe_dafen.wxml | 118 + .../pages/kaohe_dafen/kaohe_dafen.wxss | 170 + miniprogram/pages/kaohe_jilu/kaohe_jilu.js | 149 + miniprogram/pages/kaohe_jilu/kaohe_jilu.json | 9 + miniprogram/pages/kaohe_jilu/kaohe_jilu.wxml | 130 + miniprogram/pages/kaohe_jilu/kaohe_jilu.wxss | 263 + .../pages/kaohe_jinpai/kaohe_jinpai.js | 461 + .../pages/kaohe_jinpai/kaohe_jinpai.json | 9 + .../pages/kaohe_jinpai/kaohe_jinpai.wxml | 135 + .../pages/kaohe_jinpai/kaohe_jinpai.wxss | 385 + .../pages/kaohe_zhongxin/kaohe_zhongxin.js | 240 + .../pages/kaohe_zhongxin/kaohe_zhongxin.json | 10 + .../pages/kaohe_zhongxin/kaohe_zhongxin.wxml | 144 + .../pages/kaohe_zhongxin/kaohe_zhongxin.wxss | 288 + miniprogram/pages/kaoheguan/kaoheguan.js | 195 + miniprogram/pages/kaoheguan/kaoheguan.json | 11 + miniprogram/pages/kaoheguan/kaoheguan.wxml | 128 + miniprogram/pages/kaoheguan/kaoheguan.wxss | 512 + .../pages/kefuliaotian/kefuliaotian.js | 526 + .../pages/kefuliaotian/kefuliaotian.json | 7 + .../pages/kefuliaotian/kefuliaotian.wxml | 109 + .../pages/kefuliaotian/kefuliaotian.wxss | 67 + miniprogram/pages/liaotian/liaotian.js | 452 + miniprogram/pages/liaotian/liaotian.json | 7 + miniprogram/pages/liaotian/liaotian.wxml | 87 + miniprogram/pages/liaotian/liaotian.wxss | 98 + miniprogram/pages/phone-auth/phone-auth.js | 40 + miniprogram/pages/phone-auth/phone-auth.json | 3 + miniprogram/pages/phone-auth/phone-auth.wxml | 41 + miniprogram/pages/phone-auth/phone-auth.wxss | 169 + .../pages/qunliaotian/qunliaotian.json | 6 + .../pages/qunliaotian/qunliaotian.wxml | 99 + .../pages/qunliaotian/qunliaotian.wxss | 133 + miniprogram/pages/renzheng/renzheng.js | 155 + miniprogram/pages/renzheng/renzheng.json | 8 + miniprogram/pages/renzheng/renzheng.wxml | 29 + miniprogram/pages/renzheng/renzheng.wxss | 95 + .../pages/shangjiaduan/shangjiaduan.js | 44 +- .../pages/shangjiaduan/shangjiaduan.json | 14 + .../pages/shangjiaduan/shangjiaduan.wxml | 178 + .../pages/shangjiaduan/shangjiaduan.wxss | 422 + .../shangpinxiangqing/shangpinxiangqing.js | 296 + .../shangpinxiangqing/shangpinxiangqing.json | 5 + .../shangpinxiangqing/shangpinxiangqing.wxml | 112 + .../shangpinxiangqing/shangpinxiangqing.wxss | 386 + miniprogram/pages/sjchongzhi/sjchongzhi.js | 473 + miniprogram/pages/sjchongzhi/sjchongzhi.json | 13 + miniprogram/pages/sjchongzhi/sjchongzhi.wxml | 129 + miniprogram/pages/sjchongzhi/sjchongzhi.wxss | 1024 ++ miniprogram/pages/sjddxq/sjddxq.js | 707 + miniprogram/pages/sjddxq/sjddxq.json | 5 + miniprogram/pages/sjddxq/sjddxq.wxml | 354 + miniprogram/pages/sjddxq/sjddxq.wxss | 185 + miniprogram/pages/sjdingdan/sjdingdan.js | 323 + miniprogram/pages/sjdingdan/sjdingdan.json | 9 + miniprogram/pages/sjdingdan/sjdingdan.wxml | 135 + miniprogram/pages/sjdingdan/sjdingdan.wxss | 430 + miniprogram/pages/sjpaidan/sjpaidan.js | 363 + miniprogram/pages/sjpaidan/sjpaidan.json | 7 + miniprogram/pages/sjpaidan/sjpaidan.wxml | 164 + miniprogram/pages/sjpaidan/sjpaidan.wxss | 437 + miniprogram/pages/sjpaihang/sjpaihang.json | 12 + miniprogram/pages/sjpaihang/sjpaihang.wxml | 2 + miniprogram/pages/sjpaihang/sjpaihang.wxss | 5 + miniprogram/pages/sjxiaoxi/sjxiaoxi.js | 338 + miniprogram/pages/sjxiaoxi/sjxiaoxi.json | 10 + miniprogram/pages/sjxiaoxi/sjxiaoxi.wxml | 241 + miniprogram/pages/sjxiaoxi/sjxiaoxi.wxss | 751 + miniprogram/pages/tijiao/tijiao.js | 313 + miniprogram/pages/tijiao/tijiao.json | 5 + miniprogram/pages/tijiao/tijiao.wxml | 124 + miniprogram/pages/tijiao/tijiao.wxss | 280 + .../pages/tixian/components/mode1/mode1.js | 484 + .../pages/tixian/components/mode1/mode1.json | 21 + .../pages/tixian/components/mode1/mode1.wxml | 133 + .../pages/tixian/components/mode1/mode1.wxss | 424 + .../pages/tixian/components/mode2/mode2.js | 587 + .../pages/tixian/components/mode2/mode2.json | 15 + .../pages/tixian/components/mode2/mode2.wxml | 152 + .../pages/tixian/components/mode2/mode2.wxss | 407 + miniprogram/pages/tixian/tixian.js | 75 + miniprogram/pages/tixian/tixian.json | 15 + miniprogram/pages/tixian/tixian.wxml | 33 + miniprogram/pages/tixian/tixian.wxss | 50 + miniprogram/pages/wode/wode.js | 178 + miniprogram/pages/wode/wode.json | 11 + miniprogram/pages/wode/wode.wxml | 123 + miniprogram/pages/wode/wode.wxss | 254 + miniprogram/pages/wodedashou/wodedashou.js | 194 + miniprogram/pages/wodedashou/wodedashou.json | 5 + miniprogram/pages/wodedashou/wodedashou.wxml | 93 + miniprogram/pages/wodedashou/wodedashou.wxss | 258 + miniprogram/pages/xiaoxi/xiaoxi.json | 6 + miniprogram/pages/xiugai/xiugai.js | 228 + miniprogram/pages/xiugai/xiugai.json | 10 + miniprogram/pages/xiugai/xiugai.wxml | 66 + miniprogram/pages/xiugai/xiugai.wxss | 477 + miniprogram/pages/xuanren/xuanren.js | 66 + miniprogram/pages/xuanren/xuanren.json | 5 + miniprogram/pages/xuanren/xuanren.wxml | 2 + miniprogram/pages/xuanren/xuanren.wxss | 1 + .../pages/yaoqingdashou/yaoqingdashou.js | 248 + .../pages/yaoqingdashou/yaoqingdashou.json | 13 + .../pages/yaoqingdashou/yaoqingdashou.wxml | 85 + .../pages/yaoqingdashou/yaoqingdashou.wxss | 405 + miniprogram/pages/yqguanshi/yqguanshi.js | 356 + miniprogram/pages/yqguanshi/yqguanshi.json | 8 + miniprogram/pages/yqguanshi/yqguanshi.wxml | 82 + miniprogram/pages/yqguanshi/yqguanshi.wxss | 315 + miniprogram/pages/zuzhangduan/zuzhangduan.js | 201 + .../pages/zuzhangduan/zuzhangduan.json | 10 + .../pages/zuzhangduan/zuzhangduan.wxml | 108 + .../pages/zuzhangduan/zuzhangduan.wxss | 562 + miniprogram/pages/zzfhjilu/zzfhjilu.js | 216 + miniprogram/pages/zzfhjilu/zzfhjilu.json | 10 + miniprogram/pages/zzfhjilu/zzfhjilu.wxml | 119 + miniprogram/pages/zzfhjilu/zzfhjilu.wxss | 728 + miniprogram/services/popupService.js | 203 + miniprogram/sitemap.json | 7 + miniprogram/static/lib/EmojiDecoder.js | 25 + .../static/lib/goeasy-2.13.24.esm.min.js | 1 + miniprogram/static/lib/restapi.js | 146 + miniprogram/static/lib/utils.js | 49 + miniprogram/utils/chat-core.js | 75 +- miniprogram/utils/cos-wx-sdk-v5.js | 13296 ++++++++++++++++ miniprogram/utils/group-chat.js | 55 + miniprogram/utils/imAuth/dashoujianquan.js | 51 + miniprogram/utils/imAuth/imRequest.js | 67 + miniprogram/utils/imAuth/jianquanxian.js | 58 + miniprogram/utils/imAuth/laobanjianquan.js | 51 + miniprogram/utils/imageUrl.js | 74 + miniprogram/utils/message-sender.js | 44 +- miniprogram/utils/page-assets.js | 76 + miniprogram/utils/phone-auth.js | 165 + miniprogram/utils/request.js | 66 + miniprogram/utils/role-manager.js | 0 miniprogram/utils/scriptService.js | 147 + miniprogram/utils/upload.js | 95 + 292 files changed, 64010 insertions(+), 81 deletions(-) create mode 100644 miniprogram/app.json create mode 100644 miniprogram/app.wxss create mode 100644 miniprogram/components/chenghao-tag/chenghao-tag.js create mode 100644 miniprogram/components/chenghao-tag/chenghao-tag.json create mode 100644 miniprogram/components/chenghao-tag/chenghao-tag.wxml create mode 100644 miniprogram/components/chenghao-tag/chenghao-tag.wxss create mode 100644 miniprogram/components/global-notification/global-notification.js create mode 100644 miniprogram/components/global-notification/global-notification.json create mode 100644 miniprogram/components/global-notification/global-notification.wxml create mode 100644 miniprogram/components/global-notification/global-notification.wxss create mode 100644 miniprogram/components/navigation-bar/navigation-bar.js create mode 100644 miniprogram/components/navigation-bar/navigation-bar.json create mode 100644 miniprogram/components/navigation-bar/navigation-bar.wxml create mode 100644 miniprogram/components/navigation-bar/navigation-bar.wxss create mode 100644 miniprogram/components/order-card/order-card.js create mode 100644 miniprogram/components/order-card/order-card.json create mode 100644 miniprogram/components/order-card/order-card.wxml create mode 100644 miniprogram/components/order-card/order-card.wxss create mode 100644 miniprogram/components/order-sender/order-sender.js create mode 100644 miniprogram/components/order-sender/order-sender.json create mode 100644 miniprogram/components/order-sender/order-sender.wxml create mode 100644 miniprogram/components/order-sender/order-sender.wxss create mode 100644 miniprogram/components/popup-notice/popup-notice.js create mode 100644 miniprogram/components/popup-notice/popup-notice.json create mode 100644 miniprogram/components/popup-notice/popup-notice.wxml create mode 100644 miniprogram/components/popup-notice/popup-notice.wxss create mode 100644 miniprogram/config/roles.js create mode 100644 miniprogram/custom-tab-bar/index.js create mode 100644 miniprogram/custom-tab-bar/index.json create mode 100644 miniprogram/custom-tab-bar/index.wxml create mode 100644 miniprogram/custom-tab-bar/index.wxss create mode 100644 miniprogram/images/dingdan.png create mode 100644 miniprogram/images/fenlei.png create mode 100644 miniprogram/images/gonggao.png create mode 100644 miniprogram/images/goumai.png create mode 100644 miniprogram/images/jiedanchi.png create mode 100644 miniprogram/images/jieshao.png create mode 100644 miniprogram/images/jinpaidashou.png create mode 100644 miniprogram/images/role-switch.png create mode 100644 miniprogram/images/shuaxin.png create mode 100644 miniprogram/images/sousuo.png create mode 100644 miniprogram/images/tiaoxuan.png create mode 100644 miniprogram/images/tuichu.png create mode 100644 miniprogram/images/weixinzhifu.png create mode 100644 miniprogram/images/wode.png create mode 100644 miniprogram/images/xiaoxi.png create mode 100644 miniprogram/images/yituikuan.png create mode 100644 miniprogram/images/yiwancheng.png create mode 100644 miniprogram/images/zhuanqu.png create mode 100644 miniprogram/images/zhuye.png create mode 100644 miniprogram/pages/cfss/cfss/cfss.js create mode 100644 miniprogram/pages/cfss/cfss/cfss.json create mode 100644 miniprogram/pages/cfss/cfss/cfss.wxml create mode 100644 miniprogram/pages/cfss/cfss/cfss.wxss create mode 100644 miniprogram/pages/cfss/components/fakuan-list/fakuan-list.js create mode 100644 miniprogram/pages/cfss/components/fakuan-list/fakuan-list.json create mode 100644 miniprogram/pages/cfss/components/fakuan-list/fakuan-list.wxml create mode 100644 miniprogram/pages/cfss/components/fakuan-list/fakuan-list.wxss create mode 100644 miniprogram/pages/cfss/components/fakuan-pay/fakuan-pay.js create mode 100644 miniprogram/pages/cfss/components/fakuan-pay/fakuan-pay.json create mode 100644 miniprogram/pages/cfss/components/fakuan-pay/fakuan-pay.wxml create mode 100644 miniprogram/pages/cfss/components/fakuan-pay/fakuan-pay.wxss create mode 100644 miniprogram/pages/cfss/components/jifen-list/jifen-list.js create mode 100644 miniprogram/pages/cfss/components/jifen-list/jifen-list.json create mode 100644 miniprogram/pages/cfss/components/jifen-list/jifen-list.wxml create mode 100644 miniprogram/pages/cfss/components/jifen-list/jifen-list.wxss create mode 100644 miniprogram/pages/czjilu/czjilu.js create mode 100644 miniprogram/pages/czjilu/czjilu.json create mode 100644 miniprogram/pages/czjilu/czjilu.wxml create mode 100644 miniprogram/pages/czjilu/czjilu.wxss create mode 100644 miniprogram/pages/dashouchongzhi/dashouchongzhi.js create mode 100644 miniprogram/pages/dashouchongzhi/dashouchongzhi.json create mode 100644 miniprogram/pages/dashouchongzhi/dashouchongzhi.wxml create mode 100644 miniprogram/pages/dashouchongzhi/dashouchongzhi.wxss create mode 100644 miniprogram/pages/dashoudingdan/dashoudingdan.js create mode 100644 miniprogram/pages/dashoudingdan/dashoudingdan.json create mode 100644 miniprogram/pages/dashoudingdan/dashoudingdan.wxml create mode 100644 miniprogram/pages/dashoudingdan/dashoudingdan.wxss create mode 100644 miniprogram/pages/dashouduan/dashouduan.js create mode 100644 miniprogram/pages/dashouduan/dashouduan.json create mode 100644 miniprogram/pages/dashouduan/dashouduan.wxml create mode 100644 miniprogram/pages/dashouduan/dashouduan.wxss create mode 100644 miniprogram/pages/dashouguize/dashouguize.js create mode 100644 miniprogram/pages/dashouguize/dashouguize.json create mode 100644 miniprogram/pages/dashouguize/dashouguize.wxml create mode 100644 miniprogram/pages/dashouguize/dashouguize.wxss create mode 100644 miniprogram/pages/dashouxiaoxi/dashouxiaoxi.js create mode 100644 miniprogram/pages/dashouxiaoxi/dashouxiaoxi.json create mode 100644 miniprogram/pages/dashouxiaoxi/dashouxiaoxi.wxml create mode 100644 miniprogram/pages/dashouxiaoxi/dashouxiaoxi.wxss create mode 100644 miniprogram/pages/dashouxiugai/dashouxiugai.js create mode 100644 miniprogram/pages/dashouxiugai/dashouxiugai.json create mode 100644 miniprogram/pages/dashouxiugai/dashouxiugai.wxml create mode 100644 miniprogram/pages/dashouxiugai/dashouxiugai.wxss create mode 100644 miniprogram/pages/dingdan/dingdan.js create mode 100644 miniprogram/pages/dingdan/dingdan.json create mode 100644 miniprogram/pages/dingdan/dingdan.wxml create mode 100644 miniprogram/pages/dingdan/dingdan.wxss create mode 100644 miniprogram/pages/dingdanxiangqing/dingdanxiangqing.js create mode 100644 miniprogram/pages/dingdanxiangqing/dingdanxiangqing.json create mode 100644 miniprogram/pages/dingdanxiangqing/dingdanxiangqing.wxml create mode 100644 miniprogram/pages/dingdanxiangqing/dingdanxiangqing.wxss create mode 100644 miniprogram/pages/dsddxq/dsddxq.js create mode 100644 miniprogram/pages/dsddxq/dsddxq.json create mode 100644 miniprogram/pages/dsddxq/dsddxq.wxml create mode 100644 miniprogram/pages/dsddxq/dsddxq.wxss create mode 100644 miniprogram/pages/fenlei/fenlei.js create mode 100644 miniprogram/pages/fenlei/fenlei.json create mode 100644 miniprogram/pages/fenlei/fenlei.wxml create mode 100644 miniprogram/pages/fenlei/fenlei.wxss create mode 100644 miniprogram/pages/guanshiduan/guanshiduan.js create mode 100644 miniprogram/pages/guanshiduan/guanshiduan.json create mode 100644 miniprogram/pages/guanshiduan/guanshiduan.wxml create mode 100644 miniprogram/pages/guanshiduan/guanshiduan.wxss create mode 100644 miniprogram/pages/guanshipaihang/guanshipaihang.json create mode 100644 miniprogram/pages/guanshipaihang/guanshipaihang.wxml create mode 100644 miniprogram/pages/guanshipaihang/guanshipaihang.wxss create mode 100644 miniprogram/pages/guanzhual/guanzhual.js create mode 100644 miniprogram/pages/guanzhual/guanzhual.json create mode 100644 miniprogram/pages/guanzhual/guanzhual.wxml create mode 100644 miniprogram/pages/guanzhual/guanzhual.wxss create mode 100644 miniprogram/pages/haibao/haibao.js create mode 100644 miniprogram/pages/haibao/haibao.json create mode 100644 miniprogram/pages/haibao/haibao.wxml create mode 100644 miniprogram/pages/haibao/haibao.wxss create mode 100644 miniprogram/pages/index/index.js create mode 100644 miniprogram/pages/index/index.json create mode 100644 miniprogram/pages/index/index.wxml create mode 100644 miniprogram/pages/index/index.wxss create mode 100644 miniprogram/pages/jiedan/jiedan.js create mode 100644 miniprogram/pages/jiedan/jiedan.json create mode 100644 miniprogram/pages/jiedan/jiedan.wxml create mode 100644 miniprogram/pages/jiedan/jiedan.wxss create mode 100644 miniprogram/pages/jiedanchi/jiedanchi.js create mode 100644 miniprogram/pages/jiedanchi/jiedanchi.json create mode 100644 miniprogram/pages/jiedanchi/jiedanchi.wxml create mode 100644 miniprogram/pages/jiedanchi/jiedanchi.wxss create mode 100644 miniprogram/pages/jiedanchi2/jiedanchi2.js create mode 100644 miniprogram/pages/jiedanchi2/jiedanchi2.json create mode 100644 miniprogram/pages/jiedanchi2/jiedanchi2.wxml create mode 100644 miniprogram/pages/jiedanchi2/jiedanchi2.wxss create mode 100644 miniprogram/pages/jinpaids/jinpaids.js create mode 100644 miniprogram/pages/jinpaids/jinpaids.json create mode 100644 miniprogram/pages/jinpaids/jinpaids.wxml create mode 100644 miniprogram/pages/jinpaids/jinpaids.wxss create mode 100644 miniprogram/pages/jisufd/jisufd.js create mode 100644 miniprogram/pages/jisufd/jisufd.json create mode 100644 miniprogram/pages/jisufd/jisufd.wxml create mode 100644 miniprogram/pages/jisufd/jisufd.wxss create mode 100644 miniprogram/pages/kaohe_dafen/kaohe_dafen.js create mode 100644 miniprogram/pages/kaohe_dafen/kaohe_dafen.json create mode 100644 miniprogram/pages/kaohe_dafen/kaohe_dafen.wxml create mode 100644 miniprogram/pages/kaohe_dafen/kaohe_dafen.wxss create mode 100644 miniprogram/pages/kaohe_jilu/kaohe_jilu.js create mode 100644 miniprogram/pages/kaohe_jilu/kaohe_jilu.json create mode 100644 miniprogram/pages/kaohe_jilu/kaohe_jilu.wxml create mode 100644 miniprogram/pages/kaohe_jilu/kaohe_jilu.wxss create mode 100644 miniprogram/pages/kaohe_jinpai/kaohe_jinpai.js create mode 100644 miniprogram/pages/kaohe_jinpai/kaohe_jinpai.json create mode 100644 miniprogram/pages/kaohe_jinpai/kaohe_jinpai.wxml create mode 100644 miniprogram/pages/kaohe_jinpai/kaohe_jinpai.wxss create mode 100644 miniprogram/pages/kaohe_zhongxin/kaohe_zhongxin.js create mode 100644 miniprogram/pages/kaohe_zhongxin/kaohe_zhongxin.json create mode 100644 miniprogram/pages/kaohe_zhongxin/kaohe_zhongxin.wxml create mode 100644 miniprogram/pages/kaohe_zhongxin/kaohe_zhongxin.wxss create mode 100644 miniprogram/pages/kaoheguan/kaoheguan.js create mode 100644 miniprogram/pages/kaoheguan/kaoheguan.json create mode 100644 miniprogram/pages/kaoheguan/kaoheguan.wxml create mode 100644 miniprogram/pages/kaoheguan/kaoheguan.wxss create mode 100644 miniprogram/pages/kefuliaotian/kefuliaotian.js create mode 100644 miniprogram/pages/kefuliaotian/kefuliaotian.json create mode 100644 miniprogram/pages/kefuliaotian/kefuliaotian.wxml create mode 100644 miniprogram/pages/kefuliaotian/kefuliaotian.wxss create mode 100644 miniprogram/pages/liaotian/liaotian.js create mode 100644 miniprogram/pages/liaotian/liaotian.json create mode 100644 miniprogram/pages/liaotian/liaotian.wxml create mode 100644 miniprogram/pages/liaotian/liaotian.wxss create mode 100644 miniprogram/pages/phone-auth/phone-auth.js create mode 100644 miniprogram/pages/phone-auth/phone-auth.json create mode 100644 miniprogram/pages/phone-auth/phone-auth.wxml create mode 100644 miniprogram/pages/phone-auth/phone-auth.wxss create mode 100644 miniprogram/pages/qunliaotian/qunliaotian.json create mode 100644 miniprogram/pages/qunliaotian/qunliaotian.wxml create mode 100644 miniprogram/pages/qunliaotian/qunliaotian.wxss create mode 100644 miniprogram/pages/renzheng/renzheng.js create mode 100644 miniprogram/pages/renzheng/renzheng.json create mode 100644 miniprogram/pages/renzheng/renzheng.wxml create mode 100644 miniprogram/pages/renzheng/renzheng.wxss create mode 100644 miniprogram/pages/shangjiaduan/shangjiaduan.json create mode 100644 miniprogram/pages/shangjiaduan/shangjiaduan.wxml create mode 100644 miniprogram/pages/shangjiaduan/shangjiaduan.wxss create mode 100644 miniprogram/pages/shangpinxiangqing/shangpinxiangqing.js create mode 100644 miniprogram/pages/shangpinxiangqing/shangpinxiangqing.json create mode 100644 miniprogram/pages/shangpinxiangqing/shangpinxiangqing.wxml create mode 100644 miniprogram/pages/shangpinxiangqing/shangpinxiangqing.wxss create mode 100644 miniprogram/pages/sjchongzhi/sjchongzhi.js create mode 100644 miniprogram/pages/sjchongzhi/sjchongzhi.json create mode 100644 miniprogram/pages/sjchongzhi/sjchongzhi.wxml create mode 100644 miniprogram/pages/sjchongzhi/sjchongzhi.wxss create mode 100644 miniprogram/pages/sjddxq/sjddxq.js create mode 100644 miniprogram/pages/sjddxq/sjddxq.json create mode 100644 miniprogram/pages/sjddxq/sjddxq.wxml create mode 100644 miniprogram/pages/sjddxq/sjddxq.wxss create mode 100644 miniprogram/pages/sjdingdan/sjdingdan.js create mode 100644 miniprogram/pages/sjdingdan/sjdingdan.json create mode 100644 miniprogram/pages/sjdingdan/sjdingdan.wxml create mode 100644 miniprogram/pages/sjdingdan/sjdingdan.wxss create mode 100644 miniprogram/pages/sjpaidan/sjpaidan.js create mode 100644 miniprogram/pages/sjpaidan/sjpaidan.json create mode 100644 miniprogram/pages/sjpaidan/sjpaidan.wxml create mode 100644 miniprogram/pages/sjpaidan/sjpaidan.wxss create mode 100644 miniprogram/pages/sjpaihang/sjpaihang.json create mode 100644 miniprogram/pages/sjpaihang/sjpaihang.wxml create mode 100644 miniprogram/pages/sjpaihang/sjpaihang.wxss create mode 100644 miniprogram/pages/sjxiaoxi/sjxiaoxi.js create mode 100644 miniprogram/pages/sjxiaoxi/sjxiaoxi.json create mode 100644 miniprogram/pages/sjxiaoxi/sjxiaoxi.wxml create mode 100644 miniprogram/pages/sjxiaoxi/sjxiaoxi.wxss create mode 100644 miniprogram/pages/tijiao/tijiao.js create mode 100644 miniprogram/pages/tijiao/tijiao.json create mode 100644 miniprogram/pages/tijiao/tijiao.wxml create mode 100644 miniprogram/pages/tijiao/tijiao.wxss create mode 100644 miniprogram/pages/tixian/components/mode1/mode1.js create mode 100644 miniprogram/pages/tixian/components/mode1/mode1.json create mode 100644 miniprogram/pages/tixian/components/mode1/mode1.wxml create mode 100644 miniprogram/pages/tixian/components/mode1/mode1.wxss create mode 100644 miniprogram/pages/tixian/components/mode2/mode2.js create mode 100644 miniprogram/pages/tixian/components/mode2/mode2.json create mode 100644 miniprogram/pages/tixian/components/mode2/mode2.wxml create mode 100644 miniprogram/pages/tixian/components/mode2/mode2.wxss create mode 100644 miniprogram/pages/tixian/tixian.js create mode 100644 miniprogram/pages/tixian/tixian.json create mode 100644 miniprogram/pages/tixian/tixian.wxml create mode 100644 miniprogram/pages/tixian/tixian.wxss create mode 100644 miniprogram/pages/wode/wode.js create mode 100644 miniprogram/pages/wode/wode.json create mode 100644 miniprogram/pages/wode/wode.wxml create mode 100644 miniprogram/pages/wode/wode.wxss create mode 100644 miniprogram/pages/wodedashou/wodedashou.js create mode 100644 miniprogram/pages/wodedashou/wodedashou.json create mode 100644 miniprogram/pages/wodedashou/wodedashou.wxml create mode 100644 miniprogram/pages/wodedashou/wodedashou.wxss create mode 100644 miniprogram/pages/xiaoxi/xiaoxi.json create mode 100644 miniprogram/pages/xiugai/xiugai.js create mode 100644 miniprogram/pages/xiugai/xiugai.json create mode 100644 miniprogram/pages/xiugai/xiugai.wxml create mode 100644 miniprogram/pages/xiugai/xiugai.wxss create mode 100644 miniprogram/pages/xuanren/xuanren.js create mode 100644 miniprogram/pages/xuanren/xuanren.json create mode 100644 miniprogram/pages/xuanren/xuanren.wxml create mode 100644 miniprogram/pages/xuanren/xuanren.wxss create mode 100644 miniprogram/pages/yaoqingdashou/yaoqingdashou.js create mode 100644 miniprogram/pages/yaoqingdashou/yaoqingdashou.json create mode 100644 miniprogram/pages/yaoqingdashou/yaoqingdashou.wxml create mode 100644 miniprogram/pages/yaoqingdashou/yaoqingdashou.wxss create mode 100644 miniprogram/pages/yqguanshi/yqguanshi.js create mode 100644 miniprogram/pages/yqguanshi/yqguanshi.json create mode 100644 miniprogram/pages/yqguanshi/yqguanshi.wxml create mode 100644 miniprogram/pages/yqguanshi/yqguanshi.wxss create mode 100644 miniprogram/pages/zuzhangduan/zuzhangduan.js create mode 100644 miniprogram/pages/zuzhangduan/zuzhangduan.json create mode 100644 miniprogram/pages/zuzhangduan/zuzhangduan.wxml create mode 100644 miniprogram/pages/zuzhangduan/zuzhangduan.wxss create mode 100644 miniprogram/pages/zzfhjilu/zzfhjilu.js create mode 100644 miniprogram/pages/zzfhjilu/zzfhjilu.json create mode 100644 miniprogram/pages/zzfhjilu/zzfhjilu.wxml create mode 100644 miniprogram/pages/zzfhjilu/zzfhjilu.wxss create mode 100644 miniprogram/services/popupService.js create mode 100644 miniprogram/sitemap.json create mode 100644 miniprogram/static/lib/EmojiDecoder.js create mode 100644 miniprogram/static/lib/goeasy-2.13.24.esm.min.js create mode 100644 miniprogram/static/lib/restapi.js create mode 100644 miniprogram/static/lib/utils.js create mode 100644 miniprogram/utils/cos-wx-sdk-v5.js create mode 100644 miniprogram/utils/imAuth/dashoujianquan.js create mode 100644 miniprogram/utils/imAuth/imRequest.js create mode 100644 miniprogram/utils/imAuth/jianquanxian.js create mode 100644 miniprogram/utils/imAuth/laobanjianquan.js create mode 100644 miniprogram/utils/imageUrl.js create mode 100644 miniprogram/utils/page-assets.js create mode 100644 miniprogram/utils/phone-auth.js create mode 100644 miniprogram/utils/request.js create mode 100644 miniprogram/utils/role-manager.js create mode 100644 miniprogram/utils/scriptService.js create mode 100644 miniprogram/utils/upload.js diff --git a/miniprogram/app.js b/miniprogram/app.js index cd75c7c..63d2a6c 100644 --- a/miniprogram/app.js +++ b/miniprogram/app.js @@ -310,6 +310,7 @@ App({ enterpriseId: config.kefu.enterpriseId || '' }; } + this.emitEvent('configReady', config); }, initGoEasyWithConfig() { diff --git a/miniprogram/app.json b/miniprogram/app.json new file mode 100644 index 0000000..927550b --- /dev/null +++ b/miniprogram/app.json @@ -0,0 +1,107 @@ +{ + "pages": [ + "pages/index/index", + "pages/fenlei/fenlei", + "pages/xuanren/xuanren", + "pages/xiaoxi/xiaoxi", + "pages/wode/wode", + "pages/shangpinxiangqing/shangpinxiangqing", + "pages/tijiao/tijiao", + "pages/xiugai/xiugai", + "pages/dashouduan/dashouduan", + "pages/shangjiaduan/shangjiaduan", + "pages/guanshiduan/guanshiduan", + "pages/dingdan/dingdan", + "pages/dingdanxiangqing/dingdanxiangqing", + "pages/dashouguize/dashouguize", + "pages/dashouxiugai/dashouxiugai", + "pages/dashoupaihang/dashoupaihang", + "pages/dashouchongzhi/dashouchongzhi", + "pages/dashouxiaoxi/dashouxiaoxi", + "pages/dashoudingdan/dashoudingdan", + "pages/jiedan/jiedan", + "pages/tixian/tixian", + "pages/yaoqingdashou/yaoqingdashou", + "pages/wodedashou/wodedashou", + "pages/czjilu/czjilu", + "pages/guanshipaihang/guanshipaihang", + "pages/sjpaidan/sjpaidan", + "pages/sjdingdan/sjdingdan", + "pages/sjxiaoxi/sjxiaoxi", + "pages/sjpaihang/sjpaihang", + "pages/sjchongzhi/sjchongzhi", + "pages/sjddxq/sjddxq", + "pages/dsddxq/dsddxq", + "pages/liaotian/liaotian", + "pages/jisufd/jisufd", + "pages/jiedanchi/jiedanchi", + "pages/haibao/haibao", + "pages/jinpaids/jinpaids", + "pages/zuzhangduan/zuzhangduan", + "pages/guanzhual/guanzhual", + "pages/zzfhjilu/zzfhjilu", + "pages/yqguanshi/yqguanshi", + "components/global-notification/global-notification", + "components/popup-notice/popup-notice", + "pages/tixian/components/mode1/mode1", + "pages/tixian/components/mode2/mode2", + + "pages/jiedanchi2/jiedanchi2", + "pages/qunliaotian/qunliaotian", + "pages/kefuliaotian/kefuliaotian", + "pages/renzheng/renzheng", + + "components/order-card/order-card", + "components/order-sender/order-sender", + "pages/cfss/cfss/cfss", + "pages/cfss/components/fakuan-list/fakuan-list", + "pages/cfss/components/jifen-list/jifen-list", + "pages/cfss/components/fakuan-pay/fakuan-pay", + "pages/phone-auth/phone-auth", + "components/chenghao-tag/chenghao-tag", + "pages/kaoheguan/kaoheguan", + "pages/kaohe_dafen/kaohe_dafen", + "pages/kaohe_jilu/kaohe_jilu", + "pages/kaohe_zhongxin/kaohe_zhongxin", + "pages/kaohe_jinpai/kaohe_jinpai" + + ], + + "usingComponents": { + "popup-notice": "/components/popup-notice/popup-notice", + "custom-tab-bar": "/custom-tab-bar/index" + }, + + "window": { + "navigationBarTextStyle": "black", + "navigationStyle": "default", + "backgroundTextStyle": "light", + "navigationBarBackgroundColor": "#fff", + "navigationBarTitleText": "二H电竞" + }, + "tabBar": { + "custom": true, + "list": [ + + + { + "pagePath": "pages/jiedanchi/jiedanchi", + "text": "接单池", + "iconPath": "/images/jiedanchi.png", + "selectedIconPath": "/images/jiedanchi.png" + }, + { + "pagePath": "pages/jiedanchi2/jiedanchi2", + "text": "接单池", + "iconPath": "/images/jiedanchi.png", + "selectedIconPath": "/images/jiedanchi.png" + } + + ] + }, + + + "style": "v2", + "sitemapLocation": "sitemap.json", + "lazyCodeLoading": "requiredComponents" +} \ No newline at end of file diff --git a/miniprogram/app.wxss b/miniprogram/app.wxss new file mode 100644 index 0000000..06c6fc9 --- /dev/null +++ b/miniprogram/app.wxss @@ -0,0 +1,10 @@ +/**app.wxss**/ +.container { + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + padding: 200rpx 0; + box-sizing: border-box; +} diff --git a/miniprogram/components/chenghao-tag/chenghao-tag.js b/miniprogram/components/chenghao-tag/chenghao-tag.js new file mode 100644 index 0000000..ae79133 --- /dev/null +++ b/miniprogram/components/chenghao-tag/chenghao-tag.js @@ -0,0 +1,73 @@ +// components/chenghao-tag/chenghao-tag.js +const app = getApp(); + +Component({ + properties: { + mingcheng: { type: String, value: '' }, + texiaoJson: { type: Object, value: {} } + }, + data: { + // 默认值:宽152,高52,六边形,无背景图,无动画,白色字 + width: 152, + height: 52, + shapeClass: 'liubianxing', // 保证至少不是矩形 + animationClass: '', + bgStyle: '', + textColor: '#FFFFFF', + textSize: 22, + imageUrl: '' + }, + lifetimes: { + attached() { + const cfg = this.properties.texiaoJson || {}; + + // 1. 尺寸(稍大一些,一行能放3~4个) + const width = cfg.width || 152; + const height = cfg.height || 52; + + // 2. 背景处理:优先背景图,否则用渐变/纯色 + let bgStyle = ''; + let imageUrl = ''; + if (cfg.image_url) { + const ossImageUrl = app.globalData.ossImageUrl || ''; + imageUrl = cfg.image_url.startsWith('http') + ? cfg.image_url + : ossImageUrl + cfg.image_url; + } else if (cfg.bg_gradient) { + bgStyle = `background: ${cfg.bg_gradient};`; + } else if (cfg.bg_color) { + bgStyle = `background: ${cfg.bg_color};`; + } else { + // 默认金橙渐变 + bgStyle = `background: linear-gradient(135deg, #FFD700, #FF8C00);`; + } + + // 3. 形状(后端传入 shape 字段,默认 liubianxing) + const shapeClass = cfg.shape || 'liubianxing'; + + // 4. 动画 + const animationClass = cfg.animation || ''; + + // 5. 文字 + const textColor = cfg.text_color || '#FFFFFF'; + const textSize = cfg.text_size || 22; + + this.setData({ + width, height, + bgStyle, imageUrl, + shapeClass, animationClass, + textColor, textSize + }); + } + }, + methods: { + // 背景图加载失败时回退为纯色背景 + onImageError() { + this.setData({ imageUrl: '' }); + // 如果 bgStyle 为空,给个默认背景 + if (!this.data.bgStyle) { + this.setData({ bgStyle: 'background: linear-gradient(135deg, #FFD700, #FF8C00);' }); + } + } + } +}); \ No newline at end of file diff --git a/miniprogram/components/chenghao-tag/chenghao-tag.json b/miniprogram/components/chenghao-tag/chenghao-tag.json new file mode 100644 index 0000000..62389a9 --- /dev/null +++ b/miniprogram/components/chenghao-tag/chenghao-tag.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} + } \ No newline at end of file diff --git a/miniprogram/components/chenghao-tag/chenghao-tag.wxml b/miniprogram/components/chenghao-tag/chenghao-tag.wxml new file mode 100644 index 0000000..e9c44f3 --- /dev/null +++ b/miniprogram/components/chenghao-tag/chenghao-tag.wxml @@ -0,0 +1,20 @@ + + + + + + + {{mingcheng}} + \ No newline at end of file diff --git a/miniprogram/components/chenghao-tag/chenghao-tag.wxss b/miniprogram/components/chenghao-tag/chenghao-tag.wxss new file mode 100644 index 0000000..d142188 --- /dev/null +++ b/miniprogram/components/chenghao-tag/chenghao-tag.wxss @@ -0,0 +1,90 @@ +/* components/chenghao-tag/chenghao-tag.wxss */ + +/* ========== 根容器 ========== */ +.tag-root { + display: inline-flex; + align-items: center; + justify-content: center; + position: relative; + border-radius: 4rpx; + overflow: hidden; + flex-shrink: 0; + margin: 4rpx; + box-sizing: border-box; + } + + /* ========== 背景图 ========== */ + .tag-bg-image { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 0; + border-radius: inherit; + } + + /* ========== 文字层 ========== */ + .tag-text { + position: relative; + z-index: 2; + font-weight: bold; + white-space: nowrap; + text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.5); + padding: 0 10rpx; + } + + /* ========== 多边形形状 ========== */ + .tag-root.liubianxing { + clip-path: polygon(12% 0%, 88% 0%, 100% 50%, 88% 100%, 12% 100%, 0% 50%); + } + .tag-root.lingxing { + clip-path: polygon(50% 0%, 85% 12%, 100% 50%, 85% 88%, 50% 100%, 15% 88%, 0% 50%, 15% 12%); + } + .tag-root.wujiaoxing { + clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); + } + .tag-root.dunpai { + clip-path: polygon(18% 0%, 82% 0%, 100% 18%, 95% 50%, 100% 82%, 82% 100%, 18% 100%, 0% 82%, 5% 50%, 0% 18%); + } + .tag-root.jiantou { + clip-path: polygon(0% 0%, 85% 0%, 100% 50%, 85% 100%, 0% 100%, 12% 50%); + } + + /* ========== 动画 ========== */ + /* 流光扫描 */ + .tag-root.shine::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 60%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.5), transparent); + transform: skewX(-20deg); + animation: shine-anim 2s infinite; + z-index: 1; + pointer-events: none; + } + @keyframes shine-anim { + 0% { left: -100%; } + 100% { left: 200%; } + } + + /* 呼吸光晕 */ + .tag-root.pulse { + animation: pulse-anim 1.5s ease-in-out infinite; + } + @keyframes pulse-anim { + 0%, 100% { filter: brightness(1); transform: scale(1); } + 50% { filter: brightness(1.2); transform: scale(1.04); } + } + + /* 外发光闪烁 */ + .tag-root.glow { + animation: glow-anim 2s ease-in-out infinite; + } + @keyframes glow-anim { + 0%, 100% { box-shadow: 0 0 8rpx rgba(255, 215, 0, 0.4); } + 50% { box-shadow: 0 0 20rpx rgba(255, 215, 0, 0.8), 0 0 40rpx rgba(255, 215, 0, 0.4); } + } \ No newline at end of file diff --git a/miniprogram/components/global-notification/global-notification.js b/miniprogram/components/global-notification/global-notification.js new file mode 100644 index 0000000..bd88ab6 --- /dev/null +++ b/miniprogram/components/global-notification/global-notification.js @@ -0,0 +1,366 @@ +Component({ + properties: { + position: { + type: String, + value: 'top' + }, + duration: { + type: Number, + value: 3000 + }, + showProgress: { + type: Boolean, + value: true + }, + showMuteButton: { + type: Boolean, + value: true + }, + showTime: { + type: Boolean, + value: true + }, + swipeToClose: { + type: Boolean, + value: true + }, + swipeThreshold: { + type: Number, + value: 50 + } + }, + + data: { + show: false, + title: '', + message: '', + avatar: '', + notificationData: null, + progress: 100, + progressInterval: null, + positionClass: 'top', + + // 滑动相关 + touchStartY: 0, + touchStartX: 0, + currentY: 0, + currentX: 0, + isSwiping: false, + swipingClass: '', + swipeStyle: '', + swipeDistance: 0, + + // 静音状态 + isMuted: false, + + // 自动隐藏计时器 + autoHideTimeout: null + }, + + lifetimes: { + attached() { + this.loadMuteSetting(); + this.setData({ + positionClass: this.properties.position + }); + this.setupDirectEventListeners(); + }, + + detached() { + this.clearTimers(); + } + }, + + methods: { + setupDirectEventListeners() { + const app = getApp(); + if (app) { + const self = this; + const globalNotification = { + show: (data) => { + if (self && self.showNotification) { + self.showNotification(data); + } + }, + hide: () => { + if (self && self.hideNotification) { + self.hideNotification(); + } + }, + isMuted: () => { + return self.data.isMuted; + } + }; + app.globalData.globalNotification = globalNotification; + } + }, + + loadMuteSetting() { + try { + const isMuted = wx.getStorageSync('notificationMuted') || false; + this.setData({ isMuted }); + } catch (error) { + console.warn('加载静音设置失败:', error); + } + }, + + saveMuteSetting(isMuted) { + try { + wx.setStorageSync('notificationMuted', isMuted); + } catch (error) { + console.warn('保存静音设置失败:', error); + } + }, + + showNotification(data) { + if (!data) return; + if (this.data.isMuted) return; + + this.clearTimers(); + + const app = getApp(); + let avatar = data.avatar; + if (!avatar && app && app.globalData) { + avatar = app.globalData.ossImageUrl + app.globalData.morentouxiang; + } + + this.setData({ + show: true, + title: data.senderName || '新消息', + message: data.content || '[消息内容]', + avatar: avatar, + notificationData: data, + progress: 100, + swipingClass: '', + swipeStyle: '' + }); + + if (this.properties.showProgress) { + this.startProgressBar(this.properties.duration); + } + + this.data.autoHideTimeout = setTimeout(() => { + this.hideNotification(); + }, this.properties.duration); + }, + + hideNotification() { + this.clearTimers(); + this.setData({ + show: false, + progress: 100, + swipingClass: '', + swipeStyle: '' + }); + this.triggerEvent('hide'); + }, + + startProgressBar(duration) { + const interval = 100; + const steps = duration / interval; + const stepValue = 100 / steps; + + let currentProgress = 100; + this.data.progressInterval = setInterval(() => { + currentProgress -= stepValue; + if (currentProgress <= 0) { + currentProgress = 0; + this.setData({ progress: currentProgress }); + clearInterval(this.data.progressInterval); + } else { + this.setData({ progress: currentProgress }); + } + }, interval); + }, + + clearTimers() { + if (this.data.autoHideTimeout) { + clearTimeout(this.data.autoHideTimeout); + this.data.autoHideTimeout = null; + } + if (this.data.progressInterval) { + clearInterval(this.data.progressInterval); + this.data.progressInterval = null; + } + }, + + onTouchStart(e) { + if (!this.properties.swipeToClose) return; + const touch = e.touches[0]; + this.setData({ + touchStartY: touch.clientY, + touchStartX: touch.clientX, + currentY: touch.clientY, + currentX: touch.clientX, + isSwiping: false + }); + this.clearTimers(); + }, + + onTouchMove(e) { + if (!this.properties.swipeToClose) return; + const touch = e.touches[0]; + const deltaY = touch.clientY - this.data.touchStartY; + const deltaX = touch.clientX - this.data.touchStartX; + const absDeltaY = Math.abs(deltaY); + const absDeltaX = Math.abs(deltaX); + + if (absDeltaY > 10 && absDeltaY > absDeltaX) { + this.setData({ + isSwiping: true, + currentY: touch.clientY, + swipingClass: deltaY < 0 ? 'swiping-up' : 'swiping', + swipeDistance: Math.abs(deltaY), + swipeStyle: `--swipe-distance: ${Math.abs(deltaY)}rpx;` + }); + e.stopPropagation(); + } + }, + + onTouchEnd(e) { + if (!this.properties.swipeToClose || !this.data.isSwiping) { + this.restartAutoHide(); + return; + } + const deltaY = this.data.currentY - this.data.touchStartY; + const absDeltaY = Math.abs(deltaY); + if (absDeltaY > this.properties.swipeThreshold) { + this.hideNotification(); + } else { + this.setData({ + swipingClass: '', + swipeStyle: 'transition: transform 0.3s ease; transform: translateY(0);' + }); + setTimeout(() => { + this.setData({ + swipingClass: '', + swipeStyle: '' + }); + }, 300); + this.restartAutoHide(); + } + this.setData({ isSwiping: false }); + }, + + restartAutoHide() { + const remainingTime = (this.data.progress / 100) * this.properties.duration; + if (remainingTime > 0) { + this.data.autoHideTimeout = setTimeout(() => { + this.hideNotification(); + }, remainingTime); + } + }, + + onTap() { + const { notificationData } = this.data; + if (!notificationData) return; + this.triggerEvent('tap', notificationData); + this.hideNotification(); + this.navigateToChatPage(notificationData); + }, + + onClose(e) { + e.stopPropagation(); + this.triggerEvent('close'); + this.hideNotification(); + }, + + onMute(e) { + e.stopPropagation(); + const newMutedState = !this.data.isMuted; + this.setData({ isMuted: newMutedState }); + this.saveMuteSetting(newMutedState); + + const app = getApp(); + if (app && app.toggleDoNotDisturb) { + app.toggleDoNotDisturb(newMutedState); + } + this.triggerEvent('mute', { muted: newMutedState }); + wx.showToast({ + title: newMutedState ? '已开启免打扰' : '已关闭免打扰', + icon: 'success', + duration: 1500 + }); + + if (newMutedState) { + this.hideNotification(); + } + }, + + formatTime(timestamp) { + if (!timestamp) return ''; + const date = new Date(timestamp); + const now = new Date(); + const diff = now - date; + if (diff < 60 * 1000) return '刚刚'; + if (diff < 60 * 60 * 1000) return Math.floor(diff / (60 * 1000)) + '分钟前'; + if (date.toDateString() === now.toDateString()) { + return date.getHours().toString().padStart(2, '0') + ':' + date.getMinutes().toString().padStart(2, '0'); + } + const yesterday = new Date(now); + yesterday.setDate(yesterday.getDate() - 1); + if (date.toDateString() === yesterday.toDateString()) { + return '昨天 ' + date.getHours().toString().padStart(2, '0') + ':' + date.getMinutes().toString().padStart(2, '0'); + } + return (date.getMonth() + 1) + '月' + date.getDate() + '日'; + }, + + navigateToChatPage(data) { + if (!data || !data.message) { + console.warn('通知数据无效,无法跳转'); + return; + } + + const msg = data.message; + let path = ''; + let queryParam = null; + + // 根据 notificationType 或消息字段判断 + if (data.notificationType === 'cs' || msg.teamId) { + // 客服消息 + const teamId = data.teamId || msg.teamId; + path = '/pages/kefuliaotian/kefuliaotian'; + queryParam = { teamId: teamId }; + } else if (data.notificationType === 'group' || msg.groupId) { + // 群聊消息 + const groupId = data.groupId || msg.groupId; + const orderId = data.orderId || msg.orderId || ''; + const groupName = data.groupName || '订单群聊'; + const groupAvatar = data.groupAvatar || ''; + const isCross = data.isCross || msg.isCross || 0; + path = '/pages/qunliaotian/qunliaotian'; + queryParam = { + groupId, + orderId, + groupName, + groupAvatar, + isCross + }; + } else { + // 默认私聊 + const toUserId = data.senderId || msg.senderId; + const toName = data.senderName || '用户'; + const toAvatar = data.avatar || ''; + path = '/pages/liaotian/liaotian'; + queryParam = { + toUserId, + toName, + toAvatar + }; + } + + if (path && queryParam) { + const encoded = encodeURIComponent(JSON.stringify(queryParam)); + wx.navigateTo({ + url: `${path}?data=${encoded}`, + fail: (err) => { + console.error('通知跳转失败:', err); + wx.switchTab({ url: '/pages/xiaoxi/xiaoxi' }); + } + }); + } else { + wx.switchTab({ url: '/pages/xiaoxi/xiaoxi' }); + } + } + } + }); \ No newline at end of file diff --git a/miniprogram/components/global-notification/global-notification.json b/miniprogram/components/global-notification/global-notification.json new file mode 100644 index 0000000..7e37c03 --- /dev/null +++ b/miniprogram/components/global-notification/global-notification.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/miniprogram/components/global-notification/global-notification.wxml b/miniprogram/components/global-notification/global-notification.wxml new file mode 100644 index 0000000..d76b58c --- /dev/null +++ b/miniprogram/components/global-notification/global-notification.wxml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + {{title}} + {{message}} + + {{formatTime(notificationData ? notificationData.timestamp : '')}} + + + + + + + + × + + + + + + {{isMuted ? '🔕' : '🔔'}} + + + + + + + + + + \ No newline at end of file diff --git a/miniprogram/components/global-notification/global-notification.wxss b/miniprogram/components/global-notification/global-notification.wxss new file mode 100644 index 0000000..fc67be6 --- /dev/null +++ b/miniprogram/components/global-notification/global-notification.wxss @@ -0,0 +1,215 @@ +.global-notification { + position: fixed; + left: 20rpx; + right: 20rpx; + top: 0rpx; + z-index: 99999; + opacity: 0; + transform: translateY(-120%); + transition: all 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55); + pointer-events: none; + overflow: hidden; + border-radius: 24rpx; + background: linear-gradient(135deg, + rgba(41, 47, 61, 0.98) 0%, + rgba(31, 36, 48, 0.98) 100%); + backdrop-filter: blur(30rpx) saturate(180%); + -webkit-backdrop-filter: blur(30rpx) saturate(180%); + border: 1rpx solid rgba(255, 255, 255, 0.08); + box-shadow: + 0 20rpx 60rpx rgba(0, 0, 0, 0.4), + 0 0 0 1rpx rgba(255, 255, 255, 0.03), + inset 0 1rpx 0 rgba(255, 255, 255, 0.1); + min-height: 140rpx; + touch-action: pan-y; +} + +.global-notification.show { + opacity: 1; + transform: translateY(0); + pointer-events: auto; +} + +.notification-swipe-indicator { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4rpx; + display: flex; + justify-content: center; + align-items: center; + z-index: 10; +} + +.swipe-line { + width: 40rpx; + height: 4rpx; + background: rgba(255, 255, 255, 0.3); + border-radius: 2rpx; + transition: all 0.3s; +} + +.notification-swipe-indicator.active .swipe-line { + background: rgba(255, 255, 255, 0.6); + transform: scaleX(1.2); +} + +.notification-content { + display: flex; + align-items: center; + padding: 32rpx; + min-height: 140rpx; + position: relative; +} + +.notification-avatar { + width: 88rpx; + height: 88rpx; + border-radius: 44rpx; + margin-right: 24rpx; + flex-shrink: 0; + border: 3rpx solid rgba(212, 175, 55, 0.6); + box-shadow: + 0 8rpx 24rpx rgba(212, 175, 55, 0.2), + inset 0 1rpx 0 rgba(255, 255, 255, 0.3); + background-color: rgba(0, 0, 0, 0.2); +} + +.notification-body { + flex: 1; + min-width: 0; + display: flex; + flex-direction: column; + justify-content: center; +} + +.notification-title { + font-size: 34rpx; + font-weight: 600; + margin-bottom: 8rpx; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + background: linear-gradient(135deg, #D4AF37 0%, #FFD700 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3); +} + +.notification-message { + font-size: 28rpx; + line-height: 1.4; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + color: rgba(255, 255, 255, 0.95); + text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.5); +} + +.notification-time { + font-size: 24rpx; + color: rgba(255, 255, 255, 0.5); + margin-top: 4rpx; + font-weight: 300; +} + +.notification-actions { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin-left: 20rpx; + gap: 16rpx; +} + +.notification-close, +.notification-mute { + width: 56rpx; + height: 56rpx; + display: flex; + align-items: center; + justify-content: center; + border-radius: 28rpx; + background: rgba(255, 255, 255, 0.08); + border: 1rpx solid rgba(255, 255, 255, 0.1); + transition: all 0.3s; + flex-shrink: 0; + box-shadow: + 0 4rpx 12rpx rgba(0, 0, 0, 0.2), + inset 0 1rpx 0 rgba(255, 255, 255, 0.05); +} + +.notification-close:active, +.notification-mute:active { + background: rgba(255, 255, 255, 0.15); + transform: scale(0.92); +} + +.close-icon { + font-size: 32rpx; + font-weight: 300; + color: rgba(255, 255, 255, 0.9); + line-height: 1; +} + +.mute-icon { + font-size: 28rpx; + line-height: 0; + color: rgba(255, 255, 255, 0.9); +} + +.notification-mute.muted .mute-icon { + color: #D4AF37; +} + +.notification-progress { + height: 6rpx; + background: rgba(255, 255, 255, 0.05); + overflow: hidden; + border-radius: 0 0 24rpx 24rpx; +} + +.progress-bar { + height: 100%; + width: 100%; + background: linear-gradient(90deg, + #D4AF37 0%, + #FFD700 50%, + #D4AF37 100%); + background-size: 200% 100%; + transition: width 0.1s linear; + box-shadow: 0 0 20rpx rgba(212, 175, 55, 0.4); + animation: progressShine 2s linear infinite; +} + +@keyframes progressShine { + 0% { background-position: 200% 0; } + 100% { background-position: -200% 0; } +} + +.progress-bar.warning { + background: linear-gradient(90deg, + #ff3b30 0%, + #ff6b6b 50%, + #ff3b30 100%); + animation: progressShine 1s linear infinite; +} + +.global-notification.swiping { + opacity: 0.7; + transform: translateY(calc(var(--swipe-distance, 0) * -1)); +} + +.global-notification.swiping-up { + opacity: 0.3; + transform: translateY(calc(var(--swipe-distance, 0) * -1)); +} + +.global-notification:active:not(.swiping) { + transform: scale(0.995) translateY(0); + transition: transform 0.1s; +} \ No newline at end of file diff --git a/miniprogram/components/navigation-bar/navigation-bar.js b/miniprogram/components/navigation-bar/navigation-bar.js new file mode 100644 index 0000000..eb1770e --- /dev/null +++ b/miniprogram/components/navigation-bar/navigation-bar.js @@ -0,0 +1,102 @@ +Component({ + options: { + multipleSlots: true // 在组件定义时的选项中启用多slot支持 + }, + /** + * 组件的属性列表 + */ + properties: { + extClass: { + type: String, + value: '' + }, + title: { + type: String, + value: '' + }, + background: { + type: String, + value: '' + }, + color: { + type: String, + value: '' + }, + back: { + type: Boolean, + value: true + }, + loading: { + type: Boolean, + value: false + }, + homeButton: { + type: Boolean, + value: false, + }, + animated: { + // 显示隐藏的时候opacity动画效果 + type: Boolean, + value: true + }, + show: { + // 显示隐藏导航,隐藏的时候navigation-bar的高度占位还在 + type: Boolean, + value: true, + observer: '_showChange' + }, + // back为true的时候,返回的页面深度 + delta: { + type: Number, + value: 1 + }, + }, + /** + * 组件的初始数据 + */ + data: { + displayStyle: '' + }, + lifetimes: { + attached() { + const rect = wx.getMenuButtonBoundingClientRect() + const platform = (wx.getDeviceInfo() || wx.getSystemInfoSync()).platform + const isAndroid = platform === 'android' + const isDevtools = platform === 'devtools' + const { windowWidth, safeArea: { top = 0, bottom = 0 } = {} } = wx.getWindowInfo() || wx.getSystemInfoSync() + this.setData({ + ios: !isAndroid, + innerPaddingRight: `padding-right: ${windowWidth - rect.left}px`, + leftWidth: `width: ${windowWidth - rect.left}px`, + safeAreaTop: isDevtools || isAndroid ? `height: calc(var(--height) + ${top}px); padding-top: ${top}px` : `` + }) + }, + }, + /** + * 组件的方法列表 + */ + methods: { + _showChange(show) { + const animated = this.data.animated + let displayStyle = '' + if (animated) { + displayStyle = `opacity: ${show ? '1' : '0' + };transition:opacity 0.5s;` + } else { + displayStyle = `display: ${show ? '' : 'none'}` + } + this.setData({ + displayStyle + }) + }, + back() { + const data = this.data + if (data.delta) { + wx.navigateBack({ + delta: data.delta + }) + } + this.triggerEvent('back', { delta: data.delta }, {}) + } + }, +}) diff --git a/miniprogram/components/navigation-bar/navigation-bar.json b/miniprogram/components/navigation-bar/navigation-bar.json new file mode 100644 index 0000000..4a20f17 --- /dev/null +++ b/miniprogram/components/navigation-bar/navigation-bar.json @@ -0,0 +1,5 @@ +{ + "component": true, + "styleIsolation": "apply-shared", + "usingComponents": {} +} \ No newline at end of file diff --git a/miniprogram/components/navigation-bar/navigation-bar.wxml b/miniprogram/components/navigation-bar/navigation-bar.wxml new file mode 100644 index 0000000..2bfe519 --- /dev/null +++ b/miniprogram/components/navigation-bar/navigation-bar.wxml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{title}} + + + + + + + + + + + + diff --git a/miniprogram/components/navigation-bar/navigation-bar.wxss b/miniprogram/components/navigation-bar/navigation-bar.wxss new file mode 100644 index 0000000..8bd379e --- /dev/null +++ b/miniprogram/components/navigation-bar/navigation-bar.wxss @@ -0,0 +1,96 @@ +.weui-navigation-bar { + --weui-FG-0:rgba(0,0,0,.9); + --height: 44px; + --left: 16px; +} +.weui-navigation-bar .android { + --height: 48px; +} + +.weui-navigation-bar { + overflow: hidden; + color: var(--weui-FG-0); + flex: none; +} + +.weui-navigation-bar__inner { + position: relative; + top: 0; + left: 0; + height: calc(var(--height) + env(safe-area-inset-top)); + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + padding-top: env(safe-area-inset-top); + width: 100%; + box-sizing: border-box; +} + +.weui-navigation-bar__left { + position: relative; + padding-left: var(--left); + display: flex; + flex-direction: row; + align-items: flex-start; + height: 100%; + box-sizing: border-box; +} + +.weui-navigation-bar__btn_goback_wrapper { + padding: 11px 18px 11px 16px; + margin: -11px -18px -11px -16px; +} + +.weui-navigation-bar__btn_goback_wrapper.weui-active { + opacity: 0.5; +} + +.weui-navigation-bar__btn_goback { + font-size: 12px; + width: 12px; + height: 24px; + -webkit-mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%; + mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%; + -webkit-mask-size: cover; + mask-size: cover; + background-color: var(--weui-FG-0); +} + +.weui-navigation-bar__center { + font-size: 17px; + text-align: center; + position: relative; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + font-weight: bold; + flex: 1; + height: 100%; +} + +.weui-navigation-bar__loading { + margin-right: 4px; + align-items: center; +} + +.weui-loading { + font-size: 16px; + width: 16px; + height: 16px; + display: block; + background: transparent url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='80px' height='80px' viewBox='0 0 80 80' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Eloading%3C/title%3E%3Cdefs%3E%3ClinearGradient x1='94.0869141%25' y1='0%25' x2='94.0869141%25' y2='90.559082%25' id='linearGradient-1'%3E%3Cstop stop-color='%23606060' stop-opacity='0' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3ClinearGradient x1='100%25' y1='8.67370605%25' x2='100%25' y2='90.6286621%25' id='linearGradient-2'%3E%3Cstop stop-color='%23606060' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' opacity='0.9'%3E%3Cg%3E%3Cpath d='M40,0 C62.09139,0 80,17.90861 80,40 C80,62.09139 62.09139,80 40,80 L40,73 C58.2253967,73 73,58.2253967 73,40 C73,21.7746033 58.2253967,7 40,7 L40,0 Z' fill='url(%23linearGradient-1)'%3E%3C/path%3E%3Cpath d='M40,0 L40,7 C21.7746033,7 7,21.7746033 7,40 C7,58.2253967 21.7746033,73 40,73 L40,80 C17.90861,80 0,62.09139 0,40 C0,17.90861 17.90861,0 40,0 Z' fill='url(%23linearGradient-2)'%3E%3C/path%3E%3Ccircle id='Oval' fill='%23606060' cx='40.5' cy='3.5' r='3.5'%3E%3C/circle%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A") no-repeat; + background-size: 100%; + margin-left: 0; + animation: loading linear infinite 1s; +} + +@keyframes loading { + from { + transform: rotate(0); + } + to { + transform: rotate(360deg); + } +} diff --git a/miniprogram/components/order-card/order-card.js b/miniprogram/components/order-card/order-card.js new file mode 100644 index 0000000..b94bb6c --- /dev/null +++ b/miniprogram/components/order-card/order-card.js @@ -0,0 +1,102 @@ +const app = getApp(); + +Component({ + properties: { + orderId: { type: String, value: '' } + }, + + data: { + order: null, + loading: false, + errorMsg: '', + // 跨平台字段 + isCross: false, // 是否跨平台订单 + dispatchType: 0, // 1-我方派单,2-对方派单 + partnerClubId: '', // 对方俱乐部ID + }, + + lifetimes: { + attached() { + if (this.properties.orderId) { + this.fetchOrderDetail(); + } + } + }, + + methods: { + // 获取订单详情(含跨平台字段) + fetchOrderDetail() { + if (!this.properties.orderId) return; + this.setData({ loading: true, errorMsg: '' }); + const baseUrl = app.globalData.apiBaseUrl; + wx.request({ + url: `${baseUrl}/dingdan/order_detail/`, // 需后端返回 is_cross, dispatch_type, partner_club_id + method: 'POST', + data: { order_id: this.properties.orderId }, + header: { 'content-type': 'application/json' }, + success: (res) => { + if (res.statusCode === 200 && res.data && res.data.code === 0) { + const order = res.data.data; + // 处理图片URL + if (order.tupian && !order.tupian.startsWith('http')) { + order.tupian = app.globalData.ossImageUrl + order.tupian; + } + this.setData({ + order, + loading: false, + isCross: order.is_cross === 1, + dispatchType: order.dispatch_type || 0, + partnerClubId: order.partner_club_id || '', + }); + // 通知父页面状态 + this.triggerEvent('statusready', { + isCross: this.data.isCross, + dispatchType: this.data.dispatchType, + partnerClubId: this.data.partnerClubId + }); + } else { + this.setData({ errorMsg: res.data?.msg || '获取订单失败', loading: false }); + } + }, + fail: () => { + this.setData({ errorMsg: '网络请求失败', loading: false }); + } + }); + }, + + // 发送订单卡片消息(原有) + sendOrderMessage() { + if (!this.data.order) return; + this.triggerEvent('sendorder', { order: this.data.order }); + }, + + // 跨平台消息转发(供父页面调用) + forwardMessage(payload) { + const that = this; + const baseUrl = app.globalData.apiBaseUrl; + return new Promise((resolve, reject) => { + wx.request({ + url: `${baseUrl}/dingdan/kptxxts`, + method: 'POST', + data: { + order_id: that.properties.orderId, + message_type: payload.type || 'text', + content: payload.content || '', + image_url: payload.imageUrl || '', // 图片等 + }, + header: { 'content-type': 'application/json' }, + success: (res) => { + if (res.statusCode === 200 && res.data && res.data.code === 0) { + resolve(res.data); + } else { + reject(res.data); + } + }, + fail: (err) => { + reject(err); + } + }); + }); + } + } +}); \ No newline at end of file diff --git a/miniprogram/components/order-card/order-card.json b/miniprogram/components/order-card/order-card.json new file mode 100644 index 0000000..7e37c03 --- /dev/null +++ b/miniprogram/components/order-card/order-card.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/miniprogram/components/order-card/order-card.wxml b/miniprogram/components/order-card/order-card.wxml new file mode 100644 index 0000000..c87ad17 --- /dev/null +++ b/miniprogram/components/order-card/order-card.wxml @@ -0,0 +1,20 @@ + + + 关联订单 + {{order.dingdan_id}} + + 跨平台 + + + + + {{order.jieshao || '暂无介绍'}} + ¥{{order.jine}} + + 发送 + + {{errorMsg}} + + + 加载订单信息... + \ No newline at end of file diff --git a/miniprogram/components/order-card/order-card.wxss b/miniprogram/components/order-card/order-card.wxss new file mode 100644 index 0000000..62c2737 --- /dev/null +++ b/miniprogram/components/order-card/order-card.wxss @@ -0,0 +1,39 @@ +.order-card { + background: #fff; + margin: 15rpx 20rpx; + border-radius: 12rpx; + overflow: hidden; + box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.05); +} +.card-header { + display: flex; + align-items: center; + padding: 16rpx 20rpx; + border-bottom: 1rpx solid #f0f0f0; +} +.card-title { font-size: 26rpx; color: #666; } +.card-id { font-size: 24rpx; color: #999; margin-left: 15rpx; } +.cross-tag { + margin-left: auto; + background: #ff9900; + color: #fff; + font-size: 20rpx; + padding: 2rpx 12rpx; + border-radius: 8rpx; +} +.card-body { + display: flex; + align-items: center; + padding: 20rpx; +} +.card-img { width: 100rpx; height: 100rpx; border-radius: 8rpx; margin-right: 15rpx; } +.card-info { flex: 1; } +.card-jieshao { font-size: 28rpx; color: #333; } +.card-jine { font-size: 26rpx; color: #e74c3c; } +.card-send-btn { + width: 80rpx; height: 50rpx; line-height: 50rpx; + text-align: center; background: #07c160; color: #fff; + border-radius: 8rpx; font-size: 24rpx; +} +.card-error { padding: 20rpx; color: #e74c3c; text-align: center; } +.loading-text { display: block; padding: 20rpx; text-align: center; color: #999; } \ No newline at end of file diff --git a/miniprogram/components/order-sender/order-sender.js b/miniprogram/components/order-sender/order-sender.js new file mode 100644 index 0000000..f4c9444 --- /dev/null +++ b/miniprogram/components/order-sender/order-sender.js @@ -0,0 +1,16 @@ +const app = getApp(); + +Component({ + properties: { + visible: Boolean, + showDetail: { type: Boolean, value: false } + }, + + data: {}, + + methods: { + close() { + this.triggerEvent('close'); + } + } +}); \ No newline at end of file diff --git a/miniprogram/components/order-sender/order-sender.json b/miniprogram/components/order-sender/order-sender.json new file mode 100644 index 0000000..62389a9 --- /dev/null +++ b/miniprogram/components/order-sender/order-sender.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} + } \ No newline at end of file diff --git a/miniprogram/components/order-sender/order-sender.wxml b/miniprogram/components/order-sender/order-sender.wxml new file mode 100644 index 0000000..ae53ed5 --- /dev/null +++ b/miniprogram/components/order-sender/order-sender.wxml @@ -0,0 +1,12 @@ + + + + 提示 + + + + 📋 + 此功能暂未开放 + 敬请期待 + + \ No newline at end of file diff --git a/miniprogram/components/order-sender/order-sender.wxss b/miniprogram/components/order-sender/order-sender.wxss new file mode 100644 index 0000000..c0ffc48 --- /dev/null +++ b/miniprogram/components/order-sender/order-sender.wxss @@ -0,0 +1,45 @@ +.order-sender-mask { + position: fixed; top: 0; left: 0; right: 0; bottom: 0; + background: rgba(0,0,0,0.5); + z-index: 2000; + } + .order-sender { + position: fixed; bottom: 0; left: 0; right: 0; + height: 360rpx; + background: #fff; + border-radius: 24rpx 24rpx 0 0; + z-index: 2001; + transform: translateY(100%); + transition: 0.25s; + display: flex; + flex-direction: column; + } + .order-sender.show { transform: translateY(0); } + + .header { + display: flex; justify-content: space-between; + padding: 24rpx 30rpx; + border-bottom: 1rpx solid #f0f0f0; + } + .title { font-size: 32rpx; font-weight: 600; } + .close { font-size: 44rpx; color: #999; padding: 0 12rpx; } + + .content { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding-bottom: 40rpx; + } + .icon { font-size: 80rpx; margin-bottom: 20rpx; } + .notice { + font-size: 34rpx; + font-weight: 600; + color: #333; + margin-bottom: 10rpx; + } + .sub { + font-size: 24rpx; + color: #999; + } \ No newline at end of file diff --git a/miniprogram/components/popup-notice/popup-notice.js b/miniprogram/components/popup-notice/popup-notice.js new file mode 100644 index 0000000..64589db --- /dev/null +++ b/miniprogram/components/popup-notice/popup-notice.js @@ -0,0 +1,324 @@ +// components/popup-notice/popup-notice.js +import PopupService from '../../services/popupService.js'; + +Component({ + data: { + // 原有全屏弹窗数据 + visible: false, + title: '', + images: [], + processedImages: [], + hasImages: false, + hasTextOnly: false, + textContent: '', + duration: 0, + remainingSeconds: 0, + muteChecked: false, + showMuteCheckbox: false, + isFullscreen: false, + timer: null, + + // 悬浮窗相关数据 + isMinimized: false, + floatX: 20, + floatY: 200, + savedRemainingSeconds: 0, + floatAvatarUrl: '', + + // 🆕 自定义预览数据 + showCustomPreview: false, // 是否显示自定义预览遮罩 + previewUrls: [], // 当前预览的图片URL列表 + currentPreviewIndex: 0, // 当前预览图片索引 + }, + + lifetimes: { + detached() { + this.clearTimer(); + } + }, + + methods: { + // ========== 原有所有方法(完全不变,一字不漏) ========== + async show(config, onCloseCallback) { + const { title, images, duration, showMuteCheckbox, serverTime } = config; + this.onCloseCallback = onCloseCallback; + + let safeImages = JSON.parse(JSON.stringify(images || [])); + const hasImages = safeImages.length > 0; + let hasTextOnly = false, textContent = ''; + if (!hasImages) { + hasTextOnly = true; + textContent = config.text || '暂无内容'; + } + + this.setData({ + visible: true, + isMinimized: false, + title: title || '', + images: safeImages, + hasImages, + hasTextOnly, + textContent, + duration: duration || 0, + remainingSeconds: duration || 0, + muteChecked: false, + showMuteCheckbox: showMuteCheckbox || false, + isFullscreen: false, + processedImages: [], + }); + + if (duration > 0) { + this.startCountdown(); + } + + if (hasImages) { + const processed = []; + const screenWidth = wx.getSystemInfoSync().windowWidth; + const containerWidth = screenWidth * 0.9; + const imageWidth = containerWidth - 60; + for (let i = 0; i < safeImages.length; i++) { + const img = safeImages[i]; + const fullUrl = this.getFullImageUrl(img.url); + let imageHeight = 200; + try { + const res = await this.getImageInfoPromise(fullUrl); + const realHeight = (imageWidth * res.height) / res.width; + imageHeight = realHeight; + } catch (e) { + console.error('获取图片信息失败', fullUrl, e); + } + processed.push({ + url: fullUrl, + text: img.text, + height: imageHeight, + }); + } + this.setData({ processedImages: processed }); + } + }, + + getImageInfoPromise(url) { + return new Promise((resolve, reject) => { + wx.getImageInfo({ + src: url, + success: resolve, + fail: reject, + }); + }); + }, + + hide(muteToday = false) { + this.clearTimer(); + this.setData({ + visible: false, + isMinimized: false + }); + if (this.onCloseCallback) { + this.onCloseCallback({ muteToday }); + } + }, + + startCountdown() { + this.clearTimer(); + this.timer = setInterval(() => { + let sec = this.data.remainingSeconds; + if (sec <= 1) { + this.clearTimer(); + this.setData({ remainingSeconds: 0 }); + } else { + this.setData({ remainingSeconds: sec - 1 }); + } + }, 1000); + }, + + clearTimer() { + if (this.timer) { + clearInterval(this.timer); + this.timer = null; + } + }, + + onCloseTap() { + if (this.data.remainingSeconds > 0) { + wx.showToast({ + title: `请阅读${this.data.remainingSeconds}秒后再关闭`, + icon: 'none' + }); + return; + } + if (this.data.showMuteCheckbox && this.data.muteChecked) { + wx.showModal({ + title: '提示', + content: '今天将不再收到本页面的任何公告,确认吗?', + success: (res) => { + if (res.confirm) this.hide(true); + }, + }); + } else { + this.hide(false); + } + }, + + onMuteChange(e) { + this.setData({ muteChecked: e.detail.value.length > 0 }); + }, + + // 🆕 替换原有的 onPreviewImage,改用自定义预览(不触发 onShow) + onCustomPreview(e) { + const index = e.currentTarget.dataset.index; + const urls = this.data.processedImages.map(img => img.url); + this.setData({ + showCustomPreview: true, + previewUrls: urls, + currentPreviewIndex: index !== undefined ? index : 0 + }); + }, + + // 🆕 关闭自定义预览 + onCloseCustomPreview() { + this.setData({ + showCustomPreview: false, + previewUrls: [], + currentPreviewIndex: 0 + }); + }, + + // 🆕 swiper 切换事件 + onPreviewSwiperChange(e) { + this.setData({ + currentPreviewIndex: e.detail.current + }); + }, + + // 保留原 onPreviewImage 方法以防外部调用,但不再使用 + onPreviewImage(e) { + // 重定向到自定义预览 + this.onCustomPreview(e); + }, + + onImageError(e) { + console.error('图片加载失败:', e.currentTarget.dataset.url); + }, + + toggleFullscreen() { + this.setData({ isFullscreen: !this.data.isFullscreen }); + }, + + getFullImageUrl(relativeUrl) { + if (!relativeUrl) return ''; + if (relativeUrl.startsWith('http')) return relativeUrl; + const app = getApp(); + let base = app.globalData.ossImageUrl || ''; + base = base.replace(/\/+$/, ''); + const clean = relativeUrl.replace(/^\/+/, ''); + return base ? base + '/' + clean : clean; + }, + + preventMove() {}, + + onMinimize() { + const remaining = this.data.remainingSeconds; + this.clearTimer(); + + const app = getApp(); + let avatarUrl = ''; + if (app.globalData.morentouxiang) { + avatarUrl = app.globalData.morentouxiang; + } else { + avatarUrl = '/images/default-avatar.png'; + } + + if (avatarUrl && !avatarUrl.startsWith('http')) { + const ossBase = app.globalData.ossImageUrl || ''; + avatarUrl = ossBase.replace(/\/+$/, '') + '/' + avatarUrl.replace(/^\/+/, ''); + } + + this.setData({ + visible: false, + isMinimized: true, + savedRemainingSeconds: remaining, + floatX: 20, + floatY: 200, + floatAvatarUrl: avatarUrl + }); + }, + + onFloatChange(e) { + this.setData({ + floatX: e.detail.x, + floatY: e.detail.y + }); + }, + + onFloatTap() { + this.setData({ + visible: true, + isMinimized: false, + remainingSeconds: this.data.savedRemainingSeconds + }); + + if (this.data.duration > 0 && this.data.savedRemainingSeconds > 0) { + this.startCountdown(); + } + }, + + onFloatAvatarError() { + this.setData({ + floatAvatarUrl: '/images/avatar-placeholder.png' + }); + }, + + cleanup() { + this.clearTimer(); + this.setData({ + visible: false, + isMinimized: false + }); + PopupService.reset(); + }, + + onFloatTouchStart(e) { + const touch = e.touches[0]; + this.touchStartX = touch.clientX; + this.touchStartY = touch.clientY; + this.startFloatX = this.data.floatX; + this.startFloatY = this.data.floatY; + this.hasMoved = false; + return false; + }, + + onFloatTouchMove(e) { + const touch = e.touches[0]; + const deltaX = touch.clientX - this.touchStartX; + const deltaY = touch.clientY - this.touchStartY; + + if (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5) { + this.hasMoved = true; + } + + let newX = this.startFloatX + deltaX; + let newY = this.startFloatY + deltaY; + + const systemInfo = wx.getSystemInfoSync(); + const screenWidth = systemInfo.windowWidth; + const screenHeight = systemInfo.windowHeight; + const estimatedSize = 60; + + newX = Math.max(0, Math.min(newX, screenWidth - estimatedSize)); + newY = Math.max(0, Math.min(newY, screenHeight - estimatedSize)); + this.setData({ floatX: newX, floatY: newY }); + + return false; + }, + + onFloatTouchEnd(e) { + if (!this.hasMoved) { + this.onFloatTap(); + } + return false; + }, + + // 🆕 阻止事件冒泡(用于预览遮罩内部点击不关闭) + stopPropagation() {} + } + }); \ No newline at end of file diff --git a/miniprogram/components/popup-notice/popup-notice.json b/miniprogram/components/popup-notice/popup-notice.json new file mode 100644 index 0000000..62389a9 --- /dev/null +++ b/miniprogram/components/popup-notice/popup-notice.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} + } \ No newline at end of file diff --git a/miniprogram/components/popup-notice/popup-notice.wxml b/miniprogram/components/popup-notice/popup-notice.wxml new file mode 100644 index 0000000..8e682cb --- /dev/null +++ b/miniprogram/components/popup-notice/popup-notice.wxml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + {{isFullscreen ? '✕' : '⛶'}} + + + + + {{title}} + + + + + {{textContent}} + + + {{item.text}} + + + + + + + + + + + + 请阅读 {{remainingSeconds}} 秒后关闭 + + + + + 今日不再提示 + + + + + {{remainingSeconds > 0 ? '阅读中...' : '关闭'}} + + + + + + + + + + + + + + + {{currentPreviewIndex + 1}} / {{previewUrls.length}} + × + + + + + + + \ No newline at end of file diff --git a/miniprogram/components/popup-notice/popup-notice.wxss b/miniprogram/components/popup-notice/popup-notice.wxss new file mode 100644 index 0000000..ee4873b --- /dev/null +++ b/miniprogram/components/popup-notice/popup-notice.wxss @@ -0,0 +1,295 @@ +/* components/popup-notice/popup-notice.wxss */ + +/* ========== 全屏弹窗样式(原有,完全不变) ========== */ +.popup-mask { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.6); + display: flex; + align-items: center; + justify-content: center; + z-index: 10000; +} + +.popup-container { + width: 90%; + height: 85vh; + background: white; + border-radius: 32rpx; + display: flex; + flex-direction: column; + overflow: hidden; + position: relative; +} + +.popup-container.fullscreen { + width: 100%; + height: 100%; + border-radius: 0; +} + +.action-buttons { + position: absolute; + top: 20rpx; + right: 20rpx; + display: flex; + gap: 16rpx; + z-index: 10; +} + +.minimize-btn, +.fullscreen-btn { + width: 60rpx; + height: 60rpx; + background: rgba(0, 0, 0, 0.4); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + backdrop-filter: blur(4rpx); + transition: all 0.2s; +} + +.minimize-btn:active, +.fullscreen-btn:active { + background: rgba(0, 0, 0, 0.6); + transform: scale(0.9); +} + +.btn-icon { + font-size: 36rpx; + color: white; + font-weight: bold; + line-height: 1; +} + +.popup-title { + font-size: 40rpx; + font-weight: bold; + color: #000; + text-align: center; + padding: 30rpx 30rpx 20rpx; + border-bottom: 2rpx solid #eee; + background: white; +} + +.scroll-wrapper { + flex: 1; + overflow: hidden; + width: 100%; +} + +.scroll-view { + height: 100%; + width: 100%; + padding: 0; +} + +.text-content { + font-size: 36rpx; + font-weight: bold; + color: #000; + line-height: 1.6; + padding: 30rpx; + text-align: left; +} + +.image-block { + display: flex; + flex-direction: column; + width: 100%; + margin: 0; + padding: 0; +} + +.block-text { + font-size: 36rpx; + font-weight: bold; + color: #000; + padding: 16rpx 30rpx 4rpx 30rpx; + text-align: left; + line-height: 1.4; +} + +.image-padding { + padding: 0 30rpx; + box-sizing: border-box; + width: 100%; +} + +.block-image { + width: 100%; + display: block; + background: #f5f5f5; + border-radius: 16rpx; +} + +.bottom-fixed { + background: white; + border-top: 1rpx solid #eee; + padding: 20rpx 0 30rpx 0; + width: 100%; + box-sizing: border-box; +} + +.countdown-tip { + text-align: center; + font-size: 28rpx; + color: #ff6600; + margin-bottom: 20rpx; +} + +.mute-row { + display: flex; + justify-content: center; + margin-bottom: 20rpx; +} + +.mute-label { + font-size: 28rpx; + color: #555; + margin-left: 12rpx; +} + +/* 🔥 关闭按钮(替换原有 button,增加扫光) */ +.close-btn { + width: 600rpx; + height: 100rpx; + background: #1a1a1a; + border-radius: 60rpx; + display: flex; + align-items: center; + justify-content: center; + position: relative; + overflow: hidden; + margin: 0 auto; +} + +.close-btn:active { + opacity: 0.85; + transform: scale(0.98); +} + +.close-btn-disabled { + opacity: 0.6; + pointer-events: none; +} + +.close-btn-text { + color: white; + font-size: 40rpx; + font-weight: bold; + position: relative; + z-index: 2; +} + +.close-btn-sweep { + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent); + transform: skewX(-20deg); + animation: sweep 2.5s infinite ease-in-out; + z-index: 1; + pointer-events: none; +} + +@keyframes sweep { + 0% { left: -100%; } + 40% { left: 100%; } + 100% { left: 100%; } +} + +/* ========== 悬浮窗样式(纯圆形,适配自定义触摸拖动) ========== */ +.floating-avatar-wrapper { + position: fixed; + width: 120rpx; + height: 120rpx; + z-index: 10001; + transform: translateZ(0); + will-change: left, top; + display: flex; + align-items: center; + justify-content: center; +} + +.floating-avatar { + width: 120rpx; + height: 120rpx; + border-radius: 50%; + box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.3); + border: 2rpx solid rgba(255, 215, 0, 0.6); + background: #f0f0f0; + display: block; + transform: translateZ(0); +} + +/* 以下原有 movable-view 相关样式已弃用,但保留以维持代码完整(用户要求不删代码) */ +.floating-area { + display: none; +} +.floating-view { + display: none; +} +.float-avatar-wrapper { + display: none; +} +.float-text { + display: none; +} + +/* ========== 自定义图片预览遮罩样式(全屏,不触发 onShow) ========== */ +.custom-preview-mask { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.95); + z-index: 100000; + display: flex; + flex-direction: column; +} + +.preview-header { + height: 100rpx; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 30rpx; + color: white; + font-size: 32rpx; + background: rgba(0, 0, 0, 0.3); +} + +.preview-index { + color: white; +} + +.preview-close { + width: 60rpx; + height: 60rpx; + display: flex; + align-items: center; + justify-content: center; + font-size: 48rpx; + color: white; + background: rgba(255, 255, 255, 0.2); + border-radius: 50%; +} + +.preview-swiper { + flex: 1; + width: 100%; + height: 100%; +} + +.preview-image { + width: 100%; + height: 100%; +} \ No newline at end of file diff --git a/miniprogram/config/roles.js b/miniprogram/config/roles.js new file mode 100644 index 0000000..95c04dc --- /dev/null +++ b/miniprogram/config/roles.js @@ -0,0 +1,144 @@ +/* + * 角色配置表 —— 用于动态切换底部 TabBar 展示内容 + * 每个角色的 tabList 数组元素顺序决定 TabBar 显示顺序 + * 字段说明: + * pagePath : 页面路径(以 pages/ 开头) + * text : TabBar 文字 + * iconPath : 未选中图标(相对路径) + * selectedIconPath: 选中图标 + */ +const roles = { + // 普通老板(默认) + normal: { + name: '普通老板', + defaultPage: 'pages/index/index', + tabList: [ + { + pagePath: 'pages/index/index', + text: '商城', + iconPath: '/images/zhuye.png', + selectedIconPath: '/images/zhuye.png' + }, + { + pagePath: 'pages/fenlei/fenlei', + text: '分类', + iconPath: '/images/fenlei.png', + selectedIconPath: '/images/fenlei.png' + }, + { + pagePath: 'pages/xiaoxi/xiaoxi', + text: '消息', + iconPath: '/images/xiaoxi.png', + selectedIconPath: '/images/xiaoxi.png' + }, + { + pagePath: 'pages/wode/wode', + text: '我的', + iconPath: '/images/wode.png', + selectedIconPath: '/images/wode.png' + } + ] + }, + // 打手 + dashou: { + name: '打手', + defaultPage: 'pages/jiedanchi/jiedanchi', + tabList: [ + { + pagePath: 'pages/jiedanchi/jiedanchi', + text: '接单池', + iconPath: '/images/jiedanchi.png', + selectedIconPath: '/images/jiedanchi.png' + }, + { + pagePath: 'pages/xiaoxi/xiaoxi', + text: '消息', + iconPath: '/images/xiaoxi.png', + selectedIconPath: '/images/xiaoxi.png' + }, + { + pagePath: 'pages/dashoudingdan/dashoudingdan', + text: '订单', + iconPath: '/images/dashoudingdan_icon.png', // 请替换为实际图标 + selectedIconPath: '/images/dashoudingdan_icon.png' + }, + { + pagePath: 'pages/dashouduan/dashouduan', + text: '我的', + iconPath: '/images/dashouduan_icon.png', + selectedIconPath: '/images/dashouduan_icon.png' + } + ] + }, + // 商家 + shangjia: { + name: '商家', + defaultPage: 'pages/index/index', + tabList: [ + { + pagePath: 'pages/index/index', + text: '首页', + iconPath: '/images/zhuye.png', + selectedIconPath: '/images/zhuye.png' + }, + { + pagePath: 'pages/sjdingdan/sjdingdan', + text: '订单', + iconPath: '/images/sjdingdan_icon.png', // 请替换为实际图标 + selectedIconPath: '/images/sjdingdan_icon.png' + }, + { + pagePath: 'pages/xiaoxi/xiaoxi', + text: '消息', + iconPath: '/images/xiaoxi.png', + selectedIconPath: '/images/xiaoxi.png' + }, + { + pagePath: 'pages/shangjiaduan/shangjiaduan', + text: '我的', + iconPath: '/images/shangjiaduan_icon.png', + selectedIconPath: '/images/shangjiaduan_icon.png' + } + ] + }, + // 管事 + guanshi: { + name: '管事', + defaultPage: 'pages/guanshiduan/guanshiduan', + tabList: [ + { + pagePath: 'pages/xiaoxi/xiaoxi', + text: '消息', + iconPath: '/images/xiaoxi.png', + selectedIconPath: '/images/xiaoxi.png' + }, + { + pagePath: 'pages/guanshiduan/guanshiduan', + text: '我的', + iconPath: '/images/guanshiduan_icon.png', + selectedIconPath: '/images/guanshiduan_icon.png' + } + ] + }, + // 组长 + zuzhang: { + name: '组长', + defaultPage: 'pages/zuzhangduan/zuzhangduan', + tabList: [ + { + pagePath: 'pages/xiaoxi/xiaoxi', + text: '消息', + iconPath: '/images/xiaoxi.png', + selectedIconPath: '/images/xiaoxi.png' + }, + { + pagePath: 'pages/zuzhangduan/zuzhangduan', + text: '我的', + iconPath: '/images/zuzhangduan_icon.png', + selectedIconPath: '/images/zuzhangduan_icon.png' + } + ] + } + }; + + module.exports = { roles }; \ No newline at end of file diff --git a/miniprogram/custom-tab-bar/index.js b/miniprogram/custom-tab-bar/index.js new file mode 100644 index 0000000..53ab079 --- /dev/null +++ b/miniprogram/custom-tab-bar/index.js @@ -0,0 +1,194 @@ +// custom-tab-bar/index.js +const app = getApp(); + +const roleCfg = { + normal: { + name: '点单老板', + defaultPage: '/pages/index/index', + tabList: [ + { pagePath: 'pages/index/index', text: '商城', iconPath: '/images/zhuye.png', selectedIconPath: '/images/zhuye.png' }, + { pagePath: 'pages/fenlei/fenlei', text: '分类', iconPath: '/images/fenlei.png', selectedIconPath: '/images/fenlei.png' }, + { pagePath: 'pages/xiaoxi/xiaoxi', text: '消息', iconPath: '/images/xiaoxi.png', selectedIconPath: '/images/xiaoxi.png' }, + { pagePath: 'pages/wode/wode', text: '我的', iconPath: '/images/wode.png', selectedIconPath: '/images/wode.png' } + ] + }, + dashou: { + name: '打手', + defaultPage: '/pages/jiedan/jiedan', + tabList: [ + { pagePath: 'pages/jiedan/jiedan', text: '接单池', iconPath: '/images/jiedanchi.png', selectedIconPath: '/images/jiedanchi.png' }, + { pagePath: 'pages/dashoudingdan/dashoudingdan', text: '订单', iconPath: '/images/dingdan.png', selectedIconPath: '/images/dingdan.png' }, + { pagePath: 'pages/xiaoxi/xiaoxi', text: '消息', iconPath: '/images/xiaoxi.png', selectedIconPath: '/images/xiaoxi.png' }, + { pagePath: 'pages/dashouduan/dashouduan', text: '我的', iconPath: '/images/wode.png', selectedIconPath: '/images/wode.png' } + ] + }, + shangjia: { + name: '商家', + defaultPage: 'pages/sjdingdan/sjdingdan', + tabList: [ + { pagePath: 'pages/sjdingdan/sjdingdan', text: '订单', iconPath: '/images/dingdan.png', selectedIconPath: '/images/dingdan.png' }, + { pagePath: 'pages/xiaoxi/xiaoxi', text: '消息', iconPath: '/images/xiaoxi.png', selectedIconPath: '/images/xiaoxi.png' }, + { pagePath: 'pages/shangjiaduan/shangjiaduan', text: '我的', iconPath: '/images/wode.png', selectedIconPath: '/images/wode.png' } + ] + }, + guanshi: { + name: '管事', + defaultPage: '/pages/guanshiduan/guanshiduan', + tabList: [ + { pagePath: 'pages/xiaoxi/xiaoxi', text: '消息', iconPath: '/images/xiaoxi.png', selectedIconPath: '/images/xiaoxi.png' }, + { pagePath: 'pages/guanshiduan/guanshiduan', text: '我的', iconPath: '/images/wode.png', selectedIconPath: '/images/wode.png' } + ] + }, + zuzhang: { + name: '组长', + defaultPage: '/pages/zuzhangduan/zuzhangduan', + tabList: [ + { pagePath: 'pages/xiaoxi/xiaoxi', text: '消息', iconPath: '/images/xiaoxi.png', selectedIconPath: '/images/xiaoxi.png' }, + { pagePath: 'pages/zuzhangduan/zuzhangduan', text: '我的', iconPath: '/images/wode.png', selectedIconPath: '/images/wode.png' } + ] + }, + kaoheguan: { + name: '考核官', + defaultPage: '/pages/kaoheguan/kaoheguan', + tabList: [ + { pagePath: 'pages/xiaoxi/xiaoxi', text: '消息', iconPath: '/images/xiaoxi.png', selectedIconPath: '/images/xiaoxi.png' }, + { pagePath: 'pages/kaoheguan/kaoheguan', text: '我的', iconPath: '/images/wode.png', selectedIconPath: '/images/wode.png' } + ] + } +}; + +Component({ + data: { + selectedIndex: 0, + tabList: [], + currentRole: 'normal', + showRolePicker: false, + availableRoles: [], + badgeText: '' + }, + lifetimes: { + attached() { + this.refresh(); + this._badgeListener = (data) => { + if (data.badgeText !== undefined) { + this.setData({ badgeText: data.badgeText }); + } + }; + app.on('tabBarBadgeChanged', this._badgeListener); + }, + detached() { + if (this._badgeListener) { + app.off('tabBarBadgeChanged', this._badgeListener); + } + } + }, + pageLifetimes: { + show() { + this.refresh(); + const globalBadge = app.globalData.messageManager?.tabBarBadgeText || ''; + if (this.data.badgeText !== globalBadge) { + this.setData({ badgeText: globalBadge }); + } + this._syncUnreadWithDebounce(); + } + }, + methods: { + _syncUnreadWithDebounce() { + if (this._syncTimer) clearTimeout(this._syncTimer); + this._syncTimer = setTimeout(() => { + if (app && app.loadConversations) { + app.loadConversations(); + } + }, 300); + }, + + refresh() { + const role = app.globalData.currentRole || 'normal'; + let cfg = roleCfg[role]; + if (!cfg) return; + + // 打手身份下,如果 isJinpai=1,悄悄把“我的”页面换成金牌页面 + if (role === 'dashou') { + const isJinpai = wx.getStorageSync('isJinpai') === 1; + if (isJinpai) { + cfg = { + ...cfg, + tabList: cfg.tabList.map(item => { + if (item.pagePath === 'pages/dashouduan/dashouduan') { + return { ...item, pagePath: 'pages/jinpaids/jinpaids' }; + } + return { ...item }; + }) + }; + } + } + + const list = cfg.tabList.map((v, i) => ({ ...v, index: i })); + const pages = getCurrentPages(); + const curRoute = pages.length ? pages[pages.length - 1].route : ''; + let idx = list.findIndex(t => t.pagePath === curRoute); + if (idx === -1) idx = 0; + const avail = this._getAvail(); + this.setData({ currentRole: role, tabList: list, selectedIndex: idx, availableRoles: avail }); + }, + + _getAvail() { + const arr = [{ key: 'normal', name: '点单老板' }]; + if (wx.getStorageSync('dashoustatus') === 1) arr.push({ key: 'dashou', name: '打手' }); + if (wx.getStorageSync('shangjiastatus') === 1) arr.push({ key: 'shangjia', name: '商家' }); + if (wx.getStorageSync('guanshistatus') === 1) arr.push({ key: 'guanshi', name: '管事' }); + if (wx.getStorageSync('zuzhangstatus') === 1) arr.push({ key: 'zuzhang', name: '组长' }); + if (wx.getStorageSync('kaoheguanstatus') === 1) arr.push({ key: 'kaoheguan', name: '考核官' }); + return arr; + }, + + toggleRolePicker() { + this.setData({ showRolePicker: !this.data.showRolePicker }); + }, + + async selectRole(e) { + const newRole = e.currentTarget.dataset.role; + if (newRole === this.data.currentRole) { + this.setData({ showRolePicker: false }); + return; + } + + this.setData({ showRolePicker: false }); + + // 1. 立即更新角色并保存 + app.globalData.currentRole = newRole; + wx.setStorageSync('currentRole', newRole); + + // 2. 🔥 确定跳转页面:所有角色都去“我的”页面 + let targetPage = ''; + if (newRole === 'dashou') { + // 打手需要根据金牌状态决定跳转 + const isJinpai = wx.getStorageSync('isJinpai') === 1; + targetPage = isJinpai ? '/pages/jinpaids/jinpaids' : '/pages/dashouduan/dashouduan'; + } else { + // 其他角色直接取 tabList 最后一个页面 + const cfg = roleCfg[newRole]; + if (cfg && cfg.tabList.length > 0) { + targetPage = '/' + cfg.tabList[cfg.tabList.length - 1].pagePath; + } + } + + // 3. 跳转 + if (targetPage) { + wx.reLaunch({ url: targetPage }); + } + + // 4. 后台异步切换连接 + app.switchRoleAndReconnect(newRole).catch(err => { + console.error('后台切换连接失败:', err); + }); + }, + + switchTab(e) { + const path = e.currentTarget.dataset.path; + const idx = e.currentTarget.dataset.index; + if (idx === this.data.selectedIndex) return; + wx.redirectTo({ url: '/' + path }); + } + } +}); \ No newline at end of file diff --git a/miniprogram/custom-tab-bar/index.json b/miniprogram/custom-tab-bar/index.json new file mode 100644 index 0000000..62389a9 --- /dev/null +++ b/miniprogram/custom-tab-bar/index.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} + } \ No newline at end of file diff --git a/miniprogram/custom-tab-bar/index.wxml b/miniprogram/custom-tab-bar/index.wxml new file mode 100644 index 0000000..93b07a6 --- /dev/null +++ b/miniprogram/custom-tab-bar/index.wxml @@ -0,0 +1,42 @@ + + + + + + 切换 + + + + + + + + + {{badgeText}} + + + {{item.text}} + + + + + + + + + + 切换身份 + + + + + {{item.name}} + + + + + \ No newline at end of file diff --git a/miniprogram/custom-tab-bar/index.wxss b/miniprogram/custom-tab-bar/index.wxss new file mode 100644 index 0000000..7a957fa --- /dev/null +++ b/miniprogram/custom-tab-bar/index.wxss @@ -0,0 +1,165 @@ +/* custom-tab-bar/index.wxss - 角标浮于右上角,可超出胶囊 */ + +.custom-tab-bar { + position: fixed; + bottom: 0; left: 0; right: 0; + z-index: 9999; + display: flex; + justify-content: center; + align-items: flex-end; + padding-bottom: env(safe-area-inset-bottom); + background: transparent; + } + + .bar-row { + display: flex; + align-items: center; + margin-bottom: 15rpx; + padding: 0 20rpx; + width: 100%; + box-sizing: border-box; + } + + /* 左侧椭圆身份按钮 */ + .role-switch-btn { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 110rpx; + height: 100rpx; + border-radius: 50rpx; + background: #000000; + border: 1px solid rgba(255,255,255,0.15); + box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.8); + margin-right: 20rpx; + flex-shrink: 0; + } + .role-switch-icon { + width: 40rpx; + height: 40rpx; + margin-bottom: 2rpx; + } + + .role-switch-text { + font-size: 22rpx; + font-weight: 600; + color: #00f7ff; + letter-spacing: 1rpx; + } + + /* 纯黑闪光胶囊,移除overflow保证角标可见 */ + .tab-capsule { + flex: 1; + display: flex; + align-items: center; + justify-content: space-around; + height: 100rpx; + background: #000000; + border-radius: 50rpx; + border: 1px solid rgba(255,255,255,0.15); + box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.8); + padding: 0 20rpx; + position: relative; + } + .tab-capsule::before { + content: ''; + position: absolute; + top: 0; left: -100%; + width: 60%; height: 100%; + background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.25) 20%, rgba(255,255,255,0.35) 50%, rgba(255,255,255,0.25) 80%, transparent 100%); + animation: shine 3s infinite; + z-index: 1; + } + @keyframes shine { + 0% { left: -100%; } + 25% { left: 150%; } + 100% { left: 150%; } + } + + .tab-item { + position: relative; /* 角标的定位参考 */ + z-index: 2; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-width: 70rpx; + } + .tab-icon { + width: 44rpx; + height: 44rpx; + margin-bottom: 4rpx; + filter: brightness(0) invert(1); + opacity: 0.9; + } + .tab-text { + font-size: 20rpx; + color: #aaa; + z-index: 2; + } + .active .tab-icon { + opacity: 1; + filter: brightness(0) invert(1) drop-shadow(0 0 8rpx #00aaff); + } + .active .tab-text { + color: #00aaff; + font-weight: 500; + } + + /* 🔴 角标容器:绝对定位到图标右上角,允许超出 */ + .badge-container { + position: absolute; + top: -10rpx; /* 往上提,更接近图标右上角 */ + right: -15rpx; /* 往右伸,超出tab-item */ + z-index: 100; + pointer-events: none; /* 不阻挡点击 */ + } + .tab-badge { + min-width: 36rpx; + height: 36rpx; + line-height: 36rpx; + padding: 0 10rpx; + background: #ff3b30; + color: #fff; + font-size: 22rpx; + font-weight: bold; + border-radius: 36rpx; + text-align: center; + box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.3); + border: 1rpx solid rgba(255,255,255,0.4); + } + + /* 弹窗部分保持不变 */ + .picker-mask { + position: fixed; top: 0; left: 0; right: 0; bottom: 0; + background: rgba(0,0,0,0.6); + z-index: 10000; + } + .picker-panel { + position: fixed; bottom: 0; left: 0; right: 0; + background: #000000; + border-radius: 30rpx 30rpx 0 0; + z-index: 10001; + max-height: 70vh; + overflow-y: auto; + } + .picker-header { + display: flex; justify-content: space-between; align-items: center; + padding: 30rpx 40rpx 20rpx; + border-bottom: 1px solid rgba(255,255,255,0.1); + } + .picker-title { font-size: 32rpx; color: #00f7ff; } + .picker-close { font-size: 36rpx; color: #aaa; padding: 0 10rpx; } + .role-option { + display: flex; justify-content: space-between; align-items: center; + padding: 28rpx 40rpx; + border-bottom: 1px solid rgba(255,255,255,0.05); + color: #ccc; font-size: 28rpx; + } + .role-option.active { color: #00f7ff; } + .check-mark { font-size: 32rpx; color: #00f7ff; } + + page { + padding-bottom: 100rpx; + } \ No newline at end of file diff --git a/miniprogram/images/dingdan.png b/miniprogram/images/dingdan.png new file mode 100644 index 0000000000000000000000000000000000000000..b9a3a9c9a92f721c8080bff2300b9aa6141ce677 GIT binary patch literal 15163 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

+DnskI*B)TBr()2J3mUuhzdt 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 R;wk_D002ovPDHLkV1nU?u5bVV literal 0 HcmV?d00001 diff --git a/miniprogram/images/goumai.png b/miniprogram/images/goumai.png new file mode 100644 index 0000000000000000000000000000000000000000..a2ec8ed29dcf341b98b42bb3751ebca9d0014f7b GIT binary patch literal 7689 zcmYLObzGC*_a881^eCkn8y(VJ8;k}i6_J!w>5`Hf-6NHhmPSD75E(E)8U&=2MoK0i zC4Be!{quWXuP5$3=f-oNbIyIv`yFTaK$DV;nG65`P-<%-jq!Kve<$b;{#yH_t^fc4 z1GJHdhyDcn`J@>Pv)O~WEAwKEaq-MXOP-Vj{jT3xiG%uUljztYoH9Je-XfC*zS^@M z?@YEP4#>uN=E@Gd6{{uenz*m+VruBQ>M;k34TH|l3oWBp=eiFSSE}1vR`#j_ADwn9 z|J^e`3i125devk8XjwpbQbiq3Y>ka_M!!G`f&3JQIWP6VhA2#Fv1D!(0#0hoxFj|E76LXvVSpB+ zj@LAJSr64GAOW-xND8({lE1;XU$c&RiUQz8Kv10qTPQFC!sJ__!VvC*f7*S%^9hO$ z52NKG0{^Q7mBI>v+L~(h4B-_2sfFzrs6*HYxV7Y&d##-J#gLyR5Wjx?szMK@N@2GM zM`)*ddfM9qUsH(92@Qe>41n3n!I#PzyEGdf_FTr#C9)`3tsg&@mdTU}sWJjyYkt;2 z4-5S)uTYySBD=S>aazg>)!$kRe`OJn&@auhun;tMLx)5yQgQ7X!9QVVMxWCC@>5 z9e;URvpz{(O*Hn~gH8!Y?pXTzPoF+Tu))k?6xH3A`Q41trlyR!wK4>_5CO+XF#pj~ zo40igU(BbE9}_X`^yTnj4sG@&q$XI#ekQmOsr%gk%a_MQaL8R?wqigdcq7>4g2};$&6ZHhH-HmNj{2G->iyAicu3BW{f(Y5<;a!THPXyg+JK|#16|OI^IMk!%?D{AEU^hi~QkSBi8E?_@mGD7--hw zwro!CBe(Wa`D$N+P2FOWzlPAuLai@2(IPK4^4Y7%*g4UEIn?~`x6*BDK)4At>e@2& zfDsU$0STj*QX>imds!G3z8=ciKrrch>8s>I+6KVgq3f!aq_iPXZ;kC|<{7+%`V6d; zWPiSv_?YAj85(UvGAf`Z$eA?3WcB7i5Q6FhWN=g_?9ZLl2D zp5c|%owTo!AE<*USrt%*qAUoXcw((6=|t8NU0vOK8>!TsePu!)ct18bQ>ndzpQ$Iq zyOR<%n>FrC&KpFB=?9d0N^%|h{IJ;v5%TGv6`vyK5zku>tYM1Z#0To~@Y}Ip3lT9}TU#=5My?-7Mfe5NYT(OAg#hY-G=-{JcuQ5%p7KZ1T`GHXo0LjihMd1pYn8*ah#dSNa>-pt z|CHujV5bcxyRQH%M+qYIc7UaeA77+Pew<`4R*5gTQBgb}StLIe2@mT4_fE%7PW-$< zry3k)+FvAaBWyZ7fkheZv*e&>IWrb3@}G*mb04f9fCSz1^Yd}~xjj#((lw1Dm&{gd zwb6%%ZUF%T)uJz`kC(R@1z zB}^J*-@Z#5vC%+RW0ij4Ui#u^=B`;NH3h*p_Enxc>skE3z_8TyJJ*}`u|ZtZ@2VM# zHrP@-o?|q(=m`q8M{{|nYerfnnH_mnM^3=Hs1G1>ZA9X<5LxxK5S*;<uzdVcUGX;r$Iuzr*{lq6j5Kx&kEijn2 z{7D2e3(H7VRn>5VpqVM<0K1NejLWZ?%07pX7HleQ|Z)C!N14UgTIN*rCGQ+;yXy)L#n} zZ|+o3CT>v^6c89Ab}o4)`R0mNLq$$NW^+enxkK^f?M+aEGd7O`We5(~uuu5na6O+A zf6dMi$o)$26$y?Jx*8Ztd&Q5mDh*)1VzTGNvEm4EP#i5z$I^1SdcGd!4snONbGpNh zphuh>5Dq8@r`OxhwEHQk4p=XH;zrsF3bUvhjc<^A>{BEa$CH>Y_JvpZyQ~i+2~O62c9m;)ko=m`uvt;s z-#X-UqKr8py6%j*^_v`W`(fVN6}QOJ+LioI;7oAGig5hiWLMZfRyXoVrM}bYdE8;^ zYrS3V5bMOZdRO>;jN3K+-GtA^zws>0s}eQl$!*?d6QR4&#+58rWNS9=M2tOy|K87k zn!gRhddoD5gz(LofU{R03=~A_A?aLngROZZU%%O0(D`sb}L4>mzOA{TuScr>$<=sE7w&o&fMT= z<_{AGKH3irHM<~KbYLB}cYId_796}O^*U0M7)+Jo9klA>4xpA^En70oSNL0P>iyzJ)Sx)|} zOwkjw#-rAd*D1y%6Y#?g8bYn=2bpdm@>rx+!L5xd&j*#H-$R|jTNK)lTMy!M!@4B? ztmK1QVC`%ki|j!POWon`#Fq5Zg|}-*Mn*K(n;F`TSfpJT!`)=f9f5vGS~jO=>1h7&2e}LB zYVX-f$=4W;_o@Y-L&$=Z-N-+@>kYZvvfUcO-Xmh$GqbdGE$&ud97K6Vxv##nqWV|5 z-OnS4y5+Cu6}Y9Rxur#9zzXHY?>6#5rPq}>kysv*>%@@u+T(<{1P^LVZ$q8fFu^I zS?tTOCPf=bRoA1}z>Y8mVd-JM*{()U+5+CxYPIS<=`WEv#CP$c*xkoVB!lIzMRIf5 z^6c!abvYLpxiwcVK4R&XZskh^4_oms;+MS~sHzeOQ2o3iEXfATNrEIW4k=uT(+8m@ z)D{G=vLuH@st4C#8_Ux|?v1ypFwFv+W4fH2Gg}yT|KuyC0CEBf)fPeb`SQz@`p|m< z2B>+>OligyF|!kVPOSoJ4=1QLWFY}tV;NPQg|qc3N{A;r!{17dkDUat-<(f~itn|- z0Nu?^Zq?2&U*3rQeQT+PjmWRliBM%%7pu_CvcHeB!@K#5By!)a-p1NoT-7%K4VH`w zQKO)lc+xzO%^*URK*O8<2d0t8?saF*FAuusUBYUHG$2DL9}1QxbiGUHkiQB8EPfZE z9Sx2hV%33V9#Q99yA-V#pjq{ndrC6OJ7EXk1Bb>kJ99j`M`6G=-f074kZsTg=Il9w z=l-RFCh)n1)dQh6inP2tjgR_9$N1Du{yTgi>>H(MwO1JvqvtN3X20*UnN^T`giqzf(Chb4R5TK!n>mlR$Q#)Haibu{;(_5e9q(`o zCV_#08^I@fPX7)h2z?&oHp_+Gn%lS$`OErh-9vpWVQxnDZFH+lKGBUVzAv+;dczeh z=2un@o6R4maiN5~`9gc>l%iM%CT`6|P-=j*Jiv-oi|x20=Y8H03+?r>AZES!bsD*b zjZpq<*7k4*sW)k+uxvUtaI{On``*Y{m(%Q%sy{U0@$qEiFzK#V)}}uuX`x9k-mp%d zq(?{J3HSuy_3JxxB`Q6af*#c^r5LOSQ=RN?J-~97Shkyg^R)%3ifpuEbp#u>^V2_y z24?dT{#^~d9rStHR(I8m5~_}_&cI^?jsIZ*UdZW3Guu$+?mX^h@YFTUg`Ag!8#T;} zC!6(5^v(Vd?>(=s@mVUlr3ZSP!#%keaA{*BZnEc|;1$^q!Fjpe&^g(~nD+A|K*AX> zllBGx7~n1TZf8@dA#TPJ=0zi(uC>unwB$qtr0<(Kib0oX)OBguf*N1WRt*9s&WmZ3 za#+FJ#P?3u=?I&g#;qPiWb~c6@FtyS6bDIuOxa!1Of^|qR&sbwtAe^4M7tL zBW(cQNsrA%4xGOZ*lYnnQ@^<~N3Rv&YGRVEsFP+Y9|r{$F1~8C?|pmEkQr+YeBSz3 z>_9$EKAk0y{B``laqzkmMv559><(BPOg~ly8_=lt(kVsPYNolnVB_|TuytDmKuG*+ z3(c{uHPZ(gVARkFgE8*ILybj7=A`Yr$YB~p_Uu;c(WMx&bS0HCp zMaoEUaZ~6_D|xd=)0WDYGRzUBDYvaVMxp>f<&$zAhBJPP;Uaz0q)m^QA9_kcIMrk$ z#}aloEI;!XvpnGv<(t2fi3Vp>?26~iAP)v)E9EZSg?HinaWawyY4{9ldA~Uq4wgeq z>en9rgxM&3zGQ0?rwt0 zc-&(HhErKct9N#3SGIf5*dR?&k)(34*xErRao6u3Yx};Ymv1J*@u|7LQ)^{WS%yOkcTuzl;)LvlG zobBljMEp;>QXxLJ#MYr&$8_50=4R;t4}IkmJ_jFqEuYvDRW>5c!sh13D^fDFTx5IH z1khAqDoQMJWE;IXWwcYYLEe%qpIh>aBpTog+hBBz-Sqy(A>S_!khEa{`mfT)6`Z>f z@bUSYnPq$ajrV~esBo!y=?rC}yM&0uJ@84uyR|n3$yVFR@RvYOO08x3>pRb^w`djm zZId`Ttak<9r+2A6dX$;Bvt4S^5(WnR;Y13X2njiX;-20OXvgr9ZZ)3{qVWEDSOG|# zr$GW7?>lpW0@)D23J-M+ut|KXS)ncuojy2F5QYH2NeMxmEHFex6R+x6idY+xE|Nx- z)VAivBh%N{SG-GHiDZthjJUlp{W%KIoCN6@dn=~)>JgAU^9KzW_0~9`y{juYX-I9p z9Z6?DRjMtG%BZnuYt$+?dnQx6f5JHFI$f<*t5OP#@_b&iW@|qeZ>)+t*3|pENg*5 zrNCWhN`mi+GXs+mflp-JS2`UC969SN=nTMNGPM6?jkuTcawOvSCn{sG_@N`?ctM|8 z@bB3%o+sBtXs+K4@+Wsf&6CeK9$MPn=jq!E|ip%xSz%UT0Fj< z_dcCC&+&==I}ySY0&LsNGM7e`A79bw_5Fv^WE35JM*niXk9aq-Rc)73rFL$8h4PEGjINYmUP>_WuN_key7(6f+^Z zyDHTZ6prGouWdG*BPX#fRu@e+@|x+S~_vo*KNT-Ek{OO9!$SCn5)cU zfy=eJ&wu#Y^IQ3@r<8+(L#ljXFMo-;8kk>E>6?-*i@mC!pC1csh$4dH5fiwgwl@C> z9y^q<8q=_#guOEH_Wq-4N=;)#&w$uzU~l~Spg+lu>q6Ks><#BQB&A{|;0wU3lRAWa zH`ejHhvTTGu-cbwdrV4AAgV&W?@lh#AO8Mf29Rd{DgJ0kQI!Wv^+F-<`a0;phSIo* z-wd+Lq0X(5e;Id2<-wdoWry7lB>=#0bZ7G4f=MF&2-Vp+#pghRKV?=aat_y5eAV#BEvD?U)d@$+AXIAf!u2$gz?s6#xfQ}};KZ$^xTo*U zMoZX_M57_I_GyuL6kq#OrNc2Ev5!4Mzl_vYg_EY0exGSPPsZ~Lep*srxHt=e$7Rw| zX{C6AK>OwB%eL2e7GaG%ky+aqPY`f@a{Oe`jb|E;i8YeAD)HPwu~kz}4+^h5M0ZnZ z@}8=`wpOXEuFmc5RAgsT4Ppa`z8z3*DlgyqtXLxQM08k^@`CarlxZQ4M)$;zGrQO+L`2-cf9s;t!54;`S}t<`)?e?N<6%yYvT#eR?*`?CVxE_F zHhZDPt!ngNwW-mNwPZ!e4JNc*ymC$l&FY+G^lV^jG@TAnzrWp!>j9+9*=K5&+zjuI(rUwk`TC-j)8Pp?fRy0?r*Jd&|HxOjC1Q= zu=jb}2`CzIP4giXzX`%(YIxmnJIj+STy0;Bj3Amg6QY264lNw5)f$r)s}WT-@YqlR zpH$fm4-X%n{+Qj`T;26#aVb!p83|es;o3G;4B6aD&fGKY{g z%k@8IdCL)dIgV5&IPTNa>fhG1NR3w`U8|KZ_y6Pgw?D&PagT9zt?B*FeuU!dIkWV4 z)vL#wZ^&=e_z^;H*@N~Q)_>bxj}c$yQE>6gBCsD^H0>@Nuan1H5-GW$+_A)6I2;b5 zT;Uzdy#SxZhs_Q#hnn9KG;s!N`u*9Ax}>)CIz3yvyZj73z}?;51py_A5K9tq|G)hF_s_n~KagPzj?Q}48V{J5mq*S!#7n){|-Pi@1FDU_5gNN0%dv%f_&Nl` zQ2F1tsE&vZmbN0f%ufh~CSw^j8WVOe7Vo5Sl8PKta3%A_JVI?4Do6qY*!PZEQ71uV zocRyVvB8J69UWIl@$93z@9&I%#zC|3UTfDig-t1Kc$cmA!8$W5E7>;Ztb_GSbhvx;w>J&!TZdd|p#RncwHH~Ek0z7>QKryR-rVL->iDeP^RR=1?SCxht z>e6`NO$h+p-V#(QHsA@} dJO5>GL;$Rqh4e*q*-v~8KwJF*vQE_o^*`@oD@*_Y literal 0 HcmV?d00001 diff --git a/miniprogram/images/jiedanchi.png b/miniprogram/images/jiedanchi.png new file mode 100644 index 0000000000000000000000000000000000000000..16e2b9fac8c4dec75c8aad056a74b92feed38309 GIT binary patch literal 25039 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 literal 0 HcmV?d00001 diff --git a/miniprogram/images/jinpaidashou.png b/miniprogram/images/jinpaidashou.png new file mode 100644 index 0000000000000000000000000000000000000000..b54a97122b6da53045339ad48220c0eecbc3761e GIT binary patch literal 5385 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 literal 0 HcmV?d00001 diff --git a/miniprogram/images/role-switch.png b/miniprogram/images/role-switch.png new file mode 100644 index 0000000000000000000000000000000000000000..bbd4afe5695cf7bb0f42f0a65d603134287d88b4 GIT binary patch literal 5301 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 literal 0 HcmV?d00001 diff --git a/miniprogram/images/shuaxin.png b/miniprogram/images/shuaxin.png new file mode 100644 index 0000000000000000000000000000000000000000..15ad08d4509963a489aab4f4e6291e21878a4016 GIT binary patch literal 7937 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 literal 0 HcmV?d00001 diff --git a/miniprogram/images/sousuo.png b/miniprogram/images/sousuo.png new file mode 100644 index 0000000000000000000000000000000000000000..2a8f235f4bd48378d3f478aa85a88b113d986d98 GIT binary patch literal 8059 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 literal 0 HcmV?d00001 diff --git a/miniprogram/images/tuichu.png b/miniprogram/images/tuichu.png new file mode 100644 index 0000000000000000000000000000000000000000..01553b5de70648c3fe70d034cc4256d6eeaab0e6 GIT binary patch literal 5846 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 NhNn$+%e1NC{{!9gJtqJF literal 0 HcmV?d00001 diff --git a/miniprogram/images/weixinzhifu.png b/miniprogram/images/weixinzhifu.png new file mode 100644 index 0000000000000000000000000000000000000000..f2551fdcf7bf13f04a4a61d51b5ef183ad9fe0bb GIT binary patch literal 7924 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 e21!IgR09Ccq{J9PdyV@50000Z|qu literal 0 HcmV?d00001 diff --git a/miniprogram/images/wode.png b/miniprogram/images/wode.png new file mode 100644 index 0000000000000000000000000000000000000000..1fec6b3a6c8b2b04f7da9c4c7951837a316b0561 GIT binary patch literal 10677 zcmXw9byO7J7hje|mhNs?Qc98TbeHb#kWOh4mM$e0De01K5G0od0YOT-kxr!%e*697 zH|NZ}b7tn3=YBq)`(icKU*lm@V*>yHJQ!3#8`X}W&SCH~)K%{DKt2FK2!JWb z>iVM{nPHid&N4i8VhECvS*4qu^2L3YtY_NyJ&_npG-tM^_1F5dkb zcMSaj>VRvRx!8y4Nsg#69Tg+y)*a{_H~UJnPYTVkV8VuQ?!6#dEJ zukveN)^&SD16W|3LNJzQW18*ShYVtts;T4e24JR9QTQ*Fb8_xVOgMmLL^4br_A|^k zYfw{qS&ln!9SUYuN_;n#W@es1XbIu8vU&CQ&mn2CzFU5=2&`Rgx_qrZ!l-`qyC|?k z0pVpns?BX)m$&xTyQ*HbVBHtU)TxZ{(JUIA?6P6s`}5o6Y^1c$>hDumsHe`C-fb%B zp5lFh<*8Hy4UyN?4qOsFP?|lT)|R zj2A6t?|V}PuQKftZ0~o?>|=NT2t=sp&_{o{!p~=v{~k*NK5G-3b_U{ETU#><36bMI zL$|fJr$}Xu4?%+Y5h9Lo)Zrvc-917cxg)}~y!*>!&yr`^p2*%xeK^R! z`TB7E*epvUQ30y19<{gU0995F%My0K2=w(L08zpqi?G957o%A(dvSnpF5o;F+FLp4 z^q1xgziN^6*;@+UsNAMQTh?c6t-=4q`iF-8Y(rI4!o~eg@;{3T%jX9r7t_Kij!v)f zH^8jmCLjImMJXx%?Z#xnug(Oj{~XzxTrNMzPgPZML!nSWr#XQ^t+`K(P1rpX5^DYH zP0wS6BkfS6b}F9_;`Lg~UEjgD$qf~!t7e`2=jCNnC=9kSL~BrE>iJ(6W+YU5(pUB| zm_`)8i-V&lJ~^;;V&1k%Jx=Uz@uT+1)yRY5R*ta$F49XumSdvk<|KS%dT z7l|Qf3M-ZMx1&pzj z+mgoPzNmrSas6p>UH^21pDZ>zC*|gzMG3IuHoz^Vr~xuYVkMvBv!_30-y-+a2x~>ch!qs_+Y#y zJlQB3Bud-JEF@x>4+hyP5!d9@b!kZ7(}FG5;UFvbS47MMw)WuRCv9K7-8#kU;`7@2K2R+ znn{Z*j#O79pN(y}50jj#F9zB|QUpu3!{qAKfE-zuNP-cOK`=4*M?y5CB*?JELYO`` zTr9dT7zdj;!d21}9*xDz%!q>^#34F<7xKl2#>C+8>Uhb;Ze@TWB7THR_oWfa93%4x z&awDBHE~PcI(EBS4-hxhni17&@-D8;7!QbEF7|{>|GpDFpUI>d1lpD(4zZd&#C&$a z6|_ibFdq<_LkVP+K_0^{>a>l*=V<6Iu@mp`E?~V?P$o8R-It){T!>!cd^51 zW}Tt9_Z&KsZ)K1w2|V${Y+;XOCQ#TSy00P6y7Eb6unyoYSxV{ejpcz=8?Q?IK8ls6 zf9Biv`ad%fF+8wlr&)hPN|-<8{60OA$2$aoL%{}7@dd1+jmANjFTREW?XRLxye8D=i@e(!!y4(JC?t<8>V zZ0Orxvtt=5eBiGyB{*G5By4%;@9#eYIZn1>;okTU%e?=5PLlJptlK@3V~ggSBuoTL z#abxyJEc%sCt2w5FckUEQ$OiHZE4Ko(Z)8yxmVcMLpU0^Q- z1Q^AitKc8&xE;dXb7c|p6q8F!CTaQYk}&JB-?)pKdu0axd)9Wp1bM4WMZs3WI2IT7 z7N3lpoklK>x7;)kVM@dwRjm0GC=_1QaubTYyQ<>ZHu@qpo*UZhY1>XXH}(N{@~0wiLGH+P6o8j@6T4k7JxjQz?{@3;dT(Zm$N9s; zzVXM3EJ1bNE^a7sdYUgj91^z9x7oy9-JPFytBc4?JYr&RLGa8`E zt2@jB!9i>bM=H+j#EA?*5s7O1*?y<1$Nc2q-U!M5sCKdXZCud1vV$p)cq#J{u)sP- z-flu+GY>G2QGwagRxwDQh-|l}@vc6~gJZY@VJ8N;HOY7|5%qct?0Erp4QP304JEj^ zv=rT#=w8Lmv=eCLy=-4QO7OPewkzmI15>ON&-k!sozDELs!>*j;+vPm3O9r_zRks6 zn_eStI6K7;ZRLqwK!t#0!5&_UMz$FBk>vvUXn=jwQEgXh4#ux3))oiX=`2-WmVo=p zWnu2;2txoqRB#|SN4$7O)c^$a^z^K=pP<*`T8-0ewCQfWT;wk#yZP7d zhqgqen(VnT-|okkE&5jJCF|NOBJLcn$=OWn-N1q+gpD~h2MIcqrW{{3BSdCag<}$k zsU-(&wQ(eDweGZ$ro5_DC|}WFQbF`nshWf)rS|@wC+Q-=KV4(j75D}S4SD)UfzKdi z$_RUxS}6gE)AZ-CbylovXnB!z8pS_I$rth6Vi7J9cl@hA2KLDOXD$F zpDEYj)mvCvqWLW7EF^2spW*%N&+2^fU)ywE?>`C+Y%mw)JB;<>b~BaV(eR&^9)Etf zw`{tvc2F@hGn@W^aBw*6z|qhjy>5Y-kWYfJx{qF5dYQ`qI#Ic8{`hWZXdk~Vju{1x zkaw4dvIn9*_LL6Ii;Y`@9}iEt&3^|eZwtS_LVn&+iF8^Rz6q|< ztJLr5dS6pbWM|%uPxY$?tqWQNOJQRfOrSfwLn;cDk?9xrCV?ueR0JoO0fmlMAMW1` zco`96*w>`-S>TJA{S=>Xd?_H~$4k6f_(L}6Z$Qk`>2mXINMyER5LZK`CZs27j!Lyp zME${oe2_^?KZNNdD4erdiuu!-=sd(APjz_|)fJQt(9Uvgkw*)M%)vGBB zjzsyPx9R77yMx1W5;_|F+A!(e2kxmgVMWem4lyxm50BuJWzlr6cBhxUB^eIGoo`=% z%H^eg6ZeTsRf`E0=2|735%v@H+|MPtd}~PV!tOe-R2GFQAO1{8*SW2T5q2G$Rpgcl zltB9I%(y*fItsbH187^!%PJkbB3ZG7Ua?|tz{R7i3gRW+V|V58<0sHbK|XN#y);e` zbe@xOa44JRIq8+#wY8Vs9H4}DlJb3MNRMVOE>YRE$%CG3V5lHme;05Bb@=X>CDI zSyaM%RkI;Up9u*9zI{XdA_8t;tN-L(b-+zm)kI7E0Kxc3Z_m$DsIYI&7}tUR&bMz~ zi^XzaGxCg4N;ujUd3^L|cOts;-F5FQbJuS>3$&n2A7we(z4FW9R^M4EWy(jjbf<%$ z7d$-blv>GlO2qARr3wq*iB23V5T-OpNe!A`H3ha*SSCVMZ|~MJ%tIz#D=TBuiu-;z zRUXe2z^pTgTv|BCz^i$aFvrZpNyM8Q4|rR#cSwrAFc~?gHB*T1r};AUH9R>Yy5Nj7 z-AM{7u7h5;F-L5qPqkE4o?PN5+r-nRw#0d%rka)z$nAc*O_95BPJln+( z)+fu~9w>_-#dWLr(&6xxij0`)B-&E+@|Mqr(}fxUa!f(-D*SOfL*-aJGYLY)_Vj8DD`X0YAAVf&|%hkIiobvJ`0 z;`f)|(hnT6JumpuvQ0ez1N6xxEByW94d9nWz zD*B;splj^#7oc5N`@Z6+!G~NzmSwfH-$4WGLKv^H2!zrAJ^@~JL>Q-ey#IVFh|gUO zXvISIFwIE&zb*vR$rH)7X?iskx{ZYMrMydrCvVd)@%=~&mUHLV_*t5n+rrVx2C&5i z#8?cdr`q{=fS9q61o?~;hj@dpeY|l?R0K~rD)050f~a81^#fZvV=w-`7L#}9_c_zl z)%K(f0?T~=T_n`8!)%k3;aUEL-NEm``F&h{wxIyw!?%`UsJ7BEMHa$3K}CRPhUSCh zg~|ieOyu%Tn^vudGTvk?>Lho?MLE(>!s9SjetW5zI>v$awl$l1Z_r zqqa7H`giXocDAfq2CBRBV`>{jMy1XO7J=Sn-Z5xCKgYWaiB}P<>4SxX!kL)3xUffT z^CWT7nNSX32j(3$rbo@|a1osm&v!yJCB#cmx}Di~utfe5C5)c%?C9%BIDjSgzKQJl zKDr!|2ddrTrj{2K96a9aWJgdv=w7B@l--}5Wu32&=R&#ui<2MO5^G#t^9T>V9%ys@ z#{3_(mUtSfy;G^wKb~>Y{W)W&KT?gT(exmSNa6=BpMr)JelL@v14B5um(>a4nHS>? zUp70FCHlHkrc=nmYGrF(8-suNdtH`vv6I~gY_ktxRPxI88@JR=6? zfMrMymN&cAs9I878rfxnz?kD$$mcV710i9w+f@6~BXm782d`=lO-h@dTP#1&gJEG0 z55}0~dOFRI6#@|~?0W|Eb>2-Ljg)4*)xn*iR)b~bbtm|am=~;EoLPQ!vMLg* zxWCZ&stS9#)qXnIdG3^0?4RQXGj^&NUEzet?z*jPtRz0`N#9~aYIHxLjS9Pj@w~h0 z3nQzv9L!$(&uChe8G*?)U4&xgTyN9DTg(1*oBTELQ@QqpoP627CNFH!k_h46N5Pd-q^xw3LA6)mh-Md$+2n&x2tydTn%te&p_A7l5Vv zj(W~*l-TVZYDCmserL6a&VgQk54>~(Edh|I!rtp}^{W5shi^)I` zRm&cX!&ES8HS*bq-+P(GUe2xQzxtFx1Qjr{$s@%4h}3bE?-@egAMQJ=Q?4mmsdB$poQ zd(=tN_zQKR#3Uqtv|U_|&htVt9!C%CR61Y2bQ9shM{LEr56W@~wuej8V7V^&!MXG* zMARmjxp;w6U0st;E7z7+%hFbx1OoYbS-Y|YXCBxw3l7?!r=}kF?v<~#-!BYErfj2d z#B@z@))U>+&R%Itq^p;4XvJ(rPrg-NZ|xrnxuKes^()saXoOCkVFWmoJoq;uz|wQ|JdxFsU!yq)KGRl0%UV9i)_zFAc9}}M!3IU)<9*wK5Zw_yADA>61O@@12{^C2;4DKF0k(3Y;r24$v1f`^JHqPfE+r-ZEf;eXn0h# zHL~@Nh03+-PY}xCA7QO6cy6U1L+*dj2P44Oq!&?(9qDy z+9$x?!YPl#S_#b!M=By6Vxj(*_IhA{s0L=NmE z(22`=YzFBUQr_drfUH+xrFu2XygPpi%i?X&+8mRQTTZjWFkdBG~5|AENi zXCX$JE?3u*Ae>iDtbGL`z3b{l&R)WYfCP3vULI9dSxKwrLVP4|xKit!bSN33^Z1{~ z^OEO@ioXDv%H*qM32Al)`kYm0k*qRs{qqsOBj_GndLNkQ%_J^0Vg_qK5nqk?ftNO7 ztWagdU-k)KT9JPH2mwPQBcq@UlsH9zjVAU7TSQ5VgH&^;AUgk77CI!}YkNJETvE(8 z<2eUJ7KRari zxG2%Y1f4l^b}))4=1B`HRO)xJYQ`&+LJAImpONP0{hyPiay{P#osVBNdsKkXHikFJv4SSSKfSgR_Y*=@tfhfEgLD9kT%bM#+FG+g8k;~xGD&U znAqaAscpag#?n{p>AvT+mrho>nir$RSmPX zCp(w3E4hlv5G=Ei2ZzHi9}7hYG&Cq*d1nZ^TW%53kaBCP6HQKDia!CJwO1;iNnG{o z6e3o~#;OcHwo4k4YUL9WpYg~qoaaHzo-zY%AGQXuo7f%5a8yo9L)8!NI&_e0v`5Ix#=G_7ORckTC_!c+R zD-qr)*wZVu_yGG$yPPBLcku3w0fIIw2HIe^6{UrFee5#~z<@wCdytq|h?JCYr{9!7 zw@_3k$CT~PLQ^Rv!`Lz=kd5mUp>g0y!~?m`Ao9s6Fbcur-Ho8n1}b{C>Wb`jNy zHbAdVo`w#*N&_A0bhc3h$_=F;MPV7NM8H8?Dke?EGqvoBSw$0aM^_#{_E-iMER0w> zFU5SP*$RBUN;ViG>_zNX-(%xfK4b^9_+*D}qU%g=3wrf5MA*uGTTaN&|88Tl%YB+h zn#F)qb|T;&s?3hC)(0#ejHI9xW)R$`B_f93NF59wf*>HFK$PAG@#8_oTa#6o$p=>; z4nN2i4)++G8wrn)5GEy$AK=ilPpQ{D-rwg;jo3%|e?0t*4$sI}sYjm^D1k+qKK3R> z&5?rtOUVLcS=5ol5YDttigq1KC?%1>`i~MS1#@Wj5?!y+T-)HMqJq%^tiq}Y35^ik zUG}V1MIRxr!p?wr^Z0Ws4YEDJmkIy|#g^JMTR$9;T#C4`hz?D{-;#4Hn^u|#7m^&88?F_2#Xm!8l zT^%9`t|EGmiuaQQK=9ghuqrVH4NC>_kDCMBH;*Or9jrg8Y7~Cj-6~jpU-8Yeu!Im5 z_SyO=G71XL7VM40rqkMzlFA4bB&vt9dkc0tFMQ%Cl1CU~inKCSA+}i(G7zFs@O#Fj zH!YgElnj^)+7=&ww|<PA^-a9rbhpBK%?H*WXNh#@Uk?cOw&>8S_0&XkLK$eWKa}b zoXL`(k~Z%7>?{!f>jHa2GAMO%UCI7uiy!6@G)&`d{dmIFUR_-~lV#IVt8=kU%JVmk zt=MtxN&VgG@bP}bT2)mjTyIn^Aej&dB{jEXkAi10!A}!ZG&EXL?|N_FeytOPn^i0O zAwx0o)3%EW`s{y|XFZ)*94hYB8n=;3uFjTeg#eet#Cqd(bfd+ z+l(q2^vdFV^k9S)DShE)oHGZQ@M{6H}oO~Ua8-2%@m@XYN3F5Gyd7^ zc)59Lv5nXQ(9pt$su2O@Vsvv=hX^?gz^x97`U5l{H?%P*l0hW59H~qzftS7c;f*b9 zH(#+Jaq>Vme$aO+V2v>mMyPZ)nHd5iD=XXH*132H&DVdxS}P}EM{c0s-##QkTxcW- zFvL@JKu6WXk#Fr;?VI)#W)|bizdSHBD@a0MVf%ZnHogS0^;jowZ-2*Y!6&lT&3Pf% z>lkCG1V{yJ{nsy6l=?Xvbl>X-O*?y|G{-#>11!-&Ozy8Yue|I0TKlt44I4oo2#by7 zzX|sXh)hf*sB0#n$M)rV4PM`sV`gEwrQ&%Q>ay8-HZp};E$2vHp5roG+t4Xa7{7Ue zrs|`|u;y8k|Ed1={`A?%{jGvl<*W=3fq5^je7-3oArTQ8o6cin#F9`|cy_i)p%=zX zc~;W<%SB7A2pLZlQ^dqP4K7q1m3~IRz|_iZvD|DU{vff1X^u=34D|OuvqI$=2`H$r zu#hqN%C`=8!$b(ZCf;&>Rj<;R=hVx|+F;|L?LD>gO%0?+0hPm_Hd9w?56k4Wwu7@I zNjyj(#GqJaWh811?_=QRwb2x+6XMO~&>AbWn^WAe{(Yt8wVH(klP**qw+Daw%wcpU~f85c9DTY*TpkSJt}@MfBI zx2zcnAGUmxhAAm?#6z&mqp3MTV!Zme(kZ+1$lWJ;%zzkV5H!yPGs zb}@hiY4uzQEOHh4Dm*igCxxO3;ca{Oe1Xl_weDKpk@#n`ZE+eSIL^a76k z;GA2MpxcGgPaLzMMx?Nqj0Rl7n8d_rR9!>v`;LO4(5XgJkW$2Ii~34nW(bePIT(-p z&?6I);fx9)rFQ|d;7m~iuXr4`P(0^fNb&dP(VvPTWd^nMwKgccXT$`b?hr|d#EGZ??W1o!U-tlA5(g+>NdOCq$NBt#cg(EYiRvn%PPFH z{V@`WltJ=v`}3fX)Re+{e=G_7`GI``oll!)%ys22Mt+;!f})BqYFXq`o{>bnZPqEE zKP5VSEKW0JqP_!z{0_hBNh%b6IPfFu2&4f=!6h^wuiy4)>5_j*q5zV|W1wm=xcApb zQR9^cz31|n+4^VYrFrTOzna^Hk7rFiKbOVC5GRBFxXhIOy!Ng?zeEvg=R1#KeqC5w z9o}JqMq&;B)3pVY$sG+L;unfA$Y6(#jj0;eyKr)w@Dq4E!)eKamdKmktLHqL(R^** zD2AoPtqk-YR@d}HdT_(S!se!HW=P)O6Bz!PjfgGtIv}6O!({0EM;=jqPa|@d2bgD& z&(8qUN_tU#QK!Tl{T(fm)7i`YKK1+3v3R$HW6u;>j%JsEp9Z8S3+1iSk;bXP$Kt*x z(mO+$Fdx=j`5y1Rsqr^A|8|Y|H&YTBQKhS-pl@fHHXrO0m>46GH96u|*sMcM=UeL^ zQkn@4eJ-hAO`53*OVu-aFSO{dblzR75<8>q!GrCd{8p>4XCtuIt`3%j!+)?D7AXWD zMdI+kUDUm)3z4Rjbm5P96lCC4_{Xk1L`p^xIy_yvzDqT|ue$Giw)F|-5tATYd}U!o zba7Sweq5tEv+jC+M2SLYx~TeY>P+P$WUkjcq-3`^v-?N2=w{`UT5y-y{R7>bIVjeX zbemk8^*J-;?FgfPw*|w^R{Da+)tDo+2t6cr`&w(j&8M4icziq((l+Snv1Xoe`_Jzz z@YfIiH~k*-^k1n|eQP19TpByy_1tE!&U1YJ+>NiZB=3HKmV7fXD^KY+&hNJh-0e5<}`jWjB zegi}0T{GLZB5yAsE=wI)?gxfiI2g6<<9!jnRNAtl z?&2GI&l1}#^j|U6c%-E@d--n06unD`gG$JxBTq6-+Tif{GuMl@j%AZYOwe6>I~!8>IGkihHbQ zZ?3MTz67f1nu0#aSmKw$zXpcahpt-E7ip-hnJud-3;aW8iG9!NEoP=}`Z)mO7;*WN zMioRFa9KZrMcaWT(*=ZEFg+DB+vhXZqHP!hOEssj40PgOF!K(0*LCP#J)!noK0Te=OQBl8v;WW)I$$$Z VGIQ$sKI6YzFhzBR8ad0b{{fX&GO7Ro literal 0 HcmV?d00001 diff --git a/miniprogram/images/xiaoxi.png b/miniprogram/images/xiaoxi.png new file mode 100644 index 0000000000000000000000000000000000000000..e6cda270dd07e48ae45a96cd56c2e4aab2b616e5 GIT binary patch literal 4055 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 B8$tj8 literal 0 HcmV?d00001 diff --git a/miniprogram/images/yituikuan.png b/miniprogram/images/yituikuan.png new file mode 100644 index 0000000000000000000000000000000000000000..62c8fee3310a5a42820b5fdb88b03f602b88d440 GIT binary patch literal 17098 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 M07*qoM6N<$f_Anl4FCWD literal 0 HcmV?d00001 diff --git a/miniprogram/images/yiwancheng.png b/miniprogram/images/yiwancheng.png new file mode 100644 index 0000000000000000000000000000000000000000..e1c333e45c891a9952554eb6a15a16bb5542ecbf GIT binary patch literal 12372 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 literal 0 HcmV?d00001 diff --git a/miniprogram/images/zhuye.png b/miniprogram/images/zhuye.png new file mode 100644 index 0000000000000000000000000000000000000000..b2fe9aeccb7ad37e70ee4cfb482cee282bee1929 GIT binary patch literal 6269 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 literal 0 HcmV?d00001 diff --git a/miniprogram/pages/cfss/cfss/cfss.js b/miniprogram/pages/cfss/cfss/cfss.js new file mode 100644 index 0000000..abdec80 --- /dev/null +++ b/miniprogram/pages/cfss/cfss/cfss.js @@ -0,0 +1,100 @@ +// pages/cfss/cfss.js +import request from '../../../utils/request.js'; // 向上4级就是根目录 +// 如果有 COS: + +const app = getApp(); + +Page({ + data: { + // 统计数字(由接口 /yonghu/cffktjhq 返回) + stats: { + fakuan: { total: 0, daijiaona: 0, shensuzhong: 0, yijiaona: 0, yibohui: 0 }, + jifen: { total: 0, daichuli: 0, yichuli: 0, daichuli_0: 0, shensuzhong_3: 0, yichufa_1: 0, yibohui_2: 0 } + }, + + // 当前选中的主标签:'fakuan' 或 'jifen' + activeTab: 'fakuan', + + // 子标签状态值 + activeFakuanStatus: 1, // 罚款默认展示“待缴纳” + activeJifenStatus: 0, // 积分默认展示“待处理” + + // 搜索关键词(订单号) + searchDingdan: '', + + // 刷新触发器,传给子组件 + trigger: { + fakuan: 0, + jifen: 0 + } + }, + + onLoad() { + this.fetchTongji(); + }, + + onShow() { + // 每次显示页面都重新拉取统计,确保数字最新 + this.fetchTongji(); + }, + + // 获取综合统计 + async fetchTongji() { + try { + const res = await request({ + url: '/yonghu/cffktjhq', + method: 'POST' + }); + if (res.statusCode === 200 && res.data.code === 0) { + this.setData({ stats: res.data.data }); + } + } catch (error) { + console.error('获取处罚统计失败', error); + } + }, + + // 切换主Tab(罚款 / 积分) + switchMainTab(e) { + const tab = e.currentTarget.dataset.tab; + if (tab === this.data.activeTab) return; + this.setData({ activeTab: tab }); + }, + + // 切换罚款状态子标签 + switchFakuanStatus(e) { + const status = Number(e.currentTarget.dataset.status); + if (status === this.data.activeFakuanStatus) return; + this.setData({ activeFakuanStatus: status }); + this.bumpTrigger('fakuan'); // 通知罚款列表组件刷新 + }, + + // 切换积分状态子标签 + switchJifenStatus(e) { + const status = Number(e.currentTarget.dataset.status); + if (status === this.data.activeJifenStatus) return; + this.setData({ activeJifenStatus: status }); + this.bumpTrigger('jifen'); // 通知积分列表组件刷新 + }, + + // 搜索输入 + onSearchInput(e) { + this.setData({ searchDingdan: e.detail.value }); + }, + + // 执行搜索(按键盘搜索按钮或点击搜索图标) + onSearchConfirm() { + this.bumpTrigger(this.data.activeTab); + }, + + // 清空搜索关键字 + clearSearch() { + this.setData({ searchDingdan: '' }); + this.bumpTrigger(this.data.activeTab); + }, + + // 递增触发器,子组件通过 observer 响应 + bumpTrigger(tab) { + const key = `trigger.${tab}`; + this.setData({ [key]: this.data.trigger[tab] + 1 }); + } +}); \ No newline at end of file diff --git a/miniprogram/pages/cfss/cfss/cfss.json b/miniprogram/pages/cfss/cfss/cfss.json new file mode 100644 index 0000000..4ca406b --- /dev/null +++ b/miniprogram/pages/cfss/cfss/cfss.json @@ -0,0 +1,10 @@ +{ + "usingComponents": { + "fakuan-list": "/pages/cfss/components/fakuan-list/fakuan-list", + "jifen-list": "/pages/cfss/components/jifen-list/jifen-list" + }, + "navigationBarTitleText": "处罚中心", + "navigationBarBackgroundColor": "#ffffff", + "navigationBarTextStyle": "black", + "backgroundColor": "#f7f8fa" + } \ No newline at end of file diff --git a/miniprogram/pages/cfss/cfss/cfss.wxml b/miniprogram/pages/cfss/cfss/cfss.wxml new file mode 100644 index 0000000..03e8517 --- /dev/null +++ b/miniprogram/pages/cfss/cfss/cfss.wxml @@ -0,0 +1,68 @@ + + + + + + + {{ stats.fakuan.daijiaona }} + 待缴罚款 + + + {{ stats.jifen.daichuli }} + 待处理积分 + + + + 罚款:已缴{{ stats.fakuan.yijiaona }} · 申诉中{{ stats.fakuan.shensuzhong }} · 成功{{ stats.fakuan.yibohui }} + 积分:已处理{{ stats.jifen.yichuli }} + + + + + + + 罚款 + + + 积分处罚 + + + + + + + 待缴纳 {{ stats.fakuan.daijiaona }} + 申诉中 {{ stats.fakuan.shensuzhong }} + 已缴纳 {{ stats.fakuan.yijiaona }} + 申诉成功 {{ stats.fakuan.yibohui }} + + + + + 待处理 {{ stats.jifen.daichuli }} + 已处理 {{ stats.jifen.yichuli }} + + + + + + + 搜索 + + + + + + + + + + + \ No newline at end of file diff --git a/miniprogram/pages/cfss/cfss/cfss.wxss b/miniprogram/pages/cfss/cfss/cfss.wxss new file mode 100644 index 0000000..4cd5d19 --- /dev/null +++ b/miniprogram/pages/cfss/cfss/cfss.wxss @@ -0,0 +1,121 @@ +/* pages/cfss/cfss.wxss */ +page { background: #f7f8fa; font-family: -apple-system, BlinkMacSystemFont, sans-serif; } + +.page-container { padding-bottom: 30rpx; } + +/* 统计卡片 */ +.stats-card { + margin: 24rpx 28rpx; + padding: 30rpx 24rpx; + background: #fff; + border-radius: 24rpx; + box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.04); +} +.stats-number-row { + display: flex; + justify-content: space-around; + margin-bottom: 20rpx; +} +.number-block { + display: flex; + flex-direction: column; + align-items: center; +} +.big-num { + font-size: 56rpx; + font-weight: 700; +} +.green { color: #2E7D32; } +.orange { color: #E67E22; } +.num-label { + font-size: 24rpx; + color: #888; + margin-top: 8rpx; +} +.stats-detail-row { + border-top: 1rpx solid #eee; + padding-top: 18rpx; +} +.stats-detail-row text { + display: block; + font-size: 22rpx; + color: #aaa; + margin-bottom: 4rpx; +} + +/* 主Tab */ +.tab-row { + display: flex; + margin: 16rpx 28rpx; + background: #fff; + border-radius: 18rpx; + overflow: hidden; + box-shadow: 0 2rpx 6rpx rgba(0,0,0,0.02); +} +.tab-item { + flex: 1; + text-align: center; + padding: 24rpx 0; + font-size: 28rpx; + color: #666; + transition: 0.2s; +} +.tab-item.active { + color: #2E7D32; + font-weight: 600; + background: #F0F9F0; +} + +/* 子状态标签 */ +.sub-tabs { + white-space: nowrap; + margin: 8rpx 28rpx 16rpx; +} +.sub-tag { + display: inline-block; + padding: 10rpx 26rpx; + margin-right: 14rpx; + background: #fff; + border-radius: 30rpx; + font-size: 24rpx; + color: #888; + box-shadow: 0 1rpx 4rpx rgba(0,0,0,0.02); +} +.sub-tag.sub-active { + background: #E8F5E9; + color: #2E7D32; + font-weight: 600; +} + +/* 搜索栏 */ +.search-bar { + display: flex; + align-items: center; + margin: 16rpx 28rpx; + background: #fff; + border-radius: 20rpx; + padding: 12rpx 22rpx; + box-shadow: 0 1rpx 6rpx rgba(0,0,0,0.02); +} +.search-input { + flex: 1; + font-size: 26rpx; + color: #333; +} +.search-btn { + margin-left: 18rpx; + padding: 12rpx 30rpx; + background: #2E7D32; + color: #fff; + border-radius: 16rpx; + font-size: 24rpx; +} +.clear-btn { + margin-left: 16rpx; + font-size: 30rpx; + color: #aaa; +} + +.list-area { + margin-top: 10rpx; +} \ No newline at end of file diff --git a/miniprogram/pages/cfss/components/fakuan-list/fakuan-list.js b/miniprogram/pages/cfss/components/fakuan-list/fakuan-list.js new file mode 100644 index 0000000..cf45977 --- /dev/null +++ b/miniprogram/pages/cfss/components/fakuan-list/fakuan-list.js @@ -0,0 +1,317 @@ +// components/fakuan-list/fakuan-list.js +import request from '../../../../utils/request.js'; + +const app = getApp(); +const MEIYE_TIAOSHU = 5; + +Component({ + properties: { + status: { type: Number, value: 1, observer: 'reload' }, + searchDingdan: { type: String, value: '', observer: 'reload' }, + trigger: { type: Number, value: 0, observer: 'reload' } + }, + + data: { + list: [], + page: 1, + hasMore: true, + loading: false, + loadingMore: false, + ossImageUrl: app.globalData.ossImageUrl || '', + + // 详情弹窗 + showDetail: false, + detailItem: null, + + // 申诉弹窗 + showShensu: false, + shensuLiyou: '', + shensuTupian: [], + uploading: false, + uploadProgress: { current: 0, total: 0 }, + uploadProgressWidth: '0%', + + // 支付弹窗 + showPay: false, + payFadan: null + }, + + lifetimes: { + attached() { this.reload(); } + }, + + methods: { + // ==================== 数据加载 ==================== + reload() { + this.setData({ page: 1, list: [], hasMore: true }); + this.loadData(); + }, + + async loadData(isLoadMore = false) { + // 防止重复请求 + if (this.data.loading || this.data.loadingMore) return; + + if (!isLoadMore) { + this.setData({ loading: true }); + } else { + // 加载更多时,如果后端已经告知没有更多数据,不发送请求 + if (!this.data.hasMore) { + wx.showToast({ title: '没有更多了', icon: 'none', duration: 1000 }); + return; + } + this.setData({ loadingMore: true }); + } + + try { + const res = await request({ + url: '/yonghu/dsfklbhq', + method: 'POST', + data: { + page: this.data.page, + page_size: MEIYE_TIAOSHU, + zhuangtai: this.data.status, + sousuo_dingdan_id: this.data.searchDingdan + } + }); + if (res.statusCode === 200 && res.data.code === 0) { + const data = res.data.data; + const newList = isLoadMore ? this.data.list.concat(data.list || []) : (data.list || []); + this.setData({ + list: newList, + hasMore: data.has_more || false, // 以后端返回为准 + page: isLoadMore ? this.data.page + 1 : 2, // 首次加载后页码为2 + loading: false, + loadingMore: false + }); + } else { + wx.showToast({ title: res.data?.msg || '加载失败', icon: 'none' }); + this.setData({ loading: false, loadingMore: false }); + } + } catch (e) { + wx.showToast({ title: '网络请求失败', icon: 'none' }); + this.setData({ loading: false, loadingMore: false }); + } + }, + + loadMore() { + if (this.data.list.length === 0) return; + this.loadData(true); + }, + + // ==================== 详情弹窗 ==================== + openDetail(e) { + const item = e.currentTarget.dataset.item; + this.setData({ showDetail: true, detailItem: item }); + }, + closeDetail() { + this.setData({ showDetail: false, detailItem: null }); + }, + + // ==================== 申诉逻辑 ==================== + openShensu() { + const item = this.data.detailItem; + if (item.bohuiliyou) { + wx.showToast({ title: '该罚单申诉已被驳回', icon: 'none' }); + return; + } + const existingImgs = (item.shensu_tupian || []).map(url => this.getFullUrl(url)); + this.setData({ + showShensu: true, + shensuLiyou: item.shensuliyou || '', + shensuTupian: existingImgs, + uploading: false, + uploadProgress: { current: 0, total: 0 }, + uploadProgressWidth: '0%' + }); + }, + closeShensu() { + this.setData({ showShensu: false }); + }, + onShensuInput(e) { + this.setData({ shensuLiyou: e.detail.value.slice(0, 500) }); + }, + + chooseImage() { + const remain = 9 - this.data.shensuTupian.length; + if (remain <= 0) return; + wx.chooseMedia({ + count: remain, + mediaType: ['image'], + sourceType: ['album', 'camera'], + success: (res) => { + const newImgs = [...this.data.shensuTupian, ...res.tempFiles.map(f => f.tempFilePath)]; + this.setData({ shensuTupian: newImgs.slice(0, 9) }); + } + }); + }, + deleteShensuImg(e) { + const arr = this.data.shensuTupian; + arr.splice(e.currentTarget.dataset.index, 1); + this.setData({ shensuTupian: arr }); + }, + previewImage(e) { + wx.previewImage({ current: e.currentTarget.dataset.url, urls: [e.currentTarget.dataset.url] }); + }, + previewLocalImg(e) { + const idx = e.currentTarget.dataset.index; + wx.previewImage({ current: this.data.shensuTupian[idx], urls: this.data.shensuTupian }); + }, + + // ==================== 提交流程 ==================== + async submitShensu() { + if (!this.data.shensuLiyou.trim()) { + wx.showToast({ title: '请输入申诉理由', icon: 'none' }); + return; + } + wx.showLoading({ title: '提交中...' }); + try { + const newLocalPaths = this.data.shensuTupian.filter(path => !path.startsWith('http')); + let finalUrls = []; + if (newLocalPaths.length > 0) { + finalUrls = await this.piliangShangchuanShensuTupian(newLocalPaths); + if (!finalUrls) { + wx.hideLoading(); + return; + } + } + const oldRemoteRelative = this.data.shensuTupian + .filter(path => path.startsWith('http')) + .map(url => url.replace(this.data.ossImageUrl, '').replace(/^\//, '')); + const allUrls = oldRemoteRelative.concat(finalUrls); + await this.doSubmitShensu(allUrls); + } catch (err) { + console.error('提交申诉失败', err); + wx.showToast({ title: err.message || '提交失败', icon: 'none' }); + } finally { + wx.hideLoading(); + } + }, + + async doSubmitShensu(tupianUrls) { + const res = await request({ + url: '/yonghu/fkss', + method: 'POST', + data: { + fadan_id: this.data.detailItem.id, + shensu_liyou: this.data.shensuLiyou, + shensu_tupian_urls: tupianUrls + } + }); + if (res.statusCode === 200 && res.data.code === 0) { + wx.showToast({ title: '申诉已提交', icon: 'success' }); + this.setData({ showShensu: false, showDetail: false }); + this.reload(); + } else { + throw new Error(res.data?.msg || '提交失败'); + } + }, + + // ==================== 图片上传到COS ==================== + async piliangShangchuanShensuTupian(localPaths) { + const total = localPaths.length; + if (!total) return []; + this.setData({ uploading: true, uploadProgress: { current: 0, total: total }, uploadProgressWidth: '0%' }); + + let tokenData; + try { + const credRes = await request({ + url: '/dingdan/dsscpz', + method: 'POST', + data: { + dingdan_id: this.data.detailItem.guanliandingdan_id || '', + fadan_id: this.data.detailItem.id, + yongtu: 'fakuan' + } + }); + if (credRes.data.code !== 0) throw new Error(credRes.data.msg || '凭证获取失败'); + tokenData = credRes.data.data; + } catch (e) { + wx.showToast({ title: '获取上传凭证失败', icon: 'none' }); + this.setData({ uploading: false }); + return null; + } + + const COS = require('../../../../utils/cos-wx-sdk-v5.js'); + const credentials = tokenData.credentials || tokenData; + const cos = new COS({ + SimpleUploadMethod: 'putObject', + getAuthorization: (options, callback) => { + callback({ + TmpSecretId: credentials.tmpSecretId, + TmpSecretKey: credentials.tmpSecretKey, + SecurityToken: credentials.sessionToken || '', + StartTime: tokenData.startTime, + ExpiredTime: tokenData.expiredTime + }); + } + }); + const bucket = tokenData.bucket || 'julebu-1361527063'; + const region = tokenData.region || 'ap-shanghai'; + + const yonghuid = app.globalData.userInfo?.yonghuid || wx.getStorageSync('uid') || '0000000'; + const fadanId = this.data.detailItem.id; + const keys = []; + for (let i = 0; i < total; i++) { + keys.push(`fakuan/dashoufakuan/dashoufakuanshensu/${yonghuid}_${fadanId}_${Date.now() + i}.jpg`); + } + + for (let i = 0; i < total; i++) { + try { + await new Promise((resolve, reject) => { + const timeoutId = setTimeout(() => resolve(), 2000); + cos.uploadFile({ + Bucket: bucket, + Region: region, + Key: keys[i], + FilePath: localPaths[i], + onProgress: (info) => { + if (Math.round(info.percent * 100) === 100) { + clearTimeout(timeoutId); + resolve(); + } + } + }, (err) => { + clearTimeout(timeoutId); + if (err) reject(err); + else resolve(); + }); + }); + } catch (err) { + wx.showToast({ title: `第 ${i + 1} 张上传失败`, icon: 'none' }); + this.setData({ uploading: false }); + return null; + } + const done = i + 1; + this.setData({ + uploadProgress: { current: done, total: total }, + uploadProgressWidth: `${((done / total) * 100).toFixed(0)}%` + }); + } + this.setData({ uploading: false }); + return keys; + }, + + // ==================== 缴纳支付 ==================== + startPay() { + this.setData({ + showDetail: false, + showPay: true, + payFadan: this.data.detailItem + }); + }, + onPayClose() { + this.setData({ showPay: false, payFadan: null }); + }, + onPaySuccess() { + this.setData({ showPay: false, payFadan: null }); + this.reload(); + }, + + // ==================== 工具方法 ==================== + getFullUrl(url) { + if (!url) return ''; + if (url.startsWith('http')) return url; + return this.data.ossImageUrl + url; + } + } +}); \ No newline at end of file diff --git a/miniprogram/pages/cfss/components/fakuan-list/fakuan-list.json b/miniprogram/pages/cfss/components/fakuan-list/fakuan-list.json new file mode 100644 index 0000000..d192c45 --- /dev/null +++ b/miniprogram/pages/cfss/components/fakuan-list/fakuan-list.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "fakuan-pay": "/pages/cfss/components/fakuan-pay/fakuan-pay" + } +} \ No newline at end of file diff --git a/miniprogram/pages/cfss/components/fakuan-list/fakuan-list.wxml b/miniprogram/pages/cfss/components/fakuan-list/fakuan-list.wxml new file mode 100644 index 0000000..257802a --- /dev/null +++ b/miniprogram/pages/cfss/components/fakuan-list/fakuan-list.wxml @@ -0,0 +1,116 @@ + + + + 加载中... + + + + {{ item.create_time }} + {{ item.display_status }} + + 金额:¥{{ item.fakuanjine }} + 理由:{{ item.chufaliyou }} + 订单:{{ item.guanliandingdan_id }} + + + + + + 点击获取更多 + + 加载中... + —— 没有更多了 —— + 暂无罚款记录 + + + + + + + 罚款详情 + + + + 罚款金额¥{{ detailItem.fakuanjine }} + 当前状态{{ detailItem.display_status }} + 处罚理由{{ detailItem.chufaliyou }} + 关联订单{{ detailItem.guanliandingdan_id }} + 驳回理由{{ detailItem.bohuiliyou }} + 申诉理由{{ detailItem.shensuliyou }} + + + + 证据图片 + + + + + + + + + + + 申诉图片 + + + + + + + + + + + 申诉 + 立即缴纳 + 关闭 + + + + + + + + + 提交申诉 + + + + + 申诉理由 + + {{ dashouJieshao.length || 0 }}/200 + + + + + + 提示:已从服务器加载最新信息 + + + + + + + + + + + + 加载中... + + + + diff --git a/miniprogram/pages/dashouxiugai/dashouxiugai.wxss b/miniprogram/pages/dashouxiugai/dashouxiugai.wxss new file mode 100644 index 0000000..653e8db --- /dev/null +++ b/miniprogram/pages/dashouxiugai/dashouxiugai.wxss @@ -0,0 +1,197 @@ +/* 页面容器 */ +.container { + min-height: 100vh; + background: linear-gradient(135deg, #fffacd 0%, #e6f7ff 100%); + padding: 20rpx; + box-sizing: border-box; + } + + /* 头像区域 */ + .avatar-section { + display: flex; + justify-content: center; + align-items: center; + padding: 40rpx 0; + position: relative; + } + + .avatar-wrapper { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + } + + .avatar { + width: 180rpx; + height: 180rpx; + border-radius: 50%; + border: 6rpx solid #ffffff; + box-shadow: 0 0 30rpx rgba(255, 215, 0, 0.4); + z-index: 2; + position: relative; + background-color: #f5f5f5; + } + + .avatar-halo { + position: absolute; + width: 220rpx; + height: 220rpx; + border-radius: 50%; + background: radial-gradient(circle, rgba(255, 215, 0, 0.2) 0%, transparent 70%); + z-index: 1; + animation: halo-pulse 2s infinite ease-in-out; + } + + @keyframes halo-pulse { + 0%, 100% { opacity: 0.6; transform: scale(1); } + 50% { opacity: 0.8; transform: scale(1.05); } + } + + .avatar-hint { + margin-top: 20rpx; + font-size: 26rpx; + color: #666; + text-align: center; + } + + /* 信息区域 */ + .info-section { + background: rgba(255, 255, 255, 0.9); + border-radius: 20rpx; + padding: 30rpx; + margin-bottom: 40rpx; + box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.05); + } + + .info-item { + display: flex; + flex-direction: column; + margin-bottom: 40rpx; + position: relative; + padding-bottom: 30rpx; + border-bottom: 1rpx solid #f0f0f0; + } + + .info-item:last-child { + border-bottom: none; + } + + .info-label { + font-size: 28rpx; + color: #333; + font-weight: 600; + margin-bottom: 15rpx; + } + + .info-value-disabled { + font-size: 32rpx; + color: #999; + font-weight: bold; + background: #f9f9f9; + padding: 20rpx; + border-radius: 10rpx; + } + + .info-input { + font-size: 32rpx; + color: #333; + padding: 20rpx; + background: #f9f9f9; + border-radius: 10rpx; + border: 1rpx solid #e0e0e0; + } + + .info-textarea { + font-size: 30rpx; + color: #333; + padding: 20rpx; + background: #f9f9f9; + border-radius: 10rpx; + border: 1rpx solid #e0e0e0; + min-height: 200rpx; + line-height: 1.5; + } + + .info-item-textarea { + padding-bottom: 20rpx; + } + + .char-count { + position: absolute; + right: 0; + bottom: 5rpx; + font-size: 24rpx; + color: #999; + } + + /* 状态提示 */ + .status-section { + background: #e8f4fd; + border-radius: 10rpx; + padding: 20rpx; + margin-bottom: 30rpx; + border-left: 6rpx solid #1890ff; + } + + .status-text { + font-size: 26rpx; + color: #1890ff; + } + + /* 按钮区域 */ + .button-section { + padding: 20rpx 0 40rpx; + } + + .submit-btn { + background: linear-gradient(90deg, #52c41a, #73d13d); + color: white; + font-size: 32rpx; + font-weight: 600; + height: 90rpx; + line-height: 70rpx; + border-radius: 45rpx; + border: none; + box-shadow: 0 10rpx 20rpx rgba(82, 196, 26, 0.2); + } + + .submit-btn:disabled { + background: #cccccc; + box-shadow: none; + } + + .submit-btn::after { + border: none; + } + + /* 加载中 */ + .loading-wrapper { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(255, 255, 255, 0.9); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; + } + + .loading-content { + display: flex; + flex-direction: column; + align-items: center; + } + + .loading-icon { + width: 120rpx; + height: 120rpx; + margin-bottom: 30rpx; + } + + .loading-text { + font-size: 28rpx; + color: #666; + } \ No newline at end of file diff --git a/miniprogram/pages/dingdan/dingdan.js b/miniprogram/pages/dingdan/dingdan.js new file mode 100644 index 0000000..9e31b53 --- /dev/null +++ b/miniprogram/pages/dingdan/dingdan.js @@ -0,0 +1,287 @@ +// pages/dingdan/dingdan.js +const app = getApp() +import request from '../../utils/request.js' + +Page({ + data: { + // 订单状态tab配置 + dingdanZhuangtaiTabs: [ + { name: '全部', key: 'all', zhuangtaiList: [1, 2, 3, 4, 5, 6, 7, 8] }, + { name: '已下单', key: 'yixiadan', zhuangtaiList: [1, 7] }, + { name: '进行中', key: 'jinxingzhong', zhuangtaiList: [2] }, + { name: '争议订单', key: 'zhengyi', zhuangtaiList: [4, 5, 6] }, + { name: '已完成', key: 'yiwancheng', zhuangtaiList: [3] }, + { name: '结算中', key: 'jiesuanzhong', zhuangtaiList: [8] } + ], + + // 当前选中的tab索引 + xuanzhongTabIndex: 0, + // 当前选中的tab的key + currentTabKey: 'all', + + // 每个tab对应的订单数据 + dingdanShuju: { + all: { list: [], page: 1, hasMore: true, isLoading: false }, + yixiadan: { list: [], page: 1, hasMore: true, isLoading: false }, + jinxingzhong: { list: [], page: 1, hasMore: true, isLoading: false }, + zhengyi: { list: [], page: 1, hasMore: true, isLoading: false }, + yiwancheng: { list: [], page: 1, hasMore: true, isLoading: false }, + jiesuanzhong: { list: [], page: 1, hasMore: true, isLoading: false } + }, + + // 个人中心传递过来的type参数 + gerenzhongxinType: '', + + // 是否显示加载更多 + xianshiJiazaigengduo: false, + + // 页面加载状态 + isLoading: true + }, + + onLoad(options) { + const type = options.type || '' + + wx.setNavigationBarTitle({ + title: '我的订单' + }) + + this.qingkongGerenzhongxinJishu(type) + + const tabIndex = this.yingsheTypeToTabIndex(type) + const tabKey = this.data.dingdanZhuangtaiTabs[tabIndex].key + + this.setData({ + gerenzhongxinType: type, + xuanzhongTabIndex: tabIndex, + currentTabKey: tabKey, + isLoading: false + }) + + this.jiazaiDingdanShuju(tabIndex) + }, + onShow() { + // 原有代码... + + // 🆕 注册通知组件 + this.registerNotificationComponent(); +}, + +// 🆕 新增:注册通知组件 +registerNotificationComponent() { + const app = getApp(); + const notificationComp = this.selectComponent('#global-notification'); + + if (notificationComp && notificationComp.showNotification) { + console.log('🏪 商城页面注册通知组件'); + app.globalData.globalNotification = { + show: (data) => notificationComp.showNotification(data), + hide: () => notificationComp.hideNotification() + }; + } +}, + + + qingkongGerenzhongxinJishu(type) { + const jishuMap = { + 'daifuwu': 'daifuwu', + 'fuwuzhong': 'fuwuzhong', + 'yiwancheng': 'yiwancheng', + 'yituikuan': 'yituikuan' + } + + const jishuKey = jishuMap[type] + if (jishuKey && app.globalData.dingdanTiaoshu) { + app.globalData.dingdanTiaoshu[jishuKey] = 0 + } + }, + + yingsheTypeToTabIndex(type) { + const yingsheMap = { + 'daifuwu': 1, + 'fuwuzhong': 2, + 'yiwancheng': 4, + 'yituikuan': 3 + } + + return yingsheMap[type] || 0 + }, + + switchDingdanTab(e) { + const tabIndex = e.currentTarget.dataset.index + if (tabIndex === this.data.xuanzhongTabIndex) return + + const tabKey = this.data.dingdanZhuangtaiTabs[tabIndex].key + + this.setData({ + xuanzhongTabIndex: tabIndex, + currentTabKey: tabKey + }) + + this.jiazaiDingdanShuju(tabIndex) + }, + + async jiazaiDingdanShuju(tabIndex, isLoadMore = false) { + const tab = this.data.dingdanZhuangtaiTabs[tabIndex] + const tabKey = tab.key + + const tabData = this.data.dingdanShuju[tabKey] + + const page = isLoadMore ? tabData.page + 1 : 1 + + if (tabData.isLoading) return + + // 重置逻辑:如果不是加载更多,清空已有数据 + if (!isLoadMore) { + this.setData({ + [`dingdanShuju.${tabKey}.list`]: [], + [`dingdanShuju.${tabKey}.page`]: 1 + }) + } + + this.setData({ + [`dingdanShuju.${tabKey}.isLoading`]: true + }) + + wx.showLoading({ + title: isLoadMore ? '加载更多...' : '加载订单...', + mask: true + }) + + try { + const requestData = { + zhuangtai_list: tab.zhuangtaiList, + page: page, + page_size: 10 + } + + + + const res = await request({ + url: '/dingdan/dingdanhuoqu', + method: 'POST', + data: requestData, + header: { + 'content-type': 'application/json' + } + }) + + + + wx.hideLoading() + + // ✅ 关键修正:res是直接返回的数据对象,不是res.data + if (res && res.data.code === 0) { + // ✅ 关键修正:直接使用res.data.list + const newDingdanList = res.data.data.list || [] + const hasMore = res.data.data.has_more || false + + + + // 处理图片URL,拼接完整路径 + const processedList = newDingdanList.map(item => { + let tupianUrl = item.tupian || '' + + // 如果图片URL不是完整路径,拼接ossImageUrl + if (tupianUrl && !tupianUrl.startsWith('http')) { + const ossImageUrl = app.globalData.ossImageUrl || '' + tupianUrl = ossImageUrl + tupianUrl + } + + const zhuangtaiZh = this.getZhuangtaiZhongwen(item.zhuangtai) + + + return { + ...item, + tupian: tupianUrl, + zhuangtaiZh: zhuangtaiZh + } + }) + + const currentList = this.data.dingdanShuju[tabKey].list + const updatedList = isLoadMore + ? [...currentList, ...processedList] + : processedList + + this.setData({ + [`dingdanShuju.${tabKey}.list`]: updatedList, + [`dingdanShuju.${tabKey}.page`]: page, + [`dingdanShuju.${tabKey}.hasMore`]: hasMore, + [`dingdanShuju.${tabKey}.isLoading`]: false, + xianshiJiazaigengduo: hasMore + }) + + } else { + wx.showToast({ + title: res ? (res.msg || '加载失败') : '请求失败', + icon: 'none', + duration: 2000 + }) + + this.setData({ + [`dingdanShuju.${tabKey}.isLoading`]: false + }) + } + + } catch (error) { + console.error('加载订单数据失败:', error) + wx.hideLoading() + wx.showToast({ + title: '网络请求失败,请重试', + icon: 'none', + duration: 2000 + }) + + this.setData({ + [`dingdanShuju.${tabKey}.isLoading`]: false + }) + } + }, + + getZhuangtaiZhongwen(zhuangtai) { + const zhuangtaiMap = { + 1: '已下单', + 2: '进行中', + 3: '已完成', + 4: '退款中', + 5: '已退款', + 6: '退款失败', + 7: '指定中', + 8: '结算中' + } + + return zhuangtaiMap[zhuangtai] || '未知状态' + }, + + onReachBottom() { + const tabKey = this.data.currentTabKey + const tabData = this.data.dingdanShuju[tabKey] + + if (tabData.hasMore && !tabData.isLoading) { + const tabIndex = this.data.xuanzhongTabIndex + this.jiazaiDingdanShuju(tabIndex, true) + } + }, + + goToDingdanXiangqing(e) { + const dingdanItem = e.currentTarget.dataset.item + if (!dingdanItem) return + + const dingdanDataStr = encodeURIComponent(JSON.stringify(dingdanItem)) + + wx.navigateTo({ + url: `/pages/dingdanxiangqing/dingdanxiangqing?dingdanData=${dingdanDataStr}` + }) + }, + + onImageError(e) { + const index = e.currentTarget.dataset.index + const tabKey = this.data.currentTabKey + + const defaultImage = app.globalData.lunbozhanwei || '/images/default.jpg' + + this.setData({ + [`dingdanShuju.${tabKey}.list[${index}].tupian`]: defaultImage + }) + } +}) \ No newline at end of file diff --git a/miniprogram/pages/dingdan/dingdan.json b/miniprogram/pages/dingdan/dingdan.json new file mode 100644 index 0000000..837f016 --- /dev/null +++ b/miniprogram/pages/dingdan/dingdan.json @@ -0,0 +1,5 @@ +{ + "usingComponents": { + "global-notification": "/components/global-notification/global-notification" + } +} \ No newline at end of file diff --git a/miniprogram/pages/dingdan/dingdan.wxml b/miniprogram/pages/dingdan/dingdan.wxml new file mode 100644 index 0000000..9d64425 --- /dev/null +++ b/miniprogram/pages/dingdan/dingdan.wxml @@ -0,0 +1,111 @@ + + + + + + + + + {{item.name}} + + + + + + + + + + + + + 加载中... + + + + + + 暂无订单 + 快去下单体验服务吧 + + + + + + + + + + + + + + + {{item.jieshao || '暂无描述'}} + + + + + + + + {{item.zhuangtaiZh || '未知状态'}} + + + + + ¥ + {{item.jine || '0.00'}} + + + + + + + + + + 上拉加载更多 + + + + + + 没有更多订单了 + + + + + + diff --git a/miniprogram/pages/dingdan/dingdan.wxss b/miniprogram/pages/dingdan/dingdan.wxss new file mode 100644 index 0000000..afb2316 --- /dev/null +++ b/miniprogram/pages/dingdan/dingdan.wxss @@ -0,0 +1,262 @@ +/* pages/dingdan/dingdan.wxss */ + +.dingdan-page { + min-height: 100vh; + background-color: #f8f9fa; + padding-bottom: 20rpx; + } + + .dingdan-tabs-scroll { + width: 100%; + height: 90rpx; + white-space: nowrap; + background-color: #ffffff; + border-bottom: 1rpx solid #f0f0f0; + box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.03); + } + + .dingdan-tabs-container { + display: flex; + align-items: center; + height: 100%; + padding: 0 20rpx; + } + + .dingdan-tab-item { + display: inline-flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 60rpx; + padding: 0 30rpx; + margin-right: 20rpx; + border-radius: 30rpx; + background-color: #f5f5f5; + color: #666666; + font-size: 28rpx; + transition: all 0.3s ease; + position: relative; + flex-shrink: 0; + } + + .dingdan-tab-item:last-child { + margin-right: 0; + } + + .dingdan-tab-item.tab-active { + background-color: #e8f5e9; + color: #2e7d32; + font-weight: 500; + box-shadow: 0 4rpx 12rpx rgba(46, 125, 50, 0.1); + } + + .tab-active-line { + width: 40rpx; + height: 4rpx; + background-color: #4caf50; + border-radius: 2rpx; + margin-top: 6rpx; + animation: fadeIn 0.3s ease; + } + + @keyframes fadeIn { + from { opacity: 0; transform: scale(0.8); } + to { opacity: 1; transform: scale(1); } + } + + .tab-text { + font-weight: 400; + } + + .dingdan-list-container { + padding: 20rpx; + } + + .loading-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 400rpx; + } + + .loading-spinner { + width: 60rpx; + height: 60rpx; + border: 6rpx solid #e0e0e0; + border-top-color: #4caf50; + border-radius: 50%; + animation: spin 1s linear infinite; + margin-bottom: 20rpx; + } + + @keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + + .loading-text { + font-size: 28rpx; + color: #999999; + } + + .empty-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 500rpx; + padding-top: 80rpx; + } + + .empty-image { + width: 200rpx; + height: 200rpx; + margin-bottom: 30rpx; + opacity: 0.6; + } + + .empty-text { + font-size: 32rpx; + color: #999999; + margin-bottom: 10rpx; + } + + .empty-subtext { + font-size: 26rpx; + color: #cccccc; + } + + .dingdan-card { + display: flex; + align-items: center; + background-color: #ffffff; + border-radius: 16rpx; + padding: 24rpx; + margin-bottom: 20rpx; + box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); + transition: transform 0.2s ease, box-shadow 0.2s ease; + } + + .dingdan-card:active { + transform: translateY(-2rpx); + box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.08); + } + + .dingdan-card-left { + flex-shrink: 0; + margin-right: 24rpx; + } + + .dingdan-image { + width: 160rpx; + height: 160rpx; + border-radius: 12rpx; + background-color: #f5f5f5; + } + + .dingdan-card-center { + flex: 1; + height: 160rpx; + display: flex; + align-items: flex-start; + } + + .dingdan-jieshao { + font-size: 28rpx; + line-height: 40rpx; + color: #333333; + font-weight: 400; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + overflow: hidden; + text-overflow: ellipsis; + } + + .dingdan-card-right { + display: flex; + flex-direction: column; + align-items: flex-end; + justify-content: space-between; + height: 160rpx; + margin-left: 20rpx; + } + + .dingdan-zhuangtai { + font-size: 24rpx; + color: #ff6b6b; + font-weight: 500; + padding: 6rpx 16rpx; + border-radius: 20rpx; + background-color: #fff5f5; + white-space: nowrap; + } + + /* ✅ 修正后的价格样式 - 简单明了 */ + .dingdan-jine { + display: flex; + align-items: center; /* 垂直居中 */ + } + + .jine-symbol { + font-size: 28rpx; + color: #333333; + font-weight: 500; + margin-right: 4rpx; /* 添加右边距,让符号和数字有间隔 */ + } + + .jine-number { + font-size: 32rpx; /* 整数和小数一样大 */ + color: #333333; + font-weight: 600; + } + + .load-more-container { + display: flex; + align-items: center; + justify-content: center; + padding: 40rpx 0; + } + + .load-more-line { + width: 80rpx; + height: 1rpx; + background-color: #e0e0e0; + margin: 0 20rpx; + } + + .load-more-text { + font-size: 26rpx; + color: #999999; + white-space: nowrap; + } + + .no-more-container { + text-align: center; + padding: 40rpx 0; + } + + .no-more-text { + font-size: 26rpx; + color: #cccccc; + } + + @media (max-width: 375px) { + .dingdan-image { + width: 140rpx; + height: 140rpx; + } + + .dingdan-card-center { + height: 140rpx; + } + + .dingdan-card-right { + height: 140rpx; + } + + .jine-number { + font-size: 30rpx; + } + } \ No newline at end of file diff --git a/miniprogram/pages/dingdanxiangqing/dingdanxiangqing.js b/miniprogram/pages/dingdanxiangqing/dingdanxiangqing.js new file mode 100644 index 0000000..9e5fa60 --- /dev/null +++ b/miniprogram/pages/dingdanxiangqing/dingdanxiangqing.js @@ -0,0 +1,412 @@ +// pages/dingdanxiangqing/dingdanxiangqing.js +const app = getApp() +import request from '../../utils/request.js' + +Page({ + data: { + // 从跳转参数获取的基础数据 + jibenShuju: { + dingdanId: '', + tupian: '', + jieshao: '', + chuangjianshijian: '', + jine: '', + nicheng: '', + beizhu: '', + zhuangtai: 0 + }, + + // 从后端获取的详细数据 + xiangxiShuju: { + zhiding: '', // 指定打手 + dashou: '', // 服务打手 + dashoujiaofu: [], // 打手交付图片列表 + dashouliuyan: '' // 打手留言 + }, + + // 结算相关数据 + jiesuanShuju: { + pingfen: 0, // 评分 0-5 + liuyan: '' // 留言 + }, + + // 页面状态 + isLoading: true, // 页面加载中 + isJiesuanLoading: false, // 结单请求中 + + // 状态颜色映射 + zhuangtaiYanseMap: { + 1: '#E8F5E9', // 已下单 - 浅绿色 + 2: '#E3F2FD', // 进行中 - 浅蓝色 + 3: '#F3E5F5', // 已完成 - 浅紫色 + 4: '#FFF3E0', // 退款中 - 浅橙色 + 5: '#FFEBEE', // 已退款 - 浅红色 + 6: '#EFEBE9', // 退款失败 - 浅棕色 + 7: '#E0F7FA', // 指定中 - 浅青色 + 8: '#FFF8E1' // 结算中 - 浅黄色 + }, + + // 状态文字映射 + zhuangtaiWenziMap: { + 1: '已下单', + 2: '进行中', + 3: '已完成', + 4: '退款中', + 5: '已退款', + 6: '退款失败', + 7: '指定中', + 8: '结算中' + }, + + // 星星评分数据 + xingxingData: [ + { id: 1, active: false }, + { id: 2, active: false }, + { id: 3, active: false }, + { id: 4, active: false }, + { id: 5, active: false } + ] + }, + + onLoad(options) { + // 设置页面标题 + wx.setNavigationBarTitle({ + title: '订单详情' + }) + + // 解析跳转参数 + this.jiexiTiaozhuanCanshu(options) + }, + onShow() { + // 原有代码... + + // 🆕 注册通知组件 + this.registerNotificationComponent(); +}, + +// 🆕 新增:注册通知组件 +registerNotificationComponent() { + const app = getApp(); + const notificationComp = this.selectComponent('#global-notification'); + + if (notificationComp && notificationComp.showNotification) { + console.log('🏪 商城页面注册通知组件'); + app.globalData.globalNotification = { + show: (data) => notificationComp.showNotification(data), + hide: () => notificationComp.hideNotification() + }; + } +}, + + /** + * 解析跳转参数 + */ + jiexiTiaozhuanCanshu(options) { + try { + const dingdanDataStr = options.dingdanData || '' + if (!dingdanDataStr) { + wx.showToast({ + title: '订单数据错误', + icon: 'none' + }) + setTimeout(() => { + wx.navigateBack() + }, 1500) + return + } + + // 解析订单数据 + const dingdanData = JSON.parse(decodeURIComponent(dingdanDataStr)) + + + + // 处理图片URL(拼接完整路径) + let tupianUrl = dingdanData.tupian || '' + if (tupianUrl && !tupianUrl.startsWith('http')) { + const ossImageUrl = app.globalData.ossImageUrl || '' + tupianUrl = ossImageUrl + tupianUrl + } + + // 格式化价格 + let jine = dingdanData.jine || 0 + jine = parseFloat(jine) + if (isNaN(jine)) { + jine = 0 + } + const formattedJine = jine.toFixed(2) + + // 设置基础数据(状态先用跳转的,等后端返回后更新) + this.setData({ + 'jibenShuju.dingdanId': dingdanData.dingdanId || '', + 'jibenShuju.tupian': tupianUrl, + 'jibenShuju.jieshao': dingdanData.jieshao || '', + 'jibenShuju.chuangjianshijian': dingdanData.chuangjianshijian || '', + 'jibenShuju.jine': formattedJine, + 'jibenShuju.nicheng': dingdanData.nicheng || '', + 'jibenShuju.beizhu': dingdanData.beizhu || '', + // 这里先使用跳转的状态,等后端返回后会被覆盖 + 'jibenShuju.zhuangtai': dingdanData.zhuangtai || 0, + isLoading: false + }) + + + + // 加载详细数据 + this.jiazaiXiangxiShuju(dingdanData.dingdanId) + + } catch (error) { + console.error('解析订单数据失败:', error) + wx.showToast({ + title: '数据解析失败', + icon: 'none' + }) + setTimeout(() => { + wx.navigateBack() + }, 1500) + } + }, + + /** + * 加载详细数据 + */ + async jiazaiXiangxiShuju(dingdanId) { + if (!dingdanId) return + + + + try { + const res = await request({ + url: '/dingdan/dingdanxiangqing', + method: 'POST', + data: { dingdanId: dingdanId }, + header: { 'content-type': 'application/json' } + }) + + + + // 关键修正:使用正确的数据访问路径 + if (res && res.data.code === 0 && res.data.data) { + const data = res.data.data + + + + // 处理打手交付图片(拼接完整URL) + let dashoujiaofuList = data.dashoujiaofu || [] + dashoujiaofuList = dashoujiaofuList.map(imgUrl => { + if (imgUrl && !imgUrl.startsWith('http')) { + const ossImageUrl = app.globalData.ossImageUrl || '' + return ossImageUrl + imgUrl + } + return imgUrl + }) + + // 核心修正:使用后端返回的订单状态,覆盖跳转时的状态 + this.setData({ + 'xiangxiShuju.zhiding': data.zhiding || '', + 'xiangxiShuju.dashou': data.dashou || '', + 'xiangxiShuju.dashoujiaofu': dashoujiaofuList, + 'xiangxiShuju.dashouliuyan': data.dashouliuyan || '', + // 关键:使用后端返回的状态覆盖跳转的状态 + 'jibenShuju.zhuangtai': data.zhuangtai || 0 + }) + + + + } else { + console.warn('获取详细数据失败:', res?.msg || '未知错误') + wx.showToast({ + title: res?.msg || '获取订单详情失败', + icon: 'none', + duration: 2000 + }) + } + + } catch (error) { + console.error('加载详细数据失败:', error) + wx.showToast({ + title: '加载数据失败,请重试', + icon: 'none', + duration: 2000 + }) + } + }, + + /** + * 复制文本到剪贴板 + */ + async fuzhiWenben(e) { + const text = e.currentTarget.dataset.text + if (!text) return + + + + try { + await wx.setClipboardData({ + data: text + }) + + wx.showToast({ + title: '复制成功', + icon: 'success', + duration: 1500 + }) + + } catch (error) { + console.error('复制失败:', error) + wx.showToast({ + title: '复制失败', + icon: 'none' + }) + } + }, + + /** + * 预览图片 + */ + yulanTupian(e) { + const currentUrl = e.currentTarget.dataset.url + const urls = e.currentTarget.dataset.urls || [] + + if (!currentUrl) return + + wx.previewImage({ + current: currentUrl, + urls: urls.length > 0 ? urls : [currentUrl] + }) + }, + + /** + * 点击星星评分 + */ + dianjiXingxing(e) { + const pingfen = e.currentTarget.dataset.index + + // 更新星星状态 + const xingxingData = this.data.xingxingData.map((item, index) => ({ + ...item, + active: index < pingfen + })) + + this.setData({ + xingxingData: xingxingData, + 'jiesuanShuju.pingfen': pingfen + }) + + + }, + + /** + * 输入留言 + */ + shuruLiuyan(e) { + const liuyan = e.detail.value.slice(0, 50) // 限制50字 + this.setData({ + 'jiesuanShuju.liuyan': liuyan + }) + }, + + /** + * 提交结单 + */ + async tijiaoJiedan() { + const { jibenShuju, jiesuanShuju } = this.data + + console.log('提交结单,数据:', { + dingdanId: jibenShuju.dingdanId, + pingfen: jiesuanShuju.pingfen, + liuyan: jiesuanShuju.liuyan + }) + + // 验证订单状态 + if (jibenShuju.zhuangtai !== 8) { + wx.showToast({ + title: '订单不在结算状态', + icon: 'none' + }) + return + } + + // 验证评分范围 + if (jiesuanShuju.pingfen < 0 || jiesuanShuju.pingfen > 5) { + wx.showToast({ + title: '请选择0-5分评分', + icon: 'none' + }) + return + } + + // 验证订单ID + if (!jibenShuju.dingdanId) { + wx.showToast({ + title: '订单信息错误', + icon: 'none' + }) + return + } + + // 显示加载中 + this.setData({ isJiesuanLoading: true }) + wx.showLoading({ + title: '提交中...', + mask: true + }) + + try { + const res = await request({ + url: '/dingdan/jiedan', + method: 'POST', + data: { + dingdanId: jibenShuju.dingdanId, + pingfen: jiesuanShuju.pingfen, + liuyan: jiesuanShuju.liuyan + }, + header: { 'content-type': 'application/json' } + }) + + + + wx.hideLoading() + this.setData({ isJiesuanLoading: false }) + + // 使用正确的数据访问路径 + if (res && res.data.code === 0) { + // 结单成功,更新订单状态 + this.setData({ + 'jibenShuju.zhuangtai': 3, // 变为已完成状态 + 'jiesuanShuju.pingfen': 0, + 'jiesuanShuju.liuyan': '' + }) + + // 重置星星 + const resetXingxingData = this.data.xingxingData.map(item => ({ + ...item, + active: false + })) + this.setData({ xingxingData: resetXingxingData }) + + wx.showToast({ + title: '结单成功', + icon: 'success', + duration: 2000 + }) + + } else { + wx.showToast({ + title: res?.msg || '结单失败', + icon: 'none' + }) + } + + } catch (error) { + console.error('结单失败:', error) + wx.hideLoading() + this.setData({ isJiesuanLoading: false }) + wx.showToast({ + title: '网络错误,请重试', + icon: 'none' + }) + } + }, + + +}) \ No newline at end of file diff --git a/miniprogram/pages/dingdanxiangqing/dingdanxiangqing.json b/miniprogram/pages/dingdanxiangqing/dingdanxiangqing.json new file mode 100644 index 0000000..837f016 --- /dev/null +++ b/miniprogram/pages/dingdanxiangqing/dingdanxiangqing.json @@ -0,0 +1,5 @@ +{ + "usingComponents": { + "global-notification": "/components/global-notification/global-notification" + } +} \ No newline at end of file diff --git a/miniprogram/pages/dingdanxiangqing/dingdanxiangqing.wxml b/miniprogram/pages/dingdanxiangqing/dingdanxiangqing.wxml new file mode 100644 index 0000000..d0a1ab8 --- /dev/null +++ b/miniprogram/pages/dingdanxiangqing/dingdanxiangqing.wxml @@ -0,0 +1,202 @@ + + + + + + + 加载订单详情... + + + + + + + + + + + + {{jibenShuju.jieshao || '暂无描述'}} + + + + + + 订单信息 + + + + 游戏昵称: + {{jibenShuju.nicheng}} + + + + + 备注信息: + {{jibenShuju.beizhu}} + + + + + 指定打手: + {{xiangxiShuju.zhiding}} + + + + + 订单ID: + + {{jibenShuju.dingdanId}} + + 📋 + 复制 + + + + + + + 创建时间: + {{jibenShuju.chuangjianshijian}} + + + + + 订单价格: + ¥{{jibenShuju.jine}} + + + + + 订单状态: + {{zhuangtaiWenziMap[jibenShuju.zhuangtai] || '未知状态'}} + + + + + + 服务详情 + + + + 服务打手: + + {{xiangxiShuju.dashou}} + + 📋 + 复制 + + + + + + + 打手交付 + + + + + + + + + + + + 打手留言 + + {{xiangxiShuju.dashouliuyan}} + + + + + + + 订单结算 + + + + + 打星评分: + + + + {{item.active ? '★' : '☆'}} + + + + + + + + + 订单留言(可选) + + + 已输入 {{jiesuanShuju.liuyan.length}}/50 字 + + + + + + + + + + + + + + diff --git a/miniprogram/pages/dingdanxiangqing/dingdanxiangqing.wxss b/miniprogram/pages/dingdanxiangqing/dingdanxiangqing.wxss new file mode 100644 index 0000000..686128a --- /dev/null +++ b/miniprogram/pages/dingdanxiangqing/dingdanxiangqing.wxss @@ -0,0 +1,422 @@ +/* pages/dingdanxiangqing/dingdanxiangqing.wxss */ + +/* 页面基础样式 */ +.dingdanxiangqing-page { + min-height: 100vh; + background-color: #f8f9fa; + padding-bottom: 140rpx; + } + + /* 加载中状态 */ + .loading-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 60vh; + } + + .loading-spinner { + width: 80rpx; + height: 80rpx; + border: 8rpx solid #e0e0e0; + border-top-color: #4caf50; + border-radius: 50%; + animation: spin 1.2s linear infinite; + margin-bottom: 30rpx; + } + + @keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + + .loading-text { + font-size: 30rpx; + color: #666666; + } + + /* 内容区域 */ + .content-container { + padding: 25rpx; + } + + /* 商品图片和介绍区域 */ + .shangpin-area { + display: flex; + background-color: #ffffff; + border-radius: 20rpx; + padding: 25rpx; + margin-bottom: 25rpx; + box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06); + } + + .shangpin-image-container { + flex-shrink: 0; + width: 180rpx; + height: 180rpx; + margin-right: 25rpx; + } + + .shangpin-image { + width: 100%; + height: 100%; + border-radius: 12rpx; + background-color: #f5f5f5; + } + + .shangpin-jieshao { + flex: 1; + display: flex; + align-items: flex-start; + } + + .jieshao-text { + font-size: 28rpx; + line-height: 42rpx; + color: #333333; + font-weight: 400; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 4; + overflow: hidden; + text-overflow: ellipsis; + } + + /* 通用区域样式 */ + .info-title { + font-size: 32rpx; + color: #333333; + font-weight: 600; + margin-bottom: 20rpx; + padding-bottom: 12rpx; + border-bottom: 2rpx solid rgba(0, 0, 0, 0.08); + } + + .section-subtitle { + font-size: 28rpx; + color: #555555; + font-weight: 500; + display: block; + } + + /* 左右布局的订单信息项 */ + .dingdan-info-area { + background-color: #ffffff; + border-radius: 20rpx; + padding: 25rpx; + margin-bottom: 25rpx; + box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06); + } + + .info-item-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 18rpx; + padding: 12rpx 0; + } + + .info-item-row:last-child { + margin-bottom: 0; + } + + .item-label { + font-size: 28rpx; + color: #666666; + font-weight: 400; + flex-shrink: 0; + min-width: 150rpx; + } + + /* 右侧区域容器 */ + .item-right-area { + flex: 1; + display: flex; + align-items: center; + justify-content: flex-end; + } + + .item-value { + font-size: 28rpx; + color: #333333; + font-weight: 500; + word-break: break-all; + text-align: right; + margin-right: 15rpx; + } + + /* 特殊样式 */ + .jine-red { + color: #ff4444 !important; + font-weight: 600 !important; + font-size: 32rpx !important; + } + + .zhuangtai-text { + font-weight: 600 !important; + font-size: 30rpx !important; + color: #333333 !important; + } + + /* 复制按钮 */ + .copy-btn { + display: flex; + align-items: center; + justify-content: center; + font-size: 24rpx; + color: #4caf50; + background-color: #e8f5e9; + padding: 6rpx 16rpx; + border-radius: 20rpx; + border: 1rpx solid #4caf50; + transition: all 0.2s ease; + white-space: nowrap; + flex-shrink: 0; + } + + .copy-btn-hover { + background-color: #c8e6c9; + transform: scale(0.95); + } + + .copy-icon { + font-size: 20rpx; + margin-right: 6rpx; + } + + .copy-text { + font-weight: 500; + } + + /* 服务区域 */ + .fuwu-area { + background-color: #ffffff; + border-radius: 20rpx; + padding: 25rpx; + margin-bottom: 25rpx; + box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06); + } + + /* 打手交付图片网格 */ + .dashou-jiaofu-container { + margin-bottom: 20rpx; + margin-top: 15rpx; + } + + .jiaofu-grid { + display: flex; + flex-wrap: wrap; + margin: -5rpx; + } + + .jiaofu-image-item { + width: calc(33.333% - 10rpx); + margin: 5rpx; + aspect-ratio: 1/1; + } + + .jiaofu-image { + width: 100%; + height: 100%; + border-radius: 12rpx; + background-color: #f5f5f5; + transition: transform 0.2s ease; + } + + .jiaofu-image:active { + transform: scale(0.95); + } + + /* 打手留言 */ + .dashou-liuyan-container { + margin-top: 15rpx; + } + + .liuyan-content { + font-size: 26rpx; + line-height: 40rpx; + color: #555555; + padding: 15rpx; + background-color: #f9f9f9; + border-radius: 12rpx; + border-left: 4rpx solid #4caf50; + } + + /* 结算区域 */ + .jiesuan-area { + background-color: #ffffff; + border-radius: 20rpx; + padding: 25rpx; + margin-bottom: 25rpx; + box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06); + } + + /* 星星评分布局修正 */ + .pingfen-container { + margin-bottom: 25rpx; + } + + .xingxing-layout { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 10rpx; + } + + .xingxing-wrapper { + display: flex; + align-items: center; + } + + .xingxing-icon { + font-size: 52rpx; + color: #cccccc; + margin-right: 10rpx; + transition: all 0.3s ease; + cursor: pointer; + /* 去掉点击时的蓝色矩形框 */ + user-select: none; + -webkit-tap-highlight-color: transparent; + outline: none; + border: none; + background: none; + } + + .xingxing-icon:last-child { + margin-right: 0; + } + + .xingxing-active { + color: #FFD700; + text-shadow: 0 0 10rpx rgba(255, 215, 0, 0.5); + transform: scale(1.1); + } + + .xingxing-icon:active { + transform: scale(0.9); + } + + /* 留言输入 */ + .liuyan-input-container { + margin-top: 15rpx; + } + + .liuyan-textarea { + width: 100%; + min-height: 120rpx; + font-size: 28rpx; + color: #333333; + background-color: #f9f9f9; + border-radius: 12rpx; + padding: 20rpx; + margin-top: 10rpx; + box-sizing: border-box; + } + + .zi-shu { + display: block; + text-align: right; + font-size: 24rpx; + color: #999999; + margin-top: 8rpx; + } + + /* 底部安全区域 */ + .safe-area { + height: 40rpx; + } + + /* 结单按钮容器修正 */ + .jiedan-btn-container { + position: fixed; + bottom: 0; + left: 0; + right: 0; + background: linear-gradient(to top, rgba(255,255,255,0.9), transparent); + padding: 20rpx 30rpx; + backdrop-filter: blur(10rpx); + z-index: 100; + } + + .jiedan-btn { + background: linear-gradient(135deg, #4caf50, #2e7d32); + color: #ffffff; + border: none; + border-radius: 50rpx; + height: 90rpx; + font-size: 32rpx; + font-weight: 600; + position: relative; + overflow: hidden; + box-shadow: 0 6rpx 20rpx rgba(76, 175, 80, 0.3); + transition: all 0.3s ease; + width: 100%; + /* 垂直居中 */ + display: flex; + align-items: center; + justify-content: center; + } + + .jiedan-btn::after { + border: none; + } + + .btn-hover { + transform: translateY(-2rpx); + box-shadow: 0 8rpx 25rpx rgba(76, 175, 80, 0.4); + } + + .btn-text { + position: relative; + z-index: 2; + /* 确保文字垂直居中 */ + line-height: 1; + } + + /* 按钮闪光特效 */ + .btn-sparkle { + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: radial-gradient(circle, rgba(255,255,255,0.3) 1%, transparent 10%); + animation: sparkle 2s infinite linear; + z-index: 1; + } + + @keyframes sparkle { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + + /* 响应式调整 */ + @media (max-width: 375px) { + .shangpin-image-container { + width: 160rpx; + height: 160rpx; + } + + .xingxing-icon { + font-size: 48rpx; + } + + .jiedan-btn { + height: 85rpx; + font-size: 30rpx; + } + + .item-label { + min-width: 140rpx; + font-size: 26rpx; + } + + .item-value { + font-size: 26rpx; + } + + .jiedan-btn-container { + padding: 20rpx 25rpx; + } + } \ No newline at end of file diff --git a/miniprogram/pages/dsddxq/dsddxq.js b/miniprogram/pages/dsddxq/dsddxq.js new file mode 100644 index 0000000..7e53d26 --- /dev/null +++ b/miniprogram/pages/dsddxq/dsddxq.js @@ -0,0 +1,730 @@ +// pages/dsddxq/dsddxq.js - 【最终版:提交前公告弹窗 + 修改图片至少保留一张】 +const app = getApp() +import request from '../../utils/request.js' +const COS = require('../../utils/cos-wx-sdk-v5.js') +import connectionManager from '../../utils/xiaoxilj.js' + +Page({ + data: { + jibenShuju: { + dingdan_id: '', + tupian: '', + jieshao: '', + create_time: '', + jine: '', + nicheng: '', + beizhu: '', + zhuangtai: 0, + fadanpingtai: 0, + is_cross: 0 + }, + xiangxiShuju: { + shangjia_id: '', + shangjia_nicheng: '', + shangjia_liuyan: '', + tuikuan_liyou: '', + chufa_liyou: '', + chufa_zhuangtai: 0, + chufa_jieguo: '', + bohui_liyou: '', + dashou_jiaofu: [], + dashou_liuyan: '', + laoban_id: '' + }, + zhuangtaiYanseMap: { + 1: '#E8F5E9', 2: '#E3F2FD', 3: '#F3E5F5', 4: '#FFF3E0', + 5: '#FFEBEE', 6: '#EFEBE9', 7: '#E0F7FA', 8: '#FFF8E1' + }, + zhuangtaiWenziMap: { + 1: '已下单', 2: '进行中', 3: '已完成', 4: '退款中', + 5: '已退款', 6: '退款失败', 7: '指定中', 8: '结算中' + }, + isLoading: true, + isSubmitting: false, + liuyan: '', + xuanzhongTupian: [], + shangchuanJindu: 0, + shangchuanZongshu: 0, + jinduWidth: '0%', + showWanzhengJieshao: false, + wanzhengJieshao: '', + showWanzhengBeizhu: false, + wanzhengBeizhu: '', + ossImageUrl: '', + morentouxiang: '', + showRefundInfo: false, + + // 修改功能所需字段 + isModifying: false, + originalDashouJiaofu: [], + originalDashouLiuyan: '', + remainingOriginals: [], + modifiedLiuyan: '', + deletedImages: [], + newImages: [], + isConfirming: false, + modifyUploadProgress: { total: 0, current: 0, width: '0%' } + }, + + onLoad(options) { + wx.setNavigationBarTitle({ title: '订单详情' }) + this.initGlobalData() + this.jiexiTiaozhuanCanshu(options) + }, + onHide() { + const popupComp = this.selectComponent('#popupNotice'); + if (popupComp && popupComp.cleanup) { + popupComp.cleanup(); + } + }, + + onShow() { + this.registerNotificationComponent(); + }, + + registerNotificationComponent() { + const app = getApp(); + const notificationComp = this.selectComponent('#global-notification'); + if (notificationComp && notificationComp.showNotification) { + app.globalData.globalNotification = { + show: (data) => notificationComp.showNotification(data), + hide: () => notificationComp.hideNotification() + }; + } + }, + + initGlobalData() { + const app = getApp() + const ossImageUrl = app.globalData.ossImageUrl || 'https://your-oss-domain.com/' + const morentouxiang = app.globalData.morentouxiang || '/images/default-avatar.png' + this.setData({ ossImageUrl, morentouxiang }) + }, + + jiexiTiaozhuanCanshu(options) { + try { + const dingdanDataStr = options.dingdanData || '' + if (!dingdanDataStr) { + wx.showToast({ title: '订单数据错误', icon: 'none' }) + setTimeout(() => wx.navigateBack(), 1500) + return + } + const dingdanData = JSON.parse(decodeURIComponent(dingdanDataStr)) + let tupianUrl = dingdanData.tupian || '' + if (!tupianUrl) tupianUrl = this.getTupianUrl() + let jine = parseFloat(dingdanData.jine || 0) + if (isNaN(jine)) jine = 0 + const formattedJine = jine.toFixed(2) + this.setData({ + 'jibenShuju.dingdan_id': dingdanData.dingdan_id || '', + 'jibenShuju.tupian': tupianUrl, + 'jibenShuju.jieshao': dingdanData.jieshao || '', + 'jibenShuju.create_time': dingdanData.create_time || '', + 'jibenShuju.jine': formattedJine, + 'jibenShuju.nicheng': dingdanData.nicheng || '', + 'jibenShuju.beizhu': dingdanData.beizhu || '', + 'jibenShuju.zhuangtai': dingdanData.zhuangtai || 0, + 'jibenShuju.fadanpingtai': dingdanData.fadanpingtai || 0, + isLoading: false + }) + this.jiazaiXiangxiShuju(dingdanData.dingdan_id) + } catch (error) { + console.error('解析订单数据失败:', error) + wx.showToast({ title: '数据解析失败', icon: 'none' }) + setTimeout(() => wx.navigateBack(), 1500) + } + }, + + getTupianUrl() { + const cacheTouxiang = wx.getStorageSync('touxiang') || '' + let tupianPath = cacheTouxiang || app.globalData.morentouxiang || '' + const ossImageUrl = app.globalData.ossImageUrl || '' + if (tupianPath && ossImageUrl) { + if (tupianPath.startsWith('/')) tupianPath = tupianPath.substring(1) + return ossImageUrl + tupianPath + } + return '' + }, + + async jiazaiXiangxiShuju(dingdanId) { + if (!dingdanId) return + wx.showLoading({ title: '加载中...', mask: true }) + try { + const res = await request({ + url: '/dingdan/dsddxq', + method: 'POST', + data: { dingdan_id: dingdanId }, + header: { 'content-type': 'application/json' } + }) + wx.hideLoading() + if (res && res.data.code === 0 && res.data.data) { + const data = res.data.data + let dashouJiaofuList = data.dashou_jiaofu || [] + dashouJiaofuList = dashouJiaofuList.map(imgUrl => { + if (imgUrl && !imgUrl.startsWith('http')) { + const ossImageUrl = app.globalData.ossImageUrl || '' + if (imgUrl.startsWith('/')) imgUrl = imgUrl.substring(1) + return ossImageUrl + imgUrl + } + return imgUrl + }) + this.setData({ + 'xiangxiShuju.shangjia_id': data.shangjia_id || '', + 'xiangxiShuju.shangjia_nicheng': data.shangjia_nicheng || '', + 'xiangxiShuju.shangjia_liuyan': data.shangjia_liuyan || '', + 'xiangxiShuju.tuikuan_liyou': data.tuikuan_liyou || '', + 'xiangxiShuju.chufa_liyou': data.chufa_liyou || '', + 'xiangxiShuju.chufa_zhuangtai': data.chufa_zhuangtai || 0, + 'xiangxiShuju.chufa_jieguo': data.chufa_jieguo || '', + 'xiangxiShuju.bohui_liyou': data.bohui_liyou || '', + 'xiangxiShuju.dashou_jiaofu': dashouJiaofuList, + 'xiangxiShuju.dashou_liuyan': data.dashou_liuyan || '', + 'xiangxiShuju.laoban_id': data.laoban_id || '', + 'jibenShuju.zhuangtai': data.zhuangtai || 0, + 'jibenShuju.beizhu': data.beizhu || '', + 'liuyan': data.dashou_liuyan || '', + 'jibenShuju.fadanpingtai': data.fadanpingtai || 0, + 'jibenShuju.is_cross': data.is_cross || 0, + }) + const currentStatus = data.zhuangtai || 0 + const showRefund = [4,5,6].includes(currentStatus) + this.setData({ showRefundInfo: showRefund }) + } else { + const errorMsg = res?.data?.msg || '获取订单详情失败' + wx.showToast({ title: errorMsg, icon: 'none', duration: 2000 }) + } + } catch (error) { + console.error('加载详细数据失败:', error) + wx.hideLoading() + wx.showToast({ title: '加载数据失败,请重试', icon: 'none', duration: 2000 }) + } + }, + + // ========== 原有提交功能(部分修改) ========== + xuanzeTupian() { + if (this.data.isSubmitting) return + const shengyu = 9 - this.data.xuanzhongTupian.length + if (shengyu <= 0) { + wx.showToast({ title: '最多只能选择9张图片', icon: 'none' }) + return + } + wx.chooseImage({ + count: shengyu, + sizeType: ['compressed'], + sourceType: ['album', 'camera'], + success: (res) => { + const newTupian = [...this.data.xuanzhongTupian, ...res.tempFilePaths] + this.setData({ xuanzhongTupian: newTupian.slice(0, 9) }) + } + }) + }, + shanchuTupian(e) { + const index = e.currentTarget.dataset.index + const newTupian = [...this.data.xuanzhongTupian] + newTupian.splice(index, 1) + this.setData({ xuanzhongTupian: newTupian }) + }, + yulanTupian(e) { + const currentUrl = e.currentTarget.dataset.url + const urls = e.currentTarget.dataset.urls || [] + if (!currentUrl) return + wx.previewImage({ current: currentUrl, urls: urls.length > 0 ? urls : [currentUrl] }) + }, + getFileExtension(filePath) { + const lastDotIndex = filePath.lastIndexOf('.') + if (lastDotIndex === -1) return '.jpg' + const ext = filePath.substring(lastDotIndex).toLowerCase() + const allowedExts = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'] + return allowedExts.includes(ext) ? ext : '.jpg' + }, + shuruLiuyan(e) { + const liuyan = e.detail.value.slice(0, 50) + this.setData({ liuyan }) + }, + chakanWanzhengJieshao() { + this.setData({ showWanzhengJieshao: true, wanzhengJieshao: this.data.jibenShuju.jieshao || '无' }) + }, + guanbiWanzhengJieshao() { this.setData({ showWanzhengJieshao: false }) }, + chakanWanzhengBeizhu() { + this.setData({ showWanzhengBeizhu: true, wanzhengBeizhu: this.data.jibenShuju.beizhu || '无' }) + }, + guanbiWanzhengBeizhu() { this.setData({ showWanzhengBeizhu: false }) }, + async fuzhiWenben(e) { + const text = e.currentTarget.dataset.text + if (!text) return + try { + await wx.setClipboardData({ data: text }) + wx.showToast({ title: '复制成功', icon: 'success', duration: 1500 }) + } catch (error) { + console.error('复制失败:', error) + wx.showToast({ title: '复制失败', icon: 'none' }) + } + }, + goToKefu() { + const kefuLink = app.globalData.kefuConfig?.link || ''; + const corpId = app.globalData.kefuConfig?.enterpriseId || ''; + + if (!kefuLink || !corpId) { + wx.showToast({ + title: '客服配置未加载', + icon: 'none' + }); + return; + } + + wx.openCustomerServiceChat({ + extInfo: { url: kefuLink }, + corpId: corpId, + success: (res) => { + console.log('跳转客服成功', res); + }, + fail: (err) => { + console.error('跳转客服失败', err); + wx.showToast({ + title: '暂时无法连接客服', + icon: 'none' + }); + } + }); + }, + + // ===== 联系老板按钮(改为跳转订单群聊) ===== + // ===== 联系老板按钮(智能查找订单群聊) ===== +// ===== 联系老板按钮(智能查找订单群聊) ===== +goToChatWithBoss() { + const uid = wx.getStorageSync('uid') + if (!uid) return + + const orderId = this.data.jibenShuju.dingdan_id + if (!orderId) { + wx.showToast({ title: '订单ID缺失', icon: 'none' }) + return + } + + const identityType = 'dashou' + const userId = 'Ds' + uid + + const fadanPingtai = this.data.jibenShuju.fadanpingtai || 0 + const partnerUid = fadanPingtai === 2 + ? (this.data.xiangxiShuju.shangjia_id || '') + : (this.data.xiangxiShuju.laoban_id || '') + + connectionManager.connectToGroupChat({ + identityType, + userId, + orderId, + partnerUid, + fadanPingtai, + groupName: this.data.jibenShuju.nicheng + '的订单群', + isCross: this.data.jibenShuju.is_cross || 0 + }).catch(err => { + console.error('跳转群聊失败', err) + }) + }, + + async getCOSZhengshu() { + try { + const res = await request({ + url: '/dingdan/dsscpz', + method: 'POST', + data: { dingdan_id: this.data.jibenShuju.dingdan_id } + }) + if (res && res.data.code === 0 && res.data.data) return res.data.data + else throw new Error(res?.data?.msg || '获取上传凭证失败') + } catch (error) { + console.error('获取COS凭证失败:', error) + throw error + } + }, + + initCOSClient(tokenData) { + const credentials = tokenData.credentials || tokenData + const bucket = tokenData.bucket || 'julebu-1361527063' + const region = tokenData.region || 'ap-shanghai' + const cos = new COS({ + SimpleUploadMethod: 'putObject', + getAuthorization: async (options, callback) => { + const authParams = { + TmpSecretId: credentials.tmpSecretId, + TmpSecretKey: credentials.tmpSecretKey, + SecurityToken: credentials.sessionToken || '', + StartTime: tokenData.startTime || Math.floor(Date.now() / 1000), + ExpiredTime: tokenData.expiredTime || (Math.floor(Date.now() / 1000) + 7200) + } + callback(authParams) + } + }) + return { cos, bucket, region } + }, + + async shangchuanDanZhangTupian(filePath, cosKey, index, cosInstance, bucket, region) { + return new Promise((resolve) => { + const timeoutId = setTimeout(() => resolve({ status: 'optimistic_success', key: cosKey }), 2000) + cosInstance.uploadFile({ + Bucket: bucket, + Region: region, + Key: cosKey, + FilePath: filePath, + onProgress: (progressInfo) => { + const percent = Math.round(progressInfo.percent * 100) + if (percent === 100) { + clearTimeout(timeoutId) + resolve({ status: 'optimistic_success', key: cosKey }) + } + } + }) + }) + }, + + async piliangShangchuanTupian() { + const total = this.data.xuanzhongTupian.length + this.setData({ shangchuanZongshu: total, shangchuanJindu: 0, jinduWidth: '0%' }) + wx.showLoading({ title: '正在准备...', mask: true }) + const preGeneratedUrls = [] + for (let i = 0; i < total; i++) { + const timestamp = Date.now() + i + const random = Math.floor(Math.random() * 10000) + const fileExt = this.getFileExtension(this.data.xuanzhongTupian[i]) + const fileName = `${timestamp}_${random}${fileExt}` + const cosKey = `order/${this.data.jibenShuju.dingdan_id}/${fileName}` + preGeneratedUrls.push(cosKey) + } + let cosClient, bucket, region + try { + const tokenData = await this.getCOSZhengshu() + const { cos, bucket: cosBucket, region: cosRegion } = this.initCOSClient(tokenData) + cosClient = cos + bucket = cosBucket + region = cosRegion + } catch (error) { + wx.hideLoading() + wx.showToast({ title: '上传初始化失败', icon: 'none' }) + return [] + } + const uploadTasks = [] + for (let i = 0; i < total; i++) { + const task = this.shangchuanDanZhangTupian( + this.data.xuanzhongTupian[i], + preGeneratedUrls[i], + i, + cosClient, + bucket, + region + ).then((result) => { + const currentDone = i + 1 + const jinduPercent = ((currentDone / total) * 100).toFixed(0) + this.setData({ shangchuanJindu: currentDone, jinduWidth: `${jinduPercent}%` }) + return result + }) + uploadTasks.push(task) + } + wx.showLoading({ title: `上传中...`, mask: true }) + await Promise.all(uploadTasks) + wx.hideLoading() + return preGeneratedUrls + }, + + tijiaoDingdan() { + this.showAnnouncementAndConfirm() + }, + + async showAnnouncementAndConfirm() { + try { + const res = await request({ + url: '/peizhi/tanchuang', + method: 'POST', + data: { pageKey: 'dsddxq' } + }) + if (res.statusCode !== 200 || res.data.code !== 0) { + this.showOriginalConfirmAndSubmit() + return + } + const { popups = [], serverTime } = res.data.data + if (!popups.length) { + this.showOriginalConfirmAndSubmit() + return + } + const popup = popups[0] + const popupComp = this.selectComponent('#popupNotice') + if (!popupComp) { + console.error('未找到弹窗组件 #popupNotice') + this.showOriginalConfirmAndSubmit() + return + } + const showData = { + popupId: popup.popup_id, + title: popup.title || '', + duration: popup.duration || 0, + images: popup.images || [], + showMuteCheckbox: false, + serverTime: serverTime + } + popupComp.show(showData, (result) => { + this.showOriginalConfirmAndSubmit() + }) + } catch (error) { + console.error('获取公告配置失败', error) + this.showOriginalConfirmAndSubmit() + } + }, + + showOriginalConfirmAndSubmit() { + if (this.data.isSubmitting) { + wx.showToast({ title: '正在提交中', icon: 'none' }) + return + } + if (this.data.jibenShuju.zhuangtai !== 2) { + wx.showToast({ title: '订单状态不可提交', icon: 'none' }) + return + } + if (this.data.xuanzhongTupian.length === 0) { + wx.showToast({ title: '请至少上传一张图片', icon: 'none' }) + return + } + wx.showModal({ + title: '⚠️ 提交确认', + content: '在提交订单之前,请确保您已在打手端页面认真阅读打手规则。如有漏交图片,订单被退款,概不申诉。', + confirmText: '我已阅读', + cancelText: '我再想想', + success: (res) => { + if (res.confirm) this._doSubmit() + }, + fail: (err) => { + console.error('弹窗失败', err) + wx.showToast({ title: '系统异常,请重试', icon: 'none' }) + } + }) + }, + + async _doSubmit() { + this.setData({ isSubmitting: true }) + wx.showLoading({ title: '开始提交...', mask: true }) + try { + const tupianUrls = await this.piliangShangchuanTupian() + if (!tupianUrls || tupianUrls.length === 0) throw new Error('无法生成上传路径') + wx.showLoading({ title: '提交订单数据...', mask: true }) + const res = await request({ + url: '/dingdan/dstijiao', + method: 'POST', + data: { + dingdan_id: this.data.jibenShuju.dingdan_id, + liuyan: this.data.liuyan || '', + jiaofu_tupian_urls: tupianUrls + }, + header: { 'content-type': 'application/json' } + }) + wx.hideLoading() + this.setData({ isSubmitting: false }) + if (res && res.data.code === 0) { + const ossImageUrl = app.globalData.ossImageUrl || '' + const fullUrls = tupianUrls.map(url => { + if (url && !url.startsWith('http')) { + if (url.startsWith('/')) url = url.substring(1) + return ossImageUrl + url + } + return url + }) + this.setData({ + 'jibenShuju.zhuangtai': 8, + 'xiangxiShuju.dashou_liuyan': this.data.liuyan || '', + 'xiangxiShuju.dashou_jiaofu': fullUrls, + xuanzhongTupian: [], + liuyan: '', + shangchuanJindu: 0, + shangchuanZongshu: 0, + jinduWidth: '0%', + }) + if (app.globalData.dashouzhuangtai != 1) app.globalData.dashouzhuangtai = 1 + wx.showToast({ title: '提交成功!', icon: 'success', duration: 2000 }) + setTimeout(() => wx.navigateBack(), 1500) + } else { + const errorMsg = res?.data?.msg || '提交失败' + wx.showToast({ title: errorMsg, icon: 'none' }) + } + } catch (error) { + console.error('提交失败:', error) + wx.hideLoading() + this.setData({ isSubmitting: false }) + wx.showToast({ title: error.message || '提交失败', icon: 'none' }) + } + }, + + // ========== 修改功能(增加最少一张图片校验) ========== + extractRelativePath(fullUrl) { + const ossImageUrl = this.data.ossImageUrl + if (fullUrl.startsWith(ossImageUrl)) return fullUrl.substring(ossImageUrl.length) + return fullUrl + }, + enterModify() { + const { dashou_jiaofu, dashou_liuyan } = this.data.xiangxiShuju + this.setData({ + isModifying: true, + originalDashouJiaofu: dashou_jiaofu.slice(), + remainingOriginals: dashou_jiaofu.slice(), + originalDashouLiuyan: dashou_liuyan || '', + modifiedLiuyan: dashou_liuyan || '', + deletedImages: [], + newImages: [] + }) + }, + cancelModify() { + this.setData({ + isModifying: false, + originalDashouJiaofu: [], + remainingOriginals: [], + originalDashouLiuyan: '', + modifiedLiuyan: '', + deletedImages: [], + newImages: [] + }) + }, + handleDeleteImage(e) { + const fullUrl = e.currentTarget.dataset.url + const { originalDashouJiaofu, remainingOriginals, deletedImages, newImages } = this.data + if (originalDashouJiaofu.includes(fullUrl)) { + const newRemaining = remainingOriginals.filter(url => url !== fullUrl) + this.setData({ + remainingOriginals: newRemaining, + deletedImages: [...deletedImages, fullUrl] + }) + } else { + const index = newImages.indexOf(fullUrl) + if (index > -1) { + const newImagesCopy = [...newImages] + newImagesCopy.splice(index, 1) + this.setData({ newImages: newImagesCopy }) + } + } + }, + handleAddImage() { + if (this.data.isConfirming) return + const currentCount = this.getCurrentImageCount() + const maxCount = 9 - currentCount + if (maxCount <= 0) { + wx.showToast({ title: '最多9张图片', icon: 'none' }) + return + } + wx.chooseImage({ + count: maxCount, + sizeType: ['compressed'], + sourceType: ['album', 'camera'], + success: (res) => { + const newImages = [...this.data.newImages, ...res.tempFilePaths] + this.setData({ newImages: newImages.slice(0, 9) }) + } + }) + }, + getCurrentImageCount() { + const { remainingOriginals, newImages } = this.data + return remainingOriginals.length + newImages.length + }, + onModifyLiuyanInput(e) { + this.setData({ modifiedLiuyan: e.detail.value.slice(0, 50) }) + }, + + async confirmModify() { + if (this.data.isConfirming) return + const { dingdan_id } = this.data.jibenShuju + const { remainingOriginals, deletedImages, newImages, modifiedLiuyan, originalDashouLiuyan } = this.data + const hasLiuyanChange = modifiedLiuyan !== originalDashouLiuyan + const hasDelete = deletedImages.length > 0 + const hasAdd = newImages.length > 0 + + if (!hasLiuyanChange && !hasDelete && !hasAdd) { + wx.showToast({ title: '没有修改内容', icon: 'none' }) + return + } + + const finalImageCount = remainingOriginals.length + newImages.length + if (finalImageCount === 0) { + wx.showToast({ title: '至少保留一张图片', icon: 'none' }) + return + } + + this.setData({ isConfirming: true }) + wx.showLoading({ title: '提交修改...', mask: true }) + try { + const tokenData = await this.getCOSZhengshu() + const { cos, bucket, region } = this.initCOSClient(tokenData) + + let newImageRelativePaths = [] + if (hasAdd) { + const total = newImages.length + this.setData({ 'modifyUploadProgress.total': total, 'modifyUploadProgress.current': 0, 'modifyUploadProgress.width': '0%' }) + const preGeneratedKeys = [] + for (let i = 0; i < total; i++) { + const timestamp = Date.now() + i + const random = Math.floor(Math.random() * 10000) + const fileExt = this.getFileExtension(newImages[i]) + const fileName = `${timestamp}_${random}${fileExt}` + const cosKey = `order/${this.data.jibenShuju.dingdan_id}/${fileName}` + preGeneratedKeys.push(cosKey) + } + const uploadTasks = [] + for (let i = 0; i < total; i++) { + const task = this.shangchuanDanZhangTupian( + newImages[i], + preGeneratedKeys[i], + i, + cos, + bucket, + region + ).then((result) => { + const currentDone = i + 1 + const jinduPercent = ((currentDone / total) * 100).toFixed(0) + this.setData({ + 'modifyUploadProgress.current': currentDone, + 'modifyUploadProgress.width': `${jinduPercent}%` + }) + return result.key + }) + uploadTasks.push(task) + } + wx.showLoading({ title: `上传中...`, mask: true }) + newImageRelativePaths = await Promise.all(uploadTasks) + wx.hideLoading() + this.setData({ 'modifyUploadProgress.total': 0, 'modifyUploadProgress.current': 0, 'modifyUploadProgress.width': '0%' }) + } + + const deletedRelativePaths = deletedImages.map(fullUrl => this.extractRelativePath(fullUrl)) + + const res = await request({ + url: '/dingdan/dsxiugaidd', + method: 'POST', + data: { + dingdan_id, + liuyan: modifiedLiuyan, + deleted_images: deletedRelativePaths, + new_images: newImageRelativePaths + }, + header: { 'content-type': 'application/json' } + }) + wx.hideLoading() + this.setData({ isConfirming: false }) + if (res && res.data.code === 0) { + const ossImageUrl = this.data.ossImageUrl + const newFullUrls = newImageRelativePaths.map(rel => ossImageUrl + rel) + const newDashouJiaofu = [...remainingOriginals, ...newFullUrls] + this.setData({ + 'xiangxiShuju.dashou_jiaofu': newDashouJiaofu, + 'xiangxiShuju.dashou_liuyan': modifiedLiuyan, + isModifying: false, + originalDashouJiaofu: [], + remainingOriginals: [], + originalDashouLiuyan: '', + deletedImages: [], + newImages: [], + modifiedLiuyan: '' + }) + wx.showToast({ title: '修改成功', icon: 'success' }) + } else { + const errorMsg = res?.data?.msg || '修改失败' + wx.showToast({ title: errorMsg, icon: 'none' }) + } + } catch (error) { + console.error('修改失败:', error) + wx.hideLoading() + this.setData({ isConfirming: false }) + wx.showToast({ title: error.message || '修改失败', icon: 'none' }) + } + } +}) \ No newline at end of file diff --git a/miniprogram/pages/dsddxq/dsddxq.json b/miniprogram/pages/dsddxq/dsddxq.json new file mode 100644 index 0000000..837f016 --- /dev/null +++ b/miniprogram/pages/dsddxq/dsddxq.json @@ -0,0 +1,5 @@ +{ + "usingComponents": { + "global-notification": "/components/global-notification/global-notification" + } +} \ No newline at end of file diff --git a/miniprogram/pages/dsddxq/dsddxq.wxml b/miniprogram/pages/dsddxq/dsddxq.wxml new file mode 100644 index 0000000..7a715d6 --- /dev/null +++ b/miniprogram/pages/dsddxq/dsddxq.wxml @@ -0,0 +1,478 @@ + + + + + + 加载订单详情... + + + + + + + + + + + + + {{jibenShuju.jieshao || '暂无描述'}} + + + 点击上面字体查看完整介绍 + + + + + + + 订单信息 + + + + 游戏昵称: + {{jibenShuju.nicheng}} + + 📋 + 复制 + + + + + + 备注信息: + + {{jibenShuju.beizhu.length > 20 ? jibenShuju.beizhu.substring(0, 20) + '...' : jibenShuju.beizhu}} + + 查看完整 + + + + + + + 订单ID: + + {{jibenShuju.dingdan_id}} + + 📋 + 复制 + + + + + + + 创建时间: + {{jibenShuju.create_time}} + + + + + 订单价格: + ¥{{jibenShuju.jine}} + + + + + 订单状态: + {{zhuangtaiWenziMap[jibenShuju.zhuangtai] || '未知状态'}} + + + + + 发单平台: + + {{jibenShuju.fadanpingtai == 1 ? '平台发单' : (jibenShuju.fadanpingtai == 2 ? '商家发单' : '未知')}} + + + + + + + 商家信息 + + + + 商家ID: + + {{xiangxiShuju.shangjia_id}} + + 📋 + 复制 + + + + + + + 商家昵称: + {{xiangxiShuju.shangjia_nicheng}} + + + + + 商家留言 + + {{xiangxiShuju.shangjia_liuyan}} + + + + + + + 退款信息 + + + 退款理由: + {{xiangxiShuju.tuikuan_liyou}} + + + + + + 处罚申请 + + + + 申请原因: + {{xiangxiShuju.chufa_liyou}} + + + + + 申请状态: + + {{xiangxiShuju.chufa_zhuangtai == 0 ? '审核中' : (xiangxiShuju.chufa_zhuangtai == 1 ? '处罚成功' : '处罚驳回')}} + + + + + + 处罚结果: + {{xiangxiShuju.chufa_jieguo}} + + + + + 驳回理由: + {{xiangxiShuju.bohui_liyou}} + + + + + + 我的交付 + + + + 交付图片 + + + + + + + + + + + + 我的留言 + + {{xiangxiShuju.dashou_liuyan}} + + + + + + + 修改交付 + + + + 交付图片(点击叉号删除) + + + + + + + + + × + + + + + + + + + + × + + + + + + + + + 添加图片 + ({{9 - (remainingOriginals.length + newImages.length)}}/9) + + + + + + + 留言(可选,最多50字) + + + 已输入 {{modifiedLiuyan.length}}/50 字 + + + + + + + 提交订单 + + + + 选择交付图片(最多9张) + + + + + + + + × + + + + + + + + + 添加图片 + ({{9 - xuanzhongTupian.length}}/9) + + + + + + + + + + 上传中: {{shangchuanJindu}}/{{shangchuanZongshu}} + + + + + 留言(可选,最多50字) + + + 已输入 {{liuyan.length}}/50 字 + + + + + + + + + + + + + 取消修改 + + + {{isConfirming ? '提交中...' : '确认修改'}} + + + + + + + + + + 联系客服 + + + 联系老板 + + + + + + 联系客服 + + + + + + + 修改交付 + + + + + + {{isSubmitting ? '提交中...' : '立即提交'}} + + + + + + + + + + + + 订单介绍 + × + + + + {{wanzhengJieshao}} + + + + + + + + + + + 订单备注 + × + + + + {{wanzhengBeizhu}} + + + + + + + + \ No newline at end of file diff --git a/miniprogram/pages/dsddxq/dsddxq.wxss b/miniprogram/pages/dsddxq/dsddxq.wxss new file mode 100644 index 0000000..7e9a205 --- /dev/null +++ b/miniprogram/pages/dsddxq/dsddxq.wxss @@ -0,0 +1,589 @@ +/* pages/dsddxq/dsddxq.wxss */ + +/* 页面基础样式 */ +.dsddxq-page { + min-height: 100vh; + background-color: #f8f9fa; + position: relative; + box-sizing: border-box; +} + +/* 加载中状态 */ +.loading-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 60vh; +} + +.loading-spinner { + width: 80rpx; + height: 80rpx; + border: 8rpx solid #e0e0e0; + border-top-color: #2196f3; + border-radius: 50%; + animation: spin 1.2s linear infinite; + margin-bottom: 30rpx; +} + +@keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +} + +.loading-text { + font-size: 30rpx; + color: #666666; +} + +/* 内容区域 */ +.content-container { + padding: 25rpx 25rpx 220rpx; /* 减少底部内边距,避免过多空白 */ +} + +/* 商品图片和介绍区域 */ +.shangpin-area { + display: flex; + background-color: #ffffff; + border-radius: 20rpx; + padding: 25rpx; + margin-bottom: 25rpx; + box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06); +} + +.shangpin-image-container { + flex-shrink: 0; + width: 180rpx; + height: 180rpx; + margin-right: 25rpx; +} + +.shangpin-image { + width: 100%; + height: 100%; + border-radius: 12rpx; + background-color: #f5f5f5; +} + +.shangpin-jieshao { + flex: 1; + display: flex; + flex-direction: column; +} + +.jieshao-text { + font-size: 28rpx; + line-height: 42rpx; + color: #333333; + font-weight: 400; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 4; + overflow: hidden; + text-overflow: ellipsis; +} + +.chakan-wanzheng { + margin-top: 10rpx; +} + +.chakan-wanzheng text { + font-size: 24rpx; + color: #2196f3; + text-decoration: underline; +} + +/* 通用区域样式 */ +.info-title { + font-size: 32rpx; + color: #333333; + font-weight: 600; + margin-bottom: 20rpx; + padding-bottom: 12rpx; + border-bottom: 2rpx solid rgba(0, 0, 0, 0.08); +} + +.section-subtitle { + font-size: 28rpx; + color: #555555; + font-weight: 500; + display: block; + margin: 15rpx 0 10rpx; +} + +/* 订单信息区域 */ +.dingdan-info-area, +.shangjia-area, +.tuikuan-area, +.chufa-area, +.dashou-jiaofu-area, +.tijiao-area { + background-color: #ffffff; + border-radius: 20rpx; + padding: 25rpx; + margin-bottom: 25rpx; + box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06); +} + +.info-item-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 18rpx; + padding: 12rpx 0; +} + +.info-item-row:last-child { + margin-bottom: 0; +} + +.item-label { + font-size: 28rpx; + color: #666666; + font-weight: 400; + flex-shrink: 0; + min-width: 150rpx; +} + +/* 右侧区域容器 */ +.item-right-area { + flex: 1; + display: flex; + align-items: center; + justify-content: flex-end; +} + +.item-value { + font-size: 28rpx; + color: #333333; + font-weight: 500; + word-break: break-all; + text-align: right; + margin-right: 15rpx; +} + +/* 特殊样式 */ +.jine-green { + color: #4caf50 !important; + font-weight: 600 !important; + font-size: 32rpx !important; +} + +.zhuangtai-text { + font-weight: 600 !important; + font-size: 30rpx !important; + color: #333333 !important; +} + +/* 按钮样式(复制、查看) */ +.copy-btn, +.chakan-btn { + display: flex; + align-items: center; + justify-content: center; + font-size: 24rpx; + color: #4caf50; + background-color: #e8f5e9; + padding: 6rpx 16rpx; + border-radius: 20rpx; + border: 1rpx solid #4caf50; + transition: all 0.2s ease; + white-space: nowrap; + flex-shrink: 0; +} + +.chakan-btn { + color: #2196f3; + background-color: #e3f2fd; + border-color: #2196f3; + margin-left: 10rpx; +} + +.copy-btn-hover, +.chakan-btn:active { + background-color: #c8e6c9; + transform: scale(0.95); +} + +.copy-icon { + font-size: 20rpx; + margin-right: 6rpx; +} + +.copy-text { + font-weight: 500; +} + +/* 打手交付图片网格 */ +.jiaofu-grid { + display: flex; + flex-wrap: wrap; + margin: -5rpx; +} + +.jiaofu-image-item { + width: calc(33.333% - 10rpx); + margin: 5rpx; + aspect-ratio: 1/1; +} + +.jiaofu-image { + width: 100%; + height: 100%; + border-radius: 12rpx; + background-color: #f5f5f5; + transition: transform 0.2s ease; +} + +.jiaofu-image:active { + transform: scale(0.95); +} + +/* 留言内容样式 */ +.liuyan-content { + font-size: 26rpx; + line-height: 40rpx; + color: #555555; + padding: 15rpx; + background-color: #f9f9f9; + border-radius: 12rpx; + margin-top: 8rpx; +} + +/* 选择图片区域 */ +.yixuan-tupian-grid { + display: flex; + flex-wrap: wrap; + margin: -8rpx; +} + +.yixuan-tupian-item { + width: calc(33.333% - 16rpx); + margin: 8rpx; + aspect-ratio: 1/1; + position: relative; +} + +.yixuan-tupian { + width: 100%; + height: 100%; + border-radius: 12rpx; + background-color: #f5f5f5; +} + +.shanchu-btn { + position: absolute; + top: -10rpx; + right: -10rpx; + width: 40rpx; + height: 40rpx; + background-color: #ff4444; + color: white; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 24rpx; + font-weight: bold; + z-index: 10; +} + +.tianjia-btn { + width: calc(33.333% - 16rpx); + margin: 8rpx; + aspect-ratio: 1/1; + background-color: #f5f5f5; + border-radius: 12rpx; + border: 2rpx dashed #cccccc; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + color: #666666; +} + +.tianjia-icon { + font-size: 48rpx; + font-weight: 300; + margin-bottom: 10rpx; +} + +.tianjia-text { + font-size: 24rpx; + margin-bottom: 4rpx; +} + +.tianjia-tip { + font-size: 20rpx; + color: #999999; +} + +/* 上传进度 */ +.shangchuan-jindu-container { + margin-top: 20rpx; +} + +.jindu-bar { + width: 100%; + height: 20rpx; + background-color: #f0f0f0; + border-radius: 10rpx; + overflow: hidden; + margin-bottom: 10rpx; +} + +.jindu-fill { + height: 100%; + background-color: #4caf50; + border-radius: 10rpx; + transition: width 0.3s ease; +} + +.jindu-text { + font-size: 24rpx; + color: #666666; + text-align: center; + display: block; +} + +/* 留言输入 */ +.liuyan-textarea { + width: 100%; + min-height: 120rpx; + font-size: 28rpx; + color: #333333; + background-color: #f9f9f9; + border-radius: 12rpx; + padding: 20rpx; + margin-top: 10rpx; + box-sizing: border-box; +} + +.zi-shu { + display: block; + text-align: right; + font-size: 24rpx; + color: #999999; + margin-top: 8rpx; +} + +/* ==================== 底部按钮区域 ==================== */ +.bottom-btns-container { + position: fixed; + bottom: 0; + left: 0; + right: 0; + background-color: #ffffff; + padding: 20rpx 30rpx; + border-top: 1rpx solid #f0f0f0; + box-shadow: 0 -2rpx 20rpx rgba(0, 0, 0, 0.08); + z-index: 100; + display: flex; + flex-direction: column; + gap: 10rpx; /* 减小按钮间距 */ +} + +/* 🆕 新增:按钮行布局(用于并排两个按钮) */ +.btn-row { + display: flex; + justify-content: space-between; + width: 100%; +} + +/* 🆕 当有两个按钮时,各占一半(减去gap的一半) */ +.btn-row .bottom-btn { + width: calc(50% - 10rpx); +} + +/* 🆕 当只有一个按钮时,占满 */ +.btn-row .full-width { + width: 100%; +} + +/* 统一底部按钮样式 */ +.bottom-btn { + width: 100%; + height: 88rpx; /* 统一高度 */ + border-radius: 44rpx; /* 圆角 */ + display: flex; + align-items: center; + justify-content: center; + font-size: 32rpx; + font-weight: 600; + transition: all 0.3s ease; + position: relative; + overflow: hidden; + border: none; + box-sizing: border-box; +} + +.btn-hover { + opacity: 0.9; + transform: scale(0.98); +} + +/* 联系客服按钮 */ +.contact-btn { + background-color: #2196F3; + color: #ffffff; + box-shadow: 0 4rpx 15rpx rgba(33, 150, 243, 0.3); +} + +/* 🆕 新增:联系老板按钮 */ +.boss-btn { + background-color: #ff9800; + color: #ffffff; + box-shadow: 0 4rpx 15rpx rgba(255, 152, 0, 0.3); +} + +/* 🆕 新增:修改按钮(黑色) */ +.modify-btn { + background-color: #333333; + color: #ffffff; + box-shadow: 0 4rpx 15rpx rgba(51, 51, 51, 0.3); +} + +/* 🆕 新增:取消修改按钮 */ +.cancel-modify-btn { + background-color: #9e9e9e; + color: #ffffff; + box-shadow: 0 4rpx 15rpx rgba(158, 158, 158, 0.3); +} + +/* 🆕 新增:确认修改按钮 */ +.confirm-modify-btn { + background-color: #4caf50; + color: #ffffff; + box-shadow: 0 4rpx 15rpx rgba(76, 175, 80, 0.3); +} + +/* 提交按钮 */ +.submit-btn { + background: linear-gradient(135deg, #4caf50 0%, #2e7d32 100%); + color: #ffffff; + box-shadow: 0 4rpx 15rpx rgba(76, 175, 80, 0.3); +} + +/* 提交按钮闪光特效 */ +.submit-btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); + animation: flash 2s infinite; +} + +@keyframes flash { + 0% { left: -100%; } + 100% { left: 100%; } +} + +.btn-text { + position: relative; + z-index: 1; +} + +/* ==================== 弹窗样式 ==================== */ +.modal-container { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; +} + +.modal-mask { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); +} + +.modal-content { + position: relative; + width: 600rpx; + max-height: 70vh; + background-color: #ffffff; + border-radius: 20rpx; + overflow: hidden; + box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.15); + z-index: 1001; +} + +.modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 30rpx; + border-bottom: 1rpx solid #f0f0f0; +} + +.modal-title { + font-size: 34rpx; + color: #333333; + font-weight: 600; +} + +.modal-close { + font-size: 40rpx; + color: #999999; + width: 40rpx; + height: 40rpx; + display: flex; + align-items: center; + justify-content: center; +} + +.modal-body { + padding: 30rpx; + max-height: 50vh; + overflow: hidden; +} + +.modal-scroll { + height: 100%; + max-height: 50vh; +} + +.modal-content-text { + font-size: 28rpx; + line-height: 44rpx; + color: #333333; + white-space: pre-wrap; +} + +/* 响应式调整 */ +@media (max-width: 375px) { + .shangpin-image-container { + width: 160rpx; + height: 160rpx; + } + + .bottom-btn { + height: 80rpx; + font-size: 30rpx; + } + + .item-label { + min-width: 140rpx; + font-size: 26rpx; + } + + .item-value { + font-size: 26rpx; + } + + .modal-content { + width: 560rpx; + } +} \ No newline at end of file diff --git a/miniprogram/pages/fenlei/fenlei.js b/miniprogram/pages/fenlei/fenlei.js new file mode 100644 index 0000000..9cbf998 --- /dev/null +++ b/miniprogram/pages/fenlei/fenlei.js @@ -0,0 +1,452 @@ +// pages/fenlei/fenlei.js +const app = getApp() + +Page({ + /** + * 页面的初始数据 + */ + data: { + // 全局变量引用 + ossImageUrl: '', + + // 搜索相关 + searchText: '', + showSearchResult: false, + searchResults: [], + isSearching: false, + + // 页面数据 + shangpinleixing: [], + shangpinzhuanqu: [], + shangpinliebiao: [], + + // 状态控制 + selectedLeixingId: null, + selectedZhuanquId: null, + filteredZhuanquList: [], // 当前类型下的专区列表 + filteredShangpinList: [], // 当前专区下的商品列表 + zhuanquByLeixing: {}, // 类型->专区映射对象 + shangpinByZhuanqu: {}, // 专区->商品映射对象 + zhuanquGoodsCount: {}, // 专区商品数量统计 + + // UI状态 + isLoading: false, + hasInitialized: false + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + // 获取全局变量 + this.setData({ + ossImageUrl: app.globalData.ossImageUrl + }) + + // 初始化数据 + this.initPageData() + }, + onShow() { + // 原有代码... + + // 🆕 注册通知组件 + this.registerNotificationComponent(); +}, + +// 🆕 新增:注册通知组件 +registerNotificationComponent() { + const app = getApp(); + const notificationComp = this.selectComponent('#global-notification'); + + if (notificationComp && notificationComp.showNotification) { + console.log('🏪 商城页面注册通知组件'); + app.globalData.globalNotification = { + show: (data) => notificationComp.showNotification(data), + hide: () => notificationComp.hideNotification() + }; + } +}, + + /** + * 初始化页面数据 + */ + initPageData() { + const that = this + this.setData({ isLoading: true }) + + // 检查全局变量是否已有数据 + if (app.globalData.shangpinleixing && app.globalData.shangpinleixing.length > 0) { + this.initFromGlobalData() + } else { + this.loadAllShangpinData() + } + }, + + /** + * 从全局变量初始化数据 + */ + initFromGlobalData() { + const leixingList = app.globalData.shangpinleixing || [] + const zhuanquList = app.globalData.shangpinzhuanqu || [] + const shangpinList = app.globalData.shangpinliebiao || [] + + // 构建映射关系对象 + const zhuanquByLeixing = {} + const shangpinByZhuanqu = {} + const zhuanquGoodsCount = {} + + // 1. 构建专区映射 (按类型分组) + zhuanquList.forEach(zhuanqu => { + const leixingId = zhuanqu.leixing_id + if (!zhuanquByLeixing[leixingId]) { + zhuanquByLeixing[leixingId] = [] + } + zhuanquByLeixing[leixingId].push(zhuanqu) + }) + + // 2. 构建商品映射 (按专区分组)并统计数量 + shangpinList.forEach(shangpin => { + const zhuanquId = shangpin.zhuanqu_id + if (zhuanquId) { + if (!shangpinByZhuanqu[zhuanquId]) { + shangpinByZhuanqu[zhuanquId] = [] + zhuanquGoodsCount[zhuanquId] = 0 + } + + // 处理价格显示 + const jiage = parseFloat(shangpin.jiage) || 0 + const priceInteger = Math.floor(jiage) + let priceDecimal = '00' + + const decimalPart = (jiage - priceInteger).toFixed(2) + if (decimalPart > 0) { + priceDecimal = decimalPart.toString().split('.')[1] + } + + shangpinByZhuanqu[zhuanquId].push({ + id: shangpin.id, + biaoqian: shangpin.biaoqian, + jiage: jiage, + priceInteger: priceInteger, + priceDecimal: priceDecimal, + tupian_url: shangpin.tupian_url, + duiwai_xiaoliang: shangpin.duiwai_xiaoliang || 0 + }) + + zhuanquGoodsCount[zhuanquId] += 1 + } + }) + + // 设置初始选中状态(第一个类型和第一个专区) + const firstLeixing = leixingList[0] + let firstZhuanquId = null + + if (firstLeixing && zhuanquByLeixing[firstLeixing.id]) { + firstZhuanquId = zhuanquByLeixing[firstLeixing.id][0]?.id || null + } + + this.setData({ + shangpinleixing: leixingList, + shangpinzhuanqu: zhuanquList, + shangpinliebiao: shangpinList, + zhuanquByLeixing: zhuanquByLeixing, + shangpinByZhuanqu: shangpinByZhuanqu, + zhuanquGoodsCount: zhuanquGoodsCount, + selectedLeixingId: firstLeixing?.id || null, + selectedZhuanquId: firstZhuanquId + }, () => { + // 筛选数据 + this.filterData() + this.setData({ isLoading: false, hasInitialized: true }) + }) + }, + + /** + * 加载所有商品数据 + */ + loadAllShangpinData() { + const that = this + wx.request({ + url: app.globalData.apiBaseUrl + '/shangpin/shangpinhuoqu/', + method: 'POST', + header: { + 'content-type': 'application/json' + }, + success(res) { + if (res.statusCode === 200 && res.data) { + const data = res.data + + // 存储到全局变量 + app.globalData.shangpinleixing = data.shangpinleixing || [] + app.globalData.shangpinzhuanqu = data.shangpinzhuanqu || [] + app.globalData.shangpinliebiao = data.shangpinliebiao || [] + + // 从全局变量初始化 + that.initFromGlobalData() + } else { + that.handleLoadError() + } + }, + fail(error) { + console.error('加载商品数据失败:', error) + that.handleLoadError() + } + }) + }, + + /** + * 处理加载错误 + */ + handleLoadError() { + wx.showToast({ + title: '加载失败,请重试', + icon: 'none' + }) + this.setData({ isLoading: false }) + }, + + /** + * 筛选数据 + */ + filterData() { + const { selectedLeixingId, selectedZhuanquId, zhuanquByLeixing, shangpinByZhuanqu } = this.data + + // 1. 筛选专区列表 + const filteredZhuanquList = zhuanquByLeixing[selectedLeixingId] || [] + + // 2. 筛选商品列表 + let filteredShangpinList = [] + if (selectedZhuanquId) { + filteredShangpinList = shangpinByZhuanqu[selectedZhuanquId] || [] + } else if (filteredZhuanquList.length > 0) { + // 如果没有选中的专区,默认显示第一个专区的商品 + const firstZhuanquId = filteredZhuanquList[0].id + filteredShangpinList = shangpinByZhuanqu[firstZhuanquId] || [] + this.setData({ selectedZhuanquId: firstZhuanquId }) + } + + this.setData({ + filteredZhuanquList: filteredZhuanquList, + filteredShangpinList: filteredShangpinList + }) + }, + + /** + * 选择商品类型 + */ + selectLeixing(e) { + const leixingId = e.currentTarget.dataset.id + + if (this.data.selectedLeixingId === leixingId) { + return + } + + // 获取该类型下的第一个专区 + const zhuanquList = this.data.zhuanquByLeixing[leixingId] || [] + const firstZhuanquId = zhuanquList.length > 0 ? zhuanquList[0].id : null + + this.setData({ + selectedLeixingId: leixingId, + selectedZhuanquId: firstZhuanquId + }, () => { + this.filterData() + }) + }, + + /** + * 选择商品专区 + */ + selectZhuanqu(e) { + const zhuanquId = e.currentTarget.dataset.id + + if (this.data.selectedZhuanquId === zhuanquId) { + return + } + + this.setData({ + selectedZhuanquId: zhuanquId + }, () => { + // 筛选商品列表 + const filteredShangpinList = this.data.shangpinByZhuanqu[zhuanquId] || [] + this.setData({ + filteredShangpinList: filteredShangpinList + }) + }) + }, + + /** + * 搜索框输入事件 + */ + onSearchInput(e) { + this.setData({ + searchText: e.detail.value + }) + }, + + /** + * 点击搜索按钮 + */ + onSearchTap() { + const searchText = this.data.searchText.trim() + if (!searchText) { + wx.showToast({ + title: '请输入搜索内容', + icon: 'none' + }) + return + } + + // 开始搜索 + this.startSearch(searchText) + }, + + /** + * 键盘搜索事件(回车键) + */ + onSearchConfirm(e) { + const searchText = e.detail.value.trim() + if (!searchText) { + wx.showToast({ + title: '请输入搜索内容', + icon: 'none' + }) + return + } + + this.setData({ + searchText: searchText + }) + + // 开始搜索 + this.startSearch(searchText) + }, + + /** + * 执行搜索 + */ + startSearch(searchText) { + this.setData({ + isSearching: true, + showSearchResult: true + }) + + // 本地搜索 + const allShangpin = this.data.shangpinliebiao + const results = [] + + for (const item of allShangpin) { + if (item.biaoqian && item.biaoqian.toLowerCase().includes(searchText.toLowerCase())) { + // 处理价格显示 + const jiage = parseFloat(item.jiage) || 0 + const priceInteger = Math.floor(jiage) + let priceDecimal = '00' + + const decimalPart = (jiage - priceInteger).toFixed(2) + if (decimalPart > 0) { + priceDecimal = decimalPart.toString().split('.')[1] + } + + results.push({ + id: item.id, + biaoqian: item.biaoqian, + jiage: jiage, + priceInteger: priceInteger, + priceDecimal: priceDecimal, + tupian_url: item.tupian_url, + leixing_name: this.getLeixingName(item.leixing_id), + zhuanqu_name: this.getZhuanquName(item.zhuanqu_id) + }) + } + } + + this.setData({ + searchResults: results, + isSearching: false + }) + }, + + /** + * 清空搜索 + */ + onClearSearch() { + this.setData({ + searchText: '', + showSearchResult: false, + searchResults: [] + }) + }, + + /** + * 根据类型ID获取类型名称 + */ + getLeixingName(leixingId) { + const leixingList = this.data.shangpinleixing + for (const item of leixingList) { + if (item.id === leixingId) { + return item.jieshao + } + } + return '' + }, + + /** + * 根据专区ID获取专区名称 + */ + getZhuanquName(zhuanquId) { + const zhuanquList = this.data.shangpinzhuanqu + for (const item of zhuanquList) { + if (item.id === zhuanquId) { + return item.mingzi + } + } + return '' + }, + + /** + * 跳转到商品详情页 + */ + goToDetail(e) { + const shangpinId = e.currentTarget.dataset.id + if (!shangpinId) return + + wx.navigateTo({ + url: `/pages/shangpinxiangqing/shangpinxiangqing?id=${shangpinId}` + }) + }, + + /** + * 刷新所有数据 + */ + onRefresh() { + wx.showLoading({ + title: '刷新中...', + mask: true + }) + + // 清空全局变量 + app.globalData.shangpinleixing = [] + app.globalData.shangpinzhuanqu = [] + app.globalData.shangpinliebiao = [] + + this.loadAllShangpinData() + + setTimeout(() => { + wx.hideLoading() + wx.showToast({ + title: '刷新成功', + icon: 'success', + duration: 1500 + }) + }, 1000) + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + return { + title: '阿龙电竞 - 商品分类', + path: '/pages/fenlei/fenlei' + } + } +}) \ No newline at end of file diff --git a/miniprogram/pages/fenlei/fenlei.json b/miniprogram/pages/fenlei/fenlei.json new file mode 100644 index 0000000..4af9065 --- /dev/null +++ b/miniprogram/pages/fenlei/fenlei.json @@ -0,0 +1,6 @@ +{ + "usingComponents": { + "global-notification": "/components/global-notification/global-notification", + "custom-tab-bar": "/custom-tab-bar/index" + } + } \ No newline at end of file diff --git a/miniprogram/pages/fenlei/fenlei.wxml b/miniprogram/pages/fenlei/fenlei.wxml new file mode 100644 index 0000000..6f015fa --- /dev/null +++ b/miniprogram/pages/fenlei/fenlei.wxml @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + 搜索 + + + + + + + + + + + + + + + {{item.jieshao}} + + + + + + + + + + + + + + + + {{item.mingzi}} + ({{zhuanquGoodsCount[item.id] || 0}}) + + + + + + + + 暂无专区 + + + + + + + + + + + + + + + + {{item.biaoqian}} + + + + + ¥ + {{item.priceInteger}} + .{{item.priceDecimal}} + + + 了解详情 + + + + + + + + + + + 该专区暂无商品 + + + + + — 已加载全部商品 — + + + + + + + + + + + 搜索结果 + ({{searchResults.length}}个) + + + + + + + + + + + + + + {{item.biaoqian}} + + {{item.leixing_name}} + · + {{item.zhuanqu_name}} + + + ¥ + {{item.priceInteger}} + .{{item.priceDecimal}} + + + + + + + + 未找到相关商品 + + + + + + + 搜索中... + + + + + + + + + + + + + 加载中... + + + + + + + \ No newline at end of file diff --git a/miniprogram/pages/fenlei/fenlei.wxss b/miniprogram/pages/fenlei/fenlei.wxss new file mode 100644 index 0000000..d4a3420 --- /dev/null +++ b/miniprogram/pages/fenlei/fenlei.wxss @@ -0,0 +1,1215 @@ +/* pages/fenlei/fenlei.wxss */ +.fenlei-page { + width: 100%; + height: 100vh; + background: linear-gradient(135deg, #f8f9ff 0%, #f0f2ff 100%); + display: flex; + flex-direction: column; + position: relative; + overflow: hidden; + } + + /* 1. 毛玻璃搜索框区域(固定) */ + .search-container { + padding: 24rpx 32rpx; + background: transparent; + flex-shrink: 0; + position: relative; + z-index: 100; + } + + .search-box { + display: flex; + align-items: center; + background: rgba(255, 255, 255, 0.85); + backdrop-filter: blur(30rpx); + -webkit-backdrop-filter: blur(30rpx); + border-radius: 50rpx; + padding: 0 28rpx; + height: 84rpx; + box-shadow: + 0 8rpx 32rpx rgba(31, 38, 135, 0.1), + inset 0 1rpx 0 rgba(255, 255, 255, 0.8); + border: 1rpx solid rgba(255, 255, 255, 0.3); + position: relative; + overflow: hidden; + } + + .search-box::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.1)); + border-radius: 50rpx; + z-index: -1; + } + + .search-icon { + width: 34rpx; + height: 34rpx; + margin-right: 18rpx; + opacity: 0.6; + } + + .search-input { + flex: 1; + height: 100%; + font-size: 28rpx; + color: #222; + font-weight: 400; + } + + .search-placeholder { + color: #aaa; + font-size: 28rpx; + } + + .search-btn { + background: linear-gradient(135deg, #ffcc00, #ffaa00); + border-radius: 40rpx; + padding: 14rpx 32rpx; + margin-left: 20rpx; + position: relative; + overflow: hidden; + box-shadow: 0 6rpx 20rpx rgba(255, 170, 0, 0.3); + transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); + } + + .search-btn:active { + transform: scale(0.95); + box-shadow: 0 4rpx 15rpx rgba(255, 170, 0, 0.4); + } + + .search-btn-text { + font-size: 26rpx; + color: white; + font-weight: 600; + position: relative; + z-index: 1; + } + + .search-btn-glow { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent); + transform: translateX(-100%); + transition: transform 0.6s; + } + + .search-btn:active .search-btn-glow { + transform: translateX(100%); + } + + .search-clear { + width: 36rpx; + height: 36rpx; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin-left: 16rpx; + opacity: 0.6; + transition: opacity 0.3s; + } + + .search-clear:active { + opacity: 1; + } + + .clear-icon { + width: 24rpx; + height: 24rpx; + } + + /* 2. 商品类型选择区域(固定)- 恢复原大小 */ + .leixing-container { + padding: 0 32rpx 24rpx; + flex-shrink: 0; + position: relative; + } + + .leixing-bg-glow { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 300rpx; + height: 300rpx; + background: radial-gradient(circle, rgba(255, 204, 0, 0.1) 0%, transparent 70%); + z-index: -1; + } + + .leixing-scroll { + white-space: nowrap; + height: 180rpx; /* 恢复原大小 */ + } + + .leixing-list { + display: inline-flex; + padding-right: 32rpx; + } + + .leixing-item { + display: inline-flex; + flex-direction: column; + align-items: center; + margin-right: 48rpx; /* 增加间距 */ + position: relative; + padding: 12rpx; + } + + .leixing-image-box { + width: 100rpx; /* 恢复原大小 */ + height: 100rpx; /* 恢复原大小 */ + border-radius: 50%; + position: relative; + margin-bottom: 16rpx; + overflow: hidden; + background: white; + box-shadow: + 0 12rpx 30rpx rgba(0, 0, 0, 0.12), + 0 4rpx 8rpx rgba(0, 0, 0, 0.06); + transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); + } + + .leixing-active .leixing-image-box { + transform: scale(1.12); + box-shadow: + 0 18rpx 40rpx rgba(255, 204, 0, 0.3), + 0 8rpx 16rpx rgba(255, 170, 0, 0.2); + } + + .leixing-image { + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; + } + + .leixing-glow { + position: absolute; + top: -3rpx; + left: -3rpx; + right: -3rpx; + bottom: -3rpx; + border-radius: 50%; + background: linear-gradient(135deg, #ffcc00, #ffaa00, #ff8800); + opacity: 0; + transition: opacity 0.4s; + z-index: -1; + filter: blur(10rpx); + } + + .leixing-glow-active { + opacity: 0.6; + animation: glowPulse 2s infinite; + } + + .leixing-sparkle { + position: absolute; + top: 50%; + left: 50%; + width: 20rpx; + height: 20rpx; + background: white; + border-radius: 50%; + transform: translate(-50%, -50%) scale(0); + opacity: 0; + pointer-events: none; + } + + .sparkle-animation { + animation: sparkleFlash 1.5s infinite; + } + + .leixing-text { + font-size: 24rpx; + color: #555; /* 颜色加深 */ + font-weight: 500; + transition: all 0.3s; + white-space: nowrap; + } + + .leixing-active .leixing-text { + color: #ff9900; + font-weight: 600; + transform: translateY(-2rpx); + text-shadow: 0 2rpx 4rpx rgba(255, 153, 0, 0.2); + } + + .leixing-active-bar { + position: absolute; + bottom: -4rpx; + width: 44rpx; + height: 4rpx; + background: linear-gradient(90deg, #ffcc00, #ffaa00); + border-radius: 2rpx; + opacity: 0; + transform: scaleX(0); + transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); + box-shadow: 0 2rpx 8rpx rgba(255, 170, 0, 0.4); + } + + .leixing-active-bar-show { + opacity: 1; + transform: scaleX(1); + } + + .leixing-border-effect { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 50%; + border: 2rpx solid transparent; + opacity: 0; + pointer-events: none; + } + + .border-effect-active { + opacity: 1; + border-color: rgba(255, 204, 0, 0.5); + animation: borderGlow 2s infinite; + } + + /* 3. 左右分栏布局(可滚动区域) */ + .main-container { + flex: 1; + display: flex; + height: calc(100vh - 300rpx); + overflow: hidden; + } + + /* 左边:商品专区列表 */ + .zhuanqu-left { + width: 200rpx; + background: rgba(255, 255, 255, 0.7); + backdrop-filter: blur(10rpx); + border-right: 1rpx solid rgba(0, 0, 0, 0.08); + flex-shrink: 0; + position: relative; + } + + .zhuanqu-list { + padding: 0; + } + + .zhuanqu-item { + position: relative; + padding: 32rpx 0; + border-bottom: 1rpx solid rgba(0, 0, 0, 0.05); + transition: all 0.3s; + } + + .zhuanqu-item:active { + background: rgba(255, 204, 0, 0.05); + } + + .zhuanqu-item-content { + display: flex; + flex-direction: column; + align-items: center; + padding: 0 20rpx; + } + + .zhuanqu-name { + font-size: 26rpx; + color: #444; /* 颜色加深 */ + text-align: center; + line-height: 1.4; + margin-bottom: 8rpx; + transition: all 0.3s; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + font-weight: 500; + } + + .zhuanqu-active .zhuanqu-name { + color: #ff9900; + font-weight: 600; + text-shadow: 0 2rpx 4rpx rgba(255, 153, 0, 0.2); + } + + .zhuanqu-count { + font-size: 22rpx; + color: #888; + transition: all 0.3s; + } + + .zhuanqu-active .zhuanqu-count { + color: #ffaa00; + font-weight: 500; + } + + .zhuanqu-active-indicator { + position: absolute; + right: 0; + top: 50%; + transform: translateY(-50%); + width: 6rpx; + height: 44rpx; + background: linear-gradient(180deg, #ffcc00, #ffaa00); + border-radius: 3rpx 0 0 3rpx; + opacity: 0; + transition: all 0.3s; + overflow: hidden; + } + + .zhuanqu-indicator-glow { + opacity: 1; + animation: indicatorGlow 2s infinite; + box-shadow: 0 0 20rpx rgba(255, 204, 0, 0.5); + } + + .indicator-sparkle { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 10rpx; + background: rgba(255, 255, 255, 0.6); + animation: sparkleMove 1.5s infinite; + } + + .zhuanqu-hover-glow { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(90deg, transparent, rgba(255, 204, 0, 0.05), transparent); + opacity: 0; + transition: opacity 0.3s; + pointer-events: none; + } + + .zhuanqu-item:active .zhuanqu-hover-glow { + opacity: 1; + } + + .zhuanqu-click-effect { + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + border-radius: 50%; + background: rgba(255, 204, 0, 0.1); + transform: translate(-50%, -50%); + opacity: 0; + pointer-events: none; + } + + .zhuanqu-item:active .zhuanqu-click-effect { + animation: rippleEffect 0.6s ease-out; + } + + .zhuanqu-empty { + display: flex; + flex-direction: column; + align-items: center; + padding: 120rpx 0; + } + + .zhuanqu-empty-icon { + width: 120rpx; + height: 120rpx; + opacity: 0.2; + margin-bottom: 28rpx; + } + + .zhuanqu-empty-text { + font-size: 26rpx; + color: #999; + } + + /* 右边:商品列表(紧凑布局) */ + .shangpin-right { + flex: 1; + background: #fafafa; + } + + .shangpin-list { + padding: 0; + } + + .shangpin-item { + background: white; + padding: 28rpx 30rpx 22rpx; /* 底部距离缩小 */ + position: relative; + display: flex; + align-items: flex-start; + min-height: 140rpx; + overflow: hidden; + } + + .shangpin-item:active { + background: rgba(0, 0, 0, 0.02); + } + + .shangpin-image-box { + margin-right: 24rpx; + flex-shrink: 0; + position: relative; + } + + .shangpin-image { + width: 120rpx; + height: 120rpx; + border-radius: 14rpx; + background: #f5f5f5; + object-fit: cover; + } + + .shangpin-image-glow { + position: absolute; + top: -4rpx; + left: -4rpx; + right: -4rpx; + bottom: -4rpx; + border-radius: 18rpx; + background: linear-gradient(135deg, rgba(255, 204, 0, 0.2), transparent); + opacity: 0; + transition: opacity 0.3s; + pointer-events: none; + } + + .shangpin-item:active .shangpin-image-glow { + opacity: 0.5; + } + + .image-corner { + position: absolute; + top: 0; + right: 0; + width: 20rpx; + height: 20rpx; + background: linear-gradient(135deg, #ffcc00, transparent 70%); + border-radius: 0 14rpx 0 0; + } + + .shangpin-info { + flex: 1; + display: flex; + flex-direction: column; + height: 120rpx; + justify-content: space-between; + padding-top: 2rpx; /* 标题与图片顶部对齐 */ + } + + .shangpin-title { + margin-bottom: 0; + position: relative; + } + + .shangpin-title-text { + font-size: 30rpx; + font-weight: 500; + color: #222; /* 黑色加深 */ + line-height: 1.4; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; + overflow: hidden; + } + + .title-underline { + position: absolute; + bottom: -4rpx; + left: 0; + width: 0; + height: 2rpx; + background: linear-gradient(90deg, #ffcc00, #ffaa00); + transition: width 0.3s; + } + + .shangpin-item:active .title-underline { + width: 40rpx; + } + + .shangpin-footer { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: auto; + } + + .shangpin-price { + display: flex; + align-items: baseline; + position: relative; + } + + .price-icon { + font-size: 24rpx; + color: #ff6600; + font-weight: 500; + } + + .price-integer { + font-size: 36rpx; /* 适当调整大小 */ + color: #ff6600; + font-weight: 600; + margin-left: 2rpx; + } + + .price-decimal { + font-size: 24rpx; + color: #ff6600; + font-weight: 500; + } + + .price-glow { + position: absolute; + top: 50%; + left: 50%; + width: 80rpx; + height: 80rpx; + background: radial-gradient(circle, rgba(255, 102, 0, 0.1) 0%, transparent 70%); + transform: translate(-50%, -50%); + opacity: 0; + pointer-events: none; + } + + .shangpin-item:active .price-glow { + animation: priceGlow 0.6s; + } + + .detail-btn { + position: relative; + padding: 12rpx 28rpx; + background: linear-gradient(135deg, #ffcc00, #ffaa00); + border-radius: 40rpx; + transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); + overflow: hidden; + box-shadow: 0 6rpx 20rpx rgba(255, 170, 0, 0.2); + display: flex; + align-items: center; + justify-content: center; + min-width: 120rpx; + } + + .detail-btn:active { + transform: scale(0.95); + box-shadow: 0 4rpx 15rpx rgba(255, 170, 0, 0.4); + } + + .detail-btn-text { + font-size: 24rpx; + color: white; + font-weight: 500; + position: relative; + z-index: 2; + line-height: 1; + } + + .btn-glow-effect { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent); + transform: translateX(-100%); + transition: transform 0.6s; + } + + .detail-btn:active .btn-glow-effect { + transform: translateX(100%); + } + + .btn-halo { + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + border-radius: 50%; + background: rgba(255, 255, 255, 0.3); + transform: translate(-50%, -50%); + opacity: 0; + pointer-events: none; + } + + .detail-btn:active .btn-halo { + animation: buttonHalo 0.6s ease-out; + } + + .btn-star { + position: absolute; + width: 6rpx; + height: 6rpx; + background: white; + border-radius: 50%; + opacity: 0; + pointer-events: none; + } + + .detail-btn:active .btn-star { + animation: starSparkle 0.8s ease-out; + } + + .item-divider { + position: absolute; + left: 30rpx; + right: 30rpx; + bottom: 0; + height: 1rpx; + background: linear-gradient(90deg, rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.08)); + } + + .item-hover-glow { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(135deg, transparent, rgba(255, 204, 0, 0.03), transparent); + opacity: 0; + transition: opacity 0.3s; + pointer-events: none; + } + + .shangpin-item:active .item-hover-glow { + opacity: 1; + } + + .item-ripple-effect { + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + border-radius: 50%; + background: rgba(255, 204, 0, 0.1); + transform: translate(-50%, -50%); + opacity: 0; + pointer-events: none; + } + + .shangpin-item:active .item-ripple-effect { + animation: rippleEffect 0.6s ease-out; + } + + .shangpin-empty { + display: flex; + flex-direction: column; + align-items: center; + padding: 150rpx 0; + } + + .shangpin-empty-icon { + width: 180rpx; + height: 180rpx; + opacity: 0.15; + margin-bottom: 36rpx; + } + + .shangpin-empty-text { + font-size: 28rpx; + color: #999; + margin-bottom: 40rpx; + } + + .shangpin-empty-btn { + background: linear-gradient(135deg, #ffcc00, #ffaa00); + color: white; + font-size: 26rpx; + font-weight: 500; + padding: 16rpx 44rpx; + border-radius: 40rpx; + box-shadow: 0 8rpx 24rpx rgba(255, 170, 0, 0.3); + transition: all 0.3s; + } + + .shangpin-empty-btn:active { + transform: scale(0.95); + box-shadow: 0 4rpx 16rpx rgba(255, 170, 0, 0.4); + } + + .load-more { + display: flex; + align-items: center; + justify-content: center; + padding: 40rpx 0; + } + + .load-more-line { + width: 60rpx; + height: 1rpx; + background: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.1), transparent); + } + + .load-more-text { + font-size: 24rpx; + color: #bbb; + margin: 0 20rpx; + } + + /* 搜索结果弹窗 */ + .search-results-container { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 2000; + display: flex; + } + + .search-mask { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(5rpx); + } + + .search-results-content { + position: absolute; + top: 100rpx; + left: 32rpx; + right: 32rpx; + bottom: 100rpx; + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(30rpx); + border-radius: 24rpx; + box-shadow: + 0 20rpx 60rpx rgba(0, 0, 0, 0.2), + inset 0 1rpx 0 rgba(255, 255, 255, 0.8); + border: 1rpx solid rgba(255, 255, 255, 0.3); + display: flex; + flex-direction: column; + overflow: hidden; + } + + .search-results-header { + padding: 32rpx; + border-bottom: 1rpx solid rgba(0, 0, 0, 0.06); + display: flex; + align-items: center; + justify-content: space-between; + flex-shrink: 0; + } + + .search-header-left { + display: flex; + align-items: baseline; + } + + .search-results-title { + font-size: 34rpx; + font-weight: 600; + color: #333; + } + + .search-results-count { + font-size: 24rpx; + color: #999; + margin-left: 12rpx; + } + + .search-close { + width: 44rpx; + height: 44rpx; + border-radius: 50%; + background: rgba(0, 0, 0, 0.05); + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s; + } + + .search-close:active { + background: rgba(0, 0, 0, 0.1); + transform: scale(0.9); + } + + .close-icon { + width: 20rpx; + height: 20rpx; + opacity: 0.6; + } + + .search-results-list { + flex: 1; + height: 100%; /* 新增:修复滚动问题的关键代码 */ + } + + .search-result-item { + display: flex; + padding: 28rpx 32rpx; + border-bottom: 1rpx solid rgba(0, 0, 0, 0.04); + position: relative; + transition: all 0.3s; + } + + .search-result-item:active { + background: rgba(0, 0, 0, 0.02); + transform: translateY(-2rpx); + } + + .search-result-left { + margin-right: 24rpx; + position: relative; + } + + .search-result-image { + width: 120rpx; + height: 120rpx; + border-radius: 16rpx; + background: #f5f5f5; + object-fit: cover; + } + + .search-image-glow { + position: absolute; + top: -4rpx; + left: -4rpx; + right: -4rpx; + bottom: -4rpx; + border-radius: 20rpx; + background: linear-gradient(135deg, rgba(255, 204, 0, 0.2), transparent); + opacity: 0; + transition: opacity 0.3s; + pointer-events: none; + } + + .search-result-item:active .search-image-glow { + opacity: 0.5; + } + + .search-result-right { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + } + + .search-result-title { + font-size: 28rpx; + font-weight: 500; + color: #333; + line-height: 1.4; + margin-bottom: 16rpx; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + } + + .search-result-info { + display: flex; + gap: 12rpx; + margin-bottom: 20rpx; + } + + .info-tag { + padding: 6rpx 12rpx; + background: rgba(255, 204, 0, 0.1); + border-radius: 6rpx; + } + + .search-result-category { + font-size: 22rpx; + color: #666; + } + + .search-result-zhuanqu { + font-size: 22rpx; + color: #888; + } + + .search-result-price { + display: flex; + align-items: baseline; + } + + .search-item-glow { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(135deg, transparent, rgba(255, 204, 0, 0.05), transparent); + opacity: 0; + transition: opacity 0.3s; + pointer-events: none; + } + + .search-result-item:active .search-item-glow { + opacity: 1; + } + + .search-empty { + display: flex; + flex-direction: column; + align-items: center; + padding: 160rpx 0; + } + + .search-empty-icon { + width: 160rpx; + height: 160rpx; + opacity: 0.2; + margin-bottom: 36rpx; + } + + .search-empty-text { + font-size: 30rpx; + color: #999; + margin-bottom: 16rpx; + } + + .search-empty-tip { + font-size: 24rpx; + color: #bbb; + } + + .search-loading { + display: flex; + flex-direction: column; + align-items: center; + padding: 160rpx 0; + } + + .search-spinner { + width: 60rpx; + height: 60rpx; + position: relative; + margin-bottom: 24rpx; + } + + .spinner-circle { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border: 4rpx solid transparent; + border-top-color: #ffcc00; + border-radius: 50%; + animation: spin 1s linear infinite; + } + + .search-loading-text { + font-size: 26rpx; + color: #999; + } + + /* 全局加载状态 */ + .loading-toast { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.7); + backdrop-filter: blur(10rpx); + display: flex; + align-items: center; + justify-content: center; + z-index: 3000; + } + + .loading-content { + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(20rpx); + padding: 60rpx 80rpx; + border-radius: 24rpx; + display: flex; + flex-direction: column; + align-items: center; + position: relative; + border: 1rpx solid rgba(255, 255, 255, 0.1); + } + + .loading-spinner { + width: 80rpx; + height: 80rpx; + position: relative; + margin-bottom: 30rpx; + } + + .spinner-ring { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border: 4rpx solid rgba(255, 255, 255, 0.2); + border-radius: 50%; + } + + .spinner-dot { + position: absolute; + top: 0; + left: 50%; + width: 12rpx; + height: 12rpx; + background: #ffcc00; + border-radius: 50%; + transform: translateX(-50%); + animation: spin 1s linear infinite; + } + + .loading-text { + font-size: 28rpx; + color: white; + font-weight: 500; + } + + .loading-glow { + position: absolute; + top: 50%; + left: 50%; + width: 200rpx; + height: 200rpx; + background: radial-gradient(circle, rgba(255, 204, 0, 0.2) 0%, transparent 70%); + transform: translate(-50%, -50%); + z-index: -1; + } + + /* 动画定义 */ + @keyframes glowPulse { + 0%, 100% { + opacity: 0.4; + transform: scale(1); + } + 50% { + opacity: 0.8; + transform: scale(1.05); + } + } + + @keyframes sparkleFlash { + 0%, 100% { + opacity: 0; + transform: translate(-50%, -50%) scale(0); + } + 50% { + opacity: 1; + transform: translate(-50%, -50%) scale(1); + filter: blur(0); + } + } + + @keyframes borderGlow { + 0%, 100% { + border-color: rgba(255, 204, 0, 0.3); + } + 50% { + border-color: rgba(255, 204, 0, 0.8); + } + } + + @keyframes indicatorGlow { + 0%, 100% { + box-shadow: 0 0 20rpx rgba(255, 204, 0, 0.3); + } + 50% { + box-shadow: 0 0 30rpx rgba(255, 204, 0, 0.8); + } + } + + @keyframes sparkleMove { + 0% { + transform: translateY(-100%); + opacity: 0; + } + 50% { + opacity: 1; + } + 100% { + transform: translateY(400%); + opacity: 0; + } + } + + @keyframes rippleEffect { + 0% { + width: 0; + height: 0; + opacity: 0.5; + } + 100% { + width: 200rpx; + height: 200rpx; + opacity: 0; + } + } + + @keyframes priceGlow { + 0% { + opacity: 0; + transform: translate(-50%, -50%) scale(0.5); + } + 50% { + opacity: 0.6; + transform: translate(-50%, -50%) scale(1); + } + 100% { + opacity: 0; + transform: translate(-50%, -50%) scale(1.5); + } + } + + @keyframes buttonHalo { + 0% { + width: 0; + height: 0; + opacity: 0.6; + } + 100% { + width: 200rpx; + height: 200rpx; + opacity: 0; + } + } + + @keyframes starSparkle { + 0% { + opacity: 0; + transform: translate(0, 0) scale(0); + } + 20% { + opacity: 1; + transform: translate(-40rpx, -30rpx) scale(1); + } + 40% { + opacity: 1; + transform: translate(30rpx, -20rpx) scale(1); + } + 60% { + opacity: 1; + transform: translate(-20rpx, 40rpx) scale(1); + } + 80% { + opacity: 1; + transform: translate(40rpx, 20rpx) scale(1); + } + 100% { + opacity: 0; + transform: translate(0, 0) scale(0); + } + } + + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } \ No newline at end of file diff --git a/miniprogram/pages/guanshiduan/guanshiduan.js b/miniprogram/pages/guanshiduan/guanshiduan.js new file mode 100644 index 0000000..2aba158 --- /dev/null +++ b/miniprogram/pages/guanshiduan/guanshiduan.js @@ -0,0 +1,548 @@ +// pages/guanshizhongxin/guanshizhongxin.js +import request from '../../utils/request.js'; +import popupService from '../../services/popupService.js'; +import { getDefaultInviteCode } from '../../utils/default-invite-code.js'; +import { getGroupImgUrls, GUANSHIDUAN_DEFAULTS, buildOssUrl } from '../../utils/page-assets.js'; + +Page({ + data: { + // 图片路径对象(逻辑层拼接完整URL) + imgUrls: {}, + + isGuanshi: false, + isLoading: false, + inviteCode: '', + uid: '', + nicheng: '', + avatarUrl: '', + + // 管事信息 + gszhstatus: '', + yaoqingzongshu: 0, + fenyongzonge: '0.00', + fenyongtixian: '0.00', + yichongzhiDashou: 0, + zhuanhualv: 0, + + // 称号列表 + chenghaoList: [], + + // 邀请人(组长)缓存 + inviterCache: null, + }, + + onLoad(options) { + const app = getApp(); + this._onConfigReady = () => this.initImageUrls(); + app.on('configReady', this._onConfigReady); + this.initImageUrls(); + + // 处理扫码 scene + if (options.scene) { + try { + const scene = decodeURIComponent(options.scene); + options.inviteCode = scene; + } catch (e) { + console.error('scene解码失败', e); + } + } + + this.checkGuanshiStatus(); + + const { inviteCode } = options || {}; + if (inviteCode) { + this.setData({ inviteCode }); + setTimeout(() => { + this.handleInviteCodeWithLoginCheck(inviteCode); + }, 500); + } + + if (!app.globalData.hasShownPopupOnColdStart) { + app.globalData.hasShownPopupOnColdStart = true; + setTimeout(() => { + popupService.checkAndShow(this, 'guanshiduan'); + }, 300); + } + }, + + onHide() { + const popupComp = this.selectComponent('#popupNotice'); + if (popupComp && popupComp.cleanup) { + popupComp.cleanup(); + } + }, + + onUnload() { + if (this._onConfigReady) { + getApp().off('configReady', this._onConfigReady); + } + }, + + initImageUrls() { + const urls = getGroupImgUrls('guanshiduan', GUANSHIDUAN_DEFAULTS); + const g = getApp().globalData; + urls.avatarDefault = buildOssUrl(g.morentouxiang || GUANSHIDUAN_DEFAULTS.avatarDefault); + this.setData({ imgUrls: urls }); + }, + + onShow() { + this.initImageUrls(); + const inviterCache = wx.getStorageSync('inviterCache') || null; + this.setData({ inviterCache }); + + this.registerNotificationComponent(); + + if (this.data.isGuanshi) { + setTimeout(() => { + this.getGuanshiInfo(); + this.fetchChenghaoList(); + }, 300); + } + + const pages = getCurrentPages(); + const currentPage = pages[pages.length - 1]; + const options = currentPage.options || {}; + if (options.inviteCode && !this.data.isGuanshi) { + setTimeout(() => { + this.handleInviteCodeWithLoginCheck(options.inviteCode); + }, 300); + } + }, + + // ========== 全局通知注册 ========== + registerNotificationComponent() { + const app = getApp(); + const comp = this.selectComponent('#global-notification'); + if (comp && comp.showNotification) { + app.globalData.globalNotification = { + show: (data) => comp.showNotification(data), + hide: () => comp.hideNotification() + }; + } + }, + + // ========== 称号列表(新接口,区分管事) ========== + async fetchChenghaoList() { + try { + const res = await request({ + url: '/dengji/chenghao', + method: 'POST', + data: { role: 'guanshi' } + }); + if (res && res.data.code === 0 && res.data.data) { + this.setData({ chenghaoList: res.data.data.chenghao_list || [] }); + } + } catch (e) { + console.error('获取称号失败', e); + } + }, + + // ========== 联系组长(新接口) ========== + // 管事联系组长 —— 获取组长信息并跳转聊天 + // 管事联系组长 +async contactInviter() { + wx.showLoading({ title: '获取组长信息...', mask: true }); + try { + const res = await request({ + url: '/yonghu/guanshi_contact', + method: 'POST' + }); + + if (res && res.data.code === 200 && res.data.data) { + const inviter = res.data.data; + const ossImageUrl = getApp().globalData.ossImageUrl || ''; + const fullAvatar = inviter.touxiang + ? (inviter.touxiang.startsWith('http') ? inviter.touxiang : ossImageUrl + inviter.touxiang) + : ''; + + // 缓存邀请人信息 + const cacheData = { + uid: inviter.uid, + nicheng: inviter.nicheng || '', + avatar: fullAvatar + }; + wx.setStorageSync('inviterCache', cacheData); + this.setData({ inviterCache: cacheData }); + + // 跳转聊天(组长前缀请确认,默认 'Zz') + const param = { + toUserId: 'Zz' + inviter.uid, + toName: inviter.nicheng || '组长', + toAvatar: fullAvatar + }; + wx.navigateTo({ + url: '/pages/liaotian/liaotian?data=' + encodeURIComponent(JSON.stringify(param)) + }); + } else { + wx.showToast({ title: '未绑定邀请人', icon: 'none' }); + } + } catch (e) { + wx.showToast({ title: '网络错误', icon: 'none' }); + } finally { + wx.hideLoading(); + } +}, + // ========== 邀请码处理(完全照搬打手端) ========== + handleInviteCodeWithLoginCheck(inviteCode) { + const token = wx.getStorageSync('token'); + const uid = wx.getStorageSync('uid'); + if (!token || !uid) { + this.loginAndRegisterWithInviteCode(inviteCode); + } else { + if (!this.data.isGuanshi) { + wx.showLoading({ title: '自动注册中...', mask: true }); + this.callRegisterApi(inviteCode); + } else { + wx.showToast({ title: '您已是管事', icon: 'success' }); + } + } + }, + + loginAndRegisterWithInviteCode(inviteCode) { + const that = this; + wx.showLoading({ title: '登录注册中...', mask: true }); + wx.login({ + success: (loginRes) => { + if (loginRes.code) { + that.callLoginRegisterApi(loginRes.code, inviteCode); + } else { + wx.hideLoading(); + wx.showToast({ title: '微信登录失败', icon: 'none' }); + } + }, + fail: () => { + wx.hideLoading(); + wx.reLaunch({ url: '/pages/gerenzhongxin/gerenzhongxin' }); + } + }); + }, + + callLoginRegisterApi(code, inviteCode) { + const that = this; + const app = getApp(); + const apiBaseUrl = app.globalData.apiBaseUrl; + if (!apiBaseUrl) { + wx.hideLoading(); + wx.showToast({ title: '服务器配置错误', icon: 'none' }); + return; + } + wx.request({ + url: apiBaseUrl + '/yonghu/zuzhangyqmzc', + method: 'POST', + data: { code: code, inviteCode: inviteCode }, + header: { 'content-type': 'application/json' }, + success: (res) => { + if (res.statusCode === 200 && res.data && res.data.code === 200 && res.data.data) { + const userData = res.data.data; + if (userData.token) wx.setStorageSync('token', userData.token); + const identityFields = ['nicheng', 'uid', 'touxiang', 'dashoustatus', 'guanshistatus', 'shangjiastatus', 'zuzhangstatus']; + identityFields.forEach(field => { + if (userData[field] !== undefined) { + wx.setStorageSync(field, userData[field]); + app.globalData[field] = userData[field]; + } + }); + if (userData.guanshistatus === undefined) { + wx.setStorageSync('guanshistatus', 1); + app.globalData.guanshistatus = 1; + } + const groupFields = ['dashouqun', 'dashouqunid', 'guanshiqun', 'guanshiqunid']; + groupFields.forEach(field => { + if (userData[field] !== undefined) { + wx.setStorageSync(field, userData[field]); + app.globalData[field] = userData[field]; + } + }); + const guanshiData = { + gszhstatus: userData.gszhstatus || '', + yaoqingzongshu: userData.yaoqingzongshu || 0, + fenyongzonge: userData.fenyongzonge || '0.00', + fenyongtixian: userData.fenyongtixian || '0.00', + yichongzhiDashou: userData.yichongzhiDashou || 0 + }; + if (!app.globalData.guanshi) app.globalData.guanshi = {}; + Object.assign(app.globalData.guanshi, guanshiData); + const zhuanhualv = guanshiData.yaoqingzongshu > 0 + ? (guanshiData.yichongzhiDashou / guanshiData.yaoqingzongshu * 100).toFixed(1) + : 0; + that.setData({ + isGuanshi: true, + uid: userData.uid || '', + nicheng: userData.nicheng || '', + ...guanshiData, + zhuanhualv, + isLoading: false + }); + that.loadUserInfo(); + that.switchToGuanshiRole(); + wx.hideLoading(); + wx.showToast({ title: '注册成功!', icon: 'success', duration: 2000 }); + } else { + wx.hideLoading(); + wx.showToast({ title: (res.data && res.data.msg) || '注册失败', icon: 'none' }); + } + }, + fail: () => { + wx.hideLoading(); + wx.showToast({ title: '网络请求失败', icon: 'none' }); + } + }); + }, + + async callRegisterApi(inviteCode) { + try { + const res = await request({ + url: '/yonghu/guanshizhuce', + method: 'POST', + data: { inviteCode } + }); + if (res && res.data.code === 200 && res.data.data) { + const userData = res.data.data; + const identityFields = ['nicheng', 'uid', 'touxiang', 'dashoustatus', 'guanshistatus', 'shangjiastatus', 'zuzhangstatus']; + const app = getApp(); + identityFields.forEach(field => { + if (userData[field] !== undefined) { + wx.setStorageSync(field, userData[field]); + app.globalData[field] = userData[field]; + } + }); + if (userData.guanshistatus === undefined) { + wx.setStorageSync('guanshistatus', 1); + app.globalData.guanshistatus = 1; + } + const guanshiData = { + gszhstatus: userData.gszhstatus || '', + yaoqingzongshu: userData.yaoqingzongshu || 0, + fenyongzonge: userData.fenyongzonge || '0.00', + fenyongtixian: userData.fenyongtixian || '0.00', + yichongzhiDashou: userData.yichongzhiDashou || 0 + }; + if (!app.globalData.guanshi) app.globalData.guanshi = {}; + Object.assign(app.globalData.guanshi, guanshiData); + const zhuanhualv = guanshiData.yaoqingzongshu > 0 + ? (guanshiData.yichongzhiDashou / guanshiData.yaoqingzongshu * 100).toFixed(1) + : 0; + this.setData({ + isGuanshi: true, + uid: userData.uid || '', + nicheng: userData.nicheng || '', + ...guanshiData, + zhuanhualv, + isLoading: false + }); + this.loadUserInfo(); + this.switchToGuanshiRole(); + wx.hideLoading(); + wx.showToast({ title: '注册成功!', icon: 'success', duration: 2000 }); + } else { + wx.hideLoading(); + wx.showToast({ title: res?.data?.msg || '注册失败', icon: 'none' }); + } + } catch (e) { + console.error('注册失败:', e); + wx.hideLoading(); + wx.showToast({ title: e.message || '注册失败', icon: 'error' }); + } + }, + + switchToGuanshiRole() { + const app = getApp(); + app.globalData.currentRole = 'guanshi'; + wx.setStorageSync('currentRole', 'guanshi'); + const tabBar = this.getTabBar(); + if (tabBar && tabBar.refresh) tabBar.refresh(); + if (app.connectForCurrentRole) { + app.connectForCurrentRole(); + } else if (app.ensureConnection) { + app.ensureConnection(); + } + }, + + checkGuanshiStatus() { + try { + const status = wx.getStorageSync('guanshistatus'); + if (status === 1) { + this.setData({ isGuanshi: true }); + this.loadUserInfo(); + this.checkGlobalData(); + } else { + this.setData({ isGuanshi: false }); + } + } catch (e) { + this.setData({ isGuanshi: false }); + } + }, + + loadUserInfo() { + const app = getApp(); + const globalData = app.globalData || {}; + const touxiang = wx.getStorageSync('touxiang'); + const ossImageUrl = globalData.ossImageUrl || ''; + const morentouxiang = 'avatar/default.jpg'; + let avatarUrl = ''; + if (touxiang) { + avatarUrl = ossImageUrl + (touxiang.startsWith('/') ? touxiang : '/' + touxiang); + } else { + avatarUrl = ossImageUrl + (morentouxiang.startsWith('/') ? morentouxiang : '/' + morentouxiang); + } + this.setData({ + avatarUrl, + uid: wx.getStorageSync('uid') || '', + nicheng: globalData.nicheng || '' + }); + }, + + checkGlobalData() { + const app = getApp(); + const gd = app.globalData.guanshi || {}; + const needRefresh = !gd.yaoqingzongshu && !gd.fenyongzonge && !gd.fenyongtixian; + if (needRefresh) { + this.getGuanshiInfo(); + } else { + this.setDataFromGlobalData(); + } + }, + + setDataFromGlobalData() { + const gd = getApp().globalData.guanshi || {}; + const zhuanhualv = gd.yaoqingzongshu > 0 + ? (gd.yichongzhiDashou / gd.yaoqingzongshu * 100).toFixed(1) + : 0; + this.setData({ + gszhstatus: gd.gszhstatus || '', + yaoqingzongshu: gd.yaoqingzongshu || 0, + fenyongzonge: gd.fenyongzonge || '0.00', + fenyongtixian: gd.fenyongtixian || '0.00', + yichongzhiDashou: gd.yichongzhiDashou || 0, + zhuanhualv, + isLoading: false + }); + }, + + async getGuanshiInfo() { + this.setData({ isLoading: true }); + try { + const res = await request({ + url: '/yonghu/guanshixinxi', + method: 'POST' + }); + if (res && res.data.code === 200) { + const data = res.data.data; + const app = getApp(); + if (!app.globalData.guanshi) app.globalData.guanshi = {}; + const updateData = { + gszhstatus: data.gszhstatus || '', + yaoqingzongshu: data.yaoqingzongshu || 0, + fenyongzonge: data.fenyongzonge || '0.00', + fenyongtixian: data.fenyongtixian || '0.00', + yichongzhiDashou: data.yichongzhiDashou || 0 + }; + Object.assign(app.globalData.guanshi, updateData); + const zhuanhualv = updateData.yaoqingzongshu > 0 + ? (updateData.yichongzhiDashou / updateData.yaoqingzongshu * 100).toFixed(1) + : 0; + this.setData({ + ...updateData, + zhuanhualv, + isLoading: false + }); + wx.showToast({ title: '信息已更新', icon: 'success', duration: 1500 }); + } + } catch (e) { + this.setData({ isLoading: false }); + wx.showToast({ title: e.message || '获取失败', icon: 'error' }); + } + }, + + refreshGuanshiInfo() { + this.getGuanshiInfo(); + this.fetchChenghaoList(); + }, + + onInviteCodeInput(e) { + this.setData({ inviteCode: e.detail.value.trim() }); + }, + + async onRegister() { + const { inviteCode } = this.data; + if (!inviteCode) { + wx.showToast({ title: '请输入邀请码', icon: 'none' }); + return; + } + if (inviteCode.length > 100) { + wx.showToast({ title: '邀请码过长', icon: 'none' }); + return; + } + this.setData({ isLoading: true }); + try { + const res = await request({ + url: '/yonghu/guanshizhuce', + method: 'POST', + data: { inviteCode } + }); + if (res && res.data.code === 200) { + const userData = res.data.data; + const identityFields = ['dashoustatus', 'guanshistatus', 'shangjiastatus', 'zuzhangstatus']; + const app = getApp(); + identityFields.forEach(field => { + if (userData[field] !== undefined) { + wx.setStorageSync(field, userData[field]); + app.globalData[field] = userData[field]; + } + }); + if (userData.guanshistatus === undefined) { + wx.setStorageSync('guanshistatus', 1); + app.globalData.guanshistatus = 1; + } + if (!app.globalData.guanshi) app.globalData.guanshi = {}; + const updateData = { + gszhstatus: userData.gszhstatus || '', + yaoqingzongshu: userData.yaoqingzongshu || 0, + fenyongzonge: userData.fenyongzonge || '0.00', + fenyongtixian: userData.fenyongtixian || '0.00', + yichongzhiDashou: userData.yichongzhiDashou || 0 + }; + Object.assign(app.globalData.guanshi, updateData); + this.setData({ + isGuanshi: true, + ...updateData, + isLoading: false + }); + this.loadUserInfo(); + wx.showToast({ title: '注册成功!', icon: 'success', duration: 2000 }); + } + } catch (e) { + this.setData({ isLoading: false }); + wx.showToast({ title: e.message || '注册失败', icon: 'error' }); + } + }, + + onQuickRegister() { + const code = getDefaultInviteCode('guanshi'); + if (!code) { + wx.showToast({ title: '暂不支持无邀请码注册', icon: 'none' }); + return; + } + this.setData({ inviteCode: code }); + this.onRegister(); + }, + + copyUid() { + const { uid } = this.data; + if (!uid) return; + wx.setClipboardData({ + data: uid, + success: () => wx.showToast({ title: '已复制', icon: 'success' }) + }); + }, + + // ========== 页面跳转 ========== + goToWithdraw() { wx.navigateTo({ url: '/pages/tixian/tixian' }); }, + goToInviteUser() { wx.navigateTo({ url: '/pages/yaoqingdashou/yaoqingdashou' }); }, + goToMySubordinate() { wx.navigateTo({ url: '/pages/wodedashou/wodedashou' }); }, + goToRechargeRecord() { wx.navigateTo({ url: '/pages/czjilu/czjilu' }); }, + goToGuanshiRanking() { + wx.navigateTo({ url: '/pages/dashoupaihang/dashoupaihang?type=guanshi' }) + }, + goToPromoPoster() { wx.navigateTo({ url: '/pages/haibao/haibao' }); } +}); \ No newline at end of file diff --git a/miniprogram/pages/guanshiduan/guanshiduan.json b/miniprogram/pages/guanshiduan/guanshiduan.json new file mode 100644 index 0000000..9aca2d3 --- /dev/null +++ b/miniprogram/pages/guanshiduan/guanshiduan.json @@ -0,0 +1,11 @@ +{ + "usingComponents": { + "global-notification": "/components/global-notification/global-notification", + "chenghao-tag": "/components/chenghao-tag/chenghao-tag" + }, + "navigationBarBackgroundColor": "#f0f4f8", + "navigationBarTextStyle": "black", + "navigationBarTitleText": "管事中心", + "backgroundColor": "#f0f4f8", + "enablePullDownRefresh": false + } \ No newline at end of file diff --git a/miniprogram/pages/guanshiduan/guanshiduan.wxml b/miniprogram/pages/guanshiduan/guanshiduan.wxml new file mode 100644 index 0000000..3ba8dbc --- /dev/null +++ b/miniprogram/pages/guanshiduan/guanshiduan.wxml @@ -0,0 +1,122 @@ + + + + + + + ✦ 管事认证 ✦ + + + 立即注册 + + + + + + + + + + + + + + + + + + + + + + + + + + + 可提现分成 + + {{fenyongtixian}} + + + + + + {{yaoqingzongshu}} + 邀请总数 + + + {{yichongzhiDashou}} + 已充值 + + + {{fenyongzonge}} + 分成总额 + + + {{zhuanhualv}}% + 有效率 + + + + + + 提现 + + + + + + + + 邀请用户 + + + + 我的下级 + + + + 会员记录 + + + + 管事排行 + + + + 推广海报 + + + + 联系组长 + + + + + + + + + {{inviterCache.nicheng || '联系组长'}} + ID: {{inviterCache.uid}} + + + + + + + + + + + + + + \ No newline at end of file diff --git a/miniprogram/pages/guanshiduan/guanshiduan.wxss b/miniprogram/pages/guanshiduan/guanshiduan.wxss new file mode 100644 index 0000000..3cf8113 --- /dev/null +++ b/miniprogram/pages/guanshiduan/guanshiduan.wxss @@ -0,0 +1,367 @@ +/* ========== 全局背景 ========== */ +page { + background: #F8FAFE; + font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', sans-serif; + color: #1A1A1A; + } + + /* 背景图清晰可见 */ + .page-bg { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0.4; + z-index: 0; + pointer-events: none; + } + + /* ========== 未注册区域 ========== */ + .unreg-area { + position: relative; + z-index: 2; + display: flex; + align-items: center; + justify-content: center; + min-height: 100vh; + padding: 0 50rpx; + } + + .unreg-card { + width: 100%; + background: rgba(255, 255, 255, 0.75); + backdrop-filter: blur(25rpx); + -webkit-backdrop-filter: blur(25rpx); + border-radius: 48rpx; + padding: 60rpx 50rpx; + text-align: center; + box-shadow: 0 20rpx 50rpx rgba(0,0,0,0.06); + border: 1rpx solid rgba(255,255,255,0.5); + } + + .unreg-title { + font-size: 40rpx; + font-weight: 700; + color: #1A1A1A; + display: block; + margin-bottom: 50rpx; + } + + .unreg-input { + width: 100%; + height: 96rpx; + background: #FFFFFF; + border-radius: 48rpx; + padding: 0 40rpx; + font-size: 30rpx; + color: #1A1A1A; + margin-bottom: 40rpx; + box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.03); + } + + .ph { + color: #999999; + } + + .unreg-btn { + width: 100%; + height: 96rpx; + background: rgba(255,255,255,0.6); + backdrop-filter: blur(15rpx); + border-radius: 48rpx; + display: flex; + align-items: center; + justify-content: center; + border: 2rpx solid rgba(0,0,0,0.08); + box-shadow: 0 12rpx 30rpx rgba(0,0,0,0.05); + } + .unreg-btn:active { opacity: 0.8; } + .unreg-btn-text { + color: #1A1A1A; + font-size: 34rpx; + font-weight: 600; + } + + /* ========== 已注册主区域 ========== */ + .main-body { + position: relative; + z-index: 2; + padding: 0 30rpx 40rpx; + } + + /* 刷新按钮 */ + .refresh-btn { + position: absolute; + top: 40rpx; + right: 40rpx; + width: 68rpx; + height: 68rpx; + background: rgba(255,255,255,0.75); + backdrop-filter: blur(12rpx); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + z-index: 20; + border: 1rpx solid rgba(255,255,255,0.6); + box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.06); + } + .refresh-icon { + width: 38rpx; + height: 38rpx; + } + + /* 用户卡片 */ + .user-card { + margin-top: 60rpx; + margin-bottom: 30rpx; + background: rgba(255,255,255,0.7); + backdrop-filter: blur(20rpx); + -webkit-backdrop-filter: blur(20rpx); + border-radius: 36rpx; + padding: 28rpx 30rpx; + display: flex; + align-items: center; + border: 1rpx solid rgba(255,255,255,0.5); + box-shadow: 0 12rpx 35rpx rgba(0,0,0,0.05); + } + + .user-avatar { + width: 100rpx; + height: 100rpx; + border-radius: 50%; + border: 3rpx solid #FFFFFF; + margin-right: 24rpx; + } + + .user-name { + font-size: 38rpx; + font-weight: 700; + color: #1A1A1A; + display: block; + margin-bottom: 8rpx; + } + + .uid-row { + display: inline-flex; + align-items: center; + background: rgba(0,0,0,0.03); + border-radius: 20rpx; + padding: 6rpx 18rpx; + } + + .uid-text { + font-size: 26rpx; + color: #1A1A1A; + margin-right: 10rpx; + } + + .copy-icon { + width: 28rpx; + height: 28rpx; + } + + /* 称号区域 */ + .badge-zone { + margin-bottom: 24rpx; + } + .badge-scroll { + white-space: nowrap; + } + + /* 资产卡片(纯玻璃质感) */ + .asset-card { + background: rgba(255,255,255,0.7); + backdrop-filter: blur(20rpx); + -webkit-backdrop-filter: blur(20rpx); + border-radius: 36rpx; + padding: 28rpx 30rpx; + margin-bottom: 28rpx; + border: 1rpx solid rgba(255,255,255,0.5); + box-shadow: 0 12rpx 35rpx rgba(0,0,0,0.05); + } + + .asset-title { + font-size: 26rpx; + color: #1A1A1A; + font-weight: 500; + display: block; + } + + .asset-amount { + display: flex; + align-items: baseline; + margin: 10rpx 0 22rpx; + } + + .amount-number { + font-size: 74rpx; + font-weight: 800; + color: #1A1A1A; + margin-right: 8rpx; + } + + .amount-unit { + font-size: 32rpx; + color: #1A1A1A; + font-weight: 600; + } + + /* 四列数据统计 */ + .four-stats { + display: flex; + align-items: center; + justify-content: space-around; + padding: 20rpx 0; + border-top: 1rpx solid rgba(0,0,0,0.06); + border-bottom: 1rpx solid rgba(0,0,0,0.06); + margin-bottom: 22rpx; + } + + .stat-item { + text-align: center; + flex: 1; + } + + .stat-val { + font-size: 28rpx; + font-weight: 700; + color: #1A1A1A; + display: block; + margin-bottom: 6rpx; + } + + .stat-label { + font-size: 20rpx; + color: #1A1A1A; + font-weight: 500; + } + + /* 提现按钮 */ + .withdraw-btn { + display: flex; + align-items: center; + justify-content: center; + background: rgba(255,255,255,0.55); + backdrop-filter: blur(12rpx); + border-radius: 48rpx; + padding: 16rpx 0; + border: 2rpx solid rgba(0,0,0,0.06); + box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.04); + } + + .withdraw-icon { + width: 36rpx; + height: 36rpx; + margin-right: 12rpx; + } + + .withdraw-text { + font-size: 30rpx; + font-weight: 600; + color: #1A1A1A; + } + + /* 功能入口三列布局 */ + .func-grid { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + margin-bottom: 28rpx; + } + + .func-item { + width: 31%; + aspect-ratio: 1 / 1; + background: rgba(255,255,255,0.7); + backdrop-filter: blur(16rpx); + -webkit-backdrop-filter: blur(16rpx); + border-radius: 28rpx; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin-bottom: 20rpx; + border: 1rpx solid rgba(255,255,255,0.5); + box-shadow: 0 8rpx 22rpx rgba(0,0,0,0.04); + } + + .func-icon { + width: 56rpx; + height: 56rpx; + margin-bottom: 12rpx; + } + + .func-label { + font-size: 26rpx; + font-weight: 500; + color: #1A1A1A; + text-align: center; + } + + /* 联系组长卡片(底部横条) */ + .contact-card { + display: flex; + align-items: center; + justify-content: space-between; + background: rgba(255,255,255,0.7); + backdrop-filter: blur(20rpx); + -webkit-backdrop-filter: blur(20rpx); + border-radius: 36rpx; + padding: 20rpx 30rpx; + margin-bottom: 40rpx; + border: 1rpx solid rgba(255,255,255,0.5); + box-shadow: 0 10rpx 25rpx rgba(0,0,0,0.04); + } + + .contact-left { + display: flex; + align-items: center; + flex: 1; + } + + .contact-avatar { + width: 60rpx; + height: 60rpx; + border-radius: 50%; + margin-right: 18rpx; + border: 2rpx solid #FFFFFF; + } + + .contact-name { + font-size: 28rpx; + font-weight: 500; + color: #1A1A1A; + } + + .contact-uid { + font-size: 22rpx; + color: #1A1A1A; + margin-top: 4rpx; + } + + .contact-arrow { + width: 24rpx; + height: 24rpx; + } + + /* 加载遮罩 */ + .loading-mask { + position: fixed; + top:0; left:0; right:0; bottom:0; + background: rgba(255,255,255,0.85); + display: flex; + align-items: center; + justify-content: center; + z-index: 9999; + } + .loading-spinner { + width: 60rpx; + height: 60rpx; + border: 4rpx solid rgba(0,0,0,0.1); + border-top-color: #1A1A1A; + border-radius: 50%; + animation: spin 0.8s linear infinite; + } + @keyframes spin { to { transform: rotate(360deg); } } \ No newline at end of file diff --git a/miniprogram/pages/guanshipaihang/guanshipaihang.json b/miniprogram/pages/guanshipaihang/guanshipaihang.json new file mode 100644 index 0000000..f6237dd --- /dev/null +++ b/miniprogram/pages/guanshipaihang/guanshipaihang.json @@ -0,0 +1,12 @@ +{ + "usingComponents": { + "global-notification": "/components/global-notification/global-notification" + }, + "navigationBarTitleText": "管事排行榜", + "navigationBarBackgroundColor": "#000000", + "navigationBarTextStyle": "white", + "enablePullDownRefresh": false, + "backgroundColor": "#000000", + "backgroundTextStyle": "dark", + "onReachBottomDistance": 50 + } \ No newline at end of file diff --git a/miniprogram/pages/guanshipaihang/guanshipaihang.wxml b/miniprogram/pages/guanshipaihang/guanshipaihang.wxml new file mode 100644 index 0000000..8a45da9 --- /dev/null +++ b/miniprogram/pages/guanshipaihang/guanshipaihang.wxml @@ -0,0 +1,2 @@ + +正在打开排行榜... diff --git a/miniprogram/pages/guanshipaihang/guanshipaihang.wxss b/miniprogram/pages/guanshipaihang/guanshipaihang.wxss new file mode 100644 index 0000000..0ac9ca5 --- /dev/null +++ b/miniprogram/pages/guanshipaihang/guanshipaihang.wxss @@ -0,0 +1,5 @@ +.redirect-hint { + padding: 80rpx; + text-align: center; + color: #999; +} diff --git a/miniprogram/pages/guanzhual/guanzhual.js b/miniprogram/pages/guanzhual/guanzhual.js new file mode 100644 index 0000000..ea8dbfd --- /dev/null +++ b/miniprogram/pages/guanzhual/guanzhual.js @@ -0,0 +1,90 @@ +// pages/guanzhual/guanzhual.js +const app = getApp() +import request from '../../utils/request.js' + +Page({ + data: { + images: [], // 图片完整URL列表 + lastUpdate: '', // 最新更新时间 + visitCount: 0, // 浏览次数 + loading: true, // 加载中 + ossImageUrl: '' // OSS基础地址 + }, + + onLoad() { + // 获取OSS地址 + this.setData({ + ossImageUrl: app.globalData.ossImageUrl || '' + }) + this.loadData() + }, + + onShow() { + this.registerNotificationComponent() + }, + + // 注册全局通知组件 + registerNotificationComponent() { + const notificationComp = this.selectComponent('#global-notification') + if (notificationComp && notificationComp.showNotification) { + app.globalData.globalNotification = { + show: (data) => notificationComp.showNotification(data), + hide: () => notificationComp.hideNotification() + } + } + }, + + // 加载数据 + loadData() { + this.setData({ loading: true }) + + request({ + url: '/peizhi/gzal', + method: 'POST', + header: { 'content-type': 'application/json' } + }) + .then(res => { + if (res && res.data && res.data.code === 0) { + const data = res.data.data || {} + const ossImageUrl = this.data.ossImageUrl + // 拼接完整URL + const fullImages = (data.images || []).map(url => { + if (url && !url.startsWith('http')) { + return ossImageUrl + url + } + return url + }) + this.setData({ + images: fullImages, + lastUpdate: data.last_update || '', + visitCount: data.visit_count || 0, + loading: false + }) + } else { + wx.showToast({ + title: res?.data?.msg || '加载失败', + icon: 'none' + }) + this.setData({ loading: false }) + } + }) + .catch(err => { + console.error('加载关注阿龙数据失败', err) + wx.showToast({ + title: '网络错误', + icon: 'none' + }) + this.setData({ loading: false }) + }) + }, + + // 图片加载成功(可选) + onImageLoad(e) { + // 可忽略 + }, + + // 图片加载失败 + onImageError(e) { + console.warn('图片加载失败', e) + } +}) \ No newline at end of file diff --git a/miniprogram/pages/guanzhual/guanzhual.json b/miniprogram/pages/guanzhual/guanzhual.json new file mode 100644 index 0000000..ac80b22 --- /dev/null +++ b/miniprogram/pages/guanzhual/guanzhual.json @@ -0,0 +1,8 @@ +{ + "navigationBarTitleText": "关注二H", + "usingComponents": { + "global-notification": "/components/global-notification/global-notification" + }, + "enablePullDownRefresh": false, + "backgroundTextStyle": "dark" + } \ No newline at end of file diff --git a/miniprogram/pages/guanzhual/guanzhual.wxml b/miniprogram/pages/guanzhual/guanzhual.wxml new file mode 100644 index 0000000..5394ae8 --- /dev/null +++ b/miniprogram/pages/guanzhual/guanzhual.wxml @@ -0,0 +1,39 @@ + + + + + 关注快手 + {{visitCount}}次浏览 + + + 更新时间:{{lastUpdate}} + + + + + + + + + + + + 暂无内容 + + + + + + + 加载中... + + + + + \ No newline at end of file diff --git a/miniprogram/pages/guanzhual/guanzhual.wxss b/miniprogram/pages/guanzhual/guanzhual.wxss new file mode 100644 index 0000000..675b458 --- /dev/null +++ b/miniprogram/pages/guanzhual/guanzhual.wxss @@ -0,0 +1,95 @@ +/* pages/guanzhual/guanzhual.wxss */ +page { + background-color: #ffffff; + min-height: 100vh; + } + + .guanzhual-page { + padding-bottom: 30rpx; + box-sizing: border-box; + } + + /* 头部信息 */ + .header-info { + padding: 30rpx 20rpx 20rpx 20rpx; + border-bottom: 2rpx solid #f5f5f5; + } + + .title-section { + display: flex; + justify-content: space-between; + align-items: baseline; + margin-bottom: 12rpx; + } + + .main-title { + font-size: 40rpx; + font-weight: 600; + color: #333333; + } + + .visit-count { + font-size: 28rpx; + color: #999999; + } + + .sub-info { + display: flex; + justify-content: space-between; + font-size: 26rpx; + color: #aaaaaa; + } + + .update-time { + color: #888888; + } + + /* 图片列表 */ + .image-list { + padding: 0 8rpx; /* 非常微小的左右边距 */ + } + + .image-item { + width: 100%; + margin-bottom: 6rpx; /* 极小的上下间距 */ + background-color: #fafafa; + overflow: hidden; + border-radius: 4rpx; + } + + .image-item image { + width: 100%; + display: block; + } + + /* 空状态提示 */ + .empty-tip { + padding: 100rpx 0; + text-align: center; + color: #999999; + font-size: 28rpx; + } + + /* 加载状态 */ + .loading-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 100rpx 0; + } + + .loading-spinner { + width: 60rpx; + height: 60rpx; + border: 4rpx solid #e0e0e0; + border-top-color: #00C853; + border-radius: 50%; + animation: spin 1s linear infinite; + margin-bottom: 20rpx; + } + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } \ No newline at end of file diff --git a/miniprogram/pages/haibao/haibao.js b/miniprogram/pages/haibao/haibao.js new file mode 100644 index 0000000..3985d30 --- /dev/null +++ b/miniprogram/pages/haibao/haibao.js @@ -0,0 +1,281 @@ +// pages/haibao/haibao.js +import request from '../../utils/request.js'; + +const app = getApp(); + +Page({ + data: { + qrcodeUrl: '', + isLoading: false, + showPosterCanvas: false, + posterImageTemp: '', + avatarUrl: '', + uid: '', + nickName: '', + }, + + onLoad() { + this.loadQRCodeFromCache(); + this.loadUserInfo(); + }, + + onShow() { + this.registerNotificationComponent(); + }, + + registerNotificationComponent() { + const notificationComp = this.selectComponent('#global-notification'); + if (notificationComp && notificationComp.showNotification) { + app.globalData.globalNotification = { + show: (data) => notificationComp.showNotification(data), + hide: () => notificationComp.hideNotification() + }; + } + }, + + loadQRCodeFromCache() { + try { + const relativeUrl = wx.getStorageSync('haibao_url'); + if (relativeUrl) { + const fullUrl = this.getFullImageUrl(relativeUrl); + this.setData({ qrcodeUrl: fullUrl }); + } else { + this.setData({ qrcodeUrl: '' }); + } + } catch (error) { + console.error('读取缓存失败', error); + } + }, + + loadUserInfo() { + const touxiang = wx.getStorageSync('touxiang'); + const ossUrl = app.globalData.ossImageUrl || ''; + const defaultAvatar = ossUrl + (app.globalData.morentouxiang || 'avatar/default.jpg'); + let avatarUrl = defaultAvatar; + if (touxiang && typeof touxiang === 'string' && touxiang.trim() !== '') { + avatarUrl = this.getFullImageUrl(touxiang); + } + const uid = wx.getStorageSync('uid') || ''; + let nickName = app.globalData.nicheng || wx.getStorageSync('nicheng') || '管事'; + this.setData({ avatarUrl, uid, nickName }); + }, + + getFullImageUrl(url) { + if (!url) return ''; + const ossUrl = app.globalData.ossImageUrl || ''; + return url.startsWith('http') ? url : ossUrl + url; + }, + + refreshQRCode() { + if (this.data.isLoading) return; + this.setData({ isLoading: true }); + request({ + url: '/peizhi/guanshiewm', + method: 'POST', + }).then(res => { + if (res.data && res.data.code === 0) { + const relativeUrl = res.data.data.url; + if (relativeUrl) { + wx.setStorageSync('haibao_url', relativeUrl); + const fullUrl = this.getFullImageUrl(relativeUrl); + this.setData({ qrcodeUrl: fullUrl }); + wx.showToast({ title: '获取成功', icon: 'success' }); + } else { + wx.showToast({ title: '返回数据异常', icon: 'none' }); + } + } else { + wx.showToast({ title: res.data.msg || '获取失败', icon: 'none' }); + } + }).catch(err => { + console.error('获取海报失败', err); + wx.showToast({ title: '网络错误', icon: 'none' }); + }).finally(() => { + this.setData({ isLoading: false }); + }); + }, + + // 🔥【修改】保存二维码到相册(先下载网络图片) + saveToAlbum() { + if (!this.data.qrcodeUrl) { + wx.showToast({ title: '暂无二维码', icon: 'none' }); + return; + } + + wx.showLoading({ title: '保存中...', mask: true }); + wx.downloadFile({ + url: this.data.qrcodeUrl, + success: (res) => { + wx.hideLoading(); + if (res.statusCode === 200) { + // 调用已有的保存函数(传入临时路径) + this.downloadAndSave(res.tempFilePath); + } else { + wx.showToast({ title: '下载失败', icon: 'none' }); + } + }, + fail: (err) => { + wx.hideLoading(); + console.error('下载二维码失败', err); + wx.showToast({ title: '下载失败', icon: 'none' }); + } + }); + }, + + generateMyPoster() { + if (!this.data.qrcodeUrl) { + wx.showToast({ title: '请先生成二维码', icon: 'none' }); + return; + } + + wx.showLoading({ title: '生成海报中...', mask: true }); + + const ossUrl = app.globalData.ossImageUrl || ''; + const bgUrl = ossUrl + 'beijing/haibaobeijing.jpg'; + const urls = [bgUrl, this.data.qrcodeUrl, this.data.avatarUrl]; + + const promises = urls.map(url => this.loadImage(url)); + Promise.all(promises) + .then((images) => { + wx.hideLoading(); + this.setData({ showPosterCanvas: true }, () => { + setTimeout(() => { + this.drawPoster(images[0], images[1], images[2]); + }, 200); + }); + }) + .catch((err) => { + wx.hideLoading(); + wx.showToast({ title: '图片加载失败', icon: 'none' }); + console.error('图片加载失败', err); + }); + }, + + loadImage(url) { + return new Promise((resolve, reject) => { + wx.getImageInfo({ + src: url, + success: (res) => resolve(res.path), + fail: reject + }); + }); + }, + + drawPoster(bgPath, qrPath, avatarPath) { + const ctx = wx.createCanvasContext('posterCanvas', this); + const query = wx.createSelectorQuery().in(this); + query.select('.poster-canvas').boundingClientRect(rect => { + if (!rect) { + wx.showToast({ title: '画布获取失败', icon: 'none' }); + return; + } + const canvasWidth = rect.width; + const canvasHeight = rect.height; + + // 1. 绘制背景 + ctx.drawImage(bgPath, 0, 0, canvasWidth, canvasHeight); + + const qrSize = 100; + const margin = 5; + const qrX = canvasWidth - qrSize - margin; + const qrY = canvasHeight - qrSize - margin; + ctx.drawImage(qrPath, qrX, qrY, qrSize, qrSize); + + const avatarSize = 60; + const avatarX = margin + 20; + const avatarY = canvasHeight - avatarSize - margin; + ctx.save(); + ctx.beginPath(); + ctx.arc(avatarX + avatarSize/2, avatarY + avatarSize/2, avatarSize/2, 0, 2 * Math.PI); + ctx.clip(); + ctx.drawImage(avatarPath, avatarX, avatarY, avatarSize, avatarSize); + ctx.restore(); + + ctx.setFontSize(16); + ctx.setFillStyle('#333333'); + ctx.setTextAlign('left'); + + let nick = this.data.nickName || '管事'; + if (nick.length > 3) { + nick = nick.substring(0, 3) + '...'; + } + const nameText = nick; + + const textX = avatarX + avatarSize + 8; + const textY = avatarY + avatarSize/2 + 6; + ctx.fillText(nameText, textX, textY); + + ctx.setFontSize(18); + ctx.setFillStyle('#ffaa00'); + ctx.setTextAlign('left'); + const slogan = '快来加入我们 ✦'; + const sloganX = avatarX; + const sloganY = avatarY - 12; + ctx.fillText(slogan, sloganX, sloganY); + + ctx.draw(false, () => { + wx.canvasToTempFilePath({ + canvasId: 'posterCanvas', + success: (res) => { + this.setData({ posterImageTemp: res.tempFilePath }); + }, + fail: (err) => { + console.error('生成海报临时文件失败', err); + } + }, this); + }); + }).exec(); + }, + + savePoster() { + if (!this.data.posterImageTemp) { + wx.showToast({ title: '海报尚未生成', icon: 'none' }); + return; + } + this.downloadAndSave(this.data.posterImageTemp); + }, + + hidePoster() { + this.setData({ showPosterCanvas: false, posterImageTemp: '' }); + }, + + downloadAndSave(filePath) { + wx.getSetting({ + success: (res) => { + if (!res.authSetting['scope.writePhotosAlbum']) { + wx.authorize({ + scope: 'scope.writePhotosAlbum', + success: () => { + this._saveImage(filePath); + }, + fail: () => { + wx.showModal({ + title: '提示', + content: '需要您授权保存到相册', + success: (modalRes) => { + if (modalRes.confirm) { + wx.openSetting(); + } + } + }); + } + }); + } else { + this._saveImage(filePath); + } + } + }); + }, + + _saveImage(filePath) { + wx.saveImageToPhotosAlbum({ + filePath: filePath, + success: () => { + wx.showToast({ title: '保存成功', icon: 'success' }); + }, + fail: (err) => { + console.error('保存失败', err); + wx.showToast({ title: '保存失败', icon: 'none' }); + } + }); + }, +}); \ No newline at end of file diff --git a/miniprogram/pages/haibao/haibao.json b/miniprogram/pages/haibao/haibao.json new file mode 100644 index 0000000..8f6fba7 --- /dev/null +++ b/miniprogram/pages/haibao/haibao.json @@ -0,0 +1,8 @@ +{ + "usingComponents": { + "global-notification": "/components/global-notification/global-notification" + }, + "navigationBarTitleText": "推广海报", + "navigationBarBackgroundColor": "#0a0e17", + "navigationBarTextStyle": "white" + } \ No newline at end of file diff --git a/miniprogram/pages/haibao/haibao.wxml b/miniprogram/pages/haibao/haibao.wxml new file mode 100644 index 0000000..aa2c48d --- /dev/null +++ b/miniprogram/pages/haibao/haibao.wxml @@ -0,0 +1,71 @@ + + + + + + + + + + ⚡ 推广海报 ⚡ + 邀请打手扫码注册,自动填充邀请码 + + + + + + + + + + + 点击下方按钮生成您的专属二维码 + + + + + + + + 📥 + 保存二维码 + + + + {{qrcodeUrl ? '重新获取' : '获取二维码'}} + + + + 生成中... + + + + 🎨 + 生成我的专属海报 + + + + + + + + + + 📥 + 保存海报 + + + ↩️ + 返回 + + + + + + + * 打手扫码后自动进入注册页面,邀请码将自动填充 + + + + + \ No newline at end of file diff --git a/miniprogram/pages/haibao/haibao.wxss b/miniprogram/pages/haibao/haibao.wxss new file mode 100644 index 0000000..e52db1f --- /dev/null +++ b/miniprogram/pages/haibao/haibao.wxss @@ -0,0 +1,269 @@ +/* 机甲风格推广海报页面(含新增专属海报样式) */ + +page { + background: #0a0e17; + min-height: 100vh; + font-family: 'Avenir', 'PingFang SC', 'Helvetica Neue', sans-serif; + color: #fff; + } + + /* 背景网格 */ + .grid-bg { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + linear-gradient(rgba(0, 160, 255, 0.05) 1px, transparent 1px), + linear-gradient(90deg, rgba(0, 160, 255, 0.05) 1px, transparent 1px); + background-size: 50rpx 50rpx; + pointer-events: none; + z-index: 0; + } + + .page-container { + position: relative; + z-index: 2; + min-height: 100vh; + padding: 30rpx 25rpx; + box-sizing: border-box; + } + + /* 机械装饰线条 */ + .mech-line { + position: absolute; + pointer-events: none; + z-index: 1; + } + .line-h { + top: 200rpx; + left: 0; + width: 100%; + height: 2rpx; + background: linear-gradient(90deg, transparent, #00a6ff, transparent); + } + .line-v { + right: 50rpx; + top: 100rpx; + width: 2rpx; + height: 300rpx; + background: linear-gradient(180deg, transparent, #00a6ff, transparent); + } + + .content { + position: relative; + z-index: 3; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: 100vh; + padding: 40rpx 0; + } + + /* 标题区域 */ + .title-section { + text-align: center; + margin-bottom: 60rpx; + } + .title { + font-size: 44rpx; + font-weight: bold; + color: #fff; + text-shadow: 0 0 30rpx #00a6ff; + letter-spacing: 2rpx; + display: block; + margin-bottom: 20rpx; + } + .subtitle { + font-size: 28rpx; + color: #9cf; + opacity: 0.9; + letter-spacing: 1rpx; + } + + /* 二维码区域(方形,无斜切) */ + .qrcode-section { + width: 100%; + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 60rpx; + } + .qrcode-wrapper { + position: relative; + width: 400rpx; + height: 400rpx; + background: rgba(0, 20, 40, 0.8); + border: 4rpx solid #00a6ff; + /* 移除 clip-path,保持方形 */ + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 0 80rpx rgba(0, 166, 255, 0.4); + animation: qrcodePulse 2s infinite alternate; + } + .qrcode-img { + width: 90%; + height: 90%; + object-fit: contain; + } + .qrcode-glow { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: radial-gradient(circle at 30% 30%, rgba(0, 166, 255, 0.2), transparent 70%); + pointer-events: none; + } + .empty-qrcode { + width: 400rpx; + height: 400rpx; + background: rgba(0, 20, 40, 0.8); + border: 4rpx dashed #00a6ff; + /* 方形 */ + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } + .empty-icon { + font-size: 80rpx; + color: #00a6ff; + margin-bottom: 20rpx; + opacity: 0.5; + } + .empty-text { + font-size: 26rpx; + color: #9cf; + text-align: center; + padding: 0 40rpx; + } + + /* 按钮区域(机甲斜切风格) */ + .button-section { + width: 100%; + display: flex; + justify-content: center; + margin-bottom: 40rpx; + } + .btn-group { + display: flex; + gap: 20rpx; + flex-wrap: wrap; + justify-content: center; + } + .btn { + width: 220rpx; + height: 80rpx; + background: rgba(0, 30, 60, 0.8); + border: 2rpx solid #00a6ff; + border-right: none; + border-bottom: none; + clip-path: polygon(0 0, 100% 0, 90% 100%, 0 100%); + display: flex; + align-items: center; + justify-content: center; + position: relative; + transition: 0.2s; + cursor: pointer; + } + .btn:active { + transform: scale(0.96); + box-shadow: 0 0 40rpx #00a6ff; + } + .save-btn { + border-color: #00a6ff; + } + .refresh-btn { + border-color: #ffaa00; + } + .refresh-btn .btn-icon { + color: #ffaa00; + } + /* 🔥【新增】生成海报按钮样式 */ + .poster-btn { + border-color: #ffaa00; + } + .poster-btn .btn-icon { + color: #ffaa00; + } + .loading-btn { + opacity: 0.7; + pointer-events: none; + } + .btn-icon { + font-size: 36rpx; + margin-right: 8rpx; + } + .btn-text { + font-size: 26rpx; + font-weight: 500; + color: #fff; + } + .loading-spinner-small { + width: 30rpx; + height: 30rpx; + border: 4rpx solid rgba(255,255,255,0.2); + border-top: 4rpx solid #fff; + border-radius: 50%; + animation: spin 1s linear infinite; + margin-right: 10rpx; + } + + /* 🔥【新增】专属海报展示区 */ + .poster-section { + margin-top: 40rpx; + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + } + .poster-canvas { + width: 600rpx; + height: 900rpx; + background: #1a1f2e; /* 占位色 */ + border: 4rpx solid #00a6ff; + box-shadow: 0 0 60rpx #00a6ff; + /* 保持方形,无斜切 */ + } + .poster-actions { + display: flex; + gap: 30rpx; + margin-top: 30rpx; + justify-content: center; + } + .save-poster-btn { + background: linear-gradient(45deg, #0066cc, #00a6ff); + border-color: #00a6ff; + } + .back-btn { + background: rgba(0, 30, 60, 0.8); + border-color: #00a6ff; + } + + /* 使用说明(保留) */ + .instruction { + margin-top: 30rpx; + padding: 20rpx 40rpx; + background: rgba(0, 30, 50, 0.5); + border-left: 4rpx solid #00a6ff; + clip-path: polygon(0 0, 100% 0, 98% 100%, 0 100%); + } + .instruction-text { + font-size: 24rpx; + color: #9cf; + line-height: 1.6; + } + + /* 动画 */ + @keyframes qrcodePulse { + 0% { box-shadow: 0 0 40rpx rgba(0, 166, 255, 0.3); } + 100% { box-shadow: 0 0 100rpx rgba(0, 166, 255, 0.6); } + } + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } \ No newline at end of file diff --git a/miniprogram/pages/index/index.js b/miniprogram/pages/index/index.js new file mode 100644 index 0000000..d89bade --- /dev/null +++ b/miniprogram/pages/index/index.js @@ -0,0 +1,494 @@ +// pages/shangpin/shangpin.js +const app = getApp() + +Page({ + /** + * 页面的初始数据 + */ + data: { + // 全局变量引用 + ossImageUrl: '', + lunbozhanwei: '', + + // 页面数据 + shangpingonggao: '', + lunboList: [], + shangpinleixing: [], + shangpinzhuanqu: [], + shangpinliebiao: [], + + // 状态控制 + selectedLeixingId: null, + filteredData: [], + showGonggaoModal: false, + gonggaoAnim: true, + isLoading: false, + isRefreshing: false, + hasInitialized: false, + + // 🔴【新增】当前时间(用于弹窗显示) + currentTime: '' + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + // 🔥 等待全局配置加载完成 + this.waitForConfigAndInit(); + // 🆕 修改:仅在已登录时检查弹窗,避免未登录时发起请求导致 401 弹窗 + const token = wx.getStorageSync('token'); + if (token) { + PopupService.checkAndShow(this, 'index'); + } + }, + // 🆕 页面隐藏时清理弹窗视图 + onHide: function () { + const popupComp = this.selectComponent('#popupNotice'); + if (popupComp && popupComp.cleanup) { + popupComp.cleanup(); + } +}, + + + /** + * 🔥 新增:等待配置加载完成再初始化 + */ + waitForConfigAndInit() { + if (app.globalData.ossImageUrl) { + // 配置已就绪,直接初始化 + this.setData({ + ossImageUrl: app.globalData.ossImageUrl, + lunbozhanwei: app.globalData.lunbozhanwei, + currentTime: this.getCurrentTime() + }); + this.initPageData(); + } else { + // 配置未就绪,延迟重试(最多等待3秒,每100ms检查一次) + + setTimeout(() => this.waitForConfigAndInit(), 100); + } + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + // 如果已经初始化过,只更新时间;否则等待配置 + if (this.data.ossImageUrl) { + this.setData({ + gonggaoAnim: true, + currentTime: this.getCurrentTime() + }); + } + this.registerNotificationComponent(); + }, + + // 注册通知组件 + registerNotificationComponent() { + const app = getApp(); + const notificationComp = this.selectComponent('#global-notification'); + + if (notificationComp && notificationComp.showNotification) { + app.globalData.globalNotification = { + show: (data) => notificationComp.showNotification(data), + hide: () => notificationComp.hideNotification() + }; + } + }, + + /** + * 🔴【新增】获取当前时间(格式化) + */ + getCurrentTime() { + const now = new Date(); + const year = now.getFullYear(); + const month = (now.getMonth() + 1).toString().padStart(2, '0'); + const day = now.getDate().toString().padStart(2, '0'); + const hour = now.getHours().toString().padStart(2, '0'); + const minute = now.getMinutes().toString().padStart(2, '0'); + return `${year}-${month}-${day} ${hour}:${minute}`; + }, + + /** + * 🔴【新增】按paixu字段排序函数 + * 规则:1. paixu大的在前 2. paixu相同时id小的在前 3. 没有paixu的按id排序 + */ + sortByPaixu(list) { + if (!list || !Array.isArray(list)) return [] + + return [...list].sort((a, b) => { + // 获取paixu值,如果没有则默认为0 + const paixuA = a.paixu || 0 + const paixuB = b.paixu || 0 + + // 1. 先按paixu降序(大的在前) + if (paixuB !== paixuA) { + return paixuB - paixuA + } + + // 2. paixu相同时,按id升序(小的在前) + return a.id - b.id + }) + }, + + /** + * 初始化页面数据 + */ + initPageData() { + const that = this + this.setData({ isLoading: true }) + + const needLoad = [] + + // 1. 检查公告和轮播图 + if (!app.globalData.shangpingonggao || app.globalData.shangpinlunbo.length === 0) { + needLoad.push(this.loadGonggaoAndLunbo()) + } else { + this.setData({ + shangpingonggao: app.globalData.shangpingonggao, + lunboList: this.processImageUrls(app.globalData.shangpinlunbo) + }) + } + + // 2. 检查商品数据 + if (app.globalData.shangpinleixing.length === 0) { + needLoad.push(this.loadAllShangpinData()) + } else { + const leixingList = app.globalData.shangpinleixing + + // 🔴【修改】对商品类型进行排序 + const sortedLeixing = this.sortByPaixu(leixingList) + + this.setData({ + shangpinleixing: leixingList, + shangpinzhuanqu: app.globalData.shangpinzhuanqu || [], + shangpinliebiao: app.globalData.shangpinliebiao || [], + selectedLeixingId: sortedLeixing[0]?.id || null + }, () => { + this.filterShangpinData() + }) + } + + if (needLoad.length > 0) { + Promise.all(needLoad) + .then(() => { + that.setData({ isLoading: false }) + }) + .catch(error => { + console.error('数据加载失败:', error) + that.setData({ isLoading: false }) + wx.showToast({ + title: '加载失败,请重试', + icon: 'none' + }) + }) + } else { + this.setData({ isLoading: false }) + } + }, + + /** + * 加载公告和轮播图数据 + */ + loadGonggaoAndLunbo() { + const that = this + return new Promise((resolve, reject) => { + wx.request({ + url: app.globalData.apiBaseUrl + '/peizhi/shangpingonggao/', + method: 'POST', + header: { + 'content-type': 'application/json' + }, + success(res) { + if (res.statusCode === 200 && res.data) { + const data = res.data + + app.globalData.shangpingonggao = data.shangpingonggao || '' + app.globalData.shangpinlunbo = data.shangpinlunbo || [] + + that.setData({ + shangpingonggao: app.globalData.shangpingonggao, + lunboList: that.processImageUrls(app.globalData.shangpinlunbo) + }) + + resolve() + } else { + reject(new Error('请求失败')) + } + }, + fail(error) { + console.error('加载公告失败:', error) + reject(error) + } + }) + }) + }, + + /** + * 加载所有商品数据 + */ + loadAllShangpinData() { + const that = this + return new Promise((resolve, reject) => { + wx.request({ + url: app.globalData.apiBaseUrl + '/shangpin/shangpinhuoqu/', + method: 'POST', + header: { + 'content-type': 'application/json' + }, + success(res) { + if (res.statusCode === 200 && res.data) { + const data = res.data + + // 🔴【修改】对返回的数据进行排序 + const sortedLeixing = that.sortByPaixu(data.shangpinleixing || []) + const sortedZhuanqu = that.sortByPaixu(data.shangpinzhuanqu || []) + const sortedShangpin = that.sortByPaixu(data.shangpinliebiao || []) + + app.globalData.shangpinleixing = sortedLeixing + app.globalData.shangpinzhuanqu = sortedZhuanqu + app.globalData.shangpinliebiao = sortedShangpin + + that.setData({ + shangpinleixing: sortedLeixing, + shangpinzhuanqu: sortedZhuanqu, + shangpinliebiao: sortedShangpin, + selectedLeixingId: sortedLeixing[0]?.id || null + }, () => { + that.filterShangpinData() + resolve() + }) + } else { + reject(new Error('请求失败')) + } + }, + fail(error) { + console.error('加载商品数据失败:', error) + reject(error) + } + }) + }) + }, + + /** + * 处理图片URL(拼接OSS域名) + */ + processImageUrls(urlList) { + if (!urlList || !Array.isArray(urlList)) return [] + + return urlList.map(url => { + if (url.startsWith('http')) { + return url + } else { + return this.data.ossImageUrl + url + } + }) + }, + + /** + * 筛选商品数据 + */ + filterShangpinData() { + const { selectedLeixingId, shangpinzhuanqu, shangpinliebiao } = this.data + + if (!selectedLeixingId || !shangpinzhuanqu || !shangpinliebiao) { + this.setData({ filteredData: [] }) + return + } + + // 1. 构建专区Map(按类型分组,但只处理当前选中的类型) + const zhuanquByLeixing = new Map() + + shangpinzhuanqu.forEach(zhuanqu => { + if (zhuanqu.leixing_id === selectedLeixingId) { + if (!zhuanquByLeixing.has(selectedLeixingId)) { + zhuanquByLeixing.set(selectedLeixingId, []) + } + zhuanquByLeixing.get(selectedLeixingId).push(zhuanqu) + } + }) + + // 2. 构建商品Map(按专区分组) + const shangpinByZhuanqu = new Map() + + shangpinliebiao.forEach(shangpin => { + if (shangpin.leixing_id === selectedLeixingId && shangpin.zhuanqu_id) { + const zhuanquId = shangpin.zhuanqu_id + + if (!shangpinByZhuanqu.has(zhuanquId)) { + shangpinByZhuanqu.set(zhuanquId, []) + } + + // 处理价格显示 + const jiage = parseFloat(shangpin.jiage) || 0 + const priceInteger = Math.floor(jiage) + let priceDecimal = '00' + + const decimalPart = (jiage - priceInteger).toFixed(2) + if (decimalPart > 0) { + priceDecimal = decimalPart.toString().split('.')[1] + } + + shangpinByZhuanqu.get(zhuanquId).push({ + id: shangpin.id, + biaoqian: shangpin.biaoqian, + jiage: jiage, + priceInteger: priceInteger, + priceDecimal: priceDecimal, + tupian_url: shangpin.tupian_url, + duiwai_xiaoliang: shangpin.duiwai_xiaoliang || 0, + paixu: shangpin.paixu || 0 // 🔴 保留排序字段 + }) + } + }) + + // 3. 构建最终数据结构 + const filteredData = [] + const currentZhuanquList = zhuanquByLeixing.get(selectedLeixingId) || [] + + currentZhuanquList.forEach(zhuanqu => { + const shangpinList = shangpinByZhuanqu.get(zhuanqu.id) || [] + + if (shangpinList.length > 0) { + filteredData.push({ + zhuanqu: { + id: zhuanqu.id, + mingzi: zhuanqu.mingzi, + paixu: zhuanqu.paixu || 0 // 🔴 保留排序字段 + }, + shangpinList: shangpinList + }) + } + }) + + // 🔴【修改】对最终数据进行排序(确保专区顺序) + const sortedFilteredData = filteredData.sort((a, b) => { + // 按专区paixu降序 + const paixuA = a.zhuanqu.paixu || 0 + const paixuB = b.zhuanqu.paixu || 0 + if (paixuB !== paixuA) return paixuB - paixuA + // paixu相同时按专区id升序 + return a.zhuanqu.id - b.zhuanqu.id + }) + + this.setData({ filteredData: sortedFilteredData }) + }, + + /** + * 选择商品类型 + */ + selectLeixing(e) { + const leixingId = e.currentTarget.dataset.id + + if (this.data.selectedLeixingId === leixingId) { + return + } + + this.setData({ + selectedLeixingId: leixingId + }, () => { + this.filterShangpinData() + }) + }, + + /** + * 显示公告详情 + */ + showGonggaoDetail() { + this.setData({ + showGonggaoModal: true, + gonggaoAnim: false, + currentTime: this.getCurrentTime() // 🔴 更新弹窗时间 + }) + }, + + /** + * 隐藏公告详情 + */ + hideGonggaoDetail() { + this.setData({ + showGonggaoModal: false, + gonggaoAnim: true + }) + }, + + /** + * 刷新所有数据 + */ + refreshAllData() { + const that = this + this.setData({ isRefreshing: true }) + + wx.showLoading({ + title: '刷新中...', + mask: true + }) + + // 清空全局变量 + app.globalData.shangpingonggao = '' + app.globalData.shangpinlunbo = [] + app.globalData.shangpinleixing = [] + app.globalData.shangpinzhuanqu = [] + app.globalData.shangpinliebiao = [] + + Promise.all([ + that.loadGonggaoAndLunbo(), + that.loadAllShangpinData() + ]) + .then(() => { + wx.hideLoading() + that.setData({ isRefreshing: false }) + wx.showToast({ + title: '刷新成功', + icon: 'success', + duration: 1500 + }) + }) + .catch(error => { + console.error('刷新失败:', error) + wx.hideLoading() + that.setData({ isRefreshing: false }) + wx.showToast({ + title: '刷新失败', + icon: 'none' + }) + }) + }, + + /** + * 跳转到商品详情页 + */ + goToDetail(e) { + const shangpinId = e.currentTarget.dataset.id + if (!shangpinId) return + + wx.navigateTo({ + url: `/pages/shangpinxiangqing/shangpinxiangqing?id=${shangpinId}` + }) + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + // 可以在这里实现分页加载 + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + return { + title: '阿龙电竞', + path: '/pages/shangpin/shangpin' + } + }, + + /** + * 页面卸载时清理 + */ + onUnload() { + this.setData({ gonggaoAnim: false }) + } +}) \ No newline at end of file diff --git a/miniprogram/pages/index/index.json b/miniprogram/pages/index/index.json new file mode 100644 index 0000000..06f55f5 --- /dev/null +++ b/miniprogram/pages/index/index.json @@ -0,0 +1,12 @@ +{ + "usingComponents": { + "global-notification": "/components/global-notification/global-notification", + "custom-tab-bar": "/custom-tab-bar/index" + }, + + "navigationBarTitleText": "商城", + "navigationBarBackgroundColor": "#ffffff", + "navigationBarTextStyle": "black", + + "backgroundColor": "#f5faff" + } \ No newline at end of file diff --git a/miniprogram/pages/index/index.wxml b/miniprogram/pages/index/index.wxml new file mode 100644 index 0000000..d5fff6b --- /dev/null +++ b/miniprogram/pages/index/index.wxml @@ -0,0 +1,172 @@ + + + + + + + + + + {{shangpingonggao || '暂无公告'}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{item.jieshao}} + + + + + + + + + + + + + + {{item.zhuanqu.mingzi}} + + + + + + + + + + + + + + + {{item.biaoqian}} + + + + + + ¥ + {{item.priceInteger}} + .{{item.priceDecimal}} + + + + + + + + + + + + + + 暂无商品 + + + + + + + + + + + 公告详情 + × + + + {{shangpingonggao || '暂无公告内容'}} + + + + + + + + 加载中... + + + + + + \ No newline at end of file diff --git a/miniprogram/pages/index/index.wxss b/miniprogram/pages/index/index.wxss new file mode 100644 index 0000000..beb4936 --- /dev/null +++ b/miniprogram/pages/index/index.wxss @@ -0,0 +1,585 @@ +/* ===== 1. 全局样式 ===== */ +.shangpin-page { + min-height: 100vh; + background: linear-gradient(180deg, #f5faff 0%, #f0f8ff 100%); + } + +/* ===== 2. 公告栏样式 - 物理上移方案 ===== */ +.gonggao-box { + margin: 20rpx 30rpx; + height: 80rpx; + border-radius: 40rpx; + background: linear-gradient(135deg, + rgba(220, 255, 220, 0.85) 0%, + rgba(255, 255, 200, 0.85) 100%); + backdrop-filter: blur(10px); + display: flex; + align-items: center; + padding: 0 25rpx; + box-shadow: 0 4rpx 15rpx rgba(0, 100, 0, 0.08); + border: 1rpx solid rgba(255, 255, 255, 0.3); + position: relative; + overflow: hidden; + } + + .gonggao-icon { + width: 40rpx; + height: 40rpx; + margin-right: 20rpx; + flex-shrink: 0; + display: flex; + align-items: center; + } + + .gonggao-icon image { + width: 100%; + height: 100%; + } + + .gonggao-content { + flex: 1; + overflow: hidden; + height: 100%; + position: relative; + } + + /* 关键修改:使用物理上移 */ + .gonggao-text { + font-size: 26rpx; + color: #333; + white-space: nowrap; + padding-right: 50rpx; + + /* 物理上移方法1:直接调整位置 */ + position: absolute; + top: -5rpx; /* 从顶部开始计算位置 */ + left: 0; + + /* 或者使用方法2:负margin上移 */ + /* position: relative; + top: -10rpx; */ + + /* 或者使用方法3:translate上移 */ + /* transform: translateY(-5rpx); */ + } + + /* 尝试不同的上移值,直到居中为止 */ + /* 可以尝试的值:5rpx, 8rpx, 10rpx, 12rpx, 15rpx, 18rpx, 20rpx */ + + .gonggao-anim { + animation: marquee 10s linear infinite; /* 加快速度到10秒 */ + animation-delay: 0.5s; + } + + @keyframes marquee { + 0% { + transform: translateX(100%); + } + 100% { + transform: translateX(-100%); + } + } + + /* ===== 3. 轮播图样式 ===== */ + .lunbo-container { + margin: 0 30rpx 30rpx; + height: 350rpx; + border-radius: 25rpx; + overflow: hidden; + position: relative; + box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.1); + } + + .lunbo-swiper { + width: 100%; + height: 100%; + } + + .lunbo-image { + width: 100%; + height: 100%; + } + + .lunbo-placeholder { + width: 100%; + height: 100%; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + display: flex; + justify-content: center; + align-items: center; + } + + .lunbo-placeholder image { + width: 100%; + height: 100%; + opacity: 0.8; + } + + /* 刷新按钮 */ + .refresh-btn { + position: absolute; + top: 20rpx; + right: 20rpx; + width: 80rpx; + height: 80rpx; + z-index: 10; + display: flex; + justify-content: center; + align-items: center; + } + + .refresh-icon { + width: 60rpx; + height: 60rpx; + transition: transform 0.3s; + filter: drop-shadow(0 4rpx 8rpx rgba(0, 0, 0, 0.2)); + } + + .refreshing { + animation: rotate360 1s linear infinite; + } + + @keyframes rotate360 { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + + .refresh-dot { + position: absolute; + width: 12rpx; + height: 12rpx; + background: #ffcc00; + border-radius: 50%; + top: 15rpx; + right: 15rpx; + animation: pulse 2s infinite; + } + + @keyframes pulse { + 0%, 100% { + opacity: 0.8; + transform: scale(1); + } + 50% { + opacity: 1; + transform: scale(1.2); + } + } + + /* ===== 4. 商品展示区域 ===== */ + .shangpin-container { + background: rgba(255, 255, 255, 0.95); + border-radius: 40rpx 40rpx 0 0; + margin-top: -20rpx; + padding: 40rpx 30rpx 100rpx; + min-height: 800rpx; + box-shadow: 0 -10rpx 30rpx rgba(0, 0, 0, 0.05); + } + + /* 商品类型选择 - 完全重新设计,确保左对齐且间距协调 */ + .leixing-scroll { + width: 100%; + white-space: nowrap; + margin-bottom: 50rpx; + } + + .leixing-list { + display: inline-flex; + padding-left: 0; /* 完全去掉左内边距,100%左对齐 */ + padding-right: 30rpx; /* 只保留右内边距给最后一个元素一点空间 */ + padding-top: 10rpx; + padding-bottom: 10rpx; + } + + /* 关键:完全协调的间距 */ + .leixing-item { + display: inline-flex; + flex-direction: column; + align-items: center; + margin-right: 30rpx; /* 合适的间距,不会太大也不会太小 */ + transition: all 0.3s; + position: relative; + flex-shrink: 0; + width: 130rpx; /* 固定宽度,确保四个看起来协调 */ + } + + .leixing-item:last-child { + margin-right: 0; + } + + .leixing-image-box { + width: 110rpx; /* 稍微减小,让整体更紧凑 */ + height: 110rpx; + border-radius: 25rpx; + overflow: hidden; + position: relative; + margin-bottom: 12rpx; + transition: all 0.3s; + box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.1); + } + + .leixing-image { + width: 100%; + height: 100%; + } + + .leixing-glow { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 25rpx; + border: 4rpx solid transparent; + transition: all 0.3s; + } + + .leixing-active .leixing-glow { + border-color: #ffcc00; + box-shadow: 0 0 20rpx rgba(255, 204, 0, 0.5); + } + + .leixing-active .leixing-image-box { + transform: translateY(-8rpx); + } + + .leixing-text { + font-size: 24rpx; + color: #666; + white-space: nowrap; + transition: all 0.3s; + text-align: center; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + } + + .leixing-active .leixing-text { + color: #333; + font-weight: bold; + transform: scale(1.05); + } + + /* 专区标题 */ + .zhuanqu-title { + display: flex; + align-items: center; + margin: 40rpx 0 15rpx; + padding-left: 0; + position: relative; + } + + .zhuanqu-icon { + width: 40rpx; + height: 40rpx; + margin-right: 20rpx; + position: relative; + } + + .zhuanqu-icon-image { + width: 100%; + height: 100%; + filter: drop-shadow(0 2rpx 4rpx rgba(255, 204, 0, 0.3)); + } + + .zhuanqu-sparkle { + animation: sparkle 2s infinite; + } + + @keyframes sparkle { + 0%, 100% { + transform: scale(1) rotate(0deg); + filter: drop-shadow(0 2rpx 4rpx rgba(255, 204, 0, 0.3)); + } + 50% { + transform: scale(1.1) rotate(10deg); + filter: drop-shadow(0 4rpx 8rpx rgba(255, 204, 0, 0.6)); + } + } + + .zhuanqu-text { + font-size: 32rpx; + font-weight: bold; + color: #333; + position: relative; + } + + .zhuanqu-text::after { + content: ''; + position: absolute; + left: 0; + bottom: -8rpx; + width: 60rpx; + height: 4rpx; + background: linear-gradient(90deg, #ffcc00, transparent); + border-radius: 2rpx; + } + + /* 商品网格 */ + .shangpin-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 25rpx; + margin-bottom: 40rpx; + } + + .shangpin-card { + background: #ffffff; + border-radius: 20rpx; + overflow: hidden; + box-shadow: 0 8rpx 25rpx rgba(0, 0, 0, 0.06); + transition: all 0.3s; + position: relative; + } + + .shangpin-card:active { + transform: scale(0.98); + box-shadow: 0 4rpx 15rpx rgba(0, 0, 0, 0.1); + } + + .shangpin-image-box { + width: 100%; + height: 220rpx; + position: relative; + overflow: hidden; + } + + .shangpin-image { + width: 100%; + height: 100%; + transition: transform 0.5s; + } + + /* 商品标题区域 - 协调紧凑 */ + .shangpin-title { + height: 75rpx; + padding: 6rpx 12rpx 2rpx 12rpx; + display: flex; + align-items: flex-start; + overflow: hidden; + } + + .title-text { + font-size: 26rpx; + color: #000; + line-height: 34rpx; + font-weight: 450; /* 微调粗细,更加协调 */ + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-overflow: ellipsis; + } + + /* 价格和购买按钮 - 协调紧凑 */ + .shangpin-footer { + height: 50rpx; + padding: 0 12rpx 8rpx 12rpx; + display: flex; + justify-content: space-between; + align-items: center; + } + + .price-box { + display: flex; + align-items: baseline; + } + + .price-icon { + font-size: 24rpx; + color: #ff4444; + font-weight: bold; + margin-right: 2rpx; + } + + .price-integer { + font-size: 32rpx; + color: #ff4444; + font-weight: bold; + } + + .price-decimal { + font-size: 24rpx; + color: #ff4444; + font-weight: bold; + } + + .buy-btn { + width: 48rpx; + height: 48rpx; + border-radius: 50%; + background: linear-gradient(135deg, #ff4444, #ff6666); + display: flex; + justify-content: center; + align-items: center; + box-shadow: 0 4rpx 12rpx rgba(255, 68, 68, 0.3); + transition: all 0.3s; + } + + .buy-btn:active { + transform: scale(0.9); + } + + .buy-icon { + width: 26rpx; + height: 26rpx; + filter: brightness(0) invert(1); + } + + /* ===== 5. 空状态 ===== */ + .empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 100rpx 0; + } + + .empty-image { + width: 200rpx; + height: 200rpx; + margin-bottom: 40rpx; + opacity: 0.7; + } + + .empty-text { + font-size: 30rpx; + color: #999; + margin-bottom: 40rpx; + } + + .empty-btn { + background: linear-gradient(135deg, #667eea, #764ba2); + color: white; + font-size: 28rpx; + padding: 20rpx 60rpx; + border-radius: 50rpx; + box-shadow: 0 8rpx 25rpx rgba(102, 126, 234, 0.3); + } + + /* ===== 6. 弹窗样式 ===== */ + .gonggao-modal { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1000; + display: flex; + justify-content: center; + align-items: center; + } + + .modal-mask { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(5px); + } + + .modal-content { + width: 600rpx; + background: white; + border-radius: 30rpx; + overflow: hidden; + box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.2); + z-index: 1001; + animation: modalShow 0.3s; + } + + @keyframes modalShow { + from { + opacity: 0; + transform: scale(0.9); + } + to { + opacity: 1; + transform: scale(1); + } + } + + .modal-header { + padding: 40rpx; + border-bottom: 2rpx solid #f0f0f0; + display: flex; + justify-content: space-between; + align-items: center; + } + + .modal-title { + font-size: 32rpx; + font-weight: bold; + color: #333; + } + + .modal-close { + font-size: 40rpx; + color: #999; + width: 60rpx; + height: 60rpx; + display: flex; + justify-content: center; + align-items: center; + border-radius: 50%; + } + + .modal-close:active { + background: #f5f5f5; + } + + .modal-body { + max-height: 600rpx; + padding: 40rpx; + } + + .modal-text { + font-size: 28rpx; + color: #333; + line-height: 1.6; + white-space: normal; + word-break: break-word; + } + + /* ===== 7. 加载提示 ===== */ + .loading-toast { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: rgba(0, 0, 0, 0.7); + backdrop-filter: blur(10px); + padding: 30rpx 50rpx; + border-radius: 25rpx; + display: flex; + flex-direction: column; + align-items: center; + z-index: 999; + } + + .loading-spinner { + width: 60rpx; + height: 60rpx; + border: 6rpx solid rgba(255, 255, 255, 0.3); + border-top-color: white; + border-radius: 50%; + animation: spin 1s linear infinite; + margin-bottom: 20rpx; + } + + @keyframes spin { + to { + transform: rotate(360deg); + } + } + + .loading-text { + font-size: 26rpx; + color: white; + } \ No newline at end of file diff --git a/miniprogram/pages/jiedan/jiedan.js b/miniprogram/pages/jiedan/jiedan.js new file mode 100644 index 0000000..f0e4cbb --- /dev/null +++ b/miniprogram/pages/jiedan/jiedan.js @@ -0,0 +1,528 @@ +// pages/qiangdan/qiangdan.js +const app = getApp(); +import request from '../../utils/request.js'; +import PopupService from '../../services/popupService.js'; + +Page({ + data: { + // 1. 商品类型相关 + shangpinleixing: [], + xuanzhongLeixingId: null, + + // 2. 订单列表与分页相关 + dingdanList: [], + page: 1, + pageSize: 5, + hasMore: true, + isLoading: false, + + // 3. 全局状态字段 + dashoustatus: null, + zhuanghaoStatus: null, + dashouzhuangtai: null, + uid: null, + huiyuanList: [], + yajin: 0, + jifen: 0, + + // 4. 刷新控制字段 + scrollViewRefreshing: false, + lastRefreshTime: 0, + refreshCooldown: 2000, + isLoadingMore: false, + + // 5. 切换类型冷却 + lastSwitchTime: 0, + switchCooldown: 1500, + isSwitching: false, + + // 6. OSS地址 + ossImageUrl: app.globalData.ossImageUrl || '', + + // 🆕 7. 标签筛选相关 + bankuaiBiaoqian: [], // 当前商品类型所属板块的全部标签 + xuanzhongBiaoqianId: 0, // 0=全部 + }, + + async onLoad(options) { + this.loadGlobalStatus(); + await this.loadShangpinLeixing(); + PopupService.checkAndShow(this, 'jiedan'); + }, + + onHide: function () { + const popupComp = this.selectComponent('#popupNotice'); + if (popupComp && popupComp.cleanup) { + popupComp.cleanup(); + } + }, + + onShow() { + this.registerNotificationComponent(); + // 重新加载全局状态 + this.loadGlobalStatus(); + // 如果有选中类型则刷新订单 + if (this.data.xuanzhongLeixingId) { + this.loadDingdanList(true); + } + }, + + registerNotificationComponent() { + const notificationComp = this.selectComponent('#global-notification'); + if (notificationComp && notificationComp.showNotification) { + app.globalData.globalNotification = { + show: (data) => notificationComp.showNotification(data), + hide: () => notificationComp.hideNotification() + }; + } + }, + + loadGlobalStatus() { + const globalData = app.globalData; + this.setData({ + dashoustatus: wx.getStorageSync('dashoustatus'), + zhuanghaoStatus: globalData.zhanghaoStatus, + dashouzhuangtai: globalData.dashouzhuangtai, + uid: wx.getStorageSync('uid'), + huiyuanList: globalData.clumber || [], + yajin: globalData.yajin || 0, + jifen: globalData.jinfen || 0 + }); + }, + + // 加载商品类型 + async loadShangpinLeixing() { + wx.showLoading({ title: '加载商品类型...' }); + try { + const res = await request({ + url: '/dingdan/dsqdhqddlx', + method: 'POST', + header: { 'content-type': 'application/json' } + }); + if (res.statusCode === 200 && res.data) { + const data = res.data; + let list = []; + if (data.code === 200 || data.code === 0) { + if (data.data && Array.isArray(data.data.list)) list = data.data.list; + else if (data.data && Array.isArray(data.data)) list = data.data; + else if (Array.isArray(data.list)) list = data.list; + else if (Array.isArray(data)) list = data; + } + const processedList = this.processTupianUrl(list); + this.setData({ + shangpinleixing: processedList, + xuanzhongLeixingId: processedList[0]?.id || null + }); + if (this.data.xuanzhongLeixingId) { + this.loadDingdanList(true); + // 🆕 加载板块标签 + this.loadBankuaiBiaoqian(); + } + } else { + wx.showToast({ title: res.data?.msg || '加载商品类型失败', icon: 'none' }); + } + } catch (error) { + wx.showToast({ title: '网络错误,加载失败', icon: 'none' }); + } finally { + wx.hideLoading(); + } + }, + + // 处理图片URL + processTupianUrl(list) { + const ossUrl = app.globalData.ossImageUrl || ''; + return list.map(item => ({ + ...item, + full_tupian_url: item.tupian_url && !item.tupian_url.startsWith('http') + ? ossUrl + item.tupian_url + : (item.tupian_url || '/images/default-type.png') + })); + }, + + // 🆕 加载板块标签 + async loadBankuaiBiaoqian() { + const leixingId = this.data.xuanzhongLeixingId; + if (!leixingId) return; + try { + const res = await request({ + url: '/dengji/bkqhbq', + method: 'POST', + data: { leixing_id: leixingId } + }); + if (res && res.data.code === 0) { + this.setData({ + bankuaiBiaoqian: res.data.data.biaoqian_list || [], + xuanzhongBiaoqianId: 0 + }); + } + } catch (e) { + // 标签加载失败不影响主流程 + } + }, + + // 选择商品类型 + async selectLeixing(e) { + const now = Date.now(); + const lastSwitchTime = this.data.lastSwitchTime; + const switchCooldown = this.data.switchCooldown; + + if (now - lastSwitchTime < switchCooldown) { + wx.showToast({ + title: `操作太快,请${Math.ceil((switchCooldown - (now - lastSwitchTime)) / 1000)}秒后再试`, + icon: 'none', + duration: 1500 + }); + return; + } + if (this.data.isSwitching) return; + + const leixingId = e.currentTarget.dataset.id; + if (leixingId === this.data.xuanzhongLeixingId) return; + + this.setData({ isSwitching: true, lastSwitchTime: now }); + wx.showLoading({ title: '切换中...' }); + + try { + this.setData({ + xuanzhongLeixingId: leixingId, + dingdanList: [], + page: 1, + hasMore: true, + xuanzhongBiaoqianId: 0 // 重置标签筛选 + }); + await this.loadDingdanList(true); + // 🆕 切换类型后加载新标签 + await this.loadBankuaiBiaoqian(); + } catch (error) { + console.error('切换类型失败:', error); + } finally { + this.setData({ isSwitching: false }); + wx.hideLoading(); + } + }, + + // 🆕 选择标签筛选 + async selectBiaoqian(e) { + const id = e.currentTarget.dataset.id; + if (id === this.data.xuanzhongBiaoqianId) return; + this.setData({ + xuanzhongBiaoqianId: id, + dingdanList: [], + page: 1, + hasMore: true + }); + await this.loadDingdanList(true); + }, + + // 加载订单列表 + async loadDingdanList(isRefresh = false) { + if (this.data.isLoading || !this.data.xuanzhongLeixingId) return; + + const loadPage = isRefresh ? 1 : this.data.page; + if (!isRefresh && !this.data.hasMore) return; + + this.setData({ + isLoading: true, + isLoadingMore: !isRefresh + }); + + try { + const res = await request({ + url: '/dingdan/ddhq', + method: 'POST', + data: { + leixing_id: this.data.xuanzhongLeixingId, + page: loadPage, + page_size: this.data.pageSize, + // 🆕 传递标签筛选参数(0时不传) + biaoqian_id: this.data.xuanzhongBiaoqianId || undefined + } + }); + + this.setData({ + isLoading: false, + isLoadingMore: false, + scrollViewRefreshing: false + }); + + if (res.data.code === 200 || res.data.code === 0) { + const newList = res.data.data.list || []; + const hasMore = res.data.data.has_more || false; + + const processedList = newList.map(item => this.processDingdanItem(item)); + const updatedList = isRefresh ? processedList : [...this.data.dingdanList, ...processedList]; + updatedList.sort((a, b) => (b.creat_time || '').localeCompare(a.creat_time || '')); + + this.setData({ + dingdanList: updatedList, + page: loadPage, + hasMore: hasMore + }); + + if (isRefresh) { + this.setData({ lastRefreshTime: Date.now() }); + } + } else { + wx.showToast({ title: res.data.msg || '加载失败', icon: 'none' }); + } + } catch (error) { + console.error('加载订单失败:', error); + this.setData({ + isLoading: false, + isLoadingMore: false, + scrollViewRefreshing: false + }); + wx.showToast({ title: '网络请求失败', icon: 'none' }); + } + }, + + // 处理单条订单数据(包含标签) + processDingdanItem(item) { + const ossUrl = app.globalData.ossImageUrl || ''; + let fullTupianUrl = ''; + + if (item.tupian) { + fullTupianUrl = !item.tupian.startsWith('http') ? ossUrl + item.tupian : item.tupian; + } else { + const leixing = this.data.shangpinleixing.find(l => l.id === item.leixing_id); + fullTupianUrl = leixing ? leixing.full_tupian_url : '/images/default-order.png'; + } + + const isZhiding = item.zhuangtai === 7; + + let zhidingAvatar = ''; + if (item.zhiding_avatar) { + zhidingAvatar = !item.zhiding_avatar.startsWith('http') + ? ossUrl + item.zhiding_avatar + : item.zhiding_avatar; + } + const zhidingNicheng = item.zhiding_nicheng || ''; + + return { + ...item, + full_tupian_url: fullTupianUrl, + isZhiding: isZhiding, + isPingtai: item.pingtai == 1, + isShangjia: item.pingtai == 2, + zhiding_avatar_full: zhidingAvatar, + zhiding_nicheng: zhidingNicheng, + // 🆕 三层标签(后端返回,直接保留) + xuqiu_biaoqian: item.xuqiu_biaoqian || [], + dashou_biaoqian: item.dashou_biaoqian || [], + shangjia_biaoqian: item.shangjia_biaoqian || [], + }; + }, + + // 跳转到充值页面(原封不动) + goToChongzhiPage(failureType, huiyuanId = null, requiredYajin = 0) { + let url = '/pages/dashouchongzhi/dashouchongzhi'; + let params = {}; + + switch (failureType) { + case 'huiyuan': + params = { needScroll: '0', scrollTo: 'member' }; + break; + case 'yajin': + params = { needScroll: '1', scrollTo: 'bottom', requiredYajin: requiredYajin }; + break; + case 'jifen': + params = { needScroll: '1', scrollTo: 'bottom' }; + break; + } + + if (huiyuanId) params.huiyuanId = huiyuanId; + + const queryString = Object.keys(params) + .map(key => `${key}=${encodeURIComponent(params[key])}`) + .join('&'); + + wx.navigateTo({ + url: `${url}?${queryString}`, + fail: (err) => { + console.error('跳转失败:', err); + wx.showToast({ title: '跳转失败,请稍后重试', icon: 'none' }); + } + }); + }, + + // 抢单按钮(原封不动) + async onQiangdanTap(e) { + const dingdanItem = e.currentTarget.dataset.item; + if (!dingdanItem) return; + + // 校验1: 打手身份 + if (!this.data.dashoustatus || this.data.dashoustatus != 1) { + wx.showToast({ title: '请先开启打手身份', icon: 'none' }); + return; + } + // 校验2: 账号状态 + if (this.data.zhuanghaoStatus != 1) { + wx.showToast({ title: '账号异常,无法接单', icon: 'none' }); + return; + } + // 校验3: 打手接单状态 + if (this.data.dashouzhuangtai != 1) { + wx.showToast({ title: '您有订单正在接待中', icon: 'none' }); + return; + } + // 校验4: 指定订单 + if (dingdanItem.isZhiding) { + if (!this.data.uid || this.data.uid != dingdanItem.zhiding_uid) { + wx.showToast({ title: '此订单为指定单', icon: 'none' }); + return; + } + } + // 校验5: 会员要求 + if (dingdanItem.yaoqiuleixing == 1) { + const hasHuiyuan = this.data.huiyuanList.some(h => h.huiyuanid == dingdanItem.huiyuan_id); + if (!hasHuiyuan) { + wx.showToast({ + title: '未开通对应会员,无法抢单', + icon: 'none', + duration: 2000 + }); + setTimeout(() => { + this.goToChongzhiPage('huiyuan', dingdanItem.huiyuan_id); + }, 500); + return; + } + } + // 校验6: 押金要求 + if (dingdanItem.yaoqiuleixing == 2) { + if (this.data.yajin < dingdanItem.yajin) { + wx.showToast({ + title: `押金不足,需${dingdanItem.yajin}`, + icon: 'none', + duration: 2000 + }); + setTimeout(() => { + this.goToChongzhiPage('yajin', null, dingdanItem.yajin); + }, 500); + return; + } + } + // 校验7: 积分要求 + if (this.data.jifen < 5) { + wx.showToast({ + title: '积分不足,至少需要5积分', + icon: 'none', + duration: 2000 + }); + setTimeout(() => { + this.goToChongzhiPage('jifen'); + }, 500); + return; + } + + // 确认框 + const that = this; + wx.showModal({ + title: '确认抢单', + content: `确定要抢此订单吗?${dingdanItem.isZhiding ? '(指定订单)' : ''}`, + success: async function (res) { + if (res.confirm) { + wx.showLoading({ title: '抢单中...', mask: true }); + try { + const qiangdanRes = await request({ + url: '/dingdan/qiangdan', + method: 'POST', + data: { dingdan_id: dingdanItem.dingdan_id } + }); + wx.hideLoading(); + + if (qiangdanRes.data.code === 200 || qiangdanRes.data.code === 0) { + that.showQiangdanSuccessEffect(); + if (app.globalData) { + app.globalData.dashouzhuangtai = 0; + that.setData({ dashouzhuangtai: 0 }); + } + const newList = that.data.dingdanList.filter( + item => item.dingdan_id !== dingdanItem.dingdan_id + ); + that.setData({ dingdanList: newList }); + } else { + wx.showToast({ + title: qiangdanRes.data.msg || '抢单失败', + icon: 'none' + }); + } + } catch (error) { + wx.hideLoading(); + console.error('抢单请求失败:', error); + wx.showToast({ title: '网络错误,抢单失败', icon: 'none' }); + } + } + } + }); + }, + + showQiangdanSuccessEffect() { + wx.showToast({ title: '抢单成功!', icon: 'success', duration: 2000 }); + }, + + onViewDetail(e) { + const { type, content } = e.currentTarget.dataset; + wx.showModal({ + title: type === 'jieshao' ? '订单介绍' : '订单备注', + content: content, + showCancel: false, + confirmText: '知道了' + }); + }, + + onReachBottom() { + const now = Date.now(); + const lastTime = this.data.lastRefreshTime; + const cooldown = this.data.refreshCooldown; + + if (now - lastTime < cooldown) { + wx.showToast({ + title: `操作太快,请${Math.ceil((cooldown - (now - lastTime)) / 1000)}秒后再试`, + icon: 'none', + duration: 1500 + }); + return; + } + + if (this.data.isLoading || this.data.isLoadingMore) return; + + if (this.data.hasMore && !this.data.isLoading && this.data.xuanzhongLeixingId) { + this.setData({ page: this.data.page + 1 }); + this.loadDingdanList(false); + } + }, + + onPullDownRefresh() { + const now = Date.now(); + const lastTime = this.data.lastRefreshTime; + const cooldown = this.data.refreshCooldown; + + if (now - lastTime < cooldown) { + this.setData({ scrollViewRefreshing: false }); + wx.showToast({ + title: `操作太快,请${Math.ceil((cooldown - (now - lastTime)) / 1000)}秒后再试`, + icon: 'none', + duration: 1500 + }); + return; + } + + if (this.data.isLoading) { + this.setData({ scrollViewRefreshing: false }); + return; + } + + this.setData({ + scrollViewRefreshing: true, + lastRefreshTime: now, + page: 1, + hasMore: true + }); + + if (this.data.xuanzhongLeixingId) { + this.loadDingdanList(true); + } else { + this.setData({ scrollViewRefreshing: false }); + } + } +}); \ No newline at end of file diff --git a/miniprogram/pages/jiedan/jiedan.json b/miniprogram/pages/jiedan/jiedan.json new file mode 100644 index 0000000..eee9b81 --- /dev/null +++ b/miniprogram/pages/jiedan/jiedan.json @@ -0,0 +1,12 @@ +{ + "navigationBarTitleText": "抢单大厅", + "navigationBarBackgroundColor": "#0b0f1a", + "navigationBarTextStyle": "white", + "enablePullDownRefresh": false, + "backgroundTextStyle": "dark", + "backgroundColor": "#0b0f1a", + "usingComponents": { + "chenghao-tag": "/components/chenghao-tag/chenghao-tag", + "global-notification": "/components/global-notification/global-notification" + } + } \ No newline at end of file diff --git a/miniprogram/pages/jiedan/jiedan.wxml b/miniprogram/pages/jiedan/jiedan.wxml new file mode 100644 index 0000000..6450749 --- /dev/null +++ b/miniprogram/pages/jiedan/jiedan.wxml @@ -0,0 +1,208 @@ + + + + + + + + + + + {{item.jieshao}} + + + + + + + + + + + + 全部 + + + + + + + + + + + + + + + + + ⚡️ 正在刷新... + ▼ 下拉刷新订单 + + + + + + 请先选择上方订单类型 + + + + 当前类型暂无待抢订单 + + + + + + + {{item.creat_time}} + + ⚙️ 平台订单 + + + + + 指定 + + {{item.zhiding_nicheng || '指定打手'}} + UID: {{item.zhiding_uid || '未知'}} + + + + + + + + + + 介绍: + {{item.jieshao || '暂无介绍'}} + [点击查看] + + + + + 备注: + {{item.beizhu}} + [点击查看] + + + + + 需求标签: + + + + + + + + 💰 + 分佣 + {{item.dashou_fencheng || 0}} + + + + ⚡ 立即抢单 + + + + + + + + + + + {{item.creat_time}} + + 🏪 商家发单 + + + + + 指定 + + {{item.zhiding_nicheng || '指定打手'}} + UID: {{item.zhiding_uid || '未知'}} + + + + + + + + + {{item.sjnicheng || '未知商家'}} + + + + + + + + 订单介绍: + {{item.jieshao || '暂无介绍'}} + [点击查看] + + + + 商家备注: + {{item.beizhu}} + [点击查看] + + + + + 需求标签: + + + + + + + + 💰 + 分佣 + {{item.dashou_fencheng || 0}} + + + + ⚡ 立即抢单 + + + + + + + + + ⚙️ 加载更多订单中... + —— 没有更多订单了 —— + + + + + + ⚡ 订单加载中... + + + + + + + \ No newline at end of file diff --git a/miniprogram/pages/jiedan/jiedan.wxss b/miniprogram/pages/jiedan/jiedan.wxss new file mode 100644 index 0000000..52ed1a3 --- /dev/null +++ b/miniprogram/pages/jiedan/jiedan.wxss @@ -0,0 +1,762 @@ +/* pages/qiangdan/qiangdan.wxss - 高级机甲风格重构版(对称优化) */ +.qiangdan-page { + height: 100vh; + display: flex; + flex-direction: column; + background: radial-gradient(ellipse at top, #1a1f30, #0b0f1a); + overflow: hidden; + position: relative; + } + + /* 背景动态纹理,增加层次感 */ + .qiangdan-page::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + linear-gradient(45deg, rgba(0, 247, 255, 0.02) 0%, transparent 30%), + radial-gradient(circle at 30% 50%, rgba(255, 77, 109, 0.03) 0%, transparent 50%), + repeating-linear-gradient(45deg, rgba(255,255,255,0.01) 0px, rgba(255,255,255,0.01) 1px, transparent 1px, transparent 6px); + pointer-events: none; + z-index: 0; + } + + /* ====== 1. 商品类型区域 ====== */ + .leixing-quyu { + padding: 30rpx 0 20rpx; + background: rgba(18, 22, 38, 0.9); + backdrop-filter: blur(20rpx); + border-bottom: 1rpx solid rgba(255, 255, 255, 0.05); + position: relative; + z-index: 10; + flex-shrink: 0; + box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.5); + } + + .leixing-scroll { + width: 100%; + white-space: nowrap; + height: 180rpx; + } + + .leixing-container { + display: inline-flex; + padding: 0 30rpx; + gap: 20rpx; + } + + .leixing-item { + display: inline-flex; + flex-direction: column; + align-items: center; + width: 160rpx; + position: relative; + transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); + } + + .leixing-active { + transform: translateY(-8rpx); + } + + .guangyun-effect { + position: absolute; + top: -15rpx; + left: -15rpx; + right: -15rpx; + bottom: -15rpx; + background: radial-gradient(circle at center, rgba(0, 200, 255, 0.3) 0%, transparent 70%); + border-radius: 50rpx; + z-index: 0; + animation: guangyun-pulse 2s infinite ease-in-out; + } + + @keyframes guangyun-pulse { + 0%, 100% { opacity: 0.5; transform: scale(1); } + 50% { opacity: 1; transform: scale(1.1); } + } + + .leixing-tupian { + width: 120rpx; + height: 120rpx; + border-radius: 32rpx; + z-index: 1; + box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.6); + transition: all 0.3s ease; + border: 2rpx solid rgba(0, 200, 255, 0.4); + } + + .leixing-active .leixing-tupian { + box-shadow: 0 16rpx 40rpx rgba(0, 200, 255, 0.5); + border: 2rpx solid #00c8ff; + } + + .leixing-jieshao { + margin-top: 16rpx; + font-size: 24rpx; + color: #b0c0e0; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + text-align: center; + z-index: 1; + font-weight: 500; + } + + .leixing-active .leixing-jieshao { + color: #00c8ff; + text-shadow: 0 0 8px rgba(0,200,255,0.5); + } + + /* ====== 2. 分割线 ====== */ + .fenge-xian { + height: 2rpx; + background: linear-gradient(90deg, transparent, #00c8ff, #ff4d6d, transparent); + flex-shrink: 0; + margin: 0 30rpx; + opacity: 0.5; + } + + /* ====== 3. 订单列表容器 ====== */ + .dingdan-container { + flex: 1; + overflow: hidden; + position: relative; + z-index: 1; + padding: 0 20rpx; /* 统一左右内边距 */ + } + + .dingdan-scroll-view { + height: 100%; + -webkit-overflow-scrolling: touch; + } + + .refresher-container { + height: 100rpx; + display: flex; + align-items: center; + justify-content: center; + } + + .refreshing-text, + .pull-down-text { + font-size: 26rpx; + color: #6a9cff; + text-shadow: 0 0 8px rgba(0,200,255,0.3); + } + + /* ====== 4. 空状态提示 ====== */ + .empty-tip { + padding: 160rpx 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } + + .tip-icon { + width: 180rpx; + height: 180rpx; + opacity: 0.5; + margin-bottom: 30rpx; + filter: drop-shadow(0 0 20px rgba(0,200,255,0.3)); + } + + .tip-text { + font-size: 28rpx; + color: #8a9ac0; + letter-spacing: 2rpx; + } + + /* ====== 5. 订单卡片通用样式(移除左右边框,改用顶部标识)====== */ + .dingdan-card { + margin: 20rpx 0; /* 左右由容器控制 */ + border-radius: 36rpx; + padding: 28rpx 24rpx; + position: relative; + overflow: hidden; + box-shadow: 0 20rpx 40rpx rgba(0, 0, 0, 0.6); + transition: all 0.3s ease; + border: 1rpx solid rgba(255, 255, 255, 0.03); + backdrop-filter: blur(30rpx); + } + + .dingdan-card:active { + transform: scale(0.998); + box-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.8); + } + + /* 平台订单 - 冷色调,顶部光效 */ + .pingtai-card { + background: linear-gradient(145deg, rgba(18, 28, 48, 0.95), rgba(8, 18, 35, 0.98)); + } + + .pingtai-card::before { + content: ''; + position: absolute; + top: 0; + left: 10%; + width: 80%; + height: 4rpx; + background: linear-gradient(90deg, transparent, #00c8ff, transparent); + border-radius: 2rpx; + opacity: 0.7; + } + + /* 商家订单 - 暖色调,顶部光效 */ + .shangjia-card { + background: linear-gradient(145deg, rgba(38, 18, 48, 0.95), rgba(25, 8, 35, 0.98)); + } + + .shangjia-card::before { + content: ''; + position: absolute; + top: 0; + left: 10%; + width: 80%; + height: 4rpx; + background: linear-gradient(90deg, transparent, #ff4d6d, transparent); + border-radius: 2rpx; + opacity: 0.7; + } + + /* 卡片顶部 */ + .card-top { + display: flex; + align-items: center; + margin-bottom: 20rpx; + padding-bottom: 16rpx; + border-bottom: 1rpx dashed rgba(255, 255, 255, 0.08); + } + + .creat-time { + font-size: 26rpx; + color: #c0d0ff; + font-weight: 500; + text-shadow: 0 0 5px rgba(0,200,255,0.3); + } + + .top-line { + flex: 1; + height: 1rpx; + background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.2), transparent); + margin: 0 20rpx; + } + + .pingtai-tag { + font-size: 24rpx; + color: #aac8ff; + padding: 6rpx 18rpx; + background: rgba(0,200,255,0.08); + border-radius: 40rpx; + border: 1rpx solid rgba(0,200,255,0.3); + box-shadow: 0 0 10rpx rgba(0,200,255,0.2); + } + + /* ====== 6. 指定单标识行(新设计)====== */ + .zhiding-row { + display: flex; + align-items: center; + margin-bottom: 24rpx; + padding: 12rpx 20rpx; + background: rgba(255, 77, 109, 0.1); + border-radius: 60rpx; + border: 1rpx solid rgba(255, 77, 109, 0.3); + box-shadow: 0 0 20rpx rgba(255, 77, 109, 0.2); + backdrop-filter: blur(10rpx); + gap: 12rpx; + } + + .zhiding-icon { + font-size: 28rpx; + color: #ff4d6d; + font-weight: 700; + background: rgba(255, 77, 109, 0.2); + padding: 4rpx 16rpx; + border-radius: 40rpx; + text-shadow: 0 0 8px #ff4d6d; + letter-spacing: 2rpx; + } + + .zhiding-avatar { + width: 48rpx; + height: 48rpx; + border-radius: 50%; + border: 2rpx solid #ff4d6d; + box-shadow: 0 0 15rpx #ff4d6d; + object-fit: cover; + } + + .zhiding-nicheng { + font-size: 26rpx; + color: #ffc0d0; + font-weight: 500; + max-width: 160rpx; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .zhiding-uid { + font-size: 24rpx; + color: #ff9aab; + flex: 1; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-family: monospace; + } + + /* ====== 7. 平台订单内容区 ====== */ + .card-content { + display: flex; + margin-bottom: 24rpx; + align-items: center; + } + + .neirong-tupian { + width: 140rpx; + height: 140rpx; + border-radius: 50%; + margin-right: 24rpx; + flex-shrink: 0; + box-shadow: 0 10rpx 30rpx rgba(0,200,255,0.3); + border: 2rpx solid #00c8ff; + object-fit: cover; + } + + .jieshao-box { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + min-height: 140rpx; + padding: 8rpx 0; + } + + .jieshao-label { + font-size: 26rpx; + color: #d0e0ff; + font-weight: 600; + margin-bottom: 6rpx; + text-shadow: 0 0 5px rgba(0,200,255,0.3); + } + + .jieshao-text { + font-size: 26rpx; + color: #b0c8f0; + line-height: 1.4; + word-break: break-word; + } + + .jieshao-ellipsis .jieshao-text { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + overflow: hidden; + text-overflow: ellipsis; + } + + /* ====== 8. 商家订单特有样式 ====== */ + .shangjia-info { + display: flex; + align-items: center; + margin-bottom: 20rpx; + } + + .shangjia-touxiang { + width: 90rpx; + height: 90rpx; + border-radius: 50%; + margin-right: 20rpx; + border: 2rpx solid #ff4d6d; + box-shadow: 0 6rpx 18rpx rgba(255, 77, 109, 0.5); + object-fit: cover; + } + + .shangjia-nicheng { + font-size: 30rpx; + color: #ffb3c6; + font-weight: 600; + text-shadow: 0 0 8px rgba(255, 77, 109, 0.4); + } + + .shangjia-jieshao, + .shangjia-beizhu { + margin-bottom: 16rpx; + padding: 14rpx 18rpx; + background: rgba(255, 255, 255, 0.02); + border-radius: 24rpx; + border: 1rpx solid rgba(255, 77, 109, 0.2); + } + + .shangjia-jieshao .jieshao-label, + .shangjia-beizhu .beizhu-label { + display: block; + margin-bottom: 6rpx; + font-size: 24rpx; + color: #ff9aab; + } + + .shangjia-jieshao .jieshao-text, + .shangjia-beizhu .beizhu-text { + font-size: 24rpx; + color: #e0c8ff; + line-height: 1.4; + } + + .shangjia-jieshao.jieshao-ellipsis .jieshao-text { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-overflow: ellipsis; + } + + .shangjia-beizhu.beizhu-ellipsis .beizhu-text { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-overflow: ellipsis; + } + + /* ====== 9. 通用备注区 ====== */ + .beizhu-box { + margin-bottom: 20rpx; + padding: 14rpx 18rpx; + background: rgba(255, 255, 255, 0.02); + border-radius: 24rpx; + border: 1rpx solid rgba(0,200,255,0.2); + } + + .beizhu-label { + font-size: 24rpx; + color: #80d0ff; + font-weight: 600; + margin-bottom: 6rpx; + display: block; + } + + .beizhu-text { + font-size: 24rpx; + color: #b0c8f0; + line-height: 1.4; + } + + .beizhu-ellipsis .beizhu-text { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-overflow: ellipsis; + } + + .view-more { + display: block; + font-size: 22rpx; + color: #00c8ff; + margin-top: 6rpx; + text-align: right; + opacity: 0.8; + text-shadow: 0 0 5px #00c8ff; + } + + /* ====== 10. 卡片底部:分佣 + 按钮 ====== */ + .card-bottom { + display: flex; + align-items: center; + justify-content: space-between; + padding-top: 20rpx; + border-top: 1rpx solid rgba(255, 255, 255, 0.06); + } + + /* 分佣容器(图标占位,用户可自定义) */ + .fenyong-box { + display: flex; + align-items: baseline; + background: rgba(0, 0, 0, 0.3); + padding: 8rpx 20rpx; + border-radius: 60rpx; + border: 1rpx solid rgba(255, 215, 0, 0.3); + } + + /* 分佣图标占位符,用户可替换为自己图标 */ + .fenyong-icon { + font-size: 32rpx; + margin-right: 10rpx; + filter: drop-shadow(0 0 8px gold); + } + + .fenyong-text { + font-size: 24rpx; + color: #c0b0a0; + margin-right: 8rpx; + } + + .fenyong-price { + font-size: 44rpx; + color: #ffd700; + font-weight: 800; + margin-right: 4rpx; + text-shadow: 0 0 20px rgba(255, 215, 0, 0.8); + } + + .fenyong-unit { + font-size: 24rpx; + color: #a0a0b0; + } + + /* ====== 11. 机甲风格抢单按钮(对称优化)====== */ + .qiangdan-btn { + position: relative; + padding: 16rpx 44rpx; + border: none; + overflow: hidden; + transition: all 0.2s ease; + cursor: pointer; + z-index: 1; + /* 多边形形状,保证上下对称 */ + clip-path: polygon(10% 0%, 90% 0%, 100% 25%, 100% 75%, 90% 100%, 10% 100%, 0% 75%, 0% 25%); + } + + /* 按钮统一基础样式,无上下不对称阴影 */ + .mecha-btn { + background: linear-gradient(145deg, #2a3050, #181e38); + box-shadow: + 0 8rpx 0 #0a0a1a, + 0 12rpx 28rpx rgba(0, 0, 0, 0.7), + inset 0 2rpx 6rpx rgba(255, 255, 255, 0.2), + inset 0 -2rpx 4rpx rgba(0, 0, 0, 0.3); + border: 1rpx solid rgba(255, 255, 255, 0.1); + } + + /* 平台按钮冷光 */ + .pingtai-btn.mecha-btn { + background: linear-gradient(145deg, #1a2a48, #0e1a30); + box-shadow: + 0 8rpx 0 #0a1525, + 0 12rpx 28rpx rgba(0, 0, 0, 0.7), + inset 0 2rpx 6rpx #00c8ff, + inset 0 -2rpx 4rpx rgba(0, 0, 0, 0.3); + } + + /* 商家按钮暖光 */ + .shangjia-btn.mecha-btn { + background: linear-gradient(145deg, #3a2048, #251030); + box-shadow: + 0 8rpx 0 #2a0a1a, + 0 12rpx 28rpx rgba(0, 0, 0, 0.7), + inset 0 2rpx 6rpx #ff4d6d, + inset 0 -2rpx 4rpx rgba(0, 0, 0, 0.3); + } + + .btn-text { + font-size: 32rpx; + color: #fff; + font-weight: 700; + letter-spacing: 3rpx; + position: relative; + z-index: 3; + text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.7), 0 0 15rpx currentColor; + } + + /* 扫光效果 */ + .btn-shine { + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient( + to right, + rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 0.25) 50%, + rgba(255, 255, 255, 0) 100% + ); + transform: rotate(30deg); + animation: btn-shimmer 2.8s infinite linear; + z-index: 2; + } + + /* 内发光,只在悬停/按下时出现,保证对称 */ + .btn-glow { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.5), transparent 70%); + opacity: 0; + transition: opacity 0.3s; + z-index: 1; + } + + .mecha-btn:hover .btn-glow, + .mecha-btn:active .btn-glow { + opacity: 0.3; + } + + /* 按下效果,保持对称 */ + .mecha-btn:active { + transform: translateY(4rpx) scale(0.98); + box-shadow: + 0 4rpx 0 #0a0a1a, + 0 8rpx 20rpx rgba(0, 0, 0, 0.7), + inset 0 2rpx 6rpx rgba(255, 255, 255, 0.2), + inset 0 -2rpx 4rpx rgba(0, 0, 0, 0.3); + } + + /* 机械纹理,保持视觉丰富但不过分 */ + .mecha-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: + repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.02) 0px, rgba(255, 255, 255, 0.02) 2px, transparent 2px, transparent 8px); + pointer-events: none; + z-index: 1; + opacity: 0.5; + } + + @keyframes btn-shimmer { + 0% { transform: translateX(-100%) rotate(30deg); } + 100% { transform: translateX(100%) rotate(30deg); } + } + + /* ====== 12. 加载状态 ====== */ + .loading-more, + .no-more { + padding: 40rpx 0; + text-align: center; + } + + .loading-text { + font-size: 26rpx; + color: #6a9cff; + text-shadow: 0 0 10px rgba(0,200,255,0.5); + animation: pulse 1.5s infinite; + } + + .no-more-text { + font-size: 26rpx; + color: #4a5a8a; + letter-spacing: 3rpx; + } + + @keyframes pulse { + 0%, 100% { opacity: 0.7; } + 50% { opacity: 1; } + } + + .loading-mask { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(5, 8, 18, 0.95); + backdrop-filter: blur(30rpx); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 9999; + } + + .loading-spinner { + width: 90rpx; + height: 90rpx; + border: 6rpx solid rgba(0,200,255,0.2); + border-top: 6rpx solid #00c8ff; + border-right: 6rpx solid #ff4d6d; + border-radius: 50%; + animation: spin 1.2s cubic-bezier(0.68, -0.55, 0.27, 1.55) infinite; + margin-bottom: 30rpx; + box-shadow: 0 0 50rpx #00c8ff; + } + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + .loading-mask-text { + font-size: 30rpx; + color: #c0d0ff; + text-shadow: 0 0 15px rgba(0,200,255,0.7); + letter-spacing: 4rpx; + } + + + + + +/* 🆕 标签筛选区 */ +.biaoqian-quyu { + padding: 12rpx 20rpx; + background: rgba(18, 22, 38, 0.7); + backdrop-filter: blur(10rpx); + } + .biaoqian-scroll { + white-space: nowrap; + height: 80rpx; + } + .biaoqian-container { + display: inline-flex; + gap: 16rpx; + padding-right: 20rpx; + } + .biaoqian-item { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0 12rpx; + border-radius: 20rpx; + background: rgba(255,255,255,0.05); + transition: all 0.2s; + } + .biaoqian-active { + background: rgba(0,200,255,0.2); + border: 1rpx solid #00c8ff; + } + .quanbu-text { + font-size: 26rpx; + color: #ccc; + padding: 0 12rpx; + } + + /* 订单卡片内标签滚动 */ + .xuqiu-biaoqian-area { + display: flex; + align-items: center; + margin-top: 16rpx; + padding: 8rpx 0; + } + .xuqiu-label { + font-size: 24rpx; + color: #80d0ff; + margin-right: 12rpx; + flex-shrink: 0; + } + .xuqiu-biaoqian-scroll { + flex: 1; + white-space: nowrap; + } + .biaoqian-inline-scroll { + flex: 1; + white-space: nowrap; + margin-left: 10rpx; + } + /* 调整指定打手行内的标签滚动 */ + .zhiding-row .biaoqian-inline-scroll { + margin-left: auto; + max-width: 50%; + } + diff --git a/miniprogram/pages/jiedanchi/jiedanchi.js b/miniprogram/pages/jiedanchi/jiedanchi.js new file mode 100644 index 0000000..a081b4e --- /dev/null +++ b/miniprogram/pages/jiedanchi/jiedanchi.js @@ -0,0 +1,467 @@ +// pages/jiedanchi/jiedanchi.js +const app = getApp(); +import request from '../../utils/request.js'; +import PopupService from '../../services/popupService.js'; + +Page({ + data: { + // 1. 商品类型相关 + shangpinleixing: [], // 商品类型列表 {id, jieshao, tupian_url} + xuanzhongLeixingId: null, // 当前选中的类型ID + + // 2. 订单列表与分页相关 + dingdanList: [], // 当前展示的订单列表 + page: 1, + pageSize: 10, + hasMore: true, + isLoading: false, + + // 3. 全局状态字段 + dashoustatus: null, + zhuanghaoStatus: null, // 注意变量名:zhuanghaoStatus + dashouzhuangtai: null, + uid: null, + huiyuanList: [], // clumber 列表 + yajin: 0, + jifen: 0, + + // 4. 刷新控制字段 + scrollViewRefreshing: false, + lastRefreshTime: 0, + refreshCooldown: 2000, + isLoadingMore: false, + + // 5. 切换类型冷却时间控制 + lastSwitchTime: 0, + switchCooldown: 1500, + isSwitching: false, + + // 6. 全局OSS地址 + ossImageUrl: app.globalData.ossImageUrl || '', + + // 7. 授权状态控制 + showUnauthorized: false, + unauthorizedMsg: '您尚未开启此功能', + }, + + async onLoad(options) { + this.loadGlobalStatus(); + this.checkAuthorization(); + + }, + // 🆕 页面隐藏时清理弹窗视图 + onHide: function () { + const popupComp = this.selectComponent('#popupNotice'); + if (popupComp && popupComp.cleanup) { + popupComp.cleanup(); + } +}, + + onShow() { + this.registerNotificationComponent(); + this.loadGlobalStatus(); + this.checkAuthorization(); + }, + + registerNotificationComponent() { + const notificationComp = this.selectComponent('#global-notification'); + if (notificationComp && notificationComp.showNotification) { + app.globalData.globalNotification = { + show: (data) => notificationComp.showNotification(data), + hide: () => notificationComp.hideNotification() + }; + } + }, + + loadGlobalStatus() { + const globalData = app.globalData; + // 从缓存读取,确保与抢单时使用的数据源一致 + const dashoustatusCache = wx.getStorageSync('dashoustatus'); + const dashoustatus = dashoustatusCache !== '' ? dashoustatusCache : null; + + // 从 globalData 或缓存获取 zhuanghaoStatus(注意字段名可能有差异) + let zhuanghaoStatus = globalData.zhanghaoStatus; + if (zhuanghaoStatus === undefined || zhuanghaoStatus === null) { + zhuanghaoStatus = wx.getStorageSync('zhanghaoStatus'); + } + + this.setData({ + dashoustatus: dashoustatus, + zhuanghaoStatus: zhuanghaoStatus, + dashouzhuangtai: globalData.dashouzhuangtai, + uid: wx.getStorageSync('uid'), + huiyuanList: globalData.clumber || [], + yajin: globalData.yajin || 0, + jifen: globalData.jinfen || 0 + }); + + // 打印当前值,方便调试 + //console.log('loadGlobalStatus -> dashoustatus:', dashoustatus, 'zhuanghaoStatus:', zhuanghaoStatus); + }, + + checkAuthorization() { + const { dashoustatus, zhuanghaoStatus } = this.data; + //console.log('checkAuthorization -> dashoustatus:', dashoustatus, 'zhuanghaoStatus:', zhuanghaoStatus); + + // 完全复制抢单时的判断逻辑 + const isDashouValid = (dashoustatus && dashoustatus == 1) || false; // 存在且等于1 + const isZhuanghaoValid = (zhuanghaoStatus == 1); // 宽松比较,null/undefined/0 均视为 false + + const isAuthorized = isDashouValid && isZhuanghaoValid; + + if (!isAuthorized) { + this.setData({ showUnauthorized: true }); + let msg = ''; + if (!isDashouValid) msg = '您尚未开启身份'; + //else if (!isZhuanghaoValid) msg = '您的账号状态异常'; + this.setData({ unauthorizedMsg: msg || '无法使用抢单功能' }); + } else { + this.setData({ showUnauthorized: false }); + if (!this.data.shangpinleixing.length) { + this.loadShangpinLeixing(); + } else if (this.data.xuanzhongLeixingId) { + this.loadDingdanList(true); + } + PopupService.checkAndShow(this, 'jiedanchi'); + } + }, + + async loadShangpinLeixing() { + wx.showLoading({ title: '加载商品类型...' }); + try { + const res = await request({ + url: '/dingdan/dsqdhqddlx', + method: 'POST', + header: { 'content-type': 'application/json' } + }); + + if (res.statusCode === 200 && res.data) { + const data = res.data; + let list = []; + if (data.code === 200 || data.code === 0) { + if (data.data && Array.isArray(data.data.list)) { + list = data.data.list; + } else if (data.data && Array.isArray(data.data)) { + list = data.data; + } else if (Array.isArray(data.list)) { + list = data.list; + } else if (Array.isArray(data)) { + list = data; + } + } + const processedList = this.processTupianUrl(list); + this.setData({ + shangpinleixing: processedList, + xuanzhongLeixingId: processedList[0]?.id || null + }); + if (this.data.xuanzhongLeixingId) { + this.loadDingdanList(true); + } + } else { + wx.showToast({ title: res.data?.msg || '加载商品类型失败', icon: 'none', duration: 2000 }); + } + } catch (error) { + console.error('加载商品类型失败:', error); + wx.showToast({ title: '网络错误,加载失败', icon: 'none', duration: 2000 }); + } finally { + wx.hideLoading(); + } + }, + + processTupianUrl(list) { + const ossUrl = app.globalData.ossImageUrl || ''; + return list.map(item => ({ + ...item, + full_tupian_url: item.tupian_url && !item.tupian_url.startsWith('http') ? ossUrl + item.tupian_url : (item.tupian_url || '/images/default-type.png') + })); + }, + + async selectLeixing(e) { + const now = Date.now(); + if (now - this.data.lastSwitchTime < this.data.switchCooldown) { + wx.showToast({ + title: `操作太快,请${Math.ceil((this.data.switchCooldown - (now - this.data.lastSwitchTime)) / 1000)}秒后再试`, + icon: 'none', + duration: 1500 + }); + return; + } + if (this.data.isSwitching) return; + const leixingId = e.currentTarget.dataset.id; + if (leixingId === this.data.xuanzhongLeixingId) return; + this.setData({ isSwitching: true, lastSwitchTime: now }); + wx.showLoading({ title: '切换中...' }); + try { + this.setData({ + xuanzhongLeixingId: leixingId, + dingdanList: [], + page: 1, + hasMore: true + }); + await this.loadDingdanList(true); + } catch (error) { + console.error('切换类型失败:', error); + } finally { + this.setData({ isSwitching: false }); + wx.hideLoading(); + } + }, + + async loadDingdanList(isRefresh = false) { + if (this.data.isLoading || !this.data.xuanzhongLeixingId) return; + + const loadPage = isRefresh ? 1 : this.data.page; + if (!isRefresh && !this.data.hasMore) return; + + this.setData({ + isLoading: true, + isLoadingMore: !isRefresh + }); + + try { + const res = await request({ + url: '/dingdan/ddhq', + method: 'POST', + data: { + leixing_id: this.data.xuanzhongLeixingId, + page: loadPage, + page_size: this.data.pageSize + } + }); + + this.setData({ + isLoading: false, + isLoadingMore: false, + scrollViewRefreshing: false + }); + + if (res.data.code === 200 || res.data.code === 0) { + const newList = res.data.data.list || []; + const hasMore = res.data.data.has_more || false; + + const processedList = newList.map(item => this.processDingdanItem(item)); + + const updatedList = isRefresh ? processedList : [...this.data.dingdanList, ...processedList]; + + updatedList.sort((a, b) => (b.creat_time || '').localeCompare(a.creat_time || '')); + + this.setData({ + dingdanList: updatedList, + page: loadPage, + hasMore: hasMore + }); + + if (isRefresh) { + this.setData({ lastRefreshTime: Date.now() }); + } + } else { + wx.showToast({ title: res.data.msg || '加载失败', icon: 'none' }); + } + } catch (error) { + console.error('加载订单失败:', error); + this.setData({ + isLoading: false, + isLoadingMore: false, + scrollViewRefreshing: false + }); + wx.showToast({ title: '网络请求失败', icon: 'none' }); + } + }, + + processDingdanItem(item) { + const ossUrl = app.globalData.ossImageUrl || ''; + let fullTupianUrl = ''; + if (item.tupian) { + fullTupianUrl = !item.tupian.startsWith('http') ? ossUrl + item.tupian : item.tupian; + } else { + const leixing = this.data.shangpinleixing.find(l => l.id === item.leixing_id); + fullTupianUrl = leixing ? leixing.full_tupian_url : '/images/default-order.png'; + } + + const isZhiding = item.zhuangtai === 7; + + let zhidingAvatar = ''; + if (item.zhiding_avatar) { + zhidingAvatar = !item.zhiding_avatar.startsWith('http') ? ossUrl + item.zhiding_avatar : item.zhiding_avatar; + } + const zhidingNicheng = item.zhiding_nicheng || ''; + + return { + ...item, + full_tupian_url: fullTupianUrl, + isZhiding: isZhiding, + isPingtai: item.pingtai == 1, + isShangjia: item.pingtai == 2, + zhiding_avatar_full: zhidingAvatar, + zhiding_nicheng: zhidingNicheng + }; + }, + + goToChongzhiPage(failureType, huiyuanId = null, requiredYajin = 0) { + let url = '/pages/dashouchongzhi/dashouchongzhi'; + let params = {}; + switch (failureType) { + case 'huiyuan': + params = { needScroll: '0', scrollTo: 'member' }; + break; + case 'yajin': + params = { needScroll: '1', scrollTo: 'bottom', requiredYajin: requiredYajin }; + break; + case 'jifen': + params = { needScroll: '1', scrollTo: 'bottom' }; + break; + } + if (huiyuanId) params.huiyuanId = huiyuanId; + const queryString = Object.keys(params).map(key => `${key}=${encodeURIComponent(params[key])}`).join('&'); + const fullUrl = `${url}?${queryString}`; + wx.navigateTo({ + url: fullUrl, + fail: (err) => { + console.error('跳转失败:', err); + wx.showToast({ title: '跳转失败,请稍后重试', icon: 'none' }); + } + }); + }, + + async onQiangdanTap(e) { + const dingdanItem = e.currentTarget.dataset.item; + if (!dingdanItem) return; + + if (!this.data.dashoustatus || this.data.dashoustatus != 1) { + wx.showToast({ title: '请先开启打手身份', icon: 'none' }); + return; + } + if (this.data.zhuanghaoStatus != 1) { + wx.showToast({ title: '账号异常,无法接单', icon: 'none' }); + return; + } + if (this.data.dashouzhuangtai != 1) { + wx.showToast({ title: '您有订单正在接待中', icon: 'none' }); + return; + } + if (dingdanItem.isZhiding) { + if (!this.data.uid || this.data.uid != dingdanItem.zhiding_uid) { + wx.showToast({ title: '此订单为指定单', icon: 'none' }); + return; + } + } + if (dingdanItem.yaoqiuleixing == 1) { + const hasHuiyuan = this.data.huiyuanList.some(h => h.huiyuanid == dingdanItem.huiyuan_id); + if (!hasHuiyuan) { + wx.showToast({ title: '未开通对应会员,无法抢单', icon: 'none', duration: 2000 }); + setTimeout(() => this.goToChongzhiPage('huiyuan', dingdanItem.huiyuan_id), 500); + return; + } + } + if (dingdanItem.yaoqiuleixing == 2) { + if (this.data.yajin < dingdanItem.yajin) { + wx.showToast({ title: `押金不足,需${dingdanItem.yajin}`, icon: 'none', duration: 2000 }); + setTimeout(() => this.goToChongzhiPage('yajin', null, dingdanItem.yajin), 500); + return; + } + } + if (this.data.jifen < 5) { + wx.showToast({ title: '积分不足,至少需要5积分', icon: 'none', duration: 2000 }); + setTimeout(() => this.goToChongzhiPage('jifen'), 500); + return; + } + + const that = this; + wx.showModal({ + title: '确认抢单', + content: `确定要抢此订单吗?${dingdanItem.isZhiding ? '(指定订单)' : ''}`, + success: async function (res) { + if (res.confirm) { + wx.showLoading({ title: '抢单中...', mask: true }); + try { + const qiangdanRes = await request({ + url: '/dingdan/qiangdan', + method: 'POST', + data: { dingdan_id: dingdanItem.dingdan_id } + }); + wx.hideLoading(); + if (qiangdanRes.data.code === 200 || qiangdanRes.data.code === 0) { + that.showQiangdanSuccessEffect(); + if (app.globalData) { + app.globalData.dashouzhuangtai = 0; + that.setData({ dashouzhuangtai: 0 }); + } + const newList = that.data.dingdanList.filter(item => item.dingdan_id !== dingdanItem.dingdan_id); + that.setData({ dingdanList: newList }); + } else { + wx.showToast({ title: qiangdanRes.data.msg || '抢单失败', icon: 'none' }); + } + } catch (error) { + wx.hideLoading(); + console.error('抢单请求失败:', error); + wx.showToast({ title: '网络错误,抢单失败', icon: 'none' }); + } + } + } + }); + }, + + showQiangdanSuccessEffect() { + wx.showToast({ title: '抢单成功!', icon: 'success', duration: 2000 }); + }, + + onViewDetail(e) { + const { type, content } = e.currentTarget.dataset; + wx.showModal({ + title: type === 'jieshao' ? '订单介绍' : '订单备注', + content: content, + showCancel: false, + confirmText: '知道了' + }); + }, + + onReachBottom() { + const now = Date.now(); + if (now - this.data.lastRefreshTime < this.data.refreshCooldown) { + wx.showToast({ + title: `操作太快,请${Math.ceil((this.data.refreshCooldown - (now - this.data.lastRefreshTime)) / 1000)}秒后再试`, + icon: 'none', + duration: 1500 + }); + return; + } + if (this.data.isLoading || this.data.isLoadingMore) return; + if (this.data.hasMore && !this.data.isLoading && this.data.xuanzhongLeixingId) { + this.setData({ page: this.data.page + 1 }); + this.loadDingdanList(false); + } + }, + + onPullDownRefresh() { + const now = Date.now(); + if (now - this.data.lastRefreshTime < this.data.refreshCooldown) { + this.setData({ scrollViewRefreshing: false }); + wx.showToast({ + title: `操作太快,请${Math.ceil((this.data.refreshCooldown - (now - this.data.lastRefreshTime)) / 1000)}秒后再试`, + icon: 'none', + duration: 1500 + }); + return; + } + if (this.data.isLoading) { + this.setData({ scrollViewRefreshing: false }); + return; + } + this.setData({ + scrollViewRefreshing: true, + lastRefreshTime: now + }); + if (this.data.xuanzhongLeixingId) { + this.setData({ page: 1, hasMore: true }); + this.loadDingdanList(true); + } else { + this.setData({ scrollViewRefreshing: false }); + } + }, + + goToDashouRegister() { + wx.navigateTo({ + url: '/pages/dashouduan/dashouduan' + }); + } +}); \ No newline at end of file diff --git a/miniprogram/pages/jiedanchi/jiedanchi.json b/miniprogram/pages/jiedanchi/jiedanchi.json new file mode 100644 index 0000000..ea51a5d --- /dev/null +++ b/miniprogram/pages/jiedanchi/jiedanchi.json @@ -0,0 +1,9 @@ +{ + "navigationBarTitleText": "接单池", + "enablePullDownRefresh": false, + "backgroundTextStyle": "dark", + "backgroundColor": "#f5f7fa", + "usingComponents": { + "global-notification": "/components/global-notification/global-notification" + } + } \ No newline at end of file diff --git a/miniprogram/pages/jiedanchi/jiedanchi.wxml b/miniprogram/pages/jiedanchi/jiedanchi.wxml new file mode 100644 index 0000000..027df01 --- /dev/null +++ b/miniprogram/pages/jiedanchi/jiedanchi.wxml @@ -0,0 +1,263 @@ + + + + + + + + 🔒 + 功能未开启 + {{unauthorizedMsg}} + 请先注册为服务者,即可使用抢单功能 + + 立即注册 + + + + + + + + + + + + + + + + + + {{item.jieshao}} + + + + + + + + + + + + + + + 正在刷新... + 下拉刷新订单 + + + + + + + + 请先选择上方订单类型 + + + + + 当前类型暂无待抢订单 + + + + + + + + + {{item.creat_time}} + + 平台订单 + + + + + 指定 + + {{item.zhiding_nicheng || '指定打手'}} + UID: {{item.zhiding_uid || '未知'}} + + + + + + + 介绍: + {{item.jieshao || '暂无介绍'}} + [点击查看] + + + + + + 备注: + {{item.beizhu}} + [点击查看] + + + + + + 💰 + 分佣 + {{item.dashou_fencheng || 0}} + + + + 立即抢单 + + + + + + + + + + {{item.creat_time}} + + 商家发单 + + + + + 指定 + + {{item.zhiding_nicheng || '指定打手'}} + UID: {{item.zhiding_uid || '未知'}} + + + + + + {{item.sjnicheng || '未知商家'}} + + + + + 订单介绍: + {{item.jieshao || '暂无介绍'}} + [点击查看] + + + + + 商家备注: + {{item.beizhu}} + [点击查看] + + + + + + 💰 + 分佣 + {{item.dashou_fencheng || 0}} + + + + 立即抢单 + + + + + + + + + 加载更多订单中... + + + 没有更多订单了 + + + + + + + + 订单加载中... + + + + + + + \ No newline at end of file diff --git a/miniprogram/pages/jiedanchi/jiedanchi.wxss b/miniprogram/pages/jiedanchi/jiedanchi.wxss new file mode 100644 index 0000000..5784b03 --- /dev/null +++ b/miniprogram/pages/jiedanchi/jiedanchi.wxss @@ -0,0 +1,655 @@ +/* pages/qiangdan/qiangdan.wxss */ +.qiangdan-page { + height: 100vh; + display: flex; + flex-direction: column; + background-color: #f5f7fa; + overflow: hidden; + position: relative; + } + + /* ====== 授权提示页(机甲风格)====== */ + .unauthorized-container { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + background: radial-gradient(ellipse at top, #0b0f1a, #03050a); + z-index: 100; + } + + .unauthorized-card { + width: 600rpx; + padding: 60rpx 40rpx; + background: linear-gradient(145deg, #1a1f30, #0f1422); + border-radius: 60rpx; + position: relative; + overflow: hidden; + border: 2rpx solid rgba(0, 247, 255, 0.3); + box-shadow: 0 30rpx 60rpx rgba(0, 0, 0, 0.8), 0 0 30rpx rgba(0, 247, 255, 0.2); + } + + .card-glow { + position: absolute; + top: -20%; + left: -20%; + width: 140%; + height: 140%; + background: radial-gradient(circle at 30% 30%, rgba(0, 247, 255, 0.2), transparent 60%); + animation: rotateGlow 10s linear infinite; + z-index: 0; + } + + @keyframes rotateGlow { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + .card-content-unauth { + position: relative; + z-index: 2; + display: flex; + flex-direction: column; + align-items: center; + color: #ffffff; + } + + .icon-lock { + font-size: 100rpx; + margin-bottom: 30rpx; + background: rgba(255, 255, 255, 0.1); + width: 160rpx; + height: 160rpx; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + border: 4rpx solid #00f7ff; + box-shadow: 0 0 50rpx #00f7ff; + text-shadow: 0 0 20rpx #00f7ff; + } + + .title { + font-size: 48rpx; + font-weight: 700; + letter-spacing: 4rpx; + margin-bottom: 20rpx; + text-shadow: 0 0 15rpx #00f7ff; + background: linear-gradient(135deg, #ffffff, #aaddff); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + } + + .message { + font-size: 32rpx; + color: #ffaa00; + margin-bottom: 16rpx; + font-weight: 600; + text-shadow: 0 0 10rpx #ffaa00; + } + + .description { + font-size: 28rpx; + color: #a0b0d0; + margin-bottom: 50rpx; + text-align: center; + } + + .btn-register { + position: relative; + padding: 24rpx 80rpx; + background: linear-gradient(145deg, #2a3050, #181e38); + border-radius: 60rpx; + overflow: hidden; + border: 2rpx solid #00f7ff; + box-shadow: 0 10rpx 30rpx rgba(0, 247, 255, 0.4); + transition: transform 0.2s; + } + + .btn-register:active { + transform: scale(0.96); + } + + .btn-text { + font-size: 32rpx; + color: #fff; + font-weight: 700; + letter-spacing: 4rpx; + position: relative; + z-index: 2; + text-shadow: 0 0 10rpx #00f7ff; + } + + .btn-shine { + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient( + to right, + rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 0.2) 50%, + rgba(255, 255, 255, 0) 100% + ); + transform: rotate(30deg); + animation: btn-shimmer 2.8s infinite linear; + z-index: 1; + } + + @keyframes btn-shimmer { + 0% { transform: translateX(-100%) rotate(30deg); } + 100% { transform: translateX(100%) rotate(30deg); } + } + + /* ====== 原有样式(保持不变,仅略作调整以兼容提示页)====== */ + .leixing-quyu { + padding: 30rpx 0 20rpx; + background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%); + border-bottom: 1rpx solid #eaeaea; + position: relative; + z-index: 10; + flex-shrink: 0; + } + + .leixing-scroll { + width: 100%; + white-space: nowrap; + height: 180rpx; + } + + .leixing-container { + display: inline-flex; + padding: 0 30rpx; + } + + .leixing-item { + display: inline-flex; + flex-direction: column; + align-items: center; + width: 160rpx; + margin-right: 24rpx; + position: relative; + transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); + } + + .leixing-active { + transform: translateY(-6rpx); + } + + .guangyun-effect { + position: absolute; + top: -12rpx; + left: -12rpx; + right: -12rpx; + bottom: -12rpx; + background: radial-gradient(circle at center, rgba(82, 196, 26, 0.15) 0%, transparent 70%); + border-radius: 40rpx; + z-index: 0; + animation: guangyun-pulse 2s infinite ease-in-out; + } + + @keyframes guangyun-pulse { + 0%, 100% { opacity: 0.6; transform: scale(1); } + 50% { opacity: 0.9; transform: scale(1.05); } + } + + .leixing-tupian { + width: 120rpx; + height: 120rpx; + border-radius: 28rpx; + z-index: 1; + box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08); + transition: all 0.3s ease; + } + + .leixing-active .leixing-tupian { + box-shadow: 0 16rpx 40rpx rgba(82, 196, 26, 0.3); + border: 4rpx solid #52c41a; + } + + .leixing-jieshao { + margin-top: 16rpx; + font-size: 24rpx; + color: #666; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + text-align: center; + z-index: 1; + } + + .leixing-active .leixing-jieshao { + color: #52c41a; + font-weight: 600; + } + + .fenge-xian { + height: 16rpx; + background: linear-gradient(to bottom, #f0f2f5, #f8f9fa); + flex-shrink: 0; + } + + .dingdan-container { + flex: 1; + overflow: hidden; + } + + .dingdan-scroll-view { + height: 100%; + -webkit-overflow-scrolling: touch; + } + + .refresher-container { + height: 100rpx; + display: flex; + align-items: center; + justify-content: center; + } + + .refreshing-text, + .pull-down-text { + font-size: 26rpx; + color: #999; + } + + .empty-tip { + padding: 120rpx 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } + + .tip-icon { + width: 160rpx; + height: 160rpx; + opacity: 0.4; + margin-bottom: 30rpx; + } + + .tip-text { + font-size: 28rpx; + color: #aaa; + } + + .dingdan-card { + margin: 20rpx 24rpx; + border-radius: 20rpx; + padding: 28rpx; + position: relative; + overflow: hidden; + box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.06); + transition: all 0.2s ease; + border: 1rpx solid rgba(0, 0, 0, 0.08); + } + + .dingdan-card:active { + transform: scale(0.995); + } + + .pingtai-card { + background: linear-gradient(145deg, #f8fff8 0%, #f0f9f0 100%); + } + + .shangjia-card { + background: linear-gradient(145deg, #f9f0ff 0%, #f3e8ff 100%); + } + + .card-top { + display: flex; + align-items: center; + margin-bottom: 20rpx; + padding-bottom: 16rpx; + border-bottom: 1rpx dashed #e0e0e0; + } + + .creat-time { + font-size: 26rpx; + color: #555; + font-weight: 500; + } + + .top-line { + flex: 1; + height: 1rpx; + background: linear-gradient(to right, transparent, #ddd, transparent); + margin: 0 20rpx; + } + + .pingtai-tag { + font-size: 24rpx; + color: #666; + padding: 6rpx 16rpx; + background: rgba(0, 0, 0, 0.04); + border-radius: 20rpx; + } + + .zhiding-row { + display: flex; + align-items: center; + margin-bottom: 20rpx; + padding: 10rpx 16rpx; + background: rgba(255, 77, 79, 0.08); + border-radius: 12rpx; + border-left: 4rpx solid #ff4d4f; + gap: 10rpx; + } + + .zhiding-icon { + font-size: 26rpx; + margin-right: 4rpx; + } + + .zhiding-avatar { + width: 48rpx; + height: 48rpx; + border-radius: 50%; + border: 2rpx solid #ff4d4f; + object-fit: cover; + } + + .zhiding-nicheng { + font-size: 24rpx; + color: #ff4d4f; + font-weight: 500; + max-width: 120rpx; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .zhiding-uid { + font-size: 24rpx; + color: #ff4d4f; + font-weight: 400; + flex: 1; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .card-content { + display: flex; + margin-bottom: 20rpx; + } + + .neirong-tupian { + width: 140rpx; + height: 140rpx; + border-radius: 50%; + margin-right: 24rpx; + flex-shrink: 0; + box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.08); + object-fit: cover; + } + + .jieshao-box { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + min-height: 140rpx; + padding: 16rpx 0; + } + + .jieshao-label { + font-size: 26rpx; + color: #333; + font-weight: 600; + margin-bottom: 8rpx; + } + + .jieshao-text { + font-size: 26rpx; + color: #666; + line-height: 1.4; + } + + .jieshao-ellipsis .jieshao-text { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + overflow: hidden; + text-overflow: ellipsis; + } + + .shangjia-info { + display: flex; + align-items: center; + margin-bottom: 20rpx; + } + + .shangjia-touxiang { + width: 90rpx; + height: 90rpx; + border-radius: 50%; + margin-right: 20rpx; + border: 2rpx solid rgba(114, 46, 209, 0.15); + box-shadow: 0 6rpx 18rpx rgba(114, 46, 209, 0.12); + object-fit: cover; + } + + .shangjia-nicheng { + font-size: 28rpx; + color: #333; + font-weight: 600; + } + + .shangjia-jieshao, + .shangjia-beizhu { + margin-bottom: 16rpx; + padding: 14rpx 18rpx; + background: rgba(255, 255, 255, 0.6); + border-radius: 12rpx; + } + + .shangjia-jieshao .jieshao-label, + .shangjia-beizhu .beizhu-label { + display: block; + margin-bottom: 6rpx; + font-size: 24rpx; + } + + .shangjia-jieshao .jieshao-text, + .shangjia-beizhu .beizhu-text { + font-size: 24rpx; + color: #555; + line-height: 1.4; + } + + .shangjia-jieshao.jieshao-ellipsis .jieshao-text { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-overflow: ellipsis; + } + + .shangjia-beizhu.beizhu-ellipsis .beizhu-text { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-overflow: ellipsis; + } + + .beizhu-box { + margin-bottom: 20rpx; + padding: 14rpx 18rpx; + background: rgba(255, 255, 255, 0.6); + border-radius: 12rpx; + } + + .beizhu-label { + font-size: 24rpx; + color: #333; + font-weight: 600; + margin-bottom: 6rpx; + display: block; + } + + .beizhu-text { + font-size: 24rpx; + color: #666; + line-height: 1.4; + } + + .beizhu-ellipsis .beizhu-text { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-overflow: ellipsis; + } + + .view-more { + display: block; + font-size: 22rpx; + color: #1890ff; + margin-top: 6rpx; + text-align: right; + } + + .card-bottom { + display: flex; + align-items: center; + justify-content: space-between; + padding-top: 20rpx; + border-top: 1rpx solid rgba(0, 0, 0, 0.06); + } + + .fenyong-box { + display: flex; + align-items: baseline; + } + + .fenyong-icon { + font-size: 30rpx; + margin-right: 10rpx; + } + + .fenyong-text { + font-size: 24rpx; + color: #999; + margin-right: 6rpx; + } + + .fenyong-price { + font-size: 40rpx; + color: #ff4d4f; + font-weight: 700; + margin-right: 4rpx; + } + + .fenyong-unit { + font-size: 24rpx; + color: #999; + } + + .qiangdan-btn { + position: relative; + padding: 18rpx 40rpx; + border-radius: 50rpx; + overflow: hidden; + box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.12); + } + + .pingtai-btn { + background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%); + } + + .shangjia-btn { + background: linear-gradient(135deg, #722ed1 0%, #9254de 100%); + } + + .btn-text { + font-size: 28rpx; + color: white; + font-weight: 600; + letter-spacing: 1rpx; + position: relative; + z-index: 2; + } + + .btn-shine { + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient( + to right, + rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 0.3) 50%, + rgba(255, 255, 255, 0) 100% + ); + transform: rotate(30deg); + animation: btn-shimmer 3s infinite linear; + z-index: 1; + } + + @keyframes btn-shimmer { + 0% { transform: translateX(-100%) rotate(30deg); } + 100% { transform: translateX(100%) rotate(30deg); } + } + + .qiangdan-btn:active { + transform: scale(0.96); + } + + .loading-more, + .no-more { + padding: 30rpx 0; + text-align: center; + } + + .loading-text { + font-size: 26rpx; + color: #999; + } + + .no-more-text { + font-size: 26rpx; + color: #ccc; + } + + .loading-mask { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(255, 255, 255, 0.9); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 9999; + } + + .loading-spinner { + width: 70rpx; + height: 70rpx; + border: 6rpx solid #f0f0f0; + border-top: 6rpx solid #52c41a; + border-radius: 50%; + animation: spin 1s linear infinite; + margin-bottom: 24rpx; + } + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + .loading-mask-text { + font-size: 28rpx; + color: #666; + } \ No newline at end of file diff --git a/miniprogram/pages/jiedanchi2/jiedanchi2.js b/miniprogram/pages/jiedanchi2/jiedanchi2.js new file mode 100644 index 0000000..0e33db9 --- /dev/null +++ b/miniprogram/pages/jiedanchi2/jiedanchi2.js @@ -0,0 +1,66 @@ +// pages/jiedanchi2/jiedanchi2.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + + } +}) \ No newline at end of file diff --git a/miniprogram/pages/jiedanchi2/jiedanchi2.json b/miniprogram/pages/jiedanchi2/jiedanchi2.json new file mode 100644 index 0000000..3928faa --- /dev/null +++ b/miniprogram/pages/jiedanchi2/jiedanchi2.json @@ -0,0 +1,3 @@ +{ + "usingComponents": {} +} \ No newline at end of file diff --git a/miniprogram/pages/jiedanchi2/jiedanchi2.wxml b/miniprogram/pages/jiedanchi2/jiedanchi2.wxml new file mode 100644 index 0000000..fdd9cd8 --- /dev/null +++ b/miniprogram/pages/jiedanchi2/jiedanchi2.wxml @@ -0,0 +1,2 @@ + +pages/jiedanchi2/jiedanchi2.wxml \ No newline at end of file diff --git a/miniprogram/pages/jiedanchi2/jiedanchi2.wxss b/miniprogram/pages/jiedanchi2/jiedanchi2.wxss new file mode 100644 index 0000000..fae36a0 --- /dev/null +++ b/miniprogram/pages/jiedanchi2/jiedanchi2.wxss @@ -0,0 +1 @@ +/* pages/jiedanchi2/jiedanchi2.wxss */ \ No newline at end of file diff --git a/miniprogram/pages/jinpaids/jinpaids.js b/miniprogram/pages/jinpaids/jinpaids.js new file mode 100644 index 0000000..aef8cef --- /dev/null +++ b/miniprogram/pages/jinpaids/jinpaids.js @@ -0,0 +1,346 @@ +// pages/jinpaids/jinpaids.js +import request from '../../utils/request.js' +import popupService from '../../services/popupService.js' + +const app = getApp() + +Page({ + data: { + // OSS地址 + ossImageUrl: '', + + // 图标路径 + icons: { + jinpai: '', + refresh: '', + copy: '', + qiangdan: '', + chongzhi: '', + dingdan: '', + chufa: '', + paihang: '', + xiugai: '', + tixian: '', + rightArrow: '' + }, + + // 用户基本信息 + uid: '', + touxiang: '', + avatarUrl: '', + dashouNicheng: '', + + // 打手核心数据 + chenghao: '', + yongjin: '0.00', + zonge: '0.00', + yajin: '0.00', + jinfen: '0', + chengjiaoliang: '0', + zaixianZhuangtai: 0, + dashouzhuangtai: '', + clumber: [], + + // 金牌专属数据 + jiedanZongliang: '0', + jinriJiedan: '0.00', + zuijinTixian: '0.00', + + // 页面状态 + isLoading: false, + lastRefreshTime: 0, + canRefresh: true, + + // 计算数据 + chengjiaoRate: '0%', + chengjiaoAngle: 0, + tixianProgress: 0, + + // 邀请人缓存(管事) + inviterCache: null, + chenghaoList: [] // 新增 + }, + + onLoad() { + const ossUrl = app.globalData.ossImageUrl || '' + const iconBase = 'beijing/tubiao/' + + this.setData({ + ossImageUrl: ossUrl, + 'icons.jinpai': ossUrl + iconBase + 'jinpai.png', + 'icons.refresh': ossUrl + iconBase + 'shuaxin.png', + 'icons.copy': ossUrl + iconBase + 'fuzhi.png', + 'icons.qiangdan': ossUrl + iconBase + 'qiangdan.png', + 'icons.chongzhi': ossUrl + iconBase + 'chongzhi.png', + 'icons.dingdan': ossUrl + iconBase + 'dingdan.png', + 'icons.chufa': ossUrl + iconBase + 'chufa.png', + 'icons.paihang': ossUrl + iconBase + 'paihang.png', + 'icons.xiugai': ossUrl + iconBase + 'xiugai.png', + 'icons.tixian': ossUrl + iconBase + 'tixian.png', + 'icons.rightArrow': ossUrl + iconBase + 'jiantou.png', + 'icons.guize': ossUrl + iconBase + 'guize.png', + 'icons.kaohe': ossUrl + iconBase + 'kaohe.png', + }) + + this.loadUserInfo() + this.getJinpaiInfo() + + if (!app.globalData.hasShownPopupOnColdStart) { + app.globalData.hasShownPopupOnColdStart = true; + setTimeout(() => { + popupService.checkAndShow(this, 'jinpaids'); + }, 300); + } + }, + + onHide() { + const popupComp = this.selectComponent('#popupNotice'); + if (popupComp && popupComp.cleanup) { + popupComp.cleanup(); + } + }, + + onShow() { + this.registerNotificationComponent() + this.refreshJinpaiInfo() + this.fetchChenghaoList() // 新增 + const inviterCache = wx.getStorageSync('inviterCache') || null + this.setData({ inviterCache }) + }, + + registerNotificationComponent() { + const notificationComp = this.selectComponent('#global-notification') + if (notificationComp && notificationComp.showNotification) { + app.globalData.globalNotification = { + show: (data) => notificationComp.showNotification(data), + hide: () => notificationComp.hideNotification() + } + } + }, + + loadUserInfo() { + const uid = wx.getStorageSync('uid') || '' + const touxiang = wx.getStorageSync('touxiang') || '' + const ossUrl = app.globalData.ossImageUrl || '' + const defaultAvatar = ossUrl + (app.globalData.morentouxiang || 'avatar/default.jpg') + + let avatarUrl = defaultAvatar + if (touxiang) { + avatarUrl = ossUrl + (touxiang.startsWith('/') ? touxiang : '/' + touxiang) + } + + const dashouNicheng = app.globalData.dashouNicheng || wx.getStorageSync('nicheng') || '金牌选手' + + this.setData({ uid, touxiang, avatarUrl, dashouNicheng }) + }, + + async getJinpaiInfo() { + this.setData({ isLoading: true }) + + try { + const res = await request({ + url: '/yonghu/dashouxinxi', + method: 'POST' + }) + + if (res && res.data.code === 200) { + const data = res.data.data + + const updateData = { + dashouNicheng: data.dashounicheng || '', + zhanghaoStatus: data.zhanghaostatus || '', + yongjin: data.yongjin || '0.00', + zonge: data.zonge || '0.00', + yajin: data.yajin || '0.00', + chenghao: data.chenghao || '', + jinfen: data.jifen || '0', + chengjiaoliang: data.chengjiaoliang || '0', + zaixianZhuangtai: data.zaixianzhuangtai || 0, + dashouzhuangtai: data.dashouzhuangtai || '', + clumber: data.clumber || [], + jiedanZongliang: data.jiedanZongliang || '0', + jinriJiedan: data.jinriJiedan || '0.00', + zuijinTixian: data.zuijinTixian || '0.00', + } + + const jiedanTotal = parseFloat(updateData.jiedanZongliang) || 0 + const chengjiaoTotal = parseFloat(updateData.chengjiaoliang) || 0 + const rateNumber = jiedanTotal > 0 ? (chengjiaoTotal / jiedanTotal) * 100 : 0 + const chengjiaoRate = rateNumber.toFixed(1) + '%' + const chengjiaoAngle = rateNumber * 3.6 + + const zuijin = parseFloat(updateData.zuijinTixian) || 0 + const zong = parseFloat(updateData.jinriJiedan) || 0 + const tixianProgress = zong > 0 ? Math.min((zuijin / zong) * 100, 100) : 0 + + const globalUpdate = { + dashouNicheng: updateData.dashouNicheng, + zhanghaoStatus: updateData.zhanghaoStatus, + yongjin: updateData.yongjin, + zonge: updateData.zonge, + yajin: updateData.yajin, + chenghao: updateData.chenghao, + jinfen: updateData.jinfen, + chengjiaoliang: updateData.chengjiaoliang, + zaixianZhuangtai: updateData.zaixianZhuangtai, + dashouzhuangtai: updateData.dashouzhuangtai, + clumber: updateData.clumber, + } + Object.assign(app.globalData, globalUpdate) + + wx.setStorageSync('nicheng', updateData.dashouNicheng) + if (data.touxiang) { + wx.setStorageSync('touxiang', data.touxiang) + } + + this.setData({ + ...updateData, + chengjiaoRate, + chengjiaoAngle, + tixianProgress: Math.round(tixianProgress), + isLoading: false + }) + + this.checkJinpaiAndRedirect(updateData.chenghao) + + } else { + wx.showToast({ title: res?.data?.msg || '获取信息失败', icon: 'none' }) + this.setData({ isLoading: false }) + } + } catch (error) { + console.error('获取金牌信息失败:', error) + wx.showToast({ title: '网络错误', icon: 'none' }) + this.setData({ isLoading: false }) + } + }, + + refreshJinpaiInfo() { + const now = Date.now() + const lastTime = this.data.lastRefreshTime + const canRefresh = this.data.canRefresh + if (!canRefresh || (now - lastTime < 3000)) return + + + this.setData({ lastRefreshTime: now, canRefresh: false }) + this.getJinpaiInfo() + this.fetchChenghaoList() // 新增 + setTimeout(() => this.setData({ canRefresh: true }), 3000) + }, + + checkJinpaiAndRedirect(chenghao) { + if (chenghao !== '金牌选手') { + wx.setStorageSync('isJinpai', 0) + wx.redirectTo({ url: '/pages/dashouduan/dashouduan' }) + } else { + wx.setStorageSync('isJinpai', 1) + } + }, + + // 联系管事(与打手端完全一致,增加容错) + async contactInviter() { + wx.showLoading({ title: '获取管事信息...', mask: true }) + try { + const res = await request({ url: '/yonghu/hqwdyqr', method: 'POST' }) + if (res && res.data.code === 200) { + const inviter = res.data.data + const ossImageUrl = getApp().globalData.ossImageUrl || '' + const fullAvatar = inviter.touxiang + ? (inviter.touxiang.startsWith('http') ? inviter.touxiang : ossImageUrl + inviter.touxiang) + : '' + + // 缓存邀请人信息 + const cacheData = { + uid: inviter.uid, + nicheng: inviter.nicheng || '', + avatar: fullAvatar + } + wx.setStorageSync('inviterCache', cacheData) + this.setData({ inviterCache: cacheData }) + + // 确保打手身份并连接 + const app = getApp() + const myUid = wx.getStorageSync('uid') + + // 如果当前不是打手身份,则切换并重连 + if (app.globalData.currentRole !== 'dashou') { + app.globalData.currentRole = 'dashou' + wx.setStorageSync('currentRole', 'dashou') + if (app.switchRoleAndReconnect) { + await app.switchRoleAndReconnect('dashou') + } else if (app.connectWithIdentity) { + // 降级方案:直接用打手身份连接 + await app.connectWithIdentity('dashou', 'Ds' + myUid, false) + } + } else { + // 已为打手,确保连接存活 + if (app.connectForCurrentRole) { + app.connectForCurrentRole() + } else if (app.ensureConnection) { + app.ensureConnection() + } + } + + // 构造私聊参数 + const param = { + toUserId: 'Gs' + inviter.uid, + toName: inviter.nicheng || '管事', + toAvatar: fullAvatar + } + wx.navigateTo({ + url: '/pages/liaotian/liaotian?data=' + encodeURIComponent(JSON.stringify(param)), + fail: (err) => { + console.error('跳转私聊失败', err) + wx.showToast({ title: '打开聊天失败', icon: 'none' }) + } + }) + } else { + wx.showToast({ title: res?.data?.msg || '获取失败', icon: 'none' }) + } + } catch (e) { + console.error('联系管事出错:', e) + wx.showToast({ title: '网络错误', icon: 'none' }) + } finally { + wx.hideLoading() + } + }, + + copyUid() { + const { uid } = this.data + if (!uid) return wx.showToast({ title: 'UID不存在', icon: 'none' }) + wx.setClipboardData({ + data: uid, + success: () => wx.showToast({ title: '已复制UID', icon: 'success' }) + }) + }, + + previewAvatar() { + if (this.data.avatarUrl) wx.previewImage({ urls: [this.data.avatarUrl] }) + }, + + goToWithdraw() { wx.navigateTo({ url: '/pages/tixian/tixian' }) }, + goToReceiveOrder() { wx.navigateTo({ url: '/pages/jiedan/jiedan' }) }, + goToRecharge() { wx.navigateTo({ url: '/pages/dashouchongzhi/dashouchongzhi' }) }, + goToMyOrders() { wx.navigateTo({ url: '/pages/dashoudingdan/dashoudingdan' }) }, + goToMyPunishment() { wx.navigateTo({ url: '/pages/cfss/cfss/cfss' }) }, + goToRanking() { wx.navigateTo({ url: '/pages/dashoupaihang/dashoupaihang' }) }, + goToModifyInfo() { wx.navigateTo({ url: '/pages/dashouxiugai/dashouxiugai' }) }, + goToRules() { wx.navigateTo({ url: '/pages/dashouguize/dashouguize' }) }, + // 跳转到考核金牌 +goToKaohe() { + wx.navigateTo({ url: '/pages/kaohe_jinpai/kaohe_jinpai' }); + }, + + async fetchChenghaoList() { + try { + const res = await request({ + url: '/dengji/dsbqhq', + method: 'POST' + }); + if (res && res.data.code === 0 && res.data.data) { + this.setData({ chenghaoList: res.data.data.chenghao_list || [] }); + } + } catch (e) { + console.error('获取称号标签失败', e); + } +}, +}) \ No newline at end of file diff --git a/miniprogram/pages/jinpaids/jinpaids.json b/miniprogram/pages/jinpaids/jinpaids.json new file mode 100644 index 0000000..f3d656c --- /dev/null +++ b/miniprogram/pages/jinpaids/jinpaids.json @@ -0,0 +1,9 @@ +{ + "usingComponents": { + "global-notification": "/components/global-notification/global-notification", + "chenghao-tag": "/components/chenghao-tag/chenghao-tag" + }, + "navigationBarTitleText": "金牌用户", + "navigationBarBackgroundColor": "#0B2A4A", + "navigationBarTextStyle": "white" + } \ No newline at end of file diff --git a/miniprogram/pages/jinpaids/jinpaids.wxml b/miniprogram/pages/jinpaids/jinpaids.wxml new file mode 100644 index 0000000..5912b19 --- /dev/null +++ b/miniprogram/pages/jinpaids/jinpaids.wxml @@ -0,0 +1,193 @@ + + + + + + + + + + 金牌选手 + + + + 刷新 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 可提现金额 + + {{yongjin}} + + + + + + 立即提现 + + + + + + + + 总赚取 + {{zonge}}元 + + + 保证金 + {{yajin}}元 + + + 积分 + {{jinfen}} + + + 接单总量 + {{jiedanZongliang}} + + + 成交总量 + {{chengjiaoliang}} + + + 今日接单 + {{jinriJiedan}}元 + + + + + + + 成交率 + + + {{chengjiaoRate}} + + + + 最近提现占比 + + + {{tixianProgress}}% + + + 最近提现:{{zuijinTixian}}元 + 今日赚取:{{jinriJiedan}}元 + + + + + + + + + + {{inviterCache.nicheng || '我的管事'}} + ID: {{inviterCache.uid}} + + + 联系我的邀请人 + + + + + + 我的管事 + 点击联系 + + + 联系我的邀请人 + + + + + + + + 抢单大厅 + + + + 充值会员保证金 + + + + 我的订单 + + + + 我的处罚 + + + + 排行榜 + + + + 修改资料 + + + + 用户规则 + + + + 考核金牌 + + + + + + + + + + + + \ No newline at end of file diff --git a/miniprogram/pages/jinpaids/jinpaids.wxss b/miniprogram/pages/jinpaids/jinpaids.wxss new file mode 100644 index 0000000..162eae6 --- /dev/null +++ b/miniprogram/pages/jinpaids/jinpaids.wxss @@ -0,0 +1,610 @@ +/* pages/jinpaids/jinpaids.wxss - 金牌打手机甲风格(CSS变量版) */ + +/* ========== 全局 ========== */ +page { + background: #0B1A2F; + min-height: 100vh; + font-family: 'Avenir', 'PingFang SC', 'Helvetica Neue', sans-serif; + color: #fff; + } + + .bg-grid { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + linear-gradient(rgba(0, 160, 255, 0.1) 1px, transparent 1px), + linear-gradient(90deg, rgba(0, 160, 255, 0.1) 1px, transparent 1px); + background-size: 50rpx 50rpx; + pointer-events: none; + z-index: 0; + } + + .bg-energy { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: radial-gradient(circle at 20% 30%, rgba(0,200,255,0.1) 0%, transparent 40%), + radial-gradient(circle at 80% 70%, rgba(0,100,255,0.1) 0%, transparent 40%); + animation: energyFlow 20s linear infinite; + pointer-events: none; + z-index: 0; + } + + @keyframes energyFlow { + 0% { opacity: 0.3; } + 50% { opacity: 0.6; } + 100% { opacity: 0.3; } + } + + .page-container { + position: relative; + z-index: 2; + min-height: 100vh; + padding: 30rpx 25rpx; + box-sizing: border-box; + } + + /* ========== 顶部栏 ========== */ + .top-bar { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 30rpx; + margin-top: 20rpx; + } + .jinpai-badge { + display: flex; + align-items: center; + } + .jinpai-icon { + width: 60rpx; + height: 60rpx; + margin-right: 15rpx; + } + /* 火苗图标燃烧动画 */ + .fire-icon { + animation: fireBurn 0.8s infinite alternate ease-in-out; + filter: drop-shadow(0 0 10rpx #ffaa00); + } + @keyframes fireBurn { + 0% { transform: scale(1) rotate(-3deg); filter: drop-shadow(0 0 10rpx #ffaa00); } + 25% { transform: scale(1.1) rotate(2deg); filter: drop-shadow(0 0 20rpx #ff5500); } + 50% { transform: scale(1.05) rotate(-2deg); filter: drop-shadow(0 0 30rpx #ffaa00); } + 75% { transform: scale(1.15) rotate(3deg); filter: drop-shadow(0 0 40rpx #ffaa00); } + 100% { transform: scale(1) rotate(-3deg); filter: drop-shadow(0 0 10rpx #ffaa00); } + } + .jinpai-title { + font-size: 40rpx; + font-weight: bold; + color: #ffaa00; + text-shadow: 0 0 30rpx #ffaa00, 0 0 60rpx #ffaa00; + letter-spacing: 2rpx; + } + .refresh-btn { + display: flex; + align-items: center; + background: rgba(0,40,70,0.8); + border: 2rpx solid #00a6ff; + clip-path: polygon(0 0, 100% 0, 90% 100%, 0 100%); + padding: 8rpx 25rpx; + } + .refresh-icon { + width: 40rpx; + height: 40rpx; + margin-right: 10rpx; + } + .refresh-text { + font-size: 26rpx; + color: #00a6ff; + } + .refresh-btn:active { + opacity: 0.8; + } + + /* ========== 用户信息 ========== */ + .user-section { + display: flex; + background: rgba(0,30,50,0.5); + backdrop-filter: blur(20px); + border: 2rpx solid #00a6ff; + clip-path: polygon(0 0, 100% 0, 95% 100%, 0 100%); + padding: 30rpx; + margin-bottom: 40rpx; + } + .avatar-wrap { + position: relative; + width: 120rpx; + height: 120rpx; + margin-right: 30rpx; + } + .avatar { + width: 100%; + height: 100%; + border-radius: 50%; + border: 4rpx solid #00a6ff; + box-shadow: 0 0 50rpx #00a6ff; + object-fit: cover; + } + .avatar-ring { + position: absolute; + top: -10rpx; + left: -10rpx; + right: -10rpx; + bottom: -10rpx; + border-radius: 50%; + border: 2rpx solid #00a6ff; + border-top-color: transparent; + border-bottom-color: transparent; + animation: ringRotate 6s linear infinite; + } + @keyframes ringRotate { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + .user-info { + flex: 1; + } + .name-row { + display: flex; + align-items: center; + margin-bottom: 10rpx; + } + .nickname { + font-size: 40rpx; + font-weight: bold; + color: #fff; + margin-right: 15rpx; + max-width: 250rpx; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .status-tag { + font-size: 22rpx; + padding: 4rpx 16rpx; + border-radius: 30rpx; + background: rgba(255,255,255,0.1); + border: 1rpx solid currentColor; + } + .status-tag.online { color: #00ff80; border-color: #00ff80; } + .status-tag.offline { color: #aaa; border-color: #aaa; } + .uid-row { + display: flex; + align-items: center; + background: rgba(0,50,80,0.6); + border-left: 4rpx solid #00a6ff; + padding: 8rpx 20rpx; + margin-bottom: 10rpx; + width: fit-content; + } + .uid-label { + font-size: 24rpx; + color: #9cf; + margin-right: 10rpx; + } + .uid-value { + font-size: 24rpx; + color: #fff; + font-family: monospace; + margin-right: 15rpx; + } + .copy-icon { + width: 30rpx; + height: 30rpx; + } + .order-status { + display: flex; + align-items: center; + } + .status-label { + font-size: 24rpx; + color: #9cf; + margin-right: 8rpx; + } + .status-value { + font-size: 24rpx; + color: #aaa; + } + .status-value.active { + color: #00ff80; + text-shadow: 0 0 10rpx #00ff80; + } + + /* ========== 核心资产卡 ========== */ + .asset-card { + display: flex; + justify-content: space-between; + align-items: center; + background: linear-gradient(135deg, #0A1F3A, #0B2A4A); + border: 2rpx solid #00a6ff; + clip-path: polygon(0 0, 100% 0, 95% 100%, 0 100%); + padding: 30rpx 30rpx; + margin-bottom: 30rpx; + box-shadow: 0 0 40rpx #00a6ff; + } + .asset-left { + flex: 1; + } + .asset-label { + font-size: 28rpx; + color: #9cf; + display: block; + margin-bottom: 10rpx; + } + .asset-value-group { + display: flex; + align-items: baseline; + } + .asset-number { + font-size: 68rpx; + font-weight: bold; + color: #fff; + text-shadow: 0 0 30rpx #00a6ff, 0 0 60rpx #00a6ff; + } + .asset-unit { + font-size: 32rpx; + color: #00a6ff; + margin-left: 10rpx; + } + .asset-right { + display: flex; + align-items: center; + background: rgba(255,255,255,0.1); + border: 2rpx solid #ffaa00; + clip-path: polygon(0 0, 100% 0, 90% 100%, 0 100%); + padding: 15rpx 30rpx; + position: relative; + overflow: hidden; + } + .withdraw-icon { + width: 50rpx; + height: 50rpx; + margin-right: 10rpx; + } + .withdraw-text { + font-size: 32rpx; + font-weight: bold; + color: #ffaa00; + } + .withdraw-glow { + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); + animation: scan 2s infinite; + } + @keyframes scan { + 0% { left: -100%; } + 100% { left: 100%; } + } + .asset-right:active { + transform: scale(0.96); + } + + /* ========== 统计网格 ========== */ + .stats-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20rpx; + margin-bottom: 40rpx; + } + .stat-item { + background: rgba(0,30,50,0.7); + border: 1rpx solid #00a6ff; + clip-path: polygon(0 0, 100% 0, 90% 100%, 0 100%); + padding: 20rpx 10rpx; + text-align: center; + } + .stat-label { + font-size: 24rpx; + color: #9cf; + display: block; + margin-bottom: 10rpx; + } + .stat-value { + font-size: 32rpx; + font-weight: bold; + color: #fff; + } + + /* ========== 图形化数据(使用CSS变量) ========== */ + .graphic-panel { + background: rgba(0,30,50,0.6); + backdrop-filter: blur(15px); + border: 2rpx solid #00a6ff; + clip-path: polygon(0 0, 100% 0, 98% 100%, 0 100%); + padding: 30rpx; + margin-bottom: 40rpx; + display: flex; + justify-content: space-around; + flex-wrap: wrap; + } + .chart-item { + width: 45%; + text-align: center; + } + .chart-title { + font-size: 28rpx; + color: #9cf; + margin-bottom: 15rpx; + text-transform: uppercase; + border-left: 4rpx solid #00a6ff; + padding-left: 15rpx; + text-align: left; + } + + /* 环形进度条(使用CSS变量 --progress-angle) */ + .ring-chart { + position: relative; + width: 200rpx; + height: 200rpx; + margin: 0 auto; + border-radius: 50%; + overflow: hidden; + box-shadow: 0 0 40rpx #00a6ff; + } + .ring-progress { + width: 100%; + height: 100%; + background: conic-gradient(#00a6ff 0deg, #00a6ff var(--progress-angle), #1a3a5a var(--progress-angle), #1a3a5a 360deg); + border-radius: 50%; + } + .ring-inner { + position: absolute; + top: 15rpx; + left: 15rpx; + right: 15rpx; + bottom: 15rpx; + background: #0a1a2a; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 40rpx; + font-weight: bold; + color: #00a6ff; + box-shadow: inset 0 0 20rpx rgba(0,0,0,0.5); + } + + /* 提现进度条(使用CSS变量 --progress-width) */ + .progress-container { + height: 30rpx; + background: #1a3a5a; + border-radius: 15rpx; + position: relative; + overflow: hidden; + width: 100%; + margin-top: 20rpx; + } + .progress-bar { + height: 100%; + background: linear-gradient(90deg, #00a6ff, #80d4ff); + border-radius: 15rpx; + width: var(--progress-width); + position: relative; + } + .flow-bar::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.6), transparent); + animation: flow 1.5s infinite; + } + @keyframes flow { + 0% { left: -100%; } + 100% { left: 100%; } + } + .progress-label { + position: absolute; + right: 20rpx; + top: -30rpx; + font-size: 24rpx; + color: #00a6ff; + } + .progress-stats { + display: flex; + justify-content: space-between; + font-size: 24rpx; + color: #9cf; + margin-top: 15rpx; + } + + /* ========== 功能按钮(图标强光效果) ========== */ + .function-panel { + margin-bottom: 40rpx; + } + .function-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20rpx; + } + .func-item { + background: rgba(0,20,40,0.8); + border: 1rpx solid #00a6ff; + clip-path: polygon(0 0, 100% 0, 90% 100%, 0 100%); + padding: 25rpx 0; + display: flex; + flex-direction: column; + align-items: center; + transition: 0.2s; + position: relative; + overflow: hidden; + } + .func-item:active { + transform: scale(0.96); + box-shadow: 0 0 40rpx #00a6ff; + } + /* 图标超强发光 */ + .super-glow { + width: 60rpx; + height: 60rpx; + margin-bottom: 15rpx; + filter: drop-shadow(0 0 25rpx #00a6ff) drop-shadow(0 0 50rpx #00a6ff) drop-shadow(0 0 80rpx #00a6ff); + animation: superGlow 1s infinite alternate; + } + @keyframes superGlow { + 0% { filter: drop-shadow(0 0 20rpx #00a6ff) drop-shadow(0 0 40rpx #00a6ff) drop-shadow(0 0 60rpx #00a6ff); } + 100% { filter: drop-shadow(0 0 30rpx #00a6ff) drop-shadow(0 0 60rpx #00a6ff) drop-shadow(0 0 100rpx #00a6ff); } + } + .func-label { + font-size: 26rpx; + color: #fff; + z-index: 1; + } + + /* ========== 加载遮罩 ========== */ + .loading-mask { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(2,6,12,0.9); + backdrop-filter: blur(20px); + display: flex; + align-items: center; + justify-content: center; + z-index: 9999; + } + .loading-core { + width: 200rpx; + height: 200rpx; + border: 4rpx solid #00a6ff; + border-radius: 50%; + border-top-color: transparent; + animation: spin 1s linear infinite; + display: flex; + align-items: center; + justify-content: center; + } + .loading-core::after { + content: ''; + width: 100rpx; + height: 100rpx; + border: 4rpx solid #ffaa00; + border-radius: 50%; + border-bottom-color: transparent; + animation: spin 1.5s reverse infinite; + } + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + + + + + /* ========== 原有样式(完全不变) ========== */ +/* ... 此处省略,切勿修改 ... */ + +/* ========== 联系管事胶囊(新增,适配机甲风格) ========== */ +.inviter-capsule { + margin: 30rpx 25rpx 30rpx; + background: rgba(0, 20, 40, 0.85); + backdrop-filter: blur(20px); + border: 2rpx solid #00a6ff; + clip-path: polygon(5% 0, 100% 0, 95% 100%, 0 100%); + padding: 20rpx 30rpx; + display: flex; + align-items: center; + justify-content: space-between; + box-shadow: 0 0 30rpx rgba(0, 166, 255, 0.4); + position: relative; + z-index: 1; + } + + .capsule-body { + display: flex; + align-items: center; + flex: 1; + } + + .capsule-avatar { + width: 80rpx; + height: 80rpx; + border-radius: 50%; + border: 3rpx solid #00a6ff; + box-shadow: 0 0 20rpx #00a6ff; + margin-right: 20rpx; + background: #0a1a2a; + } + + .capsule-info { + display: flex; + flex-direction: column; + } + + .capsule-name { + font-size: 30rpx; + font-weight: bold; + color: #fff; + text-shadow: 0 0 15rpx #00a6ff; + margin-bottom: 6rpx; + } + + .capsule-uid { + font-size: 24rpx; + color: #9cf; + } + + .capsule-contact { + background: linear-gradient(135deg, #00a6ff, #0080ff); + border-radius: 30rpx; + padding: 12rpx 30rpx; + font-size: 26rpx; + font-weight: bold; + color: #fff; + box-shadow: 0 0 20rpx #00a6ff; + letter-spacing: 2rpx; + transition: all 0.3s; + } + + .capsule-contact:active { + transform: scale(0.95); + box-shadow: 0 0 40rpx #00a6ff; + } + + + + + + + + /* ========== 🆕 称号标签展示区 ========== */ +.badge-area { + width: 100%; + margin: 20rpx 0 30rpx 0; + padding: 0 20rpx; + box-sizing: border-box; + } + + .badge-scroll { + width: 100%; + max-height: 140rpx; + overflow-y: auto; + background: transparent; + } + + .badge-grid { + display: flex; + flex-wrap: wrap; + gap: 8rpx; + padding: 6rpx 0; + align-items: center; + justify-content: flex-start; + } + + .badge-item { + flex-shrink: 0; + } \ No newline at end of file diff --git a/miniprogram/pages/jisufd/jisufd.js b/miniprogram/pages/jisufd/jisufd.js new file mode 100644 index 0000000..49ae9cb --- /dev/null +++ b/miniprogram/pages/jisufd/jisufd.js @@ -0,0 +1,618 @@ +// pages/jisufd/jisufd.js +import request from '../../utils/request.js' + +const PAGE_SIZE = 50 +const LINK_PAGE_SIZE = 5 + +Page({ + data: { + sjyue: '0.00', + shangpinList: [], // 最终展示的商品类型列表(已倒序) + selectedTypeId: null, + selectedHuiyuanId: null, + selectedYaoqiuleixing: null, + currentTypeChenghaoList: [], + + searchParams: { keyword: '', minPrice: '', labelId: '' }, + searchLabelName: '', + isSearchMode: false, + + templateList: [], + currentPage: 1, + hasMoreData: true, + isLoadingMore: false, + + linkMap: {}, + + showDetailModal: false, + showAddModal: false, + showDeleteConfirm: false, + showNewLinkConfirm: false, + + currentTemplate: null, + currentTemplateIndex: -1, + + isEditing: false, + editJieshao: '', + editJiage: '', + editLabelId: '', + editLabelName: '', + editCommissionEnabled: false, + editCommissionValue: '', + + addJieshao: '', + addJiage: '', + addLabelId: '', + addLabelName: '', + addCommissionEnabled: false, + addCommissionValue: '', + + detailLinkFilter: 0, + detailLinkList: [], + detailLinkPage: 1, + detailLinkHasMore: true, + isLoadingLinks: false, + + isLoading: false + }, + + onLoad() { + this.loadShangjiaYue() + this.loadShangpinTypes() + }, + + onShow() { + this.registerNotificationComponent() + this.loadShangjiaYue() + }, + + registerNotificationComponent() { + const app = getApp() + const comp = this.selectComponent('#global-notification') + if (comp && comp.showNotification) { + app.globalData.globalNotification = { + show: data => comp.showNotification(data), + hide: () => comp.hideNotification() + } + } + }, + + loadShangjiaYue() { + const app = getApp() + const data = app.globalData.shangjia || {} + this.setData({ sjyue: data.sjyue || '0.00' }) + }, + + async loadShangpinTypes() { + this.setData({ isLoading: true }) + try { + const res = await request({ url: '/dingdan/sjspleixing', method: 'POST' }) + if (res && res.data.code === 200) { + let list = res.data.data || [] + // 强制倒序排列 + list.reverse() + this.setData({ shangpinList: list, isLoading: false }) + if (list.length > 0) { + this.setSelectedType(list[0]) + } + } + } catch (e) { + console.error(e) + this.setData({ isLoading: false }) + wx.showToast({ title: '加载类型失败', icon: 'error' }) + } + }, + + setSelectedType(item) { + this.setData({ + selectedTypeId: item.id, + selectedHuiyuanId: item.huiyuan_id, + selectedYaoqiuleixing: item.yaoqiuleixing, + currentTypeChenghaoList: item.chenghaoList || [] + }, () => { + this.resetAndLoadTemplates() + }) + }, + + resetAndLoadTemplates() { + this.setData({ + templateList: [], + currentPage: 1, + hasMoreData: true, + isSearchMode: false, + searchParams: { keyword: '', minPrice: '', labelId: '' }, + searchLabelName: '' + }) + this.loadTemplates() + }, + + async loadTemplates() { + const { selectedTypeId, currentPage, isSearchMode, searchParams, linkMap } = this.data + if (!selectedTypeId) { + wx.showToast({ title: '请先选择订单类型', icon: 'none' }) + return + } + if (currentPage === 1) this.setData({ isLoading: true }) + else this.setData({ isLoadingMore: true }) + + try { + const postData = { + shangpinTypeId: selectedTypeId, + page: currentPage, + pageSize: PAGE_SIZE, + getType: isSearchMode ? 1 : 2 + } + if (isSearchMode) { + if (searchParams.keyword) postData.keyword = searchParams.keyword.trim() + if (searchParams.minPrice) postData.minPrice = searchParams.minPrice + if (searchParams.labelId) postData.labelId = searchParams.labelId + } + + const res = await request({ url: '/peizhi/sjddmblb', method: 'POST', data: postData }) + if (res && res.data.code === 200) { + const data = res.data.data || {} + const newTemplates = data.list || [] + const existingIds = new Set(this.data.templateList.map(item => item.mobanId)) + const uniqueNew = newTemplates.filter(item => !existingIds.has(item.mobanId)) + + const processed = uniqueNew.map(item => { + const mobanId = item.mobanId || item.id + const cached = linkMap[mobanId] || {} + return { + ...item, + hasGenerated: cached.hasGenerated || !!item.linkUrl, + isCopied: cached.isCopied || false, + linkUrl: cached.linkUrl || item.linkUrl || '', + mobanId: mobanId, + jieshao: item.jieshao || item.moban_jieshao, + jiage: item.jiage || item.price, + fabushuliang: item.fabushuliang || item.fabu_shuliang || 0, + labelId: item.labelId, + labelName: item.labelName || '', + commissionEnabled: item.commissionEnabled, + commissionValue: item.commissionValue + } + }) + + this.setData({ + templateList: currentPage === 1 ? processed : [...this.data.templateList, ...processed], + hasMoreData: data.hasMore !== false && processed.length === PAGE_SIZE, + isLoading: false, + isLoadingMore: false + }) + } else { + this.setData({ isLoading: false, isLoadingMore: false, hasMoreData: false }) + } + } catch (e) { + console.error(e) + this.setData({ isLoading: false, isLoadingMore: false }) + wx.showToast({ title: '加载模板失败', icon: 'error' }) + } + }, + + // ---------- 搜索相关 ---------- + onSearchKeywordInput(e) { this.setData({ 'searchParams.keyword': e.detail.value }) }, + onSearchMinPriceInput(e) { this.setData({ 'searchParams.minPrice': e.detail.value }) }, + onSearchLabelChange(e) { + const idx = e.detail.value + const label = this.data.currentTypeChenghaoList[idx] + this.setData({ + 'searchParams.labelId': label ? label.id : '', + searchLabelName: label ? label.mingcheng : '' + }) + }, + onSearchConfirm() { + const { searchParams } = this.data + if (!searchParams.keyword && !searchParams.minPrice && !searchParams.labelId) { + this.resetAndLoadTemplates() + return + } + this.setData({ + isSearchMode: true, + currentPage: 1, + templateList: [], + hasMoreData: true + }, () => this.loadTemplates()) + }, + onClearSearch() { this.resetAndLoadTemplates() }, + + // ---------- 卡片生成链接 ---------- + async onGenerateLink(e) { + const { id } = e.currentTarget.dataset + const idx = this.data.templateList.findIndex(item => item.mobanId === id) + if (idx === -1) return + await this.generateLinkForTemplate(this.data.templateList[idx], idx) + }, + + onCopyLink(e) { + const { id } = e.currentTarget.dataset + const idx = this.data.templateList.findIndex(item => item.mobanId === id) + if (idx === -1) return + const template = this.data.templateList[idx] + if (!template.linkUrl) { + wx.showToast({ title: '请先生成链接', icon: 'none' }) + return + } + wx.setClipboardData({ + data: template.linkUrl, + success: () => { + const { linkMap } = this.data + const mobanId = template.mobanId + const updatedLinkMap = { ...linkMap } + if (updatedLinkMap[mobanId]) updatedLinkMap[mobanId].isCopied = true + const updatedList = [...this.data.templateList] + updatedList[idx].isCopied = true + this.setData({ linkMap: updatedLinkMap, templateList: updatedList }) + wx.showToast({ title: '链接已复制', icon: 'success' }) + } + }) + }, + + async generateLinkForTemplate(template, templateIndex) { + const { selectedTypeId, linkMap } = this.data + if (!selectedTypeId) { + wx.showToast({ title: '请选择订单类型', icon: 'none' }) + return + } + wx.showLoading({ title: '生成中...', mask: true }) + try { + const res = await request({ + url: '/peizhi/sjljhq', + method: 'POST', + data: { mobanId: template.mobanId, shangpinTypeId: selectedTypeId } + }) + if (res && res.data.code === 200) { + const data = res.data.data || {} + const mobanId = template.mobanId + const updatedLinkMap = { ...linkMap } + updatedLinkMap[mobanId] = { + hasGenerated: true, + linkUrl: data.linkUrl || '', + isCopied: false, + newBalance: data.newBalance + } + const updatedList = [...this.data.templateList] + updatedList[templateIndex] = { + ...updatedList[templateIndex], + hasGenerated: true, + linkUrl: data.linkUrl || '', + isCopied: false, + newBalance: data.newBalance + } + if (data.newBalance) { + const app = getApp() + if (app.globalData.shangjia) app.globalData.shangjia.sjyue = data.newBalance + this.setData({ sjyue: data.newBalance }) + } + this.setData({ linkMap: updatedLinkMap, templateList: updatedList }) + wx.showToast({ title: '链接生成成功', icon: 'success' }) + } else { + wx.showToast({ title: res.data.msg || '生成失败', icon: 'error' }) + } + } catch (e) { + wx.showToast({ title: '生成失败', icon: 'error' }) + } finally { + wx.hideLoading() + } + }, + + onCardTap(e) { + const { target } = e + if (target.className && (target.className.includes('btn') || target.className.includes('action'))) return + const { item } = e.currentTarget.dataset + if (!item) return + const idx = this.data.templateList.findIndex(t => t.mobanId === item.mobanId) + this.setData({ + currentTemplate: item, + currentTemplateIndex: idx, + showDetailModal: true, + isEditing: false, + editJieshao: item.jieshao || '', + editJiage: item.jiage || '', + editLabelId: item.labelId || '', + editLabelName: item.labelName || '', + editCommissionEnabled: item.commissionEnabled || false, + editCommissionValue: item.commissionValue || '', + detailLinkFilter: 0, + detailLinkList: [], + detailLinkPage: 1, + detailLinkHasMore: true + }) + this.loadDetailLinks() + }, + + hideDetailModal() { this.setData({ showDetailModal: false, isEditing: false }) }, + showAddModal() { + this.setData({ + showAddModal: true, + addJieshao: '', addJiage: '', addLabelId: '', addLabelName: '', + addCommissionEnabled: false, addCommissionValue: '' + }) + }, + hideAddModal() { this.setData({ showAddModal: false }) }, + hideDeleteConfirm() { this.setData({ showDeleteConfirm: false }) }, + hideNewLinkConfirm() { this.setData({ showNewLinkConfirm: false }) }, + + // ---------- 链接筛选与加载 ---------- + onToggleLinkFilter() { + const newFilter = this.data.detailLinkFilter === 0 ? 1 : 0 + this.setData({ + detailLinkFilter: newFilter, + detailLinkList: [], + detailLinkPage: 1, + detailLinkHasMore: true + }, () => this.loadDetailLinks()) + }, + + async loadDetailLinks() { + const { currentTemplate, detailLinkFilter, detailLinkPage, isLoadingLinks } = this.data + if (!currentTemplate || isLoadingLinks) return + this.setData({ isLoadingLinks: true }) + try { + const res = await request({ + url: '/peizhi/hqsjlslj', + method: 'POST', + data: { + mobanId: currentTemplate.mobanId, + used: detailLinkFilter, + page: detailLinkPage, + pageSize: LINK_PAGE_SIZE + } + }) + if (res && res.data.code === 200) { + const data = res.data.data || {} + const newLinks = data.list || [] + const merged = detailLinkPage === 1 ? newLinks : [...this.data.detailLinkList, ...newLinks] + this.setData({ + detailLinkList: merged, + detailLinkHasMore: newLinks.length === LINK_PAGE_SIZE, + isLoadingLinks: false + }) + } else { + this.setData({ isLoadingLinks: false }) + } + } catch (e) { + this.setData({ isLoadingLinks: false }) + wx.showToast({ title: '加载链接失败', icon: 'error' }) + } + }, + + onLoadMoreLinks() { + if (!this.data.detailLinkHasMore || this.data.isLoadingLinks) return + this.setData({ detailLinkPage: this.data.detailLinkPage + 1 }, () => this.loadDetailLinks()) + }, + + onCopyLinkItem(e) { + const url = e.currentTarget.dataset.url + if (!url) return + wx.setClipboardData({ data: url, success: () => wx.showToast({ title: '已复制', icon: 'success' }) }) + }, + + // ---------- 弹窗内操作 ---------- + onGenerateLinkModal() { + const { currentTemplate, currentTemplateIndex } = this.data + if (!currentTemplate) return + if (currentTemplate.hasGenerated && !currentTemplate.isCopied) { + this.setData({ showNewLinkConfirm: true }) + return + } + this.generateLinkForTemplate(currentTemplate, currentTemplateIndex) + }, + + onCopyLinkModal() { + const { currentTemplate, linkMap } = this.data + if (!currentTemplate || !currentTemplate.linkUrl) { + wx.showToast({ title: '请先生成链接', icon: 'none' }) + return + } + wx.setClipboardData({ + data: currentTemplate.linkUrl, + success: () => { + const mobanId = currentTemplate.mobanId + const updatedLinkMap = { ...linkMap } + if (updatedLinkMap[mobanId]) updatedLinkMap[mobanId].isCopied = true + const updatedList = [...this.data.templateList] + if (this.data.currentTemplateIndex !== -1) { + updatedList[this.data.currentTemplateIndex].isCopied = true + } + const updatedCurrent = { ...currentTemplate, isCopied: true } + this.setData({ linkMap: updatedLinkMap, templateList: updatedList, currentTemplate: updatedCurrent }) + wx.showToast({ title: '链接已复制', icon: 'success' }) + } + }) + }, + + // ---------- 编辑 ---------- + onEditTemplate() { + if (!this.data.isEditing) this.setData({ isEditing: true }) + else this.saveTemplateEdit() + }, + onEditJieshaoInput(e) { this.setData({ editJieshao: e.detail.value }) }, + onEditJiageInput(e) { this.setData({ editJiage: e.detail.value }) }, + onEditLabelChange(e) { + const idx = e.detail.value + const label = this.data.currentTypeChenghaoList[idx] + this.setData({ editLabelId: label ? label.id : '', editLabelName: label ? label.mingcheng : '' }) + }, + onEditCommissionToggle() { this.setData({ editCommissionEnabled: !this.data.editCommissionEnabled }) }, + onEditCommissionValueInput(e) { this.setData({ editCommissionValue: e.detail.value }) }, + + async saveTemplateEdit() { + const { currentTemplate, selectedTypeId, editJieshao, editJiage, editLabelId, editCommissionEnabled, editCommissionValue } = this.data + if (!currentTemplate || !selectedTypeId) return + if (editCommissionEnabled && (!editCommissionValue || isNaN(parseFloat(editCommissionValue)))) { + wx.showToast({ title: '请输入有效佣金金额', icon: 'none' }) + return + } + wx.showLoading({ title: '保存中...', mask: true }) + try { + const res = await request({ + url: '/peizhi/sjddmbgx', + method: 'POST', + data: { + mobanId: currentTemplate.mobanId, + shangpinTypeId: selectedTypeId, + jieshao: editJieshao, + jiage: editJiage, + labelId: editLabelId || '', + commissionEnabled: editCommissionEnabled, + commissionValue: editCommissionValue + } + }) + if (res && res.data.code === 200) { + const updatedList = [...this.data.templateList] + const idx = this.data.currentTemplateIndex + if (idx !== -1) { + updatedList[idx] = { + ...updatedList[idx], + jieshao: editJieshao, + jiage: editJiage, + labelId: editLabelId, + labelName: this.getLabelNameById(editLabelId), + commissionEnabled: editCommissionEnabled, + commissionValue: editCommissionValue + } + this.setData({ templateList: updatedList, currentTemplate: updatedList[idx], isEditing: false }) + } + wx.showToast({ title: '修改成功', icon: 'success' }) + } else { + wx.showToast({ title: res.data.msg || '修改失败', icon: 'error' }) + } + } catch (e) { + wx.showToast({ title: '修改失败', icon: 'error' }) + } finally { wx.hideLoading() } + }, + + onDeleteTemplate() { this.setData({ showDeleteConfirm: true }) }, + + async confirmDeleteTemplate() { + const { currentTemplate, selectedTypeId, linkMap } = this.data + if (!currentTemplate || !selectedTypeId) return + wx.showLoading({ title: '删除中...', mask: true }) + try { + const res = await request({ + url: '/peizhi/sjddmbsc', + method: 'POST', + data: { mobanId: currentTemplate.mobanId, shangpinTypeId: selectedTypeId } + }) + if (res && res.data.code === 200) { + const updatedLinkMap = { ...linkMap } + delete updatedLinkMap[currentTemplate.mobanId] + const updatedList = [...this.data.templateList] + updatedList.splice(this.data.currentTemplateIndex, 1) + this.setData({ + linkMap: updatedLinkMap, + templateList: updatedList, + showDetailModal: false, + showDeleteConfirm: false, + currentTemplate: null, + currentTemplateIndex: -1 + }) + wx.showToast({ title: '删除成功', icon: 'success' }) + } else { + wx.showToast({ title: res.data.msg || '删除失败', icon: 'error' }) + } + } catch (e) { + wx.showToast({ title: '删除失败', icon: 'error' }) + } finally { wx.hideLoading() } + }, + + async confirmNewLink() { + const { currentTemplate, currentTemplateIndex } = this.data + if (!currentTemplate) return + this.setData({ showNewLinkConfirm: false }) + await this.generateLinkForTemplate(currentTemplate, currentTemplateIndex) + }, + + // ---------- 添加模板 ---------- + onAddJieshaoInput(e) { this.setData({ addJieshao: e.detail.value }) }, + onAddJiageInput(e) { this.setData({ addJiage: e.detail.value }) }, + onAddLabelChange(e) { + const idx = e.detail.value + const label = this.data.currentTypeChenghaoList[idx] + this.setData({ addLabelId: label ? label.id : '', addLabelName: label ? label.mingcheng : '' }) + }, + onAddCommissionToggle() { this.setData({ addCommissionEnabled: !this.data.addCommissionEnabled }) }, + onAddCommissionValueInput(e) { this.setData({ addCommissionValue: e.detail.value }) }, + + async onAddTemplate() { + const { selectedTypeId, addJieshao, addJiage, addLabelId, addCommissionEnabled, addCommissionValue } = this.data + if (!selectedTypeId) { + wx.showToast({ title: '请选择订单类型', icon: 'none' }) + return + } + if (!addJieshao.trim()) { + wx.showToast({ title: '请输入订单介绍', icon: 'none' }) + return + } + if (!addJiage || isNaN(parseFloat(addJiage)) || parseFloat(addJiage) <= 0) { + wx.showToast({ title: '请输入有效的价格', icon: 'none' }) + return + } + if (addCommissionEnabled && (!addCommissionValue || isNaN(parseFloat(addCommissionValue)))) { + wx.showToast({ title: '请输入有效的佣金金额', icon: 'none' }) + return + } + + wx.showLoading({ title: '添加中...', mask: true }) + try { + const res = await request({ + url: '/peizhi/sjtjddmb', + method: 'POST', + data: { + shangpinTypeId: selectedTypeId, + jieshao: addJieshao.trim(), + jiage: addJiage, + labelId: addLabelId || '', + commissionEnabled: addCommissionEnabled, + commissionValue: addCommissionValue + } + }) + if (res && res.data.code === 200) { + const data = res.data.data || {} + const newTemplate = { + mobanId: data.mobanId, + jieshao: addJieshao, + jiage: addJiage, + fabushuliang: 0, + hasGenerated: false, + isCopied: false, + linkUrl: '', + labelId: addLabelId, + labelName: this.getLabelNameById(addLabelId), + commissionEnabled: addCommissionEnabled, + commissionValue: addCommissionValue + } + this.setData({ + templateList: [newTemplate, ...this.data.templateList], + showAddModal: false, + addJieshao: '', addJiage: '', addLabelId: '', addLabelName: '', + addCommissionEnabled: false, addCommissionValue: '' + }) + wx.showToast({ title: '添加成功', icon: 'success' }) + } else { + wx.showToast({ title: res.data.msg || '添加失败', icon: 'error' }) + } + } catch (e) { + wx.showToast({ title: '添加失败', icon: 'error' }) + } finally { wx.hideLoading() } + }, + + getLabelNameById(labelId) { + if (!labelId) return '' + const list = this.data.currentTypeChenghaoList + const found = list.find(item => item.id == labelId) + return found ? found.mingcheng : '' + }, + + onScrollToLower() { + const { hasMoreData, isLoadingMore, isSearchMode } = this.data + if (!hasMoreData || isLoadingMore || isSearchMode) return + this.setData({ currentPage: this.data.currentPage + 1 }, () => this.loadTemplates()) + }, + + onSelectType(e) { + const { id, item } = e.currentTarget.dataset + this.setSelectedType(item) + } +}) \ No newline at end of file diff --git a/miniprogram/pages/jisufd/jisufd.json b/miniprogram/pages/jisufd/jisufd.json new file mode 100644 index 0000000..e0c0695 --- /dev/null +++ b/miniprogram/pages/jisufd/jisufd.json @@ -0,0 +1,12 @@ +{ + "usingComponents": { + "global-notification": "/components/global-notification/global-notification", + "chenghao-tag": "/components/chenghao-tag/chenghao-tag" + }, + "backgroundTextStyle": "dark", + "navigationBarBackgroundColor": "#0a0a0f", + "navigationBarTitleText": "极速派单", + "navigationBarTextStyle": "white", + "backgroundColor": "#0a0a0f", + "enablePullDownRefresh": false +} \ No newline at end of file diff --git a/miniprogram/pages/jisufd/jisufd.wxml b/miniprogram/pages/jisufd/jisufd.wxml new file mode 100644 index 0000000..5d0fc2a --- /dev/null +++ b/miniprogram/pages/jisufd/jisufd.wxml @@ -0,0 +1,230 @@ + + + + + 可用余额 + + {{sjyue}} + + + 生成链接将从此余额扣除 + + + + + 选择订单类型 + + + + {{item.jieshao}} + + + + + + + + + 🔍 + + + 搜索 + + + + + 金额≥ + + + + 标签 + + + {{searchLabelName || '全部'}} + + + + 清空 + + + + + + + + + + + {{item.jieshao || '无介绍'}} + + + + + + 价格: + {{item.jiage || '0.00'}}元 + + + + {{item.hasGenerated ? '获取新链接' : '生成链接'}} + + + {{item.isCopied ? '已复制' : '一键复制'}} + + + + + + + 添加模板 + 点击创建新模板 + + + ... + 没有更多模板了 + 暂无模板 + + + + + + + + × + 模板详情 + + + 订单介绍 + {{currentTemplate.jieshao || '无介绍'}} + + + 关联标签 + + + + 价格{{currentTemplate.jiage || '0.00'}}元 + | + 发布数量{{currentTemplate.fabushuliang || 0}}次 + | + 模板ID{{currentTemplate.mobanId || 'N/A'}} + + + 佣金要求 + {{currentTemplate.commissionValue}}元(建议≤50) + + + + 链接状态: + 未使用 + 已使用 + + + + + {{item.lianjie}} + {{item.is_used ? '已使用' : '未使用'}} + 复制 + + + + 获取更多链接 + + 加载中... + 暂无链接 + + + + {{currentTemplate.hasGenerated ? '获取新链接' : '生成链接'}} + {{currentTemplate.isCopied ? '已复制' : '复制链接'}} + {{isEditing ? '保存修改' : '立即修改'}} + 删除模板 + + + + + 订单介绍 + + {{countdown}}秒后可确认 + + 取消 + 确认拒绝 + + + + + + + + 确认转移考核 + 转移后,您将无法继续考核此订单,可在考核中心重新接待。 + {{countdown}}秒后可确认 + + 取消 + 确认转移 + + + + + \ No newline at end of file diff --git a/miniprogram/pages/kaohe_dafen/kaohe_dafen.wxss b/miniprogram/pages/kaohe_dafen/kaohe_dafen.wxss new file mode 100644 index 0000000..f736716 --- /dev/null +++ b/miniprogram/pages/kaohe_dafen/kaohe_dafen.wxss @@ -0,0 +1,170 @@ +/* 根容器,全屏且底部固定 */ +.root-page { + width: 100vw; + height: 100vh; + background: radial-gradient(ellipse at 20% 20%, #1a1e2b 0%, #0b0c12 100%); + display: flex; + flex-direction: column; + } + + /* 滚动区域 */ + .scroll-container { + flex: 1; + overflow-y: auto; + padding: 30rpx 30rpx 0; + padding-bottom: constant(safe-area-inset-bottom); + padding-bottom: env(safe-area-inset-bottom); + } + + /* 卡片 */ + .card { + background: rgba(25, 27, 36, 0.8); + backdrop-filter: blur(20px); + border: 1rpx solid rgba(201, 169, 88, 0.15); + border-radius: 24rpx; + padding: 30rpx; + margin-bottom: 30rpx; + box-shadow: 0 8rpx 30rpx rgba(0,0,0,0.5); + } + + /* 用户信息 */ + .user-row { + display: flex; + align-items: center; + margin-bottom: 30rpx; + } + .avatar { + width: 80rpx; height: 80rpx; + border-radius: 50%; + border: 2rpx solid rgba(201,169,88,0.4); + margin-right: 20rpx; + } + .info { flex: 1; } + .uid { font-size: 30rpx; color: #f0f2ff; font-weight: 600; } + .time { font-size: 22rpx; color: #6a7090; margin-top: 4rpx; } + .contact-btn { + background: rgba(201,169,88,0.15); + border: 1rpx solid rgba(201,169,88,0.3); + border-radius: 20rpx; + padding: 8rpx 24rpx; + font-size: 24rpx; + color: #c9a558; + } + + /* 详情网格 */ + .detail-grid { + border-bottom: 1rpx solid rgba(255,255,255,0.06); + margin-bottom: 20rpx; + } + .detail-item { + display: flex; + align-items: center; + padding: 16rpx 0; + border-bottom: 1rpx solid rgba(255,255,255,0.04); + } + .detail-item:last-child { border-bottom: none; } + .label { font-size: 26rpx; color: #8a90b0; width: 160rpx; flex-shrink: 0; } + .value { font-size: 26rpx; color: #d0d4ff; font-weight: 500; } + .rule-content { white-space: pre-wrap; line-height: 1.5; } + .jinpai-note { font-size: 24rpx; color: #c9a558; font-weight: 600; margin-left: 10rpx; } + + /* 失败原因 */ + .fail-box { + background: rgba(255, 70, 70, 0.1); + border-left: 4rpx solid #ff5e5e; + padding: 16rpx; + border-radius: 8rpx; + margin-bottom: 20rpx; + } + .fail-label { font-size: 24rpx; color: #ff8a8a; } + .fail-text { font-size: 24rpx; color: #ffd0d0; } + + /* 昵称修改 */ + .nick-row { + display: flex; + align-items: center; + margin-bottom: 30rpx; + } + .nick-input { + flex: 1; + background: rgba(255,255,255,0.06); + border: 1rpx solid rgba(255,255,255,0.1); + border-radius: 12rpx; + padding: 12rpx 20rpx; + color: #fff; + font-size: 26rpx; + margin-right: 20rpx; + } + .save-nick-btn { + background: #c9a558; + color: #0b0c12; + padding: 12rpx 30rpx; + border-radius: 30rpx; + font-size: 26rpx; + font-weight: 600; + } + + /* 操作按钮 */ + .action-row { + display: flex; + gap: 20rpx; + margin-top: 20rpx; + } + .action-btn { + flex: 1; + height: 80rpx; + display: flex; + align-items: center; + justify-content: center; + border-radius: 40rpx; + font-size: 28rpx; + font-weight: 600; + color: #fff; + } + .agree { background: linear-gradient(135deg, #c9a558, #9e7d2e); } + .reject { background: linear-gradient(135deg, #a85050, #802a2a); } + .transfer { background: linear-gradient(135deg, #4a6090, #2a3a60); } + + /* 加载/空状态 */ + .loading, .no-more, .empty { text-align: center; padding: 30rpx; color: #6a7090; font-size: 28rpx; } + + /* 弹窗 */ + .modal-mask { + position: fixed; + top: 0; left: 0; right: 0; bottom: 0; + background: rgba(0,0,0,0.7); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + } + .modal-box { + width: 80%; + background: #1e2030; + border-radius: 24rpx; + padding: 30rpx; + border: 1rpx solid rgba(201,169,88,0.2); + } + .modal-header { font-size: 32rpx; color: #f0f2ff; font-weight: 600; margin-bottom: 20rpx; } + .modal-body { font-size: 26rpx; color: #b0b8d0; margin-bottom: 20rpx; } + .reason-input { + width: 100%; + height: 200rpx; + background: rgba(255,255,255,0.05); + border-radius: 12rpx; + padding: 15rpx; + color: #fff; + font-size: 26rpx; + box-sizing: border-box; + margin-bottom: 20rpx; + } + .countdown-text { text-align: center; font-size: 28rpx; color: #c9a558; margin-bottom: 20rpx; } + .modal-footer { display: flex; gap: 20rpx; } + .btn { + flex: 1; height: 80rpx; border-radius: 40rpx; + display: flex; align-items: center; justify-content: center; + font-size: 28rpx; font-weight: 600; + } + .cancel { background: #2a2f3e; color: #fff; } + .confirm { background: linear-gradient(135deg, #c9a558, #9e7d2e); color: #0b0c12; } + .confirm.disabled { opacity: 0.4; pointer-events: none; } \ No newline at end of file diff --git a/miniprogram/pages/kaohe_jilu/kaohe_jilu.js b/miniprogram/pages/kaohe_jilu/kaohe_jilu.js new file mode 100644 index 0000000..545e567 --- /dev/null +++ b/miniprogram/pages/kaohe_jilu/kaohe_jilu.js @@ -0,0 +1,149 @@ +// pages/kaohe_jilu/kaohe_jilu.js +const app = getApp(); +import request from '../../utils/request.js'; + +Page({ + data: { + // 板块筛选 + moduleList: [], + xuanzhongBankuaiId: 0, // 0代表全部 + // 状态筛选:0-全部 1-审核中 2-已通过 3-未通过 + statusFilter: 0, + // 记录列表 + recordList: [], + page: 1, + pageSize: 5, + hasMore: true, + isLoading: false, + isLoadingMore: false, + // 展开的记录ID集合(字符串数组) + expandedIds: [], + // OSS地址 + ossImageUrl: app.globalData.ossImageUrl || '', + }, + + onLoad() { + this.loadModules(); + }, + + // 加载板块(复用审核大厅接口) + async loadModules() { + try { + const res = await request({ url: '/dengji/shdthqmk', method: 'POST' }); + if (res && res.data.code === 0) { + const modules = res.data.data.modules || []; + this.setData({ moduleList: modules, xuanzhongBankuaiId: 0 }); + this.loadRecords(true); + } else { + wx.showToast({ title: '加载模块失败', icon: 'none' }); + } + } catch (e) { + wx.showToast({ title: '网络错误', icon: 'none' }); + } + }, + + // 选择板块 + selectModule(e) { + const bankuaiId = e.currentTarget.dataset.id; + if (bankuaiId === this.data.xuanzhongBankuaiId) return; + this.setData({ + xuanzhongBankuaiId: bankuaiId, + recordList: [], + page: 1, + hasMore: true, + expandedIds: [] + }); + this.loadRecords(true); + }, + + // 选择状态 + selectStatus(e) { + const status = e.currentTarget.dataset.status; + if (status === this.data.statusFilter) return; + this.setData({ + statusFilter: status, + recordList: [], + page: 1, + hasMore: true, + expandedIds: [] + }); + this.loadRecords(true); + }, + + // 加载历史记录 + async loadRecords(isRefresh = false) { + if (this.data.isLoading) return; + const page = isRefresh ? 1 : this.data.page; + if (!isRefresh && !this.data.hasMore) return; + + this.setData({ isLoading: true, isLoadingMore: !isRefresh }); + + try { + const res = await request({ + url: '/dengji/khghqkhjl', + method: 'POST', + data: { + bankuai_id: this.data.xuanzhongBankuaiId || undefined, + status: this.data.statusFilter || undefined, + page: page, + page_size: this.data.pageSize + } + }); + + this.setData({ isLoading: false, isLoadingMore: false }); + + if (res && res.data.code === 0) { + const list = res.data.data.list || []; + const hasMore = res.data.data.has_more; + // 拼接头像 + const oss = this.data.ossImageUrl; + const processedList = list.map(item => { + let avatar = item.shenqingren_avatar || ''; + if (avatar && !avatar.startsWith('http')) { + avatar = oss + avatar; + } + return { ...item, shenqingren_avatar: avatar }; + }); + const newList = isRefresh ? processedList : [...this.data.recordList, ...processedList]; + this.setData({ recordList: newList, page: page + 1, hasMore: hasMore }); + } else { + wx.showToast({ title: '加载记录失败', icon: 'none' }); + } + } catch (e) { + this.setData({ isLoading: false, isLoadingMore: false }); + wx.showToast({ title: '网络错误', icon: 'none' }); + } + }, + + // 上拉加载更多 + onReachBottom() { + if (this.data.hasMore && !this.data.isLoading && !this.data.isLoadingMore) { + this.loadRecords(false); + } + }, + + // 展开/收起详情 + toggleExpand(e) { + const jiluId = e.currentTarget.dataset.id; + // 确保 jiluId 是字符串 + const id = String(jiluId); + const expandedIds = this.data.expandedIds.slice(); // 拷贝 + const index = expandedIds.indexOf(id); + if (index > -1) { + expandedIds.splice(index, 1); + } else { + expandedIds.push(id); + } + this.setData({ expandedIds }); + }, + + // 去评判(跳转考核打分页) + goJudge(e) { + const item = e.currentTarget.dataset.item; + if (!item) return; + wx.navigateTo({ url: '/pages/kaohe_dafen/kaohe_dafen?jilu_id=' + item.jilu_id }); + }, + + // 阻止冒泡 + noop() {} +}); \ No newline at end of file diff --git a/miniprogram/pages/kaohe_jilu/kaohe_jilu.json b/miniprogram/pages/kaohe_jilu/kaohe_jilu.json new file mode 100644 index 0000000..f6a68c8 --- /dev/null +++ b/miniprogram/pages/kaohe_jilu/kaohe_jilu.json @@ -0,0 +1,9 @@ +{ + "usingComponents": { + "chenghao-tag": "/components/chenghao-tag/chenghao-tag", + "global-notification": "/components/global-notification/global-notification" + }, + "navigationBarTitleText": "考核记录", + "navigationBarBackgroundColor": "#FDFBF7", + "navigationBarTextStyle": "black" + } \ No newline at end of file diff --git a/miniprogram/pages/kaohe_jilu/kaohe_jilu.wxml b/miniprogram/pages/kaohe_jilu/kaohe_jilu.wxml new file mode 100644 index 0000000..b8ac9ff --- /dev/null +++ b/miniprogram/pages/kaohe_jilu/kaohe_jilu.wxml @@ -0,0 +1,130 @@ + + + + + + + + + 全部板块 + + + + {{item.mingcheng}} + + + + + + + 全部 + 审核中 + 已通过 + 未通过 + + + + + + + + 暂无考核记录 + + + + + + + + + {{item.zhuangtai == 0 ? '审核中' : (item.zhuangtai == 1 ? '已通过' : (item.zhuangtai == 2 ? '未通过' : '待审核'))}} + + + + + + + 板块 + {{item.bankuai_mingcheng}} + + + 标签 + + + + 次数 + {{item.cishu}}次 + + + 总费用 + ¥{{item.total_fee}} + + + + + + + {{expandedIds.indexOf(item.jilu_id) > -1 ? '收起详情' : '展开详情'}} + + + 去评判 + + + + + + + 考核规则 + {{item.guize_neirong}} + + + 缴纳记录 + + 第{{item.cishu}}次:¥{{item.jine}} + + 暂无缴纳记录 + + + 拒绝记录 + + + {{item.create_time}} + 第{{item.cishu}}次拒绝:{{item.yuanyin}} + + + 暂无拒绝记录 + + + 其他信息 + + 打手游戏ID:{{item.dashou_youxi_id || '无'}} + 打手备注:{{item.dashou_beizhu || '无'}} + 审核官游戏ID:{{item.shenheguan_youxi_id || '无'}} + 创建时间:{{item.create_time}} + 更新时间:{{item.update_time}} + + + + + + + 加载更多... + —— 没有更多了 —— + + + + + + + + 加载中... + + + + \ No newline at end of file diff --git a/miniprogram/pages/kaohe_jilu/kaohe_jilu.wxss b/miniprogram/pages/kaohe_jilu/kaohe_jilu.wxss new file mode 100644 index 0000000..bf37003 --- /dev/null +++ b/miniprogram/pages/kaohe_jilu/kaohe_jilu.wxss @@ -0,0 +1,263 @@ +/* pages/kaohe_jilu/kaohe_jilu.wxss - 晨露微光风格(左右均等边距) */ +page { + background: linear-gradient(135deg, #FDFBF7 0%, #F2EFE9 100%); + color: #4A4A4A; + font-family: 'SF Pro Display', 'PingFang SC', system-ui; + height: 100vh; + overflow: hidden; + } + + .page-root { + height: 100vh; + display: flex; + flex-direction: column; + overflow: hidden; + } + + /* 筛选栏 */ + .filter-bar { + background: rgba(255, 255, 255, 0.8); + backdrop-filter: blur(20px); + border-bottom: 1rpx solid rgba(0,0,0,0.04); + flex-shrink: 0; + padding: 20rpx 0 0; + } + + .module-scroll { + white-space: nowrap; + height: 70rpx; + padding: 0 30rpx; + } + .module-container { + display: inline-flex; + gap: 20rpx; + align-items: center; + height: 70rpx; + } + + .filter-item { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0 30rpx; + height: 56rpx; + border-radius: 28rpx; + background: #F0EFEC; + font-size: 26rpx; + color: #6B6B6B; + transition: all 0.2s; + } + .filter-item.active { + background: #C8A27A; + color: #FFFFFF; + font-weight: 600; + box-shadow: 0 4rpx 12rpx rgba(200, 162, 122, 0.3); + } + + .status-row { + display: flex; + padding: 15rpx 30rpx 20rpx; + gap: 30rpx; + } + .status-item { + font-size: 26rpx; + color: #8B8B8B; + padding-bottom: 8rpx; + border-bottom: 4rpx solid transparent; + transition: all 0.2s; + } + .status-item.active { + color: #C8A27A; + border-bottom-color: #C8A27A; + font-weight: 600; + } + + /* 列表容器 */ + .list-container { + flex: 1; + overflow: hidden; + } + .list-scroll { + height: 100%; + padding: 20rpx 0; /* 上下内边距 */ + } + + .empty-tip { + text-align: center; + color: #A0A0A0; + font-size: 28rpx; + padding-top: 200rpx; + } + + /* 卡片:统一左右边距 30rpx */ + .card { + background: #FFFFFF; + border-radius: 28rpx; + padding: 30rpx; + margin: 0 30rpx 24rpx 30rpx; /* 左右严格相等 */ + box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.04); + transition: all 0.3s; + } + + .card-header { + display: flex; + align-items: center; + margin-bottom: 24rpx; + } + .avatar { + width: 72rpx; + height: 72rpx; + border-radius: 50%; + margin-right: 18rpx; + border: 2rpx solid #F0EDE8; + background: #F7F5F2; + } + .user-info { + flex: 1; + } + .nickname { + font-size: 30rpx; + font-weight: 600; + color: #3A3A3A; + display: block; + } + .uid { + font-size: 24rpx; + color: #9A9A9A; + margin-top: 4rpx; + } + .status-tag { + font-size: 24rpx; + padding: 6rpx 18rpx; + border-radius: 20rpx; + font-weight: 500; + } + .status-0 { background: #FFF3E0; color: #EF6C00; } + .status-1 { background: #E8F5E9; color: #2E7D32; } + .status-2 { background: #FFEBEE; color: #C62828; } + .status-3 { background: #E3F2FD; color: #1565C0; } + + .card-summary { + display: flex; + flex-wrap: wrap; + gap: 16rpx 24rpx; + margin-bottom: 20rpx; + } + .summary-item { + display: flex; + align-items: center; + font-size: 26rpx; + } + .summary-item .label { + color: #8B8B8B; + margin-right: 12rpx; + } + .summary-item .value { + color: #3A3A3A; + font-weight: 500; + } + + .card-actions { + display: flex; + justify-content: space-between; + align-items: center; + padding-top: 20rpx; + border-top: 1rpx solid #F5F2ED; + } + .expand-btn { + font-size: 26rpx; + color: #C8A27A; + font-weight: 500; + } + .judge-btn { + font-size: 26rpx; + background: #C8A27A; + color: #FFFFFF; + padding: 8rpx 24rpx; + border-radius: 24rpx; + font-weight: 500; + } + + /* 展开详情(左右边距继承卡片,无需额外设置) */ + .card-detail { + margin-top: 20rpx; + padding-top: 20rpx; + border-top: 1rpx solid #F5F2ED; + } + .detail-section { + margin-bottom: 20rpx; + } + .detail-title { + font-size: 26rpx; + font-weight: 600; + color: #5A5A5A; + margin-bottom: 10rpx; + display: block; + } + .detail-text { + font-size: 24rpx; + color: #6B6B6B; + line-height: 1.6; + } + .fee-row, .reject-row { + font-size: 24rpx; + color: #6B6B6B; + padding: 6rpx 0; + } + .reject-item { + display: flex; + flex-direction: column; + background: #FFF9F5; + padding: 12rpx 16rpx; + border-radius: 12rpx; + margin-bottom: 12rpx; + } + .reject-time { + font-size: 22rpx; + color: #B0A090; + margin-bottom: 4rpx; + } + .reject-reason { + font-size: 24rpx; + color: #7A5A4A; + } + .detail-empty { + font-size: 24rpx; + color: #A0A0A0; + padding: 8rpx 0; + } + .info-grid { + display: flex; + flex-direction: column; + gap: 8rpx; + font-size: 24rpx; + color: #6B6B6B; + } + + /* 加载 */ + .loading-more, .no-more { + text-align: center; + padding: 30rpx; + font-size: 24rpx; + color: #A0A0A0; + } + .loading-mask { + position: fixed; + top: 0; left: 0; right: 0; bottom: 0; + background: rgba(253, 251, 247, 0.8); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 999; + } + .loading-spinner { + width: 60rpx; + height: 60rpx; + border: 4rpx solid #E0DDD5; + border-top-color: #C8A27A; + border-radius: 50%; + animation: spin 0.8s linear infinite; + margin-bottom: 20rpx; + } + @keyframes spin { to { transform: rotate(360deg); } } \ No newline at end of file diff --git a/miniprogram/pages/kaohe_jinpai/kaohe_jinpai.js b/miniprogram/pages/kaohe_jinpai/kaohe_jinpai.js new file mode 100644 index 0000000..ed6fcb4 --- /dev/null +++ b/miniprogram/pages/kaohe_jinpai/kaohe_jinpai.js @@ -0,0 +1,461 @@ +// pages/kaohe_jinpai/kaohe_jinpai.js +const app = getApp(); +import request from '../../utils/request.js'; + +Page({ + data: { + activeTab: 'all_tags', + plateList: [], // 第一个接口返回的所有板块及标签(含 fee_list) + myTags: [], + recordList: [], + recordPage: 1, + recordHasMore: true, + recordLoading: false, + recordFilter: 'pending', + showApplyModal: false, + selectedTag: null, + applyGameNick: '', + applyRemark: '', + applyFee: 0, + applyJiluId: '', + isReapply: false, + payLoading: false, + ossImageUrl: app.globalData.ossImageUrl || '', + + // 新增:考核官相关 + kaoheguanList: [], // 所有可选的考核官 + showKaoheguanModal: false, // 考核官选择弹窗 + selectedKaoheguanId: '', // 已选择的考核官ID + selectedKaoheguanInfo: null, // 已选择的考核官信息(用于展示) + searchKeyword: '', // 搜索关键词 + filteredKaoheguanList: [], // 搜索过滤后的列表 + }, + + onLoad() { + this.fetchAllTags(); + this.fetchMyRecords(true); + }, + + switchTab(e) { + const tab = e.currentTarget.dataset.tab; + if (tab === this.data.activeTab) return; + this.setData({ activeTab: tab }); + if (tab === 'my_records') this.fetchMyRecords(true); + }, + + // 获取所有板块及标签(含费用列表),缓存到 plateList,同时获取考核官列表 + async fetchAllTags() { + try { + const res = await request({ url: '/dengji/dskhhq', method: 'POST' }); + if (res.data.code === 0) { + const { plate_list, my_tags, kaoheguan_list } = res.data.data; + // 拼接考核官头像为完整URL + const ossUrl = this.data.ossImageUrl; + const processedKgList = (kaoheguan_list || []).map(kg => ({ + ...kg, + avatar: kg.avatar && !kg.avatar.startsWith('http') ? ossUrl + kg.avatar : kg.avatar, + })); + this.setData({ + plateList: plate_list || [], + myTags: my_tags || [], + kaoheguanList: processedKgList // 使用拼接后的列表 + }); + } + } catch (e) {} + }, + + // 获取我的考核记录,并根据 plateList 计算本次/预计下次费用 + async fetchMyRecords(isRefresh = false) { + if (this.data.recordLoading) return; + const page = isRefresh ? 1 : this.data.recordPage; + this.setData({ recordLoading: true }); + try { + const res = await request({ + url: '/dengji/dskhjl', + method: 'POST', + data: { status: this.data.recordFilter, page, page_size: 5 } + }); + if (res.data.code === 0) { + const { list, has_more } = res.data.data; + + // 从 plateList 构建标签ID -> 完整标签对象的映射(用于精确匹配费用) + const tagMap = {}; + this.data.plateList.forEach(plate => { + (plate.tags || []).forEach(tag => { + tagMap[tag.id] = tag; // tag 包含 fee_list + }); + }); + + // 处理每条记录:优先使用 tag_obj.id 匹配,其次 chenghao_id + const processed = list.map(item => { + // 尝试多种方式获取标签ID + const tagId = (item.tag_obj && item.tag_obj.id) || item.chenghao_id; + const tag = tagMap[tagId] || item.tag_obj || {}; + const feeList = tag.fee_list || []; + let currentFee = 0; + let nextFee = 0; + if (feeList.length > 0) { + const cishu = item.cishu; + const cur = feeList.find(f => f.cishu === cishu); + currentFee = cur ? cur.feiyong : feeList[feeList.length - 1].feiyong; + const nextCishu = cishu + 1; + const nxt = feeList.find(f => f.cishu === nextCishu); + nextFee = nxt ? nxt.feiyong : feeList[feeList.length - 1].feiyong; + } + return { + ...item, + current_fee: currentFee, + next_fee: nextFee, + tag_obj: tag // 使用匹配到的完整标签对象,保证后续“再次考核”能拿到费用 + }; + }); + + const newList = isRefresh ? processed : [...this.data.recordList, ...processed]; + this.setData({ + recordList: newList, + recordPage: page + 1, + recordHasMore: has_more, + recordLoading: false + }); + } else { + this.setData({ recordLoading: false }); + } + } catch (e) { + this.setData({ recordLoading: false }); + } + }, + + filterRecord(e) { + const filter = e.currentTarget.dataset.filter; + if (filter === this.data.recordFilter) return; + this.setData({ recordFilter: filter, recordList: [], recordPage: 1, recordHasMore: true }); + this.fetchMyRecords(true); + }, + + onReachBottom() { + if (this.data.activeTab === 'my_records' && this.data.recordHasMore) { + this.fetchMyRecords(false); + } + }, + + // 打开申请考核弹窗,费用完全基于 plateList 中的标签数据 + openApplyModal(e) { + const { tag, jiluid, reapply } = e.currentTarget.dataset; + // 查找完整标签对象,保证 fee_list 存在 + let fullTag = tag; + if (fullTag && fullTag.fee_list === undefined) { + const found = this.findTagInPlateList(fullTag.id); + if (found) fullTag = found; + } + if (!fullTag) { + const found = this.findTagInPlateList(tag); + if (found) fullTag = found; + } + + let fee = 0; + if (fullTag) { + let nextCishu = 0; + // 再次申请时,基于原记录次数计算下一次考核次数 + if (reapply && jiluid) { + const record = this.data.recordList.find(r => r.jilu_id === jiluid); + if (record) { + nextCishu = record.cishu + 1; + } else { + nextCishu = (fullTag.my_cishu || 0) + 1; + } + } else { + nextCishu = (fullTag.my_cishu || 0) + 1; + } + const feeList = fullTag.fee_list || []; + const exact = feeList.find(f => f.cishu === nextCishu); + if (exact) { + fee = exact.feiyong; + } else if (feeList.length > 0) { + fee = feeList[feeList.length - 1].feiyong; + } + } + // 检查再次申请时原记录是否有考核官,若有则不允许指定 + let canSpecify = true; + let originalShenheguanId = ''; + if (reapply && jiluid) { + const record = this.data.recordList.find(r => r.jilu_id === jiluid); + if (record && record.shenheguan_id) { + canSpecify = false; // 已有考核官,不能指定新的 + originalShenheguanId = record.shenheguan_id; + } + } + this.setData({ + showApplyModal: true, + selectedTag: fullTag || null, + applyGameNick: '', + applyRemark: '', + applyFee: fee, + applyJiluId: jiluid || '', + isReapply: reapply || false, + selectedKaoheguanId: '', // 重置 + selectedKaoheguanInfo: null, + canSpecify: canSpecify, // 新增 + originalShenheguanId: originalShenheguanId, // 新增 + }); + }, + + // 辅助方法:从 plateList 查找指定 id 的标签 + findTagInPlateList(tagId) { + if (!tagId) return null; + for (const plate of this.data.plateList) { + for (const t of (plate.tags || [])) { + if (t.id === tagId) return t; + } + } + return null; + }, + + closeApplyModal() { + this.setData({ showApplyModal: false }); + }, + + // 实时更新游戏昵称 + onNickInput(e) { + this.setData({ applyGameNick: e.detail.value }); + }, + + // 实时更新备注 + onRemarkInput(e) { + this.setData({ applyRemark: e.detail.value }); + }, + + // 新增:打开考核官选择弹窗 + openKaoheguanModal() { + if (!this.data.canSpecify) { + wx.showToast({ title: '已有考核官,无法重新指定', icon: 'none' }); + return; + } + // 根据费用筛选可选考核官 + let all = [...this.data.kaoheguanList]; + if (this.data.applyFee > 0) { + all = all.filter(kg => kg.is_renzheng); + } + this.setData({ + showKaoheguanModal: true, + filteredKaoheguanList: all, + searchKeyword: '', + }); + }, + + // 关闭考核官选择弹窗 + closeKaoheguanModal() { + this.setData({ showKaoheguanModal: false }); + }, + + // 搜索输入 + onSearchInput(e) { + const value = e.detail.value.trim(); + this.setData({ searchKeyword: value }); + this.filterKaoheguanList(value); + }, + + // 过滤考核官列表 + filterKaoheguanList(keyword) { + let all = [...this.data.kaoheguanList]; + if (this.data.applyFee > 0) { + all = all.filter(kg => kg.is_renzheng); + } + if (keyword) { + all = all.filter(kg => + kg.yonghuid.includes(keyword) || + (kg.dashou_nick && kg.dashou_nick.includes(keyword)) + ); + } + this.setData({ filteredKaoheguanList: all }); + }, + + // 选择一个考核官 + selectKaoheguan(e) { + const kg = e.currentTarget.dataset.kg; + if (kg.shenhe_zhuangtai !== 0) { + wx.showToast({ title: '该考核官正忙,无法指定', icon: 'none' }); + return; + } + this.setData({ + selectedKaoheguanId: kg.yonghuid, + selectedKaoheguanInfo: kg, + showKaoheguanModal: false, + }); + }, + + // 取消已选择的考核官 + clearSelectedKaoheguan() { + this.setData({ + selectedKaoheguanId: '', + selectedKaoheguanInfo: null, + }); + }, + + // 提交申请 + async submitApply() { + const { applyGameNick, applyRemark, applyFee, selectedTag, isReapply, applyJiluId, selectedKaoheguanId } = this.data; + if (!applyGameNick || !applyGameNick.trim()) { + wx.showToast({ title: '请输入游戏昵称', icon: 'none' }); + return; + } + if (!applyRemark || !applyRemark.trim()) { + wx.showToast({ title: '请填写备注', icon: 'none' }); + return; + } + if (applyFee > 0) { + await this.startPayProcess(); + } else { + await this.doFreeApply(); + } + }, + + // 支付流程 + async startPayProcess() { + this.setData({ payLoading: true }); + try { + const res = await request({ + url: '/yonghu/khzf', + method: 'POST', + data: { + tag_id: this.data.selectedTag.id, + game_nick: this.data.applyGameNick, + remark: this.data.applyRemark, + reapply: this.data.isReapply, + jilu_id: this.data.applyJiluId, + shenheguan_id: this.data.selectedKaoheguanId, // 新增 + } + }); + if (res.data.code !== 200) throw new Error(res.data.message || '下单失败'); + const payParams = res.data.payParams; + const dingdanid = res.data.dingdanid; + wx.requestPayment({ + timeStamp: payParams.timeStamp, + nonceStr: payParams.nonceStr, + package: payParams.package, + signType: payParams.signType || 'MD5', + paySign: payParams.paySign, + success: async () => { + await this.pollPayStatus(dingdanid); + }, + fail: () => { + wx.showToast({ title: '支付取消或失败', icon: 'none' }); + request({ url: '/yonghu/khzfsb', method: 'POST', data: { dingdanid } }).catch(()=>{}); + } + }); + } catch (e) { + wx.showToast({ title: e.message || '支付异常', icon: 'none' }); + } finally { + this.setData({ payLoading: false }); + } + }, + + // 轮询支付结果 + async pollPayStatus(dingdanid) { + for (let i = 0; i < 10; i++) { + try { + const res = await request({ url: '/yonghu/khzffc', method: 'POST', data: { dingdanid } }); + if (res.data.code === 200) { + wx.showToast({ title: '申请成功', icon: 'success' }); + this.closeApplyModal(); + this.fetchAllTags(); + this.setData({ recordList: [], recordPage: 1 }); + this.fetchMyRecords(true); + return; + } + } catch (e) {} + await new Promise(r => setTimeout(r, 2000)); + } + wx.showToast({ title: '支付确认超时', icon: 'none' }); + }, + + // 免费申请 + async doFreeApply() { + try { + const res = await request({ + url: '/dengji/dssqkh', + method: 'POST', + data: { + tag_id: this.data.selectedTag.id, + game_nick: this.data.applyGameNick, + remark: this.data.applyRemark, + reapply: this.data.isReapply, + jilu_id: this.data.applyJiluId, + shenheguan_id: this.data.selectedKaoheguanId, // 新增 + } + }); + if (res.data.code === 0) { + wx.showToast({ title: '申请成功', icon: 'success' }); + this.closeApplyModal(); + this.fetchAllTags(); + this.setData({ recordList: [], recordPage: 1 }); + this.fetchMyRecords(true); + } else { + wx.showToast({ title: res.data.msg || '申请失败', icon: 'none' }); + } + } catch (e) { + wx.showToast({ title: '网络错误', icon: 'none' }); + } + }, + + // 联系考核官(私聊) + contactKaoheguan(e) { + const item = e.currentTarget.dataset.item; + if (!item) return; + if (!item.shenheguan_id) { + wx.showToast({ title: '暂无考核官信息', icon: 'none' }); + return; + } + const uid = wx.getStorageSync('uid'); + if (!uid) { + wx.showToast({ title: '用户信息缺失', icon: 'none' }); + return; + } + if (app.globalData.currentRole !== 'dashou') { + app.globalData.currentRole = 'dashou'; + wx.setStorageSync('currentRole', 'dashou'); + } + if (app.connectForCurrentRole) { + app.connectForCurrentRole(); + } else if (app.ensureConnection) { + app.ensureConnection(); + } + const ossImageUrl = this.data.ossImageUrl || app.globalData.ossImageUrl || ''; + let fullAvatar = item.shenheguan_avatar || ''; + if (fullAvatar && !fullAvatar.startsWith('http')) { + fullAvatar = ossImageUrl + fullAvatar; + } + if (!fullAvatar) { + fullAvatar = ossImageUrl + (app.globalData.morentouxiang || 'avatar/default.jpg'); + } + const param = { + toUserId: 'Kh' + item.shenheguan_id, + toName: '考核官' + item.shenheguan_id, + toAvatar: fullAvatar + }; + wx.navigateTo({ + url: '/pages/liaotian/liaotian?data=' + encodeURIComponent(JSON.stringify(param)), + fail: (err) => { + wx.showToast({ title: '打开聊天失败', icon: 'none' }); + } + }); + }, + + showTagDetail(e) { + const tag = e.currentTarget.dataset.tag; + const feeStr = this.formatFeeList(tag.fee_list); + wx.showModal({ + title: tag.name, + content: `规则:${tag.rule || '暂无'}\n${tag.jinpai ? '【可同时开启金牌】' : ''}\n费用:${feeStr}`, + showCancel: false, + confirmText: '知道了' + }); + }, + + formatFeeList(feeList) { + if (!feeList || feeList.length === 0) return '暂无'; + let str = feeList.map(f => `第${f.cishu}次:¥${f.feiyong}`).join(';'); + const last = feeList[feeList.length - 1]; + str += `;第${last.cishu}次及以上:¥${last.feiyong}`; + return str; + }, +}); \ No newline at end of file diff --git a/miniprogram/pages/kaohe_jinpai/kaohe_jinpai.json b/miniprogram/pages/kaohe_jinpai/kaohe_jinpai.json new file mode 100644 index 0000000..fa331e5 --- /dev/null +++ b/miniprogram/pages/kaohe_jinpai/kaohe_jinpai.json @@ -0,0 +1,9 @@ +{ + "usingComponents": { + "chenghao-tag": "/components/chenghao-tag/chenghao-tag", + "global-notification": "/components/global-notification/global-notification" + }, + "navigationBarTitleText": "考核金牌", + "navigationBarBackgroundColor": "#0F0A1E", + "navigationBarTextStyle": "white" + } \ No newline at end of file diff --git a/miniprogram/pages/kaohe_jinpai/kaohe_jinpai.wxml b/miniprogram/pages/kaohe_jinpai/kaohe_jinpai.wxml new file mode 100644 index 0000000..6d89494 --- /dev/null +++ b/miniprogram/pages/kaohe_jinpai/kaohe_jinpai.wxml @@ -0,0 +1,135 @@ + + + + + 考核标签 + 我的考核 + + + + + + + {{item.mingcheng}} + + + + 金牌 + + + {{item.cishu}}次 ¥{{item.feiyong}} + ≥{{item.fee_list.length}}次 ¥{{item.fee_list[item.fee_list.length-1].feiyong}} + + 申请考核 + 已拥有 + + + + + + + + + 进行中/未通过 + 已通过 + + + + + {{item.chenghao_name}} + {{item.statusText}} + + + 板块:{{item.bankuai_name}} + 考核官:{{item.shenheguan_id || '待分配'}} + + 联系考核官 + + 游戏ID:{{item.dashou_youxi_id}} + 备注:{{item.dashou_beizhu}} + 第{{item.cishu}}次考核 · 共缴 ¥{{item.total_fee}} + + + + 本次考核费用:¥{{item.current_fee}} + 预计下次费用:¥{{item.next_fee}} + + + 上次拒绝原因:{{item.last_fail_reason}} + + + 再次考核 + + 加载中... + —— 没有更多了 —— + + + + + + + 申请考核 - {{selectedTag.name}} + + 游戏昵称 + + + + 备注 +