feat: 完善双端演示注册与红娘服务闭环
This commit is contained in:
@@ -11,6 +11,9 @@
|
||||
* 展示待处理服务、工作台数据概览
|
||||
*/
|
||||
const api = require('../../utils/api');
|
||||
const { authStore } = require('../../stores');
|
||||
const { matchmakerService } = require('../../services');
|
||||
const { IS_DEV } = require('../../env');
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@@ -20,6 +23,13 @@ Page({
|
||||
todayCount: 0,
|
||||
completedCount: 0,
|
||||
myAssignments: [],
|
||||
serviceTabs: [{ value: 'pending', label: '待处理' }, { value: 'in_progress', label: '进行中' }, { value: 'completed', label: '已完成' }],
|
||||
activeServiceTab: 'pending',
|
||||
services: [],
|
||||
visibleServices: [],
|
||||
demoEnabled: IS_DEV,
|
||||
creatingDemoUser: false,
|
||||
assigningServiceId: '',
|
||||
assignmentCount: 0,
|
||||
loading: true,
|
||||
currentDate: '',
|
||||
@@ -92,7 +102,7 @@ Page({
|
||||
}
|
||||
|
||||
if (assignmentRes) {
|
||||
const assignments = assignmentRes || [];
|
||||
const assignments = Array.isArray(assignmentRes) ? assignmentRes : (assignmentRes.list || []);
|
||||
// 联系授权申请目标 = 本人生效中的分配对象(B1:只能对分配对象发起)
|
||||
const targets = assignments.map((a) => ({
|
||||
userId: a.userId,
|
||||
@@ -105,6 +115,7 @@ Page({
|
||||
contactTargetIndex: 0,
|
||||
});
|
||||
this.loadContactAuthorizations();
|
||||
await this.loadServices(token, assignments);
|
||||
}
|
||||
if (referralRes) {
|
||||
this.setData({
|
||||
@@ -132,8 +143,83 @@ Page({
|
||||
}
|
||||
},
|
||||
|
||||
async loadServices(token, assignments) {
|
||||
const headers = { Authorization: `Bearer ${token}` };
|
||||
const assigned = await Promise.allSettled(assignments.filter((item) => item.serviceId).map((item) =>
|
||||
api.get(`/operator/matchmaker/services/${encodeURIComponent(item.serviceId)}`, {}, headers)));
|
||||
const [pending, management] = await Promise.allSettled([
|
||||
api.get('/operator/matchmaker/pending', {}, headers),
|
||||
api.get('/operator/matchmaker/management/services', {}, headers),
|
||||
]);
|
||||
const services = new Map();
|
||||
assigned.forEach((result) => {
|
||||
if (result.status === 'fulfilled' && result.value) {
|
||||
const item = result.value;
|
||||
services.set(item.serviceId || item.id, { ...item, userDisplayName: item.userProfile && item.userProfile.displayName, source: 'assignment' });
|
||||
}
|
||||
});
|
||||
if (management.status === 'fulfilled') (management.value || []).forEach((item) =>
|
||||
services.set(item.serviceId || item.id, { ...item, source: item.status === 'submitted' || item.status === 'completed' ? 'management' : 'assignment' }));
|
||||
if (pending.status === 'fulfilled') (pending.value || []).forEach((item) =>
|
||||
services.set(item.serviceId || item.id, { ...item, source: 'management' }));
|
||||
this.setData({ services: [...services.values()].map((item) => ({
|
||||
...item,
|
||||
statusLabel: this.serviceStatusLabel(item.status),
|
||||
serviceTypeLabel: item.serviceType === 'recommend_partner' ? '推荐对象' : (item.serviceType || '公益红娘服务'),
|
||||
})) });
|
||||
this.selectServiceTab({ currentTarget: { dataset: { tab: this.data.activeServiceTab } } });
|
||||
},
|
||||
|
||||
selectServiceTab(e) {
|
||||
const tab = e.currentTarget.dataset.tab;
|
||||
const statuses = tab === 'pending' ? ['submitted', 'pending']
|
||||
: tab === 'in_progress' ? ['assigned', 'in_service', 'in_progress', 'waiting_user'] : ['completed'];
|
||||
this.setData({ activeServiceTab: tab, visibleServices: this.data.services.filter((item) => statuses.includes(item.status)) });
|
||||
},
|
||||
|
||||
serviceStatusLabel(status) {
|
||||
return { submitted: '待处理', assigned: '已接单', in_service: '服务中', waiting_user: '待用户确认', completed: '已完成' }[status] || status;
|
||||
},
|
||||
|
||||
async createDemoUser() {
|
||||
if (this.data.creatingDemoUser) return;
|
||||
this.setData({ creatingDemoUser: true });
|
||||
try {
|
||||
const code = `demo_openid_workbench_${Date.now()}`;
|
||||
await authStore.loginWithDemo(code, '演示服务用户');
|
||||
await matchmakerService.applyService({ serviceType: 'recommend_partner', description: '红娘演示服务申请' });
|
||||
wx.showToast({ title: '演示申请已创建', icon: 'success' });
|
||||
this.setData({ activeServiceTab: 'pending' });
|
||||
await this.loadDashboard();
|
||||
} catch (err) {
|
||||
wx.showToast({ title: err.message || '注册演示用户失败', icon: 'none' });
|
||||
} finally {
|
||||
this.setData({ creatingDemoUser: false });
|
||||
}
|
||||
},
|
||||
|
||||
async assignToSelf(e) {
|
||||
const serviceId = e.currentTarget.dataset.id;
|
||||
const operatorId = wx.getStorageSync('operatorId');
|
||||
if (!serviceId || !operatorId || this.data.assigningServiceId) return;
|
||||
this.setData({ assigningServiceId: serviceId });
|
||||
try {
|
||||
const token = wx.getStorageSync('operatorToken');
|
||||
await api.post(`/operator/matchmaker/services/${encodeURIComponent(serviceId)}/assign`,
|
||||
{ operatorId, reason: '演示分配' }, { Authorization: `Bearer ${token}` });
|
||||
wx.showToast({ title: '已接单', icon: 'success' });
|
||||
this.setData({ activeServiceTab: 'in_progress' });
|
||||
await this.loadDashboard();
|
||||
} catch (err) {
|
||||
wx.showToast({ title: err.message || '接单失败', icon: 'none' });
|
||||
} finally {
|
||||
this.setData({ assigningServiceId: '' });
|
||||
}
|
||||
},
|
||||
|
||||
onViewService(e) {
|
||||
const serviceId = e.currentTarget.dataset.id;
|
||||
const source = e.currentTarget.dataset.source || 'assignment';
|
||||
if (!serviceId) {
|
||||
const index = Number(e.currentTarget.dataset.index);
|
||||
const item = this.data.myAssignments[index] || {};
|
||||
@@ -144,7 +230,7 @@ Page({
|
||||
});
|
||||
return;
|
||||
}
|
||||
wx.navigateTo({ url: `/pages/matchmaker-service-detail/matchmaker-service-detail?id=${serviceId}` });
|
||||
wx.navigateTo({ url: `/pages/matchmaker-service-detail/matchmaker-service-detail?id=${serviceId}&source=${source}` });
|
||||
},
|
||||
|
||||
openReferral() {
|
||||
|
||||
@@ -44,42 +44,45 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 我的服务对象分配 -->
|
||||
<!-- 统一服务工作台 -->
|
||||
<view class="section section-compact" wx:if="{{!loading}}">
|
||||
<view class="section-header">
|
||||
<view class="section-title-wrap">
|
||||
<text class="section-dot"></text>
|
||||
<text class="section-title">我的服务对象分配</text>
|
||||
<text class="section-title">服务工作台</text>
|
||||
</view>
|
||||
<text class="section-count" wx:if="{{assignmentCount > 0}}">共{{assignmentCount}}人</text>
|
||||
<button wx:if="{{demoEnabled}}" class="detail-btn" size="mini" loading="{{creatingDemoUser}}" bindtap="createDemoUser">注册演示用户</button>
|
||||
</view>
|
||||
<view class="service-tabs">
|
||||
<view wx:for="{{serviceTabs}}" wx:key="value" class="service-tab {{activeServiceTab === item.value ? 'active' : ''}}" data-tab="{{item.value}}" bindtap="selectServiceTab">{{item.label}}</view>
|
||||
</view>
|
||||
|
||||
<view class="service-list" wx:if="{{myAssignments.length > 0}}">
|
||||
<view class="service-list" wx:if="{{visibleServices.length > 0}}">
|
||||
<view
|
||||
wx:for="{{myAssignments}}"
|
||||
wx:key="id"
|
||||
wx:for="{{visibleServices}}"
|
||||
wx:key="serviceId"
|
||||
class="service-card"
|
||||
data-id="{{item.serviceId}}"
|
||||
data-source="{{item.source}}"
|
||||
data-index="{{index}}"
|
||||
bindtap="onViewService"
|
||||
>
|
||||
<view class="service-left">
|
||||
<view class="service-header">
|
||||
<view class="service-tag">{{assignmentScopeLabel(item.assignmentScope)}}</view>
|
||||
<view class="service-tag">{{assignmentStatusLabel(item.status)}}</view>
|
||||
<view class="service-time">{{formatTime(item.assignedAt)}}</view>
|
||||
<view class="service-tag">{{item.statusLabel}}</view>
|
||||
<view class="service-time">{{item.serviceTypeLabel}}</view>
|
||||
</view>
|
||||
<view class="service-name">{{item.userDisplayName || '未设置姓名'}} <text wx:if="{{item.userDisplayNumber}}">{{item.userDisplayNumber}}</text></view>
|
||||
<view class="service-desc">{{item.userAge ? item.userAge + '岁 · ' : ''}}{{item.userRegionName || '地区未设置'}}</view>
|
||||
<view class="service-name">{{item.userDisplayName || item.userDisplayNumber || '服务对象'}}</view>
|
||||
<view class="service-desc">{{item.description || item.latestFollowupContent || '暂无服务进度'}}</view>
|
||||
</view>
|
||||
<button class="detail-btn" size="mini" catchtap="onViewService" data-id="{{item.serviceId}}" data-index="{{index}}">查看详情</button>
|
||||
<button wx:if="{{item.status === 'submitted' && demoEnabled}}" class="detail-btn" size="mini" catchtap="assignToSelf" data-id="{{item.serviceId}}" loading="{{assigningServiceId === item.serviceId}}">接单</button>
|
||||
<button wx:else class="detail-btn" size="mini" catchtap="onViewService" data-id="{{item.serviceId}}" data-source="{{item.source}}">查看详情</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="empty-state empty-compact" wx:else>
|
||||
<view class="empty-illustration">📭</view>
|
||||
<view class="empty-text">暂无服务对象分配</view>
|
||||
<view class="empty-hint">分配给你的服务对象将在这里展示</view>
|
||||
<view class="empty-text">暂无该状态服务</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
@@ -157,6 +157,9 @@
|
||||
}
|
||||
|
||||
/* 服务列表 */
|
||||
.service-tabs { display: flex; border-bottom: 1rpx solid var(--color-divider); margin-bottom: 20rpx; }
|
||||
.service-tab { flex: 1; padding: 18rpx 0; text-align: center; color: var(--color-text-tertiary); font-size: 26rpx; }
|
||||
.service-tab.active { color: var(--color-primary-strong); border-bottom: 4rpx solid currentColor; font-weight: 600; }
|
||||
.service-list {
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
|
||||
Reference in New Issue
Block a user