Просмотр исходного кода

😁账号编辑增加账号类型处理

zuohuaijun 2 лет назад
Родитель
Сommit
faabef4409

+ 5 - 0
Admin.NET/Admin.NET.Core/Service/Auth/Dto/LoginUserOutput.cs

@@ -29,6 +29,11 @@ public class LoginUserOutput
     /// </summary>
     public string RealName { get; set; }
 
+    /// <summary>
+    /// 账号类型
+    /// </summary>
+    public AccountTypeEnum AccountType { get; set; } = AccountTypeEnum.NormalUser;
+
     /// <summary>
     /// 头像
     /// </summary>

+ 2 - 0
Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs

@@ -9,6 +9,7 @@
 
 using Furion.SpecificationDocument;
 using Lazy.Captcha.Core;
+using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinExpressBusinessAccountGetAllResponse.Types;
 
 namespace Admin.NET.Core.Service;
 
@@ -179,6 +180,7 @@ public class SysAuthService : IDynamicApiController, ITransient
             Id = user.Id,
             Account = user.Account,
             RealName = user.RealName,
+            AccountType = user.AccountType,
             Avatar = user.Avatar,
             Address = user.Address,
             Signature = user.Signature,

+ 2 - 0
Admin.NET/Admin.NET.Core/Service/Config/SysConfigService.cs

@@ -144,6 +144,8 @@ public class SysConfigService : IDynamicApiController, ITransient
     [NonAction]
     public async Task<T> GetConfigValue<T>(string code)
     {
+        if (string.IsNullOrWhiteSpace(code)) return default;
+
         var value = _sysCacheService.Get<string>(code);
         if (string.IsNullOrEmpty(value))
         {

+ 1 - 1
Admin.NET/Admin.NET.Core/Service/DataBase/SysDatabaseService.cs

@@ -201,7 +201,7 @@ public class SysDatabaseService : IDynamicApiController, ITransient
         catch (NotSupportedException)
         {
             //Ignore 不支持该方法则不处理
-        } 
+        }
     }
 
     /// <summary>

+ 1 - 1
Admin.NET/Admin.NET.Core/Service/User/SysUserService.cs

@@ -106,7 +106,7 @@ public class SysUserService : IDynamicApiController, ITransient
             throw Oops.Oh(ErrorCodeEnum.D1003);
 
         await _sysUserRep.AsUpdateable(input.Adapt<SysUser>()).IgnoreColumns(true)
-            .IgnoreColumns(u => new { u.AccountType, u.Password, u.Status }).ExecuteCommandAsync();
+            .IgnoreColumns(u => new { u.Password, u.Status }).ExecuteCommandAsync();
 
         await UpdateRoleAndExtOrg(input);
 

+ 76 - 2
Web/pnpm-lock.yaml

@@ -160,6 +160,9 @@ devDependencies:
   '@vue/compiler-sfc':
     specifier: ^3.3.4
     version: 3.3.4
+  code-inspector-plugin:
+    specifier: ^0.1.12
+    version: 0.1.12
   eslint:
     specifier: ^8.51.0
     version: 8.51.0
@@ -1742,6 +1745,12 @@ packages:
     resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
     dev: false
 
+  /async@2.6.4:
+    resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==}
+    dependencies:
+      lodash: 4.17.21
+    dev: true
+
   /asynckit@0.4.0:
     resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
     dev: false
@@ -1867,6 +1876,14 @@ packages:
       supports-color: 5.5.0
     dev: true
 
+  /chalk@4.1.1:
+    resolution: {integrity: sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==}
+    engines: {node: '>=10'}
+    dependencies:
+      ansi-styles: 4.3.0
+      supports-color: 7.2.0
+    dev: true
+
   /chalk@4.1.2:
     resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
     engines: {node: '>=10'}
@@ -1902,6 +1919,27 @@ packages:
       tiny-emitter: 2.1.0
     dev: false
 
+  /code-inspector-core@0.1.12:
+    resolution: {integrity: sha512-qRkJapiBgUxj/3Z7SXoYcK3Yuts6FCKiALaOud3pL89fZDO8SSsILO+OevXLoMWYMlOkLojdqOBurMsRF5WePA==}
+    dependencies:
+      '@vue/compiler-dom': 3.3.4
+      chalk: 4.1.2
+      portfinder: 1.0.32
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /code-inspector-plugin@0.1.12:
+    resolution: {integrity: sha512-IQwZVe2RcjBfHXm6RJNM+gePGfvZayKRcdPkRIMboSZgOcgpLj3eNtL9+XxhEbxLtSrlGupAK0B9s+evigar1w==}
+    dependencies:
+      chalk: 4.1.1
+      code-inspector-core: 0.1.12
+      vite-code-inspector-plugin: 0.1.12
+      webpack-code-inspector-plugin: 0.1.12
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /codepage@1.14.0:
     resolution: {integrity: sha512-iz3zJLhlrg37/gYRWgEPkaFTtzmnEv1h+r7NgZum2lFElYQPi0/5bnmuDfODHxfp0INEfnRqyfyeIJDbb7ahRw==}
     engines: {node: '>=0.8'}
@@ -2030,7 +2068,6 @@ packages:
     dependencies:
       ms: 2.1.3
     dev: true
-    optional: true
 
   /debug@4.3.4:
     resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
@@ -3007,6 +3044,10 @@ packages:
       brace-expansion: 1.1.11
     dev: true
 
+  /minimist@1.2.8:
+    resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+    dev: true
+
   /mitt@2.1.0:
     resolution: {integrity: sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==}
     dev: false
@@ -3015,6 +3056,13 @@ packages:
     resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
     dev: false
 
+  /mkdirp@0.5.6:
+    resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
+    hasBin: true
+    dependencies:
+      minimist: 1.2.8
+    dev: true
+
   /monaco-editor@0.44.0:
     resolution: {integrity: sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==}
     dev: false
@@ -3026,7 +3074,6 @@ packages:
     resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
     requiresBuild: true
     dev: true
-    optional: true
 
   /namespace-emitter@2.0.1:
     resolution: {integrity: sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==}
@@ -3203,6 +3250,17 @@ packages:
       vue-demi: 0.14.6(vue@3.3.4)
     dev: false
 
+  /portfinder@1.0.32:
+    resolution: {integrity: sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==}
+    engines: {node: '>= 0.12.0'}
+    dependencies:
+      async: 2.6.4
+      debug: 3.2.7
+      mkdirp: 0.5.6
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /postcss-selector-parser@6.0.13:
     resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==}
     engines: {node: '>=4'}
@@ -3725,6 +3783,14 @@ packages:
     resolution: {integrity: sha512-sULNk72Z6NG94X9MMgpBwinaIOYjtl7Bn5jZbV9iZaglSYr2SHm/wpXPAjl8F8OW6SzOOJgIpRek+NvOvN7wsg==}
     dev: false
 
+  /vite-code-inspector-plugin@0.1.12:
+    resolution: {integrity: sha512-ZPq5Q9xDx2nQZGO4Bo31D/ptpQAdrllT8raEriWYuuxcwk4vgZCvOoZRCE97ZsC6Z5SxejWfiE3CUAVEey04+Q==}
+    dependencies:
+      code-inspector-core: 0.1.12
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /vite-plugin-cdn-import@0.3.5(rollup@2.79.1):
     resolution: {integrity: sha512-e1raoalfBiIhv+hnMeSp1UNjloDDBhHpeFxkwRRdPBmTdDRqdEEn8owUmT5u8UBSVCs4xN3n/od4a91vXEhXPQ==}
     dependencies:
@@ -3922,6 +3988,14 @@ packages:
     resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
     dev: false
 
+  /webpack-code-inspector-plugin@0.1.12:
+    resolution: {integrity: sha512-VXukBQmLgM8IUDpdUGOxrOQ5tO7LDFpHIFVZL9voO1uInmVlYPlbKYeSCRO6fhoZoURrgIarsCfJaoQ7jYoC5w==}
+    dependencies:
+      code-inspector-core: 0.1.12
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /whatwg-url@5.0.0:
     resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
     dependencies:

+ 4 - 4
Web/src/api-services/apis/sys-file-api.ts

@@ -80,7 +80,7 @@ export const SysFileApiAxiosParamCreator = function (configuration?: Configurati
         },
         /**
          * 
-         * @summary 下载文件(文件流)
+         * @summary 根据文件Id或Url下载
          * @param {FileInput} [body] 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -509,7 +509,7 @@ export const SysFileApiFp = function(configuration?: Configuration) {
         },
         /**
          * 
-         * @summary 下载文件(文件流)
+         * @summary 根据文件Id或Url下载
          * @param {FileInput} [body] 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -641,7 +641,7 @@ export const SysFileApiFactory = function (configuration?: Configuration, basePa
         },
         /**
          * 
-         * @summary 下载文件(文件流)
+         * @summary 根据文件Id或Url下载
          * @param {FileInput} [body] 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -743,7 +743,7 @@ export class SysFileApi extends BaseAPI {
     }
     /**
      * 
-     * @summary 下载文件(文件流)
+     * @summary 根据文件Id或Url下载
      * @param {FileInput} [body] 
      * @param {*} [options] Override http request option.
      * @throws {RequiredError}

+ 7 - 1
Web/src/api-services/models/file-input.ts

@@ -24,9 +24,15 @@ export interface FileInput {
      */
     id: number;
     /**
-     * 
+     * 文件名称
      * @type {string}
      * @memberof FileInput
      */
     fileName?: string | null;
+    /**
+     * 文件Url
+     * @type {string}
+     * @memberof FileInput
+     */
+    url?: string | null;
 }

+ 7 - 0
Web/src/api-services/models/login-user-output.ts

@@ -11,6 +11,7 @@
  * https://github.com/swagger-api/swagger-codegen.git
  * Do not edit the class manually.
  */
+import { AccountTypeEnum } from './account-type-enum';
 /**
  * 用户登录信息
  * @export
@@ -35,6 +36,12 @@ export interface LoginUserOutput {
      * @memberof LoginUserOutput
      */
     realName?: string | null;
+    /**
+     * 
+     * @type {AccountTypeEnum}
+     * @memberof LoginUserOutput
+     */
+    accountType?: AccountTypeEnum;
     /**
      * 头像
      * @type {string}

+ 1 - 0
Web/src/stores/userInfo.ts

@@ -66,6 +66,7 @@ export const useUserInfo = defineStore('userInfo', {
 							id: d.id,
 							account: d.account,
 							realName: d.realName,
+							accountType: d.accountType,
 							avatar: d.avatar ? '/' + d.avatar : '/favicon.ico',
 							address: d.address,
 							signature: d.signature,

+ 2 - 2
Web/src/types/pinia.d.ts

@@ -13,8 +13,8 @@ declare interface UserInfos<T = any> {
 }
 declare interface UserInfosState {
 	userInfos: UserInfos;
-	constList: T[],
-	dictList: T[],
+	constList: T[];
+	dictList: T[];
 }
 
 // 路由缓存列表

+ 28 - 9
Web/src/views/system/user/component/editUser.vue

@@ -21,11 +21,6 @@
 									<el-input v-model="state.ruleForm.realName" placeholder="真实姓名" clearable />
 								</el-form-item>
 							</el-col>
-							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
-								<el-form-item label="昵称">
-									<el-input v-model="state.ruleForm.nickName" placeholder="昵称" clearable />
-								</el-form-item>
-							</el-col>
 							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 								<el-form-item label="手机号码" prop="phone" :rules="[{ required: true, message: '手机号码不能为空', trigger: 'blur' }]">
 									<el-input v-model="state.ruleForm.phone" placeholder="手机号码" clearable />
@@ -36,6 +31,11 @@
 									<el-date-picker v-model="state.ruleForm.birthday" type="date" placeholder="出生日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" class="w100" />
 								</el-form-item>
 							</el-col>
+							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+								<el-form-item label="昵称">
+									<el-input v-model="state.ruleForm.nickName" placeholder="昵称" clearable />
+								</el-form-item>
+							</el-col>
 							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 								<el-form-item label="性别">
 									<el-radio-group v-model="state.ruleForm.sex">
@@ -44,13 +44,27 @@
 									</el-radio-group>
 								</el-form-item>
 							</el-col>
-							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
-								<el-form-item label="角色" prop="roleIdList" :rules="[{ required: true, message: '角色集合不能为空', trigger: 'blur' }]">
+							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+								<el-form-item label="角色集合" prop="roleIdList" :rules="[{ required: true, message: '角色集合不能为空', trigger: 'blur' }]">
 									<el-select v-model="state.ruleForm.roleIdList" multiple value-key="id" clearable placeholder="角色集合" collapse-tags collapse-tags-tooltip class="w100" filterable>
 										<el-option v-for="item in state.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="mb20">
+								<el-form-item label="账号类型" prop="accountType" :rules="[{ required: true, message: '角色集合不能为空', trigger: 'blur' }]">
+									<el-select v-model="state.ruleForm.accountType" placeholder="账号类型" collapse-tags collapse-tags-tooltip class="w100">
+										<el-option label="系统管理员" :value="888" :disabled="userInfos.accountType != 888 && userInfos.accountType != 999" />
+										<el-option label="普通账号" :value="777" />
+										<el-option label="会员" :value="666" />
+									</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="state.ruleForm.age" placeholder="年龄" class="w100" />
+								</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="state.ruleForm.orderNo" placeholder="排序" class="w100" />
@@ -241,6 +255,8 @@
 
 <script lang="ts" setup name="sysEditUser">
 import { onMounted, reactive, ref } from 'vue';
+import { storeToRefs } from 'pinia';
+import { useUserInfo } from '/@/stores/userInfo';
 
 import { getAPI } from '/@/utils/axios-utils';
 import { SysPosApi, SysRoleApi, SysUserApi } from '/@/api-services/api';
@@ -252,6 +268,8 @@ const props = defineProps({
 });
 const emits = defineEmits(['handleQuery']);
 const ruleFormRef = ref();
+const storesUserInfo = useUserInfo();
+const { userInfos } = storeToRefs(storesUserInfo);
 const state = reactive({
 	loading: false,
 	isShowDialog: false,
@@ -272,7 +290,8 @@ onMounted(async () => {
 
 // 打开弹窗
 const openDialog = async (row: any) => {
-	ruleFormRef.value?.resetFields(); //重置需要放在列表赋值之前
+	ruleFormRef.value?.resetFields();
+
 	state.selectedTabName = '0'; // 重置为第一个 tab 页
 	state.ruleForm = JSON.parse(JSON.stringify(row));
 	if (row.id != undefined) {
@@ -280,7 +299,7 @@ const openDialog = async (row: any) => {
 		state.ruleForm.roleIdList = resRole.data.result;
 		var resExtOrg = await getAPI(SysUserApi).apiSysUserOwnExtOrgListUserIdGet(row.id);
 		state.ruleForm.extOrgIdList = resExtOrg.data.result;
-	}
+	} else state.ruleForm.accountType = 777; // 默认普通账号类型
 	state.isShowDialog = true;
 };
 

+ 11 - 3
Web/src/views/system/user/index.vue

@@ -33,13 +33,14 @@
 					<el-table :data="state.userData" style="width: 100%" v-loading="state.loading" border>
 						<el-table-column type="index" label="序号" width="55" align="center" fixed />
 						<el-table-column prop="account" label="账号" width="120" align="center" fixed show-overflow-tooltip />
-						<el-table-column prop="nickName" label="昵称" width="120" align="center" show-overflow-tooltip />
+						<!-- <el-table-column prop="nickName" label="昵称" width="120" align="center" show-overflow-tooltip /> -->
+						<el-table-column prop="realName" label="姓名" width="120" align="center" show-overflow-tooltip />
 						<el-table-column label="头像" width="80" align="center" show-overflow-tooltip>
 							<template #default="scope">
 								<el-avatar :src="scope.row.avatar" size="small">{{ scope.row.nickName?.slice(0, 1) ?? scope.row.realName?.slice(0, 1) }} </el-avatar>
 							</template>
 						</el-table-column>
-						<el-table-column prop="realName" label="姓名" width="120" align="center" show-overflow-tooltip />
+						<el-table-column prop="phone" label="手机号码" width="120" align="center" show-overflow-tooltip />
 						<el-table-column label="出生日期" width="100" align="center" show-overflow-tooltip>
 							<template #default="scope">
 								{{ formatDate(new Date(scope.row.birthday), 'YYYY-mm-dd') }}
@@ -51,7 +52,14 @@
 								<el-tag type="danger" v-else> 女 </el-tag>
 							</template>
 						</el-table-column>
-						<el-table-column prop="phone" label="手机号码" width="120" align="center" show-overflow-tooltip />
+						<el-table-column label="账号类型" width="100" align="center" show-overflow-tooltip>
+							<template #default="scope">
+								<el-tag v-if="scope.row.accountType === 888"> 系统管理员 </el-tag>
+								<el-tag v-else-if="scope.row.accountType === 777"> 普通账号 </el-tag>
+								<el-tag v-else-if="scope.row.accountType === 666"> 会员 </el-tag>
+								<el-tag v-else> 其他 </el-tag>
+							</template>
+						</el-table-column>
 						<el-table-column label="状态" width="70" align="center" show-overflow-tooltip>
 							<template #default="scope">
 								<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="2" size="small" @change="changeStatus(scope.row)" v-auth="'sysUser:setStatus'" />

+ 8 - 3
Web/vite.config.ts

@@ -19,14 +19,19 @@ const alias: Record<string, string> = {
 
 const viteConfig = defineConfig((mode: ConfigEnv) => {
 	const env = loadEnv(mode.mode, process.cwd());
-	fs.writeFileSync('./public/config.js', `window.__env__ = ${JSON.stringify(env, null, 2)} `)
+	fs.writeFileSync('./public/config.js', `window.__env__ = ${JSON.stringify(env, null, 2)} `);
 	return {
 		plugins: [
 			CodeInspectorPlugin({
 				bundler: 'vite',
 				hotKeys: ['shiftKey'],
 			}),
-			vue(), vueJsx(), vueSetupExtend(), viteCompression(), JSON.parse(env.VITE_OPEN_CDN) ? buildConfig.cdn() : null],
+			vue(),
+			vueJsx(),
+			vueSetupExtend(),
+			viteCompression(),
+			JSON.parse(env.VITE_OPEN_CDN) ? buildConfig.cdn() : null,
+		],
 		root: process.cwd(),
 		resolve: { alias },
 		base: mode.command === 'serve' ? './' : env.VITE_PUBLIC_PATH,
@@ -46,7 +51,7 @@ const viteConfig = defineConfig((mode: ConfigEnv) => {
 				'^/[Uu]pload': {
 					target: env.VITE_API_URL,
 					changeOrigin: true,
-				}
+				},
 			},
 		},
 		build: {