sasp-admin 0.2.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/index.js +227 -0
  2. package/package.json +19 -0
  3. package/router.js +83 -0
  4. package/src/assets/font/iconfont.css +1346 -0
  5. package/src/assets/font/iconfont.eot +0 -0
  6. package/src/assets/font/iconfont.js +1 -0
  7. package/src/assets/font/iconfont.svg +827 -0
  8. package/src/assets/font/iconfont.ttf +0 -0
  9. package/src/assets/font/iconfont.woff +0 -0
  10. package/src/assets/images/loading-bar.gif +0 -0
  11. package/src/assets/js/adminInstall.js +36 -0
  12. package/src/assets/js/api/apiAdmin.js +613 -0
  13. package/src/assets/js/global/dataGlobal.js +260 -0
  14. package/src/assets/js/global/logGlobal.js +22 -0
  15. package/src/assets/js/global/paramGlobal.js +67 -0
  16. package/src/assets/js/global/resGlobal.js +91 -0
  17. package/src/assets/js/global/userGlobal.js +283 -0
  18. package/src/components/complexViewRendering.vue +601 -0
  19. package/src/components/ifmLink.vue +71 -0
  20. package/src/components/public/data/plDataCascader.vue +85 -0
  21. package/src/components/public/data/plDataRadio.vue +73 -0
  22. package/src/components/public/data/plDataRadioGroup.vue +70 -0
  23. package/src/components/public/data/plDataSelect.vue +856 -0
  24. package/src/components/public/data/plDatePicker.vue +159 -0
  25. package/src/components/public/org/bg.png +0 -0
  26. package/src/components/public/org/sysOrgPosUserSelect.vue +1237 -0
  27. package/src/components/public/org/sysOrgPosUserSelectDark.vue +1402 -0
  28. package/src/components/public/org/sysOrgPosUserSelectNew.vue +1527 -0
  29. package/src/components/public/upload/images/compress.png +0 -0
  30. package/src/components/public/upload/images/emipty.png +0 -0
  31. package/src/components/public/upload/images/excel.png +0 -0
  32. package/src/components/public/upload/images/file.png +0 -0
  33. package/src/components/public/upload/images/pdf.png +0 -0
  34. package/src/components/public/upload/images/powerpoint.png +0 -0
  35. package/src/components/public/upload/images/project.png +0 -0
  36. package/src/components/public/upload/images/sound.png +0 -0
  37. package/src/components/public/upload/images/txt.png +0 -0
  38. package/src/components/public/upload/images/video.png +0 -0
  39. package/src/components/public/upload/images/visio.png +0 -0
  40. package/src/components/public/upload/images/word.png +0 -0
  41. package/src/components/public/upload/plImage.vue +287 -0
  42. package/src/components/public/upload/plImgUpload.vue +137 -0
  43. package/src/components/public/upload/plUpload.vue +1124 -0
  44. package/src/components/public/upload/uploadImg.js +8 -0
  45. package/src/main.js +0 -0
  46. package/src/views/VueMenuView.vue +143 -0
  47. package/src/views/cloudMenuView.vue +125 -0
  48. package/src/views/complex/config/complex.vue +501 -0
  49. package/src/views/complex/config/complexSetting.vue +1250 -0
  50. package/src/views/complex/rendering/complexShow.vue +16 -0
  51. package/src/views/data/dataManage.vue +560 -0
  52. package/src/views/data/sysData.vue +292 -0
  53. package/src/views/event/eventManager/vueEventDiy.vue +1184 -0
  54. package/src/views/event/eventManager/vueEventMain.vue +108 -0
  55. package/src/views/event/eventManager/vueEventSys.vue +296 -0
  56. package/src/views/event/js/apiEvent.js +22 -0
  57. package/src/views/fileLog/fileDownloadLog.vue +437 -0
  58. package/src/views/initData/initData.vue +4316 -0
  59. package/src/views/log/dblog/logdbDevelop.vue +306 -0
  60. package/src/views/log/dblog/logdbEnt.vue +331 -0
  61. package/src/views/log/dblog/logdbGov.vue +395 -0
  62. package/src/views/log/error/logError.vue +553 -0
  63. package/src/views/log/loginlog/logManageDevOrSup.vue +357 -0
  64. package/src/views/log/loginlog/logManageEnt.vue +343 -0
  65. package/src/views/log/loginlog/logManageGov.vue +328 -0
  66. package/src/views/log/sms/logSms.vue +308 -0
  67. package/src/views/menu/component/menuManageComponent.vue +2402 -0
  68. package/src/views/menu/component/menuModule.vue +449 -0
  69. package/src/views/menu/menuLocal.vue +223 -0
  70. package/src/views/menu/menuManage.vue +1135 -0
  71. package/src/views/menu/tenantMenuManage.vue +1132 -0
  72. package/src/views/menuRouter/cview/cviewShow.vue +18 -0
  73. package/src/views/menuRouter/cviewMenuRouter.vue +183 -0
  74. package/src/views/menuRouter/menuView.vue +132 -0
  75. package/src/views/menuRouter/urlMenuRouter.vue +160 -0
  76. package/src/views/org/entOrgTree.vue +1050 -0
  77. package/src/views/org/ownerMenu/ownerMenuTree.vue +269 -0
  78. package/src/views/org/safeValidate/safeValidate.vue +469 -0
  79. package/src/views/org/sysEntOrgUserDetail.vue +3390 -0
  80. package/src/views/org/sysOrgDimension.vue +832 -0
  81. package/src/views/org/sysOrgPosUserDetail.vue +1648 -0
  82. package/src/views/org/sysOrgPosUserTree.vue +1101 -0
  83. package/src/views/org/sysOrgTree.vue +864 -0
  84. package/src/views/param/sysParam.vue +987 -0
  85. package/src/views/preview/pdfViewer.vue +82 -0
  86. package/src/views/resources/js/resourcesCommon.js +137 -0
  87. package/src/views/resources/resRouter/resView.vue +161 -0
  88. package/src/views/resources/resourcesTabs.vue +82 -0
  89. package/src/views/resources/tabs/comp/pageResPreview.vue +309 -0
  90. package/src/views/resources/tabs/comp/pageResRegister.vue +1120 -0
  91. package/src/views/resources/tabs/dataResources.vue +843 -0
  92. package/src/views/resources/tabs/pageResources.vue +970 -0
  93. package/src/views/role/allowMenu.vue +148 -0
  94. package/src/views/role/authRole/authRole.vue +427 -0
  95. package/src/views/role/authRole/component/allocateSetting.vue +1056 -0
  96. package/src/views/role/authRole/component/authSetting.vue +1196 -0
  97. package/src/views/role/commonRole/commonRole.vue +677 -0
  98. package/src/views/role/commonRole/compoment/allocateRoleMenuSetting.vue +335 -0
  99. package/src/views/role/commonRole/compoment/authLinkMenuTree.vue +55 -0
  100. package/src/views/role/commonRole/compoment/authSettingNew.vue +190 -0
  101. package/src/views/role/commonRole/compoment/commonSetting.vue +1576 -0
  102. package/src/views/role/commonRole/compoment/commonSettingAdjust.vue +584 -0
  103. package/src/views/role/commonRole/compoment/commonSettingNew.vue +572 -0
  104. package/src/views/role/commonRole/compoment/roleMenuPower.vue +226 -0
  105. package/src/views/role/commonRole/compoment/roleMenuPowerSetting.vue +69 -0
  106. package/src/views/role/commonRole/compoment/roleMenuSetting.vue +365 -0
  107. package/src/views/role/commonRole/compoment/roleSourceSetting.vue +229 -0
  108. package/src/views/role/commonRole/tenantCommonRole.vue +768 -0
  109. package/src/views/role/role.vue +135 -0
  110. package/src/views/role/roleMenuOption.vue +898 -0
  111. package/src/views/role/roleSynchroRemind.vue +399 -0
  112. package/src/views/role/sysRole.vue +1525 -0
  113. package/src/views/role/viewMenuOptDetail.vue +182 -0
  114. package/src/views/sms/sendSms.vue +164 -0
  115. package/src/views/station/orgStation.vue +561 -0
  116. package/src/views/tenant/appContentManager.vue +938 -0
  117. package/src/views/tenant/appManager.vue +642 -0
  118. package/src/views/tenant/tenantRoleManager.vue +670 -0
  119. package/src/views/tenant/tenantUserManager.vue +615 -0
  120. package/src/views/threeinone/compoment/safeCascadeSelect.vue +327 -0
  121. package/src/views/threeinone/init/safeInitRegion.vue +203 -0
  122. package/src/views/threeinone/safeManager.vue +927 -0
  123. package/src/views/threeinone/safeMenuManage.vue +565 -0
  124. package/src/views/threeinone/safeOrgSpv.vue +364 -0
  125. package/src/views/threeinone/safeSpv/safeSpvLeftTree.vue +109 -0
  126. package/src/views/threeinone/safeSpv/safeSpvMain.vue +335 -0
  127. package/src/views/threeinone/safeSpvEconView.vue +569 -0
  128. package/src/views/threeinone/safeValidateRegion.vue +328 -0
  129. package/src/views/urlResource/urlResource.vue +856 -0
  130. package/src/views/user/empowerUser/empowerEntUserManage.vue +415 -0
  131. package/src/views/user/empowerUser/empowerOrgTree.vue +167 -0
  132. package/src/views/user/empowerUser/empowerUserList.vue +633 -0
  133. package/src/views/user/empowerUser/empowerUserListMenuDeatil.vue +656 -0
  134. package/src/views/user/empowerUser/empowerUserListViewMenuTree.vue +257 -0
  135. package/src/views/user/empowerUser/empowerUserManage.vue +99 -0
  136. package/src/views/user/stationUserManage.vue +934 -0
  137. package/src/views/user/userManage.vue +737 -0
  138. package/src/views/user/userMangement.vue +938 -0
  139. package/src/views/user/viewMenu/viewMenu.vue +113 -0
  140. package/src/views/versionupdatetool/versionUpdateTool.vue +225 -0
  141. package/src/views/versionupdatetool/versioninfomation/verisonInfomationManagement.vue +68 -0
@@ -0,0 +1,938 @@
1
+ <template>
2
+ <el-container style="height: 100%" v-show="show">
3
+ <el-header style="height: auto;">
4
+ <div class="search-form-parent el-card">
5
+ <el-form :inline="true" :model="crud.searchForm" size="small" class="demo-form-inline"
6
+ @keyup.enter.native="crud.doSearch()" onSubmit="return false;">
7
+ <el-form-item label="用户名称">
8
+ <!--<el-input v-model="crud.searchForm.userNamePinYin" placeholder="中文、拼音全拼、简拼"></el-input>-->
9
+ <el-input v-model="crud.searchForm.userName"></el-input>
10
+ </el-form-item>
11
+ <el-form-item label="用户账号">
12
+ <el-input v-model="crud.searchForm.userAccount"></el-input>
13
+ </el-form-item>
14
+ <el-form-item label="用户状态">
15
+ <el-select v-model="crud.searchForm.userStatus" clearable>
16
+ <el-option v-for="item in searchFormUserStatus" :key="item.value" :value="item.value"
17
+ :label="item.label">
18
+ </el-option>
19
+ </el-select>
20
+ </el-form-item>
21
+
22
+ <el-form-item>
23
+ <el-button type="primary" icon="el-icon-search" @click="crud.doSearch()">查询</el-button>
24
+ <el-button icon="el-icon-close" @click="crud.resetSearch()">清空</el-button>
25
+ </el-form-item>
26
+ </el-form>
27
+ </div>
28
+ </el-header>
29
+
30
+ <el-main id="tableMain" style="height: 100%">
31
+ <el-container style="height:100%" class="table-list-container">
32
+ <el-header style="height: auto;" size="medium">
33
+ <el-button type="primary" size="small" round icon="el-icon-circle-plus" @click="addUser()">新增
34
+ </el-button>
35
+ <el-button type="warning" size="small" round
36
+ @click="toggleLockedUser('20')"><i class="saspiconfont pl-icon-pwd"></i><span></span>设为已锁定
37
+ </el-button>
38
+ <el-button type="success" size="small" round
39
+ @click="toggleLockedUser('10')"><i class="saspiconfont pl-icon-08"></i><span></span>解锁
40
+ </el-button>
41
+ <!--<el-button v-if="mayOperate == true" type="danger" size="small" round
42
+ icon="el-icon-delete" @click="remove()">删除
43
+ </el-button>
44
+ <el-button v-if="mayOperate == true" type="info" size="small" round
45
+ icon="el-icon-share" @click="mount()">挂载
46
+ </el-button>-->
47
+ <el-button type="danger" size="small" round
48
+ icon="el-icon-delete" @click="remove()">删除
49
+ </el-button>
50
+ <el-button type="info" size="small" round
51
+ icon="el-icon-share" @click="mount()">挂载
52
+ </el-button>
53
+ </el-header>
54
+ <el-main style="height: 100%;" ref="tableMain">
55
+ <el-table :data="crud.dataStore.records" :ref="crud.tableRef" stripe border height="100%"
56
+ style="width: 100%;">
57
+ <el-table-column type="selection" width="40" align="center"></el-table-column>
58
+ <el-table-column type="index" label="序号" align="center" width="60"></el-table-column>
59
+ <el-table-column prop="image" label="用户头像" align="center" >
60
+ <!-- 图片的显示 -->
61
+ <template slot-scope="scope">
62
+ <img :src="imageUrl+scope.row.id" class="avatar" >
63
+ <!--<img :src="scope.row.image" min-width="70" height="70" />-->
64
+ </template>
65
+ </el-table-column>
66
+ <el-table-column label="用户名称" prop="userName" align="center"></el-table-column>
67
+ <el-table-column label="用户账号" prop="userAccount" align="center"></el-table-column>
68
+ <el-table-column label="手机号" prop="userPhone" align="center"></el-table-column>
69
+ <el-table-column label="邮箱" prop="userEmail" align="center"></el-table-column>
70
+ <el-table-column label="身份证" prop="userIdcard" align="center"></el-table-column>
71
+ <!--<el-table-column label="所在组织" prop="orgName" align="center"></el-table-column>-->
72
+ <el-table-column label="当前状态" prop="userStatus" align="center" width="150">
73
+ <template slot-scope="scope">
74
+ <el-tag :type="userStatusColor[scope.row.userStatus]">
75
+ {{userStatusObj[scope.row.userStatus]}}
76
+ </el-tag>
77
+ </template>
78
+ </el-table-column>
79
+ <el-table-column label="操作" align="center" width="350">
80
+ <template slot-scope="scope">
81
+ <el-button size="small" icon="el-icon-edit" type="primary"
82
+ v-if="scope.row.created == loginUser.id || mayOperate"
83
+ @click="updateData(scope.row)">
84
+ 修改
85
+ </el-button>
86
+ <!--<el-button size="small" icon="el-icon-edit-outline" type="primary" v-if="queryUserType != 'ent'"-->
87
+ <!--@click="changePwd(scope.row)">-->
88
+ <!--修改密码-->
89
+ <!--</el-button>-->
90
+ <el-button size="small" icon="el-icon-setting" type="primary"
91
+ v-if="scope.row.created == loginUser.id || mayOperate"
92
+ @click="resetPwd(scope.row)">
93
+ 重置密码
94
+ </el-button>
95
+ </template>
96
+ </el-table-column>
97
+ </el-table>
98
+ </el-main>
99
+ </el-container>
100
+ </el-main>
101
+
102
+ <el-footer>
103
+ <el-pagination
104
+ :ref="crud.pageRef"
105
+ :page-sizes="crud.pageSizes"
106
+ :page-size="crud.pageSize"
107
+ :current-page="crud.page"
108
+ :total="crud.dataStore.total"
109
+ @size-change="crud.sizeChange()"
110
+ @current-change="crud.currentPage()"
111
+ layout="total, sizes, prev, pager, next, jumper">
112
+ </el-pagination>
113
+ </el-footer>
114
+
115
+ <el-dialog :close-on-click-modal=false :title="title" top="10vh" :visible.sync="formDataDialog">
116
+ <el-form :model="formData" ref="formDataRef" :rules="rules">
117
+ <el-row>
118
+ <el-col :span="12">
119
+ <el-row>
120
+ <el-col :span="24">
121
+ <el-form-item label="用户姓名" label-width="150px" prop="userName" >
122
+ <el-input v-model="formData.userName" ></el-input>
123
+ </el-form-item>
124
+ </el-col>
125
+ </el-row>
126
+
127
+ <el-row>
128
+ <el-col :span="24">
129
+ <el-form-item label="用户账号" label-width="150px" prop="userAccount">
130
+ <el-input v-model="formData.userAccount"></el-input>
131
+ </el-form-item>
132
+ </el-col>
133
+ </el-row>
134
+ <el-row>
135
+ <el-col :span="24">
136
+ <el-form-item label="手机" label-width="150px" prop="userPhone">
137
+ <el-input v-model="formData.userPhone"></el-input>
138
+ </el-form-item>
139
+ </el-col>
140
+ </el-row>
141
+ </el-col>
142
+ <el-col :span="12">
143
+ <el-form-item label="头像" label-width="150px">
144
+ <pl-image
145
+ :fkid="formData.imageId"
146
+ :img-width="260"
147
+ :img-height="160"
148
+ :max-size="2"
149
+ unit="MB"></pl-image>
150
+ </el-form-item>
151
+ </el-col>
152
+ </el-row>
153
+ <el-row>
154
+ <el-col :span="12">
155
+ <el-form-item label="电子邮箱" label-width="150px" prop="userEmail">
156
+ <el-input v-model="formData.userEmail"></el-input>
157
+ </el-form-item>
158
+ </el-col>
159
+ <el-col :span="12">
160
+ <el-form-item label="QQ" label-width="150px" prop="userQq">
161
+ <el-input v-model="formData.userQq"></el-input>
162
+ </el-form-item>
163
+ </el-col>
164
+ </el-row>
165
+ <el-row>
166
+ <el-col :span="12">
167
+ <el-form-item label="身份证号" label-width="150px" prop="userIdcard">
168
+ <el-input v-model="formData.userIdcard"></el-input>
169
+ </el-form-item>
170
+ </el-col>
171
+ <el-col :span="12">
172
+ <el-form-item label="微信" label-width="150px" prop="userWechart">
173
+ <el-input v-model="formData.userWechart"></el-input>
174
+ </el-form-item>
175
+ </el-col>
176
+ </el-row>
177
+
178
+ <el-row>
179
+ <el-col :span="12">
180
+ <el-form-item label="用户类型" label-width="150px" prop="userType">
181
+ <el-select v-model="formData.userType" style="width: 100%">
182
+ <el-option v-for="item in typeOptions" :key="item.value" :label="item.label"
183
+ :value="item.value">
184
+ </el-option>
185
+ </el-select>
186
+ </el-form-item>
187
+ </el-col>
188
+ <el-col :span="12">
189
+ <el-form-item label="用户状态" label-width="150px" prop="userStatus">
190
+ <el-select v-model="formData.userStatus" style="width: 100%">
191
+ <el-option v-for="item in statusOptions" :key="item.value" :label="item.label"
192
+ :value="item.value">
193
+ </el-option>
194
+ </el-select>
195
+ </el-form-item>
196
+ </el-col>
197
+ </el-row>
198
+ </el-form>
199
+ <div slot="footer" class="dialog-footer">
200
+ <el-button type="primary" @click="submitForm()" size="small" icon="el-icon-success">确 定</el-button>
201
+ <el-button @click="formDataDialog = false" size="small" icon="el-icon-error">取 消</el-button>
202
+ </div>
203
+ </el-dialog>
204
+ <el-dialog :close-on-click-modal=false top="10vh" :visible.sync="isLoad" :title=orgTitle width="22%" height="70%">
205
+ <el-header>
206
+ <el-select v-model="currentOrgDim" style="width: 180px;margin: 0 5px 0 0"
207
+ @change="dimChange" size="small">
208
+ <el-option v-for="item in sysOrgDimensionArr"
209
+ :value="item.id" :label="item.dimName" :key="item.id">
210
+
211
+ </el-option>
212
+ </el-select>
213
+ <el-input
214
+ :placeholder="searchPlaceHolder"
215
+ v-model="filterText" style="width: 150px;margin-top: 10px" size="small">
216
+ </el-input>
217
+ </el-header>
218
+
219
+ <el-aside style="width: 100%;position: relative" class="asideTree" >
220
+ <common-tree v-if="isLoad" :request-url="api.sysOrg.listNopageDim"
221
+ :checkStrict=true
222
+ :request-param="treeRequestParam"
223
+ :deal-tree-datcheckel-tree-changea="dealTreeData"
224
+ :default-props="defaultProps" parent-id="orgParentId" :filter-text="filterText"
225
+ :refresh-proper="currentOrgDim"
226
+ :node-click="nodeClick" :expand-onclick-node=true
227
+ :init-call-back="initExpandOrignOrg" ref="orgTreeRef" :default-shift-key-select=true
228
+ :default-ctrl-key-select=true :draggable=false
229
+ :tree-node-collapse="treeNodeCollapse"
230
+ :tree-node-expand="treeNodeExpand" :filter-text-call-back="filterTextCallBack">
231
+ </common-tree>
232
+
233
+ </el-aside>
234
+ <div slot="footer" class="dialog-footer">
235
+ <el-button type="primary" @click="saveSetting()" size="small" icon="el-icon-success">保 存</el-button>
236
+ <el-button @click="isLoad = false" size="small" icon="el-icon-error">取 消</el-button>
237
+ </div>
238
+ </el-dialog>
239
+ </el-container>
240
+ </template>
241
+
242
+ <script>
243
+ import EmpowerOrgTree from "./empowerUser/empowerOrgTree";
244
+ export default {
245
+ name: "userMangement",
246
+ components: {
247
+ 'empower-org-tree':EmpowerOrgTree
248
+ },
249
+ data(){
250
+ let vm = this;
251
+ let validUserRepeat = (rule, value, callback) => { // 重名验证
252
+ let obj = {"isExit": "true"};
253
+ if (rule.field == "userAccount") {
254
+ obj["isExituserAccount"] = vm.formData.userAccount;
255
+ } else {
256
+ obj["isExitUserName"] = vm.formData.userName;
257
+ }
258
+ vm.axios.post(vm.api.sysUser.find, obj).then(res => {
259
+ let result = res.data || [];
260
+ if (result.length > 0 && result[0].id != vm.formData.id) {
261
+ callback(new Error("名称重复"));
262
+ } else {
263
+ callback();
264
+ }
265
+ })
266
+ };
267
+ return{
268
+ queryUserType: '', // 链接中传入的用户类型
269
+ show: true, // 当前页面是否有操作权限显示
270
+ crud: new this.CrudUtil({
271
+ vue: this,
272
+ entityName: "sysUser",
273
+ url: this.api.sysUser.url,
274
+ addDefaultData: {"userStatus": "10"},
275
+ initNoSearch: true,
276
+ searchForm:{rows: 10,page:0,status:1},
277
+ deleteUrl:api.sysUser.logicDelete
278
+ }),
279
+ userStatusObj: {
280
+ '10': "正常",
281
+ '20': "锁定",
282
+ '30': "暂时锁定"
283
+ },
284
+ userStatusColor: {
285
+ '10': "success",
286
+ '20': "warning",
287
+ '30': "danger"
288
+ },
289
+ searchFormUserStatus: [
290
+ {value: '10', label: "正常"},
291
+ {value: '20', label: "锁定"},
292
+ {value: '30', label: "暂时锁定"}
293
+ ],
294
+ statusOptions: [
295
+ {value: '10', label: "正常"},
296
+ {value: '20', label: "锁定"}
297
+ ], // 用户状态下拉框
298
+ sexOptions: [
299
+ {value: '男', label: "男"},
300
+ {value: '女', label: "女"}
301
+ ],
302
+
303
+ formDataDialog: false, // 用户信息对话框
304
+ loading: true, // 加载条
305
+ formData: {
306
+ 'id': "", 'userAccount': "", 'userName': "", 'userType': "", 'userStatus': "",
307
+ 'userGender': "", 'userAge': "", 'userPhone': "", 'userEmail': "",
308
+ 'userIdcard':"",'userWechart':"",'userQq':""
309
+ }, // 修改表单用户信息
310
+ typeOptions: [], // 用户类型下拉框
311
+ devTypeOptions: [{value: 'dev', label: '开发者'}], // dev用户类型仅可选一个
312
+ editUserDetail: false, // 是否可以编辑用户详情
313
+ title: "", // 表单标题
314
+ mayOperate: false, // 是否可以操作当前数据,如果是开发者可以
315
+ loginUser: {},//登录对象
316
+ //表单验证
317
+ rules: {
318
+ userAccount: [
319
+ {
320
+ required: true,
321
+ message: '该输入项为必输项',
322
+ trigger: 'blur'
323
+ }
324
+ ],
325
+ userName: [
326
+ {required: true, message: '该输入项为必输项',trigger: 'blur'}
327
+ ],
328
+ userStatus: this.plValidate('required'),
329
+ userPhone: [
330
+ {
331
+ required: true,
332
+ message: '该输入项为必输项',
333
+ trigger: 'blur'
334
+ },
335
+ {
336
+ validator: this.platValidator.mobile,
337
+ trigger: 'blur'
338
+ }
339
+ ],
340
+ userEmail: this.plValidate('email'),
341
+ userIdcard: this.plValidate('idcard'),
342
+ userQq: this.plValidate('qq'),
343
+ /*userType: this.plValidate('required'),*/
344
+ },
345
+ imageUrl:'',
346
+ isLoad:false,
347
+ treeRequestParam:{}, // 组织树的过滤条件
348
+ currentOrgDim: "", // 当前维度
349
+ orgType: "", // 当前组织类型
350
+ defaultProps: {children: 'children', label: 'orgName'},
351
+ filterText: "", // 过滤树节点的变量
352
+ orgTypeArr: [], // 所有组织类型
353
+ cascadeOptions: [], // 地区选项
354
+ sysOrgDimensionArr: [], // 所有维度
355
+ orgTitle:'',
356
+ searchPlaceHolder: "请输入组织名称",
357
+ noAuth: false, // 没有权限
358
+ currentOrgId: "", // 当前组织id
359
+ currentObj: {}, // 当前节点数据
360
+ openLowLevelCheckbox:{type:Boolean,default:false},//是否开启组织下级权限复选框
361
+ isChecked:{},
362
+ checkedOrg:[],
363
+ checkedPos:[],
364
+ checkedUser:[],
365
+ }
366
+ },
367
+ created() { // 初始化时先获取数据操作权限,然后根据是否开启操作权限获取权限数据
368
+ let vm = this;
369
+ this.imageUrl = vm.api.baseUploadUrl+'downloadFile?id=';
370
+ vm.initOriginData();
371
+ vm.initLoginUser();
372
+ vm.initOriginDates(); // 初始化下拉数据等,并初始化权限,仅初始化一次
373
+ vm.init();
374
+ },
375
+ methods:{
376
+ async initOriginData() {
377
+ let vm = this;
378
+ await vm.axios.post(vm.api.param.getSysParams).then(function (res) { // 是否可以修改用户详情,获取用户的类型
379
+ let sysParamObj = res.data;
380
+ let paramValString = sysParamObj["SysUserType"]["paramVal"];
381
+ let result = JSON.parse(vm.platStringUtil.replaceAll(paramValString, "'", "\""));
382
+ for (let [key, value] of Object.entries(result)) {
383
+ vm.typeOptions.push({"label": value, "value": key})
384
+ }
385
+ });
386
+ },
387
+ init() {
388
+ this.crud.search();
389
+ },
390
+ /**
391
+ * 当前登录用户
392
+ */
393
+ initLoginUser() {
394
+ let vm = this;
395
+ vm.axios.post(vm.api.sysUser.getLoginUser).then(function (res) {
396
+ vm.loginUser = res.data;
397
+ if (vm.loginUser.userType == "dev" || vm.loginUser.userType == "sup") {
398
+ vm.mayOperate = true;
399
+ }
400
+ });
401
+ },
402
+ /**
403
+ * 锁定和解锁
404
+ */
405
+ toggleLockedUser(status) {
406
+ let vm = this;
407
+ let selection = vm.$refs[vm.crud.setting.tableRef].selection;
408
+ if ((selection || []).length === 0) {
409
+ vm.$message({
410
+ message: "请选择要操作的用户!",
411
+ duration: 1500
412
+ });
413
+ return;
414
+ }
415
+ let message = '锁定';
416
+ if (status == '10') {
417
+ message = '正常';
418
+ }
419
+ vm.$confirm('是否要设置选中的<span style="color: red;">' + selection.length + '</span>个用户状态为' + message + '?', '提示', {
420
+ confirmButtonText: '确定',
421
+ cancelButtonText: '取消',
422
+ dangerouslyUseHTMLString: true
423
+ }).then(function () {
424
+ let arrIds = [];
425
+ selection.forEach(function (data) {
426
+ arrIds.push(data.id);
427
+ });
428
+ vm.crud.axios.post(vm.api.sysUser.settingLockedUser, {
429
+ "ids": arrIds.join(","),
430
+ "userStatus": status
431
+ }).then(function (response) {
432
+ vm.$message({
433
+ type: 'success',
434
+ message: response.data.operateMessage
435
+ });
436
+ vm.crud.search();
437
+ });
438
+ });
439
+ },
440
+ /**
441
+ * 重置密码
442
+ * @param row
443
+ */
444
+ resetPwd(row) { //
445
+ let [vm, userNameText] = [this, row.userName ? row.userName : '用户'];
446
+ this.$confirm('确定要重置' + userNameText + '的密码?', '提示', {
447
+ confirmButtonText: '确定',
448
+ cancelButtonText: '取消',
449
+ type: 'warning',
450
+ beforeClose: function (action, instance, done) {
451
+ if (action == 'confirm') {
452
+ vm.axios.post(vm.api.sysUser.resetPwd, {"id": row.id}).then(function (res) {
453
+ done(); // 完成后提示并关闭窗口
454
+ vm.$message({
455
+ type: 'success',
456
+ duration: 1500,
457
+ message: res.data.operateMessage
458
+ });
459
+ });
460
+ } else {
461
+ done();
462
+ }
463
+ }
464
+ }).catch(() => {
465
+ this.$message({
466
+ type: 'info',
467
+ message: '已取消'
468
+ });
469
+ });
470
+ },
471
+ /**
472
+ * 修改
473
+ */
474
+ updateData(row) { // 修改用户的基本信息(新增系统参数,是否允许修改用户详情)
475
+ let vm = this;
476
+ if (!row.id) {
477
+ vm.$message("数据异常,请重新加载页面!");
478
+ return;
479
+ }
480
+ vm.title = "修改用户信息";
481
+ vm.formData = {}; // 先清除表单中的数据
482
+ vm.addUserInfo = false; // 默认不添加用户详情
483
+ let obj = Object.assign({}, row);
484
+ let arr = ['id', 'userAccount', 'userName', 'userType', 'userStatus','userQq', 'userPhone',
485
+ 'userEmail','userIdcard','userWechart'];
486
+ for (let elem of arr) {
487
+ vm.$set(vm.formData, elem, obj[elem]);
488
+ }
489
+ /*if (vm.editUserDetail) {
490
+ vm.axios.post(vm.api.sysUser.find, {"id": row.id}).then(function (res) {
491
+ if (res.data.length > 0) { // 按理说只有一条信息,如果没有那是旧数据,我们帮忙插入一条
492
+ let result = res.data[0];
493
+ let tempArr = ['id', 'userAccount', 'userName', 'userType', 'userStatus','userQq', 'userPhone', 'userEmail','userIdcard','userWechart'];
494
+ for (let elem of tempArr) {
495
+ vm.$set(vm.formData, elem, result[elem]);
496
+ }
497
+ }
498
+ })
499
+ }*/
500
+ vm.formDataDialog = true;
501
+ },
502
+ /**
503
+ * 添加
504
+ */
505
+ addUser() { // 添加
506
+ let vm = this;
507
+ //每次新增唯一凭证
508
+ let id='';
509
+ /*vm.axios.post(vm.api.commonmethod.getUuid).then(function (res) {
510
+ if (res.data) {
511
+ id = res.data;
512
+ console.log(id);*/
513
+
514
+ vm.formData = {
515
+ 'id': id, 'userAccount': "", 'userName': "", 'userType': "", 'userStatus': "",
516
+ 'userGender': "", 'userAge': "", 'userQQ': "", 'userPhone': "", 'userEmail': "",
517
+ 'imageId': id,'userIdcard':"",'userWechart':"",'userQq':""
518
+ };
519
+ if (vm.queryUserType == 'dev') { // 开发者添加用户类型仅可添加开发者
520
+ vm.$set(vm.formData, 'userType', 'dev');
521
+ } else {
522
+ vm.$set(vm.formData, 'userType', vm.queryUserType);
523
+ }
524
+ vm.formData = Object.assign({}, vm.formData, vm.crud.addDefaultData);
525
+ vm.title = "添加用户信息";
526
+ vm.formDataDialog = true;
527
+ vm.$nextTick(function () {
528
+ vm.$refs.formDataRef.clearValidate(); // 再次添加清除原先的验证
529
+ })
530
+
531
+
532
+ /*}*!/
533
+ });*/
534
+ },
535
+ /**
536
+ * 表单提交
537
+ */
538
+ submitForm() {
539
+ let vm = this;
540
+ vm.$refs.formDataRef.validate((valid) => { // 表单验证
541
+ if (valid) {
542
+ vm.axios.post(vm.api.sysUser.validateAccountIsNotExists,
543
+ {
544
+ "userAccount": vm.formData.userAccount,
545
+ "userPhone": vm.formData.userPhone,
546
+ "userId": (vm.formData.id || "")
547
+ }).then(function (resValid) { // 验证账号是否存在
548
+
549
+ if (resValid.data) {
550
+
551
+ if (vm.formData.id) { // update
552
+ vm.axios.post(vm.api.sysUser.updateUser, vm.formData).then(function (res) {
553
+ vm.$message({
554
+ duration: 1000,
555
+ type: 'success',
556
+ message: res.data.operateMessage
557
+ });
558
+ vm.formDataDialog = false;
559
+ vm.crud.search();
560
+ })
561
+ } else { // add
562
+ vm.axios.post(vm.api.sysUser.addUser, vm.formData).then(function (res) {
563
+ vm.$message({
564
+ duration: 1000,
565
+ type: 'success',
566
+ message: res.data.operateMessage
567
+ });
568
+ vm.formDataDialog = false;
569
+ vm.crud.search();
570
+ })
571
+ }
572
+
573
+ } else {
574
+ vm.$message({
575
+ message: "账号已存在!",
576
+ duration: 1200,
577
+ type: "warning"
578
+ });
579
+ }
580
+
581
+
582
+ });
583
+ }
584
+ });
585
+ },
586
+ /**
587
+ * 删除
588
+ */
589
+ remove() {
590
+ let vm = this;
591
+ let selection = vm.$refs[vm.crud.setting.tableRef].selection;
592
+ if ((selection || []).length === 0) {
593
+ vm.$message({
594
+ duration: 1500,
595
+ type: 'info',
596
+ message: '请至少选择一条需要删除的数据!'
597
+ });
598
+ return;
599
+ }
600
+ if (vm.loginUser.userType == "sup" || vm.loginUser.userType == "dev") {
601
+ vm.crud.remove();
602
+ } else {
603
+ // 判断是否有不是自己创建的数据
604
+ let ifNoCreate = false;
605
+ let loginUserId = vm.loginUser.id;
606
+ selection.forEach(item => {
607
+ if (item.created != loginUserId) {
608
+ ifNoCreate = true;
609
+ }
610
+ });
611
+ if (ifNoCreate) { // 有不是本人创建的数据,不可以删除
612
+ vm.$message({
613
+ duration: 1500,
614
+ type: 'info',
615
+ message: '无法删除非当前用户创建的数据!'
616
+ });
617
+ return;
618
+ }
619
+ vm.crud.remove();
620
+ }
621
+ },
622
+ mount(){
623
+ let vm = this;
624
+ vm.orgTitle='用户挂载';
625
+ vm.isLoad = true;
626
+
627
+ },
628
+ /**
629
+ * 获取当前选中的组织维度
630
+ * @param orgDim
631
+ */
632
+ getOrgTreeInitInfo(orgDim){
633
+ let vm = this;
634
+ vm.currentOrgDim = orgDim;
635
+ },
636
+ /**
637
+ * 刷新用户列表数据
638
+ * @param data
639
+ * @param node
640
+ */
641
+ refreshUserData(data,node){
642
+ let vm = this;
643
+ vm.$refs.empowerUserList.changeSearchForm(data.id);
644
+ },
645
+ /**
646
+ * 获取左侧树数据
647
+ * @param data
648
+ */
649
+ getTreeData(data){
650
+ let vm = this;
651
+ vm.treeData = data;
652
+ },
653
+
654
+ dealTreeData(data) { // 给节点添加自定义图标
655
+ let vm = this;
656
+ for (let elem of data) {
657
+ if (elem["orgType"] == "ogn") {
658
+ elem.className = vm.pageSetting["ognCloseIcon"] || "saspiconfont pl-icon-organ";
659
+ }
660
+ if (elem["orgType"] === "dept") {
661
+ elem.className = vm.pageSetting["deptCloseIcon"] || "saspiconfont pl-icon-untitled85";
662
+ }
663
+ }
664
+ },
665
+ nodeClick(data, node) { // 节点点击事件
666
+ let vm = this;
667
+ console.log("点击了@@@");
668
+ vm.menuVisible = false;
669
+ vm.currentOrgId = data["id"];
670
+ vm.currentObj = Object.assign({}, data);
671
+ },
672
+ initExpandOrignOrg(treeVm) { // 初始化展开第一级组织
673
+ let vm = this;
674
+ let nodesMap = treeVm.getAllNode();
675
+ for (let key in nodesMap) {
676
+ if (nodesMap[key].level === 1 && nodesMap[key].data["orgType"] === 'ogn') {
677
+ nodesMap[key].expanded = true;
678
+ nodesMap[key].data.className = vm.pageSetting["ognOpenIcon"];
679
+ }
680
+ }
681
+ },
682
+ //节点关闭事件
683
+ treeNodeCollapse(data, node, comp) {
684
+ let vm = this;
685
+ if (data.orgType === "ogn") {
686
+ data.className = vm.pageSetting["ognCloseIcon"] || "saspiconfont pl-icon-organ";
687
+ }
688
+ if (data.orgType === "dept") {
689
+ data.className = vm.pageSetting["deptCloseIcon"] || "saspiconfont pl-icon-untitled85";
690
+ }
691
+ },
692
+ // 节点展开事件
693
+ treeNodeExpand(data, node, comp) {
694
+ let vm = this;
695
+ if (data.orgType === "ogn") {
696
+ data.className = vm.pageSetting["ognOpenIcon"] || "saspiconfont pl-icon-organ";
697
+ }
698
+ if (data.orgType === "dept") {
699
+ data.className = vm.pageSetting["deptOpenIcon"] || "saspiconfont pl-icon-untitled85";
700
+ }
701
+ },
702
+ // 过滤文本完成回调
703
+ filterTextCallBack() {
704
+ let vm = this;
705
+ vm.$nextTick(function () {
706
+ let nodesMap = vm.$refs.orgTreeRef.getAllNode();
707
+ for (let [key, node] of Object.entries(nodesMap)) {
708
+ if (node.expanded) {
709
+ if (node.data["orgType"] === "ogn") {
710
+ node.data.className = vm.pageSetting["ognOpenIcon"] || "saspiconfont pl-icon-organ";
711
+ }
712
+ if (node.data["orgType"] === "dept") {
713
+ node.data.className = vm.pageSetting["deptOpenIcon"] || "saspiconfont pl-icon-untitled85";
714
+ }
715
+ } else {
716
+ if (node.data["orgType"] === "ogn") {
717
+ node.data.className = vm.pageSetting["ognCloseIcon"] || "saspiconfont pl-icon-organ";
718
+ }
719
+ if (node.data["orgType"] === "dept") {
720
+ node.data.className = vm.pageSetting["deptCloseIcon"] || "saspiconfont pl-icon-untitled85";
721
+ }
722
+ }
723
+ }
724
+ });
725
+ },
726
+
727
+ initOriginDates() { // 初始化下拉数据等,仅初始化一次
728
+ let vm = this;
729
+ vm.noAuth = false;
730
+ vm.axios.post(vm.api.param.getSysParams, {"key": "SysDataOperation"}).then(function (res) {
731
+ if (res.data.paramVal === '否') {
732
+ vm.initOrigin();
733
+ } else {
734
+ vm.axios.post(vm.api.sysUser.getLoginUser).then(function (res) {
735
+ let loginUser = res.data;
736
+ vm.loginUser = loginUser;
737
+ if (loginUser.userType === 'sup' || loginUser.userType === 'dev') {
738
+ vm.initOrigin();
739
+ }else{
740
+ vm.axios.post(vm.api.sysOrgPosUser.find,{"userId":loginUser.id}).then(posUserRes => {
741
+ if(posUserRes && posUserRes.data.length > 0){
742
+ let posUser = posUserRes.data[0];
743
+ let dim = posUser.orgDim; // 所在维度
744
+ let orgTreeId = posUser.orgId; // 组织树上级
745
+ vm.$set(vm.treeRequestParam,"orgTreeId",orgTreeId);
746
+ vm.initOrigin(dim);
747
+ }else{
748
+ vm.noAuth = true; // 查不到组织架构
749
+ }
750
+ })
751
+ }
752
+ });
753
+ }
754
+ });
755
+ vm.axios.post(vm.api.param.getSysParams, {
756
+ 'key': 'SysOrgType'
757
+ }).then(res => { // 组织类型
758
+ let paramJson = JSON.parse(vm.platStringUtil.replaceAll(res.data.paramVal, "'", "\"")); // 转换组织类型为JSON
759
+ Object.keys(paramJson).forEach(function (key) {
760
+ let obj = {};
761
+ obj["value"] = key;
762
+ obj["label"] = paramJson[key];
763
+ vm.orgTypeArr.push(obj);
764
+ })
765
+ });
766
+ vm.axios.post(vm.api.data.getDataByType, {
767
+ 'typeId': '522eb83216004493b0e0eb729c564941'
768
+ }).then(res => {
769
+ let result = vm.COMMON_FUNC.buildElTree(res.data);
770
+ result.forEach(function (data) {
771
+ if (data.parentId === '-1') {
772
+ let arr = [];
773
+ arr.push(data);
774
+ vm.cascadeOptions = arr;
775
+ }
776
+ });
777
+ })
778
+ },
779
+ initOrigin(dim) { // 初始化,dim选择的维度
780
+ let vm = this;
781
+ vm.showPosUser = false;
782
+ vm.axios.post(vm.api.sysOrgDimension.find).then(res => {
783
+ let data = res.data;
784
+ for (let item of data) {
785
+ if (item.isUse === '1') {
786
+ vm.sysOrgDimensionArr.push(item);
787
+ }
788
+ }
789
+ if (vm.sysOrgDimensionArr) {
790
+ if(dim){
791
+ vm.currentOrgDim = dim;
792
+ }else{
793
+ vm.currentOrgDim = vm.sysOrgDimensionArr[0].id;
794
+ }
795
+ vm.sysOrgDimensionArr.forEach(dimension => {
796
+ if(dimension.id == vm.currentOrgDim){
797
+ vm.initDimSetting(dimension);
798
+ }
799
+ });
800
+ vm.showTree = true;
801
+ vm.showPosUser = true;
802
+ }
803
+ });
804
+ },
805
+ initDimSetting(data) { // 初始化维度配置
806
+ let vm = this;
807
+ let pageSetting = {
808
+ "closeDept": false, // 设置为true时此维度下不包含部门(左侧组织树只有机构)
809
+ "allowAddUser":false, // 允许添加用户
810
+ "ognName": "机构", // 定义机构名称
811
+ "deptName": "部门", // 定义部门名称
812
+ "posName": "岗位", // 定义岗位名称
813
+ "ognOpenIcon": "saspiconfont pl-icon-organ", // 树中组织展开时使用的图标
814
+ "ognCloseIcon": "saspiconfont pl-icon-organ", // 树中组织收缩时使用的图标
815
+ "deptOpenIcon": "saspiconfont pl-icon-untitled85", // 树中组织展开时使用的图标
816
+ "deptCloseIcon": "saspiconfont pl-icon-untitled85", // 树中组织收缩时使用的图标
817
+ "closeMainPos": false, // 关闭主岗位
818
+ "posIcon": "saspiconfont pl-icon-account", // 岗位图标
819
+ "posMainIcon": "saspiconfont pl-icon-yonghu", // 主岗位图标
820
+ "chooseUserType": "" // 可选择的用户类型(默认可选择所有类型用户,如设置ent就只可以选择ent)
821
+ };
822
+ let dimSpec = JSON.parse(data["dimSpec"] || "{}");
823
+ vm.pageSetting = Object.assign({}, pageSetting, dimSpec);
824
+ //vm.searchPlaceHolder = (vm.pageSetting['ognName'] || '机构') + "名称";
825
+ vm.closeMainPos = vm.pageSetting["closeMainPos"];
826
+ vm.closePos = vm.pageSetting["closePos"];
827
+ vm.orgType = vm.pageSetting["closeDept"] ? "ogn" : ""; // 关闭部门后不抓取部门数据
828
+ vm.$set(vm.treeRequestParam,"orgType",vm.orgType);
829
+ vm.$set(vm.treeRequestParam,"orgDim",vm.currentOrgDim);
830
+ },
831
+ dimChange(value) { // 维度切换事件
832
+ let vm = this;
833
+ vm.currentOrgId = "$";
834
+ vm.currentObj = {};
835
+ for (let elem of vm.sysOrgDimensionArr) {
836
+ if (elem.id === value) {
837
+ vm.initDimSetting(elem);
838
+ break;
839
+ }
840
+ }
841
+ },
842
+
843
+ // 当是否开启下级权限同步复选框变化时候 ,如果选中状态自动勾选所有的下级用户(如果下级用户也存在下级则也勾选同步复选框)并且设为禁用
844
+ // 如果取消勾选下级用户,则取消下级用户禁用状态,并且勾选取消
845
+ dChange(data, checked){
846
+ let vm = this;
847
+ let temple = vm.$refs.orgTreeRef;
848
+ let allChilren = temple.getCurrentChildren(data,[]) || []; //获取当前节点下的所有子节点(包含自己)
849
+ let nodesMap = temple.getAllNode(); // 节点集合
850
+ vm.stopChange = true;
851
+ allChilren.forEach(key => {
852
+ let Tdata = nodesMap[key]["data"];
853
+ if(key == data.id){
854
+ vm.$set(Tdata,"disabled",false);
855
+ Tdata["cascadeData"] = "parent";
856
+ }else{
857
+ vm.$set(Tdata,"disabled",checked);
858
+ Tdata["cascadeData"] = checked?"true":"";
859
+ if(checked){
860
+ nodesMap[key]["checked"] = false;
861
+ vm.isChecked[key] = false;
862
+ }
863
+ }
864
+ });
865
+ vm.$nextTick(() => {
866
+ vm.stopChange = false;
867
+ })
868
+ },
869
+ checkelTreeChange(data,checked){ // 树节点选中变化时的事件
870
+ console.log("点击复选框%%%%");
871
+ let vm = this;
872
+ let tempObj = {"ogn":"checkedOrg","dept":"checkedOrg","pos":"checkedPos"};
873
+ let operateArr = vm[tempObj[data["nodeType"]]];
874
+ if(checked){
875
+ let flag = false;
876
+ for(let elem of operateArr){
877
+ if(elem["id"] == data["id"]){
878
+ flag = true;
879
+ break;
880
+ }
881
+ }
882
+ if(!flag){
883
+ operateArr.push(data);
884
+ }
885
+ }else{
886
+ if(vm.openLowLevelCheckbox){
887
+ if(!vm.stopChange){
888
+ vm.isChecked[data.id] = false;
889
+ vm.dChange(data,false);
890
+ }
891
+ }
892
+ vm[tempObj[data["nodeType"]]] = operateArr.filter(item => {
893
+ return item["id"] != data["id"];
894
+ });
895
+ }
896
+ },
897
+ getCurrentChildren(node,allNodeArr){ // 获取指定节点的所有下级(包括自己)已选中的id
898
+ let vm = this;
899
+ let childProper = "childNodes";
900
+ if(node.data.id != '-1' && node["checked"]){
901
+ allNodeArr.push(node.data.id);
902
+ }
903
+ if(node[childProper] && node[childProper].length > 0){
904
+ for(let elem of node[childProper]){
905
+ this.getCurrentChildren(elem,allNodeArr);
906
+ }
907
+ }
908
+ return allNodeArr;
909
+ },
910
+ //保存组织
911
+ saveSetting(){
912
+ let vm = this;
913
+ let checkedNodes = vm.$refs.orgTreeRef.getTreeCheckedNodes();
914
+ let checkedSet = new Array(); // 已选择组织
915
+ checkedNodes.forEach(function (data) {
916
+ checkedSet.push(data.id);
917
+ /*if(data.menuPath){
918
+ data.menuPath.split(",").forEach(function (each) {
919
+ effectSet.add(each);
920
+ })
921
+ }*/
922
+ });
923
+ },
924
+ setToArray(set){ // set转array
925
+ let arr = [];
926
+ for(let item of set.keys()){
927
+ arr.push(item);
928
+ }
929
+ return arr;
930
+ },
931
+
932
+ },
933
+ }
934
+ </script>
935
+
936
+ <style scoped>
937
+
938
+ </style>