Browse Source

更新小程序页面和配置文件

pull/1/head
Default User 2 months ago
parent
commit
24db09d7f8
  1. 21
      pages/buyer/index.js
  2. 10
      pages/buyer/index.wxml
  3. 258
      pages/customer-service/index.js
  4. 53
      pages/customer-service/index.wxml
  5. 18
      pages/favorites/index.wxml
  6. 40
      pages/goods-detail/goods-detail.js
  7. 2
      pages/index/index.wxml
  8. 86
      pages/settlement/index.js
  9. 32
      pages/settlement/index.wxml
  10. 84
      pages/settlement/index.wxss
  11. 2
      project.private.config.json

21
pages/buyer/index.js

@ -2477,12 +2477,23 @@ Page({
console.error('位置数据上传失败:', err); console.error('位置数据上传失败:', err);
}); });
}, },
fail() { fail(err) {
wx.hideLoading(); wx.hideLoading();
wx.showToast({ console.error('获取位置失败:', err);
title: '获取位置失败', // 处理错误码-80418:需要申请位置API权限
icon: 'none' if (err.errCode === -80418) {
}); wx.showModal({
title: '位置服务未开通',
content: '该小程序尚未开通位置服务权限,请联系管理员申请开通后再试。',
showCancel: false,
confirmText: '我知道了'
});
} else {
wx.showToast({
title: '获取位置失败',
icon: 'none'
});
}
} }
}); });
} }

10
pages/buyer/index.wxml

@ -59,7 +59,7 @@
<span style="vertical-align: middle; font-size: 36rpx; font-weight: bold;">{{item.name}}</span> <span style="vertical-align: middle; font-size: 36rpx; font-weight: bold;">{{item.name}}</span>
<span style="vertical-align: middle; font-size: 20rpx; color: white; background: linear-gradient(135deg, #4a90e2 0%, #2b66f0 50%, #1a4bbd 100%); padding: 4rpx 8rpx; clip-path: polygon(50% 0%, 70% 10%, 100% 30%, 100% 70%, 70% 90%, 50% 100%, 30% 90%, 0% 70%, 0% 30%, 30% 10%); margin-left: 8rpx; box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3), inset 0 1rpx 2rpx rgba(255, 255, 255, 0.5); text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.5); font-weight: bold;">V</span> <span style="vertical-align: middle; font-size: 20rpx; color: white; background: linear-gradient(135deg, #4a90e2 0%, #2b66f0 50%, #1a4bbd 100%); padding: 4rpx 8rpx; clip-path: polygon(50% 0%, 70% 10%, 100% 30%, 100% 70%, 70% 90%, 50% 100%, 30% 90%, 0% 70%, 0% 30%, 30% 10%); margin-left: 8rpx; box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3), inset 0 1rpx 2rpx rgba(255, 255, 255, 0.5); text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.5); font-weight: bold;">V</span>
</view> </view>
<view style="font-size: 28rpx; font-weight: bold; margin-top: 30rpx;"> <view style="font-size: 28rpx; color: #888; margin-top: 30rpx;">
{{item.specification || '无'}} | {{item.yolk || '无'}} | {{item.minOrder || item.quantity || 1}}件 {{item.specification || '无'}} | {{item.yolk || '无'}} | {{item.minOrder || item.quantity || 1}}件
</view> </view>
</view> </view>
@ -71,14 +71,14 @@
<view style="flex: 0.4; display: flex; justify-content: space-between; align-items: center; padding: 0 20rpx;"> <view style="flex: 0.4; display: flex; justify-content: space-between; align-items: center; padding: 0 20rpx;">
<!-- 收藏人数显示 --> <!-- 收藏人数显示 -->
<view style="display: flex; align-items: center;"> <view style="display: flex; align-items: center;">
<text style="color: #060c0cff; font-size: 28rpx; font-weight: bold; margin-right: 8rpx;">已有</text> <text style="color: #999999; font-size: 28rpx; font-weight: normal; margin-right: 8rpx;">已有</text>
<text style="color: #d865d8ff; font-size: 28rpx; font-weight: bold;">{{item.reservedCount || 0}}</text> <text style="color: #d865d8ff; font-size: 28rpx; font-weight: bold;">{{item.reservedCount || 0}}</text>
<text style="color: #060c0cff; font-size: 28rpx; font-weight: bold; margin-left: 8rpx;">人收藏</text> <text style="color: #999999; font-size: 28rpx; font-weight: normal; margin-left: 8rpx;">人收藏</text>
</view> </view>
<!-- 根据是否已收藏显示不同的按钮 --> <!-- 根据是否已收藏显示不同的按钮 -->
<button <button
wx:if="{{item.isFavorite}}" wx:if="{{item.isFavorite}}"
style="background-color: #9DC209; color: white; font-size: 24rpx; font-weight: bold; width: 150rpx; height: 60rpx; border-radius: 999rpx; display: flex; justify-content: center; align-items: center; padding: 0; border: none; margin: 0; transition: background-color 0.3s ease;" style="font-size: 24rpx; font-weight: bold; width: 150rpx; height: 60rpx; border-radius: 24rpx; display: flex; justify-content: center; align-items: center; padding: 0; border: none; margin: 0; transition: all 0.3s ease; position: relative; overflow: hidden; color: #FF6B6B; background: rgba(255, 107, 107, 0.15); backdrop-filter: blur(12rpx); -webkit-backdrop-filter: blur(12rpx); border: 1rpx solid rgba(255, 255, 255, 0.3); box-shadow: 0 8rpx 32rpx rgba(31, 38, 135, 0.2), 0 4rpx 16rpx rgba(0, 0, 0, 0.1), inset 0 2rpx 4rpx rgba(255, 255, 255, 0.7), inset 0 -2rpx 4rpx rgba(0, 0, 0, 0.1);"
bindtap="cancelFavorite" bindtap="cancelFavorite"
data-item="{{item}}" data-item="{{item}}"
> >
@ -86,7 +86,7 @@
</button> </button>
<button <button
wx:else wx:else
style="background-color: #2F82FF; color: white; font-size: 24rpx; font-weight: bold; width: 150rpx; height: 60rpx; border-radius: 999rpx; display: flex; justify-content: center; align-items: center; padding: 0; border: none; margin: 0; transition: background-color 0.3s ease;" style="font-size: 24rpx; font-weight: bold; width: 150rpx; height: 60rpx; border-radius: 24rpx; display: flex; justify-content: center; align-items: center; padding: 0; border: none; margin: 0; transition: all 0.3s ease; position: relative; overflow: hidden; color: #1677ff; background: rgba(22, 119, 255, 0.15); backdrop-filter: blur(12rpx); -webkit-backdrop-filter: blur(12rpx); border: 1rpx solid rgba(255, 255, 255, 0.3); box-shadow: 0 8rpx 32rpx rgba(31, 38, 135, 0.2), 0 4rpx 16rpx rgba(0, 0, 0, 0.1), inset 0 2rpx 4rpx rgba(255, 255, 255, 0.7), inset 0 -2rpx 4rpx rgba(0, 0, 0, 0.1);"
bindtap="addFavorite" bindtap="addFavorite"
data-item="{{item}}" data-item="{{item}}"
> >

258
pages/customer-service/index.js

@ -11,26 +11,27 @@ Page({
onlineCount: 0, onlineCount: 0,
userType: 'seller' // 初始化用户类型,默认为销售员 userType: 'seller' // 初始化用户类型,默认为销售员
}, },
// 获取客服列表的方法 // 获取客服列表的方法
async fetchCustomerServices() { async fetchCustomerServices() {
try { try {
console.log('开始请求客服列表...'); console.log('开始请求客服列表...');
// 导入API工具并使用正确的请求方法 // 导入API工具并使用正确的请求方法
const api = require('../../utils/api'); const api = require('../../utils/api');
// 获取当前用户类型参数 // 获取当前用户类型参数
const userType = this.data.userType || 'seller'; const userType = this.data.userType || 'seller';
// 使用api.js中的请求工具,自动获取正确的服务器地址 // 直接使用api.request函数,该函数已经配置了正确的BASE_URL
const apiResponse = await api.request(`/api/managers?type=${userType}`, 'GET'); const res = await api.request(`/api/managers?type=${userType}`, 'GET', {});
console.log('API响应数据:', apiResponse ? JSON.stringify(apiResponse) : 'undefined'); console.log('API响应数据:', res ? JSON.stringify(res) : 'undefined');
// 更宽松的响应检查,确保能处理各种有效的响应格式 // 更宽松的响应检查,确保能处理各种有效的响应格式
if (apiResponse) { // 注意:api.request函数直接返回res.data,所以res已经是响应数据,不再有statusCode字段
// 无论success字段是否存在,只要有data字段就尝试处理 if (res) {
const dataSource = apiResponse.data || apiResponse; // 无论success字段是否存在,只要有数据就尝试处理
const dataSource = Array.isArray(res) ? res : (res.data || []);
if (Array.isArray(dataSource)) { if (Array.isArray(dataSource)) {
const processedData = dataSource.map(item => { const processedData = dataSource.map(item => {
// 解析information字段中的信息 // 解析information字段中的信息
@ -39,46 +40,70 @@ Page({
let purchaseCount = ''; let purchaseCount = '';
let profitFarmCount = ''; let profitFarmCount = '';
let profitIncreaseRate = ''; let profitIncreaseRate = '';
if (item.information) { if (item.information) {
// 处理不同类型的换行符(\r\n和\n) // 处理不同类型的换行符(\r\n和\n)
const lines = item.information.split(/\r?\n/).filter(line => line.trim()); const lines = item.information.split(/\r?\n/).filter(line => line.trim());
// 解析第一行:服务平台X年 服务X+鸡场 // 解析第一行:服务平台X年 服务X家(或X+鸡场
if (lines[0]) { if (lines[0]) {
const firstLine = lines[0].trim(); const firstLine = lines[0].trim();
const experienceMatch = firstLine.match(/服务平台(.*?)年/); // 提取完整的经验信息,包括"服务平台"
if (experienceMatch) { const fullExperienceMatch = firstLine.match(/(服务平台.*?年|服务平台.*?月)/);
experience = experienceMatch[1].trim() + '年'; if (fullExperienceMatch) {
// 直接使用完整的经验信息,如"服务平台1年"或"服务平台2个月"
experience = fullExperienceMatch[1].trim();
} else {
// 如果没有匹配到,使用默认格式
experience = '服务平台1年';
} }
const serviceCountMatch = firstLine.match(/服务(.*?)鸡场/); // 匹配服务数量,支持多种格式:服务66家、服务100+鸡场等
if (serviceCountMatch) { // 确保只匹配最后一个"服务"后面的数量
serviceCount = serviceCountMatch[1].trim(); const serviceMatches = firstLine.match(/服务(.*?)(家|鸡场)/g);
if (serviceMatches && serviceMatches.length > 0) {
// 使用最后一个匹配项
const lastServiceMatch = serviceMatches[serviceMatches.length - 1];
const serviceCountMatch = lastServiceMatch.match(/服务(.*?)(家|鸡场)/);
if (serviceCountMatch) {
serviceCount = serviceCountMatch[1].trim();
}
} }
} }
// 解析第二行:数字 数字 数字% // 解析数字行:数字 数字% 或 数字 数字 数字%
if (lines[1]) { for (let i = 1; i < lines.length; i++) {
const secondLine = lines[1].trim(); const line = lines[i].trim();
const numbers = secondLine.split(/\s+/).filter(num => num.trim()); // 匹配数字序列
if (numbers.length >= 3) { const numbers = line.split(/\s+/).filter(num => num.trim() && /\d/.test(num));
if (numbers.length >= 2) {
// 销售相关数据:累计销售和客户满意度
purchaseCount = numbers[0].trim(); purchaseCount = numbers[0].trim();
profitFarmCount = numbers[1].trim(); profitFarmCount = numbers[1].replace('%', '').trim();
profitIncreaseRate = numbers[2].replace('%', '').trim(); // 如果有第三个数字,可能是其他数据
if (numbers.length >= 3) {
profitIncreaseRate = numbers[2].replace('%', '').trim();
}
break; // 只处理第一行数字
} }
} }
} }
// 提取egg_section中的数字部分,去掉"鸡蛋分"后缀 // 处理鸡蛋分显示
let score = Math.floor(Math.random() * 20) + 980; let score = '新人暂无';
if (item.egg_section) { if (item.egg_section) {
const scoreMatch = item.egg_section.match(/(\d+)/); if (item.egg_section.trim() === '新人暂无') {
if (scoreMatch) { // 新人暂无,直接显示
score = scoreMatch[1]; score = '新人暂无';
} else {
// 提取egg_section中的数字部分,去掉"鸡蛋分"后缀
const scoreMatch = item.egg_section.match(/(\d+)/);
if (scoreMatch) {
score = scoreMatch[1];
}
} }
} }
return { return {
id: item.id || `id_${Date.now()}_${Math.random()}`, // 确保有id id: item.id || `id_${Date.now()}_${Math.random()}`, // 确保有id
managerId: item.managerId || '', managerId: item.managerId || '',
@ -89,7 +114,33 @@ Page({
name: item.name || '未知', name: item.name || '未知',
alias: item.alias || item.name || '未知', alias: item.alias || item.name || '未知',
phoneNumber: item.phoneNumber || '', phoneNumber: item.phoneNumber || '',
avatarUrl: item.avatar || item.avatarUrl || '', // 兼容avatar和avatarUrl // 解析头像URL,处理JSON数组格式和多余字符
avatarUrl: function() {
let url = '';
const avatarData = item.avatar || item.avatarUrl || '';
if (avatarData) {
try {
// 尝试解析JSON数组
const avatarArray = JSON.parse(avatarData);
if (Array.isArray(avatarArray) && avatarArray.length > 0) {
// 提取数组中的第一个URL,并清理多余字符
url = avatarArray[0].trim()
.replace(/^`/, '') // 移除开头的反引号
.replace(/`$/, '') // 移除结尾的反引号
.replace(/^"/, '') // 移除开头的引号
.replace(/"$/, ''); // 移除结尾的引号
}
} catch (e) {
// 如果不是JSON数组,直接使用,并清理多余字符
url = avatarData.trim()
.replace(/^`/, '') // 移除开头的反引号
.replace(/`$/, '') // 移除结尾的反引号
.replace(/^"/, '') // 移除开头的引号
.replace(/"$/, ''); // 移除结尾的引号
}
}
return url;
}(),
score: score, // 使用数据库中的鸡蛋分,提取数字部分 score: score, // 使用数据库中的鸡蛋分,提取数字部分
isOnline: !!item.online, // 转换为布尔值 isOnline: !!item.online, // 转换为布尔值
responsibleArea: item.responsible_area || '', // 使用数据库中的负责区域 responsibleArea: item.responsible_area || '', // 使用数据库中的负责区域
@ -104,13 +155,22 @@ Page({
}; };
}); });
console.log('处理后的数据数量:', processedData.length); console.log('处理后的数据数量:', processedData.length);
// 按鸡蛋分从高到低排序
processedData.sort((a, b) => {
const scoreA = parseInt(a.score) || 0;
const scoreB = parseInt(b.score) || 0;
return scoreB - scoreA;
});
console.log('排序后的数据:', processedData.map(item => ({ id: item.id, name: item.name, score: item.score })));
return processedData; return processedData;
} else { } else {
console.error('响应数据格式错误,不是预期的数组格式:', dataSource); console.error('响应数据格式错误,不是预期的数组格式:', dataSource);
return []; return [];
} }
} else { } else {
console.error('获取客服列表失败,状态码:', res?.statusCode, '响应数据:', res?.data); console.error('获取客服列表失败,响应数据无效:', res);
return []; return [];
} }
} catch (error) { } catch (error) {
@ -146,14 +206,14 @@ Page({
const allSkills = ['渠道拓展', '供应商维护', '质量把控', '精准把控市场价格', '谈判技巧', '库存管理']; const allSkills = ['渠道拓展', '供应商维护', '质量把控', '精准把控市场价格', '谈判技巧', '库存管理'];
const skillCount = Math.floor(Math.random() * 3) + 2; // 2-4个技能 const skillCount = Math.floor(Math.random() * 3) + 2; // 2-4个技能
const selectedSkills = []; const selectedSkills = [];
while (selectedSkills.length < skillCount) { while (selectedSkills.length < skillCount) {
const skill = allSkills[Math.floor(Math.random() * allSkills.length)]; const skill = allSkills[Math.floor(Math.random() * allSkills.length)];
if (!selectedSkills.includes(skill)) { if (!selectedSkills.includes(skill)) {
selectedSkills.push(skill); selectedSkills.push(skill);
} }
} }
return selectedSkills; return selectedSkills;
}, },
@ -184,16 +244,16 @@ Page({
} catch (e) { } catch (e) {
console.log('没有正在显示的loading'); console.log('没有正在显示的loading');
} }
wx.showLoading({ title: '加载中...' }); wx.showLoading({ title: '加载中...' });
try { try {
const services = await this.fetchCustomerServices(); const services = await this.fetchCustomerServices();
console.log('获取到的客服数量:', services.length); console.log('获取到的客服数量:', services.length);
// 计算在线数量 // 计算在线数量
const onlineCount = services.filter(item => item.isOnline).length; const onlineCount = services.filter(item => item.isOnline).length;
console.log('在线客服数量:', onlineCount); console.log('在线客服数量:', onlineCount);
// 更新数据 // 更新数据
this.setData({ this.setData({
customerServices: services, customerServices: services,
@ -201,11 +261,11 @@ Page({
onlineCount: onlineCount onlineCount: onlineCount
}); });
console.log('数据更新成功'); console.log('数据更新成功');
// 应用当前的筛选条件 // 应用当前的筛选条件
this.filterServices(); this.filterServices();
console.log('筛选条件应用完成'); console.log('筛选条件应用完成');
// 如果没有数据,显示提示(确保在hideLoading后显示) // 如果没有数据,显示提示(确保在hideLoading后显示)
if (services.length === 0) { if (services.length === 0) {
setTimeout(() => { setTimeout(() => {
@ -237,18 +297,18 @@ Page({
userType: options.type || 'seller' // 默认销售员 userType: options.type || 'seller' // 默认销售员
}); });
console.log('客服列表页面加载,类型:', this.data.userType); console.log('客服列表页面加载,类型:', this.data.userType);
// 加载客服列表 // 加载客服列表
this.loadCustomerServices(); this.loadCustomerServices();
// 检查当前用户身份 // 检查当前用户身份
this.checkUserType(); this.checkUserType();
}, },
/** /**
* 检查当前用户身份 * 检查当前用户身份
*/ */
checkUserType: function () { checkUserType: function() {
const app = getApp(); const app = getApp();
const userInfo = app.globalData.userInfo || {}; const userInfo = app.globalData.userInfo || {};
const isManager = userInfo.userType === 'manager' || userInfo.type === 'manager'; const isManager = userInfo.userType === 'manager' || userInfo.type === 'manager';
@ -265,12 +325,12 @@ Page({
selected: -1 // 不选中任何tab selected: -1 // 不选中任何tab
}); });
} }
// 当页面显示时重新加载数据,确保数据最新 // 当页面显示时重新加载数据,确保数据最新
this.loadCustomerServices(); this.loadCustomerServices();
}, },
onUnload: function () { onUnload: function() {
// 停止定期刷新 // 停止定期刷新
this.stopPeriodicRefresh(); this.stopPeriodicRefresh();
}, },
@ -284,11 +344,11 @@ Page({
}, },
onAreaFilter: function () { onAreaFilter: function () {
// 区域筛选弹窗 - 鸡蛋采购区域 // 区域筛选弹窗 - 使用用户要求的具体省份
wx.showActionSheet({ wx.showActionSheet({
itemList: ['全部', '华北区', '华东区', '华南区', '全国', '西南区', '西北区', '东北区'], itemList: ['全部', '全国', '云南', '四川', '贵州', '广西'],
success: res => { success: res => {
const areas = ['全部', '华北区', '华东区', '华南区', '全国', '西南区', '西北区', '东北区']; const areas = ['全部', '全国', '云南', '四川', '贵州', '广西'];
const selectedArea = areas[res.tapIndex]; const selectedArea = areas[res.tapIndex];
this.setData({ this.setData({
selectedArea: selectedArea selectedArea: selectedArea
@ -300,27 +360,49 @@ Page({
filterServices: function () { filterServices: function () {
const { customerServices, searchKeyword, selectedArea } = this.data; const { customerServices, searchKeyword, selectedArea } = this.data;
// 首先进行关键词搜索
let filtered = customerServices; let filtered = customerServices;
// 关键词搜索
if (searchKeyword) { if (searchKeyword) {
const keyword = searchKeyword.toLowerCase(); const keyword = searchKeyword.toLowerCase();
filtered = filtered.filter(item => { filtered = filtered.filter(item => {
return item.alias?.toLowerCase().includes(keyword) || return item.alias?.toLowerCase().includes(keyword) ||
item.name.toLowerCase().includes(keyword) || item.name.toLowerCase().includes(keyword) ||
item.phoneNumber?.includes(keyword) || item.phoneNumber?.includes(keyword) ||
item.managercompany?.toLowerCase().includes(keyword); item.managercompany?.toLowerCase().includes(keyword);
}); });
} }
// 区域筛选 // 然后进行区域筛选和排序
if (selectedArea && selectedArea !== '全部') { if (selectedArea && selectedArea !== '全部') {
// 筛选出符合条件的客服
filtered = filtered.filter(item => { filtered = filtered.filter(item => {
return item.responsibleArea?.includes(selectedArea); return item.responsibleArea?.includes(selectedArea) || item.responsibleArea?.includes('全国');
});
// 按所选地区优先排序
filtered.sort((a, b) => {
// 优先显示所选地区的客服
const aHasSelectedArea = a.responsibleArea?.includes(selectedArea);
const bHasSelectedArea = b.responsibleArea?.includes(selectedArea);
if (aHasSelectedArea && !bHasSelectedArea) return -1;
if (!aHasSelectedArea && bHasSelectedArea) return 1;
// 同一地区的客服按鸡蛋分排序
const scoreA = parseInt(a.score) || 0;
const scoreB = parseInt(b.score) || 0;
return scoreB - scoreA;
});
} else {
// 全部区域时,按鸡蛋分排序
filtered.sort((a, b) => {
const scoreA = parseInt(a.score) || 0;
const scoreB = parseInt(b.score) || 0;
return scoreB - scoreA;
}); });
} }
this.setData({ this.setData({
filteredServices: filtered filteredServices: filtered
}); });
@ -332,72 +414,72 @@ Page({
console.log('=== 开始测试聊天列表功能 ==='); console.log('=== 开始测试聊天列表功能 ===');
console.log('测试用户手机号:', userPhone); console.log('测试用户手机号:', userPhone);
console.log('测试客服手机号:', managerPhone); console.log('测试客服手机号:', managerPhone);
// 1. 测试添加聊天记录(双向) // 1. 测试添加聊天记录(双向)
console.log('\n1. 测试添加聊天记录(双向)...'); console.log('\n1. 测试添加聊天记录(双向)...');
const addChatResponse = await api.addChatRecord(userPhone, managerPhone); const addChatResponse = await api.addChatRecord(userPhone, managerPhone);
console.log('添加聊天记录响应:', addChatResponse); console.log('添加聊天记录响应:', addChatResponse);
// 2. 测试用户获取聊天列表 // 2. 测试用户获取聊天列表
console.log('\n2. 测试用户获取聊天列表...'); console.log('\n2. 测试用户获取聊天列表...');
const userChatListResponse = await api.getChatList(userPhone); const userChatListResponse = await api.getChatList(userPhone);
console.log('用户聊天列表响应:', userChatListResponse); console.log('用户聊天列表响应:', userChatListResponse);
console.log('用户聊天列表数量:', Array.isArray(userChatListResponse) ? userChatListResponse.length : 0); console.log('用户聊天列表数量:', Array.isArray(userChatListResponse) ? userChatListResponse.length : 0);
// 3. 测试客服获取聊天列表 // 3. 测试客服获取聊天列表
console.log('\n3. 测试客服获取聊天列表...'); console.log('\n3. 测试客服获取聊天列表...');
const managerChatListResponse = await api.getChatList(managerPhone); const managerChatListResponse = await api.getChatList(managerPhone);
console.log('客服聊天列表响应:', managerChatListResponse); console.log('客服聊天列表响应:', managerChatListResponse);
console.log('客服聊天列表数量:', Array.isArray(managerChatListResponse) ? managerChatListResponse.length : 0); console.log('客服聊天列表数量:', Array.isArray(managerChatListResponse) ? managerChatListResponse.length : 0);
// 4. 验证双向聊天记录是否都能正确获取 // 4. 验证双向聊天记录是否都能正确获取
console.log('\n4. 验证双向聊天记录...'); console.log('\n4. 验证双向聊天记录...');
// 检查用户是否能看到与客服的聊天记录 // 检查用户是否能看到与客服的聊天记录
const userHasManagerChat = Array.isArray(userChatListResponse) && userChatListResponse.some(chat => const userHasManagerChat = Array.isArray(userChatListResponse) && userChatListResponse.some(chat =>
(chat.user_phone === userPhone && chat.manager_phone === managerPhone) || (chat.user_phone === userPhone && chat.manager_phone === managerPhone) ||
(chat.user_phone === managerPhone && chat.manager_phone === userPhone) (chat.user_phone === managerPhone && chat.manager_phone === userPhone)
); );
// 检查客服是否能看到与用户的聊天记录 // 检查客服是否能看到与用户的聊天记录
const managerHasUserChat = Array.isArray(managerChatListResponse) && managerChatListResponse.some(chat => const managerHasUserChat = Array.isArray(managerChatListResponse) && managerChatListResponse.some(chat =>
(chat.user_phone === userPhone && chat.manager_phone === managerPhone) || (chat.user_phone === userPhone && chat.manager_phone === managerPhone) ||
(chat.user_phone === managerPhone && chat.manager_phone === userPhone) (chat.user_phone === managerPhone && chat.manager_phone === userPhone)
); );
if (userHasManagerChat) { if (userHasManagerChat) {
console.log('✓ 用户可以看到与客服的聊天记录'); console.log('✓ 用户可以看到与客服的聊天记录');
} else { } else {
console.log('❌ 用户无法看到与客服的聊天记录'); console.log('❌ 用户无法看到与客服的聊天记录');
} }
if (managerHasUserChat) { if (managerHasUserChat) {
console.log('✓ 客服可以看到与用户的聊天记录'); console.log('✓ 客服可以看到与用户的聊天记录');
} else { } else {
console.log('❌ 客服无法看到与用户的聊天记录'); console.log('❌ 客服无法看到与用户的聊天记录');
} }
// 5. 测试重复添加聊天记录(应该不会重复创建) // 5. 测试重复添加聊天记录(应该不会重复创建)
console.log('\n5. 测试重复添加聊天记录...'); console.log('\n5. 测试重复添加聊天记录...');
const duplicateAddResponse = await api.addChatRecord(userPhone, managerPhone); const duplicateAddResponse = await api.addChatRecord(userPhone, managerPhone);
console.log('重复添加聊天记录响应:', duplicateAddResponse); console.log('重复添加聊天记录响应:', duplicateAddResponse);
// 6. 再次测试获取聊天列表,确保数量没有变化 // 6. 再次测试获取聊天列表,确保数量没有变化
console.log('\n6. 再次测试获取聊天列表,确保数量没有变化...'); console.log('\n6. 再次测试获取聊天列表,确保数量没有变化...');
const finalUserChatListResponse = await api.getChatList(userPhone); const finalUserChatListResponse = await api.getChatList(userPhone);
console.log('最终用户聊天列表数量:', Array.isArray(finalUserChatListResponse) ? finalUserChatListResponse.length : 0); console.log('最终用户聊天列表数量:', Array.isArray(finalUserChatListResponse) ? finalUserChatListResponse.length : 0);
const initialLength = Array.isArray(userChatListResponse) ? userChatListResponse.length : 0; const initialLength = Array.isArray(userChatListResponse) ? userChatListResponse.length : 0;
const finalLength = Array.isArray(finalUserChatListResponse) ? finalUserChatListResponse.length : 0; const finalLength = Array.isArray(finalUserChatListResponse) ? finalUserChatListResponse.length : 0;
if (finalLength === initialLength) { if (finalLength === initialLength) {
console.log('✓ 重复添加聊天记录没有导致重复数据'); console.log('✓ 重复添加聊天记录没有导致重复数据');
} else { } else {
console.log('❌ 重复添加聊天记录导致了重复数据'); console.log('❌ 重复添加聊天记录导致了重复数据');
} }
console.log('\n=== 聊天列表功能测试完成 ==='); console.log('\n=== 聊天列表功能测试完成 ===');
// 总结测试结果 // 总结测试结果
if (userHasManagerChat && managerHasUserChat) { if (userHasManagerChat && managerHasUserChat) {
console.log('\n🎉 所有测试通过!聊天列表功能正常工作。'); console.log('\n🎉 所有测试通过!聊天列表功能正常工作。');
@ -406,7 +488,7 @@ Page({
console.log('\n❌ 测试失败!聊天列表功能存在问题。'); console.log('\n❌ 测试失败!聊天列表功能存在问题。');
return false; return false;
} }
} catch (error) { } catch (error) {
console.error('测试过程中出现错误:', error.message); console.error('测试过程中出现错误:', error.message);
if (error.response) { if (error.response) {
@ -482,17 +564,17 @@ Page({
console.log('聊天建立成功:', JSON.stringify(res, null, 2)); console.log('聊天建立成功:', JSON.stringify(res, null, 2));
// 隐藏加载提示 // 隐藏加载提示
wx.hideLoading(); wx.hideLoading();
// 使用客服手机号作为聊天会话ID // 使用客服手机号作为聊天会话ID
const chatSessionId = service.phoneNumber; const chatSessionId = service.phoneNumber;
// 跳转到聊天页面,确保正确传递客服手机号和用户名 // 跳转到聊天页面,确保正确传递客服手机号和用户名
wx.navigateTo({ wx.navigateTo({
url: `/pages/chat-detail/index?userId=${chatSessionId}&userName=${encodeURIComponent(service?.alias || '')}&phone=${service?.phoneNumber || ''}&isManager=true` url: `/pages/chat-detail/index?userId=${chatSessionId}&userName=${encodeURIComponent(service?.alias || '')}&phone=${service?.phoneNumber || ''}&isManager=true`
}); });
console.log('跳转到聊天页面:', { console.log('跳转到聊天页面:', {
chatUserId: chatSessionId, chatUserId: chatSessionId,
userName: service?.alias, userName: service?.alias,
customerServicePhone: service?.phoneNumber, customerServicePhone: service?.phoneNumber,
userPhone: userPhone userPhone: userPhone
}); });

53
pages/customer-service/index.wxml

@ -33,34 +33,51 @@
<view class="avatar-container"> <view class="avatar-container">
<image class="avatar" src="{{item.avatarUrl || '/images/default-avatar.png'}}" mode="aspectFill" /> <image class="avatar" src="{{item.avatarUrl || '/images/default-avatar.png'}}" mode="aspectFill" />
<view wx:if="{{item.isOnline}}" class="online-indicator">在线</view> <view wx:if="{{item.isOnline}}" class="online-indicator">在线</view>
<view wx:else class="offline-indicator">离线</view>
</view> </view>
<view class="broker-details"> <view class="broker-details">
<view class="name-row"> <view class="name-row">
<text class="name">{{item.alias}}</text> <text class="name">{{item.alias}}</text>
<text class="score-text">{{item.score}} 鸡蛋分</text> <text class="score-text" wx:if="{{item.score === '新人暂无'}}">{{item.score}}</text>
<text class="score-text" wx:else>{{item.score}} 鸡蛋分</text>
<text wx:if="{{item.isOnline}}" class="online-status">(在线)</text> <text wx:if="{{item.isOnline}}" class="online-status">(在线)</text>
</view> </view>
<text class="company">{{item.managercompany || '暂无公司信息'}}</text> <text class="company">{{item.managercompany || '暂无公司信息'}}</text>
<text class="department">{{item.managerdepartment}} · {{item.projectName}}</text> <text class="department">{{item.managerdepartment}} · {{item.projectName}}</text>
<text class="area">负责区域:{{item.responsibleArea}}</text> <text class="area">负责区域:{{item.responsibleArea}}</text>
<text class="experience">服务平台{{item.experience}} 服务{{item.serviceCount}}家鸡场</text> <text class="experience" wx:if="{{userType === 'seller'}}">{{item.experience}} 服务{{item.serviceCount}}个客户</text>
<!-- 业绩数据统计 --> <text class="experience" wx:else>{{item.experience}} 服务{{item.serviceCount}}家鸡场</text>
<!-- 业绩数据统计 - 根据用户类型显示不同数据 -->
<view class="performance-stats"> <view class="performance-stats">
<view class="stat-item"> <!-- 销售员数据 -->
<text class="stat-value">{{item.purchaseCount}}</text> <block wx:if="{{userType === 'seller'}}">
<text class="stat-label">累计采购(件)</text> <view class="stat-item">
</view> <text class="stat-value">{{item.purchaseCount}}</text>
<view class="stat-divider">|</view> <text class="stat-label">累计销售</text>
<view class="stat-item"> </view>
<text class="stat-value profit-rate">{{item.profitFarmCount}}</text> <view class="stat-divider">|</view>
<text class="stat-label">服务盈利鸡场(家)</text> <view class="stat-item">
</view> <text class="stat-value profit-rate">{{item.profitFarmCount}}%</text>
<view class="stat-divider">|</view> <text class="stat-label">客户满意度</text>
<view class="stat-item"> </view>
<text class="stat-value profit-rate">{{item.profitIncreaseRate}}%</text> </block>
<text class="stat-label">平均盈利增长</text>
</view> <!-- 采购员数据 -->
<block wx:else>
<view class="stat-item">
<text class="stat-value">{{item.purchaseCount}}</text>
<text class="stat-label">累计采购(件)</text>
</view>
<view class="stat-divider">|</view>
<view class="stat-item">
<text class="stat-value profit-rate">{{item.profitFarmCount}}</text>
<text class="stat-label">服务盈利鸡场(家)</text>
</view>
<view class="stat-divider">|</view>
<view class="stat-item">
<text class="stat-value profit-rate">{{item.profitIncreaseRate}}%</text>
<text class="stat-label">平均盈利增长</text>
</view>
</block>
</view> </view>
<!-- 专业技能标签 --> <!-- 专业技能标签 -->
<view class="skills-preview"> <view class="skills-preview">

18
pages/favorites/index.wxml

@ -50,7 +50,7 @@
<!-- 右侧信息区域 60%宽度(3/5),相应调整 --> <!-- 右侧信息区域 60%宽度(3/5),相应调整 -->
<view style="width: 60%; display: flex; flex-direction: column; background-color: white; border-left: 1rpx solid #f0f0f0;"> <view style="width: 60%; display: flex; flex-direction: column; background-color: white; border-left: 1rpx solid #f0f0f0;">
<!-- 上半部分商品信息区域(60%高度),可点击查看详情 --> <!-- 上半部分商品信息区域(60%高度),可点击查看详情 -->
<view style="flex: 0.6; padding: 0rpx 15rpx 15rpx 15rpx; cursor: pointer;" bindtap="goToGoodsDetail" data-item="{{item}}"> <view style="flex: 0.6; padding: 0rpx 15rpx 15rpx 15rpx; cursor: pointer;" bindtap="goToGoodsDetail" data-item="{{item}}">
<view> <view>
<view style="margin-bottom: 15rpx; margin-top: -5rpx;"> <view style="margin-bottom: 15rpx; margin-top: -5rpx;">
@ -58,7 +58,7 @@
<span style="vertical-align: middle; font-size: 36rpx; font-weight: bold;">{{item.Product.productName || '未命名商品'}}</span> <span style="vertical-align: middle; font-size: 36rpx; font-weight: bold;">{{item.Product.productName || '未命名商品'}}</span>
<span style="vertical-align: middle; font-size: 20rpx; color: white; background: linear-gradient(135deg, #4a90e2 0%, #2b66f0 50%, #1a4bbd 100%); padding: 4rpx 8rpx; clip-path: polygon(50% 0%, 70% 10%, 100% 30%, 100% 70%, 70% 90%, 50% 100%, 30% 90%, 0% 70%, 0% 30%, 30% 10%); margin-left: 8rpx; box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3), inset 0 1rpx 2rpx rgba(255, 255, 255, 0.5); text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.5); font-weight: bold;">V</span> <span style="vertical-align: middle; font-size: 20rpx; color: white; background: linear-gradient(135deg, #4a90e2 0%, #2b66f0 50%, #1a4bbd 100%); padding: 4rpx 8rpx; clip-path: polygon(50% 0%, 70% 10%, 100% 30%, 100% 70%, 70% 90%, 50% 100%, 30% 90%, 0% 70%, 0% 30%, 30% 10%); margin-left: 8rpx; box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3), inset 0 1rpx 2rpx rgba(255, 255, 255, 0.5); text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.5); font-weight: bold;">V</span>
</view> </view>
<view style="font-size: 28rpx; font-weight: bold; margin-top: 30rpx;"> <view style="font-size: 28rpx; color: #888; margin-top: 30rpx;">
{{(item.Product.spec && item.Product.spec !== '无') ? item.Product.spec : (item.Product.specification && item.Product.specification !== '无') ? item.Product.specification : '无'}} | {{item.Product.yolk || '无'}} | {{item.Product.minOrder || item.Product.quantity || 1}}件 {{(item.Product.spec && item.Product.spec !== '无') ? item.Product.spec : (item.Product.specification && item.Product.specification !== '无') ? item.Product.specification : '无'}} | {{item.Product.yolk || '无'}} | {{item.Product.minOrder || item.Product.quantity || 1}}件
</view> </view>
</view> </view>
@ -69,13 +69,13 @@
<!-- 价格显示 --> <!-- 价格显示 -->
<text style="color: #52c41a; font-size: 28rpx; font-weight: bold;">¥{{item.Product.price || 0}}</text> <text style="color: #52c41a; font-size: 28rpx; font-weight: bold;">¥{{item.Product.price || 0}}</text>
<!-- 取消收藏按钮 --> <!-- 取消收藏按钮 -->
<button <button
style="background-color: #91c41aff; color: white; font-size: 24rpx; font-weight: bold; width: 150rpx; height: 60rpx; border-radius: 999rpx; display: flex; justify-content: center; align-items: center; padding: 0; border: none; margin: 0; background: none; background-color: #91c41aff;" style="font-size: 24rpx; font-weight: bold; width: 150rpx; height: 60rpx; border-radius: 24rpx; display: flex; justify-content: center; align-items: center; padding: 0; border: none; margin: 0; transition: all 0.3s ease; position: relative; overflow: hidden; color: #FF6B6B; background: rgba(255, 107, 107, 0.15); backdrop-filter: blur(12rpx); -webkit-backdrop-filter: blur(12rpx); border: 1rpx solid rgba(255, 255, 255, 0.3); box-shadow: 0 8rpx 32rpx rgba(31, 38, 135, 0.2), 0 4rpx 16rpx rgba(0, 0, 0, 0.1), inset 0 2rpx 4rpx rgba(255, 255, 255, 0.7), inset 0 -2rpx 4rpx rgba(0, 0, 0, 0.1);"
bindtap="cancelFavorite" bindtap="cancelFavorite"
data-productid="{{item.productId}}" data-productid="{{item.productId}}"
> >
取消收藏 取消收藏
</button> </button>
</view> </view>
</view> </view>
</view> </view>

40
pages/goods-detail/goods-detail.js

@ -273,12 +273,18 @@ Page({
region: formattedGoods.region region: formattedGoods.region
}); });
// 保存预加载数据中的isFavorite状态,确保是布尔值
const preloadedFavoriteStatus = preloadedData ? (preloadedData.isFavorite || false) : false;
this.setData({ this.setData({
goodsDetail: formattedGoods goodsDetail: formattedGoods,
isFavorite: preloadedFavoriteStatus // 优先使用预加载数据中的收藏状态
}); });
// 加载商品的收藏状态 // 只有当没有预加载的收藏状态时,才从服务器加载
this.loadGoodsFavoriteStatus(productIdStr); if (!preloadedData || preloadedData.isFavorite === undefined) {
this.loadGoodsFavoriteStatus(productIdStr);
}
} else { } else {
wx.showToast({ wx.showToast({
title: '获取商品详情失败', title: '获取商品详情失败',
@ -335,10 +341,33 @@ Page({
// 调用API获取用户收藏列表 // 调用API获取用户收藏列表
API.getFavorites(userPhone) API.getFavorites(userPhone)
.then(res => { .then(res => {
if (res && res.code === 200 && res.data && Array.isArray(res.data)) { if (res && res.code === 200) {
const favoriteProductIds = res.data.map(item => String(item.productId || item.id)); // 检查API返回的数据结构,确保我们获取到正确的收藏列表
let favoritesList = [];
if (Array.isArray(res.data)) {
favoritesList = res.data;
} else if (res.data && Array.isArray(res.data.favorites)) {
favoritesList = res.data.favorites;
} else if (res.data && Array.isArray(res.data.data)) {
favoritesList = res.data.data;
}
console.log('获取收藏列表成功,处理后的数据:', favoritesList);
// 从收藏列表中提取商品ID
const favoriteProductIds = favoritesList.map(item => {
// 尝试从不同的字段名获取商品ID
return String(item.productId || item.id || item.product_id || '');
}).filter(id => id !== ''); // 过滤掉空字符串
console.log('收藏商品ID列表:', favoriteProductIds);
console.log('当前商品ID:', String(productId));
const isFavorite = favoriteProductIds.includes(String(productId)); const isFavorite = favoriteProductIds.includes(String(productId));
console.log('计算得到的收藏状态:', isFavorite);
// 只有当从收藏列表中明确获取到结果时,才更新收藏状态
// 避免因为API返回数据结构问题导致收藏状态被错误覆盖
this.setData({ this.setData({
isFavorite: isFavorite isFavorite: isFavorite
}); });
@ -346,6 +375,7 @@ Page({
}) })
.catch(err => { .catch(err => {
console.error('获取收藏状态失败:', err); console.error('获取收藏状态失败:', err);
// 注意:这里不要更新isFavorite状态,保持之前的状态
}); });
}, },

2
pages/index/index.wxml

@ -18,7 +18,7 @@
</view> </view>
</view> </view>
<!-- 按钮区域 --> <!-- 按钮区域 -->
<view class="title">"中国最专业的鸡蛋现货交易平台"</view> <view class="title">专业的鸡蛋现货交易平台</view>
<view class="buttons-section"> <view class="buttons-section">
<!-- 第一行 --> <!-- 第一行 -->
<view class="btn-row"> <view class="btn-row">

86
pages/settlement/index.js

@ -46,7 +46,9 @@ Page({
showLoginButton: true, showLoginButton: true,
// 合作模式帮助弹窗 // 合作模式帮助弹窗
showCooperationHelp: false showCooperationHelp: false,
// 滚动到的位置
scrollToView: ''
}, },
onLoad(options) { onLoad(options) {
@ -647,7 +649,7 @@ Page({
city: this.data.city || '', // 城市,确保非空 city: this.data.city || '', // 城市,确保非空
district: this.data.district || '', // 区县,确保非空 district: this.data.district || '', // 区县,确保非空
detailedaddress: this.data.detailedaddress || '', // 详细地址(即使为空也要传递) detailedaddress: this.data.detailedaddress || '', // 详细地址(即使为空也要传递)
cooperation: this.data.cooperation === '货源委托' ? 'wholesale' : (this.data.cooperation || ''), // 确保合作模式非空 cooperation: this.data.cooperation === '代销业务' ? 'wholesale' : (this.data.cooperation || ''), // 确保合作模式非空
phoneNumber: contactPhone || '', // 后端期望的字段名是phoneNumber,确保非空 phoneNumber: contactPhone || '', // 后端期望的字段名是phoneNumber,确保非空
businesslicenseurl: uploadedFiles.businessLicenseFile || '', // 营业执照URL businesslicenseurl: uploadedFiles.businessLicenseFile || '', // 营业执照URL
proofurl: uploadedFiles.animalQuarantineFile || '', // 动物检疫证明或法人身份证URL(两者共用一个字段) proofurl: uploadedFiles.animalQuarantineFile || '', // 动物检疫证明或法人身份证URL(两者共用一个字段)
@ -837,6 +839,26 @@ Page({
wx.setStorageSync('applicationId', appId); wx.setStorageSync('applicationId', appId);
} }
// 修改用户身份为seller
const userId = wx.getStorageSync('userId');
const app = getApp();
// 更新本地存储中的用户类型
wx.setStorageSync('userType', 'seller');
// 更新全局数据中的用户类型
if (app.globalData) {
app.globalData.userType = 'seller';
}
// 调用API更新用户身份到数据库
try {
const API = require('../../utils/api');
await API.updateUserType('seller');
console.log('用户身份已成功更新为seller并同步到数据库');
} catch (updateErr) {
console.error('更新用户身份到数据库失败:', updateErr);
// 即使更新失败,也不影响申请提交成功的提示
}
wx.showToast({ wx.showToast({
title: '提交成功,等待审核', title: '提交成功,等待审核',
icon: 'none', icon: 'none',
@ -1477,30 +1499,56 @@ Page({
showCooperationDetail(e) { showCooperationDetail(e) {
const type = e.currentTarget.dataset.type; const type = e.currentTarget.dataset.type;
const cooperationDetails = { const cooperationDetails = {
'货源委托': { '代销业务': {
title: '货源委托', title: '代销业务规则',
content: '货源委托是指供应商将货源委托给平台销售,平台负责销售和结算,供应商无需自行销售,只需要按照约定时间、数量、质量标准提供货源即可。' content: '\n定价规则:代销商户可自主制定所挂货源的销售价格,价格需符合平台物价管控要求,不得恶意定价。\n\n服务费规则:平台对代销挂货收取固定服务费,标准为1 元 / 件,仅在货源成功卖出后收取,未卖出不产生费用。\n\n保证金规则\n\n参与代销业务的商户需按合作车型缴纳保证金,具体标准如下:\n\n4.2 米车型:300 元 / 车\n\n6.8 米车型:500 元 / 车\n\n9.6 米车型:800 元 / 车\n\n挂车车型:1200 元 / 车\n\n保证金仅作为履约担保,合作结束且无违规违约行为的,平台将按原支付路径全额退回。\n\n协议签署要求:商户参与代销业务前,需与平台签订《委托代销协议书》,明确双方权利、义务及违约责任。\n\n销售风险说明:平台仅提供货源展示、交易撮合服务,不保证代销货源一定能够卖出,货源滞销风险由商户自行承担。\n'
}, },
'自主定价销售': { '包场合作': {
title: '自主定价销售', title: '包销合作规则',
content: '供应商可以自主制定销售价格,自行负责销售和盈亏,平台提供交易撮合服务,按约定收取服务费。' content: '\n(一)包场销售(平台自负盈亏模式)\n\n1. 合作机制:平台与乙方就指定货源协商定价后,由平台全款收购该批货源,按约定时间结算价格,货权归属平台。\n\n2. 乙方义务:乙方需按照合作约定的时间、数量、质量标准提供货源,不得出现拖欠货源、擅自将约定货源自主销售等违约行为。\n\n3. 销售与盈亏:平台自主负责收购货源的销售事宜,独立承担销售过程中的盈利与亏损。\n\n(二)包场销售(乙方自主销售模式)\n\n1. 销售限制:乙方可自主销售约定货源,或委托平台销售,严禁将该批货源委托给平台及乙方之外的第三方销售。\n\n2. 兜底与结算:平台不承担该批货源的销售兜底责任,不设定固定结算周期,实行每日结算。\n\n3. 抽成与利润分配:(委托平台销售)\n\n盈利场景:每日销售盈利部分由甲方与乙方对等分配,平台同步按1元/件标准抽取费用。\n\n亏损场景:若当日销售无盈利或者亏损,平台仍按0.8元/件标准抽取费用(可打折)\n'
}, },
'区域包场合作': { '采销联盟合作': {
title: '区域包场合作', title: '采销联盟合作规则',
content: '在指定区域内独家合作,享受区域保护政策,平台提供区域内的独家销售权限和支持。' content: '\n1. 合作主体:外部采购公司可通过成立独立的盒子公司,与平台开展货源包场或货源收购合作。\n\n2. 风险承担:盒子公司承担合作过程中产生的各类风险(包括但不限于货源质量风险、销售风险、市场风险等)。\n\n3. 利润分配:合作产生的净利润按以下比例分配:平台占20%、甲方占30%、乙方(盒子公司对应的外部采购公司)占50%。\n'
}, },
'其他': { '其他': {
title: '其他合作模式', title: '其他',
content: '其他特殊合作模式,需与平台单独协商具体合作条款和条件。' content: '其他合作模式'
} }
}; };
this.setData({ // 切换显示/隐藏功能
selectedCooperationDetail: cooperationDetails[type] || { if (this.data.selectedCooperationDetail && this.data.selectedCooperationDetail.title === cooperationDetails[type].title) {
title: type, // 再次点击同一个按钮,收起详情
content: '暂无详细说明' this.setData({
} selectedCooperationDetail: null
}); });
} else {
// 点击不同按钮,显示详情
this.setData({
selectedCooperationDetail: cooperationDetails[type] || {
title: type,
content: '暂无详细说明'
}
});
// 设置需要滚动到的ID
this.setData({
scrollToView: 'cooperation-detail-content'
});
// 延迟执行一次滚动到底部,确保内容完全可见
setTimeout(() => {
const query = wx.createSelectorQuery().in(this);
query.select('.cooperation-help-container').node().exec(nodes => {
const container = nodes[0].node;
if (container) {
// 确保滚动到最底部
container.scrollTop = container.scrollHeight;
}
});
}, 400);
}
}, },
/** /**

32
pages/settlement/index.wxml

@ -146,28 +146,28 @@
</view> </view>
<view class="cooperation-options"> <view class="cooperation-options">
<view <view
class="cooperation-option {{cooperation === '货源委托' ? 'active' : ''}}" class="cooperation-option {{cooperation === '代销业务' ? 'active' : ''}}"
bindtap="selectCooperation" bindtap="selectCooperation"
data-value="货源委托" data-value="代销业务"
> >
<view class="cooperation-icon"></view> <view class="cooperation-icon"></view>
<text class="cooperation-text">货源委托</text> <text class="cooperation-text">代销业务</text>
</view> </view>
<view <view
class="cooperation-option {{cooperation === '自主定价销售' ? 'active' : ''}}" class="cooperation-option {{cooperation === '采销联盟合作' ? 'active' : ''}}"
bindtap="selectCooperation" bindtap="selectCooperation"
data-value="自主定价销售" data-value="采销联盟合作"
> >
<view class="cooperation-icon"></view> <view class="cooperation-icon"></view>
<text class="cooperation-text">自主定价销售</text> <text class="cooperation-text">采销联盟合作</text>
</view> </view>
<view <view
class="cooperation-option {{cooperation === '区域包场合作' ? 'active' : ''}}" class="cooperation-option {{cooperation === '包场合作' ? 'active' : ''}}"
bindtap="selectCooperation" bindtap="selectCooperation"
data-value="区域包场合作" data-value="包场合作"
> >
<view class="cooperation-icon"></view> <view class="cooperation-icon"></view>
<text class="cooperation-text">区域包场合作</text> <text class="cooperation-text">包场合作</text>
</view> </view>
<view <view
class="cooperation-option {{cooperation === '其他' ? 'active' : ''}}" class="cooperation-option {{cooperation === '其他' ? 'active' : ''}}"
@ -368,20 +368,20 @@
<!-- 合作模式帮助弹窗 --> <!-- 合作模式帮助弹窗 -->
<view wx:if="{{showCooperationHelp}}" class="cooperation-help-overlay"> <view wx:if="{{showCooperationHelp}}" class="cooperation-help-overlay">
<view class="cooperation-help-container"> <scroll-view class="cooperation-help-container" scroll-y="true" enable-back-to-top="false" scroll-into-view="{{scrollToView}}">
<view class="cooperation-help-title">合作模式说明</view> <view class="cooperation-help-title">合作模式说明</view>
<view class="cooperation-help-content"> <view class="cooperation-help-content">
<view class="cooperation-buttons"> <view class="cooperation-buttons">
<button class="cooperation-button" bindtap="showCooperationDetail" data-type="货源委托">货源委托</button> <button class="cooperation-button {{selectedCooperationDetail && selectedCooperationDetail.title === '代销业务规则' ? 'selected' : ''}}" bindtap="showCooperationDetail" data-type="代销业务">代销业务</button>
<button class="cooperation-button" bindtap="showCooperationDetail" data-type="自主定价销售">自主定价销售</button> <button class="cooperation-button {{selectedCooperationDetail && selectedCooperationDetail.title === '采销联盟合作规则' ? 'selected' : ''}}" bindtap="showCooperationDetail" data-type="采销联盟合作">采销联盟合作</button>
<button class="cooperation-button" bindtap="showCooperationDetail" data-type="区域包场合作">区域包场合作</button> <button class="cooperation-button {{selectedCooperationDetail && selectedCooperationDetail.title === '包销合作规则' ? 'selected' : ''}}" bindtap="showCooperationDetail" data-type="包场合作">包场合作</button>
<button class="cooperation-button" bindtap="showCooperationDetail" data-type="其他">其他</button> <button class="cooperation-button {{selectedCooperationDetail && selectedCooperationDetail.title === '其他' ? 'selected' : ''}}" bindtap="showCooperationDetail" data-type="其他">其他</button>
</view> </view>
<view class="cooperation-detail" wx:if="{{selectedCooperationDetail}}"> <view class="cooperation-detail" wx:if="{{selectedCooperationDetail}}" id="cooperation-detail-content">
<view class="detail-title">{{selectedCooperationDetail.title}}</view> <view class="detail-title">{{selectedCooperationDetail.title}}</view>
<view class="detail-content">{{selectedCooperationDetail.content}}</view> <view class="detail-content">{{selectedCooperationDetail.content}}</view>
</view> </view>
</view> </view>
<button class="cooperation-help-button" bindtap="closeCooperationHelp">关闭</button> <button class="cooperation-help-button" bindtap="closeCooperationHelp">关闭</button>
</view> </scroll-view>
</view> </view>

84
pages/settlement/index.wxss

@ -780,8 +780,9 @@ picker {
.cooperation-option.active { .cooperation-option.active {
border-color: #07C160; border-color: #07C160;
background: #e8f7ed; border-width: 3rpx;
box-shadow: 0 2rpx 8rpx rgba(7, 193, 96, 0.15); background: #ffffff;
box-shadow: 0 4rpx 12rpx rgba(7, 193, 96, 0.2);
} }
.cooperation-option:active { .cooperation-option:active {
@ -875,18 +876,21 @@ picker {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 9999; z-index: 9999;
padding: 20rpx; padding: 0;
} }
.cooperation-help-container { .cooperation-help-container {
background-color: #fff; background-color: #fff;
border-radius: 20rpx; border-radius: 0;
padding: 50rpx 40rpx; padding: 50rpx 40rpx 150rpx;
max-width: 92%; width: 100%;
max-height: 88%; height: 100%;
max-width: 100%;
max-height: 100%;
overflow-y: auto; overflow-y: auto;
box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.2); box-shadow: none;
background: linear-gradient(to bottom, #ffffff, #f8f9fa); background: linear-gradient(to bottom, #ffffff, #f8f9fa);
display: block;
} }
/* 自定义滚动条样式 */ /* 自定义滚动条样式 */
@ -913,9 +917,9 @@ picker {
font-size: 38rpx; font-size: 38rpx;
font-weight: bold; font-weight: bold;
color: #2c3e50; color: #2c3e50;
margin-bottom: 40rpx; margin-bottom: 20rpx;
text-align: center; text-align: center;
padding-bottom: 25rpx; padding-bottom: 15rpx;
border-bottom: 2rpx solid #e8f5e8; border-bottom: 2rpx solid #e8f5e8;
letter-spacing: 2rpx; letter-spacing: 2rpx;
} }
@ -924,7 +928,13 @@ picker {
font-size: 30rpx; font-size: 30rpx;
color: #555555; color: #555555;
line-height: 56rpx; line-height: 56rpx;
margin-bottom: 50rpx; margin-bottom: 20rpx;
width: 100%;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
} }
/* 一级标题样式 */ /* 一级标题样式 */
@ -984,18 +994,22 @@ picker {
.cooperation-buttons { .cooperation-buttons {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 20rpx; gap: 25rpx;
margin-bottom: 30rpx; margin-bottom: 60rpx;
margin-top: 400rpx;
width: 100%;
align-items: center;
justify-content: center;
} }
.cooperation-button { .cooperation-button {
width: 100%; width: 80%;
padding: 24rpx; padding: 30rpx;
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%); background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
color: #333; color: #333;
border: 2rpx solid rgba(7, 193, 96, 0.2); border: 2rpx solid rgba(7, 193, 96, 0.2);
border-radius: 12rpx; border-radius: 16rpx;
font-size: 30rpx; font-size: 32rpx;
font-weight: 500; font-weight: 500;
transition: all 0.3s ease; transition: all 0.3s ease;
cursor: pointer; cursor: pointer;
@ -1003,15 +1017,31 @@ picker {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin: 0 auto;
}
/* 为帮助弹窗中的合作模式按钮添加选中样式 */
.cooperation-button.selected {
border-color: #07C160;
border-width: 3rpx;
background: #ffffff;
box-shadow: 0 4rpx 12rpx rgba(7, 193, 96, 0.2);
color: #07C160;
font-weight: 600;
} }
/* 移除原有的激活状态渐变背景,保持一致的样式 */
.cooperation-button:active { .cooperation-button:active {
transform: scale(0.98); transform: scale(0.98);
background: linear-gradient(135deg, #07C160 0%, #06ae56 100%); background: #ffffff;
color: white; color: #07C160;
border-color: #07C160; border-color: #07C160;
} }
.cooperation-button.selected:active {
background: #f8fff8;
}
.cooperation-detail { .cooperation-detail {
margin-top: 20rpx; margin-top: 20rpx;
padding: 24rpx; padding: 24rpx;
@ -1038,7 +1068,7 @@ picker {
/* 按钮样式优化 */ /* 按钮样式优化 */
.cooperation-help-button { .cooperation-help-button {
width: 100%; width: 80%;
height: 92rpx; height: 92rpx;
background: linear-gradient(135deg, #07C160 0%, #06b358 100%); background: linear-gradient(135deg, #07C160 0%, #06b358 100%);
color: #fff; color: #fff;
@ -1048,9 +1078,21 @@ picker {
font-weight: bold; font-weight: bold;
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s ease;
margin-top: 30rpx; margin-top: 60rpx;
box-shadow: 0 6rpx 20rpx rgba(7, 193, 96, 0.3); box-shadow: 0 6rpx 20rpx rgba(7, 193, 96, 0.3);
letter-spacing: 2rpx; letter-spacing: 2rpx;
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
margin-left: auto;
margin-right: auto;
position: sticky;
bottom: 40rpx;
left: 0;
right: 0;
z-index: 10;
background-color: #07C160;
} }
.cooperation-help-button:active { .cooperation-help-button:active {

2
project.private.config.json

@ -1,6 +1,6 @@
{ {
"libVersion": "3.10.3", "libVersion": "3.10.3",
"projectname": "Program-mini", "projectname": "New2",
"setting": { "setting": {
"urlCheck": false, "urlCheck": false,
"coverView": true, "coverView": true,

Loading…
Cancel
Save