Browse Source

成员管理 - 权限管理 - 项目管理开发

liuxiaona 11 months ago
parent
commit
61aadcb0b7

+ 15 - 1
src/api/ApiModel.ts

@@ -47,7 +47,11 @@ export interface menuParam{
47 47
     icon?:string,
48 48
     parent_id?:string|number,
49 49
     id?:string|number,
50
-    p_id?:any
50
+    p_id?:any,
51
+    name?:string,
52
+    note?:string,
53
+    permission_ids?:any,
54
+    permission_levels?:any,
51 55
 }
52 56
 export interface accountParam extends pageParams{
53 57
     username?:string,
@@ -236,6 +240,16 @@ export interface departParams{
236 240
     name?:string,
237 241
     pid?:string|number,
238 242
     id?:string|number,
243
+    note?:string,
244
+    head_user_id?:any,
245
+    show_type?:string|number,
246
+    department_ids?:any,
247
+    user_ids?:any,
248
+    username?:string,
249
+    password?:string,
250
+    department_id?:any,
251
+    role_id?:any,
252
+    keyword?:string
239 253
 }
240 254
 
241 255
 

+ 13 - 0
src/api/api.ts

@@ -131,6 +131,19 @@ export enum Api{
131 131
     project_edit = '/api/sys/projectsEdit',
132 132
     project_dele = '/api/sys/projectsDel',
133 133
 
134
+    //权限
135
+    limit_add = '/api/sys/roleAdd',
136
+    limit_list = '/api/sys/roleList',
137
+    limit_edit = '/api/sys/roleEdit',
138
+    limit_dele = '/api/sys/roleDel',
139
+
140
+    //人员
141
+    user_list = '/api/sys/userList',
142
+    user_add = '/api/sys/userAdd',
143
+    user_edit = '/api/sys/userEdit',
144
+    user_dele = '/api/sys/userDel',
145
+
146
+
134 147
 
135 148
 
136 149
 

+ 224 - 0
src/components/businessMoudle/limitManage/addPage.vue

@@ -0,0 +1,224 @@
1
+<template>
2
+  <div class="addPageBox"  v-loading="loading">
3
+    <Drawer :drawerShow="drawer_show" @close="closeEvent" :title="pageInfo.title" drawerSize="70%" :closeOnModal="false">
4
+      <template v-slot:content>
5
+      <div style="background-color: #fff;height: 100%">
6
+        <div class="itemBox">
7
+          <div class="title">基础信息</div>
8
+          <div class="contBox">
9
+            <Input ref="InputRef_name" spanFS="14px" title="权限名称" spanTitleWidth="100px" inputWidth="300px" placeholderTxt="权限名称" />
10
+            <Input ref="InputRef_note" spanFS="14px" class="tMar20" spanTitleWidth="100px" inputWidth="300px" title="权限描述" placeholderTxt="权限描述"/>
11
+          </div>
12
+        </div>
13
+
14
+        <div class="itemBox">
15
+          <div class="title">权限配置</div>
16
+          <div class="contBox">
17
+            <!--  列表-->
18
+            <TableList
19
+                ref="tableListRef"
20
+                :tableData="pageInfo.menuList"
21
+                :descol="tableInfo.descolList"
22
+            >
23
+              <template v-slot:subPage="slotProps">
24
+                <div>
25
+                  <el-checkbox-group v-model="slotProps.row.pageCheckList">
26
+                    <el-checkbox v-for="sub in slotProps.row.subList" :label="sub.id" :key="sub.id">{{sub.title}}</el-checkbox>
27
+                  </el-checkbox-group>
28
+                </div>
29
+              </template>
30
+              <template v-slot:limit="slotProps">
31
+                <div class="text-center" v-if="slotProps.row.title !== '首页'">
32
+                  <el-radio-group v-model="slotProps.row.limitCheckList">
33
+                    <el-radio :label="1">个人</el-radio>
34
+                    <el-radio :label="2">部门</el-radio>
35
+                    <el-radio :label="3">公司</el-radio>
36
+                    <el-radio :label="4">项目</el-radio>
37
+                  </el-radio-group>
38
+                </div>
39
+              </template>
40
+            </TableList>
41
+          </div>
42
+        </div>
43
+
44
+        <div class="itemBox">
45
+          <div class="contBox">
46
+            <el-button type="primary" plain @click="closeEvent" size="large">&nbsp;&nbsp;取消&nbsp;&nbsp;</el-button>
47
+            <el-button type="primary" @click="confirmEvent" size="large">&nbsp;&nbsp;确定&nbsp;&nbsp;</el-button>
48
+          </div>
49
+        </div>
50
+      </div>
51
+      </template>
52
+    </Drawer>
53
+  </div>
54
+</template>
55
+<script setup lang="ts">
56
+import {getCurrentInstance, nextTick, reactive, ref} from "vue";
57
+import Drawer from '@/components/capsulationMoudle/_drawer.vue'
58
+import Input from '@/components/capsulationMoudle/_input.vue'
59
+import {menuParam, reactiveTableAndAny} from "@/api/ApiModel";
60
+import TableList from '@/components/capsulationMoudle/tableList.vue'
61
+import {ElMessage} from "element-plus";
62
+import {Api} from "@/api/api";
63
+import {publicTableTs} from "@/components/businessMoudle/tableInfo";
64
+
65
+const { proxy } = getCurrentInstance() as any;
66
+// 全局方法定义
67
+const NumberHandle = proxy.$NumberHandle
68
+
69
+const emit = defineEmits<{
70
+  (event: "init"): void;
71
+}>();
72
+
73
+const props = withDefaults(defineProps<{
74
+  folderObj?:any
75
+}>(), {
76
+  folderObj:{}
77
+})
78
+
79
+const loading = ref<boolean>(false)
80
+// 表格数据公共ts
81
+const descolParams = reactive([
82
+  { name:'功能模块',column:'title',},
83
+  { name:'页面范畴',column:'subPage',slotFlag: true},
84
+  { name:'数据权限',column:'limit',slotFlag: true},
85
+])
86
+const { tableInfo,tableListRef,total } = publicTableTs(descolParams)
87
+
88
+const pageInfo = reactive<reactiveTableAndAny>({
89
+  title:'新增权限',
90
+  menuList:[],
91
+  editId:-1
92
+})
93
+
94
+// 切换显隐
95
+const drawer_show = ref<boolean>(false)
96
+const switchShow = (val:boolean,item?:any)=>{
97
+  drawer_show.value = val
98
+  nextTick(async ()=>{
99
+    if(val){
100
+      await getMenuList()
101
+      if(item!.id){
102
+        pageInfo.editId = item!.id
103
+        InputRef_name.value!.value = item.name
104
+        InputRef_note.value!.value = item.note
105
+        pageInfo.menuList.forEach(sub=>{
106
+          for(let i in item.permission_levels){
107
+            if(sub.levelName == i){
108
+              sub.limitCheckList = item.permission_levels[i]
109
+            }
110
+          }
111
+        })
112
+      }else{
113
+        pageInfo.editId =  -1
114
+        InputRef_name.value!.value = ''
115
+        InputRef_note.value!.value = ''
116
+      }
117
+
118
+    }
119
+  })
120
+}
121
+
122
+const closeEvent = () => {
123
+  drawer_show.value = false
124
+}
125
+const InputRef_name = ref<{value:string}>()
126
+const InputRef_note = ref<{value:string}>()
127
+const confirmEvent = async () => {
128
+  loading.value = true
129
+  let ids:any = []
130
+  let levels:any = {}
131
+  pageInfo.menuList.forEach(item=>{
132
+    ids = ids.concat(item.pageCheckList)
133
+    let newObj:any = {}
134
+    newObj[item.levelName] = item.limitCheckList
135
+    levels = Object.assign(levels,newObj)
136
+  })
137
+  const paramsModel = reactive<menuParam>({
138
+    name:InputRef_name.value!.value,
139
+    note:InputRef_note.value!.value,
140
+    permission_ids:ids,
141
+    permission_levels:JSON.stringify(levels),
142
+  })
143
+  let api = Api.limit_add
144
+  if(pageInfo.editId > 0){
145
+    api = Api.limit_edit
146
+    paramsModel.id = pageInfo.editId
147
+  }
148
+  let res:any = await proxy.$http.post(api,paramsModel)
149
+  loading.value = false
150
+  ElMessage.info(res.errMsg)
151
+  if(res&&res.errNo=='0'){
152
+    closeEvent()
153
+    emit('init')
154
+  }
155
+}
156
+
157
+
158
+
159
+//菜单列表
160
+const getMenuList = async () => {
161
+  let res:any = await proxy.$http.get(Api.menu_list)
162
+  if(res&&res.errNo=='0'){
163
+    pageInfo.menuList = res.rst
164
+    pageInfo.menuList.forEach(sub=>{
165
+      if(sub.title == '首页'){
166
+        sub.subList = [{id:7,title:'首页'}]
167
+      }else{
168
+        getSubMenuList(sub.id).then(result =>{
169
+          sub.subList = result
170
+        })
171
+        if(sub.title == '广告管理'){
172
+          sub.levelName = 'ad'
173
+        }else if(sub.title == '系统管理'){
174
+          sub.levelName = 'system'
175
+        }else if(sub.title == '素材管理'){
176
+          sub.levelName = 'material'
177
+        }
178
+      }
179
+    })
180
+  }
181
+}
182
+
183
+//子菜单列表
184
+const getSubMenuList = async (id:number) => {
185
+  const paramsModel = reactive<menuParam>({
186
+    parent_id:id,
187
+  })
188
+  let res:any = await proxy.$http.get(Api.menu_list,paramsModel)
189
+  return res&&res.errNo=='0' ? res.rst : []
190
+}
191
+
192
+// 父组件共享值
193
+defineExpose({
194
+  switchShow,
195
+});
196
+</script>
197
+<style scoped lang="scss">
198
+.addPageBox{
199
+  :deep(.el-drawer__header){
200
+    margin-bottom: 0;
201
+    background-color: #fff;
202
+    padding-bottom: 20px;
203
+    color: #161E46;
204
+    font-weight: 600;
205
+  }
206
+  :deep(.el-drawer__body){
207
+    background-color: #F7F7F7;
208
+  }
209
+}
210
+
211
+.itemBox{
212
+  margin-bottom: 10px;
213
+  .title{
214
+    width: 100%;
215
+    padding: 27px 33px 10px;
216
+    font-weight: 600;
217
+    font-size: 16px;
218
+  }
219
+  .contBox{
220
+    background-color: #fff;
221
+    padding: 18px 33px;
222
+  }
223
+}
224
+</style>

+ 19 - 19
src/components/businessMoudle/limitManage/index.vue

@@ -13,17 +13,21 @@
13 13
   >
14 14
     <template v-slot:operate="slotProps">
15 15
       <div class="text-center">
16
-        <span class="operate_text lMar8 pointer" @click="editEvent(slotProps.row)">编辑</span>
16
+        <span class="operate_text lMar8 pointer" @click="limitsAdd(slotProps.row)">编辑</span>
17 17
         <Popconfirm @confirm="deleEvent(slotProps.row)"/>
18 18
       </div>
19 19
     </template>
20 20
   </TableList>
21
+
22
+
23
+  <AddPage ref="AddPageRef" @init="init"></AddPage>
21 24
 </template>
22 25
 <script setup lang="ts">
23 26
 import {nextTick, onMounted, reactive, ref, getCurrentInstance} from 'vue'
24 27
 import Popconfirm from '@/components/capsulationMoudle/_popconfirm.vue'
25 28
 import TableList from '@/components/capsulationMoudle/tableList.vue'
26
-import { adqParam, reactiveTableAndAny} from "@/api/ApiModel";
29
+import AddPage from './addPage.vue'
30
+import {departParams} from "@/api/ApiModel";
27 31
 import {Api} from "@/api/api";
28 32
 import {ElMessage} from "element-plus";
29 33
 import { publicTableTs } from '@/components/businessMoudle/tableInfo'
@@ -33,31 +37,30 @@ const { proxy } = getCurrentInstance() as any;
33 37
 
34 38
 // 表格数据公共ts
35 39
 const descolParams = reactive([
36
-  { name:'权限名称',column:'account_name',},
37
-  { name:'描述',column:'account_id',cancleForMat:true},
40
+  { name:'权限名称',column:'name',},
41
+  { name:'描述',column:'note',cancleForMat:true},
38 42
   { name:'更新时间',column:'created_at'},
39 43
   { name:'操作',column:'operate',slotFlag: true},
40 44
 ])
41 45
 const { tableInfo,tableListRef,total } = publicTableTs(descolParams)
42 46
 
43
-const limitsAdd = () => {
44 47
 
48
+const AddPageRef = ref<{switchShow:(val:boolean,item?:any)=>void}>()
49
+const limitsAdd = (item?:any) => {
50
+  nextTick(()=>{
51
+    AddPageRef.value!.switchShow(true,item||'')
52
+  })
45 53
 }
46 54
 
47 55
 const InputRef_text = ref<{value:string}>()
48 56
 
49 57
 //账号列表
50
-const init = async (page?:any,pageSize?:any) => {
58
+const init = async () => {
51 59
   tableListRef.value!.loading = true
52
-  const paramsModel = reactive<adqParam>({
53
-    page:page?page:1,
54
-    page_size:pageSize?pageSize:20,
55
-  })
56
-  let res:any = await proxy.$http.get(Api.adq_list,paramsModel)
60
+  let res:any = await proxy.$http.get(Api.limit_list)
57 61
   tableListRef.value!.loading = false
58 62
   if(res&&res.errNo=='0'){
59
-    tableInfo.tableList = res.rst.data
60
-    total.value = res.rst.pageInfo.total
63
+    tableInfo.tableList = res.rst
61 64
   }else{
62 65
     ElMessage.error(res.errMsg)
63 66
   }
@@ -65,10 +68,10 @@ const init = async (page?:any,pageSize?:any) => {
65 68
 
66 69
 const deleEvent = async (item:any) => {
67 70
   tableListRef.value!.loading = true
68
-  const paramsModel = reactive<adqParam>({
69
-    account_id:item.id
71
+  const paramsModel = reactive<departParams>({
72
+    id:item.id
70 73
   })
71
-  let res:any = await proxy.$http.post(Api.adq_dele,paramsModel)
74
+  let res:any = await proxy.$http.post(Api.limit_dele,paramsModel)
72 75
   tableListRef.value!.loading = false
73 76
   ElMessage.info(res.errMsg)
74 77
   if(res&&res.errNo=='0'){
@@ -76,9 +79,6 @@ const deleEvent = async (item:any) => {
76 79
   }
77 80
 }
78 81
 
79
-const editEvent = (item:any) => {
80
-
81
-}
82 82
 
83 83
 
84 84
 onMounted( async ()=>{

+ 71 - 20
src/components/businessMoudle/memberManage/dialog/addMember.vue

@@ -8,20 +8,24 @@
8 8
           dialog-title="添加人员">
9 9
     <template v-slot:content>
10 10
       <div class="dialogBox" v-loading="loading">
11
-        <Input ref="nameRef" spanTitleWidth="50px" title="用户名" :haveTag="true"/>
12
-        <Input ref="nameRef" spanTitleWidth="50px" title="密码" :haveTag="true"/>
13
-        <div class="flex">
14
-          <Input ref="nameRef" spanTitleWidth="50px" title="部门" :haveTag="true"/>
15
-          <span>
16
-            <el-icon :size="20"><i-ep-Plus/></el-icon>
17
-            添加部门
18
-          </span>
11
+        <Input ref="nameRef" spanTitleWidth="80px" title="用户名" :haveTag="true"/>
12
+        <Input ref="psdRef" spanTitleWidth="80px" class="tMar20" title="密码" :haveTag="true"/>
13
+        <div class="flex tMar20">
14
+          <span class="spanTitle f14" style="width: 80px;">部门</span>
15
+          <el-tree-select v-model="pageInfo.treeValue"
16
+                          filterable
17
+                          :highlight-current="true"
18
+                          :props="defaultProps"
19
+                          node-key="id"
20
+                          :data="pageInfo.departList"
21
+                          :render-after-expand="false" />
19 22
         </div>
20 23
         <Select ref="ideaManRef"
24
+                spanTitleWidth="80px"
25
+                class="tMar20"
21 26
                 :clearFlag="true"
22 27
                 title="权限"
23
-                :optObj="{k:'id',la:'username',val:'id'}"
24
-                @changeEvent="init()" @clearEvent="init()"
28
+                :optObj="{k:'id',la:'name',val:'id'}"
25 29
                 :options="pageInfo.limitList"/>
26 30
 
27 31
       </div>
@@ -35,7 +39,7 @@ import Dialog from '@/components/capsulationMoudle/_dialog.vue'
35 39
 import Input from '@/components/capsulationMoudle/_input.vue'
36 40
 import {getCurrentInstance, nextTick, onMounted, reactive, ref} from "vue";
37 41
 import {ElMessage} from "element-plus";
38
-import {fileParam, reactiveTableAndAny} from "@/api/ApiModel";
42
+import {departParams, fileParam, reactiveTableAndAny} from "@/api/ApiModel";
39 43
 import {Api} from "@/api/api";
40 44
 
41 45
 const { proxy } = getCurrentInstance() as any;
@@ -47,12 +51,22 @@ const emit = defineEmits<{
47 51
 }>();
48 52
 
49 53
 
54
+const defaultProps = {
55
+  children: 'childs',
56
+  label: 'name',
57
+}
58
+
50 59
 const pageInfo = reactive<reactiveTableAndAny>({
51
-  limitList:[]
60
+  limitList:[],
61
+  departList:[],
62
+  editId:-1,
63
+  treeValue:''
52 64
 })
53 65
 
54 66
 const nameRef=ref<{value:string}>()
55
-const markRef=ref<{value:string}>()
67
+const psdRef=ref<{value:string}>()
68
+const bumenRef=ref<{value:string}>()
69
+const ideaManRef=ref<{value:string}>()
56 70
 const loading=ref<boolean>(false)
57 71
 const confirmEvent = async () => {
58 72
   if(nameRef.value!.value==''){
@@ -60,12 +74,18 @@ const confirmEvent = async () => {
60 74
     return
61 75
   }
62 76
   loading.value = true
63
-  const paramsModel = reactive<fileParam>({
64
-    pid:0,
65
-    name:nameRef.value!.value,
66
-    remarks:markRef.value!.value,
77
+  const paramsModel = reactive<departParams>({
78
+    username:nameRef.value!.value,
79
+    password:psdRef.value!.value,
80
+    department_id:pageInfo.treeValue+'',
81
+    role_id:ideaManRef.value!.value,
67 82
   })
68
-  let res:any = await proxy.$http.post(Api.file_add,paramsModel)
83
+  let api:string = Api.user_add
84
+  if(pageInfo.editId > 0){
85
+    api = Api.user_edit
86
+    paramsModel.id = pageInfo.editId
87
+  }
88
+  let res:any = await proxy.$http.post(api,paramsModel)
69 89
   loading.value = false
70 90
   if(res&&res.errNo=='0'){
71 91
     let resNew:any = res.rst
@@ -76,14 +96,45 @@ const confirmEvent = async () => {
76 96
   }
77 97
 }
78 98
 
99
+const init_depart = async () => {
100
+  let res:any = await proxy.$http.get(Api.depart_list)
101
+  if(res&&res.errNo=='0'){
102
+    let resNew:any = res.rst
103
+    pageInfo.departList = resNew
104
+  }else{
105
+    ElMessage.error(res.errMsg)
106
+  }
107
+}
79 108
 
109
+const init_limit = async () => {
110
+  let res:any = await proxy.$http.get(Api.limit_list)
111
+  if(res&&res.errNo=='0'){
112
+    pageInfo.limitList = res.rst
113
+  }else{
114
+    ElMessage.error(res.errMsg)
115
+  }
116
+}
80 117
 // 切换显隐
81 118
 const dialogShow = ref<boolean>(false)
82
-const switchShow = (val:boolean)=>{
119
+const switchShow = (val:boolean,item?:any)=>{
83 120
   dialogShow.value = val
84 121
   if(val){
85 122
     nextTick(()=>{
86
-      nameRef.value!.value = ''
123
+      init_limit()
124
+      init_depart()
125
+      if(item!.id){
126
+        pageInfo.editId = item!.id
127
+        nameRef.value!.value = item!.username
128
+        psdRef.value!.value = ''
129
+        pageInfo.treeValue = item!.department_id
130
+        ideaManRef.value!.value = item!.role_id
131
+      }else{
132
+        pageInfo.editId =  -1
133
+        nameRef.value!.value = ''
134
+        psdRef.value!.value = ''
135
+        pageInfo.treeValue = ''
136
+        ideaManRef.value!.value = ''
137
+      }
87 138
     })
88 139
   }
89 140
 }

+ 36 - 23
src/components/businessMoudle/memberManage/index.vue

@@ -1,19 +1,15 @@
1 1
 <template>
2
+
2 3
   <div class="screenBox_mini tMar0">
3
-    <Select ref="ideaManRef"
4
-            :clearFlag="true"
5
-            title="账号状态"
6
-            selectWidth="160px"
7
-            :optObj="{k:'id',la:'username',val:'id'}"
8
-            @changeEvent="init()" @clearEvent="init()"
9
-            :options="pageInfo.accStatusList"/>
10
-    <Input ref="InputRef_text" title="" placeholderTxt="用户名或邮箱" @changeEvent="init()" @clearEvent="init()"/>
4
+    <Input ref="InputRef_text" title="" placeholderTxt="名称" @changeEvent="init()" @clearEvent="init()"/>
11 5
   </div>
6
+
7
+
8
+
12 9
   <div class="albumBox flex">
13 10
     <div class="albumTree">
14 11
       <div class="title flex">
15 12
         <el-button type="primary" plain @click="newAddEvent">添加部门</el-button>
16
-        <Input ref="InputRef_text" title="" placeholderTxt="搜索部门" @changeEvent="init()" @clearEvent="init()"/>
17 13
       </div>
18 14
       <div class="companyBox">北京酷炫网络技术股份有限公司</div>
19 15
       <div class="treeBox" v-loading="treeLoading">
@@ -43,7 +39,6 @@
43 39
     <div class="albumContent">
44 40
       <div class="title flex">
45 41
         <el-button type="primary" @click="newAddEvent_member">新增成员</el-button>
46
-        <el-button type="primary" plain @click="startEvent">启用</el-button>
47 42
       </div>
48 43
       <div class="contentBox tMar10" v-loading="fileLoading">
49 44
         <!--  列表-->
@@ -56,9 +51,7 @@
56 51
         >
57 52
           <template v-slot:operate="slotProps">
58 53
             <div class="text-center">
59
-              <span class="operate_text lMar8">编辑</span>
60
-              <Popconfirm key="psd" popTxt="重置密码" @confirm="resetPsd(slotProps.row)"/>
61
-              <Popconfirm key="ty" popTxt="停用" @confirm="outService(slotProps.row)"/>
54
+              <span class="operate_text lMar8" @click="newAddEvent_member(slotProps.row)">编辑</span>
62 55
             </div>
63 56
           </template>
64 57
         </TableList>
@@ -68,6 +61,8 @@
68 61
 
69 62
 <!--  添加部门-->
70 63
   <AddDepartment ref="AddDepartmentRef" @init="init"></AddDepartment>
64
+  <!--  添加部门-->
65
+  <AddMember ref="AddMemberRef" @init="initList"></AddMember>
71 66
 </template>
72 67
 <script setup lang="ts">
73 68
 import {getCurrentInstance, nextTick, onMounted, reactive, ref} from "vue";
@@ -81,6 +76,7 @@ import {ElMessage} from "element-plus";
81 76
 import {publicTableTs} from "@/components/businessMoudle/tableInfo";
82 77
 import Popconfirm from '@/components/capsulationMoudle/_popconfirm.vue'
83 78
 import AddDepartment from '@/components/businessMoudle/memberManage/dialog/addDepartment.vue'
79
+import AddMember from '@/components/businessMoudle/memberManage/dialog/addMember.vue'
84 80
 
85 81
 const { proxy } = getCurrentInstance() as any;
86 82
 // 全局方法定义
@@ -100,6 +96,7 @@ const pageInfo = reactive<reactiveTableAndAny>({
100 96
   treeId:0,
101 97
   accStatusList:[]
102 98
 })
99
+const InputRef_text = ref<{value:string}>()
103 100
 const currentPage = ref<number>(1)
104 101
 const pageSize = ref<number>(20)
105 102
 const fileLoading = ref<boolean>(false)
@@ -108,14 +105,15 @@ const treeLoading = ref<boolean>(false)
108 105
 
109 106
 // 表格数据公共ts
110 107
 const descolParams = reactive([
111
-  { name:'用户名',column:'account_name',},
112
-  { name:'部门',column:'account_id'},
113
-  { name:'权限',column:'type_name',},
114
-  { name:'状态',column:'username',},
108
+  { name:'用户名',column:'username',},
109
+  { name:'部门',column:'department'},
110
+  { name:'权限',column:'role',},
115 111
   { name:'操作',column:'operate',slotFlag: true},
116 112
 ])
117 113
 const { tableInfo,tableListRef,total } = publicTableTs(descolParams)
118 114
 
115
+
116
+
119 117
 // 专辑树点击
120 118
 interface Tree {
121 119
   label: string
@@ -123,6 +121,7 @@ interface Tree {
123 121
 }
124 122
 
125 123
 const AddDepartmentRef = ref<{switchShow:(val:boolean,info?:any)=>void}>()
124
+const AddMemberRef = ref<{switchShow:(val:boolean,info?:any)=>void}>()
126 125
 const newAddEvent = () => {
127 126
   nextTick(()=>{
128 127
     AddDepartmentRef.value!.switchShow(true)
@@ -152,8 +151,10 @@ const deleDepart = async (id:any) => {
152 151
     ElMessage.error(res.errMsg)
153 152
   }
154 153
 }
155
-const newAddEvent_member = () => {
156
-
154
+const newAddEvent_member = (item?:any) => {
155
+  nextTick(()=>{
156
+    AddMemberRef.value!.switchShow(true,item)
157
+  })
157 158
 }
158 159
 const startEvent = () => {
159 160
 
@@ -166,10 +167,21 @@ const init = async () => {
166 167
   if(res&&res.errNo=='0'){
167 168
     let resNew:any = res.rst
168 169
     pageInfo.treeList = resNew
169
-    // if(pageInfo!.treeList!.length>0){
170
-    //   pageInfo.treeId = pageInfo.treeList[pageInfo.treeList.length-1].id
171
-    //   nextTick(()=>{treeRef.value!.setCurrentKey(pageInfo.treeId)})
172
-    // }
170
+  }else{
171
+    ElMessage.error(res.errMsg)
172
+  }
173
+}
174
+
175
+const initList = async () => {
176
+  fileLoading.value = true
177
+  const paramsModel = reactive<departParams>({
178
+    keyword:InputRef_text.value!.value,
179
+  })
180
+  let res:any = await proxy.$http.get(Api.user_list,paramsModel)
181
+  fileLoading.value = false
182
+  if(res&&res.errNo=='0'){
183
+    let resNew:any = res.rst
184
+    tableInfo.tableList = resNew
173 185
   }else{
174 186
     ElMessage.error(res.errMsg)
175 187
   }
@@ -187,6 +199,7 @@ const outService = (item:any)=>{
187 199
 onMounted(()=>{
188 200
   nextTick(async ()=>{
189 201
     await init()
202
+    await initList()
190 203
   })
191 204
 })
192 205
 </script>

+ 84 - 24
src/components/businessMoudle/projectManage/dialog/addProject.vue

@@ -11,15 +11,14 @@
11 11
     <template v-slot:content>
12 12
       <div class="dialogBox" v-loading="loading">
13 13
         <Input ref="nameRef" spanTitleWidth="80px" inputWidth="80%" title="项目名称" :haveTag="true" :haverMar15="false"/>
14
-        <Input ref="nameRef" class="tMar20" spanTitleWidth="80px" inputWidth="80%" title="备注" :haverMar15="false"/>
14
+        <Input ref="noteRef" class="tMar20" spanTitleWidth="80px" inputWidth="80%" title="备注" :haverMar15="false"/>
15 15
         <Select ref="ideaManRef"
16 16
                 class="tMar20"
17 17
                 :clearFlag="true"
18 18
                 title="项目负责人"
19 19
                 selectWidth="190px"
20 20
                 :optObj="{k:'id',la:'username',val:'id'}"
21
-                @changeEvent="init()" @clearEvent="init()"
22
-                :options="pageInfo.chargeList"/>
21
+                :options="pageInfo.userList"/>
23 22
 
24 23
         <div class="flex tMar20" style="align-items: flex-start">
25 24
           <span class="spanTitle f14" style="width: 80px;">项目负责人</span>
@@ -31,35 +30,38 @@
31 30
                           :title="coverRadioList.name"
32 31
                           @returnEvent="val=>{coverRadioList.radioVal = val}"></RadioGroup>
33 32
             </div>
34
-            <template v-show="coverRadioList.radioVal == 'appiont'">
33
+            <div v-show="coverRadioList.radioVal == '2'">
35 34
               <div class="cascader-container left">
36 35
                 <div class="cascader-title">
37
-                  <div class="tab-label active"> 部门 </div>
38
-                  <div class="tab-label"> 人员 </div>
36
+                  <span class="tab-label" :class="pageInfo.titleAc == '1' ? 'active' : ''" @click="pageInfo.titleAc = '1'"> 部门 </span>
37
+                  <span class="tab-label" :class="pageInfo.titleAc == '2' ? 'active' : ''" @click="pageInfo.titleAc = '2'"> 人员 </span>
39 38
                 </div>
40
-                <div class="cascader-list">
41
-                  <el-tree :data="pageInfo.treeList" :props="defaultProps" show-checkbox />
39
+                <div class="cascader-list" v-show="pageInfo.titleAc == '1'">
40
+                  <el-tree ref="treeCascaderRef" @change="handleChange" node-key="id" :data="pageInfo.treeList" :props="defaultProps" show-checkbox />
42 41
                 </div>
43
-                <div class="cascader-list member-parent">
44
-
42
+                <div class="cascader-list member-parent" v-show="pageInfo.titleAc == '2'">
43
+                  <el-tree ref="treeCascaderRef_user" @change="handleChange_user" node-key="id" :data="pageInfo.userList" :props="defaultProps_user" show-checkbox />
45 44
                 </div>
46
-
47 45
               </div>
48 46
               <div class="cascader-container right">
49 47
                 <div class="cascader-title">
50
-                  <span>已选可见人员(4)</span>
51
-                  <span class="clear">清空</span>
48
+                  <span>已选可见人员({{pageInfo.chooseMemberList.length + pageInfo.chooseMemberList_user.length}})</span>
49
+                  <span class="clear" @click="clearEvent">清空</span>
52 50
                 </div>
53 51
                 <div class="cascader-list">
54
-                  <div class="choose-member">
52
+                  <div class="choose-member" v-for="item in pageInfo.chooseMemberList" :key="item.id">
53
+                    <p class="choose">
54
+                      <span class="ellipsis">{{item.name || '-'}}</span>
55
+                    </p>
56
+                  </div>
57
+                  <div class="choose-member" v-for="item in pageInfo.chooseMemberList_user" :key="item.id">
55 58
                     <p class="choose">
56
-                      <span class="ellipsis"></span><el-icon :size="14" color="#999" class="pointer"><i-ep-Close /></el-icon>
59
+                      <span class="ellipsis">{{item.username || '-'}}</span>
57 60
                     </p>
58 61
                   </div>
59 62
                 </div>
60
-
61 63
               </div>
62
-            </template>
64
+            </div>
63 65
           </div>
64 66
         </div>
65 67
 
@@ -90,6 +92,10 @@ const defaultProps = {
90 92
   children: 'childs',
91 93
   label: 'name',
92 94
 }
95
+const defaultProps_user = {
96
+  children: 'childs',
97
+  label: 'username',
98
+}
93 99
 interface radioFace{
94 100
   value:number | string,
95 101
   name:string,
@@ -102,11 +108,11 @@ const coverRadioList = reactive<radioFace>({
102 108
   value:1,
103 109
   name:'项目负责人',
104 110
   EgName:'cover',
105
-  radioVal:'all',
111
+  radioVal:'1',
106 112
   haveNotes:false,
107 113
   list:[
108
-    {name:'所有人可见',value:'all'},
109
-    {name:'指定成员可见',value:'appiont'},
114
+    {name:'所有人可见',value:'1'},
115
+    {name:'指定成员可见',value:'2'},
110 116
   ]
111 117
 })
112 118
 
@@ -117,8 +123,35 @@ const pageInfo = reactive<reactiveTableAndAny>({
117 123
   title:'新增项目',
118 124
   chargeList:[],
119 125
   visibleVal:'',
126
+  titleAc:'1',
127
+  chooseMemberList:[],
128
+  chooseMemberList_user:[],
129
+  userList:[]
120 130
 })
121 131
 
132
+const clearEvent = () => {
133
+  nextTick(()=>{
134
+    pageInfo.chooseMemberList = []
135
+    pageInfo.chooseMemberList_user = []
136
+    treeCascaderRef.value!.setCheckedNodes([])
137
+    treeCascaderRef_user.value!.setCheckedNodes([])
138
+  })
139
+}
140
+
141
+const treeCascaderRef = ref()
142
+const treeCascaderRef_user = ref()
143
+const handleChange = (val:any) => {
144
+  nextTick(()=>{
145
+    pageInfo.chooseMemberList = treeCascaderRef.value!.getCheckedNodes()
146
+  })
147
+}
148
+
149
+const handleChange_user = () => {
150
+  nextTick(()=>{
151
+    pageInfo.chooseMemberList_user = treeCascaderRef_user.value!.getCheckedNodes()
152
+  })
153
+}
154
+
122 155
 const init = async () => {
123 156
   let res:any = await proxy.$http.get(Api.depart_list)
124 157
   if(res&&res.errNo=='0'){
@@ -129,8 +162,20 @@ const init = async () => {
129 162
   }
130 163
 }
131 164
 
165
+const init_userList = async () => {
166
+  let res:any = await proxy.$http.get(Api.user_list)
167
+  if(res&&res.errNo=='0'){
168
+    let resNew:any = res.rst
169
+    pageInfo.userList = resNew
170
+  }else{
171
+    ElMessage.error(res.errMsg)
172
+  }
173
+}
174
+
132 175
 const treeValue=ref('')
133 176
 const nameRef=ref<{value:string}>()
177
+const noteRef=ref<{value:string}>()
178
+const ideaManRef=ref<{value:any}>()
134 179
 const loading=ref<boolean>(false)
135 180
 const confirmEvent = async () => {
136 181
   if(nameRef.value!.value==''){
@@ -138,14 +183,18 @@ const confirmEvent = async () => {
138 183
     return
139 184
   }
140 185
   loading.value = true
141
-  let api:string = Api.depart_add
186
+  let api:string = Api.project_add
142 187
   const paramsModel = reactive<departParams>({
143
-    pid:treeValue.value,
144 188
     name:nameRef.value!.value,
189
+    note:noteRef.value!.value,
190
+    head_user_id:ideaManRef.value!.value,
191
+    show_type:coverRadioList.radioVal,
192
+    department_ids:pageInfo.chooseMemberList.map((el)=>{return el.id}),
193
+    user_ids:pageInfo.chooseMemberList_user.map((el)=>{return el.id}),
145 194
   })
146 195
   if(pageInfo.editId){ // 编辑
147 196
     paramsModel.id = pageInfo.editId
148
-    api = Api.depart_edit
197
+    api = Api.project_edit
149 198
   }
150 199
   let res:any = await proxy.$http.post(api,paramsModel)
151 200
   loading.value = false
@@ -166,13 +215,24 @@ const switchShow = (val:boolean,info?:any)=>{
166 215
   if(val){
167 216
     nextTick(async ()=>{
168 217
       nameRef.value!.value = ''
218
+      noteRef.value!.value = ''
219
+      ideaManRef.value!.value = ''
220
+      coverRadioList.radioVal = '1'
221
+      pageInfo.chooseMemberList = []
222
+      pageInfo.chooseMemberList_user = []
169 223
       treeValue.value = ''
170 224
       pageInfo.editId = ''
225
+      pageInfo.title = '新增项目'
171 226
       await init()
227
+      await init_userList()
172 228
       if(info?.id){ // 编辑
173 229
         pageInfo.editId = info?.id
174 230
         nameRef.value!.value = info.name
175
-        treeValue.value = info.pid
231
+        noteRef.value!.value = info.note
232
+        ideaManRef.value!.value = info.head_user_id
233
+        coverRadioList.radioVal = info.show_type + ''
234
+        pageInfo.chooseMemberList = []
235
+        pageInfo.chooseMemberList_user = []
176 236
         pageInfo.title = '编辑项目'
177 237
       }
178 238
     })

+ 20 - 16
src/components/businessMoudle/projectManage/index.vue

@@ -1,5 +1,7 @@
1 1
 <template>
2 2
   <div class="screenBox flex">
3
+    <Input ref="InputRef_text" title="项目名称" placeholderTxt="项目名称" @changeEvent="init()" @clearEvent="init()"/>
4
+
3 5
     <el-button type="primary" class="lMarauto"  @click="addEvent()">新增项目</el-button>
4 6
   </div>
5 7
 
@@ -13,7 +15,7 @@
13 15
   >
14 16
     <template v-slot:operate="slotProps">
15 17
       <div class="text-center">
16
-        <span class="operate_text lMar8 pointer" @click="editEvent(slotProps.row)">编辑</span>
18
+        <span class="operate_text lMar8 pointer" @click="addEvent(slotProps.row)">编辑</span>
17 19
         <Popconfirm @confirm="deleEvent(slotProps.row)"/>
18 20
       </div>
19 21
     </template>
@@ -24,9 +26,10 @@
24 26
 </template>
25 27
 <script setup lang="ts">
26 28
 import {nextTick, onMounted, reactive, ref, getCurrentInstance} from 'vue'
29
+import Input from '@/components/capsulationMoudle/_input.vue'
27 30
 import Popconfirm from '@/components/capsulationMoudle/_popconfirm.vue'
28 31
 import TableList from '@/components/capsulationMoudle/tableList.vue'
29
-import { adqParam, reactiveTableAndAny} from "@/api/ApiModel";
32
+import {adqParam, departParams, reactiveTableAndAny} from "@/api/ApiModel";
30 33
 import {Api} from "@/api/api";
31 34
 import {ElMessage} from "element-plus";
32 35
 import { publicTableTs } from '@/components/businessMoudle/tableInfo'
@@ -37,16 +40,19 @@ const { proxy } = getCurrentInstance() as any;
37 40
 
38 41
 // 表格数据公共ts
39 42
 const descolParams = reactive([
40
-  { name:'权限名称',column:'account_name',},
41
-  { name:'描述',column:'account_id',cancleForMat:true},
42
-  { name:'更新时间',column:'created_at'},
43
+  { name:'项目名称',column:'name',},
44
+  { name:'备注',column:'note',cancleForMat:true},
45
+  { name:'项目负责人',column:'head_user'},
46
+  { name:'创建人',column:'create_user'},
47
+  { name:'创建时间',column:'created_at'},
48
+  { name:'关联账户数',column:'account_num'},
43 49
   { name:'操作',column:'operate',slotFlag: true},
44 50
 ])
45 51
 const { tableInfo,tableListRef,total } = publicTableTs(descolParams)
46 52
 
47
-const addEvent = () => {
53
+const addEvent = (item?:any) => {
48 54
   nextTick(()=>{
49
-    AddProjectRef.value!.switchShow(true)
55
+    AddProjectRef.value!.switchShow(true,item||'')
50 56
   })
51 57
 }
52 58
 
@@ -57,15 +63,13 @@ const InputRef_text = ref<{value:string}>()
57 63
 //账号列表
58 64
 const init = async (page?:any,pageSize?:any) => {
59 65
   tableListRef.value!.loading = true
60
-  const paramsModel = reactive<adqParam>({
61
-    page:page?page:1,
62
-    page_size:pageSize?pageSize:20,
66
+  const paramsModel = reactive<departParams>({
67
+    name:InputRef_text.value!.value,
63 68
   })
64
-  let res:any = await proxy.$http.get(Api.adq_list,paramsModel)
69
+  let res:any = await proxy.$http.get(Api.project_list,paramsModel)
65 70
   tableListRef.value!.loading = false
66 71
   if(res&&res.errNo=='0'){
67
-    tableInfo.tableList = res.rst.data
68
-    total.value = res.rst.pageInfo.total
72
+    tableInfo.tableList = res.rst
69 73
   }else{
70 74
     ElMessage.error(res.errMsg)
71 75
   }
@@ -73,10 +77,10 @@ const init = async (page?:any,pageSize?:any) => {
73 77
 
74 78
 const deleEvent = async (item:any) => {
75 79
   tableListRef.value!.loading = true
76
-  const paramsModel = reactive<adqParam>({
77
-    account_id:item.id
80
+  const paramsModel = reactive<departParams>({
81
+    id:item.id
78 82
   })
79
-  let res:any = await proxy.$http.post(Api.adq_dele,paramsModel)
83
+  let res:any = await proxy.$http.post(Api.project_dele,paramsModel)
80 84
   tableListRef.value!.loading = false
81 85
   ElMessage.info(res.errMsg)
82 86
   if(res&&res.errNo=='0'){

+ 5 - 2
src/components/capsulationMoudle/_drawer.vue

@@ -1,6 +1,7 @@
1 1
 <template>
2 2
   <el-drawer :model-value="drawerShow"
3 3
              direction="rtl"
4
+             :close-on-click-modal="closeOnModal"
4 5
              :before-close="handleClose"
5 6
              :show-close="false"
6 7
              :size="drawerSize">
@@ -28,12 +29,14 @@ const props = withDefaults(defineProps<{
28 29
   title?: string,
29 30
   drawerShow:boolean,
30 31
   drawerSize?:string,
31
-  headerSlotFlag?:boolean
32
+  headerSlotFlag?:boolean,
33
+  closeOnModal?:boolean
32 34
 }>(),{
33 35
   title: '',
34 36
   drawerShow:false,
35 37
   drawerSize:'80%',
36
-  headerSlotFlag:false
38
+  headerSlotFlag:false,
39
+  closeOnModal:true
37 40
 })
38 41
 // 监听弹框显示
39 42
 // watch(() => props.drawerShow, isShow => {