diff --git a/src/api/file.js b/src/api/file.js
index b018c77..3999826 100644
--- a/src/api/file.js
+++ b/src/api/file.js
@@ -12,13 +12,15 @@ export function getUserCate() {
}
/**
- * 获取所有文件
+ * 获取所有文件(支持分页、分类、关键词,与后端 query 一致)
+ * @param {Object} [params] page, pageSize, cate, keyword
* @returns {Promise}
*/
-export function getAllFiles() {
+export function getAllFiles(params = {}) {
return request({
url: "/platform/allfiles",
- method: "get",
+ method: "get",
+ params,
});
}
@@ -85,13 +87,13 @@ export function getCateFiles(id, page = 1, pageSize = 24, keyword = "") {
}
/**
- * 根据ID获取文件
- * @param {number|string} id 文件ID
+ * 根据文件 ID 获取单条文件信息(非分类列表)
+ * @param {number|string} id 文件主键 ID
* @returns {Promise}
*/
export function getFileById(id) {
return request({
- url: `/platform/catefiles`,
+ url: `/platform/file/${id}`,
method: "get",
});
}
@@ -100,12 +102,17 @@ export function getFileById(id) {
* 上传文件
* @param {FormData} formData 文件数据
* @param {Object} options 额外选项
- * @param {string} [options.cate]
+ * @param {string|number} [options.cate] 文件分组,0 为未分类
+ * @param {string|number} [options.tuid] 租户用户 yz_tenant_user.id;租户侧上传时传,平台管理员不传
* @returns {Promise}
*/
export function uploadFile(formData, options = {}) {
- if (options.cate) {
- formData.append('cate', options.cate);
+ // 0 表示「未分类」,不能用 truthy 判断
+ if (options.cate !== undefined && options.cate !== null && options.cate !== "") {
+ formData.append("cate", String(options.cate));
+ }
+ if (options.tuid !== undefined && options.tuid !== null && options.tuid !== "") {
+ formData.append("tuid", String(options.tuid));
}
return request({
@@ -151,7 +158,7 @@ export function deleteFile(id) {
*/
export function deleteFilePermanently(id) {
return request({
- url: `/platform/deleteFilePermanently/${id}`,
+ url: `/platform/deletefilepermanently/${id}`,
method: "delete",
});
}
@@ -177,7 +184,7 @@ export function moveFile(id, cate) {
*/
export function batchDeleteFiles(ids) {
return request({
- url: "/platform/batchDeleteFiles",
+ url: "/platform/batchdeletefiles",
method: "post",
data: { ids },
});
diff --git a/src/api/login.js b/src/api/login.js
index d591e4a..ae1d672 100644
--- a/src/api/login.js
+++ b/src/api/login.js
@@ -9,6 +9,14 @@ export function login(data) {
});
}
+/** 当前登录用户信息(含角色名称),需携带 token */
+export function getCurrentUser() {
+ return request({
+ url: `/platform/currentUser`,
+ method: "get",
+ });
+}
+
// 发送登录验证码(手机号)
export function sendLoginCode(data) {
return request({
diff --git a/src/api/tenantUser.js b/src/api/tenantUser.js
index 70501e5..16490b7 100644
--- a/src/api/tenantUser.js
+++ b/src/api/tenantUser.js
@@ -1,6 +1,6 @@
import request from "@/utils/request";
-// 获取租户用户列表
+/** 获取租户用户列表;params 可含 tid、uid、keyword(模糊匹配姓名/手机/邮箱/账号) */
export function getTenantUserList(params) {
return request({
url: "/platform/tenantUser/list",
@@ -9,7 +9,7 @@ export function getTenantUserList(params) {
});
}
-// 创建租户用户绑定关系
+/** 创建租户用户绑定(后端写入 yz_tenant_user) */
export function createTenantUser(data) {
return request({
url: "/platform/tenantUser/create",
diff --git a/src/components/CommonHeader.vue b/src/components/CommonHeader.vue
index f380168..a5aa63d 100644
--- a/src/components/CommonHeader.vue
+++ b/src/components/CommonHeader.vue
@@ -43,6 +43,7 @@
{{ displayName }}
+ {{ roleLabel }}
@@ -73,7 +74,7 @@ import { ref, computed, onMounted, onUnmounted } from "vue";
import { useRouter, useRoute } from "vue-router";
import { useAllDataStore, useMenuStore, useTabsStore } from "@/stores";
import { useAuthStore } from "@/stores/auth";
-import { logout } from "@/api/login";
+import { logout, getCurrentUser } from "@/api/login";
import { User, SwitchButton, Sunny, Moon, Refresh, Bell, HomeFilled } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
@@ -130,7 +131,18 @@ async function refreshCache() {
}
}
-onMounted(loadMenu);
+onMounted(async () => {
+ await loadMenu();
+ if (!authStore.token) return;
+ try {
+ const res = await getCurrentUser();
+ if (res && res.code === 200 && res.data) {
+ authStore.updateUserInfo({ ...authStore.user, ...res.data });
+ }
+ } catch (e) {
+ console.error("getCurrentUser failed", e);
+ }
+});
// 根据菜单列表和当前路径计算出的面包屑导航
const breadcrumbs = computed(() => {
@@ -179,6 +191,12 @@ const displayName = computed(() => {
return user.account || '';
});
+/** 角色展示名(来自 yz_admin_role.name) */
+const roleLabel = computed(() => {
+ const n = authStore.user?.role_name;
+ return typeof n === "string" && n.trim() ? n.trim() : "";
+});
+
const handleCollapse = () => {
store.state.isCollapse = !store.state.isCollapse;
};
@@ -424,6 +442,18 @@ onUnmounted(() => {
color: #ffffff;
}
}
+
+ .user-role-tag {
+ flex-shrink: 0;
+ margin-left: 4px;
+ font-weight: 500;
+ }
+
+ html:not(.dark) & .user-role-tag {
+ color: #ffffff;
+ border-color: rgba(255, 255, 255, 0.85);
+ background: rgba(255, 255, 255, 0.12);
+ }
}
}
diff --git a/src/router/index.js b/src/router/index.js
index 5b8cd83..a5a9037 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -15,6 +15,12 @@ const staticMainChildren = [
component: () => import("@/views/user/userProfile.vue"),
meta: { requiresAuth: true, title: "用户中心" }
},
+ {
+ path: "/system/email",
+ name: "SystemEmail",
+ component: () => import("@/views/system/email/index.vue"),
+ meta: { requiresAuth: true, title: "邮箱管理" }
+ },
// 兼容拼写错误的路径重定向
{
path: "/apps/erp/dashborad",
diff --git a/src/stores/auth.js b/src/stores/auth.js
index 9424b86..9df868e 100644
--- a/src/stores/auth.js
+++ b/src/stores/auth.js
@@ -1,13 +1,39 @@
import { defineStore } from 'pinia'
import { ref, reactive } from 'vue'
-// 用户信息类型
+// 平台登录缓存仅保留以下字段(不含 tid、group_id)
const defaultUser = {
- id:'',
+ id: '',
account: '',
name: '',
rid: '',
- avatar: ''
+ avatar: '',
+ role_name: ''
+}
+
+/**
+ * 规范化写入 localStorage 的用户信息,去掉 tid、group_id 等废弃字段;
+ * 若仅有历史 group_id,则迁移到 rid。
+ */
+function normalizePlatformUser(raw) {
+ if (!raw || typeof raw !== 'object') {
+ return { ...defaultUser }
+ }
+ let rid = raw.rid
+ if (rid === undefined || rid === null || rid === '') {
+ const legacy = raw.group_id
+ if (legacy !== undefined && legacy !== null && legacy !== '') {
+ rid = legacy
+ }
+ }
+ return {
+ id: parseInt(raw.id, 10) || null,
+ account: raw.account || '',
+ name: raw.name || '',
+ rid: rid !== undefined && rid !== null && rid !== '' ? rid : '',
+ avatar: raw.avatar || '',
+ role_name: raw.role_name || ''
+ }
}
export const useAuthStore = defineStore('auth', () => {
@@ -20,8 +46,10 @@ export const useAuthStore = defineStore('auth', () => {
const cachedUser = localStorage.getItem('userInfo')
if (cachedUser) {
try {
- const userInfo = JSON.parse(cachedUser)
- Object.assign(user, userInfo)
+ const parsed = JSON.parse(cachedUser)
+ const normalized = normalizePlatformUser(parsed)
+ Object.assign(user, normalized)
+ localStorage.setItem('userInfo', JSON.stringify(normalized))
} catch (e) {
console.error('Failed to parse user info from cache:', e)
}
@@ -34,16 +62,8 @@ export const useAuthStore = defineStore('auth', () => {
// 保存登录信息(token 和用户信息)
function setLoginInfo(loginData) {
const userInfo = loginData.user || loginData
+ const normalizedUser = normalizePlatformUser(userInfo)
- const normalizedUser = {
- id: parseInt(userInfo.id) || null,
- account: userInfo.account || '',
- name: userInfo.name || '',
- rid: userInfo.rid || userInfo.group_id || '',
- avatar: userInfo.avatar || ''
- }
-
- // 使用后端返回的真实 JWT token
const accessToken = loginData.token || ''
token.value = accessToken
@@ -65,7 +85,7 @@ export const useAuthStore = defineStore('auth', () => {
function clearToken() {
token.value = ''
isLoggedIn.value = false
- Object.assign(user, defaultUser)
+ Object.assign(user, { ...defaultUser })
localStorage.removeItem('token')
localStorage.removeItem('userInfo')
}
@@ -80,14 +100,15 @@ export const useAuthStore = defineStore('auth', () => {
} else {
token.value = ''
isLoggedIn.value = false
- Object.assign(user, defaultUser)
+ Object.assign(user, { ...defaultUser })
}
}
- // 更新用户信息
- function updateUserInfo(userInfo) {
- Object.assign(user, userInfo)
- localStorage.setItem('userInfo', JSON.stringify(userInfo))
+ // 更新用户信息(合并后仍只持久化平台字段)
+ function updateUserInfo(partial) {
+ const merged = normalizePlatformUser({ ...user, ...partial })
+ Object.assign(user, merged)
+ localStorage.setItem('userInfo', JSON.stringify(merged))
}
return {
@@ -101,4 +122,3 @@ export const useAuthStore = defineStore('auth', () => {
updateUserInfo
}
})
-
diff --git a/src/stores/menu.js b/src/stores/menu.js
index 803dec5..e368f68 100644
--- a/src/stores/menu.js
+++ b/src/stores/menu.js
@@ -21,7 +21,7 @@ export const useMenuStore = defineStore('menu', () => {
try {
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}');
const loginType = userInfo.type || 'user';
- const roleId = userInfo.group_id || 0;
+ const roleId = userInfo.rid || 0;
return `menu_cache_${loginType}_${roleId}`;
} catch (e) {
return 'menu_cache_default';
@@ -109,7 +109,7 @@ export const useMenuStore = defineStore('menu', () => {
try {
const userInfo = getUserInfo();
const loginType = userInfo.type || 'user';
- const roleId = userInfo.group_id || 0;
+ const roleId = userInfo.rid || 0;
let res;
diff --git a/src/utils/request.js b/src/utils/request.js
index 805e569..1fa43af 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -1,7 +1,7 @@
import axios from 'axios';
-// 获取API基础URL,添加调试信息
-const apiBaseURL = import.meta.env.VITE_API_BASE_URL;
+// 获取API基础URL;开发环境可在 .env.development 留空,配合 Vite 代理访问 /platform
+const apiBaseURL = import.meta.env.VITE_API_BASE_URL ?? "";
// 创建axios实例
const service = axios.create({
diff --git a/src/views/apps/babyhealth/users/components/preview.vue b/src/views/apps/babyhealth/users/components/preview.vue
index 6bc25a3..7dd05f5 100644
--- a/src/views/apps/babyhealth/users/components/preview.vue
+++ b/src/views/apps/babyhealth/users/components/preview.vue
@@ -37,8 +37,8 @@
{{ user.email || "未设置" }}
-
- {{ getRoleName(user.group_id) }}
+
+ {{ getRoleName(user.rid) }}
@@ -75,7 +75,7 @@ interface User {
qq: string;
email: string;
sex: number;
- group_id: number;
+ rid: number;
status: number;
last_login_ip: string;
login_count: number;
@@ -128,19 +128,19 @@ const fetchRoles = async () => {
};
// 获取角色tag状态
-function getRoleTagType(group_id: number): string {
+function getRoleTagType(rid: number): string {
const typeMap: Record = {
1: "primary",
2: "success",
3: "warning",
4: "danger",
};
- return typeMap[group_id] || "primary";
+ return typeMap[rid] || "primary";
}
// 获取角色名称
-function getRoleName(group_id: number): string {
- const role = roles.value.find((r) => r.id === group_id);
+function getRoleName(rid: number): string {
+ const role = roles.value.find((r) => r.id === rid);
return role?.name || "未知";
}
diff --git a/src/views/apps/babyhealth/users/index.vue b/src/views/apps/babyhealth/users/index.vue
index 57f758d..dd72994 100644
--- a/src/views/apps/babyhealth/users/index.vue
+++ b/src/views/apps/babyhealth/users/index.vue
@@ -141,7 +141,7 @@ interface User {
phone: string;
qq: string;
sex: number;
- group_id: number;
+ rid: number;
status: number;
last_login_ip: string;
email: number;
diff --git a/src/views/basicSettings/siteSettings/index.vue b/src/views/basicSettings/siteSettings/index.vue
index b18db65..d1fc30f 100644
--- a/src/views/basicSettings/siteSettings/index.vue
+++ b/src/views/basicSettings/siteSettings/index.vue
@@ -26,7 +26,7 @@
/>
-
+
diff --git a/src/views/basicSettings/tenants/components/TenantUsersTab.vue b/src/views/basicSettings/tenants/components/TenantUsersTab.vue
new file mode 100644
index 0000000..f1fcec3
--- /dev/null
+++ b/src/views/basicSettings/tenants/components/TenantUsersTab.vue
@@ -0,0 +1,244 @@
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+
+
+
+
+
+
+
+
+
+
+ {{ Number(row.status) === 1 ? "启用" : "禁用" }}
+
+
+
+
+
+
+ 修改密码
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 确定
+
+
+
+
+
+
+
+
diff --git a/src/views/basicSettings/tenants/components/adduser.vue b/src/views/basicSettings/tenants/components/adduser.vue
index 69fb358..e2f7f6a 100644
--- a/src/views/basicSettings/tenants/components/adduser.vue
+++ b/src/views/basicSettings/tenants/components/adduser.vue
@@ -37,6 +37,10 @@
-
-
\ No newline at end of file
+defineExpose({ open });
+
+
+
diff --git a/src/views/basicSettings/tenants/index.vue b/src/views/basicSettings/tenants/index.vue
index 7120969..616cdd0 100644
--- a/src/views/basicSettings/tenants/index.vue
+++ b/src/views/basicSettings/tenants/index.vue
@@ -111,14 +111,9 @@
}}
-
+
-
-
-
-
-
@@ -142,7 +137,6 @@
-