Commit 2c5bc8debb43fd19e20f92e41ce46d60c3ff9122

Authored by 杨泽宇
1 parent ce470f44

角色创建限制 用户关联小区

src/layout/header.vue
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 */ 6 */
7 import { getCurrentInstance, onMounted, reactive, computed } from "vue"; 7 import { getCurrentInstance, onMounted, reactive, computed } from "vue";
8 import * as store from "@/pinia/index"; 8 import * as store from "@/pinia/index";
  9 +import { ElMessageBox } from "element-plus";
9 import { Fold, Expand } from "@element-plus/icons-vue"; 10 import { Fold, Expand } from "@element-plus/icons-vue";
10 import styles from "@/style/global.module.scss"; 11 import styles from "@/style/global.module.scss";
11 // TIP 获取全局变量,暂时只有坏图片占位图 12 // TIP 获取全局变量,暂时只有坏图片占位图
@@ -24,7 +25,15 @@ const toggleMenu = () => { @@ -24,7 +25,15 @@ const toggleMenu = () => {
24 * 退出登录 25 * 退出登录
25 */ 26 */
26 const handleLogout = () => { 27 const handleLogout = () => {
27 - store.family.loginStore().removeToken(); 28 + ElMessageBox.confirm("确认退出登录吗?", "警告", {
  29 + confirmButtonText: "确认",
  30 + cancelButtonText: "取消",
  31 + type: "warning",
  32 + }).then(() => {
  33 + store.family.loginStore().removeToken();
  34 + }).catch(error => {
  35 + console.log(error)
  36 + })
28 }; 37 };
29 let asyncData = reactive({ 38 let asyncData = reactive({
30 userInfo: "", 39 userInfo: "",
src/pinia/index.ts
1 import { defineStore } from 'pinia' 1 import { defineStore } from 'pinia'
2 -import * as all from 'pinia'  
3 -import data from './modules/data'  
4 -import menu from './modules/menu'  
5 2
6 // 获取modules文件夹下面所有ts文件 3 // 获取modules文件夹下面所有ts文件
7 -let files = import.meta.globEager('./modules/*.ts') 4 +let files: any = import.meta.globEager('./modules/*.ts')
  5 +
8 let modules:any = {}, allStore:any = {}, family: any = {} 6 let modules:any = {}, allStore:any = {}, family: any = {}
  7 +
9 for(let file in files) { 8 for(let file in files) {
10 const moduleName = file.replace(/(.*\/)*([^.]+).*/gi, '$2') 9 const moduleName = file.replace(/(.*\/)*([^.]+).*/gi, '$2')
11 modules = { ...modules, ...files[file] } 10 modules = { ...modules, ...files[file] }
12 allStore[moduleName + 'Store'] = modules 11 allStore[moduleName + 'Store'] = modules
13 - // family[moduleName + 'Store'] = modules  
14 } 12 }
15 -// console.log(allStore)  
16 13
17 for (let item in allStore) { 14 for (let item in allStore) {
18 family[item] = defineStore(allStore[item].default) 15 family[item] = defineStore(allStore[item].default)
19 } 16 }
20 17
21 -// const tengxiTestStore = defineStore({  
22 -// id: 'tengxi5290',  
23 -// state: () => ({  
24 -// age: null,  
25 -// name: '',  
26 -// }),  
27 -// getters: {  
28 -// doubleCount() {  
29 -// return this.age * 2  
30 -// },  
31 -// doubleCountPlusOne() {  
32 -// return this.doubleCount * 2 + 1  
33 -// }  
34 -// },  
35 -// actions: {  
36 -// reset() {  
37 -// this.age = 1  
38 -// },  
39 -// grown() {  
40 -// this.age += 1  
41 -// },  
42 -// init() {  
43 -// this.age = 20  
44 -// this.name = 'yzy'  
45 -// }  
46 -// },  
47 -// })  
48 -// const dataStore = defineStore(data)  
49 -// export {tengxiTestStore, dataStore}  
50 export {family} 18 export {family}
51 \ No newline at end of file 19 \ No newline at end of file
src/pinia/modules/data.ts deleted 100644 → 0
1 -const id = 'data'  
2 -const state = () => ({  
3 - data1: '10086',  
4 - desc: 'test',  
5 - })  
6 - const getters = {  
7 - doubleCount() {  
8 - return this.desc  
9 - },  
10 - doubleCountPlusOne() {  
11 - return this.data1  
12 - }  
13 - }  
14 - const actions = {  
15 - reset() {  
16 - this.data1 = '10010'  
17 - },  
18 - grown() {  
19 - this.desc = 'test test'  
20 - }  
21 - }  
22 -  
23 -export default {  
24 - namespace: true,  
25 - actions,  
26 - getters,  
27 - state,  
28 - id  
29 -}  
30 \ No newline at end of file 0 \ No newline at end of file
src/pinia/modules/menu.ts
1 -interface MenuItem {  
2 - menuList: MenuItem[],  
3 - id: number,  
4 - name: string,  
5 - priority: number,  
6 - url: string | null,  
7 - selected: boolean,  
8 - parentId: number | null,  
9 - keyword: string | null,  
10 - status: number  
11 -}  
12 const id: string = 'menu' 1 const id: string = 'menu'
13 const state: Function = () => ({ 2 const state: Function = () => ({
14 menuList: [] 3 menuList: []
@@ -19,7 +8,7 @@ const getters = { @@ -19,7 +8,7 @@ const getters = {
19 } 8 }
20 } 9 }
21 const actions = { 10 const actions = {
22 - setMenuList (data: MenuItem[]) { 11 + setMenuList (data) {
23 this.menuList = data 12 this.menuList = data
24 } 13 }
25 } 14 }
src/views/role/index.vue
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 import { reactive, ref, onMounted, getCurrentInstance } from "vue"; 2 import { reactive, ref, onMounted, getCurrentInstance } from "vue";
3 import { roleList, roleStatus } from "@/api/user/role"; 3 import { roleList, roleStatus } from "@/api/user/role";
  4 +import * as store from "@/pinia/index";
  5 +import router from "@/router";
4 import { parseTime } from "@/utils/tool"; 6 import { parseTime } from "@/utils/tool";
5 import Pagination from "@/components/Pagination/index.vue"; 7 import Pagination from "@/components/Pagination/index.vue";
6 import { ElMessageBox } from "element-plus"; 8 import { ElMessageBox } from "element-plus";
@@ -20,23 +22,9 @@ interface Params { @@ -20,23 +22,9 @@ interface Params {
20 } 22 }
21 interface Data { 23 interface Data {
22 loading: boolean; 24 loading: boolean;
23 - list: List[] | null; 25 + list: any[];
24 params: Params; 26 params: Params;
25 } 27 }
26 -interface List {  
27 - roleName: string,  
28 - code: string,  
29 - roleDesc: string,  
30 - status: number,  
31 - createTime: string,  
32 - updateTime: string,  
33 - creator: string,  
34 - creatorId: number,  
35 - updator: string,  
36 - updatorId: number,  
37 - type: number,  
38 - oId: number  
39 -}  
40 let data: Data = reactive({ 28 let data: Data = reactive({
41 list: [], 29 list: [],
42 loading: false, 30 loading: false,
@@ -49,6 +37,9 @@ let data: Data = reactive({ @@ -49,6 +37,9 @@ let data: Data = reactive({
49 }, 37 },
50 }, 38 },
51 }); 39 });
  40 +let asyncData = reactive({
  41 + userInfo: "",
  42 +});
52 /** 43 /**
53 * 列表 44 * 列表
54 */ 45 */
@@ -118,27 +109,28 @@ const handleStatus = async (obj) =&gt; { @@ -118,27 +109,28 @@ const handleStatus = async (obj) =&gt; {
118 try { 109 try {
119 const res = await roleStatus({ 110 const res = await roleStatus({
120 roleId: obj.id, 111 roleId: obj.id,
121 - status: obj.status? 0: 1 112 + status: obj.status ? 0 : 1,
122 }); 113 });
123 - if(res?.data) { 114 + if (res?.data) {
124 globalProperties.$message.success("操作成功"); 115 globalProperties.$message.success("操作成功");
125 - getList() 116 + getList();
126 } else { 117 } else {
127 globalProperties.$message.error("操作失败"); 118 globalProperties.$message.error("操作失败");
128 } 119 }
129 } catch (e) { 120 } catch (e) {
130 console.log(e); 121 console.log(e);
131 - } 122 + }
132 }; 123 };
133 /** 124 /**
134 * 状态值 125 * 状态值
135 - * @enum {number} 126 + * @enum {number}
136 */ 127 */
137 enum statusEnum { 128 enum statusEnum {
138 "禁用" = 0, 129 "禁用" = 0,
139 "启用", 130 "启用",
140 } 131 }
141 onMounted(() => { 132 onMounted(() => {
  133 + asyncData.userInfo = store.family.loginStore().id;
142 getList(); 134 getList();
143 }); 135 });
144 </script> 136 </script>
@@ -158,9 +150,13 @@ onMounted(() =&gt; { @@ -158,9 +150,13 @@ onMounted(() =&gt; {
158 </el-form-item> 150 </el-form-item>
159 <el-form-item> 151 <el-form-item>
160 <el-button type="primary" @click="handleSearch">查询</el-button> 152 <el-button type="primary" @click="handleSearch">查询</el-button>
161 - <el-button type="primary">  
162 - <router-link to="/role/edit">添加角色</router-link>  
163 - </el-button> 153 + <!-- 超管不能创建角色 -->
  154 + <el-button
  155 + type="primary"
  156 + @click="router.push({ path: '/role/edit' })"
  157 + :disabled="asyncData.userInfo === 1"
  158 + >添加角色</el-button
  159 + >
164 </el-form-item> 160 </el-form-item>
165 </el-form> 161 </el-form>
166 </el-row> 162 </el-row>
@@ -196,16 +192,23 @@ onMounted(() =&gt; { @@ -196,16 +192,23 @@ onMounted(() =&gt; {
196 scope.row.status ? "禁用" : "启用" 192 scope.row.status ? "禁用" : "启用"
197 }}</el-button> 193 }}</el-button>
198 <el-button type="text" 194 <el-button type="text"
199 - ><router-link :to="{ path: '/role/user', query: {id: scope.row.id} }" 195 + ><router-link
  196 + :to="{ path: '/role/user', query: { id: scope.row.id } }"
200 >用户</router-link 197 >用户</router-link
201 ></el-button 198 ></el-button
202 > 199 >
203 <el-button type="text" 200 <el-button type="text"
204 - ><router-link :to="{ path: '/role/permission', query: {roleId: scope.row.id, roleName: scope.row.roleName} }" 201 + ><router-link
  202 + :to="{
  203 + path: '/role/permission',
  204 + query: { roleId: scope.row.id, roleName: scope.row.roleName },
  205 + }"
205 >权限</router-link 206 >权限</router-link
206 ></el-button 207 ></el-button
207 > 208 >
208 - <el-button type="text" @click="handleDelete(scope.row)">删除</el-button> 209 + <el-button type="text" @click="handleDelete(scope.row)"
  210 + >删除</el-button
  211 + >
209 </template> 212 </template>
210 </el-table-column> 213 </el-table-column>
211 </el-table> 214 </el-table>
src/views/system/info.vue
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 import { reactive, ref, getCurrentInstance } from "vue"; 2 import { reactive, ref, getCurrentInstance } from "vue";
3 import * as store from "@/pinia/index"; 3 import * as store from "@/pinia/index";
4 -import { userPwdChange } from '@/api/user/user'; 4 +import { userPwdChange } from "@/api/user/user";
5 import type { ElForm } from "element-plus"; 5 import type { ElForm } from "element-plus";
6 6
7 const ruleFormRef = ref<InstanceType<typeof ElForm>>(); 7 const ruleFormRef = ref<InstanceType<typeof ElForm>>();
@@ -11,8 +11,8 @@ let form = reactive({ @@ -11,8 +11,8 @@ let form = reactive({
11 userId: store?.family?.loginStore()?.id, 11 userId: store?.family?.loginStore()?.id,
12 oldPassword: "", 12 oldPassword: "",
13 newPassword: "", 13 newPassword: "",
14 - surePwd: ""  
15 - } 14 + surePwd: "",
  15 + },
16 }); 16 });
17 /** 17 /**
18 * 验证两次输入密码一致 18 * 验证两次输入密码一致
@@ -21,12 +21,12 @@ let form = reactive({ @@ -21,12 +21,12 @@ let form = reactive({
21 * @callback checkPwd~checkDoublePwdCallback 21 * @callback checkPwd~checkDoublePwdCallback
22 */ 22 */
23 const checkPwd = (rules, value, callback) => { 23 const checkPwd = (rules, value, callback) => {
24 - if(value === form.data.newPassword) {  
25 - callback() 24 + if (value === form.data.newPassword) {
  25 + callback();
26 } else { 26 } else {
27 - callback(new Error('请确认密码和新密码一致')) 27 + callback(new Error("请确认密码和新密码一致"));
28 } 28 }
29 -} 29 +};
30 /** 30 /**
31 * 表单验证规则 31 * 表单验证规则
32 */ 32 */
@@ -50,10 +50,10 @@ const rules = reactive({ @@ -50,10 +50,10 @@ const rules = reactive({
50 required: true, 50 required: true,
51 message: "请确认密码和新密码一致", 51 message: "请确认密码和新密码一致",
52 trigger: "blur", 52 trigger: "blur",
53 - validator: checkPwd 53 + validator: checkPwd,
54 }, 54 },
55 ], 55 ],
56 -}) 56 +});
57 /** 57 /**
58 * 表单重置 58 * 表单重置
59 */ 59 */
@@ -72,7 +72,7 @@ const submitForm = (formEl: InstanceType&lt;typeof ElForm&gt; | undefined) =&gt; { @@ -72,7 +72,7 @@ const submitForm = (formEl: InstanceType&lt;typeof ElForm&gt; | undefined) =&gt; {
72 .then((res) => { 72 .then((res) => {
73 if (res) { 73 if (res) {
74 instance?.proxy?.$message.success("修改成功"); 74 instance?.proxy?.$message.success("修改成功");
75 - store.family.loginStore().removeToken('请重新登录'); 75 + store.family.loginStore().removeToken("请重新登录");
76 } 76 }
77 }) 77 })
78 .catch((error) => { 78 .catch((error) => {
@@ -123,9 +123,7 @@ const submitForm = (formEl: InstanceType&lt;typeof ElForm&gt; | undefined) =&gt; { @@ -123,9 +123,7 @@ const submitForm = (formEl: InstanceType&lt;typeof ElForm&gt; | undefined) =&gt; {
123 <el-button type="primary" @click="submitForm(ruleFormRef)" 123 <el-button type="primary" @click="submitForm(ruleFormRef)"
124 >提交</el-button 124 >提交</el-button
125 > 125 >
126 - <el-button  
127 - type="info"  
128 - @click="resetForm(ruleFormRef)" 126 + <el-button type="info" @click="resetForm(ruleFormRef)"
129 >取消</el-button 127 >取消</el-button
130 > 128 >
131 </el-form-item> 129 </el-form-item>
src/views/user/edit.vue
@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 import { reactive, ref, getCurrentInstance, onMounted } from "vue"; 2 import { reactive, ref, getCurrentInstance, onMounted } from "vue";
3 import { userAdd } from "@/api/user/user"; 3 import { userAdd } from "@/api/user/user";
4 import { roleList } from "@/api/user/role"; 4 import { roleList } from "@/api/user/role";
  5 +import { getTableList } from "@/api/community/residence";
5 import { useRoute } from "vue-router"; 6 import { useRoute } from "vue-router";
6 import { validMobile } from "@/utils/validate"; 7 import { validMobile } from "@/utils/validate";
7 import type { ElForm } from "element-plus"; 8 import type { ElForm } from "element-plus";
@@ -16,11 +17,14 @@ let form = reactive({ @@ -16,11 +17,14 @@ let form = reactive({
16 cellphone: "", 17 cellphone: "",
17 password: "", 18 password: "",
18 roleIds: "", 19 roleIds: "",
  20 + cIds: "",
19 userId: "", 21 userId: "",
20 }, 22 },
21 dataType: "", 23 dataType: "",
22 roles: [], 24 roles: [],
  25 + communities: [],
23 checkList: [], 26 checkList: [],
  27 + communityList: []
24 }); 28 });
25 const ruleFormRef = ref<InstanceType<typeof ElForm>>(); 29 const ruleFormRef = ref<InstanceType<typeof ElForm>>();
26 /** 30 /**
@@ -106,7 +110,7 @@ const submitForm = (formEl: InstanceType&lt;typeof ElForm&gt; | undefined) =&gt; { @@ -106,7 +110,7 @@ const submitForm = (formEl: InstanceType&lt;typeof ElForm&gt; | undefined) =&gt; {
106 * 角色列表 110 * 角色列表
107 * @param {number | null} pageSize 一次请求多少条数据 111 * @param {number | null} pageSize 一次请求多少条数据
108 */ 112 */
109 -const getRoleList = async (pageSize = 20) => { 113 +const getRoleList = async (pageSize: number = 20) => {
110 try { 114 try {
111 const res = await roleList({ 115 const res = await roleList({
112 page: 1, 116 page: 1,
@@ -120,8 +124,28 @@ const getRoleList = async (pageSize = 20) =&gt; { @@ -120,8 +124,28 @@ const getRoleList = async (pageSize = 20) =&gt; {
120 console.log(e); 124 console.log(e);
121 } 125 }
122 }; 126 };
  127 +/**
  128 + * 小区列表
  129 + * @param {number | null} pageSize 一次请求多少条数据
  130 + */
  131 +const getCommunityList = async (pageSize: number = 20) => {
  132 + try {
  133 + const res = await getTableList({
  134 + page: 1,
  135 + type: 0,
  136 + pageSize: pageSize,
  137 + });
  138 + form.communities = res.data.data.list;
  139 + if (res.data.data.total > pageSize) {
  140 + getCommunityList(res.data.data.total);
  141 + }
  142 + } catch (e) {
  143 + console.log(e);
  144 + }
  145 +};
123 onMounted(() => { 146 onMounted(() => {
124 getRoleList(); 147 getRoleList();
  148 + getCommunityList();
125 form.data = useRoute().query; 149 form.data = useRoute().query;
126 if (JSON.stringify(form.data) === "{}") { 150 if (JSON.stringify(form.data) === "{}") {
127 form.dataType = "add"; 151 form.dataType = "add";
@@ -179,6 +203,19 @@ onMounted(() =&gt; { @@ -179,6 +203,19 @@ onMounted(() =&gt; {
179 > 203 >
180 </el-checkbox-group> 204 </el-checkbox-group>
181 </el-form-item> 205 </el-form-item>
  206 + <el-form-item label="小区" style="width: 100%">
  207 + <el-checkbox-group
  208 + v-model="form.communityList"
  209 + @change="(data) => (form.data.cIds = data.join(','))"
  210 + >
  211 + <el-checkbox
  212 + v-for="(item, index) in form.communities"
  213 + :key="index"
  214 + :label="item.id"
  215 + >{{ item.name }}</el-checkbox
  216 + >
  217 + </el-checkbox-group>
  218 + </el-form-item>
182 <el-form-item style="width: 100%"> 219 <el-form-item style="width: 100%">
183 <el-button type="primary" @click="submitForm(ruleFormRef)" 220 <el-button type="primary" @click="submitForm(ruleFormRef)"
184 >提交</el-button 221 >提交</el-button
src/views/user/index.vue
@@ -183,11 +183,16 @@ onMounted(() =&gt; { @@ -183,11 +183,16 @@ onMounted(() =&gt; {
183 align="center" 183 align="center"
184 element-loading-text="拼命加载中" 184 element-loading-text="拼命加载中"
185 > 185 >
186 - <el-table-column prop="id" label="ID" align="center"> </el-table-column> 186 + <el-table-column prop="id" label="ID" align="center"></el-table-column>
187 <el-table-column prop="userName" label="昵称" align="center"> 187 <el-table-column prop="userName" label="昵称" align="center">
188 </el-table-column> 188 </el-table-column>
189 <el-table-column prop="cellphone" label="手机号" align="center"> 189 <el-table-column prop="cellphone" label="手机号" align="center">
190 </el-table-column> 190 </el-table-column>
  191 + <el-table-column prop="roleList" label="角色" align="center">
  192 + <template #default="scope">
  193 + {{scope.row.roleList.map(i => i.roleName).join(',')}}
  194 + </template>
  195 + </el-table-column>
191 <el-table-column prop="createTime" label="注册时间" align="center"> 196 <el-table-column prop="createTime" label="注册时间" align="center">
192 <template #default="scope"> 197 <template #default="scope">
193 {{ parseTime(new Date(scope.row.createTime).getTime()) }} 198 {{ parseTime(new Date(scope.row.createTime).getTime()) }}
src/views/user/login.vue
@@ -89,6 +89,7 @@ const getMenu = async () =&gt; { @@ -89,6 +89,7 @@ const getMenu = async () =&gt; {
89 auto-complete="off" 89 auto-complete="off"
90 clearable 90 clearable
91 :prefix-icon="UserFilled" 91 :prefix-icon="UserFilled"
  92 + style="width: 448px;"
92 /> 93 />
93 </el-form-item> 94 </el-form-item>
94 </el-row> 95 </el-row>