@@ -12,13 +12,14 @@
diff --git a/src/components/userSelector/index.vue b/src/components/userSelector/index.vue
new file mode 100644
index 0000000..25295e8
--- /dev/null
+++ b/src/components/userSelector/index.vue
@@ -0,0 +1,17 @@
+
+
+
+ {{ userAvatarName }}
+
+
+
+
diff --git a/src/hooks/useTokenRefresh.ts b/src/hooks/useTokenRefresh.ts
deleted file mode 100644
index 53cb882..0000000
--- a/src/hooks/useTokenRefresh.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-// useTokenRefresh.ts
-import { ref } from "vue";
-import axios from "axios";
-
-interface TokenData {
- accessToken: string; // token内容
- refreshToken: string; // 刷新的token内容
- expiresAt?: number; // 过期时间戳
-}
-
-export default function useTokenRefresh(baseUrl: string) {
- let refreshPromise: Promise
| null = null;
- let lastRefreshError: any = null;
- // 当前Token数据(使用localStorage持久化) 可根据实际情况改成localStorage存储
- const tokenData = ref({
- accessToken: localStorage.getItem("accessToken") || "",
- refreshToken: localStorage.getItem("refreshToken") || "",
- expiresAt: Number(localStorage.getItem("expiresAt")) || 0,
- });
-
- // 核心刷新方法
- const refreshToken = async (): Promise => {
- if (refreshPromise) return refreshPromise;
-
- // 如果上次刷新失败,短时间内不重复刷新,直接抛错
- if (lastRefreshError) {
- return Promise.reject(lastRefreshError);
- }
- const plainClient = axios.create({
- baseURL: baseUrl,
- timeout: 5 * 1000,
- headers: {
- "Content-Type": "application/json;charset=utf-8",
- },
- });
-
- refreshPromise = (async () => {
- try {
- const refreshToken = getRefreshToken();
- if (!refreshToken) throw new Error("refreshToken is null");
- const res = await plainClient.post("/auth/refresh", {
- refreshToken,
- });
- const newTokenData: TokenData = {
- accessToken: res.data.accessToken,
- refreshToken: res.data.refreshToken,
- expiresAt: Date.now() + res.data.expiresIn * 1000,
- };
- setTokens(newTokenData);
- lastRefreshError = null; // 成功清除错误
- return newTokenData;
- } catch (error) {
- // 刷新失败处理
- lastRefreshError = error;
- clearTokens();
- throw error;
- } finally {
- refreshPromise = null;
- }
- })();
- return refreshPromise;
- };
-
- // 保存token
- const setTokens = (data: TokenData) => {
- tokenData.value = data;
- localStorage.setItem("accessToken", data.accessToken);
- localStorage.setItem("refreshToken", data.refreshToken);
- localStorage.setItem("expiresAt", data.expiresAt.toString());
- };
- // 清理Token
- const clearTokens = () => {
- localStorage.removeItem("accessToken");
- localStorage.removeItem("refreshToken");
- localStorage.removeItem("expiresAt");
- tokenData.value = { accessToken: "", refreshToken: "", expiresAt: 0 };
- };
-
- // 获取当前Token
- const getAccessToken = () => tokenData.value.accessToken;
- // 获取refreshToken
- const getRefreshToken = () => tokenData.value.refreshToken;
- return {
- refreshToken,
- getRefreshToken,
- setTokens,
- getAccessToken,
- clearTokens,
- };
-}
\ No newline at end of file
diff --git a/src/mock/auth.ts b/src/mock/auth.ts
deleted file mode 100644
index 712af6f..0000000
--- a/src/mock/auth.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * 登录相关 Mock 数据
- */
-
-/**
- * Mock 登录响应
- */
-export const getMockLoginResponse = (username: string, password: string) => {
- // 模拟登录验证
- if (username && password) {
- return {
- code: 0,
- data: {
- accessToken: 'mock_access_token_' + Date.now(),
- refreshToken: 'mock_refresh_token_' + Date.now(),
- expiresIn: 7200, // 2小时
- userInfo: {
- id: 1,
- username: username,
- name: username === 'admin' ? '管理员' : '普通用户',
- role: username === 'admin' ? 'admin' : 'user',
- avatar: '',
- },
- },
- msg: '登录成功',
- }
- } else {
- return {
- code: 400,
- data: null,
- msg: '用户名或密码不能为空',
- }
- }
-}
-
-/**
- * Mock 用户信息响应
- */
-export const getMockUserInfoResponse = () => {
- return {
- code: 0,
- data: {
- id: 1,
- username: 'admin',
- name: '管理员',
- role: 'admin',
- avatar: '',
- },
- msg: '获取用户信息成功',
- }
-}
-
diff --git a/src/mock/index.ts b/src/mock/index.ts
deleted file mode 100644
index f01e7ff..0000000
--- a/src/mock/index.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * Mock 数据管理
- * 用于开发阶段模拟后端接口返回的数据
- */
-
-import { getMockMenuResponse } from './menu'
-import { getMockLoginResponse, getMockUserInfoResponse } from './auth'
-
-// 是否启用 Mock(可以通过环境变量控制)
-export const ENABLE_MOCK = import.meta.env.VITE_USE_MOCK === 'true' || import.meta.env.DEV
-
-/**
- * Mock API 响应映射
- * key: API 路径
- * value: 返回的 Mock 数据函数
- */
-const mockApiMap: Record any> = {
- '/api/menus': () => getMockMenuResponse(),
- '/api/auth/login': (_params?: any, data?: any) => {
- return getMockLoginResponse(data?.username || '', data?.password || '')
- },
- '/api/user/info': () => getMockUserInfoResponse(),
- // 可以在这里添加更多的 mock 接口
- // '/api/user/list': getMockUserList,
-}
-
-/**
- * 获取 Mock 数据
- * @param url API 路径
- * @param params 请求参数(GET)
- * @param data 请求体(POST/PUT)
- * @returns Mock 数据或 null
- */
-export const getMockData = (url: string, params?: any, data?: any): any => {
- if (!ENABLE_MOCK || !url) {
- return null
- }
-
- // 精确匹配
- if (mockApiMap[url]) {
- return mockApiMap[url](params, data)
- }
-
- // 模糊匹配(支持带查询参数的 URL)
- const urlWithoutQuery = url.split('?')[0]
- if (urlWithoutQuery && mockApiMap[urlWithoutQuery]) {
- return mockApiMap[urlWithoutQuery](params, data)
- }
-
- return null
-}
-
-/**
- * 检查是否应该使用 Mock 数据
- * @param url API 路径
- * @returns 是否应该使用 Mock
- */
-export const shouldUseMock = (url: string): boolean => {
- if (!ENABLE_MOCK || !url) {
- return false
- }
-
- // 精确匹配
- if (mockApiMap[url]) {
- return true
- }
-
- // 模糊匹配(支持带查询参数的 URL)
- const urlWithoutQuery = url.split('?')[0]
- return !!(urlWithoutQuery && mockApiMap[urlWithoutQuery])
-}
-
-/**
- * 添加 Mock 接口
- * @param url API 路径
- * @param mockFn Mock 数据函数
- */
-export const addMockApi = (url: string, mockFn: (params?: any, data?: any) => any) => {
- mockApiMap[url] = mockFn
-}
-
-/**
- * 移除 Mock 接口
- * @param url API 路径
- */
-export const removeMockApi = (url: string) => {
- delete mockApiMap[url]
-}
-
-export default {
- getMockData,
- shouldUseMock,
- addMockApi,
- removeMockApi,
- ENABLE_MOCK,
-}
-
diff --git a/src/mock/menu.ts b/src/mock/menu.ts
index 6abacd1..2ec9959 100644
--- a/src/mock/menu.ts
+++ b/src/mock/menu.ts
@@ -296,6 +296,45 @@ export const mockMenuData: MockMenuRoute[] = [
},
];
+
+export const mockBackendMenuData = [
+ {
+ "name": "字典管理",
+ "code": "dict",
+ "icon": "OfficeBuilding",
+ "metadata": null,
+ "children": null
+ },
+ {
+ "name": "组织管理",
+ "code": "origanization",
+ "icon": "OfficeBuilding",
+ "metadata": null,
+ "children": null
+ },
+ {
+ "name": "人员管理",
+ "code": "personnel",
+ "icon": "OfficeBuilding",
+ "metadata": null,
+ "children": null
+ },
+ {
+ "name": "权限管理",
+ "code": "permission",
+ "icon": "OfficeBuilding",
+ "metadata": null,
+ "children": null
+ },
+ {
+ "name": "流程管理",
+ "code": "flow",
+ "icon": "OfficeBuilding",
+ "metadata": null,
+ "children": null
+ }
+]
+
/**
* 获取 Mock 菜单数据的响应格式
* 模拟后端接口返回的数据结构
diff --git a/src/modules/Comment/index.scss b/src/modules/Comment/index.scss
index 87de5fa..59f35d8 100644
--- a/src/modules/Comment/index.scss
+++ b/src/modules/Comment/index.scss
@@ -189,7 +189,6 @@ $color-white: #fff;
.sub-list-controls {
display: flex;
align-items: center;
- margin-top: 12px;
padding-left: 46px; // 与头像对齐的偏移量
.expand-line {
@@ -230,6 +229,12 @@ $color-white: #fff;
background-color: rgba(64, 158, 255, 0.2);
}
}
+
+ .observer-anchor{
+ text-align: center;
+ font-size: 12px;
+ color: #808080;
+ }
}
// 评论组件骨架屏
diff --git a/src/modules/Comment/index.vue b/src/modules/Comment/index.vue
index de3b9a7..127bc64 100644
--- a/src/modules/Comment/index.vue
+++ b/src/modules/Comment/index.vue
@@ -51,14 +51,14 @@
- {{ item.employee.name }}
+ {{ item.employee.username }}
{{
formatTime(item.createTime)
}}
@@ -78,30 +78,25 @@
link
class="delete-btn"
@click="deleteMainComment(item)"
- v-if="currentUser.id === item?.employee.id"
+ v-if="currentUser.id === item?.employee.userId"
>
删除
-
+
@@ -109,13 +104,12 @@
@@ -182,6 +176,11 @@
+
+
+
+ 没有更多评论了
+
@@ -219,6 +218,7 @@
{{ item.name }}
@@ -264,6 +264,11 @@ import { useUserStore } from "@/store";
import { useRelativeTime } from "@/hooks/useRelativeTime";
import { useUserSearch } from "./useUserSearch";
import { parseMention } from "./utils";
+import {
+ getComment,
+ addReplyComment,
+ deleteComment,
+} from "@/api/modules/Comment";
const { formatTime } = useRelativeTime();
const userStore = useUserStore();
const { t } = useI18n();
@@ -279,7 +284,7 @@ const props = defineProps({
queryParams: {
//外部传入的请求参数-获取评论
type: Object,
- default: () => ({}),
+ default: () => ({ instanceId: 1, moduleId: 1 }),
},
});
const {
@@ -293,88 +298,22 @@ const {
} = useUserSearch((keyword, signal) => handleFetchSearch(keyword, signal));
// 评论业务逻辑
-const activeReply = reactive({ parentId: null, targetName: "" }); // 点击reply回复的数据信息
+const activeReply = reactive({
+ replyUserId: "",
+ parentId: null,
+ targetName: "",
+}); // 点击reply回复的数据信息
const mainInput = ref("");
const loading = ref(true); //当前骨架屏显示
const expandingCount = ref(0); //展开收起统计
// 评论数据
-const commentData = ref([
- {
- id: 1,
- content: "这是我的测试评论数据信息@张三1 😄",
- createTime: "2023-10-27T14:30:00",
- mentions: [{
- "id": 4,
- "name": "张三1",
- "start": 12,
- "end": 16
- }],
- employee: {
- id: 1,
- name: "李星倩",
- avatar: "",
- },
- childrenCount: 10,
- children: [
- {
- content: "好的那我来测试下艾特人员信息@冯娜 @张三1 你们好啊",
- mentions: [
- {
- id: 2,
- name: "冯娜",
- start: 14,
- end: 17,
- },
- {
- id: 4,
- name: "张三1",
- start: 18,
- end: 22,
- },
- ],
- employee: {
- id: 1,
- name: "李星倩",
- avatar: "",
- },
- reply: {
- id: 1,
- name: 1,
- },
- },
- {
- id: 102,
- avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=2",
- content: "收到,数据已入库,我马上看下。",
- createTime: 1767604936684,
- mentions: [{ userId: 2, name: "冯娜", start: 11, end: 15 }],
- replyEmployee: {
- id: 1,
- name: "冯娜",
- },
- employee: {
- id: 2,
- name: "zhanghan",
- avatar: "",
- },
- },
- {
- id: 103,
- avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=2",
- content: "收到,数据已入库,我马上看下。",
- createTime: 1767604936684,
- mentions: [{ userId: 2, name: "冯娜", start: 11, end: 15 }],
- employee: {
- id: 3,
- name: "王五",
- avatar: "",
- },
- },
- ],
- },
-]);
+const commentData = ref([]);
-// TODO:请求用户列表的接口函数
+// 滚动加载
+const infinityLoading = ref(false);
+const loadMoreAnchor = ref(null);
+const noMore = ref(false);
+// FIXME:请求用户列表的接口函数
const handleFetchSearch = async (keyword, signal) => {
console.log("获取参数信息", keyword, signal);
await new Promise((resolve) => setTimeout(resolve, 300));
@@ -392,6 +331,22 @@ const handleFetchSearch = async (keyword, signal) => {
];
};
+// 获取当前的的评论信息
+const getCommentData = async (childItem) => {
+ const queryData = {
+ pageNo: 1,
+ pageSize: 20,
+ ...props.queryParams,
+ ...childItem,
+ };
+ try {
+ const response = await getComment(queryData);
+ return response;
+ } catch (error) {
+ console.log("comment error:", error);
+ }
+};
+
// 点击回复插入 mentions 块
const handleKeyDown = (e) => {
if (e.key === "Backspace") {
@@ -412,19 +367,20 @@ const handleKeyDown = (e) => {
// 用户选中@圈人的操作
const onUserSelect = (user: any) => {
- console.log("获取当前返回的用户信息:", user);
recordSelection(user);
};
// 回复
const openReply = (target, group) => {
// 1. 设置回复的目标关系
- activeReply.groupId = group.id; // 根评论ID
- activeReply.parentId = target.id; // 直接父级ID
- activeReply.targetName = target.employee.name;
+ activeReply.groupId = target.rootId; // 根评论ID
+ activeReply.replyUserId = target.employee.userId; //回复-人的id
+ activeReply.parentId = target.parentId; // 直接父级ID
+ activeReply.targetName = target.employee.username; //回复人员的username
+ activeReply.id = target.id;
// 2. 沿用 @ 逻辑:自动在输入框插入 @某人
- const mentionStr = `@${target.employee.name} `;
+ const mentionStr = `@${target.employee.username} `;
// 如果输入框里已经有内容了,在前面追加,否则直接赋值
if (!mainInput.value.includes(mentionStr)) {
@@ -433,19 +389,42 @@ const openReply = (target, group) => {
};
// 删除回复-删除评论
-const deleteReply = (target, group) => {
- const index = group.children.findIndex((item) => item.id === target.id);
- group.children.splice(index, 1);
+const deleteReply = async (target, group) => {
+ try {
+ // 删除成功
+ await deleteComment(target.id);
+ ElMessage.success("删除成功");
+ const index = group.children.findIndex((item) => item.id === target.id);
+ if (index !== -1) {
+ group.children.splice(index, 1);
+ if (group.childrenCount > 0) {
+ group.childrenCount--;
+ }
+ }
+ // 删除后,如果子评论数量为0,则隐藏所有回复 childrenCount为0时会自动隐藏展开操作
+ if (group.childrenCount === 0) {
+ group.showAllReplies = false;
+ }
+ } catch (error) {
+ console.log("删除失败", error);
+ }
};
// 删除主评论-以及所有的子评论
-const deleteMainComment = (target) => {
- const index = commentData.value.findIndex((item) => item.id === target.id);
- if (index !== -1) {
- commentData.value.splice(index, 1);
- if (activeReply.groupId === target.id) {
- cancelReply();
+const deleteMainComment = async (target) => {
+ try {
+ await deleteComment(target.id);
+ ElMessage.success("删除成功");
+ // 前端动态操作
+ const index = commentData.value.findIndex((item) => item.id === target.id);
+ if (index !== -1) {
+ commentData.value.splice(index, 1);
+ if (activeReply.groupId === target.id) {
+ cancelReply();
+ }
}
+ } catch (error) {
+ console.log("删除失败", error);
}
};
@@ -474,17 +453,18 @@ const handleSendComment = async () => {
let rawText = mainInput.value;
if (!rawText.trim()) return ElMessage.warning("内容不能为空");
- let finalParentId = null;
+ let finalReplyId = null;
const expectedPrefix = `@${activeReply.targetName} `;
const isActuallyReply =
- activeReply.parentId && rawText.startsWith(expectedPrefix);
+ activeReply.replyUserId && rawText.startsWith(expectedPrefix);
if (isActuallyReply) {
- finalParentId = activeReply.parentId;
+ finalReplyId = activeReply.replyUserId;
rawText = rawText.slice(expectedPrefix.length);
} else {
- finalParentId = null;
+ finalReplyId = null;
}
- const type = finalParentId ? "reply" : "main"; //ui构造渲染判断
+
+ const type = finalReplyId ? "reply" : "main"; //ui构造渲染判断
// 构造 Payload
const mentionList: any[] = [];
const localCache = new Map();
@@ -513,24 +493,23 @@ const handleSendComment = async () => {
}
// 组装接口请求的参数
-
const params = {
content: rawText,
- mentions: mentionList,
- // TODO:如果是回复,带上关联 ID
- reply: {
- id: activeReply.groupId,
- name: activeReply.groupId,
- },
+ mentions: Object.keys(mentionList).length ? mentionList : null,
...props.queryParams,
};
- console.log("获取传递给后端的数据信息:", params);
+ // 回复数据复制
+ if(type === "reply"){
+ params.rootId = activeReply.groupId ? activeReply.groupId : activeReply.id;
+ params.parentId = activeReply.parentId;
+ params.replyUserId = activeReply.replyUserId;
+ }
try {
// 请求后端接口提交数据
- // const res = await api.postComment(params);
+ const res = await addReplyComment(params);
// 前端 UI 更新
- updateUIAfterSend(type, params);
+ updateUIAfterSend(type, params, res);
// 清空输入框
cancelReply();
clearSelection();
@@ -541,13 +520,18 @@ const handleSendComment = async () => {
};
// 更新当前的UI层
-const updateUIAfterSend = (type, params) => {
+const updateUIAfterSend = (type, params, response) => {
const newComment = {
- id: Date.now(), // TODO:这个地方需要替换为后端返回的真实id 用作后续的删除
+ id: response,
employee: {
...currentUser.value,
},
- reply: params.reply,
+ replyId: params.replyUserId,
+ replyUser: {
+ userId: activeReply.replyUserId,
+ username: activeReply.targetName,
+ },
+ rootId: params.groupId,
content: params.content,
mentions: params.mentionList,
createTime: new Date().valueOf(),
@@ -559,87 +543,114 @@ const updateUIAfterSend = (type, params) => {
commentData.value.unshift(newComment);
} else {
//回复某人的数据渲染
- const targetGroup = commentData.value.find((i) => i.id === params.reply.id);
+ const targetGroup = commentData.value.find(
+ (i) => i.id === params.rootId
+ ); //获取返回的数据信息
if (targetGroup) {
- newComment.replyTo = activeReply.targetName;
- if (!targetGroup.localReplies) targetGroup.localReplies = [];
- targetGroup.localReplies.unshift(newComment);
+ if (!targetGroup.children) targetGroup.children = [];
+ targetGroup.children.unshift(newComment);
+ targetGroup.childrenCount = targetGroup.children.length;
}
}
+
};
-// TODO:展开
-const MOCK_REPLIES_POOL = Array.from({ length: 20 }, (_, i) => ({
- id: 200 + i,
- content: `这是模拟的第 ${i + 1} 条回复内容,@张三 用于测试分页加载。`,
- createTime: Date.now() - i * 100000,
- mentions: [{ id: 1, name: "张三", start: 3, end: 10 }],
- employee: {
- id: 10 + i,
- name: `同事${i + 1}`,
- avatar: "",
- },
- reply: null,
-}));
-const loadReplies = async (item) => {
- if (item.loading) return;
- expandingCount.value++;
- item.loading = true;
- try {
- // 后端获取最终的数据信息
- // const res = await xxxxxx()
- // 模拟延迟
- await new Promise((resolve) => setTimeout(resolve, 800));
- const res = [];
+// 滚动加载数据
+const setupObserver = () => {
+ const observer = new IntersectionObserver(
+ (entries) => {
+ // 如果探测器进入视口,且当前没在加载,且还有更多数据
+ if (
+ entries[0].isIntersecting &&
+ !infinityLoading.value &&
+ !noMore.value
+ ) {
+ loadMainComments();
+ }
+ },
+ {
+ threshold: 0.1,
+ }
+ );
- // 模拟的数据
- const currentLength = item.children.length;
- const pageSize = 3;
- const nextBatch = MOCK_REPLIES_POOL.slice(
- currentLength,
- currentLength + pageSize
- );
- const combined = [
- ...(item.localReplies || []),
- ...res,
- ...item.children,
- ...nextBatch,
- ];
- item.children = combined.filter(
- (v, i, a) => a.findIndex((t) => t.id === v.id) === i
- );
- item.localReplies = [];
- item.showAllReplies = true;
- } catch (error) {
- console.log("error", error);
- } finally {
- item.loading = false;
- setTimeout(() => {
- expandingCount.value--;
- }, 100);
+ if (loadMoreAnchor.value) {
+ observer.observe(loadMoreAnchor.value);
}
};
-// 收起
-const collapseReplies = (item) => {
- expandingCount.value++;
- item.showAllReplies = false;
- console.log("收起数据", expandingCount.value);
- nextTick(() => {
- const el = document.getElementById(`comment-${item.id}`);
- el?.scrollIntoView({ behavior: "smooth", block: "nearest" });
-
- setTimeout(() => {
- expandingCount.value--;
- }, 300);
- });
+const nextPage = ref(1);
+const loadMainComments = async () => {
+ infinityLoading.value = true;
+ try {
+ const res = await getCommentData({ pageNo: nextPage.value });
+ const processedRecords = res.records.map(item => ({
+ ...item,
+ children: item.children || [],
+ localReplies: [],
+ loading: false,
+ showAllReplies: false,
+ currentPage: 1
+ }));
+ commentData.value = [...commentData.value,...processedRecords];
+ if (nextPage.value >= res.totalPage) {
+ noMore.value = true;
+ return;
+ }
+ } finally {
+ infinityLoading.value = false;
+ }
+};
+
+// TODO:展开 加载二级内容(包含回复)
+const PAGE_SIZE_MORE = 3;
+const handleExpand = async (item) => {
+ item.loading = true;
+ try {
+ const response = await getCommentData({
+ rootId: item.id,
+ pageNo: 1,
+ pageSize: PAGE_SIZE_MORE,
+ });
+
+ item.children = response.records; // 填充数据
+ item.showAllReplies = true;
+ item.currentPage = 1; // 记录当前页码
+ } catch (error) {
+ console.error("加载回复失败", error);
+ } finally {
+ item.loading = false;
+ }
+};
+// 加载更多的页码
+const loadMoreReplies = async (item) => {
+ item.loading = true;
+ const nextPage = (item.currentPage || 1) + 1;
+ try {
+ const res = await getCommentData({
+ rootId: item.id,
+ pageNum: nextPage,
+ pageSize: PAGE_SIZE_MORE,
+ });
+
+ // 将新数据追加到列表末尾
+ item.children = [...item.children, ...res];
+ item.currentPage = nextPage;
+ } finally {
+ item.loading = false;
+ }
+};
+// 收起
+const collapseReplies = (item) => {
+ item.showAllReplies = false;
+ item.children = []; //清空数据
+ item.currentPage = 0; //重置页码
};
-// 初始化 (骨架屏展示)
onMounted(() => {
setTimeout(() => {
loading.value = false;
- }, 500);
+ }, 300);
+ setupObserver();
});
diff --git a/src/pages/Layout/index.vue b/src/pages/Layout/index.vue
index e2d605d..2b5ea5e 100644
--- a/src/pages/Layout/index.vue
+++ b/src/pages/Layout/index.vue
@@ -37,8 +37,7 @@
-
-
+
@@ -218,6 +217,7 @@ onUnmounted(() => {
:deep(.el-main) {
--el-main-padding: 16px;
+ padding: var(--el-main-padding) calc(var(--el-main-padding) * 2);
background-color: #f8fafc;
}
diff --git a/src/pages/Login/index.vue b/src/pages/Login/index.vue
index 2a587f7..d4013d3 100644
--- a/src/pages/Login/index.vue
+++ b/src/pages/Login/index.vue
@@ -90,6 +90,7 @@ import { ElMessage, type FormInstance, type FormRules } from "element-plus";
import { login } from "@/api";
import { useUserStore } from "@/store";
import TokenManager from '@/utils/storage';
+import { Lock,Message,Right } from '@element-plus/icons-vue';
defineOptions({ name: "Login" });
@@ -113,8 +114,8 @@ const loginFormRef = ref();
const loading = ref(false);
const loginForm = reactive({
- username: "user",
- password: "password",
+ username: "18280362106",
+ password: "123456789",
remember:false
});
@@ -141,9 +142,10 @@ const handleLogin = async () => {
grant_type: 'password'
});
if (response) {
- const { access_token, refresh_token, expires_in,username,userId,avatar } = response;
+ const { access_token, refresh_token, expires_in,username,userId,avatar,nickname } = response;
const userInfo = {
username,
+ nickname,
userId,
avatar
}
@@ -167,7 +169,7 @@ const handleLogin = async () => {
}
} catch (error: any) {
console.error("Login error:", error);
- ElMessage.error(error.msg || "登录失败,请稍后重试");
+ ElMessage.error(error.error || "登录失败,请稍后重试");
} finally {
loading.value = false;
}
diff --git a/src/pages/stage/dict/dictFieldConfig.vue b/src/pages/stage/dict/dictFieldConfig.vue
index 3348e8f..6240906 100644
--- a/src/pages/stage/dict/dictFieldConfig.vue
+++ b/src/pages/stage/dict/dictFieldConfig.vue
@@ -13,7 +13,7 @@