SystemUserForm.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. <template>
  2. <a-spin :spinning="confirmLoading">
  3. <j-form-container :disabled="formDisabled">
  4. <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
  5. <a-row>
  6. <a-col :span="24">
  7. <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="username">
  8. <span slot="label">
  9. 用户名称&nbsp;
  10. <a-tooltip title="用户名称为邮箱格式">
  11. <a-icon type="question-circle-o" />
  12. </a-tooltip>
  13. </span>
  14. <a-input v-model="model.username" placeholder="请输入用户名称" :disabled="userDisabled" ></a-input>
  15. </a-form-model-item>
  16. </a-col>
  17. <a-col :span="24">
  18. <a-form-model-item label="描述" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remark">
  19. <a-input v-model="model.remark" placeholder="请输入描述" ></a-input>
  20. </a-form-model-item>
  21. </a-col>
  22. <a-col :span="24">
  23. <a-form-model-item label="是否为系统管理员" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="role">
  24. <a-switch v-model="model.isSystem" checked-children="是" un-checked-children="否" @change="roleChange" :disabled="model.isSsoAdmin"/>
  25. </a-form-model-item>
  26. </a-col>
  27. <a-col :span="24">
  28. <a-form-model-item label="所拥有的权限" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="role">
  29. <a-table
  30. v-if="tpmTreeData && tpmTreeData.length"
  31. ref="table"
  32. size="middle"
  33. :scroll="{x:true}"
  34. bordered
  35. rowKey="interlockSystemId"
  36. :columns="columns"
  37. :dataSource="tpmTreeData"
  38. :loading="loading"
  39. :pagination="false"
  40. defaultExpandAllRows
  41. class="interlock-user-limit"
  42. >
  43. <!-- class="j-table-force-nowrap" -->
  44. <!-- @change="handleTableChange" -->
  45. <span slot="manageTitle">
  46. <a-checkbox v-model="manageHeader" :indeterminate="indeterminateManageHeader" :disabled="model.isSystem" @change="changeManageHeader"/>
  47. <div>管理</div>
  48. </span>
  49. <span slot="manage" slot-scope="text, record">
  50. <!-- <span v-if="record.interlockType === '0' && !record.children">-</span> -->
  51. <!-- <a-checkbox v-else v-model="record.manage" :indeterminate="record.indeterminateManage" :disabled="model.isSystem"/> -->
  52. <a-checkbox v-model="record.manage" :indeterminate="record.indeterminateManage" :disabled="model.isSystem"/>
  53. </span>
  54. <span slot="viewTitle">
  55. <a-checkbox v-model="viewHeader" :indeterminate="indeterminateViewHeader" :disabled="model.isSystem" @change="changeViewHeader"/>
  56. <div>查看</div>
  57. </span>
  58. <span slot="view" slot-scope="text, record">
  59. <!-- <span v-if="record.interlockType === '0' && !record.children">-</span> -->
  60. <!-- <a-checkbox v-else v-model="record.view" :indeterminate="record.indeterminateView" :disabled="model.isSystem"/> -->
  61. <a-checkbox v-model="record.view" :indeterminate="record.indeterminateView" :disabled="model.isSystem"/>
  62. </span>
  63. </a-table>
  64. </a-form-model-item>
  65. </a-col>
  66. </a-row>
  67. </a-form-model>
  68. </j-form-container>
  69. </a-spin>
  70. </template>
  71. <script>
  72. import { httpAction, getAction } from '@/api/manage'
  73. import { validateDuplicateValue } from '@/utils/util'
  74. import cookie from 'js-cookie'
  75. export default {
  76. name: 'InterlockUserForm',
  77. components: {
  78. },
  79. props: {
  80. //表单禁用
  81. disabled: {
  82. type: Boolean,
  83. default: false,
  84. required: false
  85. }
  86. },
  87. data () {
  88. return {
  89. userDisabled: false, // 修改时用户名不可修改
  90. model:{
  91. },
  92. labelCol: {
  93. xs: { span: 24 },
  94. sm: { span: 5 },
  95. },
  96. wrapperCol: {
  97. xs: { span: 24 },
  98. sm: { span: 16 },
  99. },
  100. confirmLoading: false,
  101. validatorRules: {
  102. username: [
  103. { required: true, message: '请输入用户名称!', },
  104. { validator: (rule, value, callback) => validateDuplicateValue('interlock_user', 'username', value, this.model.id, callback)},
  105. {
  106. pattern: /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/,
  107. message: '邮箱格式不正确'
  108. },
  109. ],
  110. },
  111. url: {
  112. add: "/interlockUser/interlockUser/addUser",
  113. edit: "/interlockUser/interlockUser/editUser",
  114. queryById: "/interlockUser/interlockUser/queryUserById"
  115. },
  116. // 权限树-装置系统
  117. loading: false,
  118. tpmTreeData: [],
  119. expandedRowKeys: [],
  120. columns: [
  121. {
  122. title:'',
  123. dataIndex: 'interlockName'
  124. },
  125. {
  126. // title:'管理',
  127. align:"center",
  128. dataIndex: 'manage',
  129. width:147,
  130. slots: { title: 'manageTitle' },
  131. scopedSlots: { customRender: 'manage' },
  132. customCell: (record, index)=>{ return this.customCell(record, index, 'manage')}
  133. },
  134. {
  135. // title:'查看',
  136. align:"center",
  137. dataIndex: 'view',
  138. width:147,
  139. slots: { title: 'viewTitle' },
  140. scopedSlots: { customRender: 'view' },
  141. customCell: (record, index)=>{ return this.customCell(record, index, 'view')}
  142. },
  143. ],
  144. manageHeader: false,
  145. indeterminateManageHeader: false,
  146. viewHeader: false,
  147. indeterminateViewHeader: false,
  148. }
  149. },
  150. computed: {
  151. formDisabled(){
  152. return this.disabled
  153. },
  154. // isSsoManage(){
  155. // return cookie.get('SSORole') === 'globalAdmin'
  156. // // return this.$store.getters.userInfo.role === '0'
  157. // },
  158. },
  159. created () {
  160. //备份model原始值
  161. this.modelDefault = JSON.parse(JSON.stringify(this.model));
  162. },
  163. methods: {
  164. // 新增
  165. async add () {
  166. this.confirmLoading = true
  167. await getAction(`/base/interlockBase/list`).then(res=>{
  168. // 重组数据
  169. var arr = res.map(item => {
  170. var reValue = {}
  171. reValue.interlockName = item.interlockName
  172. reValue.interlockApparatusId = item.pid
  173. reValue.interlockSystemId = item.id
  174. reValue.interlockType = item.interlockType
  175. reValue.iotedgeGroupId = item.iotedgeGroupId
  176. reValue.limitType = ''
  177. reValue.manage = false
  178. reValue.view = false
  179. reValue.indeterminateManage = false
  180. reValue.indeterminateView = false
  181. return reValue
  182. })
  183. // arr.push({
  184. // interlockName: '所有',
  185. // interlockApparatusId: '',
  186. // interlockSystemId: '0',
  187. // manage: false,
  188. // view: false,
  189. // indeterminateManage: false,
  190. // indeterminateView: false,
  191. // })
  192. this.tpmTreeData = this.handleTree(arr, "interlockSystemId", "interlockApparatusId")
  193. this.confirmLoading = false
  194. })
  195. },
  196. // 编辑
  197. async edit (record) {
  198. this.confirmLoading = true
  199. var interlockOrgData = []
  200. // 获取装置设置数据
  201. await getAction(`/base/interlockBase/list`).then(res=>{
  202. interlockOrgData = res
  203. })
  204. // 获取当前选择账户的详情以及权限等
  205. getAction(this.url.queryById, {id: record.id}).then(response => {
  206. this.model = Object.assign({}, response.result);
  207. this.model.isSystem = this.model.role === '0' ? true : false
  208. // console.log('model', this.model)
  209. var systemLimitList = response.result.systemLimitList
  210. // 重组数据
  211. var arr = interlockOrgData.map(ele => {
  212. var value = systemLimitList.find(item => item.interlockSystemId === ele.id)
  213. // console.log(value)
  214. var reValue = {}
  215. if(value){reValue.id = value.id}
  216. reValue.interlockName = ele.interlockName
  217. reValue.interlockApparatusId = ele.pid
  218. reValue.interlockSystemId = ele.id
  219. reValue.interlockType = ele.interlockType
  220. reValue.iotedgeGroupId = ele.iotedgeGroupId
  221. reValue.limitType = ''
  222. reValue.manage = false
  223. reValue.view = false
  224. reValue.indeterminateManage = false
  225. reValue.indeterminateView = false
  226. if(this.model.role === '0'){
  227. reValue.manage = true
  228. }
  229. if(this.model.role !== '0' && value){
  230. // reValue.id = value.id
  231. reValue.limitType = value.limitType
  232. reValue.manage = value.limitType === '0' ? true : false
  233. reValue.view = value.limitType === '1' ? true : false
  234. }
  235. return reValue
  236. })
  237. // console.log(arr)
  238. this.tpmTreeData = this.handleTree(arr, "interlockSystemId", "interlockApparatusId")
  239. // console.log(this.tpmTreeData)
  240. // 根据子系统回显父装置的多选框样式
  241. this.tpmTreeData.forEach(ele => {
  242. if(ele.children && ele.children.length > 0){
  243. // 设置每一个父装置管理选择框样式
  244. var chooseLengthM = ele.children.filter(item => item.manage).length
  245. ele.indeterminateManage = !!chooseLengthM && chooseLengthM < ele.children.length
  246. ele.manage = chooseLengthM === ele.children.length
  247. // 设置每一个父装置查看选择框样式
  248. var chooseLengthV = ele.children.filter(item => item.view).length
  249. ele.indeterminateView = !!chooseLengthV && chooseLengthV < ele.children.length
  250. ele.view = chooseLengthV === ele.children.length
  251. }
  252. })
  253. // 根据装置设置总管理/查看的多选框样式
  254. // 设置总的管理/查看多选框样式
  255. var chooseLengthMH = this.tpmTreeData.filter(item => item.manage || (!item.manage && item.indeterminateManage)).length
  256. this.indeterminateManageHeader = !!chooseLengthMH && chooseLengthMH < this.tpmTreeData.length
  257. this.manageHeader = chooseLengthMH === this.tpmTreeData.length
  258. var chooseLengthVH = this.tpmTreeData.filter(item => item.view || (!item.view && item.indeterminateView)).length
  259. this.indeterminateViewHeader = !!chooseLengthVH && chooseLengthVH < this.tpmTreeData.length
  260. this.viewHeader = chooseLengthVH === this.tpmTreeData.length
  261. this.visible = true;
  262. this.confirmLoading = false
  263. })
  264. },
  265. // 表头管理多选框切换选择时
  266. changeManageHeader(e){
  267. // console.log(e.target.checked)
  268. if(e.target.checked){
  269. // 自身样式相应改变
  270. this.viewHeader = false
  271. this.indeterminateViewHeader = false
  272. this.indeterminateManageHeader = false
  273. for (let i = 0; i < this.tpmTreeData.length; i++) {
  274. // 父装置样式改变
  275. const element = this.tpmTreeData[i];
  276. element.manage = true
  277. element.indeterminateManage = false
  278. element.view = false
  279. element.indeterminateView = false
  280. if(element.children && element.children.length > 0){
  281. element.children.forEach(item => {
  282. // 子系统样式改变
  283. item.manage = true
  284. item.view = false
  285. })
  286. }
  287. }
  288. } else {
  289. for (let i = 0; i < this.tpmTreeData.length; i++) {
  290. const element = this.tpmTreeData[i];
  291. element.manage = false
  292. element.view = false
  293. if(element.children && element.children.length > 0){
  294. element.children.forEach(item => {
  295. item.manage = false
  296. item.view = false
  297. })
  298. }
  299. }
  300. }
  301. },
  302. // 表头查看多选框切换选择时
  303. changeViewHeader(e){
  304. if(e.target.checked){
  305. this.manageHeader = false
  306. this.indeterminateManageHeader = false
  307. this.indeterminateViewHeader = false
  308. for (let i = 0; i < this.tpmTreeData.length; i++) {
  309. // 父装置样式改变
  310. const element = this.tpmTreeData[i];
  311. element.view = true
  312. element.indeterminateManage = false
  313. element.manage = false
  314. element.indeterminateView = false
  315. if(element.children && element.children.length > 0){
  316. element.children.forEach(item => {
  317. // 子系统样式改变
  318. item.view = true
  319. item.manage = false
  320. })
  321. }
  322. }
  323. } else {
  324. for (let i = 0; i < this.tpmTreeData.length; i++) {
  325. const element = this.tpmTreeData[i];
  326. element.view = false
  327. element.manage = false
  328. if(element.children && element.children.length > 0){
  329. element.children.forEach(item => {
  330. item.view = false
  331. item.manage = false
  332. })
  333. }
  334. }
  335. }
  336. },
  337. // 角色切换时
  338. roleChange(e){
  339. // this.$set(this.model, 'isSystem', e)
  340. this.model = {...this.model}
  341. if(e){
  342. // 当前为管理员
  343. this.manageHeader = true
  344. this.indeterminateViewHeader = false
  345. this.indeterminateManageHeader = false
  346. for (let i = 0; i < this.tpmTreeData.length; i++) {
  347. const element = this.tpmTreeData[i];
  348. element.manage = true
  349. element.indeterminateManage = false
  350. element.indeterminateView = false
  351. if(element.children && element.children.length > 0){
  352. element.children.forEach(item => {
  353. item.manage = true
  354. item.view = false
  355. })
  356. }
  357. }
  358. } else {
  359. // 当前为管理员
  360. this.manageHeader = false
  361. for (let i = 0; i < this.tpmTreeData.length; i++) {
  362. const element = this.tpmTreeData[i];
  363. element.manage = false
  364. if(element.children && element.children.length > 0){
  365. element.children.forEach(item => {
  366. item.manage = false
  367. item.view = false
  368. })
  369. }
  370. }
  371. }
  372. },
  373. customCell(record, rowIndex, value){
  374. return {
  375. props: {
  376. },
  377. on: { // 事件
  378. click: (event) => {
  379. // console.log(event)
  380. // console.log(event.target.checked)
  381. // console.log(record, rowIndex, value)
  382. // 当前点击为装置且点击为装置选择框
  383. if(record.interlockType === '0' && event.target.type === 'checkbox'){
  384. // 全选管理
  385. if(value === 'manage' && event.target.checked){
  386. // 当前父装置多选框样式以及管理查看取反设置
  387. record.indeterminateView = false
  388. record.indeterminateManage = false
  389. record.manage = true
  390. record.view = false
  391. // 根据装置选择情况判断子系统的选择状态
  392. if(record.children && record.children.length > 0){
  393. record.children.forEach(ele => {
  394. ele.manage = true
  395. ele.view = false
  396. })
  397. }
  398. }
  399. // 全选查看
  400. if(value === 'view' && event.target.checked){
  401. // 当前父装置多选框样式以及管理查看取反设置
  402. record.indeterminateManage = false
  403. record.indeterminateView = false
  404. record.view = true
  405. record.manage = false
  406. // 根据装置选择情况判断子系统的选择状态
  407. if(record.children && record.children.length > 0){
  408. record.children.forEach(ele => {
  409. ele.view = true
  410. ele.manage = false
  411. })
  412. }
  413. }
  414. // 取消全选
  415. if(!event.target.checked){
  416. record.indeterminateManage = false
  417. record.indeterminateView = false
  418. record.view = false
  419. record.manage = false
  420. if(record.children && record.children.length > 0){
  421. record.children.forEach(ele => {
  422. ele.manage = false
  423. ele.view = false
  424. })
  425. }
  426. }
  427. }
  428. // 当前点击为装置且点击为系统选择框
  429. if(record.interlockType === '1' && event.target.type === 'checkbox'){
  430. console.log(record, rowIndex, value)
  431. // 管理和查看相互取反,并设置对应父装置的多选框样式
  432. // interlockApparatusId相当于pid,interlockSystemId相当于id
  433. // 某系统选择管理时
  434. if(value === 'manage'){
  435. // 取反
  436. // if(event.target.checked){record.view = false}
  437. record.view = event.target.checked ? !event.target.checked : record.view
  438. // 设置为true/false是为了下面判断length
  439. record.manage = event.target.checked
  440. var pidValue = this.tpmTreeData.find(item => item.interlockSystemId === record.interlockApparatusId)
  441. // 设置当前子系统父装置管理选择框样式
  442. var chooseLengthM = pidValue.children.filter(item => item.manage).length
  443. pidValue.indeterminateManage = !!chooseLengthM && chooseLengthM < pidValue.children.length
  444. pidValue.manage = chooseLengthM === pidValue.children.length
  445. // 设置当前子系统父装置查看选择框样式
  446. var chooseLengthV = pidValue.children.filter(item => item.view).length
  447. pidValue.indeterminateView = !!chooseLengthV && chooseLengthV < pidValue.children.length
  448. pidValue.view = chooseLengthV === pidValue.children.length
  449. }
  450. if(value === 'view'){
  451. // 取反
  452. record.manage = event.target.checked ? !event.target.checked : record.manage
  453. // 设置为true/false是为了下面判断length
  454. record.view = event.target.checked
  455. // 设置当前子系统父装置查看选择框样式
  456. var pidValue = this.tpmTreeData.find(item => item.interlockSystemId === record.interlockApparatusId)
  457. var chooseLengthV = pidValue.children.filter(item => item.view).length
  458. pidValue.indeterminateView = !!chooseLengthV && chooseLengthV < pidValue.children.length
  459. pidValue.view = chooseLengthV === pidValue.children.length
  460. // 设置当前子系统父装置管理选择框样式
  461. var chooseLengthM = pidValue.children.filter(item => item.manage).length
  462. pidValue.indeterminateManage = !!chooseLengthM && chooseLengthM < pidValue.children.length
  463. pidValue.manage = chooseLengthM === pidValue.children.length
  464. }
  465. }
  466. // 设置总的管理/查看多选框样式
  467. // console.log(this.tpmTreeData)
  468. // 管理选择但没完全选择样式
  469. var hasChooseLengthMH = this.tpmTreeData.filter(item => item.manage || (!item.manage && item.indeterminateManage)).length
  470. // 管理全选样式
  471. var chooseAllLengthMH = this.tpmTreeData.filter(item => item.manage).length
  472. this.indeterminateManageHeader = !!hasChooseLengthMH && hasChooseLengthMH <= this.tpmTreeData.length && chooseAllLengthMH !== this.tpmTreeData.length
  473. this.manageHeader = chooseAllLengthMH === this.tpmTreeData.length
  474. // 查看选择但没完全选择样式
  475. var hasChooseLengthVH = this.tpmTreeData.filter(item => item.view || (!item.view && item.indeterminateView)).length
  476. // 查看全选样式
  477. var chooseAllLengthVH = this.tpmTreeData.filter(item => item.view).length
  478. this.indeterminateViewHeader = !!hasChooseLengthVH && hasChooseLengthVH <= this.tpmTreeData.length && chooseAllLengthVH !== this.tpmTreeData.length
  479. this.viewHeader = chooseAllLengthVH === this.tpmTreeData.length
  480. },
  481. },
  482. };
  483. },
  484. submitForm () {
  485. const that = this;
  486. // 触发表单验证
  487. this.$refs.form.validate(valid => {
  488. if (valid) {
  489. // console.log(this.tpmTreeData)
  490. // 二维转一维
  491. var arr = []
  492. this.tpmTreeData.forEach(item => {
  493. if(item.children){
  494. arr.push(...item.children)
  495. }
  496. })
  497. // console.log(arr)
  498. this.model.systemLimitList = arr.map(item => {
  499. if(item.manage){item.limitType = '0'}
  500. if(item.view){item.limitType = '1'}
  501. if(!item.manage && !item.view){item.limitType = ''}
  502. return item
  503. })
  504. this.model.role = this.model.isSystem ? '0' : '1'
  505. // console.log(su)
  506. that.confirmLoading = true;
  507. let httpurl = '';
  508. let method = '';
  509. if(!this.model.id){
  510. httpurl+=this.url.add;
  511. method = 'post';
  512. }else{
  513. httpurl+=this.url.edit;
  514. method = 'put';
  515. }
  516. // 1820384671259701250 -- 联锁系统管理员
  517. // 1820343133955698689 -- 联锁普通SSO用户
  518. this.model.roleId = this.model.isSystem ? '1820384671259701250' : '1820343133955698689'
  519. httpAction(httpurl,this.model,method).then((res)=>{
  520. if(res.success){
  521. that.$message.success(res.message);
  522. that.$emit('ok');
  523. }else{
  524. that.$message.warning(res.message);
  525. }
  526. }).finally(() => {
  527. that.confirmLoading = false;
  528. })
  529. }
  530. })
  531. },
  532. }
  533. }
  534. </script>
  535. <style lang="less">
  536. .interlock-user-limit{
  537. tr{
  538. td{
  539. padding: 5px 8px !important;
  540. }
  541. }
  542. }
  543. </style>