mi
This commit is contained in:
9
miniprogram/src/utils/format.test.ts
Normal file
9
miniprogram/src/utils/format.test.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { formatPrice } from './format'
|
||||
|
||||
describe('formatPrice', () => {
|
||||
test('formats correctly', () => {
|
||||
expect(formatPrice(100)).toBe('¥100.00')
|
||||
expect(formatPrice(0)).toBe('¥0.00')
|
||||
expect(formatPrice(99.9)).toBe('¥99.90')
|
||||
})
|
||||
})
|
||||
3
miniprogram/src/utils/format.ts
Normal file
3
miniprogram/src/utils/format.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const formatPrice = (price: number) => {
|
||||
return `¥${Number(price).toFixed(2)}`
|
||||
}
|
||||
76
miniprogram/src/utils/request.ts
Normal file
76
miniprogram/src/utils/request.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import Taro from '@tarojs/taro'
|
||||
|
||||
const BASE_URL = process.env.TARO_APP_API_URL || 'http://localhost:8000/api'
|
||||
|
||||
export const request = async (options: Taro.request.Option) => {
|
||||
const token = Taro.getStorageSync('token')
|
||||
|
||||
const header = {
|
||||
'Content-Type': 'application/json',
|
||||
...options.header
|
||||
}
|
||||
|
||||
if (token) {
|
||||
header['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
|
||||
// Ensure URL is clean
|
||||
let url = options.url
|
||||
if (!url.startsWith('http')) {
|
||||
url = BASE_URL + (url.startsWith('/') ? url : '/' + url)
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await Taro.request({
|
||||
...options,
|
||||
url: url,
|
||||
header: header,
|
||||
})
|
||||
|
||||
if (res.statusCode === 401) {
|
||||
// Token expired
|
||||
Taro.removeStorageSync('token')
|
||||
// Optional: Auto re-login logic could go here
|
||||
Taro.showToast({ title: '登录已过期,请重试', icon: 'none' })
|
||||
// For user experience, maybe trigger login
|
||||
return Promise.reject(res)
|
||||
}
|
||||
|
||||
if (res.statusCode >= 400) {
|
||||
const errMsg = res.data?.error || res.data?.detail || '请求失败'
|
||||
Taro.showToast({ title: errMsg, icon: 'none' })
|
||||
return Promise.reject(res)
|
||||
}
|
||||
|
||||
return res.data
|
||||
} catch (err) {
|
||||
Taro.showToast({ title: '网络错误', icon: 'none' })
|
||||
return Promise.reject(err)
|
||||
}
|
||||
}
|
||||
|
||||
export const login = async () => {
|
||||
try {
|
||||
const { code } = await Taro.login()
|
||||
if (!code) throw new Error('wx.login failed')
|
||||
|
||||
const res = await Taro.request({
|
||||
url: `${BASE_URL}/wechat/login/`,
|
||||
method: 'POST',
|
||||
data: { code }
|
||||
})
|
||||
|
||||
if (res.statusCode === 200 && res.data.token) {
|
||||
Taro.setStorageSync('token', res.data.token)
|
||||
Taro.setStorageSync('openid', res.data.openid)
|
||||
// Save other info if needed
|
||||
return res.data
|
||||
} else {
|
||||
throw new Error(res.data.error || 'Login failed')
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Login error', err)
|
||||
// Don't toast here to avoid spamming if called automatically
|
||||
throw err
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user