Explorar o código

后台优化及新前端基础页面实现

zuohuaijun %!s(int64=3) %!d(string=hai) anos
pai
achega
34c3e09892
Modificáronse 29 ficheiros con 368 adicións e 99 borrados
  1. 4 4
      Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj
  2. 19 12
      Admin.NET/Admin.NET.Core/Admin.NET.Core.xml
  3. 6 0
      Admin.NET/Admin.NET.Core/Enum/JobStatusEnum.cs
  4. 1 1
      Admin.NET/Admin.NET.Core/Service/CodeGen/SysCodeGenService.cs
  5. 0 1
      Admin.NET/Admin.NET.Core/Service/Role/SysRoleService.cs
  6. 5 0
      Admin.NET/Admin.NET.Core/Service/User/Dto/UserInput.cs
  7. 1 1
      Admin.NET/Admin.NET.Core/Service/User/Dto/UserOrgInput.cs
  8. 0 15
      Admin.NET/Admin.NET.Core/Service/User/Dto/UserOutput.cs
  9. 1 1
      Admin.NET/Admin.NET.Core/Service/User/Dto/UserRoleInput.cs
  10. 23 2
      Admin.NET/Admin.NET.Core/Service/User/SysUserService.cs
  11. 6 0
      vue-next-admin/src/api-services/models/add-role-input.ts
  12. 6 0
      vue-next-admin/src/api-services/models/add-user-input.ts
  13. 6 0
      vue-next-admin/src/api-services/models/update-role-input.ts
  14. 6 0
      vue-next-admin/src/api-services/models/update-user-input.ts
  15. 1 1
      vue-next-admin/src/api-services/models/user-org-input.ts
  16. 1 1
      vue-next-admin/src/api-services/models/user-role-input.ts
  17. 2 2
      vue-next-admin/src/views/system/menu/component/editMenu.vue
  18. 7 9
      vue-next-admin/src/views/system/menu/index.vue
  19. 2 2
      vue-next-admin/src/views/system/org/component/editOrg.vue
  20. 19 3
      vue-next-admin/src/views/system/org/component/orgTree.vue
  21. 7 11
      vue-next-admin/src/views/system/org/index.vue
  22. 1 1
      vue-next-admin/src/views/system/pos/component/editPos.vue
  23. 7 9
      vue-next-admin/src/views/system/pos/index.vue
  24. 1 1
      vue-next-admin/src/views/system/role/component/editRole.vue
  25. 77 0
      vue-next-admin/src/views/system/role/component/grantData.vue
  26. 5 7
      vue-next-admin/src/views/system/role/index.vue
  27. 30 7
      vue-next-admin/src/views/system/user/component/editUser.vue
  28. 77 0
      vue-next-admin/src/views/system/user/component/grantOrg.vue
  29. 47 8
      vue-next-admin/src/views/system/user/index.vue

+ 4 - 4
Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj

@@ -24,12 +24,12 @@
 
   <ItemGroup>
     <PackageReference Include="AspNetCoreRateLimit" Version="4.0.2" />
-    <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.6.1" />
-    <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.6.1" />
-    <PackageReference Include="Furion.Pure" Version="4.6.1" />
+    <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.6.2" />
+    <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.6.2" />
+    <PackageReference Include="Furion.Pure" Version="4.6.2" />
     <PackageReference Include="Magicodes.IE.Excel" Version="2.6.4" />
     <PackageReference Include="Magicodes.IE.Pdf" Version="2.6.4" />
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.9" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.10" />
     <PackageReference Include="NEST" Version="7.17.4" />
     <PackageReference Include="NETCore.MailKit" Version="2.1.0" />
     <PackageReference Include="NewLife.Redis" Version="5.0.2022.901" />

+ 19 - 12
Admin.NET/Admin.NET.Core/Admin.NET.Core.xml

@@ -2331,6 +2331,11 @@
             请假
             </summary>
         </member>
+        <member name="F:Admin.NET.Core.JobStatusEnum.Other">
+            <summary>
+            其他
+            </summary>
+        </member>
         <member name="T:Admin.NET.Core.LoginTypeEnum">
             <summary>
             登录类型枚举
@@ -6616,6 +6621,11 @@
             账号密码
             </summary>
         </member>
+        <member name="P:Admin.NET.Core.Service.AddUserInput.RoleIdList">
+            <summary>
+            角色Id集合
+            </summary>
+        </member>
         <member name="P:Admin.NET.Core.Service.DeleteUserInput.OrgId">
             <summary>
             机构Id
@@ -6643,17 +6653,7 @@
         </member>
         <member name="P:Admin.NET.Core.Service.UserOrgInput.OrgIdList">
             <summary>
-            机构Id列表
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.Service.UserOutput.OrgName">
-            <summary>
-            机构名称
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.Service.UserOutput.PosName">
-            <summary>
-            职位名称
+            机构Id集合
             </summary>
         </member>
         <member name="T:Admin.NET.Core.Service.UserRoleInput">
@@ -6668,7 +6668,7 @@
         </member>
         <member name="P:Admin.NET.Core.Service.UserRoleInput.RoleIdList">
             <summary>
-            角色Id列表
+            角色Id集合
             </summary>
         </member>
         <member name="T:Admin.NET.Core.Service.SysUserExtOrgPosService">
@@ -6810,6 +6810,13 @@
             <param name="input"></param>
             <returns></returns>
         </member>
+        <member name="M:Admin.NET.Core.Service.SysUserService.UpdateUserRole(Admin.NET.Core.Service.AddUserInput)">
+            <summary>
+            更新用户角色
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
         <member name="M:Admin.NET.Core.Service.SysUserService.UpdateUser(Admin.NET.Core.Service.UpdateUserInput)">
             <summary>
             更新用户

+ 6 - 0
Admin.NET/Admin.NET.Core/Enum/JobStatusEnum.cs

@@ -22,4 +22,10 @@ public enum JobStatusEnum
     /// </summary>
     [Description("请假")]
     Leave = 3,
+
+    /// <summary>
+    /// 其他
+    /// </summary>
+    [Description("其他")]
+    Other = 4,
 }

+ 1 - 1
Admin.NET/Admin.NET.Core/Service/CodeGen/SysCodeGenService.cs

@@ -316,7 +316,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
             Path = "/" + className.ToLower(),
             Component = "/main/" + className + "/index",
         };
-        {//如果之前存在那么就删除本级和下级
+        {   // 如果之前存在那么就删除本级和下级
             var list = await _db.Queryable<SysMenu>().Where(e => e.Title == menuType1.Title && e.Type == menuType1.Type).ToListAsync();
             if (list.Count > 0)
             {

+ 0 - 1
Admin.NET/Admin.NET.Core/Service/Role/SysRoleService.cs

@@ -86,7 +86,6 @@ public class SysRoleService : IDynamicApiController, ITransient
     /// <returns></returns>
     private async Task UpdateRoleMenu(AddRoleInput input)
     {
-        // 更新角色菜单权限集合
         if (input.MenuIdList == null || input.MenuIdList.Count < 1)
             return;
         await GrantRoleMenu(new RoleMenuInput()

+ 5 - 0
Admin.NET/Admin.NET.Core/Service/User/Dto/UserInput.cs

@@ -45,6 +45,11 @@ public class AddUserInput : SysUser
     /// 账号密码
     /// </summary>
     public override string Password { get; set; } = CommonConst.SysPassword;
+
+    /// <summary>
+    /// 角色Id集合
+    /// </summary>
+    public List<long> RoleIdList { get; set; }
 }
 
 [NotTable]

+ 1 - 1
Admin.NET/Admin.NET.Core/Service/User/Dto/UserOrgInput.cs

@@ -11,7 +11,7 @@ public class UserOrgInput : BaseIdInput
     public long OrgId { get; set; }
 
     /// <summary>
-    /// 机构Id列表
+    /// 机构Id集合
     /// </summary>
     public List<long> OrgIdList { get; set; }
 }

+ 0 - 15
Admin.NET/Admin.NET.Core/Service/User/Dto/UserOutput.cs

@@ -1,15 +0,0 @@
-namespace Admin.NET.Core.Service;
-
-[NotTable]
-public class UserOutput : SysUser
-{
-    /// <summary>
-    /// 机构名称
-    /// </summary>
-    public string OrgName { get; set; }
-
-    /// <summary>
-    /// 职位名称
-    /// </summary>
-    public string PosName { get; set; }
-}

+ 1 - 1
Admin.NET/Admin.NET.Core/Service/User/Dto/UserRoleInput.cs

@@ -11,7 +11,7 @@ public class UserRoleInput : BaseIdInput
     public long OrgId { get; set; }
 
     /// <summary>
-    /// 角色Id列表
+    /// 角色Id集合
     /// </summary>
     public List<long> RoleIdList { get; set; }
 }

+ 23 - 2
Admin.NET/Admin.NET.Core/Service/User/SysUserService.cs

@@ -66,7 +66,26 @@ public class SysUserService : IDynamicApiController, ITransient
 
         var user = input.Adapt<SysUser>();
         user.Password = MD5Encryption.Encrypt(CommonConst.SysPassword);
-        await _sysUserRep.InsertAsync(user);
+        input.Id = (await _sysUserRep.AsInsertable(user).ExecuteReturnEntityAsync()).Id;
+
+        await UpdateUserRole(input);
+    }
+
+    /// <summary>
+    /// 更新用户角色
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    private async Task UpdateUserRole(AddUserInput input)
+    {
+        if (input.RoleIdList == null || input.RoleIdList.Count < 1)
+            return;
+        await GrantUserRole(new UserRoleInput()
+        {
+            Id = input.Id,
+            OrgId = input.OrgId,
+            RoleIdList = input.RoleIdList
+        });
     }
 
     /// <summary>
@@ -84,6 +103,8 @@ public class SysUserService : IDynamicApiController, ITransient
 
         await _sysUserRep.AsUpdateable(input.Adapt<SysUser>()).IgnoreColumns(true)
             .IgnoreColumns(u => new { u.UserType, u.Password, u.Status }).ExecuteCommandAsync();
+
+        await UpdateUserRole(input);
     }
 
     /// <summary>
@@ -143,7 +164,7 @@ public class SysUserService : IDynamicApiController, ITransient
         if (!Enum.IsDefined(typeof(StatusEnum), input.Status))
             throw Oops.Oh(ErrorCodeEnum.D3005);
 
-        user.Status = (StatusEnum)input.Status;
+        user.Status = input.Status;
         return await _sysUserRep.AsUpdateable(user)
             .UpdateColumns(u => new { u.Status }).ExecuteCommandAsync();
     }

+ 6 - 0
vue-next-admin/src/api-services/models/add-role-input.ts

@@ -97,4 +97,10 @@ export interface AddRoleInput {
      * @memberof AddRoleInput
      */
     name: string;
+    /**
+     * 菜单Id集合
+     * @type {Array<number>}
+     * @memberof AddRoleInput
+     */
+    menuIdList?: Array<number> | null;
 }

+ 6 - 0
vue-next-admin/src/api-services/models/add-user-input.ts

@@ -191,4 +191,10 @@ export interface AddUserInput {
      * @memberof AddUserInput
      */
     realName: string;
+    /**
+     * 角色Id集合
+     * @type {Array<number>}
+     * @memberof AddUserInput
+     */
+    roleIdList?: Array<number> | null;
 }

+ 6 - 0
vue-next-admin/src/api-services/models/update-role-input.ts

@@ -97,4 +97,10 @@ export interface UpdateRoleInput {
      * @memberof UpdateRoleInput
      */
     name: string;
+    /**
+     * 菜单Id集合
+     * @type {Array<number>}
+     * @memberof UpdateRoleInput
+     */
+    menuIdList?: Array<number> | null;
 }

+ 6 - 0
vue-next-admin/src/api-services/models/update-user-input.ts

@@ -191,4 +191,10 @@ export interface UpdateUserInput {
      * @memberof UpdateUserInput
      */
     realName: string;
+    /**
+     * 角色Id集合
+     * @type {Array<number>}
+     * @memberof UpdateUserInput
+     */
+    roleIdList?: Array<number> | null;
 }

+ 1 - 1
vue-next-admin/src/api-services/models/user-org-input.ts

@@ -30,7 +30,7 @@ export interface UserOrgInput {
      */
     orgId?: number;
     /**
-     * 机构Id列表
+     * 机构Id集合
      * @type {Array<number>}
      * @memberof UserOrgInput
      */

+ 1 - 1
vue-next-admin/src/api-services/models/user-role-input.ts

@@ -30,7 +30,7 @@ export interface UserRoleInput {
      */
     orgId?: number;
     /**
-     * 角色Id列表
+     * 角色Id集合
      * @type {Array<number>}
      * @memberof UserRoleInput
      */

+ 2 - 2
vue-next-admin/src/views/system/menu/component/editMenu.vue

@@ -185,7 +185,7 @@ export default defineComponent({
 				isAffix: false, // 是否固定
 				outLink: '', // 外链/内嵌时链接地址
 				isIframe: false, // 是否内嵌
-				order: 10, // 排序
+				order: 100, // 排序
 				status: 1, // 是否启用
 				remark: '', // 备注
 			},
@@ -214,7 +214,7 @@ export default defineComponent({
 			const formWrap = unref(ruleFormRef) as any;
 			if (!formWrap) return;
 
-			// 取父节点Id
+			// 上级菜单Id
 			if (Array.isArray(state.ruleForm.pid))
 				state.ruleForm.pid = state.ruleForm.pid[state.ruleForm.pid.length - 1];
 			formWrap.validate(async () => {

+ 7 - 9
vue-next-admin/src/views/system/menu/index.vue

@@ -62,16 +62,14 @@
         </el-table-column>
         <el-table-column prop="createTime" label="修改时间" align="center" show-overflow-tooltip>
         </el-table-column>
-        <el-table-column label="操作" width="80" fixed="right" align="center" show-overflow-tooltip>
+        <el-table-column label="操作" width="140" fixed="right" align="center" show-overflow-tooltip>
           <template #default="scope">
-            <el-tooltip content="菜单编辑">
-              <el-button icon="ele-Edit" size="small" text type="primary" @click="openEditMenu(scope.row)">
-              </el-button>
-            </el-tooltip>
-            <el-tooltip content="菜单删除">
-              <el-button icon="ele-Delete" size="small" text type="primary" @click="delMenu(scope.row)">
-              </el-button>
-            </el-tooltip>
+            <el-button icon="ele-Edit" size="small" text type="primary" @click="openEditMenu(scope.row)">
+              编辑
+            </el-button>
+            <el-button icon="ele-Delete" size="small" text type="primary" @click="delMenu(scope.row)">
+              删除
+            </el-button>
           </template>
         </el-table-column>
       </el-table>

+ 2 - 2
vue-next-admin/src/views/system/org/component/editOrg.vue

@@ -91,7 +91,7 @@ export default defineComponent({
 				pid: 0, // 父节点Id
 				name: '', // 机构名称
 				code: '', // 机构编码
-				order: 10, // 排序
+				order: 100, // 排序
 				status: 1, // 是否启用
 				remark: '', // 备注
 			},
@@ -119,7 +119,7 @@ export default defineComponent({
 			const formWrap = unref(ruleFormRef) as any;
 			if (!formWrap) return;
 
-			// 取父节点Id
+			// 上级机构Id
 			if (Array.isArray(state.ruleForm.pid))
 				state.ruleForm.pid = state.ruleForm.pid[state.ruleForm.pid.length - 1];
 			formWrap.validate(async () => {

+ 19 - 3
vue-next-admin/src/views/system/org/component/orgTree.vue

@@ -27,8 +27,9 @@
       </div>
     </template>
     <div style="margin-bottom: 45px" v-loading="state.loading">
-      <el-tree ref='treeRef' class='filter-tree' :data='state.orgData' :props="{children: 'children', label: 'name'}"
-        :filter-node-method='filterNode' @node-click="nodeClick" />
+      <el-tree ref='treeRef' class='filter-tree' :data='state.orgData' node-key="id"
+        :props="{children: 'children', label: 'name'}" :filter-node-method='filterNode' @node-click="nodeClick"
+        :show-checkbox="state.isShowCheckbox" :default-checked-keys="state.ownOrgData" highlight-current />
     </div>
   </el-card>
 </template>
@@ -47,6 +48,8 @@ const treeRef = ref<InstanceType<typeof ElTree>>();
 const state = reactive({
   loading: true,
   orgData: [] as any,
+  isShowCheckbox: false,
+  ownOrgData: [],
 });
 
 onMounted(() => {
@@ -64,6 +67,19 @@ const initTreeData = async () => {
   state.loading = false;
 };
 
+// 设置默认选择
+const setCheckedKeys = (orgData: any) => {
+  console.log("设置选择")
+  state.isShowCheckbox = true;
+  treeRef.value!.setCheckedKeys([]);
+  state.ownOrgData = orgData;
+};
+
+// 获取已经选择
+const getCheckedKeys = () => {
+  return treeRef.value!.getCheckedKeys();
+};
+
 const filterNode = (value: string, data: any) => {
   if (!value) return true;
   return data.name.includes(value);
@@ -93,7 +109,7 @@ const nodeClick = (node: any) => {
 
 const orgTreeData = state.orgData; // 异步数据导出不了?
 // 导出
-defineExpose({ orgTreeData });
+defineExpose({ orgTreeData, setCheckedKeys, getCheckedKeys });
 </script>
 
 <style scoped>

+ 7 - 11
vue-next-admin/src/views/system/org/index.vue

@@ -55,18 +55,14 @@
 						<el-table-column prop="createTime" label="修改时间" align="center" show-overflow-tooltip>
 						</el-table-column>
 						<el-table-column prop="remark" label="备注" show-overflow-tooltip></el-table-column>
-						<el-table-column label="操作" width="80" fixed="right" align="center" show-overflow-tooltip>
+						<el-table-column label="操作" width="140" fixed="right" align="center" show-overflow-tooltip>
 							<template #default="scope">
-								<el-tooltip content="机构编辑">
-									<el-button icon="ele-Edit" size="small" text type="primary"
-										@click="openEditOrg(scope.row)">
-									</el-button>
-								</el-tooltip>
-								<el-tooltip content="机构删除">
-									<el-button icon="ele-Delete" size="small" text type="primary"
-										@click="delOrg(scope.row)">
-									</el-button>
-								</el-tooltip>
+								<el-button icon="ele-Edit" size="small" text type="primary"
+									@click="openEditOrg(scope.row)">编辑
+								</el-button>
+								<el-button icon="ele-Delete" size="small" text type="primary"
+									@click="delOrg(scope.row)">删除
+								</el-button>
 							</template>
 						</el-table-column>
 					</el-table>

+ 1 - 1
vue-next-admin/src/views/system/pos/component/editPos.vue

@@ -74,7 +74,7 @@ export default defineComponent({
 				id: 0, // Id
 				name: '', // 职位名称
 				code: '', // 职位编码
-				order: 10, // 排序
+				order: 100, // 排序
 				status: 1, // 是否启用
 				remark: '', // 备注
 			},

+ 7 - 9
vue-next-admin/src/views/system/pos/index.vue

@@ -46,16 +46,14 @@
 				</el-table-column>
 				<el-table-column prop="createTime" label="修改时间" align="center" show-overflow-tooltip></el-table-column>
 				<el-table-column prop="remark" label="备注" show-overflow-tooltip></el-table-column>
-				<el-table-column label="操作" width="80" fixed="right" align="center" show-overflow-tooltip>
+				<el-table-column label="操作" width="140" fixed="right" align="center" show-overflow-tooltip>
 					<template #default="scope">
-						<el-tooltip content="职位编辑">
-							<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditPos(scope.row)">
-							</el-button>
-						</el-tooltip>
-						<el-tooltip content="职位删除">
-							<el-button icon="ele-Delete" size="small" text type="primary" @click="delPos(scope.row)">
-							</el-button>
-						</el-tooltip>
+						<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditPos(scope.row)">
+							编辑
+						</el-button>
+						<el-button icon="ele-Delete" size="small" text type="primary" @click="delPos(scope.row)">
+							删除
+						</el-button>
 					</template>
 				</el-table-column>
 			</el-table>

+ 1 - 1
vue-next-admin/src/views/system/role/component/editRole.vue

@@ -92,7 +92,7 @@ export default defineComponent({
 				id: 0, // Id
 				name: '', // 角色名称
 				code: '', // 角色编码
-				order: 10, // 排序
+				order: 100, // 排序
 				status: 1, // 是否启用
 				remark: '', // 备注
 				menuIdList: [] as any, // 菜单权限

+ 77 - 0
vue-next-admin/src/views/system/role/component/grantData.vue

@@ -0,0 +1,77 @@
+<template>
+	<div class="sys-grantOrg-container">
+		<el-dialog v-model="isShowDialog" width="450px">
+			<template #header>
+				<div style="font-size: large" v-drag="['.el-dialog','.el-dialog__header']">
+					授权数据范围
+				</div>
+			</template>
+			<el-form :model="ruleForm" size="default" label-width="80px">
+				<el-row :gutter="35">
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl1="24">
+						<el-form-item prop="orgIdList">
+							<OrgTree ref="orgTreeRef" />
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="cancel" size="default">取 消</el-button>
+					<el-button type="primary" @click="submit" size="default">确 定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, defineComponent, ref } from 'vue';
+import OrgTree from '/@/views/system/org/component/orgTree.vue';
+
+import { getAPI } from '/@/utils/axios-utils';
+import { SysUserApi } from '/@/api-services/api';
+
+export default defineComponent({
+	name: 'sysGrantData',
+	components: { OrgTree },
+	setup() {
+		const orgTreeRef = ref();
+		const state = reactive({
+			isShowDialog: false,
+			ruleForm: {
+				id: 0,
+				org: 0, // 用户所属机构
+				orgIdList: [] as any, // 机构集合
+			},
+		});
+		// 打开弹窗
+		const openDialog = async (row: any) => {
+			state.ruleForm = row;
+			var res = await getAPI(SysUserApi).sysUserOwnOrgGet(row.id);
+			setTimeout(() => { // 延迟传递数据
+				orgTreeRef.value?.setCheckedKeys(res.data.result);
+			}, 100);
+			state.isShowDialog = true;
+		};
+		// 取消
+		const cancel = () => {
+			state.isShowDialog = false;
+		};
+		// 提交
+		const submit = async () => {
+			state.ruleForm.orgIdList = orgTreeRef.value?.getCheckedKeys();
+			await getAPI(SysUserApi).sysUserGrantOrgPost(state.ruleForm);
+			state.isShowDialog = false;
+		};
+		return {
+			orgTreeRef,
+			openDialog,
+			cancel,
+			submit,
+			...toRefs(state),
+		};
+	},
+});
+</script>
+	

+ 5 - 7
vue-next-admin/src/views/system/role/index.vue

@@ -47,15 +47,13 @@
 				</el-table-column>
 				<el-table-column prop="createTime" label="修改时间" align="center" show-overflow-tooltip></el-table-column>
 				<el-table-column prop="remark" label="备注" show-overflow-tooltip></el-table-column>
-				<el-table-column label="操作" width="80" fixed="right" align="center" show-overflow-tooltip>
+				<el-table-column label="操作" width="110" fixed="right" align="center" show-overflow-tooltip>
 					<template #default="scope">
-						<el-tooltip content="角色编辑">
-							<el-button icon="ele-Edit" size="small" text type="primary"
-								@click="openEditRole(scope.row)">
-							</el-button>
-						</el-tooltip>
+						<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditRole(scope.row)">
+							编辑
+						</el-button>
 						<el-dropdown>
-							<span style="color: var(--el-color-primary);padding-top: 6px;">
+							<span style="color: var(--el-color-primary);padding-top: 6px;padding-left: 12px;">
 								<el-icon>
 									<ele-MoreFilled />
 								</el-icon>

+ 30 - 7
vue-next-admin/src/views/system/user/component/editUser.vue

@@ -52,6 +52,15 @@
 							<el-input v-model="ruleForm.email" placeholder="邮箱" clearable></el-input>
 						</el-form-item>
 					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="角色" prop="roleIdList">
+							<el-select v-model="ruleForm.roleIdList" multiple value-key="id" clearable
+								placeholder="拥有角色" collapse-tags collapse-tags-tooltip class="w100" filterable>
+								<el-option v-for="item in roleData" :key="item.id" :label="item.name"
+									:value="item.id" />
+							</el-select>
+						</el-form-item>
+					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb5">
 						<el-form-item label="排序">
 							<el-input-number v-model="ruleForm.order" placeholder="排序" class="w100" />
@@ -61,7 +70,7 @@
 						<div style="color: #b1b3b8">其他</div>
 					</el-divider>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
-						<el-form-item label="所属机构">
+						<el-form-item label="所属机构" prop="orgId">
 							<el-cascader :options="orgData" :props="{ checkStrictly: true, value: 'id', label: 'name' }"
 								placeholder="所属机构" clearable class="w100" v-model="ruleForm.orgId">
 								<template #default="{ node, data }">
@@ -123,7 +132,7 @@
 import { reactive, toRefs, defineComponent, getCurrentInstance, ref, unref, onMounted } from 'vue';
 
 import { getAPI } from '/@/utils/axios-utils';
-import { SysPosApi, SysUserApi } from '/@/api-services/api';
+import { SysPosApi, SysRoleApi, SysUserApi } from '/@/api-services/api';
 
 export default defineComponent({
 	name: 'sysEditUser',
@@ -161,25 +170,39 @@ export default defineComponent({
 				jobStatus: 1,
 				signature: '',
 				introduction: '',
-				order: 10, // 排序
+				order: 100, // 排序
 				remark: '', // 备注
+				roleIdList: [] as any, // 角色
 			},
-			jobStatusType: [{ value: 1, label: "在职" }, { value: 2, label: "离职" }, { value: 3, label: "请假" }], // 岗位状态
+			jobStatusType: [{ value: 1, label: "在职" }, { value: 2, label: "离职" }, { value: 3, label: "请假" }, { value: 4, label: "其他" }], // 岗位状态
 			posData: [] as any, // 职位数据
+			roleData: [] as any, // 角色数据
 			ruleRules: {
 				userName: [{ required: true, message: "账号名称不能为空", trigger: "blur" }],
 				phone: [{ required: true, message: "手机号码不能为空", trigger: "blur" }],
 				realName: [{ required: true, message: "真实姓名不能为空", trigger: "blur" }],
+				birthday: [{ required: true, message: "出生日期不能为空", trigger: "blur" }],
+				roleIdList: [{ required: true, message: "拥有角色不能为空", trigger: "blur" }],
+				orgId: [{ required: true, message: "所属机构不能为空", trigger: "blur" }],
+				posId: [{ required: true, message: "职位名称不能为空", trigger: "blur" }],
 			},
 		});
 		onMounted(async () => {
 			var res = await getAPI(SysPosApi).sysPosListGet();
 			state.posData = res.data.result;
+			var res1 = await getAPI(SysRoleApi).sysRoleListGet();
+			state.roleData = res1.data.result;
 		});
 		// 打开弹窗
-		const openDialog = (row: any) => {
+		const openDialog = async (row: any) => {
 			state.ruleForm = row;
-			state.isShowDialog = true;
+			if (JSON.stringify(row) !== "{}") {
+				var res = await getAPI(SysUserApi).sysUserOwnRoleGet(row.id);
+				state.ruleForm.roleIdList = res.data.result;
+				state.isShowDialog = true;
+			}
+			else
+				state.isShowDialog = true;
 		};
 		// 关闭弹窗
 		const closeDialog = () => {
@@ -195,7 +218,7 @@ export default defineComponent({
 			const formWrap = unref(ruleFormRef) as any;
 			if (!formWrap) return;
 
-			// 取父节点Id
+			// 所属机构Id
 			if (Array.isArray(state.ruleForm.orgId))
 				state.ruleForm.orgId = state.ruleForm.orgId[state.ruleForm.orgId.length - 1];
 			formWrap.validate(async () => {

+ 77 - 0
vue-next-admin/src/views/system/user/component/grantOrg.vue

@@ -0,0 +1,77 @@
+<template>
+	<div class="sys-grantOrg-container">
+		<el-dialog v-model="isShowDialog" width="450px">
+			<template #header>
+				<div style="font-size: large" v-drag="['.el-dialog','.el-dialog__header']">
+					授权数据范围
+				</div>
+			</template>
+			<el-form :model="ruleForm" size="default" label-width="80px">
+				<el-row :gutter="35">
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl1="24">
+						<el-form-item prop="orgIdList">
+							<OrgTree ref="orgTreeRef" />
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="cancel" size="default">取 消</el-button>
+					<el-button type="primary" @click="submit" size="default">确 定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, defineComponent, ref } from 'vue';
+import OrgTree from '/@/views/system/org/component/orgTree.vue';
+
+import { getAPI } from '/@/utils/axios-utils';
+import { SysUserApi } from '/@/api-services/api';
+
+export default defineComponent({
+	name: 'sysGrantOrg',
+	components: { OrgTree },
+	setup() {
+		const orgTreeRef = ref();
+		const state = reactive({
+			isShowDialog: false,
+			ruleForm: {
+				id: 0,
+				org: 0, // 用户所属机构
+				orgIdList: [] as any, // 机构集合
+			},
+		});
+		// 打开弹窗
+		const openDialog = async (row: any) => {
+			state.ruleForm = row;
+			var res = await getAPI(SysUserApi).sysUserOwnOrgGet(row.id);
+			setTimeout(() => { // 延迟传递数据
+				orgTreeRef.value?.setCheckedKeys(res.data.result);
+			}, 100);
+			state.isShowDialog = true;
+		};
+		// 取消
+		const cancel = () => {
+			state.isShowDialog = false;
+		};
+		// 提交
+		const submit = async () => {
+			state.ruleForm.orgIdList = orgTreeRef.value?.getCheckedKeys();
+			await getAPI(SysUserApi).sysUserGrantOrgPost(state.ruleForm);
+			state.isShowDialog = false;
+		};
+		return {
+			orgTreeRef,
+			openDialog,
+			cancel,
+			submit,
+			...toRefs(state),
+		};
+	},
+});
+</script>
+	

+ 47 - 8
vue-next-admin/src/views/system/user/index.vue

@@ -78,18 +78,34 @@
 						<el-table-column prop="createTime" label="修改时间" width="160" show-overflow-tooltip>
 						</el-table-column>
 						<el-table-column prop="remark" label="备注" width="200" show-overflow-tooltip></el-table-column>
-						<el-table-column label="操作" width="80" align="center" fixed="right" show-overflow-tooltip>
+						<el-table-column label="操作" width="110" align="center" fixed="right" show-overflow-tooltip>
 							<template #default="scope">
 								<el-tooltip content="用户编辑">
 									<el-button icon="ele-Edit" size="small" text type="primary"
-										@click="openEditUser(scope.row)">
-									</el-button>
-								</el-tooltip>
-								<el-tooltip content="用户删除">
-									<el-button icon="ele-Delete" size="small" text type="primary"
-										@click="delUser(scope.row)">
+										@click="openEditUser(scope.row)">编辑
 									</el-button>
 								</el-tooltip>
+								<el-dropdown>
+									<span style="color: var(--el-color-primary);padding-top: 6px;padding-left: 12px;">
+										<el-icon>
+											<ele-MoreFilled />
+										</el-icon>
+									</span>
+									<template #dropdown>
+										<el-dropdown-menu>
+											<el-dropdown-item icon="ele-OfficeBuilding"
+												@click="openGrantOrg(scope.row)">
+												数据范围
+											</el-dropdown-item>
+											<el-dropdown-item icon="ele-RefreshLeft" @click="resetUserPwd(scope.row)">
+												重置密码
+											</el-dropdown-item>
+											<el-dropdown-item icon="ele-Delete" @click="delUser(scope.row)">
+												删除账号
+											</el-dropdown-item>
+										</el-dropdown-menu>
+									</template>
+								</el-dropdown>
 							</template>
 						</el-table-column>
 					</el-table>
@@ -101,6 +117,7 @@
 			</el-col>
 		</el-row>
 		<EditUser ref="editUserRef" :title="editUserTitle" :orgData="orgTreeData" />
+		<GrantOrg ref="grantOrgRef" />
 	</div>
 </template>
 
@@ -110,17 +127,19 @@ import { ElMessageBox, ElMessage } from 'element-plus';
 import { formatDate } from '/@/utils/formatTime';
 import OrgTree from '/@/views/system/org/component/orgTree.vue';
 import EditUser from '/@/views/system/user/component/editUser.vue';
+import GrantOrg from '/@/views/system/user/component/grantOrg.vue';
 
 import { getAPI } from '/@/utils/axios-utils';
 import { SysUserApi, SysOrgApi } from '/@/api-services/api';
 
 export default defineComponent({
 	name: 'sysUser',
-	components: { OrgTree, EditUser },
+	components: { OrgTree, EditUser, GrantOrg },
 	setup() {
 		const { proxy } = getCurrentInstance() as any;
 		const orgTreeRef = ref()
 		const editUserRef = ref();
+		const grantOrgRef = ref();
 		const state = reactive({
 			loading: true,
 			userData: [] as any,
@@ -210,6 +229,23 @@ export default defineComponent({
 		const changeStatus = async (row: any) => {
 			await getAPI(SysUserApi).sysUserSetStatusPost({ id: row.id, status: row.status });
 		}
+		// 打开授权数据范围页面
+		const openGrantOrg = (row: any) => {
+			grantOrgRef.value.openDialog(row);
+		};
+		// 重置密码
+		const resetUserPwd = async (row: any) => {
+			ElMessageBox.confirm(`确定重置密码:【${row.userName}】?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning',
+			})
+				.then(async () => {
+					await getAPI(SysUserApi).sysUserResetPwdPost({ id: row.id });
+					ElMessage.success('密码重置成功:123456');
+				})
+				.catch(() => { });
+		}
 		// 树组件点击
 		const nodeClick = async (node: any) => {
 			state.queryParams.orgId = node.id;
@@ -222,12 +258,15 @@ export default defineComponent({
 			resetQuery,
 			orgTreeRef,
 			editUserRef,
+			grantOrgRef,
 			openAddUser,
 			openEditUser,
 			delUser,
 			handleSizeChange,
 			handleCurrentChange,
 			changeStatus,
+			openGrantOrg,
+			resetUserPwd,
 			nodeClick,
 			formatDate,
 			...toRefs(state),