feat: app

v3
veypi 4 weeks ago
parent 932b20fe72
commit 5b37b9f2a8

@ -20,6 +20,8 @@ export interface App {
init_role?: Role
init_url: string
user_count: number
status: string
user_status: string
}
export interface AppUser {
id: string

@ -26,8 +26,8 @@ export interface PostOpts {
}
// keep
export function Post(json: PostOpts) {
return webapi.Post<string>(`/token`, { json })
export function Post(json: PostOpts, config?: Object) {
return webapi.Post<string>(`/token`, { json, config })
}
export function Get(token_id: string) {
return webapi.Get<models.Token>(`/token/${token_id}`, {})

@ -4,7 +4,7 @@
// Distributed under terms of the MIT license.
//
import axios, { AxiosError, AxiosInstance, type AxiosResponse } from 'axios';
import axios, { AxiosError, type AxiosInstance, type AxiosResponse } from 'axios';
// Be careful when using SSR for cross-request state pollution
// due to creating a Singleton instance here;
@ -16,6 +16,7 @@ import axios, { AxiosError, AxiosInstance, type AxiosResponse } from 'axios';
export const token = {
value: '',
update: () => {
console.warn('token updater not set')
return new Promise<string>((resolve) => { resolve(token.value) })
},
set_updator: (fn: () => Promise<string>) => {
@ -49,10 +50,9 @@ export const token = {
}
// 请求拦截
const beforeRequest = (config: any) => {
config.retryTimes = 3
config.retryTimes = config.retryTimes || 3
// NOTE 添加自定义头部
token.value && (config.headers.Authorization = `Bearer ${token.value}`)
// config.headers['auth_token'] = ''
return config
}
@ -83,17 +83,18 @@ const responseFailed = (client: AxiosInstance) => {
return Promise.reject(new Error('请检查网络连接'))
}
let needRetry = true
// @ts-ignore
let needRetry = config?.needRetry !== false
if (response?.status == 404) {
needRetry = false
} else if (response?.status == 401) {
} else if (response?.status == 401 && needRetry) {
needRetry = false
// AuthNotFound = New(40100, "auth not found")
// AuthExpired = New(40102, "auth expired")
if (data.code === 40102 || data.code === 40100) {
token.value = ''
return token.update().then(() => {
return requestRetry(client)(1000, response!)
return requestRetry(client)(200, response!)
})
}
} else if (response?.status == 500) {
@ -143,6 +144,7 @@ interface data {
query?: any
form?: any
header?: any
config?: Object
}
@ -159,6 +161,9 @@ function transData(d: data) {
if (d.header) {
opts.headers = Object.assign(opts.headers, d.header)
}
if (d.config) {
opts = Object.assign(opts, d.config)
}
return opts
}

@ -162,9 +162,6 @@ div[voa] {
display: flex;
justify-content: space-between;
align-items: center;
height: 3rem;
line-height: 3rem;
font-size: 1.25rem;
}
.voa-account-body {
@ -199,17 +196,35 @@ div[voa] {
}
}
.voa-item-title {
height: 3rem;
line-height: 3rem;
font-size: 1.25rem;
cursor: pointer;
user-select: none;
font-weight: 500;
margin-left: -1rem;
}
.voa-apps {
.voa-apps-header {}
padding: 0 1rem;
.voa-apps-body {
margin-top: 1rem;
display: flex;
flex-wrap: wrap;
gap: 1rem;
flex-direction: column;
}
.voa-apps-box {}
.voa-apps-box {
img {
border-radius: 50%;
width: 3rem;
height: 3rem;
object-fit: cover;
}
}
}

@ -8,7 +8,16 @@ import { v } from '../v2dom'
import logic from '../logic'
export default v('voa-account', [
v('voa-account-header', [v('voa-ah-1', '我的账户'), v('voa-ah-2')]),
v('voa-account-header', [
v({
class: 'voa-item-title',
children: ['我的账户'],
onclick: () => {
logic.goto('/user')
}
}),
v('voa-ah-2')]
),
v('voa-account-body', [
v('voa-ab-ico', [v({ typ: 'img', attrs: { 'src': () => `${logic.user.icon}` } })]),
v('voa-ab-info', [

@ -14,28 +14,29 @@ import * as typs from "../typs"
export default () => {
let apps: typs.App[] = proxy.Watch([])
api.app.List({}).then(e => {
apps.push(...e)
apps.push(...e.filter((i) => i.user_status === 'ok'))
})
return v({
class: 'voa-apps',
children: [
v('voa-apps-header', [v('voa-apps-title', '我的应用')]),
v('voa-apps-body', [
vfor(apps,
(data, idx) => v('voa-apps-box', [v('span', () => idx + ': ' + data.name)])),
// [logic.myapps,
// (data) => v('voa-app-box', () => data.name)],
v({
typ: 'div', children: ['add'], vbind: [logic.myapps[0], 'name'],
v('voa-apps-header',
[v({
class: 'voa-item-title',
children: ['我的应用'],
onclick: () => {
// let tmp = apps[1]
// apps[1] = apps[0]
// apps[0] = tmp
// apps.splice(2, 1)
apps.push({ name: new Date().toLocaleTimeString() } as any)
logic.goto('/')
}
})
})]
),
v('voa-apps-body', [
vfor(apps,
(data) => v({
class: 'voa-apps-box',
children: [v('img', '', { src: () => data.icon })],
onclick: () => {
logic.goto(`/app/${data.id}`)
}
}))
])
]
})

@ -68,14 +68,15 @@ class Token {
if (this._typ === 'app') {
aid = logic.app_id
}
api.token.Post({ refresh: logic.token.refresh.raw(), user_id: logic.token.refresh.uid!, app_id: aid }).then(e => {
api.token.Post({ refresh: logic.token.refresh.raw(), user_id: logic.token.refresh.uid!, app_id: aid }, { needRetry: false }).then(e => {
if (this._typ === 'oa' && logic.app_id == logic.oa_id) {
logic.token.app.set(e)
}
this.set(e)
resolve(this)
}).catch(e => {
console.warn(`get oa token failed: ${e} `)
console.warn(`refresh token failed: ${e.err || e} `)
bus.emit('logout')
reject()
})
})

Loading…
Cancel
Save