diff --git a/src/service/api/user.ts b/src/service/api/user.ts
new file mode 100644
index 0000000..258cca6
--- /dev/null
+++ b/src/service/api/user.ts
@@ -0,0 +1,102 @@
+import { request } from '../request';
+
+// 组织列表
+export function orgListApi() {
+ return request({
+ url: '/api/organization/tree',
+ method: 'get',
+ });
+}
+// 新增组织
+export function addOrgApi(params: { label: string, parent_id: number, sort: number, is_bottom: number, org_code: string }) {
+ return request({
+ url: '/api/organization',
+ method: 'post',
+ data: params
+ });
+}
+// 编辑组织
+export function editOrgApi(id: number, params: { label: string, parent_id: number, sort: number, is_bottom: number, org_code: string }) {
+ return request({
+ url: `/api/organization/${id}`,
+ method: 'put',
+ data: params
+ });
+}
+// 删除组织
+export function deleteOrgApi(id: number) {
+ return request({
+ url: `/api/organization/${id}`,
+ method: 'delete',
+ });
+}
+
+// 获取用户列表
+export function userListApi(params: {org_id: number, keyword: string, page: number, limit: number }) {
+ return request({
+ url: '/api/user',
+ method: 'get',
+ params
+ });
+}
+
+// 新增用户
+export function addUserApi(params: { real_name: string, username: string, gender: number, mobile?: string, email?: string, dept_ids: number[], role_id: number | null, org_ids: number[], enabled: boolean }) {
+ return request({
+ url: '/api/user',
+ method: 'post',
+ data: params
+ });
+}
+
+// 编辑用户
+export function editUserApi(id: number, params: { real_name: string, username: string, gender: number, mobile?: string, email?: string, dept_ids: number[], role_id: number | null, org_ids: number[], enabled: boolean }) {
+ return request({
+ url: `/api/user/${id}`,
+ method: 'put',
+ data: params
+ });
+}
+
+// 删除用户
+export function deleteUserApi(params: { id: number, type: number }) {
+ return request({
+ url: '/api/user/operation',
+ method: 'post',
+ data: params
+ });
+}
+
+// 重置数据权限
+export function resetDataApi() {
+ return request({
+ url: `/api/user/reset-data-permission`,
+ method: 'post',
+ });
+}
+
+// 下载用户导入模板
+export function downloadTemplateApi() {
+ return request({
+ url: `/api/user/template`,
+ method: 'get',
+ responseType: 'blob',
+ });
+}
+
+// 导入用户
+export function importUserApi(params: FormData) {
+ return request({
+ url: `/api/user/import`,
+ method: 'post',
+ data: params
+ });
+}
+// 重置用户密码
+export function resetPasswordApi(id: number) {
+ return request({
+ url: `/api/user/${id}/reset-password`,
+ method: 'post',
+ });
+}
+
diff --git a/src/typings/components.d.ts b/src/typings/components.d.ts
index a8e3710..33571a6 100644
--- a/src/typings/components.d.ts
+++ b/src/typings/components.d.ts
@@ -65,7 +65,9 @@ declare module 'vue' {
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NModal: typeof import('naive-ui')['NModal']
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
+ NPagination: typeof import('naive-ui')['NPagination']
NPopconfirm: typeof import('naive-ui')['NPopconfirm']
+ NPopover: typeof import('naive-ui')['NPopover']
NProgress: typeof import('naive-ui')['NProgress']
NRadio: typeof import('naive-ui')['NRadio']
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
@@ -153,7 +155,9 @@ declare global {
const NMessageProvider: typeof import('naive-ui')['NMessageProvider']
const NModal: typeof import('naive-ui')['NModal']
const NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
+ const NPagination: typeof import('naive-ui')['NPagination']
const NPopconfirm: typeof import('naive-ui')['NPopconfirm']
+ const NPopover: typeof import('naive-ui')['NPopover']
const NProgress: typeof import('naive-ui')['NProgress']
const NRadio: typeof import('naive-ui')['NRadio']
const NRadioGroup: typeof import('naive-ui')['NRadioGroup']
diff --git a/src/utils/common.ts b/src/utils/common.ts
index 8704adf..c8843fa 100644
--- a/src/utils/common.ts
+++ b/src/utils/common.ts
@@ -95,4 +95,49 @@ export function formatTimestamp(timestamp: number | string,format: string = 'yyy
return `${year}-${month}-${day} ${hours}:${minutes}`;
}
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
-}
\ No newline at end of file
+}
+
+// 辅助函数:Fisher-Yates 洗牌算法
+function shuffle(arr:any) {
+ for (let i = arr.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [arr[i], arr[j]] = [arr[j], arr[i]];
+ }
+ return arr;
+}
+// 辅助函数:从字符串中随机获取字符
+function getRandomChar(str:any) {
+ return str[Math.floor(Math.random() * str.length)];
+}
+// 生成至少12位,包含四类字符中的至少三种的随机密码
+export function generateSecurePassword(passwordLength:number) {
+ // 定义字符池
+ const charSets:any = {
+ uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ lowercase: 'abcdefghijklmnopqrstuvwxyz',
+ numbers: '0123456789',
+ symbols: '!@#$%^&*()_+-=[]{}|;:,.<>?'
+ };
+
+ // 随机选择三种字符类型(保证至少三类)
+ const requiredTypes = shuffle(Object.keys(charSets)).slice(0, 3);
+
+ // 生成必选字符(每类至少1个)
+ let password = requiredTypes
+ .map((type:any) => getRandomChar(charSets[type]))
+ .join('');
+
+ // 生成剩余字符(允许包含所有四类)
+ const remainingLength = passwordLength - password.length;
+ const allChars = Object.values(charSets).join('');
+ for (let i = 0; i < remainingLength; i++) {
+ password += getRandomChar(allChars);
+ }
+
+ // 打乱字符顺序
+ return shuffle(password.split('')).join('');
+}
+// 获取 token
+export const getToken = () => {
+ return localStorage.getItem('token');
+};
\ No newline at end of file
diff --git a/src/utils/service.ts b/src/utils/service.ts
index 9598038..58652bd 100644
--- a/src/utils/service.ts
+++ b/src/utils/service.ts
@@ -5,6 +5,7 @@ import json5 from 'json5';
*
* @param env The current env
*/
+let url = 'http://192.168.0.230:8086';
export function createServiceConfig(env: Env.ImportMeta) {
const { VITE_SERVICE_BASE_URL, VITE_OTHER_SERVICE_BASE_URL } = env;
@@ -15,7 +16,6 @@ export function createServiceConfig(env: Env.ImportMeta) {
// eslint-disable-next-line no-console
console.error('VITE_OTHER_SERVICE_BASE_URL is not a valid json5 string');
}
- let url = 'http://192.168.0.230:8086';
if(env.DEV){
url = 'http://192.168.0.230:8086';
}else{
@@ -44,6 +44,9 @@ export function createServiceConfig(env: Env.ImportMeta) {
return config;
}
+export function getBaseUrl() {
+ return url;
+}
/**
* get backend service base url
diff --git a/src/views/systemManage/role/index.vue b/src/views/systemManage/role/index.vue
index 20e0447..7947910 100644
--- a/src/views/systemManage/role/index.vue
+++ b/src/views/systemManage/role/index.vue
@@ -4,7 +4,7 @@ import { useAppStore } from '@/store/modules/app';
import { Icon } from '@iconify/vue'
import { useThemeStore } from '@/store/modules/theme';
import { useRouter } from 'vue-router';
-import { NButton, NIcon } from 'naive-ui';
+import { NButton } from 'naive-ui';
import { roleListApi, editRoleApi } from '@/service/api/role';
const router = useRouter();
@@ -86,12 +86,11 @@ const list = ref<{ id: number, name: string, intro: string, perms: string[] }[]>
// 获取列表
const getList = async () => {
loading.value = true;
- try {
- const res = await roleListApi();
- list.value = res.data;
- } finally {
- loading.value = false;
+ const {data,error} = await roleListApi();
+ if(!error){
+ list.value = data;
}
+ loading.value = false;
}
// 设置权限
@@ -116,18 +115,16 @@ const saveRole = (e: MouseEvent) => {
formRef.value?.validate(async (errors: any) => {
if (!errors) {
btnLoading.value = true;
- try {
- await editRoleApi(currentRole.value);
+ const {error} = await editRoleApi(currentRole.value);
+ if(!error){
const target = list.value.find((item:any) => item.id === currentRole.value.id);
if (target) {
target.name = currentRole.value.name;
}
window.$message?.success('操作成功')
- btnLoading.value = false;
roleModal.value = false;
- } finally {
- btnLoading.value = false;
}
+ btnLoading.value = false;
}
})
}
@@ -135,15 +132,13 @@ const saveRole = (e: MouseEvent) => {
const savePermission = async () => {
btnLoading.value = true;
currentRole.value.perms = defaultCheckedKeys.value;
- try {
- await editRoleApi(currentRole.value);
+ const {error} = await editRoleApi(currentRole.value);
+ if(!error){
window.$message?.success('操作成功')
- btnLoading.value = false;
permissionModal.value = false;
getList();
- } finally {
- btnLoading.value = false;
}
+ btnLoading.value = false;
}
// 更新选中权限
const updateCheckedKeys = (keys: string[]) => {
diff --git a/src/views/systemManage/user/index.vue b/src/views/systemManage/user/index.vue
index 77245d0..17b3413 100644
--- a/src/views/systemManage/user/index.vue
+++ b/src/views/systemManage/user/index.vue
@@ -1,87 +1,97 @@
@@ -504,52 +634,67 @@ onMounted(() => {
+ 点击层级查看该层级全员名录;右键(或点击 ···)可编辑、添加子级、删除。 +
- 点击层级查看该层级全员名录;右键(或点击 ···)可编辑、添加子级、删除。 -
-