// pages/my/my.js
const STORAGE_KEY = 'wechatAccounts';
const TASK_ID_PREFIX = 'task_';
let taskIdCounter = 0; // 用于生成唯一任务ID
Page({
data: {
showTaskModal: false,
searchKeyword: '',
sortOptions: [
{ name: '编号顺序', key: 'tagId' },
{ name: '微信名', key: 'wechatName' },
{ name: '业务员', key: 'salesman' }
],
sortIndex: 0,
rawList: [],
displayList: [],
activeTasks: [], // 当前激活的任务列表
},
onAddTask() {
this.loadWechatData();
this.setData({ showTaskModal: true });
},
loadWechatData() {
try {
const wechats = wx.getStorageSync(STORAGE_KEY) || [];
this.setData({
rawList: wechats,
displayList: wechats
}, () => {
this.filterAndSort();
});
} catch (e) {
console.error('读取微信账号失败', e);
this.setData({ rawList: [], displayList: [] });
}
},
onSearchInput(e) {
this.setData({ searchKeyword: e.detail.value.trim() }, () => {
this.filterAndSort();
});
},
clearSearch() {
this.setData({ searchKeyword: '' }, () => {
this.filterAndSort();
});
},
onSortChange(e) {
const index = parseInt(e.detail.value);
this.setData({ sortIndex: index }, () => {
this.filterAndSort();
});
},
filterAndSort() {
const { rawList, searchKeyword, sortIndex, sortOptions } = this.data;
const kw = searchKeyword.toLowerCase();
const sortKey = sortOptions[sortIndex].key;
let result = [...rawList];
if (kw) {
result = result.filter(item =>
[item.tagId, item.wechatName, item.salesman]
.some(field => field && field.toString().toLowerCase().includes(kw))
);
}
result.sort((a, b) => {
const valA = (a[sortKey] || '').toString().toLowerCase();
const valB = (b[sortKey] || '').toString().toLowerCase();
return valA.localeCompare(valB, 'zh');
});
this.setData({ displayList: result });
},
// 选择某个账号并创建任务
selectAccount(e) {
const account = e.currentTarget.dataset.account;
const newTask = {
id: TASK_ID_PREFIX + (taskIdCounter++),
tagId: account.tagId,
salesman: account.salesman || '—',
invitedCount: 0,
acceptedCount: 0,
isExpanded: true,
tempRemark: '',
invitations: []
};
this.setData({
activeTasks: [...this.data.activeTasks, newTask],
showTaskModal: false,
searchKeyword: ''
});
},
// 切换展开/收起
toggleTaskExpand(e) {
const id = e.currentTarget.dataset.id;
const tasks = this.data.activeTasks.map(t => {
if (t.id === id) {
return { ...t, isExpanded: !t.isExpanded };
}
return t;
});
this.setData({ activeTasks: tasks });
},
// 输入客户备注
onRemarkInput(e) {
const value = e.detail.value;
const id = e.currentTarget.dataset.id;
const tasks = this.data.activeTasks.map(t => {
if (t.id === id) {
return { ...t, tempRemark: value };
}
return t;
});
this.setData({ activeTasks: tasks });
},
// 添加邀请
addInvite(e) {
const id = e.currentTarget.dataset.id;
const now = new Date();
const month = (now.getMonth() + 1).toString().padStart(2, '0');
const day = now.getDate().toString().padStart(2, '0');
const hour = now.getHours().toString().padStart(2, '0');
const minute = now.getMinutes().toString().padStart(2, '0');
const timeStr = `${month}-${day} ${hour}:${minute}`; // 格式:04-05 13:22
const tasks = this.data.activeTasks.map(t => {
if (t.id === id && t.tempRemark.trim()) {
const remark = t.tempRemark.trim();
const newInvite = {
id: Date.now() + Math.random(), // 唯一ID
remark,
accepted: false,
time: timeStr // 添加时间
};
t.invitations.push(newInvite);
t.tempRemark = '';
t.invitedCount += 1; // 正常增加邀请数
}
return t;
});
this.setData({ activeTasks: tasks });
},
// 标记为已通过
acceptInvite(e) {
const taskId = e.currentTarget.dataset.taskid;
const index = parseInt(e.currentTarget.dataset.index);
const tasks = this.data.activeTasks.map(t => {
if (t.id === taskId && !t.invitations[index].accepted) {
t.invitations[index].accepted = true;
t.acceptedCount += 1;
}
return t;
});
this.setData({ activeTasks: tasks });
},
// 删除邀请
deleteInvite(e) {
const taskId = e.currentTarget.dataset.taskid;
const index = parseInt(e.currentTarget.dataset.index);
const tasks = this.data.activeTasks.map(t => {
if (t.id === taskId && t.invitations[index]) {
const invite = t.invitations[index];
// 如果是已通过的,才减少 acceptedCount
if (invite.accepted) {
t.acceptedCount -= 1;
}
// 任何情况删除,都要减少 invitedCount
t.invitedCount -= 1;
// 删除数组项
t.invitations.splice(index, 1);
}
return t;
});
this.setData({ activeTasks: tasks });
},
// 清空所有任务
clearAllTasks() {
this.setData({
activeTasks: []
});
},
noop() {}
});
<!-- pages/my/my.wxml -->
<view class="container">
<!-- 已添加的任务列表 -->
<view wx:if="{{activeTasks.length > 0}}" class="task-header">
<button class="add-task-btn mini" bindtap="onAddTask">添加任务</button>
<button class="clear-task-btn mini" bindtap="clearAllTasks">清空任务</button>
</view>
<!-- 多个任务卡片 -->
<block wx:for="{{activeTasks}}" wx:key="id">
<view class="task-card">
<!-- 卡片头部:编号 + 业务员 + 展开箭头 -->
<view class="card-header" catchtap="toggleTaskExpand" data-id="{{item.id}}">
<text class="card-id">{{item.tagId}}</text>
<text class="card-salesman">业务员: {{item.salesman}}</text>
<text class="expand-arrow">{{item.isExpanded ? '▼' : '▶'}}</text>
</view>
<!-- 下方统计行 -->
<view class="card-stats">
<text class="stat-text">已邀请: {{item.invitedCount}}</text>
<text class="stat-text">已添加: {{item.acceptedCount}}</text>
</view>
<!-- 展开区域 -->
<view wx:if="{{item.isExpanded}}" class="card-body">
<!-- 输入区 -->
<view class="input-row">
<input type="text" placeholder="客户备注" value="{{item.tempRemark}}" bindinput="onRemarkInput" data-id="{{item.id}}" class="remark-input" />
<button class="add-invite-btn" bindtap="addInvite" data-id="{{item.id}}">添加邀请</button>
</view>
<!-- 邀请列表 -->
<view wx:for="{{item.invitations}}" wx:key="id" wx:for-item="invite" wx:for-index="idx" class="invite-item">
<block wx:if="{{!invite.accepted}}">
<!-- 显示:客户备注 + 时间 -->
<text class="invite-text">{{invite.remark}} {{invite.time}}</text>
<button class="accept-btn mini-btn" bindtap="acceptInvite" data-taskid="{{item.id}}" data-index="{{idx}}">已通过</button>
<button class="delete-btn mini-btn" bindtap="deleteInvite" data-taskid="{{item.id}}" data-index="{{idx}}">删除</button>
</block>
<block wx:else>
<text class="accepted-line">{{invite.remark}} 已通过</text>
</block>
</view>
</view>
</view>
</block>
<!-- 主添加按钮(当没有任务时显示) -->
<button wx:if="{{activeTasks.length === 0}}" class="add-task-btn" bindtap="onAddTask">添加任务</button>
<!-- 弹窗遮罩层 -->
<view class="modal-overlay" wx:if="{{showTaskModal}}" catchtouchmove="noop">
<view class="task-modal">
<!-- 搜索栏 -->
<view class="search-bar">
<input type="text" placeholder="编号/微信名/业务员" value="{{searchKeyword}}" bindinput="onSearchInput" class="search-input" />
<text class="search-icon">🔍</text>
<text class="clear-icon" wx:if="{{searchKeyword}}" catchtap="clearSearch">✕</text>
</view>
<!-- 排序选择 + 表头 -->
<view class="header-row">
<picker mode="selector" range="{{sortOptions}}" range-key="name" value="{{sortIndex}}" bindchange="onSortChange">
<view class="sort-trigger">
{{sortOptions[sortIndex].name}} <text class="arrow-down">▼</text>
</view>
</picker>
<text class="today-header">今日添加数</text>
</view>
<!-- 数据列表 -->
<scroll-view scroll-y class="data-list-container">
<block wx:for="{{displayList}}" wx:key="id">
<view class="data-item" catchtap="selectAccount" data-account="{{item}}">
<view class="col-id">{{item.tagId}}</view>
<view class="col-tag orange-tag">{{item.wechatName || '—'}}</view>
<view class="col-tag cyan-tag">{{item.salesman || '—'}}</view>
<view class="col-count">0</view>
</view>
</block>
<!-- 空数据提示 -->
<view wx:if="{{displayList.length === 0}}" class="empty-tip">暂无匹配数据</view>
</scroll-view>
</view>
</view>
</view>/* pages/my/my.wxss */
.container {
padding: 20rpx;
position: relative;
}
/* 主按钮 */
.add-task-btn {
width: 100%;
background-color: #07c160;
color: white;
margin-bottom: 20rpx;
font-size: 32rpx;
}
.mini {
display: inline-block;
width: auto;
padding: 10rpx 20rpx;
margin: 0 10rpx;
font-size: 28rpx;
}
.clear-task-btn {
background-color: #fa5151;
color: white;
float: right;
}
.task-header {
display: flex;
align-items: center;
margin-bottom: 20rpx;
}
.add-task-btn.mini {
background-color: #07c160;
color: white;
font-size: 28rpx;
padding: 10rpx 30rpx;
border-radius: 8rpx;
margin-right: auto; /* 左对齐并拉开右边距 */
}
/* 任务卡片 */
.task-card {
background: #f9f9f9;
border: 1px solid #ddd;
border-radius: 12rpx;
padding: 20rpx;
margin-bottom: 20rpx;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
font-weight: bold;
color: #333;
}
.card-id {
color: #000;
font-size: 32rpx;
}
.card-salesman {
/* 绿色背景 + 白色文字 + 内边距 + 圆角 */
background-color: #07c160;
color: white;
padding: 6rpx 16rpx;
border-radius: 6rpx;
font-size: 24rpx;
font-weight: normal;
}
.expand-arrow {
font-size: 24rpx;
color: #888;
}
.card-stats {
margin-top: 10rpx;
font-size: 24rpx;
color: #888;
}
.stat-text {
margin-right: 20rpx;
}
/* 输入行 */
.input-row {
display: flex;
margin-top: 20rpx;
align-items: center;
}
.remark-input {
flex: 1;
height: 60rpx;
border: 1px solid #ccc;
border-radius: 8rpx;
padding: 0 10rpx;
font-size: 28rpx;
margin-right: 10rpx;
}
.add-invite-btn {
background-color: #1890ff;
color: white;
font-size: 28rpx;
height: 60rpx; /* 和输入框同高 */
line-height: 60rpx; /* 垂直居中 */
padding: 0 20rpx; /* 控制宽度不要太宽 */
min-width: 100rpx;
border-radius: 8rpx;
}
/* 邀请项 */
.invite-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10rpx 0;
border-bottom: 1px dashed #eee;
font-size: 28rpx;
}
/* 客户名+时间 合并为一段文本,左对齐 */
.invite-text {
flex: 1;
color: #333;
font-size: 28rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; /* 禁止换行 */
}
.accept-btn, .delete-btn {
font-size: 24rpx;
padding: 0 15rpx;
height: 50rpx;
line-height: 50rpx;
}
.accept-btn {
background-color: #1890ff;
color: white;
height: 50rpx;
}
.delete-btn {
background-color: #fa5151;
color: white;
}
.accepted-text {
color: #aaa;
font-size: 24rpx;
}
/* 弹窗相关样式保持不变 */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 999;
}
.task-modal {
width: 90%;
max-height: 70%;
background: white;
border-radius: 16rpx;
overflow: hidden;
}
.search-bar {
display: flex;
align-items: center;
padding: 20rpx;
position: relative;
}
.search-input {
flex: 1;
height: 60rpx;
border: 1px solid #ddd;
border-radius: 8rpx;
padding: 0 60rpx;
}
.search-icon {
position: absolute;
left: 30rpx;
color: #999;
}
.mini-btn {
min-width: 60rpx !important;
padding: 0 16rpx !important;
height: 50rpx;
line-height: 50rpx;
font-size: 24rpx;
margin: 0 0 0 10rpx;
}
.accepted-line {
color: #aaa;
font-size: 28rpx;
flex: 1;
}
.clear-icon {
position: absolute;
right: 80rpx;
color: #999;
font-weight: bold;
cursor: pointer;
}
.header-row {
display: flex;
justify-content: space-between;
padding: 0 20rpx 20rpx;
align-items: center;
}
.sort-trigger {
display: flex;
align-items: center;
background: #f0f0f0;
padding: 10rpx 20rpx;
border-radius: 8rpx;
font-size: 28rpx;
}
.arrow-down {
margin-left: 10rpx;
font-size: 20rpx;
}
.today-header {
font-size: 24rpx;
color: #666;
}
.data-list-container {
max-height: 400rpx;
height: 400rpx;
}
.data-item {
display: flex;
padding: 20rpx;
border-bottom: 1px solid #eee;
font-size: 28rpx;
}
.col-id { width: 15%; }
.col-tag { padding: 6rpx 12rpx; border-radius: 6rpx; margin-right: 10rpx; }
.orange-tag { background: #fff7e6; color: #faad14; }
.cyan-tag { background: #e6fffb; color: #13c2c2; }
.col-count { width: 20%; text-align: right; color: #999; }
.empty-tip {
text-align: center;
color: #999;
padding: 40rpx;
}
同上 我现在看不到客户名字和时间 那个已通过和删除实在是太宽太长了
最新发布