文件
shanghaipeiwan/pwuniapp/common/role.js

176 行
4.8 KiB
JavaScript

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

/**
* 全局双身份与角色守卫管理模块 (Role Guard Manager)
* 覆盖四大核心角色:
* 1. PLAYER: 普通买家/玩家
* 2. EXPERT: 陪玩大神/接单人
* 3. HOST: 车队房主/局长
* 4. ADMIN: 平台管理员/运营端
*/
export const ROLE_TYPES = {
PLAYER: 'PLAYER', // 发单人端(普通玩家/发起活动/找陪玩)
EXPERT: 'EXPERT', // 接单人端(大神接单/5km雷达定位/核销)
HOST: 'HOST', // 车队房主/局长(发起AA组局/动态调价/解散退款/到场核销)
ADMIN: 'ADMIN', // 平台管理员(资质审核/争议仲裁/大盘监管)
};
export const CERT_STATUS = {
NONE: 0, // 未提交
PENDING: 1, // 待审核
APPROVED: 2, // 审核通过
REJECTED: 3, // 驳回
};
const STORAGE_KEY_ROLE = 'PW_CURRENT_USER_ROLE';
const STORAGE_KEY_CERT = 'PW_EXPERT_CERT_STATUS';
export function getExpertCertStatus() {
try {
const saved = uni.getStorageSync(STORAGE_KEY_CERT);
if (saved !== '' && saved !== null && saved !== undefined) {
return Number(saved);
}
return CERT_STATUS.NONE;
} catch (e) {
return CERT_STATUS.NONE;
}
}
export function setExpertCertStatus(status) {
const target = Number(status);
try {
uni.setStorageSync(STORAGE_KEY_CERT, target);
} catch (e) {
console.error('Failed to persist cert status', e);
}
uni.$emit('cert-status-change', target);
if (target !== CERT_STATUS.APPROVED) {
setCurrentRole(ROLE_TYPES.PLAYER);
}
return target;
}
export function isExpertCertified() {
return getExpertCertStatus() === CERT_STATUS.APPROVED;
}
export function canSwitchToRole(targetRole) {
if (targetRole === ROLE_TYPES.EXPERT) {
if (!isExpertCertified()) {
return {
allowed: false,
reason: '尚未开通或通过大神实名认证,无法切换至接单模式',
};
}
}
return { allowed: true };
}
export function getCurrentRole() {
try {
const saved = uni.getStorageSync(STORAGE_KEY_ROLE);
if (saved === ROLE_TYPES.EXPERT) {
if (isExpertCertified()) {
return ROLE_TYPES.EXPERT;
}
return ROLE_TYPES.PLAYER;
}
return ROLE_TYPES.PLAYER;
} catch (e) {
return ROLE_TYPES.PLAYER;
}
}
export function setCurrentRole(role) {
let target = role === ROLE_TYPES.EXPERT ? ROLE_TYPES.EXPERT : ROLE_TYPES.PLAYER;
if (target === ROLE_TYPES.EXPERT && !isExpertCertified()) {
console.warn('[RoleGuard] 未认证大神禁止切换至接单端,已自动降级回玩家端');
target = ROLE_TYPES.PLAYER;
}
try {
uni.setStorageSync(STORAGE_KEY_ROLE, target);
} catch (e) {
console.error('Failed to persist user role', e);
}
uni.$emit('role-change', target);
return target;
}
export function toggleRole() {
const current = getCurrentRole();
if (current === ROLE_TYPES.PLAYER) {
if (!isExpertCertified()) {
return {
success: false,
currentRole: ROLE_TYPES.PLAYER,
message: '尚未通过大神实名认证,请先提交入驻认证',
};
}
setCurrentRole(ROLE_TYPES.EXPERT);
return {
success: true,
currentRole: ROLE_TYPES.EXPERT,
message: '已切换至大神接单模式',
};
} else {
setCurrentRole(ROLE_TYPES.PLAYER);
return {
success: true,
currentRole: ROLE_TYPES.PLAYER,
message: '已切回发单人端',
};
}
}
// 非大神禁止访问的受保护页面清单
export const EXPERT_GUARD_PAGES = [
'/pages/expert/workspace',
'/pages/expert/radar',
'/pages/expert/hall',
];
export function checkRoleGuard(pageUrl) {
if (!pageUrl) return { allowed: true };
const pureUrl = pageUrl.split('?')[0];
if (EXPERT_GUARD_PAGES.includes(pureUrl)) {
if (!isExpertCertified()) {
return {
allowed: false,
code: 'FORBIDDEN_NOT_EXPERT',
redirectUrl: '/pages/user/index',
message: '非大神禁止访问接单工作台与雷达,请先在个人中心完成实名认证',
};
}
}
return { allowed: true };
}
let guardInstalled = false;
export function installRoleGuard() {
if (guardInstalled) return;
guardInstalled = true;
const routeMethods = ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'];
routeMethods.forEach((method) => {
try {
if (typeof uni !== 'undefined' && typeof uni.addInterceptor === 'function') {
uni.addInterceptor(method, {
invoke(args) {
if (!args || !args.url) return true;
const check = checkRoleGuard(args.url);
if (!check.allowed) {
uni.showToast({
title: check.message || '非大神禁止访问接单页面',
icon: 'none',
duration: 2000,
});
return false;
}
return true;
},
});
}
} catch (e) {}
});
}