refactor(frontend): Phase 3 质量整改——死状态清理、类型收口、路由收敛、上传统一
- stores: 移除未使用的 token/loading/locale 死状态;AdminCheckResult 统一收口 types/api.ts - router: 移除全 Mock 的 SKU 页生产路由(源码保留待独立工程决策) - api/request: 新增 requestRaw() 显式原始响应封装(替代 responseType hack) - Manager.vue: SimpleUpload 弃用 XMLHttpRequest,改统一 axios upload + onUploadProgress(拦截器收益全覆盖)
This commit is contained in:
1 parent
4d49e549b5
commit
ce7a17d170
6 files changed
+38
-50
No files matched your search
@@ -171,6 +171,13 @@ export function patch<T = unknown>(url: string, data?: unknown, config?: AxiosRe
|
||||
return request.patch(url, data, config) as unknown as Promise<T>
|
||||
}
|
||||
|
||||
/** 原始响应请求:返回 AxiosResponse(绕过 {code,data} 解包),
|
||||
* 供需要访问原始响应体(非标准结构/流式响应)的场景使用,
|
||||
* 替代 responseType:'text' + 双重类型断言的 hack */
|
||||
export function requestRaw<T = unknown>(config: AxiosRequestConfig): Promise<AxiosResponse<T>> {
|
||||
return request.request(config) as Promise<AxiosResponse<T>>
|
||||
}
|
||||
|
||||
/** 上传文件 */
|
||||
export function upload<T = unknown>(url: string, formData: FormData, config?: AxiosRequestConfig): Promise<T> {
|
||||
return request.post(url, formData, {
|
||||
|
||||
+2
-7
@@ -360,13 +360,8 @@ export const staticRoutes: RouteRecordRaw[] = [
|
||||
component: () => import('@/views/LegacyPage.vue'),
|
||||
meta: { title: '储值查看', requiresAuth: true, menuGuarded: true, legacySrc: '/pages/private/CreateE/StoreValue.html' },
|
||||
},
|
||||
// === 阶段 8:SKU(移动端 C 端,待决策是否拆分独立工程) ===
|
||||
{
|
||||
path: 'sku',
|
||||
name: 'Sku',
|
||||
component: () => import('@/views/SKU/Sku.vue'),
|
||||
meta: { title: '商品详情', requiresAuth: false },
|
||||
},
|
||||
// === SKU(移动端 C 端):全 Mock 页面已从生产路由移除 ===
|
||||
// Sku.vue 仍保留源码(1870 行 Mock 数据 + TODO),待决策是否拆分为独立移动端工程后再接入
|
||||
// === 兜底:未匹配路由在 DefaultLayout 内显示 404(保留 menu/nav/tab) ===
|
||||
// 作为 DefaultLayout 子路由,享有完整框架;requiresAuth: true 使其自动开 tab
|
||||
{
|
||||
|
||||
+1
-4
@@ -131,7 +131,7 @@ function applyPrimaryColor(color: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
/** 应用状态:侧边栏折叠、主题、配色、语言等全局 UI 状态 */
|
||||
/** 应用状态:侧边栏折叠、主题、配色等全局 UI 状态 */
|
||||
export const useAppStore = defineStore('app', () => {
|
||||
/** 侧边栏是否折叠 */
|
||||
const sidebarCollapsed = ref(false)
|
||||
@@ -139,8 +139,6 @@ export const useAppStore = defineStore('app', () => {
|
||||
const theme = ref<ThemeMode>('default')
|
||||
/** 自定义主色(hex);设置后覆盖预设配色,null 表示用预设 */
|
||||
const customPrimary = ref<string | null>(null)
|
||||
/** 当前语言 */
|
||||
const locale = ref<'zh-CN' | 'en-US'>('zh-CN')
|
||||
|
||||
/** 切换侧边栏 */
|
||||
function toggleSidebar(): void {
|
||||
@@ -193,7 +191,6 @@ export const useAppStore = defineStore('app', () => {
|
||||
sidebarCollapsed,
|
||||
theme,
|
||||
customPrimary,
|
||||
locale,
|
||||
toggleSidebar,
|
||||
setTheme,
|
||||
setCustomColor,
|
||||
|
||||
+5
-15
@@ -32,8 +32,6 @@ export const useUserStore = defineStore('user', () => {
|
||||
const userInfo = ref<UserInfo | null>(null)
|
||||
const roles = ref<RoleItem[]>([])
|
||||
const menus = ref<MenuItem[]>([])
|
||||
const token = ref<string>('')
|
||||
const loading = ref(false)
|
||||
// CheckAdmin 结果(后端按当前角色权限码判定管理员,不依赖 GetELTUserInfo 的 IsAdmin 字段)
|
||||
const adminCheck = ref<AdminCheckResult | null>(null)
|
||||
// CheckAdmin 是否已加载完成(成功或失败都置 true,供页面区分"加载中"与"确实无权限")
|
||||
@@ -114,16 +112,11 @@ export const useUserStore = defineStore('user', () => {
|
||||
// === 动作 ===
|
||||
/** 登录 */
|
||||
async function login(params: LoginParams): Promise<void> {
|
||||
loading.value = true
|
||||
try {
|
||||
await apiLogin(params)
|
||||
await fetchUserInfo()
|
||||
await fetchMenus()
|
||||
await fetchRoles()
|
||||
await fetchAdminCheck()
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
await apiLogin(params)
|
||||
await fetchUserInfo()
|
||||
await fetchMenus()
|
||||
await fetchRoles()
|
||||
await fetchAdminCheck()
|
||||
}
|
||||
|
||||
/** 注销 */
|
||||
@@ -243,7 +236,6 @@ export const useUserStore = defineStore('user', () => {
|
||||
userInfo.value = null
|
||||
roles.value = []
|
||||
menus.value = []
|
||||
token.value = ''
|
||||
adminCheck.value = null
|
||||
adminChecked.value = false
|
||||
localStorage.removeItem(CACHE_KEY)
|
||||
@@ -254,8 +246,6 @@ export const useUserStore = defineStore('user', () => {
|
||||
userInfo,
|
||||
roles,
|
||||
menus,
|
||||
token,
|
||||
loading,
|
||||
adminCheck,
|
||||
adminChecked,
|
||||
// 计算属性
|
||||
|
||||
+18
-3
@@ -324,10 +324,25 @@ export interface RoleScope {
|
||||
WorkgroupUUID?: string
|
||||
}
|
||||
|
||||
/** CheckAdmin 接口返回结果 */
|
||||
/** CheckAdmin 接口返回结果(对齐后端 /API/FormAPI/CheckAdmin) */
|
||||
export interface AdminCheckResult {
|
||||
/** 是否管理员 */
|
||||
is_admin?: boolean
|
||||
/** 用户作用域 */
|
||||
role_scope?: RoleScope | null
|
||||
is_superuser?: boolean
|
||||
is_super_admin?: boolean
|
||||
is_tenant_admin?: boolean
|
||||
current_role_name?: string
|
||||
current_role_uuid?: string
|
||||
current_company_uuid?: string
|
||||
current_tenant_uuid?: string
|
||||
has_current_company?: boolean
|
||||
/** 当前角色的数据作用域 */
|
||||
role_scope?: {
|
||||
Type?: string
|
||||
TypeLabel?: string
|
||||
IsAdmin?: boolean
|
||||
IsDeptManager?: boolean
|
||||
IsWorkgroupLead?: boolean
|
||||
IsMember?: boolean
|
||||
} | null
|
||||
}
|
||||
@@ -525,7 +525,7 @@ async function UploadFiles(files: File[]): Promise<void> {
|
||||
|
||||
/**
|
||||
* 简单上传:单 FormData
|
||||
* 直接用 XHR 拿 onprogress 进度回调
|
||||
* 走统一 axios 实例(拦截器注入时区/作用域参数/401 处理),onUploadProgress 拿进度
|
||||
*/
|
||||
async function SimpleUpload(
|
||||
file: File,
|
||||
@@ -533,26 +533,10 @@ async function SimpleUpload(
|
||||
): Promise<void> {
|
||||
const fd = new FormData()
|
||||
fd.append('file', file)
|
||||
// TODO: @/api/request 的 upload() 封装暂未暴露 onProgress 回调
|
||||
// 若后续扩展 upload() 支持 onUploadProgress,可改回 upload('/API/Asset/Upload', fd, { onUploadProgress })
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.open('POST', '/API/Asset/Upload')
|
||||
xhr.withCredentials = true
|
||||
xhr.upload.onprogress = (e) => {
|
||||
if (e.lengthComputable) onProgress(Math.round((e.loaded / e.total) * 100))
|
||||
}
|
||||
xhr.onload = () => {
|
||||
try {
|
||||
const data = JSON.parse(xhr.responseText)
|
||||
if (data.code === 0) resolve()
|
||||
else reject(new Error(data.msg || '上传失败'))
|
||||
} catch {
|
||||
reject(new Error('解析响应失败'))
|
||||
}
|
||||
}
|
||||
xhr.onerror = () => reject(new Error('网络错误'))
|
||||
xhr.send(fd)
|
||||
await upload('/API/Asset/Upload', fd, {
|
||||
onUploadProgress: (e) => {
|
||||
if (e.total) onProgress(Math.round((e.loaded / e.total) * 100))
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user