backup: 子客服改造前保本版本(逍遥梦UI+商家客服页mock)

This commit is contained in:
XingQue
2026-06-20 01:50:14 +08:00
parent 0767e23f11
commit a751708d6e
49 changed files with 8189 additions and 5268 deletions

215
app.json
View File

@@ -1,107 +1,110 @@
{
"pages": [
"pages/index/index",
"pages/category/category",
"pages/pick-user/pick-user",
"pages/messages/messages",
"pages/mine/mine",
"pages/product-detail/product-detail",
"pages/submit/submit",
"pages/edit/edit",
"pages/fighter/fighter",
"pages/merchant/merchant",
"pages/manager/manager",
"pages/orders/orders",
"pages/order-detail/order-detail",
"pages/fighter-rules/fighter-rules",
"pages/fighter-edit/fighter-edit",
"pages/fighter-rank/fighter-rank",
"pages/fighter-recharge/fighter-recharge",
"pages/fighter-msg/fighter-msg",
"pages/fighter-orders/fighter-orders",
"pages/accept-order/accept-order",
"pages/withdraw/withdraw",
"pages/invite-fighter/invite-fighter",
"pages/my-fighter/my-fighter",
"pages/recharge-log/recharge-log",
"pages/manager-rank/manager-rank",
"pages/merchant-dispatch/merchant-dispatch",
"pages/merchant-orders/merchant-orders",
"pages/merchant-msg/merchant-msg",
"pages/merchant-rank/merchant-rank",
"pages/merchant-recharge/merchant-recharge",
"pages/merchant-order-detail/merchant-order-detail",
"pages/fighter-order-detail/fighter-order-detail",
"pages/chat/chat",
"pages/express-order/express-order",
"pages/order-pool/order-pool",
"pages/poster/poster",
"pages/gold-fighter/gold-fighter",
"pages/leader/leader",
"pages/manager-assign/manager-assign",
"pages/leader-bonus-log/leader-bonus-log",
"pages/invite-manager/invite-manager",
"pages/order-pool2/order-pool2",
"pages/group-chat/group-chat",
"pages/cs-chat/cs-chat",
"pages/verify/verify",
"components/global-notification/global-notification",
"components/popup-notice/popup-notice",
"components/order-card/order-card",
"components/order-sender/order-sender",
"pages/penalty/penalty/penalty",
"pages/penalty/components/fakuan-list/fakuan-list",
"pages/penalty/components/jifen-list/jifen-list",
"pages/penalty/components/fakuan-pay/fakuan-pay",
"pages/phone-auth/phone-auth",
"components/chenghao-tag/chenghao-tag",
"pages/assessor/assessor",
"pages/assess-score/assess-score",
"pages/assess-log/assess-log",
"pages/assess-center/assess-center",
"pages/assess-gold/assess-gold",
"pages/escort-orders/escort-orders",
"pages/withdraw/components/mode1/mode1",
"pages/withdraw/components/mode2/mode2"
],
"usingComponents": {
"popup-notice": "/components/popup-notice/popup-notice",
"tab-bar": "/tab-bar/index"
},
"window": {
"navigationBarTextStyle": "black",
"navigationStyle": "default",
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "星阙网络"
},
"tabBar": {
"custom": true,
"list": [
{
"pagePath": "pages/order-pool/order-pool",
"text": "接单池",
"iconPath": "/images/order-pool.png",
"selectedIconPath": "/images/order-pool.png"
},
{
"pagePath": "pages/order-pool2/order-pool2",
"text": "接单池",
"iconPath": "/images/order-pool.png",
"selectedIconPath": "/images/order-pool.png"
}
]
},
"style": "v2",
"sitemapLocation": "sitemap.json",
"lazyCodeLoading": "requiredComponents"
{
"pages": [
"pages/index/index",
"pages/category/category",
"pages/pick-user/pick-user",
"pages/messages/messages",
"pages/mine/mine",
"pages/product-detail/product-detail",
"pages/submit/submit",
"pages/edit/edit",
"pages/fighter/fighter",
"pages/merchant/merchant",
"pages/merchant-home/merchant-home",
"pages/merchant-kefu-key/merchant-kefu-key",
"pages/merchant-kefu-list/merchant-kefu-list",
"pages/manager/manager",
"pages/orders/orders",
"pages/order-detail/order-detail",
"pages/fighter-rules/fighter-rules",
"pages/fighter-edit/fighter-edit",
"pages/fighter-rank/fighter-rank",
"pages/fighter-recharge/fighter-recharge",
"pages/fighter-msg/fighter-msg",
"pages/fighter-orders/fighter-orders",
"pages/accept-order/accept-order",
"pages/withdraw/withdraw",
"pages/invite-fighter/invite-fighter",
"pages/my-fighter/my-fighter",
"pages/recharge-log/recharge-log",
"pages/manager-rank/manager-rank",
"pages/merchant-dispatch/merchant-dispatch",
"pages/merchant-orders/merchant-orders",
"pages/merchant-msg/merchant-msg",
"pages/merchant-rank/merchant-rank",
"pages/merchant-recharge/merchant-recharge",
"pages/merchant-order-detail/merchant-order-detail",
"pages/fighter-order-detail/fighter-order-detail",
"pages/chat/chat",
"pages/express-order/express-order",
"pages/order-pool/order-pool",
"pages/poster/poster",
"pages/gold-fighter/gold-fighter",
"pages/leader/leader",
"pages/manager-assign/manager-assign",
"pages/leader-bonus-log/leader-bonus-log",
"pages/invite-manager/invite-manager",
"pages/order-pool2/order-pool2",
"pages/group-chat/group-chat",
"pages/cs-chat/cs-chat",
"pages/verify/verify",
"components/global-notification/global-notification",
"components/popup-notice/popup-notice",
"components/order-card/order-card",
"components/order-sender/order-sender",
"pages/penalty/penalty/penalty",
"pages/penalty/components/fakuan-list/fakuan-list",
"pages/penalty/components/jifen-list/jifen-list",
"pages/penalty/components/fakuan-pay/fakuan-pay",
"pages/phone-auth/phone-auth",
"components/chenghao-tag/chenghao-tag",
"pages/assessor/assessor",
"pages/assess-score/assess-score",
"pages/assess-log/assess-log",
"pages/assess-center/assess-center",
"pages/assess-gold/assess-gold",
"pages/escort-orders/escort-orders",
"pages/withdraw/components/mode1/mode1",
"pages/withdraw/components/mode2/mode2"
],
"usingComponents": {
"popup-notice": "/components/popup-notice/popup-notice",
"tab-bar": "/tab-bar/index"
},
"window": {
"navigationBarTextStyle": "black",
"navigationStyle": "default",
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "星阙网络"
},
"tabBar": {
"custom": true,
"list": [
{
"pagePath": "pages/order-pool/order-pool",
"text": "接单池",
"iconPath": "/images/order-pool.png",
"selectedIconPath": "/images/order-pool.png"
},
{
"pagePath": "pages/order-pool2/order-pool2",
"text": "接单池",
"iconPath": "/images/order-pool.png",
"selectedIconPath": "/images/order-pool.png"
}
]
},
"style": "v2",
"sitemapLocation": "sitemap.json",
"lazyCodeLoading": "requiredComponents"
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
{
"navigationBarTitleText": "抢单大厅",
"navigationBarBackgroundColor": "#0b0f1a",
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#f7dc51",
"navigationBarTextStyle": "black",
"enablePullDownRefresh": false,
"backgroundTextStyle": "dark",
"backgroundColor": "#0b0f1a",
"backgroundColor": "#fff8e1",
"usingComponents": {
"chenghao-tag": "/components/chenghao-tag/chenghao-tag",
"global-notification": "/components/global-notification/global-notification"

View File

@@ -1,220 +1,393 @@
<!-- pages/qiangdan/qiangdan.wxml -->
<view class="qiangdan-page">
<!-- 商品类型选择 -->
<view class="leixing-quyu">
<scroll-view class="leixing-scroll" scroll-x enhanced show-scrollbar="{{false}}">
<view class="leixing-container">
<block wx:for="{{shangpinleixing}}" wx:key="id">
<view
class="leixing-item {{xuanzhongLeixingId == item.id ? 'leixing-active' : ''}}"
data-id="{{item.id}}"
bindtap="selectLeixing"
>
<view wx:if="{{xuanzhongLeixingId == item.id}}" class="guangyun-effect"></view>
<image class="leixing-tupian" src="{{item.full_tupian_url}}" mode="aspectFill"/>
<text class="leixing-jieshao">{{item.jieshao}}</text>
</view>
</block>
</view>
</scroll-view>
</view>
<!-- 🆕 标签筛选区 -->
<view class="biaoqian-quyu" wx:if="{{bankuaiBiaoqian.length > 0}}">
<scroll-view class="biaoqian-scroll" scroll-x enhanced show-scrollbar="{{false}}">
<view class="biaoqian-container">
<view class="biaoqian-item {{xuanzhongBiaoqianId == 0 ? 'biaoqian-active' : ''}}" data-id="0" bindtap="selectBiaoqian">
<text class="quanbu-text">全部</text>
</view>
<block wx:for="{{bankuaiBiaoqian}}" wx:key="id">
<view class="biaoqian-item {{xuanzhongBiaoqianId == item.id ? 'biaoqian-active' : ''}}" data-id="{{item.id}}" bindtap="selectBiaoqian">
<chenghao-tag mingcheng="{{item.mingcheng}}" texiaoJson="{{item.texiao_json}}" />
</view>
</block>
</view>
</scroll-view>
</view>
<scroll-view
<view class="fenge-xian"></view>
class="page-main-scroll"
<!-- 订单列表 -->
<view class="dingdan-container">
<scroll-view
class="dingdan-scroll-view"
scroll-y enhanced show-scrollbar="{{false}}"
refresher-enabled="{{xuanzhongLeixingId != null}}"
refresher-threshold="80"
refresher-default-style="black"
refresher-background="#0b0f1a"
refresher-triggered="{{scrollViewRefreshing}}"
bindrefresherrefresh="onPullDownRefresh"
bindscrolltolower="onReachBottom"
>
<view class="refresher-container" slot="refresher">
<text wx:if="{{scrollViewRefreshing}}" class="refreshing-text">⚡️ 正在刷新...</text>
<text wx:else class="pull-down-text">▼ 下拉刷新订单</text>
</view>
scroll-y
<view class="dingdan-list">
<view wx:if="{{!xuanzhongLeixingId}}" class="empty-tip">
<image src="/images/icon_select.png" class="tip-icon"></image>
<text class="tip-text">请先选择上方订单类型</text>
</view>
<view wx:elif="{{dingdanList.length === 0 && !isLoading}}" class="empty-tip">
<image src="/images/icon_empty_order.png" class="tip-icon"></image>
<text class="tip-text">当前类型暂无待抢订单</text>
</view>
enhanced
<block wx:for="{{dingdanList}}" wx:key="dingdan_id">
<!-- 平台订单卡片 -->
<view wx:if="{{item.isPingtai}}" class="dingdan-card pingtai-card" data-item="{{item}}">
<view class="card-top">
<text class="creat-time">{{item.creat_time}}</text>
<view class="top-line"></view>
<text class="pingtai-tag">⚙️ 平台订单</text>
</view>
show-scrollbar="{{false}}"
<!-- 指定接单员行(新增标签滚动) -->
<view wx:if="{{item.isZhiding}}" class="zhiding-row">
<text class="zhiding-icon">指定</text>
<image wx:if="{{item.zhiding_avatar_full}}" class="zhiding-avatar" src="{{item.zhiding_avatar_full}}" mode="aspectFill"/>
<text class="zhiding-nicheng">{{item.zhiding_nicheng || '指定接单员'}}</text>
<text class="zhiding-uid">UID: {{item.zhiding_uid || '未知'}}</text>
<!-- 🆕 接单员标签 -->
<scroll-view wx:if="{{item.dashou_biaoqian.length > 0}}" class="biaoqian-inline-scroll" scroll-x>
<chenghao-tag wx:for="{{item.dashou_biaoqian}}" wx:for-item="tag" wx:key="id" mingcheng="{{tag.mingcheng}}" texiaoJson="{{tag.texiao_json}}" />
</scroll-view>
</view>
refresher-enabled="{{xuanzhongLeixingId != null}}"
<view class="card-content">
<image class="neirong-tupian" src="{{item.full_tupian_url}}" mode="aspectFill"/>
<view class="jieshao-box {{item.jieshao && item.jieshao.length > 60 ? 'jieshao-ellipsis' : ''}}" data-type="jieshao" data-content="{{item.jieshao}}" bindtap="onViewDetail">
<text class="jieshao-label">介绍:</text>
<text class="jieshao-text">{{item.jieshao || '暂无介绍'}}</text>
<text wx:if="{{item.jieshao && item.jieshao.length > 60}}" class="view-more">[点击查看]</text>
</view>
</view>
refresher-threshold="80"
<view wx:if="{{item.beizhu}}" class="beizhu-box {{item.beizhu.length > 40 ? 'beizhu-ellipsis' : ''}}" data-type="beizhu" data-content="{{item.beizhu}}" bindtap="onViewDetail">
<text class="beizhu-label">备注:</text>
<text class="beizhu-text">{{item.beizhu}}</text>
<text wx:if="{{item.beizhu.length > 40}}" class="view-more">[点击查看]</text>
</view>
refresher-default-style="black"
<!-- 🆕 订单需求标签 -->
<view wx:if="{{item.xuqiu_biaoqian.length > 0}}" class="xuqiu-biaoqian-area">
<text class="xuqiu-label">需求标签:</text>
<scroll-view class="xuqiu-biaoqian-scroll" scroll-x>
<chenghao-tag wx:for="{{item.xuqiu_biaoqian}}" wx:for-item="tag" wx:key="id" mingcheng="{{tag.mingcheng}}" texiaoJson="{{tag.texiao_json}}" />
</scroll-view>
</view>
refresher-background="#fff8e1"
<view class="card-bottom">
<view class="fenyong-box">
<text class="fenyong-icon">💰</text>
<text class="fenyong-text">分佣</text>
<!-- 🆕 根据是否有权限显示价格或提示 -->
<block wx:if="{{item.hasRequiredMember}}">
<text class="fenyong-price">{{item.dashou_fencheng || 0}}</text>
<text class="fenyong-unit">元</text>
</block>
<block wx:else>
<text class="fenyong-price" style="font-size: 28rpx; color: #ffaa88;">未开通会员</text>
</block>
</view>
<view class="qiangdan-btn mecha-btn pingtai-btn" data-item="{{item}}" bindtap="onQiangdanTap">
<text class="btn-text">⚡ 立即抢单</text>
<view class="btn-shine"></view>
<view class="btn-glow"></view>
<view class="mecha-overlay"></view>
</view>
</view>
</view>
refresher-triggered="{{scrollViewRefreshing}}"
<!-- 商家订单卡片 -->
<view wx:elif="{{item.isShangjia}}" class="dingdan-card shangjia-card" data-item="{{item}}">
<view class="card-top">
<text class="creat-time">{{item.creat_time}}</text>
<view class="top-line"></view>
<text class="pingtai-tag">🏪 商家发单</text>
</view>
bindrefresherrefresh="onPullDownRefresh"
<!-- 指定接单员行 -->
<view wx:if="{{item.isZhiding}}" class="zhiding-row">
<text class="zhiding-icon">指定</text>
<image wx:if="{{item.zhiding_avatar_full}}" class="zhiding-avatar" src="{{item.zhiding_avatar_full}}" mode="aspectFill"/>
<text class="zhiding-nicheng">{{item.zhiding_nicheng || '指定接单员'}}</text>
<text class="zhiding-uid">UID: {{item.zhiding_uid || '未知'}}</text>
<!-- 🆕 接单员标签 -->
<scroll-view wx:if="{{item.dashou_biaoqian.length > 0}}" class="biaoqian-inline-scroll" scroll-x>
<chenghao-tag wx:for="{{item.dashou_biaoqian}}" wx:for-item="tag" wx:key="id" mingcheng="{{tag.mingcheng}}" texiaoJson="{{tag.texiao_json}}" />
</scroll-view>
</view>
bindscrolltolower="onReachBottom"
<view class="shangjia-info">
<image class="shangjia-touxiang" src="{{item.full_tupian_url}}" mode="aspectFill"/>
<text class="shangjia-nicheng">{{item.sjnicheng || '未知商家'}}</text>
<!-- 🆕 商家标签 -->
<scroll-view wx:if="{{item.shangjia_biaoqian.length > 0}}" class="biaoqian-inline-scroll" scroll-x>
<chenghao-tag wx:for="{{item.shangjia_biaoqian}}" wx:for-item="tag" wx:key="id" mingcheng="{{tag.mingcheng}}" texiaoJson="{{tag.texiao_json}}" />
</scroll-view>
</view>
>
<view class="shangjia-jieshao {{item.jieshao && item.jieshao.length > 50 ? 'jieshao-ellipsis' : ''}}" data-type="jieshao" data-content="{{item.jieshao}}" bindtap="onViewDetail">
<text class="jieshao-label">订单介绍:</text>
<text class="jieshao-text">{{item.jieshao || '暂无介绍'}}</text>
<text wx:if="{{item.jieshao && item.jieshao.length > 50}}" class="view-more">[点击查看]</text>
</view>
<view class="refresher-container" slot="refresher">
<view wx:if="{{item.beizhu}}" class="shangjia-beizhu {{item.beizhu.length > 30 ? 'beizhu-ellipsis' : ''}}" data-type="beizhu" data-content="{{item.beizhu}}" bindtap="onViewDetail">
<text class="beizhu-label">商家备注:</text>
<text class="beizhu-text">{{item.beizhu}}</text>
<text wx:if="{{item.beizhu.length > 30}}" class="view-more">[点击查看]</text>
</view>
<text wx:if="{{scrollViewRefreshing}}" class="refreshing-text">正在刷新...</text>
<!-- 🆕 订单需求标签 -->
<view wx:if="{{item.xuqiu_biaoqian.length > 0}}" class="xuqiu-biaoqian-area">
<text class="xuqiu-label">需求标签:</text>
<scroll-view class="xuqiu-biaoqian-scroll" scroll-x>
<chenghao-tag wx:for="{{item.xuqiu_biaoqian}}" wx:for-item="tag" wx:key="id" mingcheng="{{tag.mingcheng}}" texiaoJson="{{tag.texiao_json}}" />
</scroll-view>
</view>
<text wx:else class="pull-down-text">下拉刷新订单</text>
<view class="card-bottom">
<view class="fenyong-box">
<text class="fenyong-icon">💰</text>
<text class="fenyong-text">分佣</text>
<!-- 🆕 根据是否有权限显示价格或提示 -->
<block wx:if="{{item.hasRequiredMember}}">
<text class="fenyong-price">{{item.dashou_fencheng || 0}}</text>
<text class="fenyong-unit">元</text>
</block>
<block wx:else>
<text class="fenyong-price" style="font-size: 28rpx; color: #ffaa88;">未开通会员</text>
</block>
</view>
<view class="qiangdan-btn mecha-btn shangjia-btn" data-item="{{item}}" bindtap="onQiangdanTap">
<text class="btn-text">⚡ 立即抢单</text>
<view class="btn-shine"></view>
<view class="btn-glow"></view>
<view class="mecha-overlay"></view>
</view>
</view>
</view>
</block>
<view wx:if="{{isLoadingMore && dingdanList.length > 0}}" class="loading-more"><text class="loading-text">⚙️ 加载更多订单中...</text></view>
<view wx:if="{{!hasMore && dingdanList.length > 0}}" class="no-more"><text class="no-more-text">—— 没有更多订单了 ——</text></view>
</view>
</scroll-view>
<view wx:if="{{isLoading && dingdanList.length === 0 && xuanzhongLeixingId}}" class="loading-mask">
<view class="loading-spinner"></view>
<text class="loading-mask-text">⚡ 订单加载中...</text>
</view>
<!-- 商品轮播(只读 globalData与点单端同源 -->
<view class="xym-lunbo-container" wx:if="{{lunboList.length > 0}}">
<swiper
class="xym-lunbo-swiper"
indicator-dots="{{lunboList.length > 1}}"
indicator-color="rgba(255,255,255,0.6)"
indicator-active-color="#ffd061"
autoplay="{{lunboList.length > 1}}"
interval="4000"
circular
>
<block wx:for="{{lunboList}}" wx:key="index">
<swiper-item>
<image class="xym-lunbo-image" src="{{item}}" mode="aspectFill"/>
</swiper-item>
</block>
</swiper>
</view>
<!-- 商品类型选择 -->
<view class="leixing-quyu">
<scroll-view class="leixing-scroll" scroll-x enhanced show-scrollbar="{{false}}">
<view class="leixing-container">
<block wx:for="{{shangpinleixing}}" wx:key="id">
<view
class="leixing-item {{xuanzhongLeixingId == item.id ? 'leixing-active' : ''}}"
data-id="{{item.id}}"
bindtap="selectLeixing"
>
<view wx:if="{{xuanzhongLeixingId == item.id}}" class="guangyun-effect"></view>
<image class="leixing-tupian" src="{{item.full_tupian_url}}" mode="aspectFill"/>
<text class="leixing-jieshao">{{item.jieshao}}</text>
</view>
</block>
</view>
</scroll-view>
</view>
<!-- 标签筛选区 -->
<view class="biaoqian-quyu" wx:if="{{bankuaiBiaoqian.length > 0}}">
<scroll-view class="biaoqian-scroll" scroll-x enhanced show-scrollbar="{{false}}">
<view class="biaoqian-container">
<view class="biaoqian-item {{xuanzhongBiaoqianId == 0 ? 'biaoqian-active' : ''}}" data-id="0" bindtap="selectBiaoqian">
<text class="quanbu-text">全部</text>
</view>
<block wx:for="{{bankuaiBiaoqian}}" wx:key="id">
<view class="biaoqian-item {{xuanzhongBiaoqianId == item.id ? 'biaoqian-active' : ''}}" data-id="{{item.id}}" bindtap="selectBiaoqian">
<chenghao-tag mingcheng="{{item.mingcheng}}" texiaoJson="{{item.texiao_json}}" />
</view>
</block>
</view>
</scroll-view>
</view>
<view class="fenge-xian"></view>
<!-- 订单列表 -->
<view class="dingdan-list">
<view wx:if="{{!xuanzhongLeixingId}}" class="empty-tip">
<image src="/images/icon_select.png" class="tip-icon"></image>
<text class="tip-text">请先选择上方订单类型</text>
</view>
<view wx:elif="{{dingdanList.length === 0 && !isLoading}}" class="empty-tip">
<image src="/images/icon_empty_order.png" class="tip-icon"></image>
<text class="tip-text">当前类型暂无待抢订单</text>
</view>
<block wx:for="{{dingdanList}}" wx:key="dingdan_id">
<!-- 平台订单(逍遥梦卡片布局) -->
<view wx:if="{{item.isPingtai}}" class="xym-order-item xym-pingtai-order" data-item="{{item}}">
<view class="xym-pingtai-head flexb">
<text class="xym-head-time">{{item.creat_time}}</text>
<view class="xym-head-tag">平台订单</view>
</view>
<view class="xym-pingtai-body">
<view class="order-con">
<view wx:if="{{item.isZhiding}}" class="zhiding-strip myflex light">
<text class="zhiding-label">指定</text>
<image wx:if="{{item.zhiding_avatar_full}}" class="zhiding-avatar" src="{{item.zhiding_avatar_full}}" mode="aspectFill"/>
<text class="zhiding-name">{{item.zhiding_nicheng || '指定接单员'}}</text>
</view>
<view class="order-row myflex">
<image class="o-logo" src="{{item.full_tupian_url}}" mode="aspectFill"/>
<view class="o-col">
<view class="o-goods light line2" data-type="jieshao" data-content="{{item.jieshao}}" bindtap="onViewDetail">{{item.jieshao || '暂无介绍'}}</view>
</view>
</view>
<view class="reward-badge platform-reward" wx:if="{{item.hasRequiredMember}}">
<text class="reward-yen sm">¥</text>
<text class="reward-num">{{item.dashou_fencheng || 0}}</text>
</view>
<view class="reward-badge member-tip" wx:else>
<text class="reward-tip">未开通会员</text>
</view>
<view wx:if="{{item.beizhu}}" class="remark-block gold" data-type="beizhu" data-content="{{item.beizhu}}" bindtap="onViewDetail">
<text class="remark-label">备注:</text>{{item.beizhu}}
</view>
<view wx:if="{{item.xuqiu_biaoqian.length > 0}}" class="xuqiu-tags-row">
<text class="xuqiu-label">需求标签</text>
<scroll-view class="biaoqian-inline-scroll" scroll-x>
<chenghao-tag wx:for="{{item.xuqiu_biaoqian}}" wx:for-item="tag" wx:key="id" mingcheng="{{tag.mingcheng}}" texiaoJson="{{tag.texiao_json}}" />
</scroll-view>
</view>
<view class="o-foot flexb">
<text class="o-amt light">平台派单</text>
<view class="qiangdan flexa btn-bg btn-qiang btn-qiang-brown" data-item="{{item}}" bindtap="onQiangdanTap">抢单</view>
</view>
</view>
</view>
</view>
<!-- 商家订单(逍遥梦卡片布局) -->
<view wx:elif="{{item.isShangjia}}" class="xym-order-item xym-shangjia-order" data-item="{{item}}">
<view class="xym-shangjia-head flexb">
<text class="xym-head-time">{{item.creat_time}}</text>
<view class="xym-head-tag">商家发单</view>
</view>
<view class="xym-shangjia-body">
<view class="order-con">
<view wx:if="{{item.isZhiding}}" class="zhiding-strip myflex">
<text class="zhiding-label">指定</text>
<image wx:if="{{item.zhiding_avatar_full}}" class="zhiding-avatar" src="{{item.zhiding_avatar_full}}" mode="aspectFill"/>
<text class="zhiding-name">{{item.zhiding_nicheng || '指定接单员'}}</text>
</view>
<view class="merchant-line myflex">
<image class="m-avatar-sm" src="{{item.full_tupian_url}}" mode="aspectFill"/>
<text class="m-name-sm">{{item.sjnicheng || '未知商家'}}</text>
</view>
<view class="order-row myflex">
<view class="o-col">
<view class="o-goods line2" data-type="jieshao" data-content="{{item.jieshao}}" bindtap="onViewDetail">{{item.jieshao || '暂无介绍'}}</view>
</view>
</view>
<view class="reward-badge normal-reward" wx:if="{{item.hasRequiredMember}}">
<text class="reward-yen sm">¥</text>
<text class="reward-num dark">{{item.dashou_fencheng || 0}}</text>
</view>
<view class="reward-badge member-tip" wx:else>
<text class="reward-tip">未开通会员</text>
</view>
<view wx:if="{{item.beizhu}}" class="remark-block dark" data-type="beizhu" data-content="{{item.beizhu}}" bindtap="onViewDetail">
<text class="remark-label">商家备注:</text>{{item.beizhu}}
</view>
<view wx:if="{{item.shangjia_biaoqian.length > 0 || item.xuqiu_biaoqian.length > 0}}" class="xuqiu-tags-row">
<scroll-view wx:if="{{item.shangjia_biaoqian.length > 0}}" class="biaoqian-inline-scroll" scroll-x>
<chenghao-tag wx:for="{{item.shangjia_biaoqian}}" wx:for-item="tag" wx:key="id" mingcheng="{{tag.mingcheng}}" texiaoJson="{{tag.texiao_json}}" />
</scroll-view>
<scroll-view wx:if="{{item.xuqiu_biaoqian.length > 0}}" class="biaoqian-inline-scroll" scroll-x style="margin-top:8rpx">
<chenghao-tag wx:for="{{item.xuqiu_biaoqian}}" wx:for-item="tag" wx:key="id" mingcheng="{{tag.mingcheng}}" texiaoJson="{{tag.texiao_json}}" />
</scroll-view>
</view>
<view class="o-foot flexb">
<text class="o-amt">商家派单</text>
<view class="qiangdan flexa btn-bg btn-qiang" data-item="{{item}}" bindtap="onQiangdanTap">抢单</view>
</view>
</view>
</view>
</view>
</block>
<view wx:if="{{isLoadingMore && dingdanList.length > 0}}" class="loading-more"><text class="loading-text">加载更多订单中...</text></view>
<view wx:if="{{!hasMore && dingdanList.length > 0}}" class="no-more"><text class="no-more-text">—— 没有更多订单了 ——</text></view>
</view>
<view class="scroll-bottom-spacer"></view>
</scroll-view>
<view wx:if="{{isLoading && dingdanList.length === 0 && xuanzhongLeixingId}}" class="loading-mask">
<view class="loading-spinner"></view>
<text class="loading-mask-text">订单加载中...</text>
</view>
<global-notification id="global-notification" />
<popup-notice id="popupNotice" />
<tab-bar />
</view>
</view>

View File

@@ -1,4 +1,5 @@
/* pages/qiangdan/qiangdan.wxss - 高级机甲风格重构版(对称优化) */
@import '../../styles/dashou-xym-theme.wxss';
.qiangdan-page {
height: 100vh;
display: flex;
@@ -120,20 +121,23 @@
opacity: 0.5;
}
/* ====== 3. 订单列表容器 ====== */
.dingdan-container {
/* ====== 3. 页面主滚动(下拉刷新在顶部) ====== */
.page-main-scroll {
flex: 1;
overflow: hidden;
position: relative;
z-index: 1;
padding: 0 20rpx; /* 统一左右内边距 */
}
.dingdan-scroll-view {
height: 100%;
height: 0;
-webkit-overflow-scrolling: touch;
}
.scroll-bottom-spacer {
height: 24rpx;
}
.dingdan-list {
padding: 0 20rpx;
position: relative;
z-index: 1;
}
.refresher-container {
height: 100rpx;
display: flex;
@@ -760,3 +764,4 @@
max-width: 50%;
}
@import '../../styles/dashou-xym-order-card.wxss';

View File

@@ -4,9 +4,9 @@
"chenghao-tag": "/components/chenghao-tag/chenghao-tag"
},
"backgroundTextStyle": "dark",
"navigationBarBackgroundColor": "#0a0a0f",
"navigationBarTitleText": "极速派单",
"navigationBarTextStyle": "white",
"backgroundColor": "#0a0a0f",
"navigationBarBackgroundColor": "#fff8e1",
"navigationBarTitleText": "常规发单",
"navigationBarTextStyle": "black",
"backgroundColor": "#f5f5f5",
"enablePullDownRefresh": false
}

View File

@@ -1,230 +1,230 @@
<!-- pages/express-order/express-order.wxml -->
<view class="page-container">
<!-- 余额卡片 -->
<view class="balance-card">
<text class="balance-label">可用余额</text>
<view class="balance-amount">
<text class="amount-value">{{sjyue}}</text>
<text class="amount-unit">元</text>
</view>
<text class="balance-tip">生成链接将从此余额扣除</text>
</view>
<!-- 商品类型选择 -->
<view class="section">
<text class="section-title">选择订单类型</text>
<scroll-view class="type-scroll" scroll-x="true" enable-flex>
<block wx:for="{{shangpinList}}" wx:key="id">
<view class="type-item {{selectedTypeId === item.id ? 'type-active' : ''}}"
data-id="{{item.id}}" data-item="{{item}}" bindtap="onSelectType">
<text class="type-text">{{item.jieshao}}</text>
</view>
</block>
</scroll-view>
</view>
<!-- 搜索区域 -->
<view class="search-section">
<view class="search-box">
<text class="search-icon">🔍</text>
<input class="search-input" placeholder="输入模板ID/介绍..." value="{{searchParams.keyword}}"
bindinput="onSearchKeywordInput" bindconfirm="onSearchConfirm"/>
<view class="search-btn" bindtap="onSearchConfirm">
<text class="search-btn-text">搜索</text>
</view>
</view>
<view class="filter-row">
<view class="filter-item">
<text class="filter-label">金额≥</text>
<input class="filter-input" type="digit" placeholder="元" value="{{searchParams.minPrice}}" bindinput="onSearchMinPriceInput"/>
</view>
<view class="filter-item">
<text class="filter-label">标签</text>
<picker mode="selector" range="{{currentTypeChenghaoList}}" range-key="mingcheng" bindchange="onSearchLabelChange">
<view class="picker-view">
<text>{{searchLabelName || '全部'}}</text>
</view>
</picker>
</view>
<view class="clear-search" bindtap="onClearSearch"><text>清空</text></view>
</view>
</view>
<!-- 模板卡片网格 -->
<view class="template-section">
<scroll-view class="template-scroll" scroll-y="true" scroll-with-animation="true" bindscrolltolower="onScrollToLower">
<view class="template-grid">
<block wx:for="{{templateList}}" wx:key="mobanId">
<view class="template-card" bindtap="onCardTap" data-item="{{item}}">
<view class="template-intro">
<text class="intro-text">{{item.jieshao || '无介绍'}}</text>
</view>
<view class="template-label" wx:if="{{item.labelName}}">
<chenghao-tag mingcheng="{{item.labelName}}" texiaoJson="{{''}}"/>
</view>
<view class="template-price-row">
<text class="template-price-label">价格:</text>
<text class="template-price-value">{{item.jiage || '0.00'}}元</text>
</view>
<view class="template-actions-grid">
<view class="action-grid-btn generate-grid-btn {{item.hasGenerated ? 'generated' : ''}}"
data-id="{{item.mobanId}}" catchtap="onGenerateLink">
{{item.hasGenerated ? '获取新链接' : '生成链接'}}
</view>
<view class="action-grid-btn copy-grid-btn {{item.isCopied ? 'copied' : ''}}"
data-id="{{item.mobanId}}" catchtap="onCopyLink">
{{item.isCopied ? '已复制' : '一键复制'}}
</view>
</view>
</view>
</block>
<view class="template-card add-card" bindtap="showAddModal">
<view class="add-icon"></view>
<text class="add-text">添加模板</text>
<text class="add-subtext">点击创建新模板</text>
</view>
</view>
<view class="load-more" wx:if="{{isLoadingMore}}">...</view>
<view class="no-more" wx:if="{{!hasMoreData && templateList.length > 0}}">没有更多模板了</view>
<view class="empty-state" wx:if="{{templateList.length === 0 && !isLoading}}">暂无模板</view>
</scroll-view>
</view>
</view>
<!-- 详情弹窗 -->
<view class="modal-overlay" wx:if="{{showDetailModal}}" bindtap="hideDetailModal">
<view class="modal-content detail-modal" catchtap="stopPropagation">
<view class="modal-close" bindtap="hideDetailModal">×</view>
<view class="modal-header"><text class="modal-title">模板详情</text></view>
<view class="detail-info" wx:if="{{currentTemplate}}">
<view class="detail-item">
<text class="detail-label">订单介绍</text>
<view class="detail-value intro-value"><text>{{currentTemplate.jieshao || '无介绍'}}</text></view>
</view>
<view class="detail-item" wx:if="{{currentTemplate.labelName}}">
<text class="detail-label">关联标签</text>
<chenghao-tag mingcheng="{{currentTemplate.labelName}}" texiaoJson="{{currentTemplate.texiaoJson}}"/>
</view>
<view class="detail-meta-row">
<view class="meta-item"><text class="meta-label">价格</text><text class="meta-value price-meta">{{currentTemplate.jiage || '0.00'}}元</text></view>
<view class="meta-divider">|</view>
<view class="meta-item"><text class="meta-label">发布数量</text><text class="meta-value count-meta">{{currentTemplate.fabushuliang || 0}}次</text></view>
<view class="meta-divider">|</view>
<view class="meta-item"><text class="meta-label">模板ID</text><text class="meta-value id-meta">{{currentTemplate.mobanId || 'N/A'}}</text></view>
</view>
<view class="detail-item" wx:if="{{currentTemplate.commissionEnabled}}">
<text class="detail-label">佣金要求</text>
<text class="detail-value">{{currentTemplate.commissionValue}}元建议≤50</text>
</view>
<!-- 链接筛选 -->
<view class="link-filter-bar">
<text class="filter-label">链接状态:</text>
<view class="filter-switch {{detailLinkFilter === 0 ? 'active' : ''}}" bindtap="onToggleLinkFilter">未使用</view>
<view class="filter-switch {{detailLinkFilter === 1 ? 'active' : ''}}" bindtap="onToggleLinkFilter">已使用</view>
</view>
<scroll-view class="link-list" scroll-y="true" style="max-height: 300rpx;">
<block wx:for="{{detailLinkList}}" wx:key="id">
<view class="link-item">
<text class="link-url" selectable="true">{{item.lianjie}}</text>
<text class="link-status">{{item.is_used ? '已使用' : '未使用'}}</text>
<view wx:if="{{!item.is_used}}" class="copy-link-btn" bindtap="onCopyLinkItem" data-url="{{item.lianjie}}">复制</view>
</view>
</block>
<view class="load-more-links" wx:if="{{detailLinkHasMore}}">
<view class="load-more-btn" bindtap="onLoadMoreLinks">获取更多链接</view>
</view>
<view wx:if="{{isLoadingLinks}}" class="link-loading">加载中...</view>
<view wx:if="{{detailLinkList.length === 0 && !isLoadingLinks}}" class="link-empty">暂无链接</view>
</scroll-view>
</view>
<view class="modal-actions-grid">
<view class="modal-grid-btn generate-modal-grid-btn" bindtap="onGenerateLinkModal">{{currentTemplate.hasGenerated ? '获取新链接' : '生成链接'}}</view>
<view class="modal-grid-btn copy-modal-grid-btn {{currentTemplate.isCopied ? 'copied' : ''}}" bindtap="onCopyLinkModal">{{currentTemplate.isCopied ? '已复制' : '复制链接'}}</view>
<view class="modal-grid-btn edit-modal-grid-btn" bindtap="onEditTemplate">{{isEditing ? '保存修改' : '立即修改'}}</view>
<view class="modal-grid-btn delete-modal-grid-btn" bindtap="onDeleteTemplate">删除模板</view>
</view>
<!-- 编辑区 -->
<view class="edit-section" wx:if="{{isEditing}}">
<view class="edit-item">
<text class="edit-label">订单介绍</text>
<textarea class="edit-input intro-edit" value="{{editJieshao}}" maxlength="100" placeholder="请输入订单介绍100字以内" bindinput="onEditJieshaoInput" auto-height/>
<text class="word-count">{{editJieshao.length}}/100</text>
</view>
<view class="edit-item">
<text class="edit-label">价格(元)</text>
<input class="edit-input price-edit" type="digit" value="{{editJiage}}" placeholder="0.1 - 10000" bindinput="onEditJiageInput"/>
</view>
<view class="edit-item">
<text class="edit-label">标签</text>
<picker mode="selector" range="{{currentTypeChenghaoList}}" range-key="mingcheng" bindchange="onEditLabelChange">
<view class="picker-view"><text>{{editLabelName || '无'}}</text></view>
</picker>
</view>
<view class="edit-item commission-item">
<text class="edit-label">佣金要求建议≤50</text>
<switch checked="{{editCommissionEnabled}}" bindchange="onEditCommissionToggle"/>
<input wx:if="{{editCommissionEnabled}}" class="commission-input" type="digit" placeholder="佣金金额" value="{{editCommissionValue}}" bindinput="onEditCommissionValueInput"/>
</view>
</view>
</view>
</view>
<!-- 添加模板弹窗 -->
<view class="modal-overlay" wx:if="{{showAddModal}}" bindtap="hideAddModal">
<view class="modal-content add-modal" catchtap="stopPropagation">
<view class="modal-close" bindtap="hideAddModal">×</view>
<view class="modal-header"><text class="modal-title">添加模板</text></view>
<view class="add-form">
<view class="form-item">
<text class="form-label">订单介绍</text>
<textarea class="form-input intro-input" value="{{addJieshao}}" maxlength="100" placeholder="请输入订单介绍(必填)" bindinput="onAddJieshaoInput" auto-height/>
<text class="word-count">{{addJieshao.length}}/100</text>
</view>
<view class="form-item">
<text class="form-label">价格(元)</text>
<input class="form-input price-input" type="digit" value="{{addJiage}}" placeholder="0.1 - 10000" bindinput="onAddJiageInput"/>
</view>
<view class="form-item">
<text class="form-label">标签</text>
<picker mode="selector" range="{{currentTypeChenghaoList}}" range-key="mingcheng" bindchange="onAddLabelChange">
<view class="picker-view"><text>{{addLabelName || '可选'}}</text></view>
</picker>
</view>
<view class="form-item commission-item">
<text class="form-label">佣金要求建议≤50</text>
<switch checked="{{addCommissionEnabled}}" bindchange="onAddCommissionToggle"/>
<input wx:if="{{addCommissionEnabled}}" class="commission-input" type="digit" placeholder="佣金金额" value="{{addCommissionValue}}" bindinput="onAddCommissionValueInput"/>
</view>
</view>
<view class="modal-actions-grid add-actions-grid">
<view class="modal-grid-btn cancel-grid-btn" bindtap="hideAddModal">取消</view>
<view class="modal-grid-btn confirm-add-grid-btn" bindtap="onAddTemplate">确认添加</view>
</view>
</view>
</view>
<!-- 删除确认弹窗 -->
<view class="modal-overlay confirm-overlay" wx:if="{{showDeleteConfirm}}" bindtap="hideDeleteConfirm">
<view class="confirm-content" catchtap="stopPropagation">
<text class="confirm-title">确认删除</text>
<text class="confirm-text">确定要删除这个模板吗?此操作不可恢复。</text>
<view class="confirm-actions-grid">
<view class="confirm-grid-btn cancel-confirm-grid-btn" bindtap="hideDeleteConfirm">取消</view>
<view class="confirm-grid-btn delete-confirm-grid-btn" bindtap="confirmDeleteTemplate">确定删除</view>
</view>
</view>
</view>
<!-- 获取新链接确认弹窗 -->
<view class="modal-overlay confirm-overlay" wx:if="{{showNewLinkConfirm}}" bindtap="hideNewLinkConfirm">
<view class="confirm-content" catchtap="stopPropagation">
<text class="confirm-title">获取新链接</text>
<text class="confirm-text">{{currentTemplate.isCopied ? '确定要获取新链接吗?旧链接将失效。' : '您还没有复制当前链接,确定要获取新链接吗?'}}</text>
<view class="confirm-actions-grid">
<view class="confirm-grid-btn cancel-confirm-grid-btn" bindtap="hideNewLinkConfirm">取消</view>
<view class="confirm-grid-btn confirm-new-link-grid-btn" bindtap="confirmNewLink">确定</view>
</view>
</view>
</view>
<!-- pages/express-order/express-order.wxml -->
<view class="page-container sj-form-theme">
<!-- 余额卡片 -->
<view class="balance-card">
<text class="balance-label">可用余额</text>
<view class="balance-amount">
<text class="amount-value">{{sjyue}}</text>
<text class="amount-unit">元</text>
</view>
<text class="balance-tip">生成链接将从此余额扣除</text>
</view>
<!-- 商品类型选择 -->
<view class="section">
<text class="section-title">选择订单类型</text>
<scroll-view class="type-scroll" scroll-x="true" enable-flex>
<block wx:for="{{shangpinList}}" wx:key="id">
<view class="type-item {{selectedTypeId === item.id ? 'type-active' : ''}}"
data-id="{{item.id}}" data-item="{{item}}" bindtap="onSelectType">
<text class="type-text">{{item.jieshao}}</text>
</view>
</block>
</scroll-view>
</view>
<!-- 搜索区域 -->
<view class="search-section">
<view class="search-box">
<text class="search-icon">🔍</text>
<input class="search-input" placeholder="输入模板ID/介绍..." value="{{searchParams.keyword}}"
bindinput="onSearchKeywordInput" bindconfirm="onSearchConfirm"/>
<view class="search-btn" bindtap="onSearchConfirm">
<text class="search-btn-text">搜索</text>
</view>
</view>
<view class="filter-row">
<view class="filter-item">
<text class="filter-label">金额≥</text>
<input class="filter-input" type="digit" placeholder="元" value="{{searchParams.minPrice}}" bindinput="onSearchMinPriceInput"/>
</view>
<view class="filter-item">
<text class="filter-label">标签</text>
<picker mode="selector" range="{{currentTypeChenghaoList}}" range-key="mingcheng" bindchange="onSearchLabelChange">
<view class="picker-view">
<text>{{searchLabelName || '全部'}}</text>
</view>
</picker>
</view>
<view class="clear-search" bindtap="onClearSearch"><text>清空</text></view>
</view>
</view>
<!-- 模板卡片网格 -->
<view class="template-section">
<scroll-view class="template-scroll" scroll-y="true" scroll-with-animation="true" bindscrolltolower="onScrollToLower">
<view class="template-grid">
<block wx:for="{{templateList}}" wx:key="mobanId">
<view class="template-card" bindtap="onCardTap" data-item="{{item}}">
<view class="template-intro">
<text class="intro-text">{{item.jieshao || '无介绍'}}</text>
</view>
<view class="template-label" wx:if="{{item.labelName}}">
<chenghao-tag mingcheng="{{item.labelName}}" texiaoJson="{{''}}"/>
</view>
<view class="template-price-row">
<text class="template-price-label">价格:</text>
<text class="template-price-value">{{item.jiage || '0.00'}}元</text>
</view>
<view class="template-actions-grid">
<view class="action-grid-btn generate-grid-btn {{item.hasGenerated ? 'generated' : ''}}"
data-id="{{item.mobanId}}" catchtap="onGenerateLink">
{{item.hasGenerated ? '获取新链接' : '生成链接'}}
</view>
<view class="action-grid-btn copy-grid-btn {{item.isCopied ? 'copied' : ''}}"
data-id="{{item.mobanId}}" catchtap="onCopyLink">
{{item.isCopied ? '已复制' : '一键复制'}}
</view>
</view>
</view>
</block>
<view class="template-card add-card" bindtap="showAddModal">
<view class="add-icon"></view>
<text class="add-text">添加模板</text>
<text class="add-subtext">点击创建新模板</text>
</view>
</view>
<view class="load-more" wx:if="{{isLoadingMore}}">...</view>
<view class="no-more" wx:if="{{!hasMoreData && templateList.length > 0}}">没有更多模板了</view>
<view class="empty-state" wx:if="{{templateList.length === 0 && !isLoading}}">暂无模板</view>
</scroll-view>
</view>
</view>
<!-- 详情弹窗 -->
<view class="modal-overlay" wx:if="{{showDetailModal}}" bindtap="hideDetailModal">
<view class="modal-content detail-modal" catchtap="stopPropagation">
<view class="modal-close" bindtap="hideDetailModal">×</view>
<view class="modal-header"><text class="modal-title">模板详情</text></view>
<view class="detail-info" wx:if="{{currentTemplate}}">
<view class="detail-item">
<text class="detail-label">订单介绍</text>
<view class="detail-value intro-value"><text>{{currentTemplate.jieshao || '无介绍'}}</text></view>
</view>
<view class="detail-item" wx:if="{{currentTemplate.labelName}}">
<text class="detail-label">关联标签</text>
<chenghao-tag mingcheng="{{currentTemplate.labelName}}" texiaoJson="{{currentTemplate.texiaoJson}}"/>
</view>
<view class="detail-meta-row">
<view class="meta-item"><text class="meta-label">价格</text><text class="meta-value price-meta">{{currentTemplate.jiage || '0.00'}}元</text></view>
<view class="meta-divider">|</view>
<view class="meta-item"><text class="meta-label">发布数量</text><text class="meta-value count-meta">{{currentTemplate.fabushuliang || 0}}次</text></view>
<view class="meta-divider">|</view>
<view class="meta-item"><text class="meta-label">模板ID</text><text class="meta-value id-meta">{{currentTemplate.mobanId || 'N/A'}}</text></view>
</view>
<view class="detail-item" wx:if="{{currentTemplate.commissionEnabled}}">
<text class="detail-label">佣金要求</text>
<text class="detail-value">{{currentTemplate.commissionValue}}元建议≤50</text>
</view>
<!-- 链接筛选 -->
<view class="link-filter-bar">
<text class="filter-label">链接状态:</text>
<view class="filter-switch {{detailLinkFilter === 0 ? 'active' : ''}}" bindtap="onToggleLinkFilter">未使用</view>
<view class="filter-switch {{detailLinkFilter === 1 ? 'active' : ''}}" bindtap="onToggleLinkFilter">已使用</view>
</view>
<scroll-view class="link-list" scroll-y="true" style="max-height: 300rpx;">
<block wx:for="{{detailLinkList}}" wx:key="id">
<view class="link-item">
<text class="link-url" selectable="true">{{item.lianjie}}</text>
<text class="link-status">{{item.is_used ? '已使用' : '未使用'}}</text>
<view wx:if="{{!item.is_used}}" class="copy-link-btn" bindtap="onCopyLinkItem" data-url="{{item.lianjie}}">复制</view>
</view>
</block>
<view class="load-more-links" wx:if="{{detailLinkHasMore}}">
<view class="load-more-btn" bindtap="onLoadMoreLinks">获取更多链接</view>
</view>
<view wx:if="{{isLoadingLinks}}" class="link-loading">加载中...</view>
<view wx:if="{{detailLinkList.length === 0 && !isLoadingLinks}}" class="link-empty">暂无链接</view>
</scroll-view>
</view>
<view class="modal-actions-grid">
<view class="modal-grid-btn generate-modal-grid-btn" bindtap="onGenerateLinkModal">{{currentTemplate.hasGenerated ? '获取新链接' : '生成链接'}}</view>
<view class="modal-grid-btn copy-modal-grid-btn {{currentTemplate.isCopied ? 'copied' : ''}}" bindtap="onCopyLinkModal">{{currentTemplate.isCopied ? '已复制' : '复制链接'}}</view>
<view class="modal-grid-btn edit-modal-grid-btn" bindtap="onEditTemplate">{{isEditing ? '保存修改' : '立即修改'}}</view>
<view class="modal-grid-btn delete-modal-grid-btn" bindtap="onDeleteTemplate">删除模板</view>
</view>
<!-- 编辑区 -->
<view class="edit-section" wx:if="{{isEditing}}">
<view class="edit-item">
<text class="edit-label">订单介绍</text>
<textarea class="edit-input intro-edit" value="{{editJieshao}}" maxlength="100" placeholder="请输入订单介绍100字以内" bindinput="onEditJieshaoInput" auto-height/>
<text class="word-count">{{editJieshao.length}}/100</text>
</view>
<view class="edit-item">
<text class="edit-label">价格(元)</text>
<input class="edit-input price-edit" type="digit" value="{{editJiage}}" placeholder="0.1 - 10000" bindinput="onEditJiageInput"/>
</view>
<view class="edit-item">
<text class="edit-label">标签</text>
<picker mode="selector" range="{{currentTypeChenghaoList}}" range-key="mingcheng" bindchange="onEditLabelChange">
<view class="picker-view"><text>{{editLabelName || '无'}}</text></view>
</picker>
</view>
<view class="edit-item commission-item">
<text class="edit-label">佣金要求建议≤50</text>
<switch checked="{{editCommissionEnabled}}" bindchange="onEditCommissionToggle"/>
<input wx:if="{{editCommissionEnabled}}" class="commission-input" type="digit" placeholder="佣金金额" value="{{editCommissionValue}}" bindinput="onEditCommissionValueInput"/>
</view>
</view>
</view>
</view>
<!-- 添加模板弹窗 -->
<view class="modal-overlay" wx:if="{{showAddModal}}" bindtap="hideAddModal">
<view class="modal-content add-modal" catchtap="stopPropagation">
<view class="modal-close" bindtap="hideAddModal">×</view>
<view class="modal-header"><text class="modal-title">添加模板</text></view>
<view class="add-form">
<view class="form-item">
<text class="form-label">订单介绍</text>
<textarea class="form-input intro-input" value="{{addJieshao}}" maxlength="100" placeholder="请输入订单介绍(必填)" bindinput="onAddJieshaoInput" auto-height/>
<text class="word-count">{{addJieshao.length}}/100</text>
</view>
<view class="form-item">
<text class="form-label">价格(元)</text>
<input class="form-input price-input" type="digit" value="{{addJiage}}" placeholder="0.1 - 10000" bindinput="onAddJiageInput"/>
</view>
<view class="form-item">
<text class="form-label">标签</text>
<picker mode="selector" range="{{currentTypeChenghaoList}}" range-key="mingcheng" bindchange="onAddLabelChange">
<view class="picker-view"><text>{{addLabelName || '可选'}}</text></view>
</picker>
</view>
<view class="form-item commission-item">
<text class="form-label">佣金要求建议≤50</text>
<switch checked="{{addCommissionEnabled}}" bindchange="onAddCommissionToggle"/>
<input wx:if="{{addCommissionEnabled}}" class="commission-input" type="digit" placeholder="佣金金额" value="{{addCommissionValue}}" bindinput="onAddCommissionValueInput"/>
</view>
</view>
<view class="modal-actions-grid add-actions-grid">
<view class="modal-grid-btn cancel-grid-btn" bindtap="hideAddModal">取消</view>
<view class="modal-grid-btn confirm-add-grid-btn" bindtap="onAddTemplate">确认添加</view>
</view>
</view>
</view>
<!-- 删除确认弹窗 -->
<view class="modal-overlay confirm-overlay" wx:if="{{showDeleteConfirm}}" bindtap="hideDeleteConfirm">
<view class="confirm-content" catchtap="stopPropagation">
<text class="confirm-title">确认删除</text>
<text class="confirm-text">确定要删除这个模板吗?此操作不可恢复。</text>
<view class="confirm-actions-grid">
<view class="confirm-grid-btn cancel-confirm-grid-btn" bindtap="hideDeleteConfirm">取消</view>
<view class="confirm-grid-btn delete-confirm-grid-btn" bindtap="confirmDeleteTemplate">确定删除</view>
</view>
</view>
</view>
<!-- 获取新链接确认弹窗 -->
<view class="modal-overlay confirm-overlay" wx:if="{{showNewLinkConfirm}}" bindtap="hideNewLinkConfirm">
<view class="confirm-content" catchtap="stopPropagation">
<text class="confirm-title">获取新链接</text>
<text class="confirm-text">{{currentTemplate.isCopied ? '确定要获取新链接吗?旧链接将失效。' : '您还没有复制当前链接,确定要获取新链接吗?'}}</text>
<view class="confirm-actions-grid">
<view class="confirm-grid-btn cancel-confirm-grid-btn" bindtap="hideNewLinkConfirm">取消</view>
<view class="confirm-grid-btn confirm-new-link-grid-btn" bindtap="confirmNewLink">确定</view>
</view>
</view>
</view>
<global-notification id="global-notification" />

View File

@@ -1,222 +1,586 @@
/* pages/express-order/express-order.wxss - 增强版,包含标签展示 */
.page-container {
min-height: 100vh;
background: linear-gradient(135deg, #0a0a0f 0%, #1a1a2e 50%, #16213e 100%);
padding: 30rpx;
box-sizing: border-box;
padding-bottom: 40rpx;
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif;
}
.balance-card {
background: linear-gradient(135deg, rgba(20,20,30,0.9), rgba(30,30,50,0.9));
border-radius: 24rpx;
padding: 36rpx;
margin-bottom: 40rpx;
color: #fff;
box-shadow: 0 15rpx 35rpx rgba(0,0,0,0.4), 0 0 40rpx rgba(0,150,255,0.15);
text-align: center;
border: 1.5rpx solid rgba(0,180,255,0.2);
backdrop-filter: blur(10rpx);
position: relative;
overflow: hidden;
}
.balance-card::before {
content: '';
position: absolute;
top: -50%; left: -50%;
width: 200%; height: 200%;
background: linear-gradient(45deg, transparent 30%, rgba(0,180,255,0.1) 50%, transparent 70%);
animation: cardShine 6s infinite linear;
z-index: 1;
}
@keyframes cardShine {
0% { transform: translateX(-100%) translateY(-100%) rotate(45deg); }
100% { transform: translateX(100%) translateY(100%) rotate(45deg); }
}
.balance-label { font-size: 28rpx; color: rgba(255,255,255,0.8); margin-bottom: 18rpx; font-weight: 500; position: relative; z-index: 2; }
.balance-amount { display: flex; align-items: baseline; justify-content: center; margin-bottom: 15rpx; position: relative; z-index: 2; }
.amount-value { font-size: 64rpx; font-weight: bold; color: #00B4FF; text-shadow: 0 0 20rpx rgba(0,180,255,0.7), 0 0 40rpx rgba(0,180,255,0.4); animation: amountGlow 3s infinite alternate; }
@keyframes amountGlow {
0% { color: #00B4FF; text-shadow: 0 0 15rpx rgba(0,180,255,0.6); }
100% { color: #00E0FF; text-shadow: 0 0 25rpx rgba(0,180,255,0.8), 0 0 50rpx rgba(0,180,255,0.5); }
}
.amount-unit { font-size: 36rpx; color: #00B4FF; margin-left: 12rpx; font-weight: 500; z-index: 2; }
.balance-tip { font-size: 24rpx; color: rgba(255,255,255,0.6); z-index: 2; }
.section { margin-bottom: 35rpx; }
.section-title { font-size: 32rpx; font-weight: 700; color: #FFFFFF; margin-bottom: 25rpx; padding-left: 12rpx; border-left: 6rpx solid #9C27B0; text-shadow: 0 2rpx 4rpx rgba(0,0,0,0.3); }
.type-scroll { white-space: nowrap; display: flex; height: 90rpx; }
.type-item {
display: inline-flex; flex-shrink: 0; align-items: center; justify-content: center;
height: 85rpx; padding: 0 40rpx; margin-right: 20rpx;
background: rgba(255,255,255,0.08); border-radius: 45rpx; border: 2rpx solid rgba(255,255,255,0.15);
font-size: 28rpx; color: rgba(255,255,255,0.8);
transition: all 0.3s cubic-bezier(0.175,0.885,0.32,1.275);
backdrop-filter: blur(10rpx);
}
.type-active {
background: linear-gradient(135deg, #9C27B0 0%, #673AB7 100%);
border-color: #9C27B0; color: white; transform: scale(1.05);
box-shadow: 0 10rpx 25rpx rgba(156,39,176,0.4), 0 0 30rpx rgba(156,39,176,0.3);
}
.type-text { max-width: 220rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
/* 搜索区域 */
.search-section { margin-bottom: 35rpx; }
.search-box {
display: flex; align-items: center;
background: rgba(255,255,255,0.1); border-radius: 50rpx;
padding: 20rpx 30rpx; border: 2rpx solid rgba(255,255,255,0.2);
backdrop-filter: blur(10rpx); transition: all 0.3s ease;
}
.search-box:focus-within { border-color: #9C27B0; background: rgba(255,255,255,0.15); box-shadow: 0 0 25rpx rgba(156,39,176,0.3); }
.search-icon { font-size: 32rpx; color: rgba(255,255,255,0.7); margin-right: 20rpx; flex-shrink: 0; }
.search-input { flex: 1; font-size: 28rpx; color: #FFFFFF; background: transparent; border: none; outline: none; min-height: 40rpx; }
.search-input::placeholder { color: rgba(255,255,255,0.4); }
.search-btn { background: linear-gradient(135deg, #9C27B0 0%, #673AB7 100%); border-radius: 40rpx; padding: 15rpx 30rpx; margin-left: 20rpx; flex-shrink: 0; box-shadow: 0 8rpx 20rpx rgba(156,39,176,0.3); }
.search-btn:active { transform: scale(0.95); }
.search-btn-text { font-size: 26rpx; color: white; font-weight: 600; }
.filter-row { display: flex; align-items: center; margin-top: 20rpx; gap: 15rpx; }
.filter-item { display: flex; align-items: center; background: rgba(255,255,255,0.08); border-radius: 30rpx; padding: 10rpx 20rpx; border: 1rpx solid rgba(255,255,255,0.15); }
.filter-label { font-size: 24rpx; color: rgba(255,255,255,0.7); margin-right: 10rpx; }
.filter-input { width: 120rpx; height: 50rpx; background: transparent; color: #fff; font-size: 26rpx; }
.picker-view { padding: 10rpx 0; color: rgba(255,255,255,0.9); font-size: 26rpx; max-width: 160rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.clear-search { margin-left: auto; padding: 10rpx 20rpx; background: rgba(255,255,255,0.1); border-radius: 20rpx; color: rgba(255,255,255,0.7); font-size: 24rpx; }
/* 模板区域 */
.template-section { height: calc(100vh - 600rpx); position: relative; }
.template-scroll { height: 100%; }
.template-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 25rpx; padding-bottom: 30rpx; }
.template-card {
background: linear-gradient(145deg, rgba(30,30,45,0.9), rgba(40,40,60,0.9));
border-radius: 20rpx; padding: 25rpx;
border: 1.5rpx solid rgba(255,255,255,0.1);
box-shadow: 0 10rpx 30rpx rgba(0,0,0,0.3), 0 0 25rpx rgba(0,180,255,0.1);
transition: all 0.3s ease; backdrop-filter: blur(10rpx);
display: flex; flex-direction: column; min-height: 280rpx; position: relative; overflow: hidden;
}
.template-card::before { content: ''; position: absolute; top:0; left:0; right:0; height:4rpx; background: linear-gradient(90deg, #9C27B0, #00B4FF, #9C27B0); opacity:0.6; }
.template-intro { flex:1; margin-bottom:10rpx; min-height:70rpx; overflow:hidden; }
.intro-text { font-size:24rpx; line-height:1.4; color:rgba(255,255,255,0.9); display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; overflow:hidden; font-weight:500; }
.template-label { margin-bottom: 10rpx; }
.template-price-row { display:flex; align-items:center; margin-bottom:20rpx; padding:10rpx 0; border-bottom:1rpx solid rgba(255,255,255,0.1); }
.template-price-label { font-size:22rpx; color:rgba(255,255,255,0.7); margin-right:10rpx; }
.template-price-value { font-size:26rpx; font-weight:bold; color:#FFD700; text-shadow:0 0 10rpx rgba(255,215,0,0.3); flex:1; }
.template-actions-grid { display:flex; flex-direction:column; gap:12rpx; margin-top:10rpx; }
.action-grid-btn {
height:65rpx; border-radius:32rpx; font-size:24rpx; font-weight:600; transition:all 0.3s ease;
border:none; padding:0 20rpx; box-shadow:0 4rpx 12rpx rgba(0,0,0,0.2), inset 0 1rpx 0 rgba(255,255,255,0.1);
display:flex !important; align-items:center !important; justify-content:center !important; text-align:center !important;
}
.generate-grid-btn { background:linear-gradient(135deg, #00B4FF, #0091EA); color:white; }
.generate-grid-btn.generated { background:linear-gradient(135deg, #4CAF50, #2E7D32); }
.copy-grid-btn { background:linear-gradient(135deg, #9C27B0, #673AB7); color:white; }
.copy-grid-btn.copied { background:linear-gradient(135deg, #FF9800, #F57C00); }
.add-card { background: linear-gradient(145deg, rgba(40,40,60,0.7), rgba(60,60,80,0.7)); border:2rpx dashed rgba(255,255,255,0.3); display:flex; flex-direction:column; align-items:center; justify-content:center; min-height:280rpx; }
.add-icon { font-size:60rpx; color:rgba(255,255,255,0.6); margin-bottom:20rpx; }
.add-text { font-size:30rpx; color:rgba(255,255,255,0.8); font-weight:600; margin-bottom:8rpx; }
.add-subtext { font-size:24rpx; color:rgba(255,255,255,0.5); }
/* 弹窗通用 */
.modal-overlay { position:fixed; top:0; left:0; right:0; bottom:0; background:rgba(0,0,0,0.75); display:flex; align-items:center; justify-content:center; z-index:9999; padding:30rpx; backdrop-filter:blur(10rpx); animation:fadeIn 0.3s ease; }
@keyframes fadeIn { from{opacity:0;} to{opacity:1;} }
.modal-content {
background:linear-gradient(145deg, rgba(30,30,45,0.95), rgba(40,40,60,0.95));
border-radius:30rpx; width:100%; max-width:700rpx; max-height:85vh; overflow-y:auto;
border:1.5rpx solid rgba(255,255,255,0.15);
box-shadow:0 25rpx 80rpx rgba(0,0,0,0.6), 0 0 60rpx rgba(0,180,255,0.2);
animation:slideUp 0.4s cubic-bezier(0.175,0.885,0.32,1.275);
position:relative;
}
@keyframes slideUp { from{transform:translateY(100rpx) scale(0.9); opacity:0;} to{transform:translateY(0) scale(1); opacity:1;} }
.modal-close { position:absolute; top:25rpx; right:25rpx; width:60rpx; height:60rpx; border-radius:50%; background:rgba(255,255,255,0.1); display:flex; align-items:center; justify-content:center; font-size:40rpx; color:rgba(255,255,255,0.7); z-index:10; }
.modal-header { padding:40rpx 40rpx 20rpx; text-align:center; }
.modal-title { font-size:36rpx; font-weight:bold; color:#FFFFFF; }
.detail-info { padding:30rpx 40rpx; }
.detail-item { margin-bottom:30rpx; }
.detail-label { font-size:26rpx; color:rgba(255,255,255,0.7); margin-bottom:10rpx; font-weight:500; }
.detail-value { font-size:28rpx; color:#FFFFFF; word-break:break-word; }
.intro-value { background:rgba(255,255,255,0.05); border-radius:15rpx; padding:20rpx; border:1rpx solid rgba(255,255,255,0.1); max-height:200rpx; overflow-y:auto; }
.detail-meta-row { display:flex; align-items:center; justify-content:space-between; padding:25rpx 0; margin:20rpx 0; border-top:1rpx solid rgba(255,255,255,0.1); border-bottom:1rpx solid rgba(255,255,255,0.1); }
.meta-item { display:flex; flex-direction:column; align-items:center; flex:1; }
.meta-label { font-size:22rpx; color:rgba(255,255,255,0.6); margin-bottom:8rpx; }
.meta-value { font-size:26rpx; font-weight:600; }
.price-meta { color:#FFD700; text-shadow:0 0 10rpx rgba(255,215,0,0.3); }
.count-meta { color:#00B4FF; }
.id-meta { color:#4CAF50; font-family:'Courier New',monospace; font-size:24rpx; }
.meta-divider { color:rgba(255,255,255,0.2); font-size:24rpx; margin:0 15rpx; }
.link-filter-bar { display:flex; align-items:center; margin-top:30rpx; margin-bottom:20rpx; }
.filter-switch {
padding:10rpx 25rpx; margin-left:10rpx; border-radius:20rpx; background:rgba(255,255,255,0.1);
font-size:24rpx; color:rgba(255,255,255,0.7); transition:all 0.3s;
}
.filter-switch.active { background:linear-gradient(135deg, #00B4FF, #0091EA); color:white; }
.link-list { background:rgba(0,0,0,0.2); border-radius:15rpx; padding:15rpx; }
.link-item { display:flex; align-items:center; justify-content:space-between; padding:15rpx 0; border-bottom:1rpx solid rgba(255,255,255,0.1); }
.link-url { flex:1; font-size:22rpx; color:rgba(255,255,255,0.8); word-break:break-all; margin-right:15rpx; }
.link-status { font-size:20rpx; color:rgba(255,255,255,0.5); margin-right:15rpx; }
.copy-link-btn { padding:8rpx 20rpx; background:#00B4FF; color:white; border-radius:15rpx; font-size:22rpx; }
.load-more-links { text-align:center; padding:20rpx 0; }
.load-more-btn { display:inline-block; padding:15rpx 40rpx; background:linear-gradient(135deg, #9C27B0, #673AB7); border-radius:30rpx; color:white; font-size:26rpx; }
.link-loading, .link-empty { text-align:center; padding:30rpx; color:rgba(255,255,255,0.5); font-size:24rpx; }
/* 弹窗按钮 */
.modal-actions-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:18rpx; padding:30rpx 40rpx 40rpx; border-top:1rpx solid rgba(255,255,255,0.1); }
.modal-grid-btn {
height:85rpx; border-radius:42rpx; font-size:28rpx; font-weight:600; transition:all 0.3s;
border:none; padding:0 20rpx; box-shadow:0 8rpx 25rpx rgba(0,0,0,0.3), inset 0 1rpx 0 rgba(255,255,255,0.2);
display:flex !important; align-items:center !important; justify-content:center !important;
}
.generate-modal-grid-btn { background:linear-gradient(145deg, #00B4FF, #0091EA); color:white; }
.copy-modal-grid-btn { background:linear-gradient(145deg, #9C27B0, #673AB7); color:white; }
.copy-modal-grid-btn.copied { background:linear-gradient(145deg, #FF9800, #F57C00); }
.edit-modal-grid-btn { background:linear-gradient(145deg, #4CAF50, #2E7D32); color:white; }
.delete-modal-grid-btn { background:linear-gradient(145deg, #FF4444, #CC0000); color:white; }
/* 编辑区 */
.edit-section { padding:30rpx 40rpx 20rpx; border-top:1rpx solid rgba(255,255,255,0.1); margin-top:20rpx; }
.edit-item { margin-bottom:30rpx; }
.edit-label { font-size:26rpx; color:rgba(255,255,255,0.8); margin-bottom:15rpx; font-weight:600; }
.edit-input { width:100%; background:rgba(255,255,255,0.08); border:1.5rpx solid rgba(255,255,255,0.2); border-radius:15rpx; padding:25rpx; font-size:28rpx; color:#FFFFFF; }
.intro-edit { min-height:150rpx; }
.price-edit { text-align:center; font-size:32rpx; font-weight:600; height:90rpx; line-height:90rpx; }
.picker-view { padding:25rpx; background:rgba(255,255,255,0.08); border-radius:15rpx; border:1.5rpx solid rgba(255,255,255,0.2); color:#fff; }
.commission-item { display:flex; align-items:center; gap:20rpx; }
.commission-input { flex:1; background:rgba(255,255,255,0.08); border-radius:15rpx; padding:20rpx; color:#fff; }
/* 添加表单 */
.add-form { padding:30rpx 40rpx 20rpx; }
.form-item { margin-bottom:35rpx; }
.form-label { font-size:28rpx; color:rgba(255,255,255,0.8); margin-bottom:18rpx; font-weight:600; }
.intro-input, .price-input { width:100%; background:rgba(255,255,255,0.08); border:1.5rpx solid rgba(255,255,255,0.2); border-radius:15rpx; padding:25rpx; font-size:28rpx; color:#FFFFFF; }
.intro-input { min-height:180rpx; }
.price-input { height:90rpx; line-height:90rpx; text-align:center; font-weight:600; }
.add-actions-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:25rpx; padding:30rpx 40rpx 40rpx; border-top:1rpx solid rgba(255,255,255,0.1); }
.cancel-grid-btn { background:rgba(255,255,255,0.1); color:rgba(255,255,255,0.8); border:1.5rpx solid rgba(255,255,255,0.2); }
.confirm-add-grid-btn { background:linear-gradient(145deg, #9C27B0, #673AB7); color:white; }
/* 确认弹窗 */
.confirm-content {
background:linear-gradient(145deg, rgba(40,40,60,0.95), rgba(50,50,70,0.95));
border-radius:25rpx; padding:50rpx 40rpx 40rpx; width:85%; max-width:550rpx;
border:1.5rpx solid rgba(255,255,255,0.15); box-shadow:0 30rpx 90rpx rgba(0,0,0,0.7); text-align:center;
animation:scaleIn 0.3s ease;
}
@keyframes scaleIn { from{transform:scale(0.8); opacity:0;} to{transform:scale(1); opacity:1;} }
.confirm-title { font-size:34rpx; font-weight:bold; color:#FFFFFF; margin-bottom:25rpx; }
.confirm-text { font-size:28rpx; color:rgba(255,255,255,0.8); margin-bottom:40rpx; }
.confirm-actions-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:25rpx; }
.confirm-grid-btn { height:85rpx; border-radius:42rpx; font-size:28rpx; font-weight:600; display:flex; align-items:center; justify-content:center; }
.cancel-confirm-grid-btn { background:rgba(255,255,255,0.1); color:rgba(255,255,255,0.8); border:1.5rpx solid rgba(255,255,255,0.2); }
.delete-confirm-grid-btn { background:linear-gradient(145deg, #FF4444, #CC0000); color:white; }
.confirm-new-link-grid-btn { background:linear-gradient(145deg, #00B4FF, #0091EA); color:white; }
.loading-mask { position:fixed; top:0; left:0; right:0; bottom:0; background:rgba(18,18,24,0.95); display:flex; align-items:center; justify-content:center; z-index:10000; }
.loading-content { background:rgba(40,40,60,0.95); padding:60rpx 80rpx; border-radius:30rpx; display:flex; flex-direction:column; align-items:center; box-shadow:0 25rpx 70rpx rgba(0,0,0,0.6); }
.loading-spinner { width:90rpx; height:90rpx; border:8rpx solid rgba(0,180,255,0.2); border-top:8rpx solid #00B4FF; border-radius:50%; animation:spin 1.2s linear infinite; margin-bottom:35rpx; }
.loading-text { font-size:30rpx; color:#00B4FF; font-weight:600; }
@keyframes spin { 0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);} }
@import '../../styles/shangjia-xym-form.wxss';
page {
background: #f5f5f5;
}
.balance-amount {
display: flex;
align-items: baseline;
justify-content: center;
margin-bottom: 15rpx;
}
.type-scroll {
white-space: nowrap;
display: flex;
height: 90rpx;
}
.type-text {
max-width: 220rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 500;
}
.filter-row {
display: flex;
align-items: center;
margin-top: 20rpx;
gap: 15rpx;
}
.filter-item {
display: flex;
align-items: center;
border-radius: 30rpx;
padding: 10rpx 20rpx;
}
.filter-label {
font-size: 24rpx;
margin-right: 10rpx;
}
.filter-input {
width: 120rpx;
height: 50rpx;
background: transparent;
font-size: 26rpx;
}
.clear-search {
margin-left: auto;
padding: 10rpx 20rpx;
border-radius: 20rpx;
font-size: 24rpx;
}
.template-section {
height: calc(100vh - 600rpx);
position: relative;
}
.template-scroll {
height: 100%;
}
.template-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 25rpx;
padding-bottom: 30rpx;
}
.template-card {
padding: 25rpx;
display: flex;
flex-direction: column;
min-height: 280rpx;
position: relative;
overflow: hidden;
}
.template-intro {
flex: 1;
margin-bottom: 10rpx;
min-height: 70rpx;
overflow: hidden;
}
.intro-text {
font-size: 24rpx;
line-height: 1.4;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
font-weight: 500;
}
.template-label {
margin-bottom: 10rpx;
}
.template-price-row {
display: flex;
align-items: center;
margin-bottom: 20rpx;
padding: 10rpx 0;
border-bottom: 1rpx solid #eee;
}
.template-actions-grid {
display: flex;
flex-direction: column;
gap: 12rpx;
margin-top: 10rpx;
}
.action-grid-btn {
height: 65rpx;
border-radius: 32rpx;
font-size: 24rpx;
font-weight: 600;
border: none;
padding: 0 20rpx;
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
.add-card {
border: 2rpx dashed #ddd;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 280rpx;
}
.add-icon {
font-size: 60rpx;
color: #bbb;
margin-bottom: 20rpx;
}
.add-text {
font-size: 30rpx;
color: #666;
font-weight: 600;
margin-bottom: 8rpx;
}
.add-subtext {
font-size: 24rpx;
color: #999;
}
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.45);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
padding: 30rpx;
}
.modal-content {
background: #fff;
border-radius: 24rpx;
width: 100%;
max-width: 700rpx;
max-height: 85vh;
overflow-y: auto;
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);
}
.modal-close {
position: absolute;
top: 25rpx;
right: 25rpx;
width: 60rpx;
height: 60rpx;
border-radius: 50%;
background: #f5f5f5;
display: flex;
align-items: center;
justify-content: center;
font-size: 40rpx;
color: #999;
z-index: 10;
}
.modal-header {
padding: 40rpx 40rpx 20rpx;
text-align: center;
}
.modal-title {
font-size: 36rpx;
font-weight: bold;
color: #222;
}
.detail-info {
padding: 30rpx 40rpx;
}
.detail-item {
margin-bottom: 30rpx;
}
.detail-label {
font-size: 26rpx;
color: #888;
margin-bottom: 10rpx;
}
.detail-value {
font-size: 28rpx;
color: #333;
word-break: break-word;
}
.intro-value {
background: #f9f9f9;
border-radius: 15rpx;
padding: 20rpx;
max-height: 200rpx;
overflow-y: auto;
}
.detail-meta-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 25rpx 0;
margin: 20rpx 0;
border-top: 1rpx solid #eee;
border-bottom: 1rpx solid #eee;
}
.meta-item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}
.meta-label {
font-size: 22rpx;
color: #999;
margin-bottom: 8rpx;
}
.meta-value {
font-size: 26rpx;
font-weight: 600;
color: #333;
}
.meta-divider {
color: #ddd;
font-size: 24rpx;
margin: 0 15rpx;
}
.link-filter-bar {
display: flex;
align-items: center;
margin-top: 30rpx;
margin-bottom: 20rpx;
}
.filter-switch {
padding: 10rpx 25rpx;
margin-left: 10rpx;
border-radius: 20rpx;
background: #f5f5f5;
font-size: 24rpx;
color: #666;
}
.filter-switch.active {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492f00;
}
.link-list {
background: #f9f9f9;
border-radius: 15rpx;
padding: 15rpx;
}
.link-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 15rpx 0;
border-bottom: 1rpx solid #eee;
}
.link-url {
flex: 1;
font-size: 22rpx;
color: #666;
word-break: break-all;
margin-right: 15rpx;
}
.link-status {
font-size: 20rpx;
color: #999;
margin-right: 15rpx;
}
.copy-link-btn {
padding: 8rpx 20rpx;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492f00;
border-radius: 15rpx;
font-size: 22rpx;
}
.load-more-links {
text-align: center;
padding: 20rpx 0;
}
.load-more-btn {
display: inline-block;
padding: 15rpx 40rpx;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
border-radius: 30rpx;
color: #492f00;
font-size: 26rpx;
}
.link-loading,
.link-empty {
text-align: center;
padding: 30rpx;
color: #999;
font-size: 24rpx;
}
.modal-actions-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 18rpx;
padding: 30rpx 40rpx 40rpx;
border-top: 1rpx solid #eee;
}
.modal-grid-btn {
height: 85rpx;
border-radius: 42rpx;
font-size: 28rpx;
font-weight: 600;
border: none;
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
.generate-modal-grid-btn,
.copy-modal-grid-btn,
.edit-modal-grid-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492f00;
}
.delete-modal-grid-btn {
background: #ffebee;
color: #c62828;
}
.edit-section {
padding: 30rpx 40rpx 20rpx;
border-top: 1rpx solid #eee;
margin-top: 20rpx;
}
.edit-item {
margin-bottom: 30rpx;
}
.edit-label {
font-size: 26rpx;
color: #666;
margin-bottom: 15rpx;
font-weight: 600;
}
.edit-input {
width: 100%;
background: #f5f5f5;
border-radius: 15rpx;
padding: 25rpx;
font-size: 28rpx;
color: #333;
}
.intro-edit {
min-height: 150rpx;
}
.price-edit {
text-align: center;
font-size: 32rpx;
font-weight: 600;
height: 90rpx;
line-height: 90rpx;
}
.commission-item {
display: flex;
align-items: center;
gap: 20rpx;
}
.commission-input {
flex: 1;
background: #f5f5f5;
border-radius: 15rpx;
padding: 20rpx;
color: #333;
}
.add-form {
padding: 30rpx 40rpx 20rpx;
}
.form-item {
margin-bottom: 35rpx;
}
.form-label {
font-size: 28rpx;
color: #666;
margin-bottom: 18rpx;
font-weight: 600;
}
.intro-input,
.price-input {
width: 100%;
background: #f5f5f5;
border-radius: 15rpx;
padding: 25rpx;
font-size: 28rpx;
color: #333;
}
.intro-input {
min-height: 180rpx;
}
.price-input {
height: 90rpx;
line-height: 90rpx;
text-align: center;
font-weight: 600;
}
.add-actions-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 25rpx;
padding: 30rpx 40rpx 40rpx;
border-top: 1rpx solid #eee;
}
.cancel-grid-btn {
background: #f5f5f5;
color: #666;
}
.confirm-add-grid-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492f00;
}
.confirm-content {
background: #fff;
border-radius: 25rpx;
padding: 50rpx 40rpx 40rpx;
width: 85%;
max-width: 550rpx;
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);
text-align: center;
}
.confirm-title {
font-size: 34rpx;
font-weight: bold;
color: #222;
margin-bottom: 25rpx;
}
.confirm-text {
font-size: 28rpx;
color: #666;
margin-bottom: 40rpx;
}
.confirm-actions-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 25rpx;
}
.confirm-grid-btn {
height: 85rpx;
border-radius: 42rpx;
font-size: 28rpx;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
}
.cancel-confirm-grid-btn {
background: #f5f5f5;
color: #666;
}
.delete-confirm-grid-btn {
background: #ffebee;
color: #c62828;
}
.confirm-new-link-grid-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492f00;
}
.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: 10000;
}
.loading-content {
background: #fff;
padding: 60rpx 80rpx;
border-radius: 30rpx;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.08);
}
.loading-spinner {
width: 90rpx;
height: 90rpx;
border: 8rpx solid #eee;
border-top: 8rpx solid #ffd061;
border-radius: 50%;
animation: spin 1.2s linear infinite;
margin-bottom: 35rpx;
}
.loading-text {
font-size: 30rpx;
font-weight: 600;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

View File

@@ -57,8 +57,8 @@
lower-threshold="50"
>
<view class="refresher-slot" slot="refresher">
<text wx:if="{{scrollViewRefreshing}}" class="refreshing-text">正在刷新...</text>
<text wx:else class="pull-text">下拉刷新</text>
<text wx:if="{{scrollViewRefreshing}}" class="refreshing-text">正在刷新...</text>
<text wx:else class="pull-text">下拉刷新</text>
</view>
<!-- 内容容器:仅设置左侧 padding右侧间距由 wrapper 控制 -->

View File

@@ -344,4 +344,6 @@ page {
padding: 40rpx 0;
font-size: 26rpx;
color: #999;
}
}
@import '../../styles/dashou-xym-orders-theme.wxss';

View File

@@ -1702,4 +1702,6 @@
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
}
@import '../../styles/dashou-xym-recharge-theme.wxss';

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,12 @@
{
"usingComponents": {
"global-notification": "/components/global-notification/global-notification",
"chenghao-tag": "/components/chenghao-tag/chenghao-tag",
"tab-bar": "/tab-bar/index"
},
"navigationBarBackgroundColor": "#e8ecf4",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的",
"backgroundColor": "#e8ecf4",
"backgroundTextStyle": "light",
"enablePullDownRefresh": false,
"onReachBottomDistance": 50
}
"usingComponents": {
"global-notification": "/components/global-notification/global-notification",
"chenghao-tag": "/components/chenghao-tag/chenghao-tag",
"tab-bar": "/tab-bar/index"
},
"navigationStyle": "custom",
"backgroundColor": "#fff8e1",
"backgroundTextStyle": "dark",
"enablePullDownRefresh": false,
"onReachBottomDistance": 50
}

View File

@@ -1,395 +1,238 @@
<image class="page-bg" src="{{imgUrls.pageBg}}" mode="aspectFill" />
<!-- 打手端个人中心 - 逍遥梦布局,逻辑/事件不变 -->
<!-- 未注册打手(无任何服务身份时显示) -->
<!-- 未注册 -->
<block wx:if="{{!isDashou && !isGuanshi && !isZuzhang && !isKaoheguan}}">
<view class="unreg-area">
<view class="unreg-card">
<text class="unreg-title">接单员认证</text>
<input class="unreg-input" type="text" placeholder="输入邀请码" maxlength="100" value="{{inviteCode}}" bindinput="onInviteCodeInput" placeholder-class="ph" />
<view class="unreg-btn" bindtap="onRegister">
<text class="unreg-btn-text">立即注册</text>
<view class="user-page unreg-page">
<view class="page-header">
<view class="status-bar" style="height:{{statusBar}}px"></view>
<view class="nav-bar" style="height:{{navBar - statusBar}}px"><text class="nav-title">我的</text></view>
</view>
<view class="unreg-btn unreg-btn-secondary" bindtap="quickRegisterAsPlatform">
<text class="unreg-btn-text">平台直签注册</text>
</view>
<view class="unreg-clear" bindtap="switchToNormal">
<image class="unreg-clear-icon" src="{{imgUrls.iconSwitch}}" mode="aspectFit" />
<text class="unreg-clear-text">返回点单端</text>
</view>
<view class="unreg-clear" bindtap="clearCache">
<image class="unreg-clear-icon" src="{{imgUrls.iconClear}}" mode="aspectFit" />
<text class="unreg-clear-text">清除缓存,重新登录</text>
<view class="unreg-area">
<view class="panel shadow unreg-card">
<text class="unreg-title">接单员认证</text>
<input class="unreg-input" type="text" placeholder="输入邀请码" maxlength="100" value="{{inviteCode}}" bindinput="onInviteCodeInput" placeholder-class="ph" />
<view class="btn-bg unreg-btn" bindtap="onRegister"><text class="unreg-btn-text">立即注册</text></view>
<view class="unreg-btn-secondary" bindtap="quickRegisterAsPlatform"><text>平台直签注册</text></view>
<view class="unreg-link" bindtap="switchToNormal"><text>返回点单端</text></view>
<view class="unreg-link" bindtap="clearCache"><text>清除缓存,重新登录</text></view>
</view>
</view>
<tab-bar/>
</view>
</view>
</block>
<!-- 已注册 -->
<block wx:else>
<view class="main-body {{layoutSparse ? 'layout-sparse-padding' : ''}}">
<view class="refresh-btn" bindtap="onTapRefresh">
<image class="refresh-icon" src="{{imgUrls.iconRefresh}}" mode="aspectFit" />
</view>
<view class="user-card">
<image class="user-card-bg" src="{{imgUrls.userCardBg}}" mode="aspectFill" />
<view class="user-card-inner">
<image class="user-avatar" src="{{avatarUrl || imgUrls.avatarDefault}}" mode="aspectFill" bindtap="previewAvatar" />
<view class="user-info">
<view class="name-row">
<text class="user-name">{{dashouNicheng || '接单员'}}</text>
<view class="role-tags">
<view class="role-tag role-tag-dashou">接单员</view>
<view class="role-tag role-tag-guanshi" wx:if="{{isGuanshi}}">管事</view>
<view class="role-tag role-tag-zuzhang" wx:if="{{isZuzhang}}">组长</view>
<view class="role-tag role-tag-kaohe" wx:if="{{isKaoheguan}}">考核</view>
</view>
</view>
<view class="uid-row" bindtap="copyUid">
<text class="uid-text">UID: {{uid || '--'}}</text>
<image class="copy-icon" src="{{imgUrls.iconCopy}}" mode="aspectFit" />
</view>
</view>
</view>
</view>
<!-- 联系客服(企业微信) -->
<view class="kefu-banner" bindtap="goToKefu">
<image class="kefu-banner-bg" src="{{imgUrls.kefuBannerBg}}" mode="aspectFill" />
<view class="kefu-banner-overlay"></view>
<view class="kefu-banner-content">
<view class="kefu-banner-left">
<image class="kefu-banner-icon" src="{{imgUrls.iconKefu}}" mode="aspectFit" />
<view class="kefu-banner-text">
<text class="kefu-banner-title">在线客服</text>
<text class="kefu-banner-sub">企业微信 · 即时响应</text>
</view>
</view>
<view class="kefu-banner-btn">联系</view>
</view>
</view>
<view class="badge-zone" wx:if="{{chenghaoList.length > 0 || (isGuanshi && guanshiChenghaoList.length > 0)}}">
<scroll-view scroll-x class="badge-scroll" wx:if="{{chenghaoList.length > 0}}">
<view class="badge-tag-wrap" wx:for="{{chenghaoList}}" wx:key="index">
<chenghao-tag mingcheng="{{item.mingcheng}}" texiaoJson="{{item.texiao_json}}" />
</view>
</scroll-view>
<scroll-view scroll-x class="badge-scroll badge-scroll-sub" wx:if="{{isGuanshi && guanshiChenghaoList.length > 0}}">
<view class="badge-tag-wrap" wx:for="{{guanshiChenghaoList}}" wx:key="index">
<chenghao-tag mingcheng="{{item.mingcheng}}" texiaoJson="{{item.texiao_json}}" />
</view>
</scroll-view>
</view>
<!-- 我的资产 -->
<view class="section-card section-asset">
<!-- 黑卡 VIP -->
<view class="vip-black-card" bindtap="goToRecharge">
<image class="vip-black-bg" src="{{imgUrls.vipCardBg}}" mode="aspectFill" />
<view class="vip-black-overlay"></view>
<view class="vip-black-body">
<view class="vip-black-text">
<text class="vip-black-title">会员充值</text>
<text class="vip-black-sub">VIP 专属权益 · 尊享服务</text>
</view>
<view class="vip-black-action">
<text class="vip-black-go">去充值</text>
</view>
</view>
<view class="user-page">
<view class="page-header">
<view class="status-bar" style="height:{{statusBar}}px"></view>
<view class="nav-bar" style="height:{{navBar - statusBar}}px"><text class="nav-title">我的</text></view>
</view>
<view class="asset-panel">
<view class="asset-panel-fallback"></view>
<image class="asset-panel-bg" src="{{imgUrls.assetPanelBg}}" mode="aspectFill" />
<view class="asset-panel-inner">
<view class="asset-panel-head">
<image class="asset-panel-head-icon" src="{{imgUrls.iconSectionAsset}}" mode="aspectFit" />
<text class="asset-panel-head-title">我的资产</text>
</view>
<view class="total-asset-row">
<view class="total-asset-fallback"></view>
<image class="total-asset-bg" src="{{imgUrls.totalAssetBg}}" mode="aspectFill" />
<view class="total-asset-inner">
<view class="total-asset-left">
<text class="total-asset-label">总资产(可提现)</text>
<text class="total-asset-val">¥{{totalAssets}}</text>
<view class="asset-breakdown-list">
<view class="asset-breakdown-line" wx:for="{{assetBreakdown}}" wx:key="label">
<text class="breakdown-name">{{item.label}}</text>
<text class="breakdown-amt">¥{{item.amount}}</text>
</view>
<view class="refresh-float" bindtap="onTapRefresh">
<image class="refresh-float-ico" src="{{imgUrls.iconRefresh}}" mode="aspectFit"/>
</view>
<scroll-view class="content" scroll-y enhanced show-scrollbar="{{false}}">
<!-- 用户信息 -->
<view class="user-info flexb">
<view class="flex">
<image class="avatar" src="{{avatarUrl || imgUrls.avatarDefault}}" mode="aspectFill" bindtap="previewAvatar"/>
<view class="user-text-col">
<view class="nickname-row">
<text class="nickname">{{dashouNicheng || '接单员'}}</text>
<view class="deposit-tag" wx:if="{{yajin && yajin != '0' && yajin != '0.00'}}">保证金</view>
<view class="role-tags">
<text class="role-tag">接单员</text>
<text class="role-tag" wx:if="{{isGuanshi}}">管事</text>
<text class="role-tag" wx:if="{{isZuzhang}}">组长</text>
<text class="role-tag" wx:if="{{isKaoheguan}}">考核</text>
</view>
</view>
<view class="withdraw-btn" catchtap="goToTotalWithdraw">提现</view>
</view>
</view>
<view class="stats-grid">
<view class="mini-stat">
<text class="mini-val">{{jinfen || '0'}}</text>
<text class="mini-lbl">积分</text>
</view>
<view class="mini-stat">
<text class="mini-val">{{yajin || '0.00'}}</text>
<text class="mini-lbl">保证金</text>
</view>
<view class="mini-stat" wx:if="{{isGuanshi}}">
<text class="mini-val">{{yaoqingzongshu || 0}}</text>
<text class="mini-lbl">邀请总数</text>
</view>
<view class="mini-stat" wx:if="{{isGuanshi}}">
<text class="mini-val">{{yichongzhiDashou || 0}}</text>
<text class="mini-lbl">已充值</text>
</view>
<view class="mini-stat" wx:if="{{isGuanshi}}">
<text class="mini-val">{{fenyongzonge || '0.00'}}</text>
<text class="mini-lbl">分成总额</text>
</view>
<view class="mini-stat" wx:if="{{isGuanshi}}">
<text class="mini-val">{{zhuanhualv || 0}}%</text>
<text class="mini-lbl">有效率</text>
</view>
<view class="mini-stat" wx:if="{{isZuzhang}}">
<text class="mini-val">{{guanshiCount || 0}}</text>
<text class="mini-lbl">邀请管事</text>
</view>
<view class="mini-stat" wx:if="{{isZuzhang}}">
<text class="mini-val">{{fenhongZonge || '0.00'}}</text>
<text class="mini-lbl">分红总额</text>
</view>
<view class="mini-stat" wx:if="{{isKaoheguan}}">
<text class="mini-val">{{shenheZongshu || 0}}</text>
<text class="mini-lbl">审核总数</text>
</view>
<view class="mini-stat" wx:if="{{isKaoheguan}}">
<text class="mini-val">{{tongguoZongshu || 0}}</text>
<text class="mini-lbl">通过总数</text>
</view>
<view class="mini-stat" wx:if="{{isKaoheguan}}">
<text class="mini-val">{{pendingShenheCount || 0}}</text>
<text class="mini-lbl">待审核</text>
<view class="sn-row" bindtap="copyUid">
<text class="sn">ID: {{uid || '--'}}</text>
<image class="copy-ico" src="{{imgUrls.iconCopy}}" mode="aspectFit"/>
</view>
</view>
</view>
<image class="setting-ico" src="{{imgUrls.iconEdit}}" mode="aspectFit" bindtap="goToModifyInfo"/>
</view>
</view>
</view>
<!-- 荣耀排行榜 -->
<view class="rank-section">
<view class="rank-hub-head">
<image class="rank-hub-head-icon" src="{{imgUrls.iconSectionRank}}" mode="aspectFit" />
<view class="rank-hub-head-text">
<text class="rank-hub-title">荣耀排行榜</text>
<text class="rank-hub-sub">四榜实时更新</text>
<!-- 称号 -->
<view class="badge-zone" wx:if="{{chenghaoList.length > 0 || (isGuanshi && guanshiChenghaoList.length > 0)}}">
<scroll-view scroll-x class="badge-scroll" wx:if="{{chenghaoList.length > 0}}">
<view class="badge-tag-wrap" wx:for="{{chenghaoList}}" wx:key="index">
<chenghao-tag mingcheng="{{item.mingcheng}}" texiaoJson="{{item.texiao_json}}"/>
</view>
</scroll-view>
<scroll-view scroll-x class="badge-scroll" wx:if="{{isGuanshi && guanshiChenghaoList.length > 0}}">
<view class="badge-tag-wrap" wx:for="{{guanshiChenghaoList}}" wx:key="index">
<chenghao-tag mingcheng="{{item.mingcheng}}" texiaoJson="{{item.texiao_json}}"/>
</view>
</scroll-view>
</view>
</view>
<view class="rank-grid">
<view
class="rank-card {{item.themeClass}}"
wx:for="{{rankBoardList}}"
wx:key="type"
bindtap="goToRanking"
data-type="{{item.type}}"
>
<!-- 背景水印图标 -->
<image class="rank-card-watermark" src="{{item.icon}}" mode="aspectFit" />
<!-- 内容区:左卡片靠左,右卡片靠右 -->
<view class="rank-card-body">
<view class="rank-card-info">
<image class="rank-card-icon" src="{{item.icon}}" mode="aspectFit" />
<text class="rank-card-title">{{item.name}}</text>
<text class="rank-card-desc">{{item.sub}}</text>
<!-- 佣金/资产卡(逍遥梦 wallet-card -->
<view class="wallet-card flexb">
<view class="wallet-left">
<view class="w-label">我的佣金(元)</view>
<view class="w-num">¥{{totalAssets}}</view>
<view class="w-sub">可提现 ¥{{yongjin || '0.00'}} · 查看</view>
</view>
<view class="wallet-btns flex">
<view class="btn-outline" catchtap="goToRecharge">充值</view>
<view class="btn-outline" catchtap="goToTotalWithdraw">去提现</view>
</view>
</view>
<!-- 会员充值 + 保证金(均跳转同一充值页) -->
<view class="banner-row flex">
<image class="banner-img" src="{{imgUrls.bannerVip}}" mode="widthFix" bindtap="goToRecharge"/>
<image class="banner-img" src="{{imgUrls.bannerDeposit}}" mode="widthFix" bindtap="goToRecharge"/>
</view>
<!-- 资产统计(逍遥梦 freeze-row -->
<view class="freeze-row flexa">
<view class="freeze-col flexmc">
<text class="freeze-num">{{jinfen || '0'}}</text>
<text class="freeze-lbl">积分</text>
</view>
<view class="freeze-col flexmc">
<text class="freeze-num">{{yajin || '0.00'}}</text>
<text class="freeze-lbl">保证金</text>
</view>
<view class="freeze-col flexmc">
<text class="freeze-num">{{yongjin || '0.00'}}</text>
<text class="freeze-lbl">佣金</text>
</view>
</view>
<!-- 角色扩展统计(从左往右排列,不均分撑满) -->
<view class="stats-bar" wx:if="{{isGuanshi || isZuzhang || isKaoheguan}}">
<view class="stat-cell" wx:if="{{isGuanshi}}"><text class="stat-val">{{yaoqingzongshu || 0}}</text><text class="stat-lbl">邀请总数</text></view>
<view class="stat-cell" wx:if="{{isGuanshi}}"><text class="stat-val">{{yichongzhiDashou || 0}}</text><text class="stat-lbl">已充值</text></view>
<view class="stat-cell" wx:if="{{isGuanshi}}"><text class="stat-val">{{fenyongzonge || '0.00'}}</text><text class="stat-lbl">分成总额</text></view>
<view class="stat-cell" wx:if="{{isGuanshi}}"><text class="stat-val">{{zhuanhualv || 0}}%</text><text class="stat-lbl">有效率</text></view>
<view class="stat-cell" wx:if="{{isZuzhang}}"><text class="stat-val">{{guanshiCount || 0}}</text><text class="stat-lbl">邀请管事</text></view>
<view class="stat-cell" wx:if="{{isZuzhang}}"><text class="stat-val">{{fenhongZonge || '0.00'}}</text><text class="stat-lbl">分红总额</text></view>
<view class="stat-cell" wx:if="{{isKaoheguan}}"><text class="stat-val">{{shenheZongshu || 0}}</text><text class="stat-lbl">审核总数</text></view>
<view class="stat-cell" wx:if="{{isKaoheguan}}"><text class="stat-val">{{tongguoZongshu || 0}}</text><text class="stat-lbl">通过总数</text></view>
<view class="stat-cell" wx:if="{{isKaoheguan}}"><text class="stat-val">{{pendingShenheCount || 0}}</text><text class="stat-lbl">待审核</text></view>
</view>
<!-- 接单服务(对应逍遥梦「我的订单」四宫格) -->
<view class="panel shadow">
<view class="panel-title flexb"><text class="lg">接单服务</text></view>
<view class="order-nav flexa">
<view class="nav-item flexmc" bindtap="goToReceiveOrder">
<image class="nav-icon" src="{{imgUrls.iconGame}}" mode="aspectFit"/><text class="sm">抢单大厅</text>
</view>
<view class="nav-item flexmc" bindtap="goToMyOrders">
<image class="nav-icon" src="{{imgUrls.iconOrders}}" mode="aspectFit"/><text class="sm">我的订单</text>
</view>
<view class="nav-item flexmc" bindtap="goToMyPunishment">
<image class="nav-icon" src="{{imgUrls.iconPunish}}" mode="aspectFit"/><text class="sm">我的处罚</text>
</view>
<view class="nav-item flexmc" bindtap="goToKaohe">
<image class="nav-icon" src="{{imgUrls.iconMedal}}" mode="aspectFit"/><text class="sm">考核金牌</text>
</view>
</view>
</view>
</view>
</view>
<!-- 接单员功能 -->
<view class="section-card">
<view class="section-head-line">
<image class="section-head-icon" src="{{imgUrls.iconSectionFunc}}" mode="aspectFit" />
<text class="section-title section-title-sm">接单员功能</text>
</view>
<view class="func-panel">
<image class="func-panel-bg" src="{{imgUrls.funcPanelBg}}" mode="aspectFill" />
<view class="func-grid {{layoutSparse ? 'func-grid-sparse' : ''}}">
<view class="func-cell" bindtap="goToReceiveOrder">
<image class="func-icon" src="{{imgUrls.iconGame}}" mode="aspectFit" />
<text class="func-label">抢单大厅</text>
<!-- 荣耀排行榜(横向滑动,省空间) -->
<view class="rank-hub panel shadow">
<view class="panel-title flexb">
<text class="lg">荣耀排行榜</text>
<text class="rank-hub-tip">TOP50</text>
</view>
<view class="func-cell" bindtap="goToMyOrders">
<image class="func-icon" src="{{imgUrls.iconOrders}}" mode="aspectFit" />
<text class="func-label">我的订单</text>
</view>
<view class="func-cell" bindtap="goToMyPunishment">
<image class="func-icon" src="{{imgUrls.iconPunish}}" mode="aspectFit" />
<text class="func-label">我的处罚</text>
</view>
<view class="func-cell" bindtap="goToKaohe">
<image class="func-icon" src="{{imgUrls.iconMedal}}" mode="aspectFit" />
<text class="func-label">考核金牌</text>
</view>
<view class="func-cell" bindtap="goToGuanzhuKs">
<image class="func-icon" src="{{imgUrls.iconKuaishou}}" mode="aspectFit" />
<text class="func-label">关注快手</text>
<scroll-view scroll-x class="rank-hub-scroll" enhanced show-scrollbar="{{false}}">
<view class="rank-hub-track">
<view
wx:for="{{rankBoardList}}"
wx:key="type"
class="rank-tile {{item.themeClass}}"
bindtap="goToRanking"
data-type="{{item.type}}"
>
<view class="rank-tile-inner">
<image class="rank-tile-icon" src="{{item.icon}}" mode="aspectFit"/>
<view class="rank-tile-text">
<text class="rank-tile-name">{{item.name}}</text>
<text class="rank-tile-sub">{{item.sub}}</text>
</view>
<text class="rank-tile-go">进入</text>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 管事功能 -->
<view class="panel shadow" wx:if="{{isGuanshi}}">
<view class="panel-title"><text class="lg">管事功能</text></view>
<view class="func-grid">
<view class="func-item flexmc" bindtap="goToInviteUser"><image class="func-icon" src="{{imgUrls.iconInvite}}" mode="aspectFit"/><text class="func-txt">邀请用户</text></view>
<view class="func-item flexmc" bindtap="goToMySubordinate"><image class="func-icon" src="{{imgUrls.iconSub}}" mode="aspectFit"/><text class="func-txt">我的下级</text></view>
<view class="func-item flexmc" bindtap="goToRechargeRecord"><image class="func-icon" src="{{imgUrls.iconRecord}}" mode="aspectFit"/><text class="func-txt">会员记录</text></view>
<view class="func-item flexmc" bindtap="goToPromoPoster"><image class="func-icon" src="{{imgUrls.iconPoster}}" mode="aspectFit"/><text class="func-txt">推广海报</text></view>
<view class="func-item flexmc" bindtap="contactZuzhang"><image class="func-icon" src="{{imgUrls.iconContact}}" mode="aspectFit"/><text class="func-txt">联系组长</text></view>
</view>
</view>
</view>
</view>
<!-- 管事功能 -->
<view class="section-card" wx:if="{{isGuanshi}}">
<view class="section-head-line">
<image class="section-head-icon" src="{{imgUrls.iconSectionGuanshi}}" mode="aspectFit" />
<text class="section-title section-title-sm">管事功能</text>
</view>
<view class="func-panel">
<image class="func-panel-bg" src="{{imgUrls.funcPanelBg}}" mode="aspectFill" />
<view class="func-grid">
<view class="func-cell" bindtap="goToInviteUser">
<image class="func-icon" src="{{imgUrls.iconInvite}}" mode="aspectFit" />
<text class="func-label">邀请用户</text>
</view>
<view class="func-cell" bindtap="goToMySubordinate">
<image class="func-icon" src="{{imgUrls.iconSub}}" mode="aspectFit" />
<text class="func-label">我的下级</text>
</view>
<view class="func-cell" bindtap="goToRechargeRecord">
<image class="func-icon" src="{{imgUrls.iconRecord}}" mode="aspectFit" />
<text class="func-label">会员记录</text>
</view>
<view class="func-cell" bindtap="goToPromoPoster">
<image class="func-icon" src="{{imgUrls.iconPoster}}" mode="aspectFit" />
<text class="func-label">推广海报</text>
</view>
<view class="func-cell" bindtap="contactZuzhang">
<image class="func-icon" src="{{imgUrls.iconContact}}" mode="aspectFit" />
<text class="func-label">联系组长</text>
<!-- 组长功能 -->
<view class="panel shadow" wx:if="{{isZuzhang}}">
<view class="panel-title"><text class="lg">组长功能</text></view>
<view class="func-grid">
<view class="func-item flexmc" bindtap="goToFenhongJilu"><image class="func-icon" src="{{imgUrls.iconRecord}}" mode="aspectFit"/><text class="func-txt">分红记录</text></view>
<view class="func-item flexmc" bindtap="goToYaoqingGuanshi"><image class="func-icon" src="{{imgUrls.iconInvite}}" mode="aspectFit"/><text class="func-txt">邀请管事</text></view>
</view>
</view>
</view>
</view>
<!-- 组长功能 -->
<view class="section-card" wx:if="{{isZuzhang}}">
<view class="section-head-line">
<image class="section-head-icon" src="{{imgUrls.iconSectionZuzhang}}" mode="aspectFit" />
<text class="section-title section-title-sm">组长功能</text>
</view>
<view class="func-panel">
<image class="func-panel-bg" src="{{imgUrls.funcPanelBg}}" mode="aspectFill" />
<view class="func-grid">
<view class="func-cell" bindtap="goToFenhongJilu">
<image class="func-icon" src="{{imgUrls.iconRecord}}" mode="aspectFit" />
<text class="func-label">分红记录</text>
</view>
<view class="func-cell" bindtap="goToYaoqingGuanshi">
<image class="func-icon" src="{{imgUrls.iconInvite}}" mode="aspectFit" />
<text class="func-label">邀请管事</text>
<!-- 考核官功能 -->
<view class="panel shadow" wx:if="{{isKaoheguan}}">
<view class="panel-title"><text class="lg">考核官功能</text></view>
<view class="func-grid">
<view class="func-item flexmc" bindtap="goToKaoheDafen"><image class="func-icon" src="{{imgUrls.iconKaoheDafen}}" mode="aspectFit"/><text class="func-txt">考核打分</text></view>
<view class="func-item flexmc" bindtap="goToKaoheJilu"><image class="func-icon" src="{{imgUrls.iconKaoheJilu}}" mode="aspectFit"/><text class="func-txt">考核记录</text></view>
<view class="func-item flexmc" bindtap="goToKaoheZhongxin"><image class="func-icon" src="{{imgUrls.iconKaoheZhongxin}}" mode="aspectFit"/><text class="func-txt">考核中心</text></view>
<view class="func-item flexmc" bindtap="goToKaoheWithdraw"><image class="func-icon" src="{{imgUrls.iconWithdraw}}" mode="aspectFit"/><text class="func-txt">考核提现</text></view>
</view>
</view>
</view>
</view>
<!-- 考核官功能 -->
<view class="section-card" wx:if="{{isKaoheguan}}">
<view class="section-head-line">
<image class="section-head-icon" src="{{imgUrls.iconSectionKaohe}}" mode="aspectFit" />
<text class="section-title section-title-sm">考核官功能</text>
</view>
<view class="func-panel">
<image class="func-panel-bg" src="{{imgUrls.funcPanelBg}}" mode="aspectFill" />
<view class="func-grid">
<view class="func-cell" bindtap="goToKaoheDafen">
<image class="func-icon" src="{{imgUrls.iconKaoheDafen}}" mode="aspectFit" />
<text class="func-label">考核打分</text>
</view>
<view class="func-cell" bindtap="goToKaoheJilu">
<image class="func-icon" src="{{imgUrls.iconKaoheJilu}}" mode="aspectFit" />
<text class="func-label">考核记录</text>
</view>
<view class="func-cell" bindtap="goToKaoheZhongxin">
<image class="func-icon" src="{{imgUrls.iconKaoheZhongxin}}" mode="aspectFit" />
<text class="func-label">考核中心</text>
</view>
<view class="func-cell" bindtap="goToKaoheWithdraw">
<image class="func-icon" src="{{imgUrls.iconWithdraw}}" mode="aspectFit" />
<text class="func-label">考核提现</text>
<!-- 身份认证 -->
<view class="panel shadow" wx:if="{{showAuthSection}}">
<view class="panel-title"><text class="lg">身份认证</text></view>
<view class="func-grid">
<view class="func-item flexmc" wx:for="{{pendingAuthList}}" wx:key="type" bindtap="onTapAuthItem" data-type="{{item.type}}">
<image class="func-icon" src="{{item.icon}}" mode="aspectFit"/>
<text class="func-txt">{{item.name}}</text>
<text class="func-tag {{item.done ? 'func-tag-done' : ''}}">{{item.tag}}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 身份认证:仅未认证身份 + 商家(已认证可进商家端) -->
<view class="section-card" wx:if="{{showAuthSection}}">
<view class="section-head-line">
<image class="section-head-icon" src="{{imgUrls.iconSectionMore}}" mode="aspectFit" />
<text class="section-title section-title-sm">身份认证</text>
</view>
<view class="func-panel">
<image class="func-panel-bg" src="{{imgUrls.authPanelBg}}" mode="aspectFill" />
<view class="auth-grid auth-grid-dynamic">
<view
class="auth-cell"
wx:for="{{pendingAuthList}}"
wx:key="type"
bindtap="onTapAuthItem"
data-type="{{item.type}}"
>
<image class="auth-cell-icon" src="{{item.icon}}" mode="aspectFit" />
<text class="auth-cell-name">{{item.name}}</text>
<text class="auth-cell-tag {{item.done ? 'auth-cell-tag-done' : ''}}">{{item.tag}}</text>
<!-- 更多功能 -->
<view class="panel shadow">
<view class="panel-title"><text class="lg">更多功能</text></view>
<view class="func-grid">
<view class="func-item flexmc" bindtap="goToKefu"><image class="func-icon" src="{{imgUrls.iconKefu}}" mode="aspectFit"/><text class="func-txt">在线客服</text></view>
<view class="func-item flexmc" bindtap="goToGuanzhuKs"><image class="func-icon" src="{{imgUrls.iconKuaishou}}" mode="aspectFit"/><text class="func-txt">关注快手</text></view>
<view class="func-item flexmc" bindtap="contactInviter"><image class="func-icon" src="{{imgUrls.iconInvite}}" mode="aspectFit"/><text class="func-txt">联系邀请人</text></view>
<view class="func-item flexmc" bindtap="goToRules"><image class="func-icon" src="{{imgUrls.iconBook}}" mode="aspectFit"/><text class="func-txt">用户规则</text></view>
<view class="func-item flexmc" bindtap="switchToNormal"><image class="func-icon" src="{{imgUrls.iconSwitch}}" mode="aspectFit"/><text class="func-txt">返回点单端</text></view>
<view class="func-item flexmc" bindtap="clearCache"><image class="func-icon" src="{{imgUrls.iconClear}}" mode="aspectFit"/><text class="func-txt">清除缓存</text></view>
</view>
</view>
</view>
</view>
<!-- 更多 -->
<view class="section-card section-last">
<view class="section-head-line">
<image class="section-head-icon" src="{{imgUrls.iconSectionMore}}" mode="aspectFit" />
<text class="section-title section-title-sm">更多</text>
</view>
<view class="list-card">
<image class="list-card-bg" src="{{imgUrls.listBg}}" mode="aspectFill" />
<view class="list-card-inner">
<view class="list-item" bindtap="contactInviter">
<image class="list-icon" src="{{imgUrls.iconInvite}}" mode="aspectFit" />
<text class="list-text">联系邀请人</text>
<image class="list-arrow" src="{{imgUrls.iconArrow}}" mode="aspectFit" />
</view>
<view class="list-item" bindtap="goToModifyInfo">
<image class="list-icon" src="{{imgUrls.iconEdit}}" mode="aspectFit" />
<text class="list-text">修改个人信息</text>
<image class="list-arrow" src="{{imgUrls.iconArrow}}" mode="aspectFit" />
</view>
<view class="list-item" bindtap="goToRules">
<image class="list-icon" src="{{imgUrls.iconBook}}" mode="aspectFit" />
<text class="list-text">用户规则</text>
<image class="list-arrow" src="{{imgUrls.iconArrow}}" mode="aspectFit" />
</view>
<view class="list-item" bindtap="switchToNormal">
<image class="list-icon" src="{{imgUrls.iconSwitch}}" mode="aspectFit" />
<text class="list-text">返回点单端</text>
<image class="list-arrow" src="{{imgUrls.iconArrow}}" mode="aspectFit" />
</view>
<view class="list-item" bindtap="clearCache">
<image class="list-icon" src="{{imgUrls.iconClear}}" mode="aspectFit" />
<text class="list-text">清除缓存</text>
<text class="list-sub">重新登录</text>
<image class="list-arrow" src="{{imgUrls.iconArrow}}" mode="aspectFit" />
</view>
</view>
</view>
<view class="content-bottom"></view>
</scroll-view>
<tab-bar/>
</view>
</view>
</block>
<view class="loading-mask" wx:if="{{isLoading}}">
<view class="loading-spinner"></view>
</view>
<global-notification id="global-notification" />
<tab-bar />
<popup-notice id="popupNotice" />
<global-notification id="global-notification"/>
<popup-notice id="popupNotice"/>

File diff suppressed because it is too large Load Diff

View File

@@ -4,9 +4,9 @@
"popup-notice": "/components/popup-notice/popup-notice"
},
"backgroundTextStyle": "dark",
"navigationBarBackgroundColor": "#0a0a0f",
"navigationBarTitleText": "商家派单",
"navigationBarTextStyle": "white",
"backgroundColor": "#0a0a0f",
"navigationBarBackgroundColor": "#fff8e1",
"navigationBarTitleText": "自定义发单",
"navigationBarTextStyle": "black",
"backgroundColor": "#f5f5f5",
"enablePullDownRefresh": false
}

View File

@@ -1,5 +1,5 @@
<!-- pages/merchant-dispatch/merchant-dispatch.wxml -->
<view class="page">
<view class="page sj-form-theme">
<!-- 余额卡片 -->
<view class="balance-card">
<text class="balance-label">可用余额</text>
@@ -144,7 +144,7 @@
<text class="field-optional">选填</text>
</view>
<view class="switch-row">
<switch checked="{{commissionEnabled}}" bindchange="onCommissionToggle" color="#9C27B0"/>
<switch checked="{{commissionEnabled}}" bindchange="onCommissionToggle" color="#ffd061"/>
<text class="switch-label">{{commissionEnabled ? '已开启' : '未开启'}}</text>
</view>
<input

View File

@@ -1,31 +1,10 @@
/* 商家派单 */
@import '../../styles/shangjia-xym-form.wxss';
page {
background: #f5f5f5;
}
.page {
min-height: 100vh;
padding: 24rpx;
padding-bottom: 160rpx;
box-sizing: border-box;
}
/* 余额卡片 */
.balance-card {
background: #1a1a2e;
border-radius: 16rpx;
padding: 36rpx 32rpx;
margin-bottom: 20rpx;
text-align: center;
}
.balance-label {
font-size: 24rpx;
color: rgba(255,255,255,0.5);
display: block;
}
/* 商家派单 - 布局补充 */
.balance-row {
display: flex;
align-items: baseline;
@@ -36,31 +15,21 @@ page {
.balance-value {
font-size: 52rpx;
font-weight: 700;
color: #f0d060;
line-height: 1;
}
.balance-unit {
font-size: 26rpx;
color: #f0d060;
margin-left: 6rpx;
font-weight: 500;
}
.balance-tip {
font-size: 20rpx;
color: rgba(255,255,255,0.35);
display: block;
}
/* 卡片 */
.card {
background: #fff;
border-radius: 16rpx;
padding: 28rpx;
margin-bottom: 20rpx;
}
.card-header {
display: flex;
align-items: center;
@@ -71,46 +40,16 @@ page {
width: 8rpx;
height: 8rpx;
border-radius: 4rpx;
background: #9C27B0;
margin-right: 12rpx;
flex-shrink: 0;
}
.card-title {
font-size: 28rpx;
font-weight: 700;
color: #333;
}
/* 订单类型 */
.type-scroll {
white-space: nowrap;
display: flex;
padding: 8rpx 0;
}
.type-chip {
display: inline-flex;
flex-shrink: 0;
align-items: center;
justify-content: center;
height: 64rpx;
padding: 0 28rpx;
margin-right: 14rpx;
background: #f5f5f5;
border-radius: 32rpx;
font-size: 24rpx;
color: #666;
border: 1rpx solid transparent;
}
.type-chip--active {
background: #f3e5f9;
color: #9C27B0;
border-color: #9C27B0;
font-weight: 600;
}
/* 表单字段 */
.field {
margin-bottom: 24rpx;

View File

@@ -0,0 +1,276 @@
import { createPage, request, ensureRoleOnCenterPage } from '../../utils/base-page.js';
import { getOrderStatusText } from '../../utils/api-helper.js';
const app = getApp();
/** 与订单页「全部」Tab 一致的状态筛选 */
const ALL_ORDER_ZHUANGTAI = [1, 2, 3, 4, 5, 6, 7, 8];
const RECENT_ORDER_SIZE = 5;
Page(createPage({
data: {
statusBar: 20,
navBar: 44,
isShangjia: false,
lunboList: [],
lunbozhanwei: '/images/lunbozhanwei.jpg',
gonggao: '',
swiperCurrent: 0,
imgUrls: {
noticeIco: 'https://bintao.xmxym88.com/xcx/bintao/38.png',
statCardBg: 'https://bintao.xmxym88.com/xcx/bintao/3.png',
kefuKeyBtn: 'https://bintao.xmxym88.com/xcx/bintao/13.png',
kefuListBtn: 'https://bintao.xmxym88.com/xcx/bintao/21.png',
},
stats: {
pendingCount: 0,
pendingAmount: '0.00',
todayDispatch: 0,
todayRefund: 0,
},
recentOrders: [],
recentLoading: false,
},
onLoad() {
const sys = wx.getSystemInfoSync();
this.setData({
statusBar: sys.statusBarHeight || 20,
navBar: (sys.statusBarHeight || 20) + 44,
lunbozhanwei: app.globalData.lunbozhanwei || '/images/lunbozhanwei.jpg',
});
this.checkRole();
this.waitForConfigAndLoadBanner();
this.checkColdStartPopup('shangjiaduan');
},
onShow() {
this.registerNotificationComponent();
this.checkRole();
if (this.data.isShangjia) {
ensureRoleOnCenterPage(this, 'shangjia');
this.loadDashboard();
}
this.loadBannerData();
},
onPullDownRefresh() {
Promise.all([
this.loadBannerData(true),
this.data.isShangjia ? this.loadDashboard() : Promise.resolve(),
]).finally(() => {
wx.stopPullDownRefresh();
});
},
waitForConfigAndLoadBanner() {
if (app.globalData.ossImageUrl || app.globalData.apiBaseUrl) {
this.loadBannerData(true);
return;
}
setTimeout(() => this.waitForConfigAndLoadBanner(), 100);
},
processImageUrls(urlList) {
if (!urlList || !Array.isArray(urlList)) return [];
const oss = app.globalData.ossImageUrl || '';
return urlList.map((url) => (url && url.startsWith('http') ? url : oss + url));
},
checkRole() {
const ok = Number(wx.getStorageSync('shangjiastatus')) === 1;
this.setData({ isShangjia: ok });
},
loadBannerData(forceFetch) {
const g = app.globalData || {};
const cachedList = g.shangpinlunbo || [];
if (!forceFetch && cachedList.length) {
this.setData({
lunboList: this.processImageUrls(cachedList),
gonggao: g.shangpingonggao || '',
lunbozhanwei: g.lunbozhanwei || this.data.lunbozhanwei,
});
return Promise.resolve();
}
if (!forceFetch && g.shangpingonggao) {
this.setData({
lunboList: this.processImageUrls(cachedList),
gonggao: g.shangpingonggao,
});
return Promise.resolve();
}
const apiBase = g.apiBaseUrl || '';
if (!apiBase) return Promise.resolve();
return new Promise((resolve) => {
wx.request({
url: `${apiBase}/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 || [];
this.setData({
lunboList: this.processImageUrls(app.globalData.shangpinlunbo),
gonggao: app.globalData.shangpingonggao,
});
}
},
complete: resolve,
});
});
},
async loadDashboard() {
await Promise.all([
this.loadShangjiaBrief(),
this.loadPendingStats(),
this.loadRecentOrders(),
]);
},
async loadShangjiaBrief() {
try {
const res = await request({
url: '/yonghu/shangjiaxinxi',
method: 'POST',
});
if (res.data && res.data.code === 200) {
const d = res.data.data || {};
app.globalData.shangjia = d;
this.setData({
stats: {
...this.data.stats,
todayDispatch: d.jinripaidan || 0,
todayRefund: d.jinrituikuan || 0,
},
});
}
} catch (e) {
console.error('商家信息加载失败', e);
}
},
async loadPendingStats() {
try {
const res = await request({
url: '/dingdan/sjdingdanhq',
method: 'POST',
data: { zhuangtai_list: [8], page: 1, page_size: 20 },
});
if (res.data && (res.data.code === 0 || res.data.code === 200)) {
const data = res.data.data || {};
const list = data.list || [];
let amount = 0;
list.forEach((item) => {
const v = parseFloat(item.jine || item.dingdan_jine || 0);
if (!Number.isNaN(v)) amount += v;
});
this.setData({
stats: {
...this.data.stats,
pendingCount: data.pending_count != null ? data.pending_count : list.length,
pendingAmount: amount.toFixed(2),
},
});
}
} catch (e) {
console.error('待结算统计失败', e);
}
},
/** 最近订单:同订单页「全部」筛选,取最新若干条 */
async loadRecentOrders() {
if (this.data.recentLoading) return;
this.setData({ recentLoading: true });
try {
const res = await request({
url: '/dingdan/sjdingdanhq',
method: 'POST',
data: {
zhuangtai_list: ALL_ORDER_ZHUANGTAI,
page: 1,
page_size: RECENT_ORDER_SIZE,
},
});
if (res.data && (res.data.code === 0 || res.data.code === 200)) {
const oss = app.globalData.ossImageUrl || '';
const list = (res.data.data.list || []).map((item) => {
let tupian = item.tupian || '';
if (tupian && !tupian.startsWith('http')) {
tupian = oss + tupian;
}
const raw = { ...item, tupian };
return {
dingdan_id: item.dingdan_id,
title: item.jieshao || '暂无描述',
time: item.create_time || '',
status: getOrderStatusText(item.zhuangtai),
money: item.jine || '0.00',
raw,
};
});
this.setData({ recentOrders: list });
}
} catch (e) {
console.error('最近订单加载失败', e);
} finally {
this.setData({ recentLoading: false });
}
},
onSwiperChange(e) {
this.setData({ swiperCurrent: e.detail.current });
},
goDispatch() {
wx.navigateTo({ url: '/pages/merchant-dispatch/merchant-dispatch' });
},
goExpress() {
wx.navigateTo({ url: '/pages/express-order/express-order' });
},
goOrdersTab() {
wx.redirectTo({ url: '/pages/merchant-orders/merchant-orders' });
},
goPendingOrders() {
wx.redirectTo({ url: '/pages/merchant-orders/merchant-orders' });
},
goOrderDetail(e) {
const index = e.currentTarget.dataset.index;
const row = this.data.recentOrders[index];
if (!row || !row.raw) return;
const dataStr = encodeURIComponent(JSON.stringify(row.raw));
wx.navigateTo({
url: `/pages/merchant-order-detail/merchant-order-detail?dingdanData=${dataStr}`,
});
},
goKefuKey() {
wx.navigateTo({ url: '/pages/merchant-kefu-key/merchant-kefu-key' });
},
goKefuList() {
wx.navigateTo({ url: '/pages/merchant-kefu-list/merchant-kefu-list' });
},
goMerchantProfile() {
wx.redirectTo({ url: '/pages/merchant/merchant' });
},
goRegister() {
wx.redirectTo({ url: '/pages/merchant/merchant' });
},
}, {
roleConfig: {
role: 'shangjia',
statusKey: 'shangjiastatus',
dataFlag: 'isShangjia',
pageId: 'shangjiaduan',
},
}));

View File

@@ -0,0 +1,11 @@
{
"navigationStyle": "custom",
"enablePullDownRefresh": true,
"backgroundColor": "#fff8e1",
"backgroundTextStyle": "dark",
"usingComponents": {
"global-notification": "/components/global-notification/global-notification",
"popup-notice": "/components/popup-notice/popup-notice",
"tab-bar": "/tab-bar/index"
}
}

View File

@@ -0,0 +1,120 @@
<!-- 商家中心首页 - 逍遥梦布局,功能/接口不变 -->
<view class="sj-page sj-page--home">
<view class="sj-page-header">
<view class="status-bar" style="height:{{statusBar}}px"></view>
<view class="nav-bar flexm" style="height:{{navBar - statusBar}}px">
<text class="sj-nav-title">商家中心</text>
</view>
</view>
<block wx:if="{{!isShangjia}}">
<view class="guest-box sj-mx20 sj-panel">
<text class="guest-title">商家入驻</text>
<text class="guest-desc">完成入驻后可发单、管理订单</text>
<view class="sj-btn-bg guest-btn flexm" bindtap="goRegister">去入驻</view>
</view>
<tab-bar/>
</block>
<block wx:else>
<view class="sj-main-body">
<view class="swiper-wrap" wx:if="{{lunboList.length}}">
<view class="swiper-con">
<swiper class="banner-swiper" autoplay circular interval="4000" duration="500" bindchange="onSwiperChange">
<swiper-item wx:for="{{lunboList}}" wx:key="index">
<image class="slide-image" src="{{item}}" mode="aspectFill"/>
</swiper-item>
</swiper>
<view class="dots flexm">
<view wx:for="{{lunboList}}" wx:key="index" class="dot {{swiperCurrent===index?'active':''}}"></view>
</view>
</view>
</view>
<view class="swiper-wrap" wx:else>
<image class="slide-image banner-placeholder" src="{{lunbozhanwei}}" mode="aspectFill"/>
</view>
<view class="sj-notice-bar" wx:if="{{gonggao}}">
<image class="notice-ico" src="{{imgUrls.noticeIco}}" mode="aspectFit"/>
<text class="sj-notice-txt">{{gonggao}}</text>
</view>
<view class="sj-fadan-row">
<view class="sj-fadan-img-btn sj-fadan-img-btn--left" bindtap="goExpress"/>
<view class="sj-fadan-img-btn sj-fadan-img-btn--right" bindtap="goDispatch"/>
</view>
<view class="merchant-stats shadow">
<view class="merchant-stats-bg" style="background-image:url({{imgUrls.statCardBg}})"></view>
<view class="merchant-stats-inner">
<view class="stats-hd flexb">
<text class="stats-hd-sp"></text>
<text class="stats-more" bindtap="goOrdersTab">查看更多</text>
</view>
<view class="stats-row flexa">
<view class="stat-col stat-col--l" bindtap="goPendingOrders">
<text class="stat-lbl">待结算订单(数)</text>
<text class="stat-num">{{stats.pendingCount}}</text>
</view>
<view class="stat-divider"></view>
<view class="stat-col stat-col--r">
<text class="stat-lbl">待结算金额(元)</text>
<text class="stat-num">{{stats.pendingAmount}}</text>
</view>
</view>
<view class="stats-row flexa stats-row--gap">
<view class="stat-col stat-col--l">
<text class="stat-lbl">今日派单(数)</text>
<text class="stat-num">{{stats.todayDispatch}}</text>
</view>
<view class="stat-divider"></view>
<view class="stat-col stat-col--r">
<text class="stat-lbl">今日退款(数)</text>
<text class="stat-num">{{stats.todayRefund}}</text>
</view>
</view>
<view class="stats-kefu-wrap">
<view class="kefu-row-inset flexm">
<view class="kefu-btn-inset" bindtap="goKefuKey">
<image class="kefu-inset-img" src="{{imgUrls.kefuKeyBtn}}" mode="widthFix"/>
</view>
<view class="kefu-btn-inset kefu-btn-inset--right" bindtap="goKefuList">
<image class="kefu-inset-img" src="{{imgUrls.kefuListBtn}}" mode="widthFix"/>
</view>
</view>
</view>
</view>
</view>
<view class="recent-box shadow">
<view class="recent-hd flexb">
<text class="recent-title">最近订单</text>
<text class="recent-more" bindtap="goOrdersTab">查看更多</text>
</view>
<view wx:if="{{recentLoading && !recentOrders.length}}" class="recent-empty">加载中...</view>
<block wx:elif="{{recentOrders.length}}">
<view
wx:for="{{recentOrders}}"
wx:key="dingdan_id"
class="recent-item flexb"
bindtap="goOrderDetail"
data-index="{{index}}"
>
<view class="recent-main">
<text class="recent-name line2">{{item.title}}</text>
<text class="recent-sub">{{item.time}} · {{item.status}}</text>
</view>
<text class="recent-money">¥{{item.money}}</text>
</view>
</block>
<view wx:else class="recent-empty">暂无最近订单</view>
</view>
<view class="sj-scroll-bottom"></view>
</view>
<tab-bar/>
</block>
<global-notification id="global-notification"/>
<popup-notice id="popupNotice"/>
</view>

View File

@@ -0,0 +1,309 @@
@import '../../styles/shangjia-xym-common.wxss';
page {
background: #fff8e1;
}
.sj-page--home {
overflow: visible;
padding-bottom: calc(110rpx + env(safe-area-inset-bottom));
}
.nav-bar {
display: flex;
align-items: center;
justify-content: center;
}
.guest-box {
margin-top: 80rpx;
padding: 48rpx 32rpx;
text-align: center;
}
.guest-title {
display: block;
font-size: 34rpx;
font-weight: 700;
color: #343434;
}
.guest-desc {
display: block;
font-size: 26rpx;
color: #888;
margin: 16rpx 0 32rpx;
}
.guest-btn {
height: 88rpx;
font-size: 30rpx;
}
.sj-main-body {
position: relative;
z-index: 3;
padding-bottom: 24rpx;
}
.swiper-wrap {
box-sizing: border-box;
overflow: hidden;
margin: 12rpx 24rpx 16rpx;
}
.swiper-con {
position: relative;
overflow: hidden;
}
.banner-swiper,
.slide-image,
.banner-placeholder {
width: 100%;
height: 300rpx;
border-radius: 20rpx;
}
.dots {
position: absolute;
bottom: 20rpx;
left: 50%;
transform: translateX(-50%);
z-index: 3;
gap: 10rpx;
}
.dot {
width: 8rpx;
height: 8rpx;
border-radius: 50%;
background: #fff;
transition: all 0.3s;
}
.dot.active {
width: 16rpx;
border-radius: 8rpx;
background: #ffd061;
}
.sj-notice-bar {
display: flex;
align-items: center;
background: #fdf9db;
margin: 0 24rpx;
border-radius: 10rpx;
padding: 10rpx 16rpx;
}
.notice-ico {
width: 56rpx;
height: 56rpx;
flex-shrink: 0;
margin-right: 12rpx;
}
.sj-notice-txt {
font-size: 24rpx;
color: #666;
line-height: 1.5;
flex: 1;
}
.sj-fadan-row {
display: flex;
margin: 24rpx 20rpx 0;
padding: 10rpx;
gap: 8rpx;
}
.sj-fadan-img-btn {
flex: 1;
height: 150rpx;
background-size: 100% 100%;
background-repeat: no-repeat;
}
.sj-fadan-img-btn--left {
background-image: url('https://bintao.xmxym88.com/xcx/bintao/74.png');
margin-right: 8rpx;
}
.sj-fadan-img-btn--right {
background-image: url('https://bintao.xmxym88.com/xcx/bintao/76.png');
margin-left: 8rpx;
}
.merchant-stats {
margin: 32rpx 25rpx 0;
border-radius: 26rpx;
padding-bottom: 24rpx;
position: relative;
overflow: hidden;
background: #fff;
box-shadow: 0 6rpx 22rpx rgba(0, 0, 0, 0.08);
}
.merchant-stats-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-size: 100% auto;
background-repeat: no-repeat;
pointer-events: none;
z-index: 0;
}
.merchant-stats-inner {
position: relative;
z-index: 2;
padding: 0 0 10rpx;
}
.stats-hd {
padding: 24rpx 25rpx 10rpx;
}
.stats-hd-sp {
flex: 1;
}
.stats-more {
font-size: 28rpx;
font-weight: 700;
color: #fff;
}
.stats-row {
align-items: stretch;
background: #fff;
border-radius: 20rpx;
margin: 0 16rpx;
}
.stats-row--gap {
margin-top: 12rpx;
}
.stat-col {
flex: 1;
min-width: 0;
padding: 36rpx 24rpx;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.stat-lbl {
font-size: 24rpx;
color: #666;
opacity: 0.85;
margin-bottom: 12rpx;
}
.stat-num {
font-size: 44rpx;
font-weight: 700;
color: #222;
}
.stat-divider {
width: 2rpx;
background: #eee;
height: 80rpx;
align-self: center;
flex-shrink: 0;
}
.stats-kefu-wrap {
margin: 20rpx 24rpx 0;
}
.kefu-row-inset {
align-items: flex-start;
width: 100%;
gap: 20rpx;
}
.kefu-btn-inset {
flex: 1;
line-height: 0;
}
.kefu-inset-img {
width: 100%;
display: block;
}
.recent-box {
margin: 28rpx 24rpx 0;
border-radius: 26rpx;
background: #fff;
padding-bottom: 10rpx;
box-shadow: 0 6rpx 22rpx rgba(0, 0, 0, 0.06);
}
.recent-hd {
padding: 24rpx;
}
.recent-title {
font-size: 32rpx;
font-weight: 700;
color: #222;
}
.recent-more {
font-size: 24rpx;
color: #999;
}
.recent-item {
padding: 20rpx 24rpx;
border-top: 1rpx solid #f0f0f0;
align-items: center;
}
.recent-name {
font-size: 28rpx;
font-weight: 700;
color: #333;
}
.recent-sub {
font-size: 22rpx;
color: #999;
margin-top: 8rpx;
display: block;
}
.recent-money {
font-size: 30rpx;
color: #e67e22;
font-weight: 700;
flex-shrink: 0;
margin-left: 16rpx;
}
.recent-main {
flex: 1;
min-width: 0;
}
.recent-empty {
text-align: center;
padding: 48rpx;
font-size: 26rpx;
color: #999;
}
.line2 {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}

View File

@@ -0,0 +1,60 @@
/** 客服邀请码/秘钥 - UI 预览,后端接入前使用 mock 数据 */
Page({
data: {
statusBar: 20,
gudingCode: 'XQKF2026',
kefuTips: '客服秘钥用于绑定子客服账号,后端接口就绪后将自动替换为真实数据。',
sublist: [{ name: '全部' }, { name: '未使用' }, { name: '已使用' }],
subCurrent: 0,
list: [
{ id: 1, typeName: '财务', code: 'CW-8X2K9P', status: 0, adddate: '2026-06-10' },
{ id: 2, typeName: '总管', code: 'ZG-3M7N1Q', status: 1, adddate: '2026-06-08', usedate: '2026-06-12', user: { nickname: '客服小张', avatar: '/images/default-avatar.png' } },
],
showQrcodeTips: false,
},
onLoad() {
const sys = wx.getSystemInfoSync();
this.setData({ statusBar: sys.statusBarHeight || 20 });
},
goBack() {
wx.navigateBack();
},
copyFixed() {
wx.setClipboardData({ data: this.data.gudingCode });
},
switchSub(e) {
this.setData({ subCurrent: Number(e.currentTarget.dataset.idx) });
},
addKey() {
wx.showToast({ title: '后端接入后可添加', icon: 'none' });
},
copyCode(e) {
wx.setClipboardData({ data: e.currentTarget.dataset.code || '' });
},
delKey() {
wx.showToast({ title: '预览数据不可删除', icon: 'none' });
},
showTips() {
this.setData({ showQrcodeTips: true });
},
closeTips() {
this.setData({ showQrcodeTips: false });
},
previewQr() {
wx.previewImage({
urls: ['https://xy-1314784552.cos.ap-guangzhou.myqcloud.com/uploads/images/ewm.png'],
});
},
noop() {},
});

View File

@@ -0,0 +1,5 @@
{
"navigationStyle": "custom",
"backgroundColor": "#fff8e1",
"usingComponents": {}
}

View File

@@ -0,0 +1,69 @@
<view class="sub-page pagebg">
<image class="page-bg-img" src="https://bintao.xmxym88.com/xcx/static/images/bg.png" mode="widthFix"/>
<view class="page-body">
<view class="status-bar" style="height:{{statusBar}}px"></view>
<view class="nav-bar flexb">
<text class="back" bindtap="goBack"></text>
<text class="nav-title">邀请码</text>
<text class="back placeholder"></text>
</view>
<scroll-view scroll-y class="list-scroll" show-scrollbar="{{false}}">
<view wx:if="{{gudingCode}}" class="fixed-code-card flexb">
<view class="fixed-code-main">
<text class="fixed-code-lbl">固定邀请码:</text>
<text class="fixed-code-val">{{gudingCode}}</text>
</view>
<view class="copy-btn" bindtap="copyFixed">复制</view>
</view>
<view wx:if="{{kefuTips}}" class="tips-bar">{{kefuTips}}</view>
<view class="toolbar flexb">
<view class="sub-tabs flexa">
<view wx:for="{{sublist}}" wx:key="name" class="sub-tab {{subCurrent==index?'on':''}}" data-idx="{{index}}" bindtap="switchSub">{{item.name}}</view>
</view>
<view class="add-btn" bindtap="addKey">添加</view>
</view>
<view class="help-row flexb" bindtap="showTips">
<text class="help-link">秘钥使用方法</text>
<text class="help-arrow"></text>
</view>
<view wx:for="{{list}}" wx:key="id" class="key-item">
<view class="key-row flexb">
<view class="tag-type">{{item.typeName}}</view>
<view class="key-code" bindtap="copyCode" data-code="{{item.code}}">{{item.code}}</view>
<view class="status-txt {{item.status==0?'unused':'used'}}">{{item.status==0?'未使用':'已使用'}}</view>
</view>
<view class="key-meta">生成日期:{{item.adddate}}</view>
<view wx:if="{{item.status==1}}" class="key-meta">使用日期:{{item.usedate}}</view>
<view wx:if="{{item.user.nickname}}" class="key-user flex">
<image class="user-av" src="{{item.user.avatar}}" mode="aspectFill"/>
<text>使用人:{{item.user.nickname}}</text>
</view>
<view class="key-actions flexb">
<text class="act-copy" bindtap="copyCode" data-code="{{item.code}}">复制秘钥</text>
<text class="act-del" bindtap="delKey" data-id="{{item.id}}">删除</text>
</view>
</view>
<view wx:if="{{!list.length}}" class="empty-tip">暂无卡密</view>
<view class="load-tip">预览 · 接口就绪后对接真实数据</view>
</scroll-view>
</view>
<view wx:if="{{showQrcodeTips}}" class="mask" bindtap="closeTips">
<view class="popup" catchtap="noop">
<view class="popup-title">秘钥使用方法</view>
<scroll-view scroll-y class="popup-scroll">
<view class="popup-txt">把秘钥发给客服,用户扫下方二维码输入秘钥即可绑定。</view>
<view class="qr-wrap">
<image class="qr-img" src="https://xy-1314784552.cos.ap-guangzhou.myqcloud.com/uploads/images/ewm.png" mode="widthFix" bindtap="previewQr"/>
</view>
</scroll-view>
<view class="popup-close" bindtap="closeTips">关闭</view>
</view>
</view>
</view>

View File

@@ -0,0 +1,335 @@
.pagebg {
min-height: 100vh;
background: #f5f5f5;
position: relative;
overflow: hidden;
}
.page-bg-img {
width: 100%;
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
z-index: 0;
max-height: 420rpx;
}
.page-body {
position: relative;
z-index: 2;
display: flex;
flex-direction: column;
min-height: 100vh;
box-sizing: border-box;
}
.status-bar,
.nav-bar {
flex-shrink: 0;
}
.nav-bar {
padding: 0 24rpx;
height: 88rpx;
align-items: center;
}
.nav-title {
font-size: 34rpx;
font-weight: 700;
color: #343434;
}
.back {
width: 60rpx;
font-size: 48rpx;
color: #333;
}
.back.placeholder {
opacity: 0;
}
.flex { display: flex; align-items: center; }
.flexb { display: flex; align-items: center; justify-content: space-between; }
.flexa { display: flex; align-items: center; justify-content: space-around; }
.list-scroll {
flex: 1;
height: calc(100vh - 88rpx);
padding: 0 20rpx 30rpx;
box-sizing: border-box;
}
.fixed-code-card {
background: #fff;
border-radius: 20rpx;
padding: 24rpx;
margin: 10rpx 0 16rpx;
align-items: center;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
}
.fixed-code-main {
flex: 1;
min-width: 0;
}
.fixed-code-lbl {
font-size: 28rpx;
color: #333;
font-weight: 700;
}
.fixed-code-val {
display: block;
margin-top: 8rpx;
font-size: 32rpx;
color: #f00;
font-weight: 700;
word-break: break-all;
}
.copy-btn {
padding: 16rpx 32rpx;
min-height: 64rpx;
border-radius: 10rpx;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492f00;
font-size: 28rpx;
font-weight: 700;
flex-shrink: 0;
margin-left: 16rpx;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
.tips-bar {
background: #fff7e6;
border: 1rpx solid #ffd591;
border-radius: 12rpx;
padding: 18rpx 20rpx;
font-size: 26rpx;
color: #ad6800;
line-height: 1.5;
margin-bottom: 16rpx;
}
.toolbar {
margin-bottom: 12rpx;
padding: 6rpx 0;
align-items: center;
}
.sub-tabs {
flex: 1;
background: #fff;
border-radius: 12rpx;
padding: 6rpx;
}
.sub-tab {
padding: 16rpx 24rpx;
font-size: 26rpx;
color: #666;
border-radius: 8rpx;
}
.sub-tab.on {
background: #1b6ef3;
color: #fff;
}
.add-btn {
margin-left: 16rpx;
padding: 16rpx 32rpx;
min-height: 64rpx;
background: #1b6ef3;
color: #fff;
border-radius: 10rpx;
font-size: 28rpx;
font-weight: 700;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
.help-row {
background: #fff;
border-radius: 12rpx;
padding: 22rpx 24rpx;
margin-bottom: 16rpx;
align-items: center;
}
.help-link {
font-size: 28rpx;
color: #1b6ef3;
font-weight: 700;
}
.help-arrow {
font-size: 36rpx;
color: #999;
}
.key-item {
background: #fff;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
}
.key-row {
align-items: flex-start;
margin-bottom: 10rpx;
}
.tag-type {
font-size: 22rpx;
color: #fff;
background: #1b6ef3;
padding: 6rpx 14rpx;
border-radius: 6rpx;
margin-right: 12rpx;
flex-shrink: 0;
}
.key-code {
flex: 1;
font-size: 30rpx;
font-weight: 700;
color: #333;
word-break: break-all;
padding-right: 12rpx;
}
.status-txt {
font-size: 24rpx;
flex-shrink: 0;
}
.status-txt.unused { color: #0a0; }
.status-txt.used { color: #aaa; }
.key-meta {
font-size: 24rpx;
color: #aaa;
margin-top: 8rpx;
}
.key-user {
align-items: center;
margin-top: 10rpx;
font-size: 24rpx;
color: #666;
}
.user-av {
width: 48rpx;
height: 48rpx;
border-radius: 50%;
margin-right: 10rpx;
}
.key-actions {
margin-top: 16rpx;
padding-top: 16rpx;
border-top: 1rpx dashed #eee;
}
.act-copy,
.act-del {
font-size: 28rpx;
padding: 12rpx 24rpx;
border-radius: 8rpx;
}
.act-copy {
color: #007aff;
background: #eef6ff;
}
.act-del {
color: #fff;
background: #f56c6c;
}
.empty-tip {
text-align: center;
color: #999;
padding: 80rpx 0;
font-size: 28rpx;
}
.load-tip {
text-align: center;
padding: 32rpx;
font-size: 22rpx;
color: #bbb;
}
.mask {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.45);
z-index: 99;
display: flex;
align-items: flex-end;
}
.popup {
width: 100%;
background: #fff;
border-radius: 26rpx 26rpx 0 0;
padding-bottom: calc(30rpx + env(safe-area-inset-bottom));
}
.popup-title {
font-size: 32rpx;
font-weight: 700;
padding: 30rpx;
}
.popup-scroll {
max-height: 60vh;
padding: 0 30rpx;
box-sizing: border-box;
}
.popup-txt {
font-size: 28rpx;
line-height: 1.6;
color: #333;
}
.qr-wrap {
background: #f9f9f9;
margin-top: 30rpx;
text-align: center;
padding: 20rpx;
}
.qr-img {
width: 100%;
}
.popup-close {
margin: 20rpx 30rpx 0;
text-align: center;
padding: 24rpx;
background: #1b6ef3;
color: #fff;
border-radius: 12rpx;
font-size: 30rpx;
font-weight: 700;
}

View File

@@ -0,0 +1,47 @@
/** 客服列表 - UI 预览mock 数据 */
Page({
data: {
statusBar: 20,
list: [
{
id: 1,
nickname: '客服总管-阿星',
avatar: '/images/default-avatar.png',
uid: '1008601',
isChief: true,
isFinance: false,
orderCount: 128,
settleCount: 96,
settleAmount: '12800.00',
},
{
id: 2,
nickname: '财务-小李',
avatar: '/images/default-avatar.png',
uid: '1008602',
isChief: false,
isFinance: true,
orderCount: 56,
settleCount: 52,
settleAmount: '6800.00',
},
],
},
onLoad() {
const sys = wx.getSystemInfoSync();
this.setData({ statusBar: sys.statusBarHeight || 20 });
},
goBack() {
wx.navigateBack();
},
copyUid(e) {
wx.setClipboardData({ data: e.currentTarget.dataset.uid || '' });
},
onAction(e) {
wx.showToast({ title: '后端接入后生效', icon: 'none' });
},
});

View File

@@ -0,0 +1,5 @@
{
"navigationStyle": "custom",
"backgroundColor": "#fff8e1",
"usingComponents": {}
}

View File

@@ -0,0 +1,47 @@
<view class="sub-page sj-page">
<view class="status-bar" style="height:{{statusBar}}px"></view>
<view class="sub-nav flexb">
<text class="back" bindtap="goBack"></text>
<text class="sub-nav-title">客服列表</text>
<text class="back placeholder"></text>
</view>
<scroll-view scroll-y class="sub-scroll" enhanced show-scrollbar="{{false}}">
<view wx:for="{{list}}" wx:key="id" class="kefu-card sj-mx20">
<view class="kefu-head flex">
<image class="kefu-av" src="{{item.avatar}}" mode="aspectFill"/>
<view class="kefu-info">
<view class="flex">
<text class="kefu-name">{{item.nickname}}</text>
<text wx:if="{{item.isChief}}" class="badge badge-chief">总管</text>
<text wx:if="{{item.isFinance}}" class="badge badge-finance">财务</text>
</view>
<view class="uid-row flex">
<text class="kefu-uid">ID: {{item.uid}}</text>
<text class="copy-link" bindtap="copyUid" data-uid="{{item.uid}}">复制</text>
</view>
</view>
</view>
<view class="kefu-stats flexa">
<view class="stat-box flexmc">
<text class="stat-n">{{item.orderCount}}</text>
<text class="stat-l">接单数</text>
</view>
<view class="stat-box flexmc">
<text class="stat-n">{{item.settleCount}}</text>
<text class="stat-l">结算数</text>
</view>
<view class="stat-box flexmc">
<text class="stat-n">¥{{item.settleAmount}}</text>
<text class="stat-l">结算金额</text>
</view>
</view>
<view class="kefu-actions flexa">
<text class="act" bindtap="onAction">查看订单</text>
<text class="act" bindtap="onAction">权限管理</text>
<text class="act act-del" bindtap="onAction">删除</text>
</view>
</view>
<view class="load-tip">预览 · 接口就绪后对接真实数据</view>
</scroll-view>
</view>

View File

@@ -0,0 +1,109 @@
@import '../../styles/shangjia-xym-common.wxss';
.sub-nav {
padding: 0 24rpx 12rpx;
}
.back {
width: 60rpx;
font-size: 48rpx;
color: #333;
}
.back.placeholder { opacity: 0; }
.sub-nav-title {
font-size: 34rpx;
font-weight: 700;
color: #343434;
}
.sub-scroll {
height: calc(100vh - 120rpx);
}
.kefu-card {
background: #fff;
border-radius: 20rpx;
padding: 24rpx;
margin-bottom: 16rpx;
margin-top: 12rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
}
.kefu-av {
width: 88rpx;
height: 88rpx;
border-radius: 50%;
margin-right: 16rpx;
background: #eee;
}
.kefu-name {
font-size: 30rpx;
font-weight: 700;
color: #333;
}
.badge {
margin-left: 8rpx;
font-size: 20rpx;
padding: 2rpx 10rpx;
border-radius: 6rpx;
color: #fff;
}
.badge-chief { background: #ffb508; }
.badge-finance { background: #1b6ef3; }
.kefu-uid {
font-size: 24rpx;
color: #999;
margin-top: 8rpx;
}
.copy-link {
margin-left: 12rpx;
font-size: 22rpx;
color: #1b6ef3;
}
.kefu-stats {
margin-top: 20rpx;
padding: 16rpx 0;
border-top: 1rpx solid #f5f5f5;
border-bottom: 1rpx solid #f5f5f5;
}
.stat-n {
font-size: 28rpx;
font-weight: 700;
color: #e67e22;
}
.stat-l {
font-size: 22rpx;
color: #999;
margin-top: 4rpx;
}
.kefu-actions {
margin-top: 16rpx;
gap: 24rpx;
}
.act {
font-size: 24rpx;
color: #1b6ef3;
}
.act-del {
color: #e64340;
}
.load-tip {
text-align: center;
padding: 32rpx;
font-size: 22rpx;
color: #bbb;
}

View File

@@ -1,242 +1,288 @@
// pages/shangjiazhongxin/shangjiiazhongxin.js
import { createPage, ensureRoleOnCenterPage, lockPrimaryRole, parseSceneOptions } from '../../utils/base-page.js';
import { ensureLogin } from '../../utils/login.js';
const app = getApp();
Page(createPage({
data: {
// 图片资源
imgUrls: {
pageBg: '',
avatarCardBg: '',
assetCardBg: '',
statCardBg: '',
funcItemBg: '',
primaryFuncBg: '',
highlightFuncBg: '',
iconRelease: '',
iconFast: '',
iconOrders: '',
iconService: '',
iconPunish: '',
iconRank: '',
iconRecharge: '',
iconWithdraw: '',
iconRefresh: '',
iconCopy: '',
avatarFrame: '',
iconClear: '',
},
// 商家状态
isShangjia: false,
isAutoRegistering: false,
// 用户基础信息
uid: '',
avatarUrl: '',
nicheng: '',
// 商家核心数据
sjyue: '0.00',
fabu: 0,
tuikuan: 0,
jinriliushui: '0.00',
jinyueliushui: '0.00',
jinridingdan: 0,
jinrituikuan: 0,
chenghaoList: [],
// 交互控制
inviteCode: '',
},
onLoad(options) {
const parsed = parseSceneOptions(options);
this.setupImageUrls();
this.checkRoleStatus();
const inviteCode = parsed.inviteCode;
if (inviteCode) {
this.setData({ inviteCode });
setTimeout(() => this.handleInviteCodeWithLoginCheck({
inviteCode,
role: 'shangjia',
statusKey: 'shangjiastatus',
alreadyMsg: '您已是商家',
onNeedLogin: (code) => {
this.setData({ inviteCode: code });
ensureLogin({ silent: false, page: this })
.then(() => {
if (!this.data.isShangjia) {
wx.showLoading({ title: '商家注册中...', mask: true });
this.setData({ isAutoRegistering: true });
this.onRegister();
}
})
.catch(() => {});
},
onAlreadyRegistered: () => {
wx.showToast({ title: '您已是商家', icon: 'success' });
ensureRoleOnCenterPage(this, 'shangjia');
},
}), 500);
}
this.checkColdStartPopup('shangjiaduan');
},
onShow() {
this.registerNotificationComponent();
if (this.data.isShangjia) {
ensureRoleOnCenterPage(this, 'shangjia');
this.refreshShangjiaInfo();
}
},
// 图片路径初始化
setupImageUrls() {
const ossBase = app.globalData.ossImageUrl || '';
const imgDir = `${ossBase}beijing/shangjiaduan/`;
this.setData({
imgUrls: this.initImageUrls({
pageBg: `${imgDir}page_bg.png`,
avatarCardBg: `${imgDir}avatar_card_bg.png`,
assetCardBg: `${imgDir}asset_card_bg.png`,
statCardBg: `${imgDir}stat_card_bg.png`,
funcItemBg: `${imgDir}func_item_bg.png`,
primaryFuncBg: `${imgDir}primary_func_bg.png`,
highlightFuncBg: `${imgDir}highlight_func_bg.png`,
iconRelease: `${imgDir}icon_release.png`,
iconFast: `${imgDir}icon_fast.png`,
iconOrders: `${imgDir}icon_orders.png`,
iconService: `${imgDir}icon_service.png`,
iconPunish: `${imgDir}icon_punish.png`,
iconRank: `${imgDir}icon_rank.png`,
iconRecharge: `${imgDir}icon_recharge.png`,
iconWithdraw: `${imgDir}icon_withdraw.png`,
iconRefresh: `${imgDir}icon_refresh.png`,
iconCopy: `${imgDir}icon_copy.png`,
avatarFrame: `${imgDir}avatar_frame.png`,
iconClear: `${ossBase}beijing/tubiao/grzx_qingchu.jpg`,
iconSwitch: '/images/_exit.png',
})
});
},
// 商家状态检查(覆盖基类 checkRoleStatus增加 getShangjiaInfo 调用)
checkRoleStatus() {
try {
const shangjiastatus = wx.getStorageSync('shangjiastatus');
const uid = wx.getStorageSync('uid');
if (shangjiastatus) {
this.setData({ isShangjia: true, uid: uid || '' });
this.loadAvatar();
this.getShangjiaInfo();
ensureRoleOnCenterPage(this, 'shangjia');
} else {
this.setData({ isShangjia: false });
}
} catch (error) {
console.error('读取商家状态失败', error);
this.setData({ isShangjia: false });
}
},
// 获取商家信息
async getShangjiaInfo() {
await this.loadData({
url: '/yonghu/shangjiaxinxi',
method: 'POST',
successCode: 200,
errorMsg: '取商家信息失败',
onSuccess: (data) => {
// 更新全局缓存
app.globalData.shangjia = data;
wx.setStorageSync('shangjiastatus', 1);
const chenghaoList = data.chenghao_list || [];
this.setData({
nicheng: data.nicheng || '',
sjyue: data.sjyue || '0.00',
fabu: data.fadanzong || 0,
tuikuan: data.tuikuanzong || 0,
jinriliushui: data.riliushui || '0.00',
jinyueliushui: data.yueliushui || '0.00',
jinridingdan: data.jinripaidan || 0,
jinrituikuan: data.jinrituikuan || 0,
chenghaoList: chenghaoList,
isLoading: false,
});
if (this.data.isAutoRegistering) {
this.setData({ isAutoRegistering: false });
wx.showToast({ title: '商家注册成功', icon: 'success' });
}
},
});
},
refreshShangjiaInfo() {
this.throttledRefresh(() => this.getShangjiaInfo());
},
async onRegister() {
const { inviteCode } = this.data;
await this.registerWithInviteCode({
inviteCode,
apiUrl: '/yonghu/shangjiahuce',
role: 'shangjia',
statusKey: 'shangjiastatus',
successMsg: '商家注册成功',
onSuccess: (userData) => {
app.globalData.shangjia = userData;
const chenghaoList = userData.chenghao_list || [];
this.setData({
isShangjia: true,
nicheng: userData.nicheng || '',
sjyue: userData.sjyue || '0.00',
fabu: userData.fabu || 0,
tuikuan: userData.tuikuan || 0,
jinriliushui: userData.jinriliushui || '0.00',
jinyueliushui: userData.jinyueliushui || '0.00',
jinridingdan: userData.jinridingdan || 0,
chenghaoList: chenghaoList,
isAutoRegistering: false,
});
this.loadAvatar();
ensureRoleOnCenterPage(this, 'shangjia');
lockPrimaryRole('shangjia');
},
});
},
previewAvatar() {
if (this.data.avatarUrl) {
wx.previewImage({ urls: [this.data.avatarUrl] });
}
},
// 页面跳转
goToPaiDan() { wx.navigateTo({ url: '/pages/merchant-dispatch/merchant-dispatch' }); },
goToJiSuPaiDan() {
wx.vibrateShort({ type: 'medium' });
wx.navigateTo({ url: '/pages/express-order/express-order' });
},
goToMyOrders() { wx.navigateTo({ url: '/pages/merchant-orders/merchant-orders' }); },
goToRecharge() { wx.navigateTo({ url: '/pages/merchant-recharge/merchant-recharge' }); },
goToWithdraw() { wx.navigateTo({ url: '/pages/withdraw/withdraw' }); },
goToRanking() { wx.navigateTo({ url: '/pages/fighter-rank/fighter-rank?type=shangjia' }); },
goToMessages() { wx.navigateTo({ url: '/pages/merchant-msg/merchant-msg' }); },
}, {
roleConfig: {
role: 'shangjia',
statusKey: 'shangjiastatus',
dataFlag: 'isShangjia',
pageId: 'shangjiaduan',
apiUrl: '/yonghu/shangjiaxinxi',
},
}));
// pages/shangjiazhongxin/shangjiiazhongxin.js
import { createPage, ensureRoleOnCenterPage, lockPrimaryRole, parseSceneOptions, request } from '../../utils/base-page.js';
import { ensureLogin } from '../../utils/login.js';
const app = getApp();
Page(createPage({
data: {
// 图片资源
imgUrls: {
pageBg: '',
avatarCardBg: '',
assetCardBg: '',
statCardBg: '',
funcItemBg: '',
primaryFuncBg: '',
highlightFuncBg: '',
iconRelease: '',
iconFast: '',
iconOrders: '',
iconService: '',
iconPunish: '',
iconRank: '',
iconRecharge: '',
iconWithdraw: '',
iconRefresh: '',
iconCopy: '',
avatarFrame: '',
iconClear: '',
},
// 商家状态
isShangjia: false,
isAutoRegistering: false,
// 用户基础信息
uid: '',
avatarUrl: '',
nicheng: '',
// 商家核心数据
sjyue: '0.00',
fabu: 0,
tuikuan: 0,
jinriliushui: '0.00',
jinyueliushui: '0.00',
jinridingdan: 0,
jinrituikuan: 0,
chenghaoList: [],
// 交互控制
inviteCode: '',
pendingCount: 0,
punishPending: 0,
statusBar: 20,
navBar: 44,
},
onLoad(options) {
const sys = wx.getSystemInfoSync();
this.setData({
statusBar: sys.statusBarHeight || 20,
navBar: (sys.statusBarHeight || 20) + 44,
});
const parsed = parseSceneOptions(options);
this.setupImageUrls();
this.checkRoleStatus();
const inviteCode = parsed.inviteCode;
if (inviteCode) {
this.setData({ inviteCode });
setTimeout(() => this.handleInviteCodeWithLoginCheck({
inviteCode,
role: 'shangjia',
statusKey: 'shangjiastatus',
alreadyMsg: '您已是商家',
onNeedLogin: (code) => {
this.setData({ inviteCode: code });
ensureLogin({ silent: false, page: this })
.then(() => {
if (!this.data.isShangjia) {
wx.showLoading({ title: '商家注册中...', mask: true });
this.setData({ isAutoRegistering: true });
this.onRegister();
}
})
.catch(() => {});
},
onAlreadyRegistered: () => {
wx.showToast({ title: '您已是商家', icon: 'success' });
ensureRoleOnCenterPage(this, 'shangjia');
},
}), 500);
}
this.checkColdStartPopup('shangjiaduan');
},
onShow() {
this.registerNotificationComponent();
if (this.data.isShangjia) {
ensureRoleOnCenterPage(this, 'shangjia');
this.refreshShangjiaInfo();
this.loadPendingCount();
this.loadPunishPending();
}
},
// 图片路径初始化
setupImageUrls() {
const ossBase = app.globalData.ossImageUrl || '';
const imgDir = `${ossBase}beijing/shangjiaduan/`;
this.setData({
imgUrls: this.initImageUrls({
pageBg: `${imgDir}page_bg.png`,
avatarCardBg: `${imgDir}avatar_card_bg.png`,
assetCardBg: `${imgDir}asset_card_bg.png`,
statCardBg: `${imgDir}stat_card_bg.png`,
funcItemBg: `${imgDir}func_item_bg.png`,
primaryFuncBg: `${imgDir}primary_func_bg.png`,
highlightFuncBg: `${imgDir}highlight_func_bg.png`,
iconRelease: `${imgDir}icon_release.png`,
iconFast: `${imgDir}icon_fast.png`,
iconOrders: `${imgDir}icon_orders.png`,
iconService: `${imgDir}icon_service.png`,
iconPunish: `${imgDir}icon_punish.png`,
iconRank: `${imgDir}icon_rank.png`,
iconRecharge: `${imgDir}icon_recharge.png`,
iconWithdraw: `${imgDir}icon_withdraw.png`,
iconRefresh: `${imgDir}icon_refresh.png`,
iconCopy: `${imgDir}icon_copy.png`,
avatarFrame: `${imgDir}avatar_frame.png`,
iconClear: `${ossBase}beijing/tubiao/grzx_qingchu.jpg`,
iconSwitch: '/images/_exit.png',
})
});
},
// 商家状态检查(覆盖基类 checkRoleStatus增加 getShangjiaInfo 调用)
checkRoleStatus() {
try {
const shangjiastatus = wx.getStorageSync('shangjiastatus');
const uid = wx.getStorageSync('uid');
if (shangjiastatus) {
this.setData({ isShangjia: true, uid: uid || '' });
this.loadAvatar();
this.getShangjiaInfo();
ensureRoleOnCenterPage(this, 'shangjia');
} else {
this.setData({ isShangjia: false });
}
} catch (error) {
console.error('取商家状态失败', error);
this.setData({ isShangjia: false });
}
},
// 获取商家信息
async getShangjiaInfo() {
await this.loadData({
url: '/yonghu/shangjiaxinxi',
method: 'POST',
successCode: 200,
errorMsg: '获取商家信息失败',
onSuccess: (data) => {
// 更新全局缓存
app.globalData.shangjia = data;
wx.setStorageSync('shangjiastatus', 1);
const chenghaoList = data.chenghao_list || [];
this.setData({
nicheng: data.nicheng || '',
sjyue: data.sjyue || '0.00',
fabu: data.fadanzong || 0,
tuikuan: data.tuikuanzong || 0,
jinriliushui: data.riliushui || '0.00',
jinyueliushui: data.yueliushui || '0.00',
jinridingdan: data.jinripaidan || 0,
jinrituikuan: data.jinrituikuan || 0,
chenghaoList: chenghaoList,
isLoading: false,
});
if (this.data.isAutoRegistering) {
this.setData({ isAutoRegistering: false });
wx.showToast({ title: '商家注册成功', icon: 'success' });
}
},
});
},
refreshShangjiaInfo() {
this.throttledRefresh(() => this.getShangjiaInfo());
},
async loadPendingCount() {
try {
const res = await request({
url: '/dingdan/sjdingdanhq',
method: 'POST',
data: { zhuangtai_list: [8], page: 1, page_size: 1 },
});
if (res && res.data && (res.data.code === 0 || res.data.code === 200)) {
this.setData({ pendingCount: res.data.data.pending_count || 0 });
}
} catch (e) {
console.error('待结算数量失败', e);
}
},
async loadPunishPending() {
try {
const res = await request({
url: '/yonghu/sjcfjlhq',
method: 'POST',
data: { page: 1, page_size: 1, zhuangtai: 0 },
});
if (res && res.data && (res.data.code === 0 || res.data.code === 200)) {
const d = res.data.data || {};
this.setData({ punishPending: d.daichuli_count || d.pending_count || 0 });
}
} catch (e) {
/* 接口字段未定时静默 */
}
},
async onRegister() {
const { inviteCode } = this.data;
await this.registerWithInviteCode({
inviteCode,
apiUrl: '/yonghu/shangjiahuce',
role: 'shangjia',
statusKey: 'shangjiastatus',
successMsg: '商家注册成功',
onSuccess: (userData) => {
app.globalData.shangjia = userData;
const chenghaoList = userData.chenghao_list || [];
this.setData({
isShangjia: true,
nicheng: userData.nicheng || '',
sjyue: userData.sjyue || '0.00',
fabu: userData.fabu || 0,
tuikuan: userData.tuikuan || 0,
jinriliushui: userData.jinriliushui || '0.00',
jinyueliushui: userData.jinyueliushui || '0.00',
jinridingdan: userData.jinridingdan || 0,
chenghaoList: chenghaoList,
isAutoRegistering: false,
});
this.loadAvatar();
ensureRoleOnCenterPage(this, 'shangjia');
lockPrimaryRole('shangjia');
},
});
},
previewAvatar() {
if (this.data.avatarUrl) {
wx.previewImage({ urls: [this.data.avatarUrl] });
}
},
// 页面跳转
goToPaiDan() { wx.navigateTo({ url: '/pages/merchant-dispatch/merchant-dispatch' }); },
goToJiSuPaiDan() {
wx.vibrateShort({ type: 'medium' });
wx.navigateTo({ url: '/pages/express-order/express-order' });
},
goToMyOrders() { wx.redirectTo({ url: '/pages/merchant-orders/merchant-orders' }); },
goToPendingOrders() { wx.redirectTo({ url: '/pages/merchant-orders/merchant-orders' }); },
goToHome() { wx.redirectTo({ url: '/pages/merchant-home/merchant-home' }); },
goToKefuKey() { wx.navigateTo({ url: '/pages/merchant-kefu-key/merchant-kefu-key' }); },
goToKefuList() { wx.navigateTo({ url: '/pages/merchant-kefu-list/merchant-kefu-list' }); },
goToRecharge() { wx.navigateTo({ url: '/pages/merchant-recharge/merchant-recharge' }); },
goToWithdraw() { wx.navigateTo({ url: '/pages/withdraw/withdraw' }); },
goToRanking() { wx.navigateTo({ url: '/pages/fighter-rank/fighter-rank?type=shangjia' }); },
goToMessages() { wx.navigateTo({ url: '/pages/merchant-msg/merchant-msg' }); },
}, {
roleConfig: {
role: 'shangjia',
statusKey: 'shangjiastatus',
dataFlag: 'isShangjia',
pageId: 'shangjiaduan',
apiUrl: '/yonghu/shangjiaxinxi',
},
}));

View File

@@ -5,10 +5,8 @@
"tab-bar": "/tab-bar/index",
"chenghao-tag": "/components/chenghao-tag/chenghao-tag"
},
"navigationBarTitleText": "商家中心",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
"backgroundColor": "#f8f9fc",
"backgroundTextStyle": "light",
"navigationStyle": "custom",
"backgroundColor": "#fff8e1",
"backgroundTextStyle": "dark",
"enablePullDownRefresh": false
}

View File

@@ -1,199 +1,166 @@
<!-- pages/shangjiazhongxin/shangjiazhongxin.wxml -->
<!-- 最终优化版:指标卡片缩小,图标缩小,资产卡片缩小,背景模糊 -->
<!-- 页面背景纹理 -->
<image class="page-bg" src="{{imgUrls.pageBg}}" mode="aspectFill" />
<!-- 未注册状态 -->
<view class="page-container unregistered" wx:if="{{!isShangjia}}">
<view class="unreg-card" style="background-image: url('{{imgUrls.assetCardBg}}'); background-size: cover; background-position: center;">
<view class="unreg-content">
<text class="status-title">商家入驻</text>
<text class="status-desc">输入邀请码,解锁专属商家权益</text>
<view class="input-group">
<input class="invite-input" type="text" placeholder="请输入邀请码" maxlength="100" value="{{inviteCode}}" bindinput="onInviteCodeInput" placeholder-class="input-placeholder"/>
</view>
<button class="register-btn" bindtap="onRegister">立即注册</button>
<view class="register-tip">已有邀请码?点击上方注册</view>
<view class="sys-item sys-item-unreg" bindtap="switchToNormal">
<image class="sys-icon" src="{{imgUrls.iconSwitch}}" mode="aspectFit" />
<text class="sys-text">返回点单端</text>
</view>
<view class="sys-item sys-item-unreg" bindtap="clearCache">
<image class="sys-icon" src="{{imgUrls.iconClear}}" mode="aspectFit" />
<text class="sys-text">清除缓存</text>
<text class="sys-sub">重新登录</text>
<!-- 商家端个人中心 - 逍遥梦布局,逻辑/接口不变 -->
<block wx:if="{{!isShangjia}}">
<view class="sj-page user-page">
<view class="sj-page-header">
<view class="status-bar" style="height:{{statusBar}}px"></view>
<view class="nav-bar flexm" style="height:{{navBar - statusBar}}px"><text class="sj-nav-title">我的</text></view>
</view>
<view class="unreg-area sj-mx20">
<view class="sj-panel unreg-card">
<text class="unreg-title">商家入驻</text>
<input class="unreg-input" placeholder="请输入邀请码" maxlength="100" value="{{inviteCode}}" bindinput="onInviteCodeInput"/>
<view class="sj-btn-bg unreg-btn flexm" bindtap="onRegister">立即注册</view>
<view class="unreg-link" bindtap="switchToNormal">返回点单端</view>
<view class="unreg-link" bindtap="clearCache">清除缓存,重新登录</view>
</view>
</view>
<tab-bar/>
</view>
</view>
</block>
<!-- 已注册商家主页面 -->
<view class="page-container registered" wx:else>
<!-- 刷新按钮 -->
<view class="refresh-btn" bindtap="refreshShangjiaInfo">
<image class="refresh-icon" src="{{imgUrls.iconRefresh}}" mode="aspectFit" />
</view>
<block wx:else>
<view class="sj-page user-page">
<view class="sj-page-header">
<view class="status-bar" style="height:{{statusBar}}px"></view>
<view class="nav-bar flexm" style="height:{{navBar - statusBar}}px"><text class="sj-nav-title">我的</text></view>
</view>
<!-- 头像卡片 -->
<view class="avatar-card" style="background-image: url('{{imgUrls.avatarCardBg}}'); background-size: cover; background-position: center;">
<view class="avatar-content">
<view class="avatar-wrapper" bindtap="previewAvatar">
<image class="avatar-img" src="{{avatarUrl}}" mode="aspectFill" />
<image class="avatar-frame" src="{{imgUrls.avatarFrame}}" mode="aspectFit" />
</view>
<view class="user-info">
<text class="nicheng">{{nicheng || '商家'}}</text>
<view class="uid-area">
<text class="uid-label">UID</text>
<text class="uid-value">{{uid || '------'}}</text>
<image class="copy-icon" src="{{imgUrls.iconCopy}}" mode="aspectFit" bindtap="copyUid" />
<view class="refresh-float" bindtap="refreshShangjiaInfo">
<image class="refresh-float-ico" src="{{imgUrls.iconRefresh}}" mode="aspectFit"/>
</view>
<scroll-view class="content" scroll-y enhanced show-scrollbar="{{false}}">
<view class="user-info flexb">
<view class="flex">
<image class="avatar" src="{{avatarUrl || imgUrls.iconService}}" mode="aspectFill" bindtap="previewAvatar"/>
<view>
<view class="nickname-row flex">
<text class="nickname">{{nicheng || '商家'}}</text>
<view class="sj-identity-tag">商家</view>
</view>
<view class="sn-row flex" bindtap="copyUid">
<text class="sn">ID: {{uid || '--'}}</text>
<image class="copy-ico" src="{{imgUrls.iconCopy}}" mode="aspectFit"/>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 荣誉称号区域 -->
<view class="badge-area" wx:if="{{chenghaoList.length > 0}}">
<scroll-view class="badge-scroll" scroll-x="true" show-scrollbar="{{false}}">
<view class="badge-row">
<block wx:for="{{chenghaoList}}" wx:key="index">
<chenghao-tag mingcheng="{{item.mingcheng}}" texiaoJson="{{item.texiao_json}}" />
</block>
<view class="badge-zone" wx:if="{{chenghaoList.length > 0}}">
<scroll-view scroll-x class="badge-scroll">
<view class="badge-tag-wrap" wx:for="{{chenghaoList}}" wx:key="index">
<chenghao-tag mingcheng="{{item.mingcheng}}" texiaoJson="{{item.texiao_json}}"/>
</view>
</scroll-view>
</view>
<view class="sj-wallet-card flexb">
<view>
<view class="sj-w-label">商家余额(元)</view>
<view class="sj-w-num">¥{{sjyue}}</view>
<view class="sj-w-sub">发单总量 {{fabu}} · 退款 {{tuikuan}}</view>
</view>
<view class="wallet-btns flex">
<view class="sj-btn-outline" catchtap="goToRecharge">充值</view>
<view class="sj-btn-outline" catchtap="goToWithdraw">去提现</view>
</view>
</view>
<view class="freeze-row flexa">
<view class="freeze-col flexmc">
<text class="freeze-num">{{jinriliushui}}</text>
<text class="freeze-lbl">今日流水</text>
</view>
<view class="freeze-col flexmc">
<text class="freeze-num">{{jinyueliushui}}</text>
<text class="freeze-lbl">今月流水</text>
</view>
<view class="freeze-col flexmc">
<text class="freeze-num">{{jinridingdan}}</text>
<text class="freeze-lbl">今日派单</text>
</view>
</view>
<view class="sj-panel sj-mx20 order-nav-box">
<view class="sj-section-hd">我的订单</view>
<view class="sj-order-nav">
<view class="sj-order-nav-item" bindtap="goToPendingOrders">
<text class="sj-order-nav-num">{{pendingCount}}</text>
<text class="sj-order-nav-lbl">待结算</text>
</view>
<view class="sj-order-nav-item" bindtap="goToMyOrders">
<text class="sj-order-nav-num">{{jinrituikuan}}</text>
<text class="sj-order-nav-lbl">今日退款</text>
</view>
<view class="sj-order-nav-item" bindtap="goToMessages">
<text class="sj-order-nav-num">{{punishPending}}</text>
<text class="sj-order-nav-lbl">处罚待处理</text>
</view>
<view class="sj-order-nav-item" bindtap="goToMyOrders">
<text class="sj-order-nav-num"></text>
<text class="sj-order-nav-lbl">全部订单</text>
</view>
</view>
</view>
<view class="sj-panel sj-mx20">
<view class="sj-section-hd">交易与发单</view>
<view class="sj-func-grid">
<view class="sj-func-item" bindtap="goToPaiDan">
<image class="sj-func-icon" src="{{imgUrls.iconRelease}}" mode="aspectFit"/>
<text class="sj-func-txt">自定义单</text>
</view>
<view class="sj-func-item" bindtap="goToJiSuPaiDan">
<image class="sj-func-icon" src="{{imgUrls.iconFast}}" mode="aspectFit"/>
<text class="sj-func-txt">常规单</text>
</view>
<view class="sj-func-item" bindtap="goToKefuKey">
<image class="sj-func-icon" src="{{imgUrls.iconService}}" mode="aspectFit"/>
<text class="sj-func-txt">客服邀请码</text>
</view>
<view class="sj-func-item" bindtap="goToKefuList">
<image class="sj-func-icon" src="{{imgUrls.iconService}}" mode="aspectFit"/>
<text class="sj-func-txt">客服列表</text>
</view>
<view class="sj-func-item" bindtap="goToMessages">
<image class="sj-func-icon" src="{{imgUrls.iconPunish}}" mode="aspectFit"/>
<text class="sj-func-txt">处罚记录</text>
</view>
<view class="sj-func-item" bindtap="goToRanking">
<image class="sj-func-icon" src="{{imgUrls.iconRank}}" mode="aspectFit"/>
<text class="sj-func-txt">商家排行</text>
</view>
<view class="sj-func-item" bindtap="goToKefu">
<image class="sj-func-icon" src="{{imgUrls.iconService}}" mode="aspectFit"/>
<text class="sj-func-txt">在线客服</text>
</view>
<view class="sj-func-item" bindtap="goToHome">
<image class="sj-func-icon" src="{{imgUrls.iconOrders}}" mode="aspectFit"/>
<text class="sj-func-txt">商家首页</text>
</view>
</view>
</view>
<view class="sj-panel sj-mx20 sys-panel">
<view class="sys-item flexb" bindtap="switchToNormal">
<text class="sys-text">返回点单端</text>
<text class="sys-arrow"></text>
</view>
<view class="sys-item flexb" bindtap="clearCache">
<text class="sys-text">清除缓存</text>
<text class="sys-sub">重新登录</text>
</view>
</view>
<view class="sj-scroll-bottom"></view>
</scroll-view>
<tab-bar/>
</view>
</block>
<!-- 资产卡片(稍微缩小) -->
<view class="asset-card" style="background-image: url('{{imgUrls.assetCardBg}}'); background-size: cover; background-position: center;">
<view class="card-content glass-effect">
<view class="balance-area">
<text class="balance-label">账户余额(元)</text>
<view class="balance-value">
<text class="value-num">{{sjyue}}</text>
<text class="value-unit">¥</text>
</view>
<view class="action-buttons">
<view class="action-btn recharge" bindtap="goToRecharge">
<image class="btn-icon" src="{{imgUrls.iconRecharge}}" mode="aspectFit" />
<text>充值</text>
</view>
<view class="action-btn withdraw" bindtap="goToWithdraw">
<image class="btn-icon" src="{{imgUrls.iconWithdraw}}" mode="aspectFit" />
<text>提现</text>
</view>
</view>
</view>
<view class="divider"></view>
<view class="stats-row">
<view class="stat-item">
<text class="stat-label">发单总量</text>
<text class="stat-number">{{fabu}}</text>
</view>
<view class="stat-item">
<text class="stat-label">退款总量</text>
<text class="stat-number">{{tuikuan}}</text>
</view>
<view class="stat-item">
<text class="stat-label">今日流水</text>
<text class="stat-number">{{jinriliushui}}</text>
</view>
<view class="stat-item">
<text class="stat-label">今月流水</text>
<text class="stat-number">{{jinyueliushui}}</text>
</view>
</view>
</view>
</view>
<!-- 核心指标卡片组(缩小版) -->
<view class="metrics-section">
<view class="metric-card" style="background-image: url('{{imgUrls.statCardBg}}'); background-size: cover; background-position: center;">
<view class="metric-content">
<image class="metric-icon" src="{{imgUrls.iconRelease}}" mode="aspectFit" />
<text class="metric-value">{{jinridingdan}}</text>
<text class="metric-label">今日派单</text>
</view>
</view>
<view class="metric-card" style="background-image: url('{{imgUrls.statCardBg}}'); background-size: cover; background-position: center;">
<view class="metric-content">
<image class="metric-icon" src="{{imgUrls.iconPunish}}" mode="aspectFit" />
<text class="metric-value">{{jinrituikuan}}</text>
<text class="metric-label">今日退款</text>
</view>
</view>
</view>
<!-- 功能宫格(图标缩小) -->
<view class="function-grid">
<view class="func-item primary" style="background-image: url('{{imgUrls.primaryFuncBg}}'); background-size: cover; background-position: center;">
<view class="func-content" bindtap="goToPaiDan">
<image class="func-icon" src="{{imgUrls.iconRelease}}" mode="aspectFit" />
<text class="func-name">发布订单</text>
<text class="func-desc">快速派单</text>
</view>
</view>
<view class="func-item highlight" style="background-image: url('{{imgUrls.highlightFuncBg}}'); background-size: cover; background-position: center;">
<view class="func-content" bindtap="goToJiSuPaiDan">
<image class="func-icon" src="{{imgUrls.iconFast}}" mode="aspectFit" />
<text class="func-name">极速派单</text>
<text class="func-desc">闪电体验</text>
</view>
</view>
<view class="func-item" style="background-image: url('{{imgUrls.funcItemBg}}'); background-size: cover; background-position: center;">
<view class="func-content" bindtap="goToMyOrders">
<image class="func-icon" src="{{imgUrls.iconOrders}}" mode="aspectFit" />
<text class="func-name">我的订单</text>
<text class="func-desc">管理派单</text>
</view>
</view>
<view class="func-item" style="background-image: url('{{imgUrls.funcItemBg}}'); background-size: cover; background-position: center;">
<view class="func-content" bindtap="goToMessages">
<image class="func-icon" src="{{imgUrls.iconPunish}}" mode="aspectFit" />
<text class="func-name">处罚记录</text>
<text class="func-desc">违规查询</text>
</view>
</view>
<view class="func-item" style="background-image: url('{{imgUrls.funcItemBg}}'); background-size: cover; background-position: center;">
<view class="func-content" bindtap="goToRanking">
<image class="func-icon" src="{{imgUrls.iconRank}}" mode="aspectFit" />
<text class="func-name">商家排行</text>
<text class="func-desc">业绩排名</text>
</view>
</view>
<view class="func-item" style="background-image: url('{{imgUrls.funcItemBg}}'); background-size: cover; background-position: center;">
<view class="func-content" bindtap="goToKefu">
<image class="func-icon" src="{{imgUrls.iconService}}" mode="aspectFit" />
<text class="func-name">在线客服</text>
<text class="func-desc">帮助中心</text>
</view>
</view>
</view>
<view class="sys-list">
<view class="sys-item" bindtap="switchToNormal">
<image class="sys-icon" src="{{imgUrls.iconSwitch}}" mode="aspectFit" />
<text class="sys-text">返回点单端</text>
</view>
<view class="sys-item" bindtap="clearCache">
<image class="sys-icon" src="{{imgUrls.iconClear}}" mode="aspectFit" />
<text class="sys-text">清除缓存</text>
<text class="sys-sub">重新登录</text>
</view>
</view>
<view class="safe-bottom"></view>
</view>
<!-- 加载遮罩 -->
<view class="loading-mask" wx:if="{{isLoading}}">
<view class="loading-content">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
<view class="loading-spinner"></view>
</view>
<!-- 全局组件 -->
<global-notification id="global-notification" />
<popup-notice id="popupNotice" />
<tab-bar />
<global-notification id="global-notification"/>
<popup-notice id="popupNotice"/>

View File

@@ -1,425 +1,226 @@
/* pages/shangjiazhongxin/shangjiazhongxin.wxss */
page {
background-color: #f5f7fb;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}
/* .page-bg 与全局类似,仅保留差异 */
.page-bg {
opacity: 0.15;
filter: blur(8rpx);
}
/* .page-container 与全局类似,仅保留差异 */
.page-container {
z-index: 1;
padding: 0 32rpx;
box-sizing: border-box;
background-color: transparent;
}
/* 未注册卡片 */
.unregistered {
display: flex;
align-items: center;
justify-content: center;
padding-top: 200rpx;
}
/* .unreg-card 与 .card 类似,仅保留差异 */
.unreg-card {
width: 90%;
border-radius: 48rpx;
box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.2);
background-color: transparent;
}
.unreg-content {
padding: 60rpx 40rpx;
text-align: center;
background: rgba(0,0,0,0.65);
backdrop-filter: blur(16rpx);
border-radius: 48rpx;
}
.status-title {
font-size: 44rpx;
font-weight: 700;
color: #fff;
margin-bottom: 16rpx;
}
.status-desc {
font-size: 28rpx;
color: #ddd;
margin-bottom: 50rpx;
}
.input-group {
margin-bottom: 40rpx;
}
/* .invite-input 与 .input-rounded--dark 类似,仅保留差异 */
.invite-input {
height: 96rpx;
background: rgba(255,255,255,0.2);
border-radius: 48rpx;
font-size: 30rpx;
}
/* .register-btn 与 .btn .btn-primary .btn-primary--orange 完全相同,删除 */
.register-tip {
margin-top: 32rpx;
font-size: 24rpx;
color: #ddd;
}
/* 已注册页面 */
.registered {
padding-top: 30rpx;
padding-bottom: 40rpx;
}
/* .refresh-btn 与全局 .refresh-btn .refresh-btn--dark 类似,仅保留差异 */
.refresh-btn {
position: absolute;
top: 30rpx;
width: 72rpx;
height: 72rpx;
border-radius: 36rpx;
}
.refresh-icon {
width: 40rpx;
height: 40rpx;
filter: brightness(0) invert(1);
}
/* 头像卡片 */
.avatar-card {
border-radius: 60rpx;
overflow: hidden;
margin-bottom: 36rpx;
box-shadow: 0 6rpx 18rpx rgba(0,0,0,0.2);
background-color: transparent;
}
.avatar-content {
display: flex;
align-items: center;
padding: 28rpx 32rpx;
background: rgba(0,0,0,0.55);
backdrop-filter: blur(20rpx);
}
.avatar-wrapper {
position: relative;
width: 110rpx;
height: 110rpx;
margin-right: 28rpx;
}
/* .avatar-img 与 .avatar-circle 类似,仅保留差异 */
.avatar-img {
width: 100%;
height: 100%;
border: 2rpx solid rgba(255,255,255,0.3);
}
.avatar-frame {
position: absolute;
top: -8rpx;
left: -8rpx;
width: 126rpx;
height: 126rpx;
pointer-events: none;
}
.user-info {
flex: 1;
}
.nicheng {
font-size: 40rpx;
font-weight: 700;
color: #fff;
margin-bottom: 16rpx;
text-shadow: 0 2rpx 6rpx rgba(0,0,0,0.5);
background: rgba(0,0,0,0.6);
display: inline-block;
padding: 6rpx 20rpx;
border-radius: 40rpx;
}
.uid-area {
display: flex;
align-items: center;
}
.uid-label {
font-size: 26rpx;
color: #fff;
background: rgba(0,0,0,0.7);
padding: 6rpx 16rpx;
border-radius: 28rpx;
margin-right: 16rpx;
backdrop-filter: blur(4rpx);
}
.uid-value {
font-size: 28rpx;
color: #fff;
font-family: monospace;
background: rgba(0,0,0,0.6);
padding: 6rpx 16rpx;
border-radius: 28rpx;
}
.copy-icon {
width: 40rpx;
height: 40rpx;
margin-left: 20rpx;
opacity: 0.9;
filter: drop-shadow(0 2rpx 2rpx rgba(0,0,0,0.5));
}
/* 荣誉标签 */
.badge-area {
margin-bottom: 36rpx;
}
.badge-scroll {
white-space: nowrap;
}
.badge-row {
display: inline-flex;
gap: 16rpx;
padding: 8rpx 0;
}
/* 资产卡片 */
.asset-card {
border-radius: 48rpx;
overflow: hidden;
margin-bottom: 36rpx;
box-shadow: 0 10rpx 24rpx rgba(0,0,0,0.2);
background-color: transparent;
}
.glass-effect {
padding: 44rpx 36rpx;
background: rgba(0,0,0,0.55);
backdrop-filter: blur(20rpx);
}
.balance-area {
display: flex;
justify-content: space-between;
align-items: flex-start;
flex-wrap: wrap;
margin-bottom: 32rpx;
}
.balance-label {
font-size: 28rpx;
color: #ffdebc;
font-weight: 500;
}
.balance-value {
display: flex;
align-items: baseline;
}
.value-num {
font-size: 64rpx;
font-weight: 800;
color: #ffd966;
font-family: 'DIN', monospace;
}
.value-unit {
font-size: 32rpx;
color: #ffdebc;
margin-left: 6rpx;
}
.action-buttons {
display: flex;
gap: 24rpx;
}
.action-btn {
display: flex;
align-items: center;
gap: 10rpx;
background: rgba(255,255,255,0.9);
padding: 12rpx 28rpx;
border-radius: 60rpx;
font-size: 26rpx;
font-weight: 500;
}
.action-btn.recharge {
color: #ff8c1a;
}
.action-btn.withdraw {
color: #2d3e6e;
}
.btn-icon {
width: 32rpx;
height: 32rpx;
}
/* .divider 与全局 .divider-gradient 类似,仅保留差异 */
.divider {
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.5), transparent);
margin: 24rpx 0;
}
.stats-row {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.stat-item {
flex: 1;
text-align: center;
}
.stat-label {
font-size: 24rpx;
color: #ddd;
margin-bottom: 12rpx;
display: block;
}
.stat-number {
font-size: 34rpx;
font-weight: 700;
color: #fff;
}
/* 核心指标卡片组 */
.metrics-section {
display: flex;
gap: 24rpx;
margin-bottom: 40rpx;
}
.metric-card {
flex: 1;
border-radius: 36rpx;
overflow: hidden;
box-shadow: 0 6rpx 16rpx rgba(0,0,0,0.2);
background-color: transparent;
}
.metric-content {
display: flex;
flex-direction: column;
align-items: center;
padding: 24rpx 0;
background: rgba(0,0,0,0.55);
backdrop-filter: blur(12rpx);
}
.metric-icon {
width: 48rpx;
height: 48rpx;
margin-bottom: 16rpx;
filter: brightness(0) invert(1);
}
.metric-value {
font-size: 44rpx;
font-weight: 800;
color: #ffd966;
margin-bottom: 8rpx;
}
.metric-label {
font-size: 24rpx;
color: #eee;
}
/* 功能宫格 */
.function-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24rpx;
margin-top: 12rpx;
}
.func-item {
border-radius: 32rpx;
overflow: hidden;
box-shadow: 0 6rpx 14rpx rgba(0,0,0,0.2);
background-color: transparent;
}
.func-content {
display: flex;
flex-direction: column;
align-items: center;
padding: 32rpx 12rpx 28rpx;
background: rgba(0,0,0,0.55);
backdrop-filter: blur(12rpx);
transition: all 0.2s ease;
}
.func-icon {
width: 64rpx;
height: 64rpx;
margin-bottom: 20rpx;
filter: brightness(0) invert(1);
}
.func-name {
font-size: 28rpx;
font-weight: 600;
color: #fff;
margin-bottom: 8rpx;
}
.func-desc {
font-size: 22rpx;
color: #ddd;
}
/* 底部安全区 */
.safe-bottom {
height: 40rpx;
}
/* .sys-list 无全局对应,保留 */
.sys-list {
margin: 24rpx 32rpx 0;
background: rgba(255, 255, 255, 0.92);
border-radius: 20rpx;
overflow: hidden;
border: 1rpx solid rgba(0, 0, 0, 0.06);
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
}
/* .sys-item 与 .list-item 类似,仅保留差异(无 border-bottom */
.sys-item {
padding: 24rpx 28rpx;
}
.sys-item-unreg {
margin-top: 28rpx;
padding-top: 24rpx;
border-top: 1rpx solid rgba(0, 0, 0, 0.08);
justify-content: center;
background: rgba(255, 255, 255, 0.55);
border-radius: 16rpx;
}
/* .sys-icon 与 .list-icon 类似,仅保留差异 */
.sys-icon {
width: 32rpx;
height: 32rpx;
margin-right: 14rpx;
}
/* .sys-text 与 .list-text 类似,仅保留差异 */
.sys-text {
font-size: 28rpx;
color: #1A1A1A;
font-weight: 600;
}
/* .sys-sub 无全局对应,保留 */
.sys-sub {
flex: 1;
text-align: right;
font-size: 22rpx;
color: #888;
margin-left: 12rpx;
}
/* .loading-mask 与全局 .loading-mask .loading-mask--dark 类似,仅保留差异 */
.loading-mask {
backdrop-filter: blur(10px);
}
.loading-content {
background: rgba(0,0,0,0.8);
padding: 48rpx 64rpx;
border-radius: 32rpx;
display: flex;
flex-direction: column;
align-items: center;
}
/* .loading-spinner 与 .spinner--md 类似,仅保留差异 */
.loading-spinner {
width: 72rpx;
height: 72rpx;
border: 6rpx solid rgba(255,255,255,0.3);
border-top-color: #ffd966;
margin-bottom: 24rpx;
}
/* .loading-text 与全局 .loading-text 类似,仅保留差异 */
.loading-text {
font-size: 28rpx;
}
@import '../../styles/shangjia-xym-common.wxss';
page {
background: #fff8e1;
}
.user-page {
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
.nav-bar {
display: flex;
align-items: center;
justify-content: center;
}
.content {
flex: 1;
height: 0;
}
.refresh-float {
position: fixed;
right: 24rpx;
top: calc(env(safe-area-inset-top) + 100rpx);
z-index: 10;
width: 56rpx;
height: 56rpx;
background: rgba(255, 255, 255, 0.85);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.refresh-float-ico {
width: 32rpx;
height: 32rpx;
}
.user-info {
padding: 10rpx 30rpx;
}
.avatar {
width: 110rpx;
height: 110rpx;
border-radius: 50%;
border: 4rpx solid #f1f7ff;
margin-right: 20rpx;
background: #eee;
}
.nickname {
font-size: 38rpx;
font-weight: 700;
color: #222;
}
.nickname-row {
flex-wrap: wrap;
align-items: center;
gap: 8rpx;
}
.sn-row {
margin-top: 8rpx;
align-items: center;
}
.sn {
color: #999;
font-size: 24rpx;
}
.copy-ico {
width: 24rpx;
height: 24rpx;
margin-left: 8rpx;
opacity: 0.6;
}
.badge-zone {
padding: 0 24rpx 8rpx;
}
.badge-scroll {
white-space: nowrap;
width: 100%;
}
.badge-tag-wrap {
display: inline-block;
transform: scale(0.72);
transform-origin: left center;
margin-right: -8rpx;
}
.wallet-btns .sj-btn-outline {
margin-left: 12rpx;
}
.freeze-row {
margin: 16rpx 30rpx 0;
padding: 20rpx 10rpx;
border-radius: 15rpx;
background: #fef6d4;
}
.freeze-col {
flex: 1;
}
.freeze-num {
font-size: 32rpx;
font-weight: 700;
color: #7e893c;
}
.freeze-lbl {
font-size: 24rpx;
color: #7e893c;
font-weight: 700;
margin-top: 4rpx;
}
.order-nav-box {
margin-top: 16rpx;
}
.unreg-area {
flex: 1;
padding: 40rpx 0 16rpx;
}
.unreg-card {
padding: 40rpx 30rpx;
}
.unreg-title {
display: block;
font-size: 32rpx;
font-weight: 700;
text-align: center;
margin-bottom: 24rpx;
}
.unreg-input {
height: 80rpx;
border-radius: 12rpx;
margin-bottom: 20rpx;
background: #f7f7f7;
padding: 0 24rpx;
font-size: 28rpx;
border: 1rpx solid #eee;
}
.unreg-btn {
height: 80rpx;
font-size: 28rpx;
margin-bottom: 16rpx;
}
.unreg-link {
text-align: center;
padding: 16rpx;
font-size: 24rpx;
color: #999;
}
.sys-panel {
margin-top: 16rpx;
margin-bottom: 16rpx;
padding: 0 8rpx;
}
.sys-item {
padding: 24rpx 20rpx;
border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);
}
.sys-item:last-child {
border-bottom: none;
}
.sys-text {
font-size: 28rpx;
color: #333;
}
.sys-sub {
font-size: 22rpx;
color: #999;
}
.sys-arrow {
color: #ccc;
font-size: 32rpx;
}
.loading-mask {
position: fixed;
inset: 0;
background: rgba(255, 255, 255, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 999;
}
.loading-spinner {
width: 60rpx;
height: 60rpx;
border: 4rpx solid rgba(0, 0, 0, 0.08);
border-top-color: #ffd061;
border-radius: 50%;
animation: sjSpin 0.8s linear infinite;
}
@keyframes sjSpin {
to { transform: rotate(360deg); }
}

View File

@@ -1,7 +1,7 @@
/* 我的页面 */
page {
background: #F7F3ED;
background: #f5f5f5;
height: 100vh;
overflow: hidden;
}
@@ -18,8 +18,7 @@ page {
position: fixed;
top: 0; left: 0;
width: 100vw; height: 100vh;
background: radial-gradient(ellipse at 30% 20%, rgba(201,169,98,0.08) 0%, transparent 60%),
radial-gradient(ellipse at 80% 70%, rgba(201,169,98,0.05) 0%, transparent 50%);
background: linear-gradient(180deg, #fef6d4 0%, #f5f5f5 40%, #f5f5f5 100%);
z-index: 0;
pointer-events: none;
}
@@ -49,7 +48,7 @@ page {
height: 48rpx;
}
.icon-bg {
background: rgba(201,169,98,0.08);
background: #fef6d4;
border-radius: 22rpx;
display: flex;
align-items: center;
@@ -125,7 +124,7 @@ page {
line-height: 1.2;
}
.gradient-bg {
background: linear-gradient(to right, rgba(201,169,98,0.01), rgba(201,169,98,0.10));
background: linear-gradient(to right, rgba(255, 208, 97, 0.05), rgba(255, 208, 97, 0.15));
}
.title-text {
font-size: 34rpx;
@@ -134,15 +133,15 @@ page {
letter-spacing: 1rpx;
}
/* 毛玻璃容器 */
/* 卡片容器 */
.frosted-box {
background: rgba(255, 255, 255, 0.52);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-radius: 28rpx;
background: #fdfcfa;
backdrop-filter: none;
-webkit-backdrop-filter: none;
border-radius: 20rpx;
padding: 36rpx 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.04), inset 0 1rpx 0 rgba(255,255,255,0.8);
border: 1rpx solid rgba(255,255,255,0.5);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.06);
border: none;
}
/* 订单行 */

View File

@@ -1,458 +1,473 @@
// pages/order-pool/order-pool.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: 10,
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. 授权状态控制
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;
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
});
},
checkAuthorization() {
const { dashoustatus, zhuanghaoStatus } = this.data;
const isDashouValid = (dashoustatus && dashoustatus == 1) || false;
const isZhuanghaoValid = (zhuanghaoStatus == 1);
const isAuthorized = isDashouValid && isZhuanghaoValid;
if (!isAuthorized) {
this.setData({ showUnauthorized: true });
let msg = '';
if (!isDashouValid) 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/fighter-recharge/fighter-recharge';
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/fighter/fighter'
});
}
// pages/order-pool/order-pool.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: 10,
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. 授权状态控制
showUnauthorized: false,
unauthorizedMsg: '您尚未开启此功能',
// 商品轮播展示(只读 globalData无额外接口
lunboList: [],
},
async onLoad(options) {
this.syncShopBannerFromGlobal();
this.loadGlobalStatus();
this.checkAuthorization();
},
// 页面隐藏时清理弹窗视图
onHide: function () {
const popupComp = this.selectComponent('#popupNotice');
if (popupComp && popupComp.cleanup) {
popupComp.cleanup();
}
},
onShow() {
this.syncShopBannerFromGlobal();
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()
};
}
},
/** 同步点单端已加载的商品轮播图,仅展示用 */
syncShopBannerFromGlobal() {
const oss = app.globalData.ossImageUrl || '';
const lunboList = (app.globalData.shangpinlunbo || []).map((url) => {
if (!url) return '';
return url.startsWith('http') ? url : oss + url;
}).filter(Boolean);
this.setData({ lunboList });
},
loadGlobalStatus() {
const globalData = app.globalData;
const dashoustatusCache = wx.getStorageSync('dashoustatus');
const dashoustatus = dashoustatusCache !== '' ? dashoustatusCache : null;
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
});
},
checkAuthorization() {
const { dashoustatus, zhuanghaoStatus } = this.data;
const isDashouValid = (dashoustatus && dashoustatus == 1) || false;
const isZhuanghaoValid = (zhuanghaoStatus == 1);
const isAuthorized = isDashouValid && isZhuanghaoValid;
if (!isAuthorized) {
this.setData({ showUnauthorized: true });
let msg = '';
if (!isDashouValid) 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/fighter-recharge/fighter-recharge';
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/fighter/fighter'
});
}
});

View File

@@ -5,7 +5,7 @@
<view class="unauthorized-card">
<view class="card-glow"></view>
<view class="card-content-unauth">
<view class="icon-lock">🔒</view>
<view class="icon-lock"></view>
<text class="title">功能未开启</text>
<text class="message">{{unauthorizedMsg}}</text>
<text class="description">请先注册为服务者,即可使用抢单功能</text>
@@ -19,6 +19,25 @@
<!-- 正常内容(授权后显示) -->
<block wx:else>
<!-- 商品轮播(只读 globalData与点单端同源 -->
<view class="xym-lunbo-container" wx:if="{{lunboList.length > 0}}">
<swiper
class="xym-lunbo-swiper"
indicator-dots="{{lunboList.length > 1}}"
indicator-color="rgba(255,255,255,0.6)"
indicator-active-color="#ffd061"
autoplay="{{lunboList.length > 1}}"
interval="4000"
circular
>
<block wx:for="{{lunboList}}" wx:key="index">
<swiper-item>
<image class="xym-lunbo-image" src="{{item}}" mode="aspectFill" />
</swiper-item>
</block>
</swiper>
</view>
<!-- 顶部区域:商品类型选择 -->
<view class="leixing-quyu">
<scroll-view class="leixing-scroll" scroll-x enhanced show-scrollbar="{{false}}">
@@ -143,7 +162,7 @@
<!-- 底部:分佣 + 抢单按钮 -->
<view class="card-bottom">
<view class="fenyong-box">
<text class="fenyong-icon">💰</text>
<view class="fenyong-mark"></view>
<text class="fenyong-text">分佣</text>
<text class="fenyong-price">{{item.dashou_fencheng || 0}}</text>
<text class="fenyong-unit">元</text>
@@ -223,7 +242,7 @@
<!-- 底部:分佣 + 抢单按钮 -->
<view class="card-bottom">
<view class="fenyong-box">
<text class="fenyong-icon">💰</text>
<view class="fenyong-mark"></view>
<text class="fenyong-text">分佣</text>
<text class="fenyong-price">{{item.dashou_fencheng || 0}}</text>
<text class="fenyong-unit">元</text>

View File

@@ -1,4 +1,5 @@
/* pages/qiangdan/qiangdan.wxss */
@import '../../styles/dashou-xym-theme.wxss';
.qiangdan-page {
height: 100vh;
display: flex;
@@ -59,18 +60,27 @@
}
.icon-lock {
font-size: 100rpx;
position: relative;
width: 72rpx;
height: 52rpx;
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;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
border-radius: 10rpx;
box-shadow: 0 8rpx 24rpx rgba(180, 130, 20, 0.25);
}
.icon-lock::before {
content: '';
position: absolute;
top: -34rpx;
left: 50%;
transform: translateX(-50%);
width: 44rpx;
height: 36rpx;
border: 8rpx solid #ffd061;
border-bottom: none;
border-radius: 22rpx 22rpx 0 0;
box-sizing: border-box;
}
.title {

View File

@@ -0,0 +1,341 @@
/* 抢单订单卡片 - 逍遥梦布局(星阙数据) */
.flex { display: flex; align-items: center; }
.flexb { display: flex; align-items: center; justify-content: space-between; }
.flexa { display: flex; align-items: center; justify-content: center; }
.myflex { display: flex; align-items: center; }
.dingdan-list {
padding: 0 0 24rpx;
}
.xym-order-item {
margin-bottom: 24rpx;
position: relative;
overflow: visible;
border-radius: 30rpx;
box-shadow: 0 10rpx 28rpx rgba(0, 0, 0, 0.09);
}
/* 平台订单 */
.xym-pingtai-order {
padding-bottom: 5rpx;
background: #927a46;
}
.xym-pingtai-head {
height: 72rpx;
padding: 0 24rpx;
background: linear-gradient(50deg, #957c48, #5c4a28);
border-radius: 30rpx 30rpx 0 0;
}
.xym-head-time {
font-size: 24rpx;
color: #fcd270;
}
.xym-head-tag {
font-size: 22rpx;
padding: 4rpx 16rpx;
border-radius: 8rpx;
font-weight: 600;
background: rgba(252, 210, 112, 0.22);
color: #fcd270;
border: 1rpx solid rgba(252, 210, 112, 0.4);
}
.xym-pingtai-body {
border-radius: 40rpx 10rpx 30rpx 30rpx;
padding: 0 20rpx 24rpx;
background: linear-gradient(to bottom, #3a3220, #cec180);
}
/* 商家订单 */
.xym-shangjia-order {
padding-bottom: 5rpx;
background: linear-gradient(to bottom, #fff8e1, #ffe0b2);
overflow: hidden;
}
.xym-shangjia-body {
border-radius: 10rpx 10rpx 30rpx 30rpx;
padding: 0 20rpx 24rpx;
}
.xym-shangjia-head {
padding: 16rpx 24rpx 8rpx;
}
.xym-shangjia-head .xym-head-time {
color: #888;
}
.xym-shangjia-head .xym-head-tag {
background: rgba(255, 255, 255, 0.65);
color: #492f00;
border-color: rgba(255, 208, 97, 0.5);
}
.order-con {
position: relative;
min-height: 108rpx;
}
.order-row {
align-items: flex-start;
padding: 24rpx 10rpx 14rpx;
}
.o-logo {
width: 88rpx;
height: 88rpx;
border-radius: 12rpx;
margin-right: 14rpx;
flex-shrink: 0;
background: #eee;
}
.o-col {
flex: 1;
min-width: 0;
padding-right: 136rpx;
box-sizing: border-box;
}
.o-goods {
font-weight: 700;
font-size: 30rpx;
line-height: 1.5;
color: #333;
}
.o-goods.light {
color: #fff;
}
.line2 {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.merchant-line {
display: flex;
align-items: center;
padding: 0 10rpx 12rpx;
gap: 12rpx;
}
.m-avatar-sm {
width: 56rpx;
height: 56rpx;
border-radius: 50%;
flex-shrink: 0;
background: #eee;
}
.m-name-sm {
font-size: 26rpx;
font-weight: 600;
color: #333;
}
.zhiding-strip {
margin: 0 10rpx 12rpx;
padding: 10rpx 16rpx;
background: rgba(255, 77, 109, 0.12);
border-radius: 12rpx;
flex-wrap: wrap;
gap: 8rpx;
}
.zhiding-strip.light {
background: rgba(255, 255, 255, 0.35);
}
.zhiding-strip .zhiding-label {
font-size: 22rpx;
color: #ff4d6d;
font-weight: 700;
padding: 2rpx 12rpx;
background: rgba(255, 77, 109, 0.15);
border-radius: 8rpx;
}
.zhiding-strip .zhiding-avatar {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
}
.zhiding-strip .zhiding-name {
font-size: 24rpx;
color: #666;
max-width: 200rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.xym-pingtai-body .zhiding-strip .zhiding-name {
color: #f5e6b8;
}
.reward-badge {
position: absolute;
right: 0;
top: 18rpx;
font-size: 24rpx;
padding: 6rpx 20rpx;
border-radius: 30rpx 10rpx 0 30rpx;
display: flex;
align-items: baseline;
z-index: 3;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.reward-badge.normal-reward {
color: #492f00;
background: linear-gradient(to bottom, #fae04d, #ffc0a3);
}
.reward-badge.platform-reward {
color: #fff;
background: linear-gradient(to right, #dabd83, #704029);
}
.xym-shangjia-body .reward-badge:not(.member-tip) {
top: 76rpx;
}
.reward-badge.member-tip {
background: rgba(255, 255, 255, 0.85);
padding: 8rpx 16rpx;
border-radius: 20rpx;
top: 16rpx;
right: 10rpx;
}
.reward-yen {
font-size: 28rpx;
}
.reward-num {
font-weight: 700;
font-size: 34rpx;
}
.reward-num.dark {
color: #c00;
}
.reward-tip {
font-size: 22rpx;
color: #c0392b;
font-weight: 600;
}
.reward-yen.sm {
font-size: 26rpx;
}
.remark-block {
font-size: 24rpx;
margin: 8rpx 10rpx 0;
padding: 12rpx 16rpx;
border-left: 4rpx solid;
border-radius: 0 8rpx 8rpx 0;
overflow: hidden;
}
.remark-block.gold {
color: #fff;
border-color: #ffd700;
background: rgba(255, 215, 0, 0.12);
}
.remark-block.dark {
color: #666;
border-color: #87ceeb;
background: rgba(135, 206, 235, 0.12);
}
.remark-label {
font-weight: 600;
}
.remark-block.gold .remark-label {
color: #ffd700;
}
.remark-block.dark .remark-label {
color: #87ceeb;
}
.xuqiu-tags-row {
margin: 12rpx 10rpx 0;
padding-top: 12rpx;
border-top: 2rpx dotted rgba(255, 255, 255, 0.35);
}
.xym-shangjia-body .xuqiu-tags-row {
border-top-color: rgba(0, 0, 0, 0.08);
}
.xuqiu-tags-row .xuqiu-label {
font-size: 22rpx;
color: #87ceeb;
margin-bottom: 8rpx;
display: block;
}
.o-foot {
margin-top: 18rpx;
padding: 0 10rpx 8rpx;
}
.o-amt {
font-size: 26rpx;
color: #999;
}
.o-amt.light {
color: #f5e6b8;
}
.btn-bg {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
border-radius: 60rpx;
color: #492f00;
}
.qiangdan {
color: #492f00;
width: 180rpx;
min-width: 100rpx;
padding: 15rpx 10rpx;
border: 2rpx solid #fff;
box-sizing: border-box;
font-size: 26rpx;
font-weight: 700;
flex-shrink: 0;
}
.qiangdan.btn-qiang-brown {
background: linear-gradient(to right, #7a4a2d 0%, #e4ce94 100%) !important;
color: #000 !important;
}
.view-more-inline {
font-size: 22rpx;
color: #87ceeb;
margin-left: 4rpx;
}
.biaoqian-inline-scroll {
white-space: nowrap;
width: 100%;
}

View File

@@ -0,0 +1,84 @@
/* 打手我的订单 - 逍遥梦风格视觉覆盖 */
.ds-page {
background: #f5f5f5 !important;
}
.leixing-area {
background: #fff !important;
border-bottom: none !important;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06) !important;
margin: 12rpx 20rpx 0 !important;
border-radius: 28rpx !important;
}
.leixing-item.leixing-active {
background: linear-gradient(180deg, #fff0c2, #f5d563) !important;
box-shadow: 0 4rpx 12rpx rgba(255, 208, 97, 0.35) !important;
}
.leixing-active .leixing-name {
color: #492f00 !important;
font-weight: 700 !important;
}
.filter-row {
background: transparent !important;
border-bottom: none !important;
}
.type-switch {
background: rgba(255, 255, 255, 0.8) !important;
}
.type-btn.type-active {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
box-shadow: 0 2rpx 8rpx rgba(180, 130, 20, 0.2) !important;
}
.search-box {
background: #fff !important;
border: 1rpx solid rgba(255, 208, 97, 0.3) !important;
}
.left-status {
background: rgba(255, 255, 255, 0.92) !important;
border-right: none !important;
}
.status-item.status-active {
background: #fff8e1 !important;
}
.status-active .status-name {
color: #492f00 !important;
}
.status-dot {
background: #ffd061 !important;
}
.right-list {
background: #f5f5f5 !important;
}
.order-card {
background: #fdfcfa !important;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06) !important;
}
.card-price {
color: #c0392b !important;
}
.loading-spinner,
.mini-spinner {
border-top-color: #ffd061 !important;
}
.load-more-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
border: 2rpx solid #fff !important;
}

View File

@@ -0,0 +1,92 @@
/* 打手排行榜 - 逍遥梦风格视觉覆盖 */
page {
background: #f5f5f5 !important;
color: #333 !important;
}
.rank-page {
background: #f5f5f5 !important;
}
.page-bg {
opacity: 0.35 !important;
}
.page-title {
color: #343434 !important;
}
.refresh-wrap {
background: rgba(255, 255, 255, 0.85) !important;
}
.role-chip {
background: rgba(255, 255, 255, 0.8) !important;
color: #666 !important;
border: 2rpx solid rgba(255, 208, 97, 0.25) !important;
}
.role-chip.on {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
border-color: #ffd061 !important;
font-weight: 700 !important;
}
.date-chip {
background: rgba(255, 255, 255, 0.7) !important;
color: #666 !important;
}
.date-chip.on {
background: #fef6d4 !important;
color: #492f00 !important;
font-weight: 700 !important;
}
.sort-tip {
color: #999 !important;
}
.podium-panel {
background: #fdfcfa !important;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06) !important;
}
.p-name {
color: #222 !important;
}
.p-score {
color: #c0392b !important;
}
.rank-row {
background: #fdfcfa !important;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04) !important;
}
.rank-row .r-name {
color: #333 !important;
}
.rank-row .r-score {
color: #492f00 !important;
}
.my-rank-bar {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
}
.my-rank-bar text {
color: #492f00 !important;
}
.state-wrap text {
color: #999 !important;
}
.loader {
border-top-color: #ffd061 !important;
}

View File

@@ -0,0 +1,213 @@
/* 打手充值页 - 逍遥梦风格视觉覆盖(不改 wxml/逻辑) */
.page-container {
background: linear-gradient(180deg, #f7dc51 0%, #fff 22%, #fff8e1 100%) !important;
}
.page-container::before {
display: none !important;
}
.vip-section {
background: transparent !important;
}
.section-header .dec-text,
.section-subtitle {
color: #492f00 !important;
}
.dec-line,
.dec-diamond {
background: #ffd061 !important;
}
.vip-card {
background: #fdfcfa !important;
border: 2rpx solid rgba(255, 208, 97, 0.5) !important;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08) !important;
}
.vip-card.active {
border-color: #ffd061 !important;
box-shadow: 0 8rpx 28rpx rgba(255, 208, 97, 0.35) !important;
}
.card-frame,
.frame-corner,
.frame-line {
display: none !important;
}
.vip-title .title-text,
.vip-price .price-number,
.detail-title .title-text {
color: #222 !important;
}
.vip-price .price-symbol,
.vip-price .price-unit {
color: #666 !important;
}
.feature-text {
color: #666 !important;
}
.vip-detail {
background: #fdfcfa !important;
border-radius: 20rpx !important;
margin: 0 24rpx !important;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06) !important;
}
.detail-text,
.rule-text {
color: #666 !important;
}
.tech-buy-btn,
.tech-btn,
.modal-btn.confirm-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
border: 2rpx solid #fff !important;
border-radius: 44rpx !important;
box-shadow: 0 4rpx 12rpx rgba(180, 130, 20, 0.25) !important;
}
.buy-btn-text,
.btn-text,
.tech-btn .btn-text {
color: #492f00 !important;
}
.buy-btn-bg,
.buy-btn-glow,
.btn-bg,
.btn-glow,
.btn-energy,
.btn-shine,
.btn-sparkle {
display: none !important;
}
.tech-grid {
flex-wrap: wrap !important;
}
.tech-card {
background: #fdfcfa !important;
border: none !important;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06) !important;
min-height: 240rpx !important;
}
.tech-card::before {
display: none !important;
}
.card-title .title-text,
.amount-number,
.jifen-value {
color: #222 !important;
}
.amount-unit,
.amount-symbol,
.jifen-label,
.footer-text,
.empty-text {
color: #666 !important;
}
.huiyuan-tag,
.tech-tag {
background: #fef6d4 !important;
border: 1rpx solid rgba(255, 208, 97, 0.4) !important;
}
.tag-name {
color: #492f00 !important;
}
.tag-time {
color: #999 !important;
}
.tech-line {
background: linear-gradient(90deg, transparent, #ffd061, transparent) !important;
}
.tech-modal .modal-container {
background: #fdfcfa !important;
border: none !important;
box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.12) !important;
}
.modal-corner {
display: none !important;
}
.modal-title {
color: #222 !important;
}
.modal-subtitle,
.input-tip,
.detail-label {
color: #666 !important;
}
.modal-btn.cancel-btn {
background: #f5f5f5 !important;
color: #666 !important;
}
.yajin-input {
color: #222 !important;
}
.quick-btn {
background: #fef6d4 !important;
border: 2rpx solid rgba(255, 208, 97, 0.4) !important;
}
.quick-btn.active {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
border-color: #ffd061 !important;
}
.quick-text {
color: #492f00 !important;
}
.pay-method-item {
background: #fef6d4 !important;
border-radius: 16rpx !important;
}
.method-name {
color: #222 !important;
}
.method-desc {
color: #999 !important;
}
.tech-loading .loading-backdrop {
background: rgba(255, 248, 225, 0.85) !important;
}
.loading-text,
.loading-subtext {
color: #666 !important;
}
.spinner-ring {
border-color: rgba(255, 208, 97, 0.3) !important;
border-top-color: #ffd061 !important;
}
.tech-footer .footer-text {
color: #999 !important;
}

View File

@@ -0,0 +1,288 @@
/* 打手端抢单页 - 逍遥梦风格视觉覆盖(不改 wxml 结构/class */
.xym-lunbo-container {
margin: 16rpx 24rpx 0;
border-radius: 20rpx;
overflow: hidden;
flex-shrink: 0;
}
.xym-lunbo-swiper {
height: 300rpx;
border-radius: 20rpx;
}
.xym-lunbo-image {
width: 100%;
height: 300rpx;
border-radius: 20rpx;
}
.qiangdan-page {
background: linear-gradient(180deg, #f7dc51 0%, #fff 28%, #fff8e1 100%) !important;
}
.qiangdan-page::before {
display: none !important;
}
.leixing-quyu {
background: #fff !important;
border-bottom: none !important;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06) !important;
margin: 12rpx 20rpx 0 !important;
border-radius: 28rpx !important;
padding: 14rpx 0 8rpx !important;
}
.leixing-scroll {
height: 132rpx !important;
}
.leixing-item {
width: 120rpx !important;
}
.leixing-tupian {
width: 88rpx !important;
height: 88rpx !important;
border-radius: 20rpx !important;
border: none !important;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08) !important;
}
.leixing-active .leixing-tupian {
border: 3rpx solid #ffd061 !important;
box-shadow: 0 6rpx 16rpx rgba(255, 208, 97, 0.45) !important;
}
.leixing-jieshao {
margin-top: 8rpx !important;
font-size: 22rpx !important;
color: #666 !important;
text-shadow: none !important;
}
.leixing-active .leixing-jieshao {
color: #492f00 !important;
font-weight: 700 !important;
}
.guangyun-effect {
background: radial-gradient(circle, rgba(255, 208, 97, 0.35) 0%, transparent 70%) !important;
}
.biaoqian-quyu {
background: transparent !important;
padding: 8rpx 20rpx 0 !important;
}
.biaoqian-item {
background: rgba(255, 255, 255, 0.65) !important;
border: 2rpx solid rgba(201, 162, 39, 0.25) !important;
}
.biaoqian-active {
background: linear-gradient(180deg, #fff0c2, #f5d563) !important;
border-color: rgba(180, 130, 20, 0.85) !important;
}
.fenge-xian {
background: linear-gradient(90deg, transparent, #ffd061, transparent) !important;
opacity: 0.6 !important;
margin: 6rpx 30rpx 0 !important;
}
.dingdan-list {
padding: 16rpx 20rpx 0 !important;
margin-top: 8rpx !important;
}
.refreshing-text,
.pull-down-text {
color: #6b5420 !important;
text-shadow: none !important;
}
.tip-text {
color: #999 !important;
}
.tip-icon {
filter: none !important;
}
.dingdan-card {
border-radius: 28rpx !important;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08) !important;
border: none !important;
backdrop-filter: none !important;
}
.pingtai-card {
background: linear-gradient(to bottom, #927a46, #cec180) !important;
padding: 0 0 16rpx !important;
}
.pingtai-card::before,
.shangjia-card::before {
display: none !important;
}
.pingtai-card .card-top,
.shangjia-card .card-top {
background: linear-gradient(50deg, #957c48, #5c4a28) !important;
border-radius: 28rpx 28rpx 0 0 !important;
margin: -28rpx -24rpx 16rpx !important;
padding: 16rpx 24rpx !important;
}
.pingtai-tag,
.creat-time {
color: #fcd270 !important;
}
.shangjia-card {
background: linear-gradient(to bottom, #fff8e1, #ffe0b2) !important;
}
.card-content,
.jieshao-box,
.beizhu-box,
.shangjia-jieshao,
.shangjia-beizhu {
background: rgba(255, 255, 255, 0.55) !important;
border-radius: 12rpx !important;
}
.jieshao-label,
.beizhu-label,
.xuqiu-label {
color: #87ceeb !important;
}
.jieshao-text,
.beizhu-text {
color: #333 !important;
}
.fenyong-box {
background: linear-gradient(to bottom, #fae04d, #ffc0a3) !important;
border-radius: 30rpx !important;
}
.fenyong-text,
.fenyong-price,
.fenyong-unit {
color: #492f00 !important;
}
.qiangdan-btn,
.mecha-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
border: 2rpx solid #fff !important;
box-shadow: 0 4rpx 12rpx rgba(180, 130, 20, 0.25) !important;
}
.qiangdan-btn .btn-text,
.mecha-btn .btn-text {
color: #492f00 !important;
}
.btn-shine,
.btn-glow,
.mecha-overlay {
display: none !important;
}
.loading-mask {
background: rgba(255, 248, 225, 0.85) !important;
}
.loading-mask-text,
.loading-text,
.no-more-text {
color: #999 !important;
}
.unauthorized-container {
background: linear-gradient(180deg, #f7dc51, #fff 50%) !important;
}
.unauthorized-card {
background: #fdfcfa !important;
border: none !important;
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.08) !important;
}
.unauthorized-card .title {
color: #343434 !important;
}
.unauthorized-card .message,
.unauthorized-card .description {
color: #666 !important;
}
.btn-register {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
border-radius: 44rpx !important;
}
.btn-register .btn-text {
color: #492f00 !important;
}
.card-glow {
display: none !important;
}
.order-type-tag {
font-size: 22rpx;
padding: 6rpx 16rpx;
border-radius: 8rpx;
font-weight: 600;
line-height: 1.4;
}
.tag-platform {
background: rgba(252, 210, 112, 0.22);
color: #fcd270;
border: 1rpx solid rgba(252, 210, 112, 0.45);
}
.tag-merchant {
background: rgba(255, 255, 255, 0.45);
color: #492f00;
border: 1rpx solid rgba(255, 208, 97, 0.55);
}
.fenyong-mark {
width: 36rpx;
height: 36rpx;
line-height: 36rpx;
text-align: center;
font-size: 22rpx;
font-weight: 700;
color: #492f00;
background: rgba(255, 255, 255, 0.72);
border-radius: 50%;
margin-right: 8rpx;
flex-shrink: 0;
}
.fenyong-icon {
display: none !important;
}
.qiangdan-btn {
min-width: 180rpx !important;
height: 68rpx !important;
border-radius: 34rpx !important;
}
.qiangdan-btn .btn-text {
font-size: 28rpx !important;
font-weight: 700 !important;
letter-spacing: 1rpx;
}

View File

@@ -0,0 +1,307 @@
/* 商家端逍遥梦风格 - 公共布局/色板(仅 UI */
.flex { display: flex; align-items: center; }
.flexb { display: flex; align-items: center; justify-content: space-between; }
.flexa { display: flex; align-items: center; justify-content: space-around; }
.flexm { display: flex; align-items: center; justify-content: center; }
.flexmc { display: flex; flex-direction: column; align-items: center; justify-content: center; }
.sj-page {
min-height: 100vh;
display: flex;
flex-direction: column;
background: linear-gradient(180deg, #f7dc51 0%, #fff 28%, #fff8e1 100%);
box-sizing: border-box;
overflow: hidden;
}
.sj-page-header {
flex-shrink: 0;
position: relative;
z-index: 2;
}
.sj-nav-title {
font-size: 34rpx;
font-weight: 700;
color: #343434;
}
.sj-scroll {
flex: 1;
height: 0;
}
.sj-mx20 {
margin-left: 24rpx;
margin-right: 24rpx;
}
.sj-panel {
background: #fdfcfa;
border-radius: 20rpx;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.06);
}
.sj-btn-outline {
padding: 10rpx 24rpx;
font-size: 26rpx;
font-weight: 700;
border: 2rpx solid #fff;
border-radius: 60rpx;
background: linear-gradient(180deg, #fae04d, #ffc0a3);
color: #492f00;
white-space: nowrap;
}
.sj-btn-bg {
background: linear-gradient(180deg, #fae04d, #ffc0a3);
border-radius: 60rpx;
color: #492f00;
font-weight: 700;
}
.sj-identity-tag {
margin-left: 8rpx;
font-size: 20rpx;
padding: 4rpx 12rpx;
border-radius: 8rpx;
background: #ff9900;
color: #fff;
}
.sj-wallet-card {
margin: 0 30rpx;
padding: 24rpx 20rpx;
border-radius: 26rpx;
background: #fef6d4;
}
.sj-w-label {
color: #666;
font-size: 26rpx;
}
.sj-w-num {
font-size: 44rpx;
font-weight: 700;
color: #222;
margin-top: 10rpx;
}
.sj-w-sub {
color: #666;
font-size: 26rpx;
margin-top: 8rpx;
}
.sj-section-hd {
padding: 16rpx 24rpx 8rpx;
font-size: 32rpx;
font-weight: 700;
color: #343434;
}
.sj-fadan-row {
display: flex;
gap: 16rpx;
margin: 16rpx 0 0;
}
.sj-fadan-btn {
flex: 1;
height: 150rpx;
border-radius: 20rpx;
overflow: hidden;
position: relative;
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.08);
}
.sj-fadan-btn-inner {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 16rpx;
box-sizing: border-box;
}
.sj-fadan-btn--regular {
background: linear-gradient(135deg, #fff8e1, #ffe0b2);
}
.sj-fadan-btn--custom {
background: linear-gradient(135deg, #fef6d4, #f5d563);
}
.sj-fadan-title {
font-size: 30rpx;
font-weight: 700;
color: #492f00;
}
.sj-fadan-sub {
font-size: 22rpx;
color: #886633;
margin-top: 8rpx;
}
.sj-notice-bar {
display: flex;
align-items: center;
background: #fdf9db;
margin: 14rpx 24rpx 0;
border-radius: 10rpx;
padding: 10rpx 16rpx;
}
.sj-notice-txt {
font-size: 24rpx;
color: #4a3000;
line-height: 1.4;
flex: 1;
}
.sj-stat-card {
margin: 16rpx 24rpx 0;
padding: 20rpx 16rpx 16rpx;
border-radius: 20rpx;
background: #fff;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
position: relative;
overflow: hidden;
}
.sj-stat-row {
display: flex;
align-items: stretch;
padding: 12rpx 8rpx;
}
.sj-stat-col {
flex: 1;
text-align: center;
padding: 8rpx 4rpx;
}
.sj-stat-divider {
width: 1rpx;
background: rgba(0, 0, 0, 0.06);
margin: 8rpx 0;
}
.sj-stat-lbl {
display: block;
font-size: 22rpx;
color: #888;
}
.sj-stat-num {
display: block;
font-size: 36rpx;
font-weight: 700;
color: #e67e22;
margin-top: 8rpx;
}
.sj-kefu-row {
display: flex;
gap: 16rpx;
margin-top: 16rpx;
padding-top: 12rpx;
border-top: 1rpx dashed rgba(0, 0, 0, 0.08);
}
.sj-kefu-entry {
flex: 1;
text-align: center;
padding: 16rpx 8rpx;
border-radius: 12rpx;
background: linear-gradient(180deg, #fff8e1, #fef6d4);
font-size: 24rpx;
color: #492f00;
font-weight: 600;
}
.sj-recent-item {
padding: 20rpx 24rpx;
border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);
}
.sj-recent-name {
font-size: 28rpx;
font-weight: 600;
color: #333;
}
.sj-recent-sub {
font-size: 22rpx;
color: #999;
margin-top: 6rpx;
}
.sj-recent-money {
font-size: 30rpx;
font-weight: 700;
color: #e67e22;
flex-shrink: 0;
margin-left: 16rpx;
}
.sj-order-nav {
display: flex;
flex-wrap: wrap;
padding: 8rpx 0 16rpx;
}
.sj-order-nav-item {
width: 25%;
padding: 16rpx 0;
text-align: center;
}
.sj-order-nav-num {
display: block;
font-size: 32rpx;
font-weight: 700;
color: #222;
}
.sj-order-nav-lbl {
display: block;
font-size: 22rpx;
color: #999;
margin-top: 6rpx;
}
.sj-func-grid {
display: flex;
flex-wrap: wrap;
padding: 8rpx 0 16rpx;
}
.sj-func-item {
width: 25%;
padding: 20rpx 0;
display: flex;
flex-direction: column;
align-items: center;
}
.sj-func-icon {
width: 48rpx;
height: 48rpx;
margin-bottom: 8rpx;
}
.sj-func-txt {
font-size: 24rpx;
color: #666;
text-align: center;
}
.sj-scroll-bottom {
height: 24rpx;
}

View File

@@ -0,0 +1,256 @@
/* 商家发单页 - 逍遥梦 addorder 风格(常规单/自定义单共用) */
.sj-form-page,
.page.sj-form-theme,
.page-container.sj-form-theme {
min-height: 100vh;
padding: 24rpx;
padding-bottom: 160rpx;
box-sizing: border-box;
background: linear-gradient(180deg, #f7dc51 0%, #f5f5f5 18%, #f5f5f5 100%);
}
.sj-form-theme .balance-card {
background: #fef6d4 !important;
border-radius: 26rpx !important;
padding: 28rpx 24rpx !important;
margin-bottom: 20rpx !important;
text-align: center !important;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06) !important;
border: none !important;
backdrop-filter: none !important;
position: relative !important;
overflow: visible !important;
}
.sj-form-theme .balance-card::before {
display: none !important;
}
.sj-form-theme .balance-label {
font-size: 26rpx !important;
color: #666 !important;
}
.sj-form-theme .balance-value,
.sj-form-theme .amount-value {
font-size: 48rpx !important;
font-weight: 700 !important;
color: #222 !important;
text-shadow: none !important;
animation: none !important;
}
.sj-form-theme .balance-unit,
.sj-form-theme .amount-unit {
font-size: 28rpx !important;
color: #666 !important;
}
.sj-form-theme .balance-tip {
font-size: 22rpx !important;
color: #999 !important;
}
.sj-form-theme .balance-row,
.sj-form-theme .balance-amount {
justify-content: center !important;
}
.sj-form-theme .card,
.sj-form-theme .section {
background: #fdfcfa !important;
border-radius: 20rpx !important;
padding: 24rpx !important;
margin-bottom: 20rpx !important;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.06) !important;
border: none !important;
}
.sj-form-theme .card-header,
.sj-form-theme .section-title {
margin-bottom: 16rpx !important;
padding-left: 0 !important;
border-left: none !important;
text-shadow: none !important;
}
.sj-form-theme .card-dot {
background: #ffd061 !important;
}
.sj-form-theme .card-title,
.sj-form-theme .section-title {
font-size: 30rpx !important;
font-weight: 700 !important;
color: #222 !important;
}
.sj-form-theme .type-chip,
.sj-form-theme .type-item {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
padding: 12rpx 24rpx !important;
margin-right: 16rpx !important;
border-radius: 30rpx !important;
background: #f5f5f5 !important;
border: none !important;
font-size: 26rpx !important;
color: #666 !important;
opacity: 1 !important;
transform: none !important;
box-shadow: none !important;
backdrop-filter: none !important;
height: auto !important;
min-height: 64rpx !important;
}
.sj-form-theme .type-chip--active,
.sj-form-theme .type-active {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
font-weight: 700 !important;
border: none !important;
transform: none !important;
box-shadow: 0 4rpx 12rpx rgba(255, 208, 97, 0.35) !important;
}
.sj-form-theme .type-text {
color: inherit !important;
}
.sj-form-theme .field {
padding: 20rpx 0 !important;
border-bottom: 1rpx dashed #eee !important;
}
.sj-form-theme .field-label {
font-size: 28rpx !important;
color: #333 !important;
}
.sj-form-theme .field-input {
font-size: 28rpx !important;
color: #333 !important;
background: transparent !important;
}
.sj-form-theme .field-required {
color: #f00 !important;
}
.sj-form-theme .field-hint,
.sj-form-theme .field-optional {
color: #999 !important;
font-size: 22rpx !important;
}
.sj-form-theme .field-picker {
background: #f5f5f5 !important;
border-radius: 12rpx !important;
color: #333 !important;
}
.sj-form-theme .price-prefix {
color: #333 !important;
}
.sj-form-theme .price-input {
color: #333 !important;
}
.sj-form-theme .submit-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
border-radius: 44rpx !important;
font-weight: 700 !important;
box-shadow: 0 6rpx 16rpx rgba(255, 208, 97, 0.35) !important;
}
.sj-form-theme .submit-bar {
background: rgba(255, 255, 255, 0.96) !important;
border-top: 1rpx solid #eee !important;
}
.sj-form-theme switch {
color: #ffd061 !important;
}
.sj-form-theme .search-section {
margin-bottom: 20rpx !important;
}
.sj-form-theme .search-box {
background: #fff !important;
border: 1rpx solid #eee !important;
border-radius: 50rpx !important;
box-shadow: none !important;
}
.sj-form-theme .search-input {
color: #333 !important;
}
.sj-form-theme .search-icon {
color: #999 !important;
}
.sj-form-theme .search-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
box-shadow: none !important;
}
.sj-form-theme .search-btn-text {
color: #492f00 !important;
}
.sj-form-theme .filter-row,
.sj-form-theme .filter-item {
color: #666 !important;
}
.sj-form-theme .filter-input,
.sj-form-theme .picker-view {
background: #f5f5f5 !important;
color: #333 !important;
border-radius: 8rpx !important;
}
.sj-form-theme .template-card {
background: #fdfcfa !important;
border: 1rpx solid rgba(0, 0, 0, 0.06) !important;
border-radius: 20rpx !important;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06) !important;
}
.sj-form-theme .intro-text,
.sj-form-theme .template-price-label,
.sj-form-theme .template-price-value {
color: #333 !important;
}
.sj-form-theme .generate-grid-btn,
.sj-form-theme .copy-grid-btn,
.sj-form-theme .action-grid-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
border: 2rpx solid #fff !important;
box-shadow: none !important;
}
.sj-form-theme .template-section,
.sj-form-theme .template-scroll {
background: transparent !important;
}
.sj-form-theme .empty-tip,
.sj-form-theme .loading-text {
color: #999 !important;
}
.sj-form-theme .tutorial-btn {
background: linear-gradient(180deg, #fae04d, #ffc0a3) !important;
color: #492f00 !important;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1) !important;
}

View File

@@ -1,109 +1,110 @@
// tab-bar/index.js — 三端固定,无身份切换
const app = getApp();
import { getTabRole } from '../utils/primary-role.js';
const roleCfg = {
normal: {
name: '点单老板',
tabList: [
{ pagePath: 'pages/index/index', text: '商城', iconPath: '/images/home.png', selectedIconPath: '/images/home.png' },
{ pagePath: 'pages/category/category', text: '分类', iconPath: '/images/category.png', selectedIconPath: '/images/category.png' },
{ pagePath: 'pages/messages/messages', text: '消息', iconPath: '/images/messages.png', selectedIconPath: '/images/messages.png' },
{ pagePath: 'pages/mine/mine', text: '我的', iconPath: '/images/mine.png', selectedIconPath: '/images/mine.png' },
],
},
dashou: {
name: '接单员',
tabList: [
{ pagePath: 'pages/accept-order/accept-order', text: '接单池', iconPath: '/images/order-pool.png', selectedIconPath: '/images/order-pool.png' },
{ pagePath: 'pages/fighter-orders/fighter-orders', text: '订单', iconPath: '/images/orders.png', selectedIconPath: '/images/orders.png' },
{ pagePath: 'pages/messages/messages', text: '消息', iconPath: '/images/messages.png', selectedIconPath: '/images/messages.png' },
{ pagePath: 'pages/fighter/fighter', text: '我的', iconPath: '/images/mine.png', selectedIconPath: '/images/mine.png' },
],
},
shangjia: {
name: '商家',
tabList: [
{ pagePath: 'pages/merchant-orders/merchant-orders', text: '订单', iconPath: '/images/orders.png', selectedIconPath: '/images/orders.png' },
{ pagePath: 'pages/messages/messages', text: '消息', iconPath: '/images/messages.png', selectedIconPath: '/images/messages.png' },
{ pagePath: 'pages/merchant/merchant', text: '我的', iconPath: '/images/mine.png', selectedIconPath: '/images/mine.png' },
],
},
};
Component({
data: {
selectedIndex: 0,
tabList: [],
currentRole: 'normal',
badgeText: '',
},
lifetimes: {
attached() {
this.refresh();
this._badgeListener = (data) => {
if (data.badgeText !== undefined) {
this.setData({ badgeText: data.badgeText });
}
};
this._roleListener = () => this.refresh();
app.on('tabBarBadgeChanged', this._badgeListener);
app.on('currentRoleChanged', this._roleListener);
},
detached() {
if (this._badgeListener) app.off('tabBarBadgeChanged', this._badgeListener);
if (this._roleListener) app.off('currentRoleChanged', this._roleListener);
},
},
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 token = wx.getStorageSync('token');
let role = getTabRole(app);
if (!token) {
role = 'normal';
}
app.globalData.currentRole = role;
wx.setStorageSync('currentRole', role);
let cfg = roleCfg[role];
if (!cfg) {
cfg = roleCfg.normal;
role = 'normal';
}
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;
this.setData({ currentRole: role, tabList: list, selectedIndex: idx });
},
switchTab(e) {
const path = e.currentTarget.dataset.path;
const idx = e.currentTarget.dataset.index;
if (idx === this.data.selectedIndex) return;
wx.redirectTo({ url: '/' + path });
},
},
});
// tab-bar/index.js — 三端固定,无身份切换
const app = getApp();
import { getTabRole } from '../utils/primary-role.js';
const roleCfg = {
normal: {
name: '点单老板',
tabList: [
{ pagePath: 'pages/index/index', text: '商城', iconPath: '/images/home.png', selectedIconPath: '/images/home.png' },
{ pagePath: 'pages/category/category', text: '分类', iconPath: '/images/category.png', selectedIconPath: '/images/category.png' },
{ pagePath: 'pages/messages/messages', text: '消息', iconPath: '/images/messages.png', selectedIconPath: '/images/messages.png' },
{ pagePath: 'pages/mine/mine', text: '我的', iconPath: '/images/mine.png', selectedIconPath: '/images/mine.png' },
],
},
dashou: {
name: '接单员',
tabList: [
{ pagePath: 'pages/accept-order/accept-order', text: '接单池', iconPath: '/images/order-pool.png', selectedIconPath: '/images/order-pool.png' },
{ pagePath: 'pages/fighter-orders/fighter-orders', text: '订单', iconPath: '/images/orders.png', selectedIconPath: '/images/orders.png' },
{ pagePath: 'pages/messages/messages', text: '消息', iconPath: '/images/messages.png', selectedIconPath: '/images/messages.png' },
{ pagePath: 'pages/fighter/fighter', text: '我的', iconPath: '/images/mine.png', selectedIconPath: '/images/mine.png' },
],
},
shangjia: {
name: '商家',
tabList: [
{ pagePath: 'pages/merchant-home/merchant-home', text: '首页', iconPath: '/images/home.png', selectedIconPath: '/images/home.png' },
{ pagePath: 'pages/messages/messages', text: '消息', iconPath: '/images/messages.png', selectedIconPath: '/images/messages.png' },
{ pagePath: 'pages/merchant-orders/merchant-orders', text: '订单', iconPath: '/images/orders.png', selectedIconPath: '/images/orders.png' },
{ pagePath: 'pages/merchant/merchant', text: '我的', iconPath: '/images/mine.png', selectedIconPath: '/images/mine.png' },
],
},
};
Component({
data: {
selectedIndex: 0,
tabList: [],
currentRole: 'normal',
badgeText: '',
},
lifetimes: {
attached() {
this.refresh();
this._badgeListener = (data) => {
if (data.badgeText !== undefined) {
this.setData({ badgeText: data.badgeText });
}
};
this._roleListener = () => this.refresh();
app.on('tabBarBadgeChanged', this._badgeListener);
app.on('currentRoleChanged', this._roleListener);
},
detached() {
if (this._badgeListener) app.off('tabBarBadgeChanged', this._badgeListener);
if (this._roleListener) app.off('currentRoleChanged', this._roleListener);
},
},
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 token = wx.getStorageSync('token');
let role = getTabRole(app);
if (!token) {
role = 'normal';
}
app.globalData.currentRole = role;
wx.setStorageSync('currentRole', role);
let cfg = roleCfg[role];
if (!cfg) {
cfg = roleCfg.normal;
role = 'normal';
}
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;
this.setData({ currentRole: role, tabList: list, selectedIndex: idx });
},
switchTab(e) {
const path = e.currentTarget.dataset.path;
const idx = e.currentTarget.dataset.index;
if (idx === this.data.selectedIndex) return;
wx.redirectTo({ url: '/' + path });
},
},
});

View File

@@ -1,24 +1,23 @@
<view class="tab-bar">
<view class="bar-row">
<view class="tab-capsule">
<block wx:for="{{tabList}}" wx:key="index">
<view
class="tab-item {{selectedIndex === index ? 'active' : ''}}"
data-path="{{item.pagePath}}"
data-index="{{index}}"
catchtap="switchTab"
>
<view class="badge-container" wx:if="{{item.pagePath === 'pages/messages/messages' && badgeText}}">
<view class="tab-badge">{{badgeText}}</view>
</view>
<image
class="tab-icon"
src="{{selectedIndex === index ? item.selectedIconPath : item.iconPath}}"
mode="aspectFit"
/>
<text class="tab-text">{{item.text}}</text>
</view>
</block>
</view>
</view>
</view>
<view class="c-tab-spacer"></view>
<view class="c-tab-outer">
<view class="c-tab-bar">
<block wx:for="{{tabList}}" wx:key="index">
<view
class="c-tab-item"
data-path="{{item.pagePath}}"
data-index="{{index}}"
catchtap="switchTab"
>
<view class="c-tab-dot" wx:if="{{item.pagePath === 'pages/messages/messages' && badgeText}}">
<text class="c-tab-dot-t">{{badgeText}}</text>
</view>
<image
class="c-tab-ico"
mode="aspectFit"
src="{{selectedIndex === index ? item.selectedIconPath : item.iconPath}}"
/>
<text class="c-tab-txt {{selectedIndex === index ? 'c-tab-txt-on' : ''}}">{{item.text}}</text>
</view>
</block>
</view>
</view>

View File

@@ -1,124 +1,73 @@
/* tab-bar — 三端固定,全宽 Tab 胶囊 */
.c-tab-spacer {
flex-shrink: 0;
width: 100%;
height: calc(100rpx + env(safe-area-inset-bottom));
}
.tab-bar {
position: fixed;
.c-tab-outer {
background: #fff;
border-top: 1rpx solid #e5e5e5;
bottom: 0;
left: 0;
position: fixed;
right: 0;
z-index: 9999;
display: flex;
justify-content: center;
align-items: flex-end;
z-index: 99999;
padding-bottom: env(safe-area-inset-bottom);
background: transparent;
}
.bar-row {
display: flex;
align-items: center;
margin-bottom: 15rpx;
padding: 0 24rpx;
width: 100%;
.c-tab-bar {
align-items: flex-end;
box-sizing: border-box;
}
.tab-capsule {
flex: 1;
display: flex;
align-items: center;
flex-direction: row;
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;
overflow: hidden;
min-height: 100rpx;
padding-top: 8rpx;
}
.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.15) 20%,
rgba(255, 255, 255, 0.22) 50%,
rgba(255, 255, 255, 0.15) 80%,
transparent 100%
);
animation: shine 8s infinite;
z-index: 1;
}
@keyframes shine {
0% { left: -60%; }
15% { left: 100%; }
100% { left: 100%; }
}
.tab-item {
position: relative;
z-index: 2;
display: flex;
flex-direction: column;
.c-tab-item {
align-items: center;
justify-content: center;
min-width: 70rpx;
display: flex;
flex: 1;
flex-direction: column;
justify-content: flex-end;
padding-bottom: 4rpx;
position: relative;
}
.tab-icon {
width: 44rpx;
height: 44rpx;
margin-bottom: 4rpx;
filter: brightness(0) invert(1);
opacity: 0.9;
.c-tab-ico {
height: 48rpx;
width: 48rpx;
}
.tab-text {
.c-tab-txt {
color: #999;
font-size: 20rpx;
color: #aaa;
margin-top: 4rpx;
}
.c-tab-txt-on {
color: #ffd061;
font-weight: 600;
}
.c-tab-dot {
align-items: center;
background: #fa3534;
border-radius: 16rpx;
display: flex;
height: 32rpx;
justify-content: center;
min-width: 32rpx;
padding: 0 6rpx;
position: absolute;
right: 18%;
top: 0;
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;
z-index: 100;
pointer-events: none;
}
.tab-badge {
min-width: 36rpx;
height: 36rpx;
line-height: 36rpx;
padding: 0 10rpx;
background: #ff3b30;
.c-tab-dot-t {
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);
}
page {
padding-bottom: 100rpx;
font-size: 20rpx;
line-height: 1;
}

View File

@@ -1,105 +1,105 @@
/** 三端固定normal | dashou | shangjia认证后不可回退 */
const VALID = ['normal', 'dashou', 'shangjia'];
const LEGACY_CENTER_ROLES = ['guanshi', 'zuzhang', 'kaoheguan'];
/** 旧版管事/组长/考核官主端标识 → 统一回落打手 Tab */
export function migrateLegacyCenterRole(app) {
app = app || getApp();
const cur = wx.getStorageSync('currentRole') || app.globalData.currentRole || '';
const pri = wx.getStorageSync('primaryRole') || '';
const isLegacy = LEGACY_CENTER_ROLES.includes(cur) || LEGACY_CENTER_ROLES.includes(pri);
if (!isLegacy) return false;
const hasDashouSide =
isRoleStatusActive(wx.getStorageSync('dashoustatus'))
|| isRoleStatusActive(wx.getStorageSync('guanshistatus'))
|| isRoleStatusActive(wx.getStorageSync('zuzhangstatus'))
|| isRoleStatusActive(wx.getStorageSync('kaoheguanstatus'));
if (hasDashouSide) {
lockPrimaryRole('dashou', app);
return true;
}
return false;
}
export function isRoleStatusActive(status) {
return Number(status) === 1;
}
/** 读取主端(兼容旧 currentRole / 管事组长落地页) */
export function getPrimaryRole(app) {
app = app || getApp();
const stored = wx.getStorageSync('primaryRole');
if (VALID.includes(stored)) {
return stored;
}
const legacy = wx.getStorageSync('currentRole') || app.globalData.currentRole || 'normal';
if (legacy === 'dashou' || legacy === 'shangjia') {
return legacy;
}
if (legacy === 'guanshi' || legacy === 'zuzhang' || legacy === 'kaoheguan') {
if (isRoleStatusActive(wx.getStorageSync('dashoustatus'))) {
return 'dashou';
}
if (isRoleStatusActive(wx.getStorageSync('shangjiastatus'))) {
return 'shangjia';
}
}
if (isRoleStatusActive(wx.getStorageSync('dashoustatus'))) {
return 'dashou';
}
if (isRoleStatusActive(wx.getStorageSync('shangjiastatus'))) {
return 'shangjia';
}
return 'normal';
}
/** 锁定主端并同步 TabBar 角色 */
export function lockPrimaryRole(role, app) {
if (!VALID.includes(role)) return;
app = app || getApp();
wx.setStorageSync('primaryRole', role);
wx.setStorageSync('currentRole', role);
app.globalData.primaryRole = role;
app.globalData.currentRole = role;
if (app.emitEvent) {
app.emitEvent('currentRoleChanged', { role });
}
}
/** TabBar / IM 使用的有效角色(仅三端) */
export function getTabRole(app) {
return getPrimaryRole(app);
}
export function clearPrimaryRole(app) {
app = app || getApp();
wx.removeStorageSync('primaryRole');
lockPrimaryRole('normal', app);
}
export const PRIMARY_DEFAULT_PAGES = {
normal: '/pages/mine/mine',
dashou: '/pages/accept-order/accept-order',
shangjia: '/pages/merchant-orders/merchant-orders',
};
/** 锁定主端并跳转到该端默认首页,同时建立 IM 长连接 */
export function enterLockedRole(role, app) {
if (!VALID.includes(role) || role === 'normal') return false;
app = app || getApp();
lockPrimaryRole(role, app);
wx.reLaunch({ url: PRIMARY_DEFAULT_PAGES[role] });
setTimeout(() => {
if (app.switchRoleAndReconnect) {
app.switchRoleAndReconnect(role).catch(() => {
if (app.connectForCurrentRole) app.connectForCurrentRole();
});
} else if (app.connectForCurrentRole) {
app.connectForCurrentRole();
}
}, 600);
return true;
}
/** 三端固定normal | dashou | shangjia认证后不可回退 */
const VALID = ['normal', 'dashou', 'shangjia'];
const LEGACY_CENTER_ROLES = ['guanshi', 'zuzhang', 'kaoheguan'];
/** 旧版管事/组长/考核官主端标识 → 统一回落打手 Tab */
export function migrateLegacyCenterRole(app) {
app = app || getApp();
const cur = wx.getStorageSync('currentRole') || app.globalData.currentRole || '';
const pri = wx.getStorageSync('primaryRole') || '';
const isLegacy = LEGACY_CENTER_ROLES.includes(cur) || LEGACY_CENTER_ROLES.includes(pri);
if (!isLegacy) return false;
const hasDashouSide =
isRoleStatusActive(wx.getStorageSync('dashoustatus'))
|| isRoleStatusActive(wx.getStorageSync('guanshistatus'))
|| isRoleStatusActive(wx.getStorageSync('zuzhangstatus'))
|| isRoleStatusActive(wx.getStorageSync('kaoheguanstatus'));
if (hasDashouSide) {
lockPrimaryRole('dashou', app);
return true;
}
return false;
}
export function isRoleStatusActive(status) {
return Number(status) === 1;
}
/** 读取主端(兼容旧 currentRole / 管事组长落地页) */
export function getPrimaryRole(app) {
app = app || getApp();
const stored = wx.getStorageSync('primaryRole');
if (VALID.includes(stored)) {
return stored;
}
const legacy = wx.getStorageSync('currentRole') || app.globalData.currentRole || 'normal';
if (legacy === 'dashou' || legacy === 'shangjia') {
return legacy;
}
if (legacy === 'guanshi' || legacy === 'zuzhang' || legacy === 'kaoheguan') {
if (isRoleStatusActive(wx.getStorageSync('dashoustatus'))) {
return 'dashou';
}
if (isRoleStatusActive(wx.getStorageSync('shangjiastatus'))) {
return 'shangjia';
}
}
if (isRoleStatusActive(wx.getStorageSync('dashoustatus'))) {
return 'dashou';
}
if (isRoleStatusActive(wx.getStorageSync('shangjiastatus'))) {
return 'shangjia';
}
return 'normal';
}
/** 锁定主端并同步 TabBar 角色 */
export function lockPrimaryRole(role, app) {
if (!VALID.includes(role)) return;
app = app || getApp();
wx.setStorageSync('primaryRole', role);
wx.setStorageSync('currentRole', role);
app.globalData.primaryRole = role;
app.globalData.currentRole = role;
if (app.emitEvent) {
app.emitEvent('currentRoleChanged', { role });
}
}
/** TabBar / IM 使用的有效角色(仅三端) */
export function getTabRole(app) {
return getPrimaryRole(app);
}
export function clearPrimaryRole(app) {
app = app || getApp();
wx.removeStorageSync('primaryRole');
lockPrimaryRole('normal', app);
}
export const PRIMARY_DEFAULT_PAGES = {
normal: '/pages/mine/mine',
dashou: '/pages/accept-order/accept-order',
shangjia: '/pages/merchant-home/merchant-home',
};
/** 锁定主端并跳转到该端默认首页,同时建立 IM 长连接 */
export function enterLockedRole(role, app) {
if (!VALID.includes(role) || role === 'normal') return false;
app = app || getApp();
lockPrimaryRole(role, app);
wx.reLaunch({ url: PRIMARY_DEFAULT_PAGES[role] });
setTimeout(() => {
if (app.switchRoleAndReconnect) {
app.switchRoleAndReconnect(role).catch(() => {
if (app.connectForCurrentRole) app.connectForCurrentRole();
});
} else if (app.connectForCurrentRole) {
app.connectForCurrentRole();
}
}, 600);
return true;
}