- 弃用 service 请求,重新设计了 request 请求方案。

- 用户信息绑定方式更改为 userInfo
This commit is contained in:
icssoa
2025-08-27 19:27:52 +08:00
parent 2bab42954a
commit d4c7467f8b
25 changed files with 222 additions and 528 deletions

View File

@@ -16,7 +16,7 @@ type PagerResponse = {
};
// 分页回调函数类型
type PagerCallback = (params: UTSJSONObject) => Promise<UTSJSONObject>;
type PagerCallback = (params: UTSJSONObject) => Promise<any>;
// 分页器类
export class Pager {
@@ -75,9 +75,6 @@ export class Pager {
this.size = pagination.size;
this.total = pagination.total;
// 更新加载完成状态
this.finished.value = this.list.value.length >= this.total;
// 更新列表数据
if (data.page == 1) {
this.list.value = [...list];
@@ -85,6 +82,9 @@ export class Pager {
this.list.value.push(...list);
}
// 更新加载完成状态
this.finished.value = this.list.value.length >= this.total;
resolve(res);
})
.catch((err) => {

View File

@@ -2,10 +2,12 @@ import { reactive } from "vue";
import { isNull } from "../utils";
// #ifdef APP
// @ts-ignore
type Instance = ComponentPublicInstance | null;
// #endif
// #ifndef APP
// @ts-ignore
type Instance = any;
// #endif

View File

@@ -1,6 +1,6 @@
import { ref } from "vue";
import { assign, getUrlParam, storage } from "../utils";
import { service } from "../service";
import { request } from "../service";
import { t } from "@/locale";
import { config } from "@/config";
@@ -62,20 +62,28 @@ export class Wx {
*/
getMpConfig() {
if (this.isWxBrowser()) {
service.user.comm
.wxMpConfig({
request({
url: "/app/user/common/wxMpConfig",
method: "POST",
data: {
url: `${location.origin}${location.pathname}`
})
.then((res) => {
}
}).then((res) => {
if (res != null) {
wx.config({
debug: config.wx.debug,
jsApiList: ["chooseWXPay"],
...res
jsApiList: res.jsApiList || ["chooseWXPay"],
appId: res.appId,
timestamp: res.timestamp,
nonceStr: res.nonceStr,
signature: res.signature,
openTagList: res.openTagList
});
// 合并配置到mpConfig
assign(this.mpConfig, res);
});
}
});
}
}

View File

@@ -42,3 +42,4 @@ export * from "./store";
export * from "./theme";
export * from "./upload";
export * from "./utils";
export * from "./types";

View File

@@ -1,4 +1,3 @@
import type { Service } from "../types";
import { isDev, ignoreTokens, config } from "@/config";
import { locale, t } from "@/locale";
import { isNull, isObject, parse, storage } from "../utils";
@@ -43,7 +42,7 @@ const isIgnoreToken = (url: string) => {
* @param options 请求参数
* @returns Promise<T>
*/
export function request<T = any>(options: RequestOptions): Promise<T> {
export function request(options: RequestOptions): Promise<any | null> {
let { url, method = "GET", data = {}, header = {}, timeout = 60000 } = options;
const { user } = useStore();
@@ -84,40 +83,43 @@ export function request<T = any>(options: RequestOptions): Promise<T> {
// 401 无权限
if (res.statusCode == 401) {
user.logout();
return reject({ message: t("无权限") } as Response);
reject({ message: t("无权限") } as Response);
}
// 502 服务异常
if (res.statusCode == 502) {
return reject({
else if (res.statusCode == 502) {
reject({
message: t("服务异常")
} as Response);
}
// 404 未找到
if (res.statusCode == 404) {
else if (res.statusCode == 404) {
return reject({
message: `[404] ${url}`
} as Response);
}
// 200 正常响应
if (res.statusCode == 200) {
if (!isObject(res.data as any)) {
resolve(res.data as T);
return;
}
else if (res.statusCode == 200) {
if (res.data == null) {
resolve(null);
} else if (!isObject(res.data as any)) {
resolve(res.data);
} else {
// 解析响应数据
const { code, message, data } = parse<Response>(
res.data ?? { code: 0 }
)!;
// 解析响应数据
const { code, message, data } = parse<Response>(res.data ?? { code: 0 })!;
switch (code) {
case 1000:
resolve(data as T);
break;
default:
reject({ message, code } as Response);
break;
switch (code) {
case 1000:
resolve(data);
break;
default:
reject({ message, code } as Response);
break;
}
}
} else {
reject({ message: t("服务异常") } as Response);
@@ -178,6 +180,3 @@ export function request<T = any>(options: RequestOptions): Promise<T> {
next();
});
}
// 服务对象(实际会在其他地方赋值)
export const service = {} as Service;

View File

@@ -1,6 +1,5 @@
import { reactive } from "vue";
import { service } from "../service";
import type { DictKey } from "../types";
import { request } from "../service";
import { forInObject, isNull, parse } from "../utils";
// 字典项类型定义
@@ -40,7 +39,7 @@ export class Dict {
* @param key 字典key
* @returns 字典项数组
*/
get(key: DictKey): DictItem[] {
get(key: string): DictItem[] {
return this.find(key)?.list ?? new Array<DictItem>();
}
@@ -50,7 +49,7 @@ export class Dict {
* @param value 字典项值
* @returns 字典项或null
*/
getItem(key: DictKey, value: any): DictItem | null {
getItem(key: string, value: any): DictItem | null {
const item = this.get(key).find((e) => e.value == value);
if (isNull(item)) {
@@ -66,7 +65,7 @@ export class Dict {
* @param values 字典项值数组
* @returns 字典项数组
*/
getItems(key: DictKey, values: any[]): DictItem[] {
getItems(key: string, values: any[]): DictItem[] {
return values.map((e) => this.getItem(key, e)).filter((e) => !isNull(e)) as DictItem[];
}
@@ -76,7 +75,7 @@ export class Dict {
* @param value 字典项值
* @returns 字典项label字符串
*/
getItemLabel(key: DictKey, value: any): string {
getItemLabel(key: string, value: any): string {
const item = this.getItem(key, value);
if (isNull(item) || isNull(item?.label)) {
@@ -90,8 +89,16 @@ export class Dict {
* 刷新字典数据
* @param types 可选指定需要刷新的字典key数组
*/
async refresh(types?: DictKey[] | null): Promise<void> {
const res = await service.dict.info.data({ types });
async refresh(types?: string[] | null): Promise<void> {
const res = await request({
url: "/app/dict/info/data",
method: "POST",
data: { types }
});
if (res == null) {
return;
}
// 遍历返回的字典数据
forInObject(res, (arr, key) => {
@@ -127,11 +134,3 @@ export class Dict {
// 单例字典对象
export const dict = new Dict();
/**
* 获取字典实例
* @returns Dict实例
*/
export function useDict() {
return dict;
}

View File

@@ -1,28 +1,21 @@
import { reactive } from "vue";
import type { UserInfoEntity } from "../types";
import { forInObject, isNull, parse, storage } from "../utils";
import { service } from "../service";
import { computed, ref } from "vue";
import { forInObject, isNull, isObject, parse, storage } from "../utils";
import { router } from "../router";
import { request } from "../service";
import type { UserInfo } from "@/types";
/**
* Token类型定义
* @property token 访问token
* @property expire token过期时间
* @property refreshToken 刷新token
* @property refreshExpire 刷新token过期时间
*/
export type Token = {
token: string;
expire: number;
refreshToken: string;
refreshExpire: number;
token: string; // 访问token
expire: number; // token过期时间
refreshToken: string; // 刷新token
refreshExpire: number; // 刷新token过期时间
};
export class User {
/**
* 用户信息,响应式对象属性结构见UserInfoEntity
* 用户信息,响应式对象
*/
info = reactive<UserInfoEntity>({});
info = ref<UserInfo | null>(null);
/**
* 当前token字符串或null
@@ -40,7 +33,9 @@ export class User {
this.token = token == "" ? null : token;
// 初始化用户信息
this.set(userInfo!);
if (userInfo != null && isObject(userInfo)) {
this.set(userInfo);
}
}
/**
@@ -49,10 +44,11 @@ export class User {
*/
async get() {
if (this.token != null) {
await service.user.info
.person({})
await request({
url: "/app/user/info/person"
})
.then((res) => {
if (!isNull(res)) {
if (res != null) {
this.set(res);
}
})
@@ -71,13 +67,8 @@ export class User {
return;
}
// 先清空原有信息
this.remove();
// 逐项赋值到响应式info对象
forInObject(data, (value, key) => {
this.info[key] = value;
});
// 设置
this.info.value = parse<UserInfo>(data)!;
// 持久化到本地存储
storage.set("userInfo", data, 0);
@@ -87,43 +78,38 @@ export class User {
* 更新用户信息(本地与服务端同步)
* @param data 新的用户信息
*/
async update(data: UserInfoEntity) {
if (isNull(data) || this.isNull()) {
async update(data: any) {
if (isNull(data) || isNull(this.info.value)) {
return;
}
const params = { ...data };
// 本地同步更新
forInObject(params as any, (value, key) => {
this.info[key] = value;
forInObject(data, (value, key) => {
this.info.value![key] = value;
});
// 同步到服务端
await service.user.info.updatePerson(params);
}
/**
* 移除用户信息(仅清空本地响应式对象,不清除本地存储)
*/
remove() {
forInObject({ ...this.info } as any, (_, key) => {
// #ifdef APP
this.info[key] = null;
// #endif
// #ifndef APP
delete this.info[key];
// #endif
await request({
url: "/app/user/info/updatePerson",
method: "POST",
data
});
}
/**
* 判断用户信息是否为空以id字段为准
* 移除用户信息
*/
remove() {
this.info.value = null;
storage.remove("userInfo");
}
/**
* 判断用户信息是否为空
* @returns boolean
*/
isNull() {
return isNull(this.info["id"]);
return this.info.value == null;
}
/**
@@ -164,16 +150,21 @@ export class User {
*/
refreshToken(): Promise<string> {
return new Promise((resolve, reject) => {
service.user.login
.refreshToken({
request({
url: "/app/user/login/refreshToken",
method: "POST",
data: {
refreshToken: storage.get("refreshToken")
})
}
})
.then((res) => {
const token = parse<Token>(res);
if (res != null) {
const token = parse<Token>(res);
if (token != null) {
this.setToken(token);
resolve(token.token);
if (token != null) {
this.setToken(token);
resolve(token.token);
}
}
})
.catch((err) => {
@@ -189,9 +180,6 @@ export class User {
export const user = new User();
/**
* 获取用户单例实例组合式API用法
* @returns User
* 用户信息,响应式对象
*/
export function useUser() {
return user;
}
export const userInfo = computed(() => user.info.value);

View File

@@ -1,5 +1,3 @@
export * from "@/.cool/eps";
export type PushAnimationType =
| "auto"
| "none"

View File

@@ -1,5 +1,5 @@
import { config } from "@/config";
import { service } from "../service";
import { request } from "../service";
import { basename, extname, filename, parse, parseObject, pathJoin, uuid } from "../utils";
import { useStore } from "../store";
@@ -57,8 +57,11 @@ export type LocalUploadResponse = {
// 获取上传模式(本地/云端及云类型)
async function getUploadMode(): Promise<UploadMode> {
const res = await service.base.comm.uploadMode({});
return parse<UploadMode>(res)!;
const res = await request({
url: "/app/base/comm/uploadMode"
});
return parse<UploadMode>(res!)!;
}
/**
@@ -199,10 +202,13 @@ export async function uploadFile(
}
// 获取云上传参数
service.base.comm
.upload(data)
request({
url: "/app/base/comm/upload",
method: "POST",
data
})
.then((res) => {
const d = parse<CloudUploadResponse>(res)!;
const d = parse<CloudUploadResponse>(res!)!;
switch (type) {
// 腾讯云COS