fix: 商家入口按角色显示;消息合并;清缓存不自动登录且隐藏邀请码UI

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQueandCursor committed 2026-07-27 04:44:48 +08:00
1 parent 283133473a
commit a44be49ac6
10 files changed
+141 -65

No files matched your search

+41 -25
View File
@@ -18,8 +18,7 @@ import {
} from '../../utils/miniapp-icons.js'
import { getDefaultAvatarUrl } from '../../utils/avatar.js'
import { ensureRoleAgreement } from '../../utils/role-agreement-gate.js'
import { isFighterOnly, FIGHTER_ONLY_DEFAULT_INVITE, FIGHTER_HOME } from '../../utils/fighter-only.js'
import { ensureLogin } from '../../utils/login.js'
import { isFighterOnly, FIGHTER_ONLY_DEFAULT_INVITE, FIGHTER_HOME, shouldSkipAutoAuth, clearSkipAutoAuth } from '../../utils/fighter-only.js'
const PLATFORM_INVITE_CODE = FIGHTER_ONLY_DEFAULT_INVITE || '0000008VfJKPu4Spmcjt'
const app = getApp()
@@ -177,7 +176,7 @@ Page(createPage({
}, 500);
}
} else if (isFighterOnly()) {
// 无邀请码进入:自动用硬编码管事邀请码注册(有邀请链路不受影响)
// 无邀请码进入:自动用硬编码管事邀请码注册(清缓存后跳过,需手动登录)
setTimeout(() => {
this.tryAutoRegisterDefaultInvite();
}, 600);
@@ -371,11 +370,14 @@ Page(createPage({
push('goToKefu', '在线客服', img.iconKefu);
push('goToComplaintCreate', '投诉反馈', img.iconComplaint || img.iconContact);
push('goToComplaintList', '投诉记录', img.iconComplaint || img.iconRecord);
// 龙先生:不提供前端商家认证,仅已开通时进入商家端
// 龙先生:仅已开通商家时显示入口;未开通不展示
if (d.shangjiaCertified) {
push('onTapShangjiaAuth', '进入商家端', img.iconShangjia);
}
push('onTapStaffAuth', isStaffMode() ? '商家客服工作台' : '商家客服入驻', img.iconKefu || img.iconShangjia);
// 仅已是商家客服时显示工作台,未入驻不展示「入驻」入口
if (isStaffMode()) {
push('onTapStaffAuth', '商家客服工作台', img.iconKefu || img.iconShangjia);
}
if (d.showPindaoEntry) {
push('openPindaoModal', '频道', img.iconPindao);
}
@@ -411,7 +413,10 @@ Page(createPage({
if (!isFighterOnly()) {
push('switchToNormal', '返回点单端', img.iconSwitch);
}
push('handleWechatLogin', '一键登录', img.iconRefresh);
// 未登录才显示一键登录;已登录只保留清缓存
if (!wx.getStorageSync('token')) {
push('handleWechatLogin', '一键登录', img.iconRefresh);
}
push('clearCache', '清除缓存/退出', img.iconClear);
this.setData({ moreFuncList: list });
@@ -943,32 +948,32 @@ Page(createPage({
}
},
/** 纯打手端:无邀请码时自动绑定默认管事 */
/** 纯打手端:无邀请码时自动绑定默认管事(硬编码 inviteCode 正常传后端) */
tryAutoRegisterDefaultInvite() {
if (!isFighterOnly()) return;
if (shouldSkipAutoAuth()) return;
if (this.data.isDashou || this.data.isGuanshi || this.data.isZuzhang || this.data.isKaoheguan) return;
if (this.data.isAutoRegistering) return;
if (Number(wx.getStorageSync('dashoustatus')) === 1) return;
const code = PLATFORM_INVITE_CODE;
if (!code) {
console.error('默认邀请码缺失,无法自动注册');
return;
}
this.setData({ inviteCode: code, isAutoRegistering: true });
this.handleInviteCodeWithLoginCheck(code);
},
handleWechatLogin() {
ensureLogin({ silent: false, page: this })
.then(() => {
this.checkDashouStatus();
this.checkRoleStatuses();
if (!this.data.isDashou && isFighterOnly()) {
this.tryAutoRegisterDefaultInvite();
} else if (this.data.isDashou) {
this.refreshAllInfo(false);
}
wx.showToast({ title: '登录成功', icon: 'success' });
})
.catch(() => {
wx.showToast({ title: '登录失败', icon: 'none' });
});
// 用户主动登录:清掉「跳过自动登录」标记,并用硬编码邀请码走后端注册
clearSkipAutoAuth();
const code = PLATFORM_INVITE_CODE;
if (!code) {
wx.showToast({ title: '注册配置异常', icon: 'none' });
return;
}
this.setData({ inviteCode: code, isAutoRegistering: true });
this.handleInviteCodeWithLoginCheck(code);
},
_goFighterHomeAfterRegister() {
@@ -1002,15 +1007,23 @@ Page(createPage({
const that = this;
const app = getApp();
const apiBaseUrl = app.globalData.apiBaseUrl;
const finalInvite = (inviteCode || PLATFORM_INVITE_CODE || '').trim();
if (!finalInvite) {
wx.hideLoading();
wx.showToast({ title: '邀请码缺失,无法注册', icon: 'none' });
that.setData({ isAutoRegistering: false });
return;
}
if (!apiBaseUrl) {
wx.hideLoading();
wx.showToast({ title: '服务器配置错误', icon: 'none' });
return;
}
console.log('[fighter-auth] wdlyhdl inviteCode=', finalInvite);
wx.request({
url: apiBaseUrl + '/yonghu/wdlyhdl',
method: 'POST',
data: { code: code, inviteCode: inviteCode },
data: { code: code, inviteCode: finalInvite },
header: { 'content-type': 'application/json' },
success: (res) => {
if (res.statusCode === 200 && res.data && res.data.code === 0 && res.data.data) {
@@ -1059,6 +1072,7 @@ Page(createPage({
that.getDashouInfo();
that.switchToDashouRole();
lockPrimaryRole('dashou');
clearSkipAutoAuth();
wx.hideLoading();
wx.showToast({ title: '登录注册成功!', icon: 'success', duration: 2000 });
that._goFighterHomeAfterRegister();
@@ -1171,17 +1185,18 @@ Page(createPage({
},
async onRegister() {
const { inviteCode } = this.data;
const inviteCode = (this.data.inviteCode || PLATFORM_INVITE_CODE || '').trim();
if (!inviteCode) {
wx.showToast({ title: '请输入邀请码', icon: 'none', duration: 2000 });
wx.showToast({ title: '邀请码缺失,无法注册', icon: 'none', duration: 2000 });
return;
}
if (inviteCode.length > 100) {
wx.showToast({ title: '邀请码不能超过100字符', icon: 'none', duration: 2000 });
return;
}
this.setData({ isLoading: true });
this.setData({ isLoading: true, inviteCode });
try {
console.log('[fighter-auth] dashouzhuce inviteCode=', inviteCode);
const res = await request({
url: '/yonghu/dashouzhuce',
method: 'POST',
@@ -1227,6 +1242,7 @@ Page(createPage({
this.loadAvatar();
ensureRoleOnCenterPage(this, 'dashou');
lockPrimaryRole('dashou');
clearSkipAutoAuth();
wx.showToast({ title: '注册成功!', icon: 'success', duration: 2000 });
this._updateTotalAssets();
this._goFighterHomeAfterRegister();
+6 -6
View File
@@ -9,12 +9,12 @@
</view>
<view class="unreg-area">
<view class="panel shadow unreg-card">
<text class="unreg-title">{{isAutoRegistering ? '正在自动注册...' : '接单员认证'}}</text>
<input class="unreg-input" type="text" placeholder="输入邀请码(有邀请请填写)" maxlength="100" value="{{inviteCode}}" bindinput="onInviteCodeInput" placeholder-class="ph" />
<view class="btn-bg unreg-btn" bindtap="onRegister"><text class="unreg-btn-text">立即注册</text></view>
<view class="unreg-btn-secondary" bindtap="handleWechatLogin"><text>一键登录</text></view>
<view class="unreg-btn-secondary" bindtap="quickRegisterAsPlatform"><text>默认管事注册</text></view>
<view class="unreg-link" bindtap="clearCache"><text>清除缓存 / 退出</text></view>
<text class="unreg-title">{{isAutoRegistering ? '正在登录注册...' : '接单员'}}</text>
<text class="unreg-tip">{{isAutoRegistering ? '请稍候' : '点击下方登录即可进入'}}</text>
<view class="btn-bg unreg-btn" bindtap="handleWechatLogin" wx:if="{{!isAutoRegistering}}">
<text class="unreg-btn-text">一键登录</text>
</view>
<view class="unreg-link" bindtap="clearCache" wx:if="{{!isAutoRegistering}}"><text>清除缓存</text></view>
</view>
</view>
<tab-bar/>
+10 -1
View File
@@ -678,7 +678,16 @@ page {
font-weight: 700;
display: block;
text-align: center;
margin-bottom: 24rpx;
margin-bottom: 12rpx;
}
.unreg-tip {
display: block;
text-align: center;
font-size: 24rpx;
color: #999;
margin-bottom: 28rpx;
line-height: 1.4;
}
.unreg-input {
+19 -10
View File
@@ -16,7 +16,7 @@ Page(createPage({
allConversations: [],
filteredConversations: [],
activeTab: 0,
tabUnread: [0, 0, 0],
tabUnread: [0, 0],
displayCount: 10,
searchKeyword: '',
actionPopup: { visible: false, conversation: null },
@@ -210,7 +210,14 @@ Page(createPage({
const uid = wx.getStorageSync('uid');
if (!uid) {
wx.showToast({ title: '请先登录', icon: 'none' });
setTimeout(() => { wx.redirectTo({ url: '/pages/mine/mine' }); }, 1500);
setTimeout(() => {
try {
const { isFighterOnly, FIGHTER_MINE } = require('../../utils/fighter-only.js');
wx.redirectTo({ url: isFighterOnly() ? FIGHTER_MINE : '/pages/mine/mine' });
} catch (e) {
wx.redirectTo({ url: '/pages/fighter/fighter' });
}
}, 1500);
return false;
}
let currentUser = app.globalData.currentUser;
@@ -506,10 +513,11 @@ Page(createPage({
const { allConversations, activeTab, searchKeyword } = this.data;
let filtered = [];
if (activeTab === 0) {
filtered = allConversations.filter(c => isOrderGroupConversation(c));
// 订单群聊 + 用户私聊合并,点击仍按类型跳不同页
filtered = allConversations.filter(c =>
isOrderGroupConversation(c) || c.type === 'private' || c.type === 'group'
).filter(c => c.type !== 'cs');
} else if (activeTab === 1) {
filtered = allConversations.filter(c => c.type === 'private');
} else if (activeTab === 2) {
filtered = allConversations.filter(c => c.type === 'cs');
}
@@ -523,11 +531,12 @@ Page(createPage({
});
}
const tabUnread = [0, 0, 0];
const tabUnread = [0, 0];
allConversations.forEach(c => {
if (isOrderGroupConversation(c)) tabUnread[0] += c.unread || 0;
else if (c.type === 'private') tabUnread[1] += c.unread || 0;
else if (c.type === 'cs') tabUnread[2] += c.unread || 0;
if (c.type === 'cs') tabUnread[1] += c.unread || 0;
else if (isOrderGroupConversation(c) || c.type === 'private' || c.type === 'group') {
tabUnread[0] += c.unread || 0;
}
});
this.setData({ filteredConversations: filtered, tabUnread });
@@ -665,7 +674,7 @@ Page(createPage({
const rpxRatio = 750 / windowWidth;
const headerHeight = 150 / rpxRatio;
const tabBarHeight = 130 / rpxRatio;
const kefuBarHeight = this.data.activeTab === 2 ? (112 / rpxRatio) : 0;
const kefuBarHeight = this.data.activeTab === 1 ? (112 / rpxRatio) : 0;
const safeAreaBottom = systemInfo.safeArea ? (windowHeight - systemInfo.safeArea.bottom) : 0;
this.setData({ scrollHeight: windowHeight - headerHeight - tabBarHeight - kefuBarHeight - safeAreaBottom });
},
+6 -10
View File
@@ -15,24 +15,20 @@
<text class="im-status-text">{{imStatusText}},点击重连</text>
</view>
<!-- 标签栏 -->
<!-- 标签栏:订单+用户消息合并;客服单独 -->
<view class="tab-row">
<view class="tab-item {{activeTab === 0 ? 'active' : ''}}" data-index="0" bindtap="switchTab">
<text class="tab-label">订单消息</text>
<text class="tab-label">消息</text>
<text class="tab-badge" wx:if="{{tabUnread && tabUnread[0] > 0}}">{{tabUnread[0]}}</text>
</view>
<view class="tab-item {{activeTab === 1 ? 'active' : ''}}" data-index="1" bindtap="switchTab">
<text class="tab-label">用户消息</text>
<text class="tab-badge" wx:if="{{tabUnread && tabUnread[1] > 0}}">{{tabUnread[1]}}</text>
</view>
<view class="tab-item {{activeTab === 2 ? 'active' : ''}}" data-index="2" bindtap="switchTab">
<text class="tab-label">客服消息</text>
<text class="tab-badge" wx:if="{{tabUnread && tabUnread[2] > 0}}">{{tabUnread[2]}}</text>
<text class="tab-badge" wx:if="{{tabUnread && tabUnread[1] > 0}}">{{tabUnread[1]}}</text>
</view>
</view>
<view class="kefu-entry" wx:if="{{activeTab === 2}}">
<button class="kefu-btn" bindtap="chatKefu">💬 联系客服</button>
<view class="kefu-entry" wx:if="{{activeTab === 1}}">
<view class="kefu-btn" bindtap="chatKefu">联系客服</view>
</view>
<!-- 会话列表 (上拉加载更多) -->
@@ -71,7 +67,7 @@
</block>
<view class="load-tip" wx:if="{{filteredConversations.length > displayCount}}">上拉加载更多</view>
<view class="empty" wx:if="{{filteredConversations.length === 0 && activeTab !== 2}}">
<view class="empty" wx:if="{{filteredConversations.length === 0 && activeTab !== 1}}">
<text>暂无相关消息</text>
</view>
</scroll-view>
+17 -8
View File
@@ -337,21 +337,30 @@
/* 客服入口 */
.kefu-entry {
padding: 16rpx 24rpx 8rpx;
background: #fff;
padding: 16rpx 24rpx 12rpx;
background: #f5f6f8;
}
.kefu-btn {
width: 100%;
height: 88rpx;
line-height: 88rpx;
background: linear-gradient(135deg, #07c160 0%, #06ad56 100%);
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
background: #1a1a1a;
color: #fff;
border-radius: 44rpx;
font-size: 32rpx;
font-weight: 700;
box-shadow: 0 8rpx 24rpx rgba(7, 193, 96, 0.35);
border-radius: 12rpx;
font-size: 30rpx;
font-weight: 600;
letter-spacing: 2rpx;
line-height: 1;
border: none;
box-shadow: none;
}
.kefu-btn:active {
opacity: 0.88;
}
.kefu-btn::after {
+2 -2
View File
@@ -119,9 +119,9 @@ Component({
refresh() {
const token = wx.getStorageSync('token');
let role = getTabRole(app);
// 纯打手端:无 token 也固定打手 Tab,绝不回落点单端
// 纯打手端:无 token 固定打手 Tab;有商家主端锁定时保持商家 Tab
if (isFighterOnly()) {
role = 'dashou';
if (role !== 'shangjia') role = 'dashou';
} else if (!token) {
role = 'normal';
}
+24 -1
View File
@@ -5,7 +5,7 @@
*/
export const FIGHTER_ONLY = true
/** 无邀请码搜索进入时,自动注册绑定的管事邀请码(前端硬编码) */
/** 无邀请码搜索进入时,自动注册绑定的管事邀请码(前端硬编码,仍正常传给后端) */
export const FIGHTER_ONLY_DEFAULT_INVITE = '0000008VfJKPu4Spmcjt'
/** 已认证打手冷启动默认页 */
@@ -14,6 +14,9 @@ export const FIGHTER_HOME = '/pages/accept-order/accept-order'
/** 未登录 / 未认证 / 清缓存后的落地页(注册 + 我的) */
export const FIGHTER_MINE = '/pages/fighter/fighter'
/** 清除缓存后禁止自动登录/自动注册(用户手动点登录后再清) */
export const SKIP_AUTO_AUTH_KEY = 'fighter_skip_auto_auth'
export function isFighterOnly() {
return FIGHTER_ONLY === true
}
@@ -22,6 +25,26 @@ export function isDashouCertified() {
return Number(wx.getStorageSync('dashoustatus')) === 1
}
export function markSkipAutoAuth() {
try {
wx.setStorageSync(SKIP_AUTO_AUTH_KEY, '1')
} catch (e) {}
}
export function clearSkipAutoAuth() {
try {
wx.removeStorageSync(SKIP_AUTO_AUTH_KEY)
} catch (e) {}
}
export function shouldSkipAutoAuth() {
try {
return wx.getStorageSync(SKIP_AUTO_AUTH_KEY) === '1'
} catch (e) {
return false
}
}
/** 冷启动应去的页面 */
export function resolveFighterOnlyLaunchUrl() {
const token = wx.getStorageSync('token')
+10 -2
View File
@@ -35,8 +35,15 @@ export function isRoleStatusActive(status) {
/** 读取主端(兼容旧 currentRole / 管事组长落地页) */
export function getPrimaryRole(app) {
app = app || getApp();
// 纯打手端:始终锁定 dashou,不进入点单/商家主端
if (isFighterOnly()) {
const stored = wx.getStorageSync('primaryRole');
// 已开通商家且主动进入商家端时,允许临时切商家(扫码/商家功能不受影响)
if (stored === 'shangjia' && isRoleStatusActive(wx.getStorageSync('shangjiastatus'))) {
return 'shangjia';
}
if (isStaffMode() && stored === 'shangjia') {
return 'shangjia';
}
return 'dashou';
}
const stored = wx.getStorageSync('primaryRole');
@@ -95,7 +102,8 @@ export function clearPrimaryRole(app) {
export const PRIMARY_DEFAULT_PAGES = {
normal: isFighterOnly() ? FIGHTER_MINE : '/pages/mine/mine',
dashou: FIGHTER_HOME,
shangjia: isFighterOnly() ? FIGHTER_HOME : '/pages/merchant-home/merchant-home',
// 商家端首页保持不变,纯打手端也允许已开通商家进入
shangjia: '/pages/merchant-home/merchant-home',
};
/** 锁定主端并跳转到该端默认首页,同时建立 IM 长连接 */
+6
View File
@@ -172,6 +172,12 @@ export function resetGuestSession(page, options = {}) {
wx.setStorageSync(configKey, configCache);
}
// 纯打手端:清缓存后禁止自动登录,需用户手动点登录
try {
const { isFighterOnly, markSkipAutoAuth } = require('./fighter-only.js');
if (isFighterOnly()) markSkipAutoAuth();
} catch (e) {}
clearPrimaryRole(app);
app.globalData.token = '';
app.globalData.nicheng = '';