修正了 pages 名为拼音的问题

This commit is contained in:
2026-06-13 10:44:02 +08:00
parent 76cc4ac55e
commit 296e41a8a7
249 changed files with 29660 additions and 29505 deletions

View File

@@ -0,0 +1,577 @@
// pages/qiangdan/qiangdan.js
const app = getApp();
import request from '../../utils/request.js';
import PopupService from '../../services/popupService.js';
import { reconnectForRole } from '../../utils/role-tab-bar.js';
Page({
data: {
// 1. 商品类型相关
shangpinleixing: [],
xuanzhongLeixingId: null,
// 2. 订单列表与分页相关
dingdanList: [],
page: 1,
pageSize: 5,
hasMore: true,
isLoading: false,
// 3. 全局状态字段
dashoustatus: null,
zhuanghaoStatus: null,
dashouzhuangtai: null,
uid: null,
huiyuanList: [],
yajin: 0,
jifen: 0,
// 4. 刷新控制字段
scrollViewRefreshing: false,
lastRefreshTime: 0,
refreshCooldown: 2000,
isLoadingMore: false,
// 5. 切换类型冷却
lastSwitchTime: 0,
switchCooldown: 1500,
isSwitching: false,
// 6. OSS地址
ossImageUrl: app.globalData.ossImageUrl || '',
// 🆕 7. 标签筛选相关
bankuaiBiaoqian: [], // 当前商品类型所属板块的全部标签
xuanzhongBiaoqianId: 0, // 0=全部
},
async onLoad(options) {
this.loadGlobalStatus();
await this.loadShangpinLeixing();
PopupService.checkAndShow(this, 'jiedan');
},
onHide: function () {
const popupComp = this.selectComponent('#popupNotice');
if (popupComp && popupComp.cleanup) {
popupComp.cleanup();
}
},
onShow() {
this.registerNotificationComponent();
this.loadGlobalStatus();
if (wx.getStorageSync('uid')) {
reconnectForRole('dashou');
if (app.startImWhenReady) app.startImWhenReady();
this.refreshDashouProfileSilent();
}
if (this.data.xuanzhongLeixingId) {
this.loadDingdanList(true);
}
},
async refreshDashouProfileSilent() {
try {
const res = await request({ url: '/yonghu/dashouxinxi', method: 'POST' });
if (!res || res.data.code != 200) return;
const data = res.data.data || {};
const patch = {
dashouNicheng: data.dashounicheng || '',
zhanghaoStatus: data.zhanghaostatus || '',
dashouzhuangtai: data.dashouzhuangtai || '',
yajin: data.yajin || 0,
jifen: data.jifen || 0,
clumber: data.clumber || [],
};
Object.assign(app.globalData, {
dashouNicheng: patch.dashouNicheng,
zhanghaoStatus: patch.zhanghaoStatus,
dashouzhuangtai: patch.dashouzhuangtai,
yajin: patch.yajin,
jinfen: patch.jifen,
clumber: patch.clumber,
});
if (data.dashoustatus !== undefined) {
wx.setStorageSync('dashoustatus', data.dashoustatus);
app.globalData.dashoustatus = data.dashoustatus;
}
this.setData({
zhuanghaoStatus: patch.zhanghaoStatus,
dashouzhuangtai: patch.dashouzhuangtai,
huiyuanList: patch.clumber,
yajin: patch.yajin,
jifen: patch.jifen,
});
} catch (e) {}
},
registerNotificationComponent() {
const notificationComp = this.selectComponent('#global-notification');
if (notificationComp && notificationComp.showNotification) {
app.globalData.globalNotification = {
show: (data) => notificationComp.showNotification(data),
hide: () => notificationComp.hideNotification()
};
}
},
loadGlobalStatus() {
const globalData = app.globalData;
this.setData({
dashoustatus: wx.getStorageSync('dashoustatus'),
zhuanghaoStatus: globalData.zhanghaoStatus,
dashouzhuangtai: globalData.dashouzhuangtai,
uid: wx.getStorageSync('uid'),
huiyuanList: globalData.clumber || [],
yajin: globalData.yajin || 0,
jifen: globalData.jinfen || 0
});
},
// 加载商品类型
async loadShangpinLeixing() {
wx.showLoading({ title: '加载商品类型...' });
try {
const res = await request({
url: '/dingdan/dsqdhqddlx',
method: 'POST',
header: { 'content-type': 'application/json' }
});
if (res.statusCode === 200 && res.data) {
const data = res.data;
let list = [];
if (data.code === 200 || data.code === 0) {
if (data.data && Array.isArray(data.data.list)) list = data.data.list;
else if (data.data && Array.isArray(data.data)) list = data.data;
else if (Array.isArray(data.list)) list = data.list;
else if (Array.isArray(data)) list = data;
}
const processedList = this.processTupianUrl(list);
this.setData({
shangpinleixing: processedList,
xuanzhongLeixingId: processedList[0]?.id || null
});
if (this.data.xuanzhongLeixingId) {
this.loadDingdanList(true);
// 🆕 加载板块标签
this.loadBankuaiBiaoqian();
}
} else {
wx.showToast({ title: res.data?.msg || '加载商品类型失败', icon: 'none' });
}
} catch (error) {
wx.showToast({ title: '网络错误,加载失败', icon: 'none' });
} finally {
wx.hideLoading();
}
},
// 处理图片URL
processTupianUrl(list) {
const ossUrl = app.globalData.ossImageUrl || '';
return list.map(item => ({
...item,
full_tupian_url: item.tupian_url && !item.tupian_url.startsWith('http')
? ossUrl + item.tupian_url
: (item.tupian_url || '/images/default-type.png')
}));
},
// 🆕 加载板块标签
async loadBankuaiBiaoqian() {
const leixingId = this.data.xuanzhongLeixingId;
if (!leixingId) return;
try {
const res = await request({
url: '/dengji/bkqhbq',
method: 'POST',
data: { leixing_id: leixingId }
});
if (res && res.data.code === 0) {
this.setData({
bankuaiBiaoqian: res.data.data.biaoqian_list || [],
xuanzhongBiaoqianId: 0
});
}
} catch (e) {
// 标签加载失败不影响主流程
}
},
// 选择商品类型
async selectLeixing(e) {
const now = Date.now();
const lastSwitchTime = this.data.lastSwitchTime;
const switchCooldown = this.data.switchCooldown;
if (now - lastSwitchTime < switchCooldown) {
wx.showToast({
title: `操作太快,请${Math.ceil((switchCooldown - (now - lastSwitchTime)) / 1000)}秒后再试`,
icon: 'none',
duration: 1500
});
return;
}
if (this.data.isSwitching) return;
const leixingId = e.currentTarget.dataset.id;
if (leixingId === this.data.xuanzhongLeixingId) return;
this.setData({ isSwitching: true, lastSwitchTime: now });
wx.showLoading({ title: '切换中...' });
try {
this.setData({
xuanzhongLeixingId: leixingId,
dingdanList: [],
page: 1,
hasMore: true,
xuanzhongBiaoqianId: 0 // 重置标签筛选
});
await this.loadDingdanList(true);
// 🆕 切换类型后加载新标签
await this.loadBankuaiBiaoqian();
} catch (error) {
console.error('切换类型失败:', error);
} finally {
this.setData({ isSwitching: false });
wx.hideLoading();
}
},
// 🆕 选择标签筛选
async selectBiaoqian(e) {
const id = e.currentTarget.dataset.id;
if (id === this.data.xuanzhongBiaoqianId) return;
this.setData({
xuanzhongBiaoqianId: id,
dingdanList: [],
page: 1,
hasMore: true
});
await this.loadDingdanList(true);
},
// 加载订单列表
async loadDingdanList(isRefresh = false) {
if (this.data.isLoading || !this.data.xuanzhongLeixingId) return;
const loadPage = isRefresh ? 1 : this.data.page;
if (!isRefresh && !this.data.hasMore) return;
this.setData({
isLoading: true,
isLoadingMore: !isRefresh
});
try {
const res = await request({
url: '/dingdan/ddhq',
method: 'POST',
data: {
leixing_id: this.data.xuanzhongLeixingId,
page: loadPage,
page_size: this.data.pageSize,
// 🆕 传递标签筛选参数0时不传
biaoqian_id: this.data.xuanzhongBiaoqianId || undefined
}
});
this.setData({
isLoading: false,
isLoadingMore: false,
scrollViewRefreshing: false
});
if (res.data.code === 200 || res.data.code === 0) {
const newList = res.data.data.list || [];
const hasMore = res.data.data.has_more || false;
// 🆕 处理每条订单,增加 hasRequiredMember 字段
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 || '';
// 🆕 判断用户是否有订单所需的会员仅当订单要求会员类型且存在huiyuan_id
let hasRequiredMember = true;
if (item.yaoqiuleixing == 1 && item.huiyuan_id) {
const userHasIt = this.data.huiyuanList.some(h => h.huiyuanid == item.huiyuan_id);
hasRequiredMember = userHasIt;
}
return {
...item,
full_tupian_url: fullTupianUrl,
isZhiding: isZhiding,
isPingtai: item.pingtai == 1,
isShangjia: item.pingtai == 2,
zhiding_avatar_full: zhidingAvatar,
zhiding_nicheng: zhidingNicheng,
// 🆕 三层标签(后端返回,直接保留)
xuqiu_biaoqian: item.xuqiu_biaoqian || [],
dashou_biaoqian: item.dashou_biaoqian || [],
shangjia_biaoqian: item.shangjia_biaoqian || [],
// 🆕 是否有查看价格的权限
hasRequiredMember: hasRequiredMember,
};
},
// 跳转到充值页面(原封不动)
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('&');
wx.navigateTo({
url: `${url}?${queryString}`,
fail: (err) => {
console.error('跳转失败:', err);
wx.showToast({ title: '跳转失败,请稍后重试', icon: 'none' });
}
});
},
// 抢单按钮(原封不动)
async onQiangdanTap(e) {
const dingdanItem = e.currentTarget.dataset.item;
if (!dingdanItem) return;
// 校验1: 打手身份
if (!this.data.dashoustatus || this.data.dashoustatus != 1) {
wx.showToast({ title: '请先开启打手身份', icon: 'none' });
return;
}
// 校验2: 账号状态
if (this.data.zhuanghaoStatus != 1) {
wx.showToast({ title: '账号异常,无法接单', icon: 'none' });
return;
}
// 校验3: 打手接单状态
if (this.data.dashouzhuangtai != 1) {
wx.showToast({ title: '您有订单正在接待中', icon: 'none' });
return;
}
// 校验4: 指定订单
if (dingdanItem.isZhiding) {
if (!this.data.uid || this.data.uid != dingdanItem.zhiding_uid) {
wx.showToast({ title: '此订单为指定单', icon: 'none' });
return;
}
}
// 校验5: 会员要求
if (dingdanItem.yaoqiuleixing == 1) {
const hasHuiyuan = this.data.huiyuanList.some(h => h.huiyuanid == dingdanItem.huiyuan_id);
if (!hasHuiyuan) {
wx.showToast({
title: '未开通对应会员,无法抢单',
icon: 'none',
duration: 2000
});
setTimeout(() => {
this.goToChongzhiPage('huiyuan', dingdanItem.huiyuan_id);
}, 500);
return;
}
}
// 校验6: 押金要求
if (dingdanItem.yaoqiuleixing == 2) {
if (this.data.yajin < dingdanItem.yajin) {
wx.showToast({
title: `押金不足,需${dingdanItem.yajin}`,
icon: 'none',
duration: 2000
});
setTimeout(() => {
this.goToChongzhiPage('yajin', null, dingdanItem.yajin);
}, 500);
return;
}
}
// 校验7: 积分要求
if (this.data.jifen < 5) {
wx.showToast({
title: '积分不足至少需要5积分',
icon: 'none',
duration: 2000
});
setTimeout(() => {
this.goToChongzhiPage('jifen');
}, 500);
return;
}
// 确认框
const that = this;
wx.showModal({
title: '确认抢单',
content: `确定要抢此订单吗?${dingdanItem.isZhiding ? '(指定订单)' : ''}`,
success: async function (res) {
if (res.confirm) {
wx.showLoading({ title: '抢单中...', mask: true });
try {
const qiangdanRes = await request({
url: '/dingdan/qiangdan',
method: 'POST',
data: { dingdan_id: dingdanItem.dingdan_id }
});
wx.hideLoading();
if (qiangdanRes.data.code === 200 || qiangdanRes.data.code === 0) {
that.showQiangdanSuccessEffect();
if (app.globalData) {
app.globalData.dashouzhuangtai = 0;
that.setData({ dashouzhuangtai: 0 });
}
const newList = that.data.dingdanList.filter(
item => item.dingdan_id !== dingdanItem.dingdan_id
);
that.setData({ dingdanList: newList });
} else {
wx.showToast({
title: qiangdanRes.data.msg || '抢单失败',
icon: 'none'
});
}
} catch (error) {
wx.hideLoading();
console.error('抢单请求失败:', error);
wx.showToast({ title: '网络错误,抢单失败', icon: 'none' });
}
}
}
});
},
showQiangdanSuccessEffect() {
wx.showToast({ title: '抢单成功!', icon: 'success', duration: 2000 });
},
onViewDetail(e) {
const { type, content } = e.currentTarget.dataset;
wx.showModal({
title: type === 'jieshao' ? '订单介绍' : '订单备注',
content: content,
showCancel: false,
confirmText: '知道了'
});
},
onReachBottom() {
const now = Date.now();
const lastTime = this.data.lastRefreshTime;
const cooldown = this.data.refreshCooldown;
if (now - lastTime < cooldown) {
wx.showToast({
title: `操作太快,请${Math.ceil((cooldown - (now - lastTime)) / 1000)}秒后再试`,
icon: 'none',
duration: 1500
});
return;
}
if (this.data.isLoading || this.data.isLoadingMore) return;
if (this.data.hasMore && !this.data.isLoading && this.data.xuanzhongLeixingId) {
this.setData({ page: this.data.page + 1 });
this.loadDingdanList(false);
}
},
onPullDownRefresh() {
const now = Date.now();
const lastTime = this.data.lastRefreshTime;
const cooldown = this.data.refreshCooldown;
if (now - lastTime < cooldown) {
this.setData({ scrollViewRefreshing: false });
wx.showToast({
title: `操作太快,请${Math.ceil((cooldown - (now - lastTime)) / 1000)}秒后再试`,
icon: 'none',
duration: 1500
});
return;
}
if (this.data.isLoading) {
this.setData({ scrollViewRefreshing: false });
return;
}
this.setData({
scrollViewRefreshing: true,
lastRefreshTime: now,
page: 1,
hasMore: true
});
if (this.data.xuanzhongLeixingId) {
this.loadDingdanList(true);
} else {
this.setData({ scrollViewRefreshing: false });
}
}
});

View File

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

View File

@@ -0,0 +1,220 @@
<!-- 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>
<view class="fenge-xian"></view>
<!-- 订单列表 -->
<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>
<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="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>
<!-- 指定打手行(新增标签滚动) -->
<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>
<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>
<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>
<!-- 🆕 订单需求标签 -->
<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>
<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>
<!-- 商家订单卡片 -->
<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>
<!-- 指定打手行 -->
<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>
<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 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>
<!-- 🆕 订单需求标签 -->
<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>
<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>
</view>
<global-notification id="global-notification" />
<popup-notice id="popupNotice" />
<custom-tab-bar />
</view>

View File

@@ -0,0 +1,762 @@
/* pages/qiangdan/qiangdan.wxss - 高级机甲风格重构版(对称优化) */
.qiangdan-page {
height: 100vh;
display: flex;
flex-direction: column;
background: radial-gradient(ellipse at top, #1a1f30, #0b0f1a);
overflow: hidden;
position: relative;
}
/* 背景动态纹理,增加层次感 */
.qiangdan-page::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
linear-gradient(45deg, rgba(0, 247, 255, 0.02) 0%, transparent 30%),
radial-gradient(circle at 30% 50%, rgba(255, 77, 109, 0.03) 0%, transparent 50%),
repeating-linear-gradient(45deg, rgba(255,255,255,0.01) 0px, rgba(255,255,255,0.01) 1px, transparent 1px, transparent 6px);
pointer-events: none;
z-index: 0;
}
/* ====== 1. 商品类型区域 ====== */
.leixing-quyu {
padding: 30rpx 0 20rpx;
background: rgba(18, 22, 38, 0.9);
backdrop-filter: blur(20rpx);
border-bottom: 1rpx solid rgba(255, 255, 255, 0.05);
position: relative;
z-index: 10;
flex-shrink: 0;
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.5);
}
.leixing-scroll {
width: 100%;
white-space: nowrap;
height: 180rpx;
}
.leixing-container {
display: inline-flex;
padding: 0 30rpx;
gap: 20rpx;
}
.leixing-item {
display: inline-flex;
flex-direction: column;
align-items: center;
width: 160rpx;
position: relative;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.leixing-active {
transform: translateY(-8rpx);
}
.guangyun-effect {
position: absolute;
top: -15rpx;
left: -15rpx;
right: -15rpx;
bottom: -15rpx;
background: radial-gradient(circle at center, rgba(0, 200, 255, 0.3) 0%, transparent 70%);
border-radius: 50rpx;
z-index: 0;
animation: guangyun-pulse 2s infinite ease-in-out;
}
@keyframes guangyun-pulse {
0%, 100% { opacity: 0.5; transform: scale(1); }
50% { opacity: 1; transform: scale(1.1); }
}
.leixing-tupian {
width: 120rpx;
height: 120rpx;
border-radius: 32rpx;
z-index: 1;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.6);
transition: all 0.3s ease;
border: 2rpx solid rgba(0, 200, 255, 0.4);
}
.leixing-active .leixing-tupian {
box-shadow: 0 16rpx 40rpx rgba(0, 200, 255, 0.5);
border: 2rpx solid #00c8ff;
}
.leixing-jieshao {
margin-top: 16rpx;
font-size: 24rpx;
color: #b0c0e0;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
z-index: 1;
font-weight: 500;
}
.leixing-active .leixing-jieshao {
color: #00c8ff;
text-shadow: 0 0 8px rgba(0,200,255,0.5);
}
/* ====== 2. 分割线 ====== */
.fenge-xian {
height: 2rpx;
background: linear-gradient(90deg, transparent, #00c8ff, #ff4d6d, transparent);
flex-shrink: 0;
margin: 0 30rpx;
opacity: 0.5;
}
/* ====== 3. 订单列表容器 ====== */
.dingdan-container {
flex: 1;
overflow: hidden;
position: relative;
z-index: 1;
padding: 0 20rpx; /* 统一左右内边距 */
}
.dingdan-scroll-view {
height: 100%;
-webkit-overflow-scrolling: touch;
}
.refresher-container {
height: 100rpx;
display: flex;
align-items: center;
justify-content: center;
}
.refreshing-text,
.pull-down-text {
font-size: 26rpx;
color: #6a9cff;
text-shadow: 0 0 8px rgba(0,200,255,0.3);
}
/* ====== 4. 空状态提示 ====== */
.empty-tip {
padding: 160rpx 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.tip-icon {
width: 180rpx;
height: 180rpx;
opacity: 0.5;
margin-bottom: 30rpx;
filter: drop-shadow(0 0 20px rgba(0,200,255,0.3));
}
.tip-text {
font-size: 28rpx;
color: #8a9ac0;
letter-spacing: 2rpx;
}
/* ====== 5. 订单卡片通用样式(移除左右边框,改用顶部标识)====== */
.dingdan-card {
margin: 20rpx 0; /* 左右由容器控制 */
border-radius: 36rpx;
padding: 28rpx 24rpx;
position: relative;
overflow: hidden;
box-shadow: 0 20rpx 40rpx rgba(0, 0, 0, 0.6);
transition: all 0.3s ease;
border: 1rpx solid rgba(255, 255, 255, 0.03);
backdrop-filter: blur(30rpx);
}
.dingdan-card:active {
transform: scale(0.998);
box-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.8);
}
/* 平台订单 - 冷色调,顶部光效 */
.pingtai-card {
background: linear-gradient(145deg, rgba(18, 28, 48, 0.95), rgba(8, 18, 35, 0.98));
}
.pingtai-card::before {
content: '';
position: absolute;
top: 0;
left: 10%;
width: 80%;
height: 4rpx;
background: linear-gradient(90deg, transparent, #00c8ff, transparent);
border-radius: 2rpx;
opacity: 0.7;
}
/* 商家订单 - 暖色调,顶部光效 */
.shangjia-card {
background: linear-gradient(145deg, rgba(38, 18, 48, 0.95), rgba(25, 8, 35, 0.98));
}
.shangjia-card::before {
content: '';
position: absolute;
top: 0;
left: 10%;
width: 80%;
height: 4rpx;
background: linear-gradient(90deg, transparent, #ff4d6d, transparent);
border-radius: 2rpx;
opacity: 0.7;
}
/* 卡片顶部 */
.card-top {
display: flex;
align-items: center;
margin-bottom: 20rpx;
padding-bottom: 16rpx;
border-bottom: 1rpx dashed rgba(255, 255, 255, 0.08);
}
.creat-time {
font-size: 26rpx;
color: #c0d0ff;
font-weight: 500;
text-shadow: 0 0 5px rgba(0,200,255,0.3);
}
.top-line {
flex: 1;
height: 1rpx;
background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.2), transparent);
margin: 0 20rpx;
}
.pingtai-tag {
font-size: 24rpx;
color: #aac8ff;
padding: 6rpx 18rpx;
background: rgba(0,200,255,0.08);
border-radius: 40rpx;
border: 1rpx solid rgba(0,200,255,0.3);
box-shadow: 0 0 10rpx rgba(0,200,255,0.2);
}
/* ====== 6. 指定单标识行(新设计)====== */
.zhiding-row {
display: flex;
align-items: center;
margin-bottom: 24rpx;
padding: 12rpx 20rpx;
background: rgba(255, 77, 109, 0.1);
border-radius: 60rpx;
border: 1rpx solid rgba(255, 77, 109, 0.3);
box-shadow: 0 0 20rpx rgba(255, 77, 109, 0.2);
backdrop-filter: blur(10rpx);
gap: 12rpx;
}
.zhiding-icon {
font-size: 28rpx;
color: #ff4d6d;
font-weight: 700;
background: rgba(255, 77, 109, 0.2);
padding: 4rpx 16rpx;
border-radius: 40rpx;
text-shadow: 0 0 8px #ff4d6d;
letter-spacing: 2rpx;
}
.zhiding-avatar {
width: 48rpx;
height: 48rpx;
border-radius: 50%;
border: 2rpx solid #ff4d6d;
box-shadow: 0 0 15rpx #ff4d6d;
object-fit: cover;
}
.zhiding-nicheng {
font-size: 26rpx;
color: #ffc0d0;
font-weight: 500;
max-width: 160rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.zhiding-uid {
font-size: 24rpx;
color: #ff9aab;
flex: 1;
text-align: right;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-family: monospace;
}
/* ====== 7. 平台订单内容区 ====== */
.card-content {
display: flex;
margin-bottom: 24rpx;
align-items: center;
}
.neirong-tupian {
width: 140rpx;
height: 140rpx;
border-radius: 50%;
margin-right: 24rpx;
flex-shrink: 0;
box-shadow: 0 10rpx 30rpx rgba(0,200,255,0.3);
border: 2rpx solid #00c8ff;
object-fit: cover;
}
.jieshao-box {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
min-height: 140rpx;
padding: 8rpx 0;
}
.jieshao-label {
font-size: 26rpx;
color: #d0e0ff;
font-weight: 600;
margin-bottom: 6rpx;
text-shadow: 0 0 5px rgba(0,200,255,0.3);
}
.jieshao-text {
font-size: 26rpx;
color: #b0c8f0;
line-height: 1.4;
word-break: break-word;
}
.jieshao-ellipsis .jieshao-text {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
}
/* ====== 8. 商家订单特有样式 ====== */
.shangjia-info {
display: flex;
align-items: center;
margin-bottom: 20rpx;
}
.shangjia-touxiang {
width: 90rpx;
height: 90rpx;
border-radius: 50%;
margin-right: 20rpx;
border: 2rpx solid #ff4d6d;
box-shadow: 0 6rpx 18rpx rgba(255, 77, 109, 0.5);
object-fit: cover;
}
.shangjia-nicheng {
font-size: 30rpx;
color: #ffb3c6;
font-weight: 600;
text-shadow: 0 0 8px rgba(255, 77, 109, 0.4);
}
.shangjia-jieshao,
.shangjia-beizhu {
margin-bottom: 16rpx;
padding: 14rpx 18rpx;
background: rgba(255, 255, 255, 0.02);
border-radius: 24rpx;
border: 1rpx solid rgba(255, 77, 109, 0.2);
}
.shangjia-jieshao .jieshao-label,
.shangjia-beizhu .beizhu-label {
display: block;
margin-bottom: 6rpx;
font-size: 24rpx;
color: #ff9aab;
}
.shangjia-jieshao .jieshao-text,
.shangjia-beizhu .beizhu-text {
font-size: 24rpx;
color: #e0c8ff;
line-height: 1.4;
}
.shangjia-jieshao.jieshao-ellipsis .jieshao-text {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
.shangjia-beizhu.beizhu-ellipsis .beizhu-text {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
/* ====== 9. 通用备注区 ====== */
.beizhu-box {
margin-bottom: 20rpx;
padding: 14rpx 18rpx;
background: rgba(255, 255, 255, 0.02);
border-radius: 24rpx;
border: 1rpx solid rgba(0,200,255,0.2);
}
.beizhu-label {
font-size: 24rpx;
color: #80d0ff;
font-weight: 600;
margin-bottom: 6rpx;
display: block;
}
.beizhu-text {
font-size: 24rpx;
color: #b0c8f0;
line-height: 1.4;
}
.beizhu-ellipsis .beizhu-text {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
.view-more {
display: block;
font-size: 22rpx;
color: #00c8ff;
margin-top: 6rpx;
text-align: right;
opacity: 0.8;
text-shadow: 0 0 5px #00c8ff;
}
/* ====== 10. 卡片底部:分佣 + 按钮 ====== */
.card-bottom {
display: flex;
align-items: center;
justify-content: space-between;
padding-top: 20rpx;
border-top: 1rpx solid rgba(255, 255, 255, 0.06);
}
/* 分佣容器(图标占位,用户可自定义) */
.fenyong-box {
display: flex;
align-items: baseline;
background: rgba(0, 0, 0, 0.3);
padding: 8rpx 20rpx;
border-radius: 60rpx;
border: 1rpx solid rgba(255, 215, 0, 0.3);
}
/* 分佣图标占位符,用户可替换为自己图标 */
.fenyong-icon {
font-size: 32rpx;
margin-right: 10rpx;
filter: drop-shadow(0 0 8px gold);
}
.fenyong-text {
font-size: 24rpx;
color: #c0b0a0;
margin-right: 8rpx;
}
.fenyong-price {
font-size: 44rpx;
color: #ffd700;
font-weight: 800;
margin-right: 4rpx;
text-shadow: 0 0 20px rgba(255, 215, 0, 0.8);
}
.fenyong-unit {
font-size: 24rpx;
color: #a0a0b0;
}
/* ====== 11. 机甲风格抢单按钮(对称优化)====== */
.qiangdan-btn {
position: relative;
padding: 16rpx 44rpx;
border: none;
overflow: hidden;
transition: all 0.2s ease;
cursor: pointer;
z-index: 1;
/* 多边形形状,保证上下对称 */
clip-path: polygon(10% 0%, 90% 0%, 100% 25%, 100% 75%, 90% 100%, 10% 100%, 0% 75%, 0% 25%);
}
/* 按钮统一基础样式,无上下不对称阴影 */
.mecha-btn {
background: linear-gradient(145deg, #2a3050, #181e38);
box-shadow:
0 8rpx 0 #0a0a1a,
0 12rpx 28rpx rgba(0, 0, 0, 0.7),
inset 0 2rpx 6rpx rgba(255, 255, 255, 0.2),
inset 0 -2rpx 4rpx rgba(0, 0, 0, 0.3);
border: 1rpx solid rgba(255, 255, 255, 0.1);
}
/* 平台按钮冷光 */
.pingtai-btn.mecha-btn {
background: linear-gradient(145deg, #1a2a48, #0e1a30);
box-shadow:
0 8rpx 0 #0a1525,
0 12rpx 28rpx rgba(0, 0, 0, 0.7),
inset 0 2rpx 6rpx #00c8ff,
inset 0 -2rpx 4rpx rgba(0, 0, 0, 0.3);
}
/* 商家按钮暖光 */
.shangjia-btn.mecha-btn {
background: linear-gradient(145deg, #3a2048, #251030);
box-shadow:
0 8rpx 0 #2a0a1a,
0 12rpx 28rpx rgba(0, 0, 0, 0.7),
inset 0 2rpx 6rpx #ff4d6d,
inset 0 -2rpx 4rpx rgba(0, 0, 0, 0.3);
}
.btn-text {
font-size: 32rpx;
color: #fff;
font-weight: 700;
letter-spacing: 3rpx;
position: relative;
z-index: 3;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.7), 0 0 15rpx currentColor;
}
/* 扫光效果 */
.btn-shine {
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: linear-gradient(
to right,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.25) 50%,
rgba(255, 255, 255, 0) 100%
);
transform: rotate(30deg);
animation: btn-shimmer 2.8s infinite linear;
z-index: 2;
}
/* 内发光,只在悬停/按下时出现,保证对称 */
.btn-glow {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.5), transparent 70%);
opacity: 0;
transition: opacity 0.3s;
z-index: 1;
}
.mecha-btn:hover .btn-glow,
.mecha-btn:active .btn-glow {
opacity: 0.3;
}
/* 按下效果,保持对称 */
.mecha-btn:active {
transform: translateY(4rpx) scale(0.98);
box-shadow:
0 4rpx 0 #0a0a1a,
0 8rpx 20rpx rgba(0, 0, 0, 0.7),
inset 0 2rpx 6rpx rgba(255, 255, 255, 0.2),
inset 0 -2rpx 4rpx rgba(0, 0, 0, 0.3);
}
/* 机械纹理,保持视觉丰富但不过分 */
.mecha-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image:
repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.02) 0px, rgba(255, 255, 255, 0.02) 2px, transparent 2px, transparent 8px);
pointer-events: none;
z-index: 1;
opacity: 0.5;
}
@keyframes btn-shimmer {
0% { transform: translateX(-100%) rotate(30deg); }
100% { transform: translateX(100%) rotate(30deg); }
}
/* ====== 12. 加载状态 ====== */
.loading-more,
.no-more {
padding: 40rpx 0;
text-align: center;
}
.loading-text {
font-size: 26rpx;
color: #6a9cff;
text-shadow: 0 0 10px rgba(0,200,255,0.5);
animation: pulse 1.5s infinite;
}
.no-more-text {
font-size: 26rpx;
color: #4a5a8a;
letter-spacing: 3rpx;
}
@keyframes pulse {
0%, 100% { opacity: 0.7; }
50% { opacity: 1; }
}
.loading-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(5, 8, 18, 0.95);
backdrop-filter: blur(30rpx);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 9999;
}
.loading-spinner {
width: 90rpx;
height: 90rpx;
border: 6rpx solid rgba(0,200,255,0.2);
border-top: 6rpx solid #00c8ff;
border-right: 6rpx solid #ff4d6d;
border-radius: 50%;
animation: spin 1.2s cubic-bezier(0.68, -0.55, 0.27, 1.55) infinite;
margin-bottom: 30rpx;
box-shadow: 0 0 50rpx #00c8ff;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-mask-text {
font-size: 30rpx;
color: #c0d0ff;
text-shadow: 0 0 15px rgba(0,200,255,0.7);
letter-spacing: 4rpx;
}
/* 🆕 标签筛选区 */
.biaoqian-quyu {
padding: 12rpx 20rpx;
background: rgba(18, 22, 38, 0.7);
backdrop-filter: blur(10rpx);
}
.biaoqian-scroll {
white-space: nowrap;
height: 80rpx;
}
.biaoqian-container {
display: inline-flex;
gap: 16rpx;
padding-right: 20rpx;
}
.biaoqian-item {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0 12rpx;
border-radius: 20rpx;
background: rgba(255,255,255,0.05);
transition: all 0.2s;
}
.biaoqian-active {
background: rgba(0,200,255,0.2);
border: 1rpx solid #00c8ff;
}
.quanbu-text {
font-size: 26rpx;
color: #ccc;
padding: 0 12rpx;
}
/* 订单卡片内标签滚动 */
.xuqiu-biaoqian-area {
display: flex;
align-items: center;
margin-top: 16rpx;
padding: 8rpx 0;
}
.xuqiu-label {
font-size: 24rpx;
color: #80d0ff;
margin-right: 12rpx;
flex-shrink: 0;
}
.xuqiu-biaoqian-scroll {
flex: 1;
white-space: nowrap;
}
.biaoqian-inline-scroll {
flex: 1;
white-space: nowrap;
margin-left: 10rpx;
}
/* 调整指定打手行内的标签滚动 */
.zhiding-row .biaoqian-inline-scroll {
margin-left: auto;
max-width: 50%;
}