Merge remote-tracking branch 'origin/develop' into develop_mzh

This commit is contained in:
米子豪 2025-01-03 15:49:45 +08:00
commit e2653a3674
25 changed files with 643 additions and 150 deletions

11
env/.env vendored
View File

@ -7,9 +7,14 @@ VITE_WX_APPID='wxa2abb91f64032a2b'
# h5部署网站的base配置到 manifest.config.ts 里的 h5.router.base
VITE_APP_PUBLIC_BASE=/
VITE_SERVER_BASEURL='https://ukw0y1.laf.run'
VITE_UPLOAD_BASEURL='https://ukw0y1.laf.run/upload'
# h5是否需要配置代理
VITE_APP_PROXY=false
VITE_APP_PROXY_PREFIX='/api'
VITE_SERVER_BASEURL='https://dev.work.star-lock.cn/api'
VITE_APP_ENV='XHJ_DEV'
VITE_APP_VERSION='1.0.0'
VITE_APP_BUILD_NUMBER=1

View File

@ -4,3 +4,9 @@ NODE_ENV='development'
VITE_DELETE_CONSOLE=false
# 是否开启sourcemap
VITE_SHOW_SOURCEMAP=true
VITE_SERVER_BASEURL='https://dev.work.star-lock.cn'
VITE_APP_TITLE='斯凯签勤_DEV'
VITE_APP_ENV='SKY_DEV'

View File

@ -2,3 +2,9 @@
NODE_ENV='development'
# 是否去除console 和 debugger
VITE_DELETE_CONSOLE=false
VITE_SERVER_BASEURL='https://pre.work.star-lock.cn'
VITE_APP_TITLE='斯凯签勤_PRE'
VITE_APP_ENV='SKY_PRE'

12
env/.env.sky_release vendored Normal file
View File

@ -0,0 +1,12 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV='development'
# 是否去除console 和 debugger
VITE_DELETE_CONSOLE=true
# 是否开启sourcemap
VITE_SHOW_SOURCEMAP=false
VITE_SERVER_BASEURL='https://pre.work.star-lock.cn'
VITE_APP_TITLE='斯凯签勤'
VITE_APP_ENV='SKY'

12
env/.env.xhj_dev vendored Normal file
View File

@ -0,0 +1,12 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV='development'
# 是否去除console 和 debugger
VITE_DELETE_CONSOLE=false
# 是否开启sourcemap
VITE_SHOW_SOURCEMAP=true
VITE_SERVER_BASEURL='https://dev.work.star-lock.cn'
VITE_APP_TITLE='星星勤务_DEV'
VITE_APP_ENV='XHJ_DEV'

10
env/.env.xhj_pre vendored Normal file
View File

@ -0,0 +1,10 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV='development'
# 是否去除console 和 debugger
VITE_DELETE_CONSOLE=false
VITE_SERVER_BASEURL='https://pre.work.star-lock.cn'
VITE_APP_TITLE='星星勤务_PRE'
VITE_APP_ENV='XHJ_PRE'

View File

@ -4,3 +4,10 @@ NODE_ENV='development'
VITE_DELETE_CONSOLE=true
# 是否开启sourcemap
VITE_SHOW_SOURCEMAP=false
VITE_SERVER_BASEURL='https://work.star-lock.cn'
VITE_APP_TITLE='星星勤务'
VITE_APP_ENV='XHJ'

View File

@ -7,6 +7,12 @@
"pnpm": ">=7.30"
},
"scripts": {
"build:app-android-xhj_dev": "uni build -p app-android --mode xhj_dev",
"build:app-android-sky_dev": "uni build -p app-android --mode sky_dev",
"build:app-android-xhj_pre": "uni build -p app-android --mode xhj_pre",
"build:app-android-sky_pre": "uni build -p app-android --mode sky_pre",
"build:app-android-xhj_release": "uni build -p app-android --mode xhj_release",
"build:app-android-sky_release": "uni build -p app-android --mode sky_release",
"preinstall": "npx only-allow pnpm",
"uvm": "npx @dcloudio/uvm@latest",
"uvm-rm": "node ./scripts/postupgrade.js",

View File

@ -1,3 +0,0 @@
export const phoneRegExp = /^1[3-9]\d{9}$/
export const passwordRegExp = /^(?![0-9]+$)(?![a-zA-Z]+$)(?![^0-9a-zA-Z]+$).{8,20}$/

View File

@ -0,0 +1,5 @@
export const phoneRegExp: RegExp = /^1[3-9]\d{9}$/
export const passwordRegExp: RegExp = /^(?![0-9]+$)(?![a-zA-Z]+$)(?![^0-9a-zA-Z]+$).{8,20}$/
export const codeRegExp: RegExp = /^[0-9]{6}$/

48
src/constants/result.ts Normal file
View File

@ -0,0 +1,48 @@
export class Result {
static codes = {
Success: 0,
Fail: -1,
NotMore: -2,
PaySuccessful: 10003
}
static resultsMap = new Map([
[Result.codes.Success, { message: '成功', data: {} }],
[Result.codes.Fail, { message: '网络加载失败', data: {} }],
[Result.codes.NotMore, { message: '没有更多', data: {} }],
[Result.codes.PaySuccessful, { message: '支付成功', data: {} }]
])
constructor(code, data, message) {
const result = Result.resultsMap.get(code)
if (result) {
this.code = code
this.message = message || result.message
this.data = data || result.data
} else {
this.code = code
this.message = message || ''
this.data = data || {}
}
}
// 成功
static get Success() {
return new Result(Result.codes.Success)
}
// 失败(默认错误)
static get Fail() {
return new Result(Result.codes.Fail)
}
// 没有更多
static get NotMore() {
return new Result(Result.codes.NotMore)
}
// 支付成功
static get PaySuccessful() {
return new Result(Result.codes.PaySuccessful)
}
}

View File

@ -17,7 +17,6 @@ const baseUrl = getEnvBaseUrl()
const httpInterceptor = {
// 拦截前触发
invoke(options: CustomRequestOptions) {
// 接口请求支持通过 query 参数配置 queryString
if (options.query) {
const queryStr = qs.stringify(options.query)
if (options.url.includes('?')) {
@ -26,7 +25,6 @@ const httpInterceptor = {
options.url += `?${queryStr}`
}
}
// 非 http 开头需拼接地址
if (!options.url.startsWith('http')) {
// #ifdef H5
// console.log(__VITE_APP_PROXY__)
@ -42,16 +40,13 @@ const httpInterceptor = {
// #endif
// TIPS: 如果需要对接多个后端服务,也可以在这里处理,拼接成所需要的地址
}
// 1. 请求超时
options.timeout = 10000 // 10s
// 2. (可选)添加小程序端请求头标识
options.timeout = 3000
options.header = {
platform, // 可选,与 uniapp 定义的平台一致,告诉后台来源
platform,
version: import.meta.env.VITE_APP_VERSION + '+' + import.meta.env.VITE_APP_BUILD_NUMBER,
...options.header
}
// 3. 添加 token 请求头标识
const userStore = useUserStore()
const { token } = userStore.userInfo as unknown as IUserInfo
const token = uni.getStorageSync('token')
if (token) {
options.header.Authorization = `Bearer ${token}`
}

View File

@ -38,6 +38,14 @@
</template>
<script setup lang="ts">
import { codeLoginApi, CodeLoginRequest } from '@/service/user'
import { PlatId } from '@/typings'
import { Result } from '@/constants/result'
import { useBasicStore, useUserStore } from '@/store'
const $basic = useBasicStore()
const $user = useUserStore()
const phone = ref<string>('')
const code = ref<string>('')
@ -48,6 +56,12 @@
const type = ref<string>('')
const systemInfo = ref<GetSystemInfoResult>(null)
onMounted(async () => {
systemInfo.value = await $basic.getSystemInfo()
})
onLoad(async options => {
phone.value = options.phone
type.value = options.type
@ -55,14 +69,53 @@
countDownStart()
})
watch(code, newVal => {
watch(code, async newVal => {
if (newVal.length === 6) {
//
if (type.value === 'login') {
console.log('login')
await uni.showLoading({
title: '登录中',
mask: true
})
try {
const result = await codeLoginApi<CodeLoginRequest>({
platId: PlatId.app,
phone: phone.value,
verificationCode: code.value,
deviceInfo: {
deviceNo: systemInfo.value?.deviceId,
deviceName: `${systemInfo.value?.deviceBrand} ${systemInfo.value?.deviceModel}`,
deviceBrand: systemInfo.value?.deviceBrand,
deviceModel: systemInfo.value?.deviceModel
}
})
uni.hideLoading()
if (result.errorCode === Result.Success.code) {
uni.setStorageSync('token', result.data.token)
$user.getUserInfo()
await uni.switchTab({
url: '/pages/home/home'
})
await uni.showToast({
title: '登录成功',
icon: 'none'
})
} else {
await uni.showToast({
title: result.errorMsg,
icon: 'none'
})
}
} catch (err) {
console.log(err)
uni.hideLoading()
await uni.showToast({
title: '登录失败,请稍后再试',
icon: 'none'
})
}
} else if (type.value === 'reset-password') {
uni.navigateTo({
url: `/pages/reset-password/reset-password`
await uni.redirectTo({
url: `/pages/reset-password/reset-password?phone=${phone.value}&code=${code.value}`
})
}
}

View File

@ -32,6 +32,9 @@
<script setup lang="ts">
import { phoneRegExp } from '@/constants/regular-expressions'
import { AccountChannel, CodeType, IResData } from '@/typings'
import { getCodeApi, UserGetCodeRequest } from '@/service/user'
import { Result } from '@/constants/result'
const phone = ref<string>('')
const phonePass = computed(() => phoneRegExp.test(phone.value))
@ -42,18 +45,42 @@
}
})
const codeLogin = () => {
const codeLogin = async () => {
if (!phonePass.value) {
return
}
uni.navigateTo({
url: `/pages/code/code?phone=${phone.value}&type=reset-password`
await uni.showLoading({
title: '加载中',
mask: true
})
try {
const result: IResData = await getCodeApi<UserGetCodeRequest>({
account: phone.value,
channel: AccountChannel.phone,
codeType: CodeType.reset
})
uni.hideLoading()
if (result.errorCode === Result.Success.code) {
await uni.navigateTo({
url: `/pages/reset-password/reset-password?phone=${phone.value}`
})
} else {
await uni.showToast({
title: result.errorMsg,
icon: 'none'
})
}
} catch (err) {
console.log(err)
uni.hideLoading()
await uni.showToast({
title: '获取验证码失败,请稍后再试',
icon: 'none'
})
}
}
const phoneChange = (value: string) => {
phone.value = value
}
</script>
<style scoped lang="scss"></style>

View File

@ -39,7 +39,7 @@
const tab = ref<number>(0)
const props = defineProps({
defineProps({
list: {
type: Array<HomeTab>,
required: true

View File

@ -8,24 +8,24 @@
</route>
<template>
<view class="custom-bg-default">
<TopNavigation :title="appName"></TopNavigation>
<button class="mt-12" @click="toLogin">去登录</button>
<CustomTab class="mt-10" :list="featuresList" @clickItem="clickItem"></CustomTab>
<view class="pt-10">
<CustomTabBar :list="list" :default-index="1" @change="change"></CustomTabBar>
<view v-if="$user.loginStatus">
<CustomTab class="mt-10" :list="featuresList" @clickItem="clickItem"></CustomTab>
<button class="mt-12" @click="$user.logout">退出登录</button>
</view>
<view v-else>
<button class="mt-12" @click="toLogin">去登录</button>
</view>
<view @click="handleClick">考勤</view>
</view>
</template>
<script lang="ts" setup>
import { useUserStore } from '@/store'
import CustomTab from '@/pages/home/CustomTab.vue'
import { useUserStore } from '@/store'
import { Result } from '@/constants/result'
const $user = useUserStore()
const appName = import.meta.env.VITE_APP_TITLE
const list = ref<Array<TabBarItem>>([
{
title: '首页',
@ -222,19 +222,20 @@
}
])
// uni API
onLoad(() => {
$user.setUserInfo({ nickname: '1', avatar: '1', token: '1' })
console.log($user.userInfo.nickname)
})
const change = data => {
console.log(data.value)
if (data.value === 3) {
list.value[data.value].value = 0
onMounted(async () => {
const tokenStorage: string = uni.getStorageSync('token')
if (tokenStorage) {
const result: boolean = await $user.getUserInfo()
if (result.code === Result.Success.code) {
console.log('获取用户信息成功')
} else {
await uni.showToast({
title: result.message,
icon: 'none'
})
}
}
}
})
const toLogin = () => {
uni.navigateTo({

View File

@ -146,12 +146,20 @@
</text>
</Modal>
</template>
<script lang="ts" setup>
import { useBasicStore } from '@/store'
import { useBasicStore, useUserStore } from '@/store'
import { passwordRegExp, phoneRegExp } from '@/constants/regular-expressions'
import {
getCodeApi,
passwordLoginApi,
PasswordLoginRequest,
UserGetCodeRequest
} from '@/service/user'
import { AccountChannel, CodeType, IResData, PlatId } from '@/typings'
import { Result } from '@/constants/result'
const $basic = useBasicStore()
const $user = useUserStore()
const appName = import.meta.env.VITE_APP_TITLE
@ -176,7 +184,7 @@
systemInfo.value = await $basic.getSystemInfo()
})
const passwordLogin = () => {
const passwordLogin = async () => {
if (!phonePass.value || !passwordPass.value) {
return
}
@ -185,10 +193,50 @@
agreementModal.value.showModal()
return
}
console.log('登录')
await uni.showLoading({
title: '登录中',
mask: true
})
try {
const result = await passwordLoginApi<PasswordLoginRequest>({
platId: PlatId.app,
username: phone.value,
password: password.value,
deviceInfo: {
deviceNo: systemInfo.value?.deviceId,
deviceName: `${systemInfo.value?.deviceBrand} ${systemInfo.value?.deviceModel}`,
deviceBrand: systemInfo.value?.deviceBrand,
deviceModel: systemInfo.value?.deviceModel
}
})
uni.hideLoading()
if (result.errorCode === Result.Success.code) {
uni.setStorageSync('token', result.data.token)
$user.getUserInfo()
await uni.switchTab({
url: '/pages/home/home'
})
await uni.showToast({
title: '登录成功',
icon: 'none'
})
} else {
await uni.showToast({
title: result.errorMsg,
icon: 'none'
})
}
} catch (err) {
console.log(err)
uni.hideLoading()
await uni.showToast({
title: '获取验证码失败,请稍后再试',
icon: 'none'
})
}
}
const codeLogin = () => {
const codeLogin = async () => {
if (!phonePass.value) {
return
}
@ -197,9 +245,35 @@
agreementModal.value.showModal()
return
}
uni.navigateTo({
url: `/pages/code/code?phone=${phone.value}&type=login`
await uni.showLoading({
title: '加载中',
mask: true
})
try {
const result: IResData = await getCodeApi<UserGetCodeRequest>({
account: phone.value,
channel: AccountChannel.phone,
codeType: CodeType.login
})
uni.hideLoading()
if (result.errorCode === Result.Success.code) {
await uni.navigateTo({
url: `/pages/code/code?phone=${phone.value}&type=login`
})
} else {
await uni.showToast({
title: result.errorMsg,
icon: 'none'
})
}
} catch (err) {
console.log(err)
uni.hideLoading()
await uni.showToast({
title: '获取验证码失败,请稍后再试',
icon: 'none'
})
}
}
const resetPassword = () => {

View File

@ -9,8 +9,29 @@
<template>
<view>
<TopNavigation></TopNavigation>
<view class="text-6 ml-4 pt-7 custom-color-black font-bold">请输入手机号</view>
<view class="text-6 ml-4 pt-7 custom-color-black font-bold">设置新密码</view>
<view class="text-3.5 ml-4 mt-2 mb-2 custom-color-grey">
<view>已发送验证码至{{ maskedPhone }}</view>
</view>
<view class="p-5">
<wd-input
v-model="code"
:maxlength="6"
class="mt-6"
type="number"
placeholder="请输入验证码"
placeholderClass="text-4 custom-color-grey"
size="large"
@change="codeChange"
use-suffix-slot
>
<template #suffix>
<view v-if="countDown > 0" class="text-4 custom-color-grey">
{{ countDown }}s后重新获取
</view>
<view v-else class="text-4 custom-color-blue" @click="getCode">重新获取</view>
</template>
</wd-input>
<wd-input
v-model="password"
:maxlength="20"
@ -45,7 +66,7 @@
:disabled="!(passwordPass && confirmPasswordPass && password === confirmPassword)"
:round="false"
size="large"
@click="codeLogin"
@click="resetPassword"
>
提交
</wd-button>
@ -54,14 +75,143 @@
</template>
<script setup lang="ts">
import { passwordRegExp } from '@/constants/regular-expressions'
import { codeRegExp, passwordRegExp } from '@/constants/regular-expressions'
import { getCodeApi, resetPasswordApi, UserGetCodeRequest } from '@/service/user'
import { Result } from '@/constants/result'
import { AccountChannel, CodeType, IResData } from '@/typings'
const phone = ref<string>('')
const code = ref<string>('')
const password = ref<string>('')
const confirmPassword = ref<string>('')
const countDown = ref<number>(60)
const maskedPhone = computed(() => {
if (phone.value.length === 11) {
return phone.value.slice(0, 3) + '****' + phone.value.slice(7)
}
return phone.value
})
const codePass = computed(() => codeRegExp.test(code.value))
const passwordPass = computed(() => passwordRegExp.test(password.value))
const confirmPasswordPass = computed(() => password.value === confirmPassword.value)
onLoad(options => {
phone.value = options.phone
startCounting()
})
const getCode = async () => {
await uni.showLoading({
title: '加载中',
mask: true
})
try {
const result: IResData = await getCodeApi<UserGetCodeRequest>({
account: phone.value,
channel: AccountChannel.phone,
codeType: CodeType.reset
})
uni.hideLoading()
if (result.errorCode === Result.Success.code) {
await uni.showToast({
title: '验证码已发送',
icon: 'none'
})
} else {
await uni.showToast({
title: result.errorMsg,
icon: 'none'
})
}
} catch (err) {
console.log(err)
uni.hideLoading()
await uni.showToast({
title: '获取验证码失败,请稍后再试',
icon: 'none'
})
}
}
const startCounting = () => {
const timestamp: number = new Date().getTime()
countDown.value = 60
const countDownTimer = setInterval(() => {
if (countDown.value > 0) {
countDown.value = 60 - Math.floor((new Date().getTime() - timestamp) / 1000)
} else {
clearInterval(countDownTimer)
}
}, 1000)
}
const resetPassword = async () => {
if (code.value === '') {
await uni.showToast({
title: '验证码不能为空',
icon: 'none'
})
return
} else if (!codePass.value) {
await uni.showToast({
title: '验证码格式不正确',
icon: 'none'
})
return
} else if (password.value === '' || confirmPassword.value === '') {
await uni.showToast({
title: '密码不能为空',
icon: 'none'
})
return
} else if (!passwordPass.value || !confirmPasswordPass.value) {
await uni.showToast({
title: '密码格式不正确',
icon: 'none'
})
return
} else if (password.value !== confirmPassword.value) {
await uni.showToast({
title: '两次密码不一致',
icon: 'none'
})
return
}
await uni.showLoading({
title: '修改中'
})
try {
const resetPasswordApiResult = await resetPasswordApi({
newPassword: password.value,
account: phone.value,
verificationCode: code.value
})
uni.hideLoading()
if (resetPasswordApiResult.errorCode === Result.Success.code) {
await uni.navigateBack({ delta: 2 })
await uni.showToast({
title: '密码重置成功',
icon: 'none'
})
} else {
await uni.showToast({
title: resetPasswordApiResult.errorMsg,
icon: 'none'
})
}
} catch (err) {
console.log(err)
uni.hideLoading()
await uni.showToast({
title: '密码重置失败,请稍后再试',
icon: 'none'
})
}
}
const passwordChange = (value: string) => {
password.value = value
}
@ -69,6 +219,10 @@
const confirmPasswordChange = (value: string) => {
confirmPassword.value = value
}
const codeChange = (value: string) => {
code.value = value
}
</script>
<style scoped lang="scss"></style>

View File

@ -1,15 +0,0 @@
import { http } from '@/utils/http'
export interface IFooItem {
id: string
name: string
}
/** GET 请求 */
export const getFooAPI = (name: string) => {
return http.get<IFooItem>('/foo', { name })
}
/** POST 请求 */
export const postFooAPI = (name: string) => {
return http.post<IFooItem>('/foo', { name }, { name })
}

79
src/service/user.ts Normal file
View File

@ -0,0 +1,79 @@
import { http } from '@/utils/http'
export interface UserGetCodeRequest {
account: string
channel: string
codeType: string
countryCode?: string
}
// 获取验证码
export const getCodeApi = (params: UserGetCodeRequest) => {
return http.post('/v1/common/sendValidationCode', params)
}
export interface PasswordLoginRequest {
platId: number
username: string
password: string
deviceInfo?: DeviceInfo
}
interface DeviceInfo {
deviceNo?: string
deviceName?: string
deviceBrand?: string
deviceModel?: string
}
// 密码登录
export const passwordLoginApi = (params: PasswordLoginRequest) => {
return http.post('/v1/user/pwdLogin', params)
}
export interface CodeLoginRequest {
platId: number
phone: string
verificationCode: string
deviceInfo?: DeviceInfo
}
// 验证码登录
export const codeLoginApi = (params: CodeLoginRequest) => {
return http.post('/v1/user/codeLogin', params)
}
export interface UserInfo {
id?: number
accountNo?: string
phone?: string
nickname?: string
headUrl?: string
createdAt?: string
lastLoginTime?: string
currentTeamNo?: string
teamList?: Array<TeamInfo>
}
interface TeamInfo {
teamNo?: string
teamName?: string
teamCode?: string
}
// 获取用户信息
export const getUserInfoApi = (params: UserInfo) => {
return http.post('/v1/user/detail', params)
}
export interface resetPasswordRequest {
countryCode?: string
account: string
verificationCode: number
newPassword: string
}
// 重置密码
export const resetPasswordApi = (params: resetPasswordRequest) => {
return http.post('/v1/user/resetPassword', params)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 B

View File

@ -1,32 +1,50 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
const initState = { nickname: '', avatar: '' }
import { getUserInfoApi, UserInfo } from '@/service/user'
import { Result } from '@/constants/result'
export const useUserStore = defineStore(
'user',
() => {
const userInfo = ref<IUserInfo>({ ...initState })
const userInfo = ref<UserInfo>(null)
const loginStatus = ref<boolean>(false)
const setUserInfo = (val: IUserInfo) => {
userInfo.value = val
const getUserInfo = async () => {
try {
const result = await getUserInfoApi()
if (result.errorCode === Result.Success.code) {
userInfo.value = result.data
loginStatus.value = true
uni.setStorageSync('userInfo', userInfo.value)
return new Result(result.errorCode, userInfo.value, result.errorMsg)
}
loginStatus.value = false
return Result.Fail
} catch (error) {
const userInfoStorage = uni.getStorageSync('userInfo')
if (userInfoStorage) {
userInfo.value = userInfoStorage
loginStatus.value = true
return new Result(Result.Success.code, userInfo.value, Result.Success.message)
} else {
loginStatus.value = false
return Result.Fail
}
}
}
const clearUserInfo = () => {
userInfo.value = { ...initState }
const logout = () => {
userInfo.value = null
loginStatus.value = false
uni.removeStorageSync('userInfo')
uni.removeStorageSync('token')
}
// 一般没有reset需求不需要的可以删除
const reset = () => {
userInfo.value = { ...initState }
}
const isLogined = computed(() => !!userInfo.value.token)
return {
userInfo,
setUserInfo,
clearUserInfo,
isLogined,
reset
loginStatus,
logout,
getUserInfo
}
},
{

View File

@ -1,41 +1,49 @@
// 全局要用的类型放到这里
type IResData<T> = {
export type IResData<T> = {
errorCode: number
errorMsg: string
data: T
}
// uni.uploadFile文件上传参数
type IUniUploadFileOptions = {
file?: File
files?: UniApp.UploadFileOptionFiles[]
filePath?: string
name?: string
formData?: any
}
type IUserInfo = {
nickname?: string
avatar?: string
openid?: string
token?: string
}
type TabBarItem = {
export type TabBarItem = {
icon: string
title: string
isDot?: boolean
value?: number
}
type HomeTabItem = {
export type HomeTabItem = {
icon: string
title: string
id: number
}
type HomeTab = {
export type HomeTab = {
title: string
list: HomeTabItem[]
}
export enum AccountChannel {
phone = '1',
email = '2'
}
export enum CodeType {
login = '1',
reset = '2',
bindPhone = '3',
unbindPhone = '4',
deleteAccount = '5',
bindEmail = '6',
unbindEmail = '7',
deleteLock = '8',
updatePassword = '9'
}
export enum PlatId {
web = 1,
app = 2,
miniProgram = 3,
pc = 4
}

View File

@ -1,8 +1,10 @@
import { CustomRequestOptions } from '@/interceptors/request'
import { useUserStore } from '@/store'
export const http = <T>(options: CustomRequestOptions) => {
// 1. 返回 Promise 对象
return new Promise<IResData<T>>((resolve, reject) => {
const timestamp = new Date().getTime()
uni.request({
...options,
dataType: 'json',
@ -11,18 +13,22 @@ export const http = <T>(options: CustomRequestOptions) => {
// #endif
// 响应成功
success(res) {
// 状态码 2xx参考 axios 的设计
if (res.statusCode >= 200 && res.statusCode < 300) {
if (res.data.errorCode === 403) {
// 401错误 -> 清理用户信息,跳转到登录页
// userStore.clearUserInfo()
// uni.navigateTo({ url: '/pages/login/login' })
const $user = useUserStore()
$user.logout()
uni.switchTab({
url: '/pages/home/home'
})
uni.showToast({
icon: 'none',
title: '登录已过期,请重新登录'
})
reject(res)
} else {
resolve(res.data as IResData<T>)
}
} else {
// 其他错误 -> 根据后端错误信息轻提示
uni.showToast({
icon: 'none',
title: '网络错误,请重试'
@ -32,30 +38,31 @@ export const http = <T>(options: CustomRequestOptions) => {
},
// 响应失败
fail(err) {
console.log('请求失败', err)
uni.showToast({
icon: 'none',
title: '网络错误,请重试'
})
reject(err)
},
complete(res) {
console.log(options.url, {
env: import.meta.env.VITE_APP_ENV,
statusCode: res?.statusCode,
code: res?.data?.errorCode,
baseUrl: import.meta.env.VITE_SERVER_BASEURL,
url: options.url,
req: options.data,
res: res?.data?.data,
header: options.header,
message: res?.data?.errorMsg,
duration: new Date().getTime() - timestamp
})
}
})
})
}
/**
* GET
* @param url
* @param query query参数
* @returns
*/
export const httpGet = <T>(url: string, query?: Record<string, any>) => {
return http<T>({
url,
query,
method: 'GET'
})
}
/**
* POST
* @param url
@ -76,5 +83,4 @@ export const httpPost = <T>(
})
}
http.get = httpGet
http.post = httpPost

View File

@ -124,28 +124,7 @@ export const needLoginPages: string[] = getAllPages('needLogin').map(page => pag
*/
export const getEnvBaseUrl = () => {
// 请求基准地址
let baseUrl = import.meta.env.VITE_SERVER_BASEURL
// 小程序端环境区分
if (isMp) {
const {
miniProgram: { envVersion }
} = uni.getAccountInfoSync()
switch (envVersion) {
case 'develop':
baseUrl = 'https://ukw0y1.laf.run'
break
case 'trial':
baseUrl = 'https://ukw0y1.laf.run'
break
case 'release':
baseUrl = 'https://ukw0y1.laf.run'
break
}
}
return baseUrl
return import.meta.env.VITE_SERVER_BASEURL
}
/**