diff --git a/src/api/user.ts b/src/api/user.ts
index aecbf02..46217fb 100644
--- a/src/api/user.ts
+++ b/src/api/user.ts
@@ -292,8 +292,8 @@ export interface UserForm {
mobile?: string;
/** 昵称 */
nickname?: string;
- /** 角色ID集合 */
- roleIds: number[];
+ /** 角色ID集合(后端 Long 序列化为字符串,兼容数字) */
+ roleIds: (number | string)[];
/** 用户状态(1:正常;0:禁用) */
status?: number;
/** 用户名 */
diff --git a/src/components/cu-date-query/index.vue b/src/components/cu-date-query/index.vue
index f2da517..4ea37db 100644
--- a/src/components/cu-date-query/index.vue
+++ b/src/components/cu-date-query/index.vue
@@ -63,7 +63,7 @@ const handleConfirm = () => {
const startDate = dayjs(dateRange.value[0]).format("YYYY-MM-DD");
const endDate = dayjs(dateRange.value[1]).format("YYYY-MM-DD");
- let newVal: any = [startDate, endDate];
+ let newVal: string | string[] = [startDate, endDate];
// #ifdef MP-WEIXIN
newVal = `${startDate},${endDate}`;
diff --git a/src/components/custom-navbar/index.vue b/src/components/custom-navbar/index.vue
index 59348b1..9767fc5 100644
--- a/src/components/custom-navbar/index.vue
+++ b/src/components/custom-navbar/index.vue
@@ -30,8 +30,9 @@
-
+
+
diff --git a/src/components/custom-tree/index.vue b/src/components/custom-tree/index.vue
index 4b90b43..374fee8 100644
--- a/src/components/custom-tree/index.vue
+++ b/src/components/custom-tree/index.vue
@@ -71,7 +71,7 @@
import { ref, computed, watch } from "vue";
export interface TreeOption {
- [key: string]: any;
+ [key: string]: unknown;
value: string;
label: string;
children?: TreeOption[];
@@ -163,7 +163,7 @@ const flatNodes = computed(() => {
result.push({
...node,
value: String(node[props.valueKey]),
- label: node[props.labelKey],
+ label: node[props.labelKey] as string,
level,
hasChildren: !!(children && children.length > 0),
raw: node,
diff --git a/src/composables/useNavigation.ts b/src/composables/useNavigation.ts
index ba3652e..568beb4 100644
--- a/src/composables/useNavigation.ts
+++ b/src/composables/useNavigation.ts
@@ -2,7 +2,6 @@ import { checkLogin } from "@/utils/auth";
interface NavItem {
url?: string;
- [key: string]: any;
}
export function useNavigation() {
diff --git a/src/composables/useScanLogin.ts b/src/composables/useScanLogin.ts
new file mode 100644
index 0000000..f3d9b84
--- /dev/null
+++ b/src/composables/useScanLogin.ts
@@ -0,0 +1,28 @@
+import { checkLogin } from "@/utils/auth";
+
+/**
+ * 扫码登录 PC 端
+ *
+ * 调起相机扫描 PC 端登录二维码,校验票据后跳转扫码确认页。
+ * 未登录时跳转登录页,用户取消扫码静默处理。
+ */
+export function useScanLogin() {
+ const scanLogin = async () => {
+ if (!checkLogin()) return;
+ try {
+ const res = await uni.scanCode({ scanType: ["qrCode"] });
+ const ticket = (res.result || "").trim();
+ if (!ticket) {
+ uni.showToast({ title: "无效的二维码", icon: "none" });
+ return;
+ }
+ uni.navigateTo({
+ url: `/pages/mine/scan-confirm/index?ticket=${encodeURIComponent(ticket)}`,
+ });
+ } catch {
+ // 用户取消扫码,静默处理
+ }
+ };
+
+ return { scanLogin };
+}
diff --git a/src/composables/useSse.ts b/src/composables/useSse.ts
index e1342fd..899eaf2 100644
--- a/src/composables/useSse.ts
+++ b/src/composables/useSse.ts
@@ -9,7 +9,7 @@ export interface UseSseOptions {
maxReconnectAttempts?: number;
}
-type EventHandler = (data: any) => void;
+type EventHandler = (data: unknown) => void;
export enum SseConnectionState {
DISCONNECTED = "DISCONNECTED",
@@ -44,8 +44,8 @@ function createSseConnection(options: UseSseOptions = {}) {
const eventHandlers = new Map>();
- const log = (...args: any[]) => config.debug && console.log("[SSE]", ...args);
- const logError = (...args: any[]) => console.error("[SSE]", ...args);
+ const log = (...args: unknown[]) => config.debug && console.log("[SSE]", ...args);
+ const logError = (...args: unknown[]) => console.error("[SSE]", ...args);
const clearTimer = (timer: typeof connectionTimeoutTimer) => {
if (timer) {
diff --git a/src/layouts/tabbar.vue b/src/layouts/tabbar.vue
index 7bab790..42d9329 100644
--- a/src/layouts/tabbar.vue
+++ b/src/layouts/tabbar.vue
@@ -1,6 +1,11 @@
-
+
-
- 登 录
-
+ 登 录
@@ -243,9 +241,7 @@
演示环境验证码:123456
-
- 确认绑定
-
+ 确认绑定
@@ -264,6 +260,7 @@ import type { FormSchema } from "@wot-ui/ui/components/wd-form/types";
import { useUserStore } from "@/store/modules/user";
import { useCountdown } from "@/composables/useCountdown";
+import { getErrorMessage } from "@/utils";
import AuthAPI from "@/api/auth";
definePage({
@@ -432,8 +429,8 @@ async function doFormLogin() {
await userStore.getInfo();
toast.success("登录成功");
setTimeout(() => uni.reLaunch({ url: redirect.value }), 800);
- } catch (error: any) {
- toast.error(error?.message || "登录失败");
+ } catch (error) {
+ toast.error(getErrorMessage(error, "登录失败"));
if (loginMode.value === "PASSWORD") fetchCaptcha();
} finally {
isLoading.value = false;
@@ -475,13 +472,18 @@ const handleSendCode = async () => {
await AuthAPI.sendSmsLoginCode(mobile);
toast.success("验证码已发送");
startSmsCountdown();
- } catch (error: any) {
- toast.error(error?.message || "发送失败");
+ } catch (error) {
+ toast.error(getErrorMessage(error, "发送失败"));
}
};
// 微信登录
-const handleWechatPhoneLogin = async (e: any) => {
+/** 微信手机号快捷填充按钮回调事件 */
+interface WxPhoneLoginEvent {
+ detail: { code?: string };
+}
+
+const handleWechatPhoneLogin = async (e: WxPhoneLoginEvent) => {
const phoneCode = e.detail.code;
if (!isAgreePolicy.value) {
openPolicyDialog("WECHAT_PHONE", phoneCode);
@@ -518,7 +520,7 @@ const handleWechatSilentLogin = async () => {
isLoading.value = true;
try {
const { code } = await uni.login();
- const result: any = await userStore.loginByWxMa(code);
+ const result = await userStore.loginByWxMa(code);
if (result.needBindMobile && result.openid) {
wechatOpenid.value = result.openid;
showBindMobilePopup.value = true;
@@ -527,8 +529,8 @@ const handleWechatSilentLogin = async () => {
toast.success("登录成功");
setTimeout(() => uni.reLaunch({ url: redirect.value }), 800);
}
- } catch (error: any) {
- toast.error(error?.message || "微信登录失败");
+ } catch (error) {
+ toast.error(getErrorMessage(error, "微信登录失败"));
} finally {
isLoading.value = false;
}
@@ -546,8 +548,8 @@ const handleSendBindCode = async () => {
await AuthAPI.sendSmsLoginCode(mobile);
toast.success("验证码已发送");
startBindSmsCountdown();
- } catch (error: any) {
- toast.error(error?.message || "发送失败");
+ } catch (error) {
+ toast.error(getErrorMessage(error, "发送失败"));
}
};
@@ -575,8 +577,8 @@ const handleBindMobile = async () => {
resetBindForm();
toast.success("绑定成功");
setTimeout(() => uni.reLaunch({ url: redirect.value }), 800);
- } catch (error: any) {
- toast.error(error?.message || "绑定失败");
+ } catch (error) {
+ toast.error(getErrorMessage(error, "绑定失败"));
} finally {
isBindLoading.value = false;
}
@@ -597,7 +599,7 @@ const handleBack = () => {
};
// 生命周期
-onLoad((options: any) => {
+onLoad((options) => {
const fromQuery = options?.redirect ? decodeURIComponent(options.redirect) : "";
if (fromQuery && fromQuery !== "/pages/login/index") redirect.value = fromQuery;
uni.setNavigationBarTitle({ title: "" });
diff --git a/src/pages/mine/index.vue b/src/pages/mine/index.vue
index aaefcbb..1eaeba5 100644
--- a/src/pages/mine/index.vue
+++ b/src/pages/mine/index.vue
@@ -11,6 +11,11 @@
:show-back="false"
:placeholder="false"
>
+
+
+
+
+
个人中心
@@ -65,9 +70,7 @@
-
- 立即登录
-
+ 立即登录
@@ -132,16 +135,6 @@
-
@@ -390,7 +388,7 @@ function showNoticeActions(item: NoticeItem) {
actionSheetVisible.value = true;
}
-function handleActionSelect({ item }: { item: any }) {
+function handleActionSelect({ item }: { item: { name: string } }) {
pendingAction.value[item.name]?.();
}
diff --git a/src/pages/work/role/assign-perm.vue b/src/pages/work/role/assign-perm.vue
index 96d85a5..754b52e 100644
--- a/src/pages/work/role/assign-perm.vue
+++ b/src/pages/work/role/assign-perm.vue
@@ -10,7 +10,9 @@
全选
- 取消全选
+
+ 取消全选
+
diff --git a/src/pages/work/role/index.vue b/src/pages/work/role/index.vue
index 3a69ad4..887d786 100644
--- a/src/pages/work/role/index.vue
+++ b/src/pages/work/role/index.vue
@@ -254,7 +254,7 @@ function closeRoleDialog() {
}
// 操作菜单分发
-function handleActionSelect({ item }: { item: any }) {
+function handleActionSelect({ item }: { item: { name: string } }) {
const value = item.name;
const role = currentActionItem.value;
if (value === "编辑") {
@@ -267,7 +267,7 @@ function handleActionSelect({ item }: { item: any }) {
msg: `确定要删除角色「${role.name}」吗?`,
headerImage: "warning",
}).then(async () => {
- await RoleAPI.deleteByIds(String(item.id));
+ await RoleAPI.deleteByIds(String(role.id));
toast.success("删除成功");
loadRoleList();
});
diff --git a/src/pages/work/user/index.vue b/src/pages/work/user/index.vue
index 64be659..e280c08 100644
--- a/src/pages/work/user/index.vue
+++ b/src/pages/work/user/index.vue
@@ -202,10 +202,7 @@
取消
-
+
确认
@@ -217,6 +214,7 @@