11<script setup lang="ts">
2- import { ref } from " vue" ;
2+ import { ref , onMounted } from " vue" ;
3+ import { getUserList } from " @/api/system"
4+ import ReCol from " @/components/ReCol" ;
35import { formRules } from " ./utils/rule" ;
46import { FormProps } from " ./utils/types" ;
57
68const props = withDefaults (defineProps <FormProps >(), {
9+ title: " 新增" ,
710 formInline : () => ({
811 name: " " ,
912 code: " " ,
13+ status: 50 ,
14+ is_super_role: false ,
15+ member: [],
1016 remark: " "
1117 })
1218});
1319
20+ const statusOptions = [
21+ {
22+ value: 50 ,
23+ label: " 生效中"
24+ },
25+ {
26+ value: 100 ,
27+ label: " 已失效"
28+ }
29+ ];
30+ const roleOptions = [
31+ {
32+ value: true ,
33+ label: " 是"
34+ },
35+ {
36+ value: false ,
37+ label: " 否"
38+ }
39+ ];
1440const ruleFormRef = ref ();
1541const newFormInline = ref (props .formInline );
1642
1743function getRef() {
1844 return ruleFormRef .value ;
1945}
2046
47+ const fetchUserLoading = ref (false );
48+ const allUsers = ref ([]);
49+
50+ function fetchAllUsers(query ? : string , init : boolean = false ) {
51+ if (! init && ! query ) return ;
52+ fetchUserLoading .value = true ;
53+ allUsers .value .length = 0 ;
54+ let params = {};
55+ if (query ) {params [" username" ] = query ;}
56+ getUserList (params ).then ((res ) => {
57+ // allUsers.value = res.data.list;
58+ const currentUserIds = newFormInline .value .member .map (item => item .id );
59+ const currentUsers = [];
60+ newFormInline .value .member .forEach (user => {
61+ currentUsers .push (user );
62+ })
63+ res .data .list .forEach (user => {
64+ if (! currentUserIds .includes (user .id )) {
65+ currentUsers .push (user );
66+ }
67+ })
68+ allUsers .value = currentUsers ;
69+ fetchUserLoading .value = false ;
70+ })
71+ }
72+
73+ onMounted (() => {
74+ fetchAllUsers (" " , true );
75+ })
76+
2177defineExpose ({ getRef });
2278 </script >
2379
@@ -28,28 +84,176 @@ defineExpose({ getRef });
2884 :rules =" formRules"
2985 label-width =" 82px"
3086 >
31- <el-form-item label =" 角色名称" prop =" name" >
32- <el-input
33- v-model =" newFormInline.name"
34- clearable
35- placeholder =" 请输入角色名称"
36- />
37- </el-form-item >
38-
39- <el-form-item label =" 角色标识" prop =" code" >
40- <el-input
41- v-model =" newFormInline.code"
42- clearable
43- placeholder =" 请输入角色标识"
44- />
45- </el-form-item >
46-
47- <el-form-item label =" 备注" >
48- <el-input
49- v-model =" newFormInline.remark"
50- placeholder =" 请输入备注信息"
51- type =" textarea"
52- />
53- </el-form-item >
87+ <el-row :gutter =" 30" >
88+ <re-col :value =" 12" :xs =" 24" :sm =" 24" >
89+ <el-form-item label =" 名称" prop =" name" >
90+ <el-input
91+ v-model =" newFormInline.name"
92+ clearable
93+ placeholder =" 请输入角色名称"
94+ />
95+ </el-form-item >
96+ </re-col >
97+ <re-col :value =" 12" :xs =" 24" :sm =" 24" >
98+ <el-form-item label =" 部门编号" prop =" code" >
99+ <el-input
100+ v-model =" newFormInline.code"
101+ clearable
102+ placeholder =" 请输入角色编号"
103+ />
104+ </el-form-item >
105+ </re-col >
106+
107+ <re-col :value =" 12" :xs =" 24" :sm =" 24" >
108+ <el-form-item label =" 状态" >
109+ <el-select
110+ v-model =" newFormInline.status"
111+ placeholder =" 请选择状态"
112+ class =" w-full"
113+ clearable
114+ >
115+ <el-option
116+ v-for =" (item, index) in statusOptions"
117+ :key =" index"
118+ :label =" item.label"
119+ :value =" item.value"
120+ />
121+ </el-select >
122+ </el-form-item >
123+ </re-col >
124+
125+ <re-col :value =" 12" :xs =" 24" :sm =" 24" >
126+ <el-form-item label =" SuperRole" >
127+ <el-select
128+ v-model =" newFormInline.is_super_role"
129+ placeholder =" 请选择"
130+ class =" w-full"
131+ clearable
132+ >
133+ <el-option
134+ v-for =" (item, index) in roleOptions"
135+ :key =" index"
136+ :label =" item.label"
137+ :value =" item.value"
138+ />
139+ </el-select >
140+ </el-form-item >
141+ </re-col >
142+ <re-col >
143+ <el-form-item label =" 成员" >
144+ <el-select
145+ v-model =" newFormInline.member"
146+ :loading =" fetchUserLoading"
147+ value-key =" id"
148+ multiple
149+ filterable
150+ remote
151+ reserve-keyword
152+ :remote-method =" fetchAllUsers"
153+ placeholder =" 请输入备注信息"
154+ >
155+ <el-option
156+ v-for =" user in allUsers"
157+ :key =" user.id"
158+ :label =" user.username"
159+ :value =" user"
160+ />
161+ <template #loading >
162+ <el-icon class =" is-loading" >
163+ <svg class =" circular" viewBox =" 0 0 20 20" >
164+ <g
165+ class =" path2 loading-path"
166+ stroke-width =" 0"
167+ style =" animation : none ; stroke : none "
168+ >
169+ <circle r =" 3.375" class =" dot1" rx =" 0" ry =" 0" />
170+ <circle r =" 3.375" class =" dot2" rx =" 0" ry =" 0" />
171+ <circle r =" 3.375" class =" dot4" rx =" 0" ry =" 0" />
172+ <circle r =" 3.375" class =" dot3" rx =" 0" ry =" 0" />
173+ </g >
174+ </svg >
175+ </el-icon >
176+ </template >
177+ </el-select >
178+ </el-form-item >
179+ </re-col >
180+ <re-col >
181+ <el-form-item label =" 备注" >
182+ <el-input
183+ v-model =" newFormInline.remark"
184+ placeholder =" 请输入备注信息"
185+ type =" textarea"
186+ />
187+ </el-form-item >
188+ </re-col >
189+ </el-row >
54190 </el-form >
55191</template >
192+
193+ <style >
194+ .circular {
195+ display : inline ;
196+ height : 30px ;
197+ width : 30px ;
198+ animation : loading-rotate 2s linear infinite ;
199+ }
200+ .path {
201+ animation : loading-dash 1.5s ease-in-out infinite ;
202+ stroke-dasharray : 90 , 150 ;
203+ stroke-dashoffset : 0 ;
204+ stroke-width : 2 ;
205+ stroke : var (--el-color-primary );
206+ stroke-linecap : round ;
207+ }
208+ .loading-path .dot1 {
209+ transform : translate (3.75px , 3.75px );
210+ fill : var (--el-color-primary );
211+ animation : custom-spin-move 1s infinite linear alternate ;
212+ opacity : 0.3 ;
213+ }
214+ .loading-path .dot2 {
215+ transform : translate (calc (100% - 3.75px ), 3.75px );
216+ fill : var (--el-color-primary );
217+ animation : custom-spin-move 1s infinite linear alternate ;
218+ opacity : 0.3 ;
219+ animation-delay : 0.4s ;
220+ }
221+ .loading-path .dot3 {
222+ transform : translate (3.75px , calc (100% - 3.75px ));
223+ fill : var (--el-color-primary );
224+ animation : custom-spin-move 1s infinite linear alternate ;
225+ opacity : 0.3 ;
226+ animation-delay : 1.2s ;
227+ }
228+ .loading-path .dot4 {
229+ transform : translate (calc (100% - 3.75px ), calc (100% - 3.75px ));
230+ fill : var (--el-color-primary );
231+ animation : custom-spin-move 1s infinite linear alternate ;
232+ opacity : 0.3 ;
233+ animation-delay : 0.8s ;
234+ }
235+ @keyframes loading-rotate {
236+ to {
237+ transform : rotate (360deg );
238+ }
239+ }
240+ @keyframes loading-dash {
241+ 0% {
242+ stroke-dasharray : 1 , 200 ;
243+ stroke-dashoffset : 0 ;
244+ }
245+ 50% {
246+ stroke-dasharray : 90 , 150 ;
247+ stroke-dashoffset : -40px ;
248+ }
249+ 100% {
250+ stroke-dasharray : 90 , 150 ;
251+ stroke-dashoffset : -120px ;
252+ }
253+ }
254+ @keyframes custom-spin-move {
255+ to {
256+ opacity : 1 ;
257+ }
258+ }
259+ </style >
0 commit comments