461 lines
14 KiB
JavaScript
461 lines
14 KiB
JavaScript
// pages/kaohe_jinpai/kaohe_jinpai.js
|
||
const app = getApp();
|
||
import request from '../../utils/request.js';
|
||
|
||
Page({
|
||
data: {
|
||
activeTab: 'all_tags',
|
||
plateList: [], // 第一个接口返回的所有板块及标签(含 fee_list)
|
||
myTags: [],
|
||
recordList: [],
|
||
recordPage: 1,
|
||
recordHasMore: true,
|
||
recordLoading: false,
|
||
recordFilter: 'pending',
|
||
showApplyModal: false,
|
||
selectedTag: null,
|
||
applyGameNick: '',
|
||
applyRemark: '',
|
||
applyFee: 0,
|
||
applyJiluId: '',
|
||
isReapply: false,
|
||
payLoading: false,
|
||
ossImageUrl: app.globalData.ossImageUrl || '',
|
||
|
||
// 新增:考核官相关
|
||
kaoheguanList: [], // 所有可选的考核官
|
||
showKaoheguanModal: false, // 考核官选择弹窗
|
||
selectedKaoheguanId: '', // 已选择的考核官ID
|
||
selectedKaoheguanInfo: null, // 已选择的考核官信息(用于展示)
|
||
searchKeyword: '', // 搜索关键词
|
||
filteredKaoheguanList: [], // 搜索过滤后的列表
|
||
},
|
||
|
||
onLoad() {
|
||
this.fetchAllTags();
|
||
this.fetchMyRecords(true);
|
||
},
|
||
|
||
switchTab(e) {
|
||
const tab = e.currentTarget.dataset.tab;
|
||
if (tab === this.data.activeTab) return;
|
||
this.setData({ activeTab: tab });
|
||
if (tab === 'my_records') this.fetchMyRecords(true);
|
||
},
|
||
|
||
// 获取所有板块及标签(含费用列表),缓存到 plateList,同时获取考核官列表
|
||
async fetchAllTags() {
|
||
try {
|
||
const res = await request({ url: '/dengji/dskhhq', method: 'POST' });
|
||
if (res.data.code === 0) {
|
||
const { plate_list, my_tags, kaoheguan_list } = res.data.data;
|
||
// 拼接考核官头像为完整URL
|
||
const ossUrl = this.data.ossImageUrl;
|
||
const processedKgList = (kaoheguan_list || []).map(kg => ({
|
||
...kg,
|
||
avatar: kg.avatar && !kg.avatar.startsWith('http') ? ossUrl + kg.avatar : kg.avatar,
|
||
}));
|
||
this.setData({
|
||
plateList: plate_list || [],
|
||
myTags: my_tags || [],
|
||
kaoheguanList: processedKgList // 使用拼接后的列表
|
||
});
|
||
}
|
||
} catch (e) {}
|
||
},
|
||
|
||
// 获取我的考核记录,并根据 plateList 计算本次/预计下次费用
|
||
async fetchMyRecords(isRefresh = false) {
|
||
if (this.data.recordLoading) return;
|
||
const page = isRefresh ? 1 : this.data.recordPage;
|
||
this.setData({ recordLoading: true });
|
||
try {
|
||
const res = await request({
|
||
url: '/dengji/dskhjl',
|
||
method: 'POST',
|
||
data: { status: this.data.recordFilter, page, page_size: 5 }
|
||
});
|
||
if (res.data.code === 0) {
|
||
const { list, has_more } = res.data.data;
|
||
|
||
// 从 plateList 构建标签ID -> 完整标签对象的映射(用于精确匹配费用)
|
||
const tagMap = {};
|
||
this.data.plateList.forEach(plate => {
|
||
(plate.tags || []).forEach(tag => {
|
||
tagMap[tag.id] = tag; // tag 包含 fee_list
|
||
});
|
||
});
|
||
|
||
// 处理每条记录:优先使用 tag_obj.id 匹配,其次 chenghao_id
|
||
const processed = list.map(item => {
|
||
// 尝试多种方式获取标签ID
|
||
const tagId = (item.tag_obj && item.tag_obj.id) || item.chenghao_id;
|
||
const tag = tagMap[tagId] || item.tag_obj || {};
|
||
const feeList = tag.fee_list || [];
|
||
let currentFee = 0;
|
||
let nextFee = 0;
|
||
if (feeList.length > 0) {
|
||
const cishu = item.cishu;
|
||
const cur = feeList.find(f => f.cishu === cishu);
|
||
currentFee = cur ? cur.feiyong : feeList[feeList.length - 1].feiyong;
|
||
const nextCishu = cishu + 1;
|
||
const nxt = feeList.find(f => f.cishu === nextCishu);
|
||
nextFee = nxt ? nxt.feiyong : feeList[feeList.length - 1].feiyong;
|
||
}
|
||
return {
|
||
...item,
|
||
current_fee: currentFee,
|
||
next_fee: nextFee,
|
||
tag_obj: tag // 使用匹配到的完整标签对象,保证后续“再次考核”能拿到费用
|
||
};
|
||
});
|
||
|
||
const newList = isRefresh ? processed : [...this.data.recordList, ...processed];
|
||
this.setData({
|
||
recordList: newList,
|
||
recordPage: page + 1,
|
||
recordHasMore: has_more,
|
||
recordLoading: false
|
||
});
|
||
} else {
|
||
this.setData({ recordLoading: false });
|
||
}
|
||
} catch (e) {
|
||
this.setData({ recordLoading: false });
|
||
}
|
||
},
|
||
|
||
filterRecord(e) {
|
||
const filter = e.currentTarget.dataset.filter;
|
||
if (filter === this.data.recordFilter) return;
|
||
this.setData({ recordFilter: filter, recordList: [], recordPage: 1, recordHasMore: true });
|
||
this.fetchMyRecords(true);
|
||
},
|
||
|
||
onReachBottom() {
|
||
if (this.data.activeTab === 'my_records' && this.data.recordHasMore) {
|
||
this.fetchMyRecords(false);
|
||
}
|
||
},
|
||
|
||
// 打开申请考核弹窗,费用完全基于 plateList 中的标签数据
|
||
openApplyModal(e) {
|
||
const { tag, jiluid, reapply } = e.currentTarget.dataset;
|
||
// 查找完整标签对象,保证 fee_list 存在
|
||
let fullTag = tag;
|
||
if (fullTag && fullTag.fee_list === undefined) {
|
||
const found = this.findTagInPlateList(fullTag.id);
|
||
if (found) fullTag = found;
|
||
}
|
||
if (!fullTag) {
|
||
const found = this.findTagInPlateList(tag);
|
||
if (found) fullTag = found;
|
||
}
|
||
|
||
let fee = 0;
|
||
if (fullTag) {
|
||
let nextCishu = 0;
|
||
// 再次申请时,基于原记录次数计算下一次考核次数
|
||
if (reapply && jiluid) {
|
||
const record = this.data.recordList.find(r => r.jilu_id === jiluid);
|
||
if (record) {
|
||
nextCishu = record.cishu + 1;
|
||
} else {
|
||
nextCishu = (fullTag.my_cishu || 0) + 1;
|
||
}
|
||
} else {
|
||
nextCishu = (fullTag.my_cishu || 0) + 1;
|
||
}
|
||
const feeList = fullTag.fee_list || [];
|
||
const exact = feeList.find(f => f.cishu === nextCishu);
|
||
if (exact) {
|
||
fee = exact.feiyong;
|
||
} else if (feeList.length > 0) {
|
||
fee = feeList[feeList.length - 1].feiyong;
|
||
}
|
||
}
|
||
// 检查再次申请时原记录是否有考核官,若有则不允许指定
|
||
let canSpecify = true;
|
||
let originalShenheguanId = '';
|
||
if (reapply && jiluid) {
|
||
const record = this.data.recordList.find(r => r.jilu_id === jiluid);
|
||
if (record && record.shenheguan_id) {
|
||
canSpecify = false; // 已有考核官,不能指定新的
|
||
originalShenheguanId = record.shenheguan_id;
|
||
}
|
||
}
|
||
this.setData({
|
||
showApplyModal: true,
|
||
selectedTag: fullTag || null,
|
||
applyGameNick: '',
|
||
applyRemark: '',
|
||
applyFee: fee,
|
||
applyJiluId: jiluid || '',
|
||
isReapply: reapply || false,
|
||
selectedKaoheguanId: '', // 重置
|
||
selectedKaoheguanInfo: null,
|
||
canSpecify: canSpecify, // 新增
|
||
originalShenheguanId: originalShenheguanId, // 新增
|
||
});
|
||
},
|
||
|
||
// 辅助方法:从 plateList 查找指定 id 的标签
|
||
findTagInPlateList(tagId) {
|
||
if (!tagId) return null;
|
||
for (const plate of this.data.plateList) {
|
||
for (const t of (plate.tags || [])) {
|
||
if (t.id === tagId) return t;
|
||
}
|
||
}
|
||
return null;
|
||
},
|
||
|
||
closeApplyModal() {
|
||
this.setData({ showApplyModal: false });
|
||
},
|
||
|
||
// 实时更新游戏昵称
|
||
onNickInput(e) {
|
||
this.setData({ applyGameNick: e.detail.value });
|
||
},
|
||
|
||
// 实时更新备注
|
||
onRemarkInput(e) {
|
||
this.setData({ applyRemark: e.detail.value });
|
||
},
|
||
|
||
// 新增:打开考核官选择弹窗
|
||
openKaoheguanModal() {
|
||
if (!this.data.canSpecify) {
|
||
wx.showToast({ title: '已有考核官,无法重新指定', icon: 'none' });
|
||
return;
|
||
}
|
||
// 根据费用筛选可选考核官
|
||
let all = [...this.data.kaoheguanList];
|
||
if (this.data.applyFee > 0) {
|
||
all = all.filter(kg => kg.is_renzheng);
|
||
}
|
||
this.setData({
|
||
showKaoheguanModal: true,
|
||
filteredKaoheguanList: all,
|
||
searchKeyword: '',
|
||
});
|
||
},
|
||
|
||
// 关闭考核官选择弹窗
|
||
closeKaoheguanModal() {
|
||
this.setData({ showKaoheguanModal: false });
|
||
},
|
||
|
||
// 搜索输入
|
||
onSearchInput(e) {
|
||
const value = e.detail.value.trim();
|
||
this.setData({ searchKeyword: value });
|
||
this.filterKaoheguanList(value);
|
||
},
|
||
|
||
// 过滤考核官列表
|
||
filterKaoheguanList(keyword) {
|
||
let all = [...this.data.kaoheguanList];
|
||
if (this.data.applyFee > 0) {
|
||
all = all.filter(kg => kg.is_renzheng);
|
||
}
|
||
if (keyword) {
|
||
all = all.filter(kg =>
|
||
kg.yonghuid.includes(keyword) ||
|
||
(kg.dashou_nick && kg.dashou_nick.includes(keyword))
|
||
);
|
||
}
|
||
this.setData({ filteredKaoheguanList: all });
|
||
},
|
||
|
||
// 选择一个考核官
|
||
selectKaoheguan(e) {
|
||
const kg = e.currentTarget.dataset.kg;
|
||
if (kg.shenhe_zhuangtai !== 0) {
|
||
wx.showToast({ title: '该考核官正忙,无法指定', icon: 'none' });
|
||
return;
|
||
}
|
||
this.setData({
|
||
selectedKaoheguanId: kg.yonghuid,
|
||
selectedKaoheguanInfo: kg,
|
||
showKaoheguanModal: false,
|
||
});
|
||
},
|
||
|
||
// 取消已选择的考核官
|
||
clearSelectedKaoheguan() {
|
||
this.setData({
|
||
selectedKaoheguanId: '',
|
||
selectedKaoheguanInfo: null,
|
||
});
|
||
},
|
||
|
||
// 提交申请
|
||
async submitApply() {
|
||
const { applyGameNick, applyRemark, applyFee, selectedTag, isReapply, applyJiluId, selectedKaoheguanId } = this.data;
|
||
if (!applyGameNick || !applyGameNick.trim()) {
|
||
wx.showToast({ title: '请输入游戏昵称', icon: 'none' });
|
||
return;
|
||
}
|
||
if (!applyRemark || !applyRemark.trim()) {
|
||
wx.showToast({ title: '请填写备注', icon: 'none' });
|
||
return;
|
||
}
|
||
if (applyFee > 0) {
|
||
await this.startPayProcess();
|
||
} else {
|
||
await this.doFreeApply();
|
||
}
|
||
},
|
||
|
||
// 支付流程
|
||
async startPayProcess() {
|
||
this.setData({ payLoading: true });
|
||
try {
|
||
const res = await request({
|
||
url: '/yonghu/khzf',
|
||
method: 'POST',
|
||
data: {
|
||
tag_id: this.data.selectedTag.id,
|
||
game_nick: this.data.applyGameNick,
|
||
remark: this.data.applyRemark,
|
||
reapply: this.data.isReapply,
|
||
jilu_id: this.data.applyJiluId,
|
||
shenheguan_id: this.data.selectedKaoheguanId, // 新增
|
||
}
|
||
});
|
||
if (res.data.code !== 200) throw new Error(res.data.message || '下单失败');
|
||
const payParams = res.data.payParams;
|
||
const dingdanid = res.data.dingdanid;
|
||
wx.requestPayment({
|
||
timeStamp: payParams.timeStamp,
|
||
nonceStr: payParams.nonceStr,
|
||
package: payParams.package,
|
||
signType: payParams.signType || 'MD5',
|
||
paySign: payParams.paySign,
|
||
success: async () => {
|
||
await this.pollPayStatus(dingdanid);
|
||
},
|
||
fail: () => {
|
||
wx.showToast({ title: '支付取消或失败', icon: 'none' });
|
||
request({ url: '/yonghu/khzfsb', method: 'POST', data: { dingdanid } }).catch(()=>{});
|
||
}
|
||
});
|
||
} catch (e) {
|
||
wx.showToast({ title: e.message || '支付异常', icon: 'none' });
|
||
} finally {
|
||
this.setData({ payLoading: false });
|
||
}
|
||
},
|
||
|
||
// 轮询支付结果
|
||
async pollPayStatus(dingdanid) {
|
||
for (let i = 0; i < 10; i++) {
|
||
try {
|
||
const res = await request({ url: '/yonghu/khzffc', method: 'POST', data: { dingdanid } });
|
||
if (res.data.code === 200) {
|
||
wx.showToast({ title: '申请成功', icon: 'success' });
|
||
this.closeApplyModal();
|
||
this.fetchAllTags();
|
||
this.setData({ recordList: [], recordPage: 1 });
|
||
this.fetchMyRecords(true);
|
||
return;
|
||
}
|
||
} catch (e) {}
|
||
await new Promise(r => setTimeout(r, 2000));
|
||
}
|
||
wx.showToast({ title: '支付确认超时', icon: 'none' });
|
||
},
|
||
|
||
// 免费申请
|
||
async doFreeApply() {
|
||
try {
|
||
const res = await request({
|
||
url: '/dengji/dssqkh',
|
||
method: 'POST',
|
||
data: {
|
||
tag_id: this.data.selectedTag.id,
|
||
game_nick: this.data.applyGameNick,
|
||
remark: this.data.applyRemark,
|
||
reapply: this.data.isReapply,
|
||
jilu_id: this.data.applyJiluId,
|
||
shenheguan_id: this.data.selectedKaoheguanId, // 新增
|
||
}
|
||
});
|
||
if (res.data.code === 0) {
|
||
wx.showToast({ title: '申请成功', icon: 'success' });
|
||
this.closeApplyModal();
|
||
this.fetchAllTags();
|
||
this.setData({ recordList: [], recordPage: 1 });
|
||
this.fetchMyRecords(true);
|
||
} else {
|
||
wx.showToast({ title: res.data.msg || '申请失败', icon: 'none' });
|
||
}
|
||
} catch (e) {
|
||
wx.showToast({ title: '网络错误', icon: 'none' });
|
||
}
|
||
},
|
||
|
||
// 联系考核官(私聊)
|
||
contactKaoheguan(e) {
|
||
const item = e.currentTarget.dataset.item;
|
||
if (!item) return;
|
||
if (!item.shenheguan_id) {
|
||
wx.showToast({ title: '暂无考核官信息', icon: 'none' });
|
||
return;
|
||
}
|
||
const uid = wx.getStorageSync('uid');
|
||
if (!uid) {
|
||
wx.showToast({ title: '用户信息缺失', icon: 'none' });
|
||
return;
|
||
}
|
||
if (app.globalData.currentRole !== 'dashou') {
|
||
app.globalData.currentRole = 'dashou';
|
||
wx.setStorageSync('currentRole', 'dashou');
|
||
}
|
||
if (app.connectForCurrentRole) {
|
||
app.connectForCurrentRole();
|
||
} else if (app.ensureConnection) {
|
||
app.ensureConnection();
|
||
}
|
||
const ossImageUrl = this.data.ossImageUrl || app.globalData.ossImageUrl || '';
|
||
let fullAvatar = item.shenheguan_avatar || '';
|
||
if (fullAvatar && !fullAvatar.startsWith('http')) {
|
||
fullAvatar = ossImageUrl + fullAvatar;
|
||
}
|
||
if (!fullAvatar) {
|
||
fullAvatar = ossImageUrl + (app.globalData.morentouxiang || 'avatar/default.jpg');
|
||
}
|
||
const param = {
|
||
toUserId: 'Kh' + item.shenheguan_id,
|
||
toName: '考核官' + item.shenheguan_id,
|
||
toAvatar: fullAvatar
|
||
};
|
||
wx.navigateTo({
|
||
url: '/pages/liaotian/liaotian?data=' + encodeURIComponent(JSON.stringify(param)),
|
||
fail: (err) => {
|
||
wx.showToast({ title: '打开聊天失败', icon: 'none' });
|
||
}
|
||
});
|
||
},
|
||
|
||
showTagDetail(e) {
|
||
const tag = e.currentTarget.dataset.tag;
|
||
const feeStr = this.formatFeeList(tag.fee_list);
|
||
wx.showModal({
|
||
title: tag.name,
|
||
content: `规则:${tag.rule || '暂无'}\n${tag.jinpai ? '【可同时开启金牌】' : ''}\n费用:${feeStr}`,
|
||
showCancel: false,
|
||
confirmText: '知道了'
|
||
});
|
||
},
|
||
|
||
formatFeeList(feeList) {
|
||
if (!feeList || feeList.length === 0) return '暂无';
|
||
let str = feeList.map(f => `第${f.cishu}次:¥${f.feiyong}`).join(';');
|
||
const last = feeList[feeList.length - 1];
|
||
str += `;第${last.cishu}次及以上:¥${last.feiyong}`;
|
||
return str;
|
||
},
|
||
}); |