feat: 后端初始化2

This commit is contained in:
2026-07-28 15:43:27 +08:00
parent dfe0d6bd95
commit 53305757f8
26 changed files with 734 additions and 36 deletions
+21
View File
@@ -0,0 +1,21 @@
const API_BASE = process.env.VUE_APP_SUPPLIED_API_BASE || 'http://localhost:8888/.netlify/functions'
const normalizeBase = base => base.replace(/\/$/, '')
export const postFunction = async (name, body = {}) => {
const response = await fetch(`${normalizeBase(API_BASE)}/${name}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
})
const payload = await response.json().catch(() => ({}))
if (!response.ok || payload.success === false) {
const message = payload.error?.message || payload.msg || '请求失败'
throw new Error(message)
}
return payload.data
}
+137
View File
@@ -0,0 +1,137 @@
import { defineStore } from 'pinia'
import { postFunction } from '@/api/supplied-service'
const USER_KEY = 'joyful-selection-user'
const DEFAULT_SUPPLIER_IDENTIFICATION = (process.env.VUE_APP_SUPPLIER_IDENTIFICATION || '').toLowerCase()
const readUser = () => {
try {
return JSON.parse(localStorage.getItem(USER_KEY) || '{}')
} catch (error) {
return {}
}
}
const saveUser = data => {
localStorage.setItem(USER_KEY, JSON.stringify(data))
}
export const useUserStore = defineStore('joyfulSelectionUser', {
state: () => ({
userId: '',
supplierIdentification: '',
supplierId: '',
supplierName: '',
clientId: '',
token: '',
refreshToken: '',
tokenExpiresAt: 0,
loaded: false,
loadingToken: false
}),
getters: {
hasToken: state => Boolean(state.token && state.tokenExpiresAt > Date.now())
},
actions: {
loadUser() {
const data = readUser()
this.userId = data.userId || ''
const supplierIdentification = DEFAULT_SUPPLIER_IDENTIFICATION || data.supplierIdentification || ''
const supplierChanged = Boolean(data.supplierIdentification && supplierIdentification !== data.supplierIdentification)
this.supplierIdentification = supplierIdentification
this.supplierId = supplierChanged ? '' : data.supplierId || ''
this.supplierName = supplierChanged ? '' : data.supplierName || ''
this.clientId = supplierChanged ? '' : data.clientId || ''
this.token = supplierChanged ? '' : data.token || ''
this.refreshToken = supplierChanged ? '' : data.refreshToken || ''
this.tokenExpiresAt = supplierChanged ? 0 : Number(data.tokenExpiresAt || 0)
this.loaded = true
},
persistUser() {
saveUser({
userId: this.userId,
supplierIdentification: this.supplierIdentification,
supplierId: this.supplierId,
supplierName: this.supplierName,
clientId: this.clientId,
token: this.token,
refreshToken: this.refreshToken,
tokenExpiresAt: this.tokenExpiresAt
})
this.loaded = true
},
hydrateFromRoute(query = {}) {
if (!this.loaded) {
this.loadUser()
}
const nextUserId = query.userId || ''
if (nextUserId && nextUserId !== this.userId) {
this.userId = nextUserId
this.token = ''
this.refreshToken = ''
this.tokenExpiresAt = 0
}
if (!this.supplierIdentification) {
this.supplierIdentification = DEFAULT_SUPPLIER_IDENTIFICATION
}
this.persistUser()
},
async fetchSupplierInfo() {
if (!this.loaded) {
this.loadUser()
}
if (!this.supplierIdentification) {
return
}
const data = await postFunction('supplier-info', {
supplierIdentification: this.supplierIdentification
})
if (data?.supplierId && data.supplierId !== this.supplierId) {
this.token = ''
this.refreshToken = ''
this.tokenExpiresAt = 0
}
this.supplierId = data?.supplierId || ''
this.supplierName = data?.supplierName || ''
this.clientId = data?.clientId || ''
this.persistUser()
},
async fetchBridgeToken() {
if (!this.loaded) {
this.loadUser()
}
if (!this.userId || !this.supplierIdentification || this.loadingToken || this.hasToken) {
return
}
this.loadingToken = true
try {
if (!this.supplierId) {
await this.fetchSupplierInfo()
}
const data = await postFunction('supplier-token', {
userId: this.userId,
supplierIdentification: this.supplierIdentification
})
this.supplierId = data?.supplierId || this.supplierId
this.supplierName = data?.supplierName || this.supplierName
this.token = data?.token || data?.accessToken || ''
this.refreshToken = data?.refreshToken || ''
const expiresIn = Number(data?.expiresIn || 0)
this.tokenExpiresAt = this.token && expiresIn > 0 ? Date.now() + expiresIn * 1000 : 0
this.persistUser()
} finally {
this.loadingToken = false
}
}
}
})
@@ -13,6 +13,7 @@
<script>
import { mapActions, mapState } from 'pinia'
import { useCartStore } from '@/store/cart'
import { useUserStore } from '@/store/user'
export default {
name: 'JoyfulSelectionLayout',
@@ -27,9 +28,26 @@ export default {
},
created() {
this.loadCart()
this.prepareUserSession()
},
watch: {
'$route.query': {
handler() {
this.prepareUserSession()
},
deep: true
}
},
methods: {
...mapActions(useCartStore, ['loadCart'])
...mapActions(useCartStore, ['loadCart']),
...mapActions(useUserStore, ['hydrateFromRoute', 'fetchBridgeToken']),
prepareUserSession() {
this.hydrateFromRoute(this.$route.query)
this.fetchBridgeToken().catch(error => {
console.warn('获取平台授权令牌失败', error)
this.$toast(error.message || '供应商验证失败,请稍后再试')
})
}
}
}
</script>