refactor: 项目重构,仅保留 login 和 supplementPersonal 页面
删除 11 个旧页面、组件、lefu SDK、旧资源文件。 新增 request 封装(GET/POST/PUT)、api 层、utils/common 身份证工具。 重写 login(登录流程提取到 app.ts) 和 supplementPersonal(简化表单逻辑)。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
439f560218
commit
83d909b95b
@@ -0,0 +1,84 @@
|
||||
/** 身份证解析结果 */
|
||||
export interface IdCardParsed {
|
||||
/** 性别文本(男/女),解析失败返回空字符串 */
|
||||
gender: string
|
||||
/** 年龄文本,解析失败返回空字符串 */
|
||||
age: string
|
||||
/** 生日 YYYY-MM-DD */
|
||||
birthday: string
|
||||
/** 性别 1=男 2=女 */
|
||||
sex: number
|
||||
}
|
||||
|
||||
/** storage 中 userInfo 的类型 */
|
||||
export interface StorageUserInfo {
|
||||
id: string
|
||||
userId: string
|
||||
parentUserId: string | null
|
||||
scaleDeviceId: string
|
||||
deviceId: string | null
|
||||
deviceType: string
|
||||
dataType: number
|
||||
userType: string | null
|
||||
idCard: string
|
||||
height: number
|
||||
weight: number
|
||||
birthday: string
|
||||
sex: number
|
||||
avatar: string | null
|
||||
phone: string | null
|
||||
thirdId: string
|
||||
realname: string
|
||||
bmi: number
|
||||
createBy: string
|
||||
createTime: string
|
||||
updateBy: string | null
|
||||
updateTime: string | null
|
||||
delFlag: number
|
||||
sn: string | null
|
||||
workNo: string | null
|
||||
remark: string | null
|
||||
relationType: string | null
|
||||
sex_dictText: string
|
||||
connectDeviceInfo: string
|
||||
}
|
||||
|
||||
/** 校验身份证号格式是否合法 */
|
||||
export const isIdCardValid = (idCard: string): boolean => {
|
||||
if (idCard.length !== 18) return false
|
||||
// 前 17 位必须为数字
|
||||
if (!/^\d{17}$/.test(idCard.slice(0, 17))) return false
|
||||
// 第 18 位为数字或 X
|
||||
if (!/^[\dXx]$/.test(idCard[17])) return false
|
||||
return true
|
||||
}
|
||||
|
||||
/** 解析身份证号,提取性别、年龄、生日 */
|
||||
export const parseIdCard = (idCard: string): IdCardParsed => {
|
||||
const empty: IdCardParsed = { gender: '', age: '', birthday: '', sex: 0 }
|
||||
if (!isIdCardValid(idCard)) return empty
|
||||
|
||||
// 第 17 位奇数为男,偶数为女
|
||||
const sexCode = parseInt(idCard[16], 10)
|
||||
const sex = sexCode % 2 === 1 ? 1 : 2
|
||||
|
||||
// 第 7-14 位为生日 YYYYMMDD
|
||||
const year = parseInt(idCard.slice(6, 10), 10)
|
||||
const month = parseInt(idCard.slice(10, 12), 10)
|
||||
const day = parseInt(idCard.slice(12, 14), 10)
|
||||
|
||||
// 计算年龄
|
||||
const now = new Date()
|
||||
const birth = new Date(year, month - 1, day)
|
||||
let age = now.getFullYear() - year
|
||||
if (now.getMonth() < month - 1 || (now.getMonth() === month - 1 && now.getDate() < day)) {
|
||||
age--
|
||||
}
|
||||
|
||||
return {
|
||||
gender: sex === 1 ? '男' : '女',
|
||||
age: String(age),
|
||||
birthday: `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`,
|
||||
sex,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// TODO: 替换为实际接口地址
|
||||
const IS_DEV = false
|
||||
|
||||
export const BASE_URL = IS_DEV
|
||||
? ''
|
||||
: ''
|
||||
|
||||
export const TIMEOUT = 30000
|
||||
@@ -1,10 +1,8 @@
|
||||
import type { ApiResponse, HttpMethod, RequestOptions } from './types'
|
||||
import { BASE_URL, TIMEOUT } from './config'
|
||||
|
||||
export type { ApiResponse, RequestOptions }
|
||||
|
||||
// const BASE_URL = 'http://10.10.10.10:8889/' // 测试环境
|
||||
const BASE_URL = 'https://device.shuziweidao.com/gateway/' // 正式环境
|
||||
|
||||
let _loadingCount = 0
|
||||
|
||||
const _showLoading = (title: string): void => {
|
||||
@@ -29,7 +27,7 @@ const request = <T = any>(
|
||||
|
||||
const header: Record<string, string> = { 'content-type': contentType }
|
||||
const token = wx.getStorageSync('token') as string
|
||||
if (token) header['X-Access-Token'] = token
|
||||
if (token) header['abtoken'] = token
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.request({
|
||||
@@ -37,17 +35,14 @@ const request = <T = any>(
|
||||
data,
|
||||
method,
|
||||
header,
|
||||
timeout: TIMEOUT,
|
||||
success: (res) => {
|
||||
if (loading) _hideLoading()
|
||||
const body = res.data as ApiResponse<T>
|
||||
if (body.code === 200) {
|
||||
if (body.code === '00000') {
|
||||
resolve(body)
|
||||
} else if (body.code === 401) {
|
||||
wx.clearStorageSync()
|
||||
wx.reLaunch({ url: '/pages/login/login' })
|
||||
reject(body)
|
||||
} else {
|
||||
wx.showToast({ title: body.message || '请求失败', icon: 'none' })
|
||||
wx.showToast({ title: body.msg || '请求失败', icon: 'none' })
|
||||
reject(body)
|
||||
}
|
||||
},
|
||||
@@ -77,12 +72,3 @@ export const put = <T = any>(
|
||||
data?: Record<string, any>,
|
||||
options?: RequestOptions,
|
||||
): Promise<ApiResponse<T>> => request<T>(url, data, 'PUT', options)
|
||||
|
||||
export const del = <T = any>(
|
||||
url: string,
|
||||
data?: Record<string, any>,
|
||||
options?: RequestOptions,
|
||||
): Promise<ApiResponse<T>> => request<T>(url, data, 'DELETE', {
|
||||
contentType: 'application/x-www-form-urlencoded',
|
||||
...options,
|
||||
})
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
export interface ApiResponse<T = any> {
|
||||
code: number
|
||||
result: T
|
||||
message?: string
|
||||
code: string
|
||||
msg: string
|
||||
data: T
|
||||
}
|
||||
|
||||
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'
|
||||
export type HttpMethod = 'GET' | 'POST' | 'PUT'
|
||||
|
||||
export interface RequestOptions {
|
||||
/** 是否显示 loading,默认 true */
|
||||
loading?: boolean
|
||||
/** loading 文案,默认"加载中..." */
|
||||
loadingTitle?: string
|
||||
/** Content-Type,默认 application/json */
|
||||
contentType?: 'application/json' | 'application/x-www-form-urlencoded'
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
export const formatTime = (date: Date) => {
|
||||
const year = date.getFullYear()
|
||||
const month = date.getMonth() + 1
|
||||
const day = date.getDate()
|
||||
const hour = date.getHours()
|
||||
const minute = date.getMinutes()
|
||||
const second = date.getSeconds()
|
||||
|
||||
return (
|
||||
[year, month, day].map(formatNumber).join('/') +
|
||||
' ' +
|
||||
[hour, minute, second].map(formatNumber).join(':')
|
||||
)
|
||||
}
|
||||
|
||||
const formatNumber = (n: number) => {
|
||||
const s = n.toString()
|
||||
return s[1] ? s : '0' + s
|
||||
}
|
||||
Reference in New Issue
Block a user