137 lines
4.8 KiB
TypeScript
137 lines
4.8 KiB
TypeScript
import type { LoginResult } from '@/types/api';
|
|
|
|
export const tokenKey = 'aihr_mobile_access_token';
|
|
export const clientIdKey = 'aihr_mobile_client_id';
|
|
export const phoneKey = 'aihr_mobile_phone';
|
|
export const loginRedirectKey = 'aihr_mobile_login_redirect';
|
|
export const positionKey = 'aihr_mobile_position';
|
|
export const roleKey = 'aihr_mobile_role';
|
|
export const phonePattern = /^1[3-9]\d{9}$/;
|
|
|
|
export const userPositionOptions = ['生活顾问', '保安', '保洁', '保修', '客服'] as const;
|
|
|
|
export type UserPosition = typeof userPositionOptions[number];
|
|
|
|
export interface UserPositionProfile {
|
|
value: UserPosition;
|
|
heroTitle: string;
|
|
quickQuestions: string[];
|
|
tip: string;
|
|
}
|
|
|
|
export interface AuthState {
|
|
token: string;
|
|
clientId: string;
|
|
phone: string;
|
|
position: UserPosition | '';
|
|
}
|
|
|
|
const positionProfiles: Record<UserPosition, UserPositionProfile> = {
|
|
生活顾问: {
|
|
value: '生活顾问',
|
|
heroTitle: '客服管家',
|
|
quickQuestions: ['催费话术', '投诉应对', '收费标准'],
|
|
tip: '接待客户三步法:听清诉求 → 共情理解 → 解决闭环'
|
|
},
|
|
保安: {
|
|
value: '保安',
|
|
heroTitle: '秩序岗',
|
|
quickQuestions: ['门岗核验', '巡逻异常', '车辆指引'],
|
|
tip: '今日小贴士:异常先确认人车物,再登记,再同步主管。'
|
|
},
|
|
保洁: {
|
|
value: '保洁',
|
|
heroTitle: '环境岗',
|
|
quickQuestions: ['公区清洁', '垃圾分类', '消杀标准'],
|
|
tip: '今日小贴士:高频区域先看地面、扶手、电梯按钮。'
|
|
},
|
|
保修: {
|
|
value: '保修',
|
|
heroTitle: '工程维修',
|
|
quickQuestions: ['报修接单', '上门话术', '安全检查'],
|
|
tip: '今日小贴士:上门前确认故障、工具、预约时间。'
|
|
},
|
|
客服: {
|
|
value: '客服',
|
|
heroTitle: '服务前台',
|
|
quickQuestions: ['来访接待', '投诉登记', '工单跟进'],
|
|
tip: '今日小贴士:复杂诉求先复述确认,再记录责任人与时限。'
|
|
}
|
|
};
|
|
|
|
const cleanText = (value: unknown) => String(value || '').trim();
|
|
|
|
export const normalizePosition = (value: unknown): UserPosition | '' => {
|
|
const text = cleanText(value);
|
|
if (!text) return '';
|
|
if (text.includes('生活顾问') || text.includes('客服管家') || text.includes('物业管家') || text.includes('管家')) {
|
|
return '生活顾问';
|
|
}
|
|
if (text.includes('保安') || text.includes('秩序') || text.includes('安保')) return '保安';
|
|
if (text.includes('保洁') || text.includes('环境')) return '保洁';
|
|
if (text.includes('保修') || text.includes('维修') || text.includes('工程')) return '保修';
|
|
if (text.includes('客服') || text.includes('前台')) return '客服';
|
|
return (userPositionOptions as readonly string[]).includes(text) ? (text as UserPosition) : '';
|
|
};
|
|
|
|
export const hasSelectedPosition = () => Boolean(normalizePosition(uni.getStorageSync(positionKey)));
|
|
|
|
export const getSelectedPosition = (): UserPosition =>
|
|
normalizePosition(uni.getStorageSync(positionKey)) || '生活顾问';
|
|
|
|
export const getPositionProfile = (position: unknown) =>
|
|
positionProfiles[normalizePosition(position) || '生活顾问'];
|
|
|
|
export const getSelectedPositionProfile = () => getPositionProfile(getSelectedPosition());
|
|
|
|
export const saveSelectedPosition = (position: unknown) => {
|
|
const normalized = normalizePosition(position);
|
|
if (!normalized) return '';
|
|
uni.setStorageSync(positionKey, normalized);
|
|
return normalized;
|
|
};
|
|
|
|
export const getAuth = (): AuthState => ({
|
|
token: uni.getStorageSync(tokenKey) || '',
|
|
clientId: uni.getStorageSync(clientIdKey) || '',
|
|
phone: uni.getStorageSync(phoneKey) || '',
|
|
position: normalizePosition(uni.getStorageSync(positionKey))
|
|
});
|
|
|
|
export const isLoggedIn = () => {
|
|
const auth = getAuth();
|
|
return Boolean(auth.token && auth.clientId && auth.phone);
|
|
};
|
|
|
|
export const saveAuth = (result: LoginResult, phone: string) => {
|
|
const previousPhone = uni.getStorageSync(phoneKey) || '';
|
|
if (previousPhone && previousPhone !== phone) {
|
|
uni.removeStorageSync(positionKey);
|
|
uni.removeStorageSync(roleKey);
|
|
}
|
|
uni.setStorageSync(tokenKey, result.access_token);
|
|
uni.setStorageSync(clientIdKey, result.client_id);
|
|
uni.setStorageSync(phoneKey, phone);
|
|
};
|
|
|
|
export const clearAuth = () => {
|
|
uni.removeStorageSync(tokenKey);
|
|
uni.removeStorageSync(clientIdKey);
|
|
uni.removeStorageSync(phoneKey);
|
|
uni.removeStorageSync(positionKey);
|
|
uni.removeStorageSync(roleKey);
|
|
uni.removeStorageSync(loginRedirectKey);
|
|
};
|
|
|
|
export const rememberLoginRedirect = (url: string) => {
|
|
uni.setStorageSync(loginRedirectKey, url);
|
|
};
|
|
|
|
export const consumeLoginRedirect = () => {
|
|
const url = uni.getStorageSync(loginRedirectKey) || '';
|
|
uni.removeStorageSync(loginRedirectKey);
|
|
return url;
|
|
};
|
|
|
|
export const validatePhone = (phone: string) => phonePattern.test(phone);
|