Account.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. <template>
  2. <schema-table
  3. ref="table"
  4. :schema="schema"
  5. >
  6. <confirm-dialog
  7. ref="editDialog"
  8. title="新增账号"
  9. @confirm="onSave"
  10. >
  11. <template #default>
  12. <div class="c-grid-form u-align-self--center">
  13. <span class="c-grid-form__label u-required">账号</span>
  14. <div
  15. class="u-width has-info"
  16. data-info="仅可包含数字、字母"
  17. >
  18. <el-input
  19. v-model.trim="user.username"
  20. placeholder="4~20个字符"
  21. maxlength="20"
  22. clearable
  23. />
  24. </div>
  25. <span class="c-grid-form__label">姓名</span>
  26. <el-input
  27. v-model.trim="user.name"
  28. class="u-width--sm"
  29. placeholder="账号使用者姓名"
  30. maxlength="20"
  31. clearable
  32. />
  33. <span class="c-grid-form__label">部门</span>
  34. <div class="c-grid-form__auto u-overflow-x--auto">
  35. <el-tree
  36. ref="tree"
  37. class="inline-flex"
  38. :data="groups"
  39. node-key="path"
  40. :props="treeProps"
  41. :current-node-key="group.path"
  42. :default-expanded-keys="expandKeys"
  43. :expand-on-click-node="false"
  44. accordion
  45. highlight-current
  46. auto-expand-parent
  47. @node-click="onGroupClick"
  48. />
  49. </div>
  50. </div>
  51. </template>
  52. </confirm-dialog>
  53. <c-dialog
  54. ref="dialog"
  55. size="medium"
  56. title="设置"
  57. >
  58. <template #default>
  59. <settings
  60. :user="user"
  61. :tenant="tenant"
  62. :groups="groups"
  63. @del="onDel"
  64. @group="onGroupChange"
  65. />
  66. </template>
  67. </c-dialog>
  68. <confirm-dialog
  69. ref="eventDialog"
  70. title="自定义事件"
  71. @confirm="onConfirmEvents"
  72. >
  73. <el-checkbox-group
  74. v-model="selectedEvents"
  75. class="l-grid--info mini"
  76. >
  77. <el-checkbox
  78. v-for="item in events"
  79. :key="item.id"
  80. :label="item.id"
  81. >
  82. {{ item.label }}
  83. </el-checkbox>
  84. </el-checkbox-group>
  85. </confirm-dialog>
  86. </schema-table>
  87. </template>
  88. <script>
  89. import { mapGetters } from 'vuex'
  90. import { AlarmLevelInfo } from '@/constant'
  91. import {
  92. getUsersByDepartment,
  93. addUser,
  94. updateUserName,
  95. toggleUser,
  96. updateUserInformLevel,
  97. getUserInforms
  98. } from '@/api/user'
  99. import Settings from './Settings'
  100. const CustomEvents = Object.freeze([
  101. { id: 1, level: 0, label: '播控器离线' },
  102. { id: 17, level: 2, label: '播控器工作时段离线' },
  103. { id: 15, level: 2, label: '播控器人为离线' },
  104. { id: 9, level: 0, label: '播控器上线' },
  105. { id: 32, level: 2, label: '播控器非工作时段上线' },
  106. { id: 40, level: 2, label: '播控器上线失败' },
  107. { id: 35, level: 0, label: '接收卡提示性预警' },
  108. { id: 2, level: 2, label: '接收卡紧急预警' },
  109. { id: 36, level: 2, label: '手动关闭电源' },
  110. { id: 37, level: 2, label: '手动开启电源' },
  111. { id: 42, level: 2, label: '电源定时任务' },
  112. { id: 0, level: 1, label: '屏幕疑似黑屏' },
  113. { id: 13, level: 2, label: '屏幕黑屏' },
  114. { id: 10, level: 2, label: '屏幕内容疑似不合规' },
  115. // { id: 3, level: 2, label: '屏幕内容不合规(拼接器)' },
  116. { id: 11, level: 2, label: '屏幕内容不合规' },
  117. { id: 18, level: 0, label: '温度传感器提示告警' },
  118. { id: 19, level: 0, label: '温度传感器一级告警' },
  119. { id: 20, level: 0, label: '温度传感器二级告警' },
  120. { id: 21, level: 1, label: '温度传感器三级告警' },
  121. { id: 22, level: 2, label: '温度传感器四级告警' },
  122. { id: 23, level: 2, label: '位移传感器报警' },
  123. { id: 7, level: 2, label: '屏幕监控摄像头离线' },
  124. { id: 8, level: 2, label: '人流监测摄像头离线' },
  125. { id: 33, level: 0, label: '屏幕监控摄像头上线' },
  126. { id: 34, level: 0, label: '人流监测摄像头上线' }
  127. ])
  128. export default {
  129. name: 'Account',
  130. components: {
  131. Settings
  132. },
  133. props: {
  134. groups: {
  135. type: Array,
  136. required: true
  137. },
  138. group: {
  139. type: Object,
  140. required: true
  141. }
  142. },
  143. data () {
  144. return {
  145. schema: {
  146. list: this.getUsersByDepartment,
  147. condition: { recursive: 1 },
  148. buttons: [
  149. { type: 'add', on: this.onAdd }
  150. ],
  151. filters: [
  152. { key: 'recursive', type: 'checkbox', label: '级联' }
  153. ],
  154. cols: [
  155. { label: '部门', render: ({ path, tenant }) => this.groupMap[path || tenant] },
  156. { prop: 'userName', label: '账号' },
  157. { label: '使用者', render: (data, h) => h('edit-input', {
  158. props: {
  159. value: data.name || '',
  160. placeholder: '-'
  161. },
  162. on: { edit: val => this.onEditName(data, val) }
  163. }), 'class-name': 'c-edit-column' },
  164. { label: '消息推送', render: (data, h) => h('el-select', {
  165. props: {
  166. value: data.informLevel
  167. },
  168. on: {
  169. change: val => this.updateInformLevel(val, data)
  170. }
  171. }, [
  172. data.informLevel === 9999 && h('i', {
  173. slot: 'prefix',
  174. staticClass: 'l-flex--row center el-icon-edit u-font-size--md has-active',
  175. staticStyle: {
  176. height: '100%'
  177. },
  178. on: { click: e => {
  179. e.stopPropagation()
  180. this.onEditEvents(data)
  181. } }
  182. }),
  183. h('el-option', {
  184. key: 'none',
  185. props: {
  186. value: -1,
  187. label: '不预警'
  188. }
  189. }),
  190. h('el-option', {
  191. key: 'info',
  192. props: {
  193. value: 0,
  194. label: `${AlarmLevelInfo[0]}及以上`
  195. }
  196. }),
  197. h('el-option', {
  198. key: 'warning',
  199. props: {
  200. value: 1,
  201. label: `${AlarmLevelInfo[1]}及以上`
  202. }
  203. }),
  204. h('el-option', {
  205. key: 'error',
  206. props: {
  207. value: 2,
  208. label: AlarmLevelInfo[2]
  209. }
  210. }),
  211. h('el-option', {
  212. key: 'terror',
  213. props: {
  214. value: 9999,
  215. label: AlarmLevelInfo[9999]
  216. }
  217. })
  218. ]) },
  219. { type: 'tag', render: ({ userId, enabled }) => userId === this.userId
  220. ? null
  221. : {
  222. type: enabled ? 'success' : 'danger',
  223. label: enabled ? '启用' : '禁用'
  224. }, on: this.onToggle },
  225. { type: 'invoke', use: ({ userId }) => userId !== this.userId, render: [
  226. { label: '设置', on: this.onSettings }
  227. ] }
  228. ]
  229. },
  230. user: {},
  231. treeProps: { label: 'name', children: 'children' },
  232. events: CustomEvents,
  233. selectedEvents: []
  234. }
  235. },
  236. computed: {
  237. ...mapGetters(['tenant', 'userId']),
  238. expandKeys () {
  239. let groups = this.groups
  240. const group = this.group
  241. const arr = []
  242. const marks = group.path.split('/').filter(Boolean)
  243. let cpath = '/'
  244. while (marks.length > 1) {
  245. cpath += marks.shift()
  246. const tpath = cpath
  247. const temp = groups.find(({ path }) => path === tpath)
  248. arr.push(temp.path)
  249. groups = temp.children
  250. cpath += '/'
  251. }
  252. return arr.length ? arr : [this.tenant]
  253. },
  254. groupMap () {
  255. const map = {}
  256. this.createMap(this.groups, map)
  257. return map
  258. }
  259. },
  260. watch: {
  261. group () {
  262. this.$refs.table.pageTo(1)
  263. }
  264. },
  265. methods: {
  266. createMap (arr, map) {
  267. arr?.forEach(({ path, name, children }) => {
  268. map[path] = name
  269. this.createMap(children, map)
  270. })
  271. },
  272. getUsersByDepartment (params) {
  273. return getUsersByDepartment({
  274. departmentId: this.group.id,
  275. ...params
  276. })
  277. },
  278. onSettings (user) {
  279. this.user = user
  280. this.$refs.dialog.show()
  281. },
  282. onDel () {
  283. this.$refs.dialog.hide()
  284. this.$refs.table.decrease(1)
  285. },
  286. onGroupChange () {
  287. this.$refs.table.pageTo()
  288. },
  289. onAdd () {
  290. this.user = {
  291. username: '',
  292. name: ''
  293. }
  294. this.$department = { id: this.group.id, path: this.group.path, name: this.group.name }
  295. this.$refs.editDialog.show()
  296. },
  297. onGroupClick ({ id, path, name }) {
  298. this.$department = { id, path, name }
  299. },
  300. onSave (done) {
  301. const { username } = this.user
  302. if (!username) {
  303. this.$message({
  304. type: 'warning',
  305. message: '请填写用户账号'
  306. })
  307. return
  308. }
  309. if (username.length < 4) {
  310. this.$message({
  311. type: 'warning',
  312. message: '用户账号过短'
  313. })
  314. return
  315. }
  316. if (!/^[\da-zA-Z]{4,}$/.test(username)) {
  317. this.$message({
  318. type: 'warning',
  319. message: '用户账号格式错误'
  320. })
  321. return
  322. }
  323. addUser({
  324. ...this.user,
  325. ...(
  326. this.$department.id
  327. ? { departmentId: this.$department.id, departmentName: this.$department.name }
  328. : { departmentName: '顶层部门' }
  329. )
  330. }).then(() => {
  331. done()
  332. if (this.$department.path.indexOf(this.group.path) === 0) {
  333. this.$refs.table.pageTo(1)
  334. }
  335. })
  336. },
  337. onEditName (user, { newVal, oldVal }) {
  338. if (newVal === oldVal) {
  339. return
  340. }
  341. user.name = newVal
  342. updateUserName(user.userId, newVal).catch(() => {
  343. user.name = oldVal
  344. })
  345. },
  346. onToggle (user) {
  347. const enabled = [1, 0][user.enabled]
  348. this.$confirm(
  349. `${enabled ? '启用' : '停用'}账号${user.userName}?`,
  350. '操作确认',
  351. { type: 'warning' }
  352. ).then(() => toggleUser(
  353. user,
  354. enabled
  355. )).then(() => {
  356. user.enabled = enabled
  357. })
  358. },
  359. updateInformLevel (val, user) {
  360. updateUserInformLevel(user, val).then(() => {
  361. user.informLevel = val
  362. if (val === 9999) {
  363. this.onEditEvents(user)
  364. }
  365. })
  366. },
  367. onEditEvents (user) {
  368. this.$user = user
  369. getUserInforms(user).then(({ data }) => {
  370. this.selectedEvents = data
  371. this.$refs.eventDialog.show()
  372. })
  373. },
  374. onConfirmEvents (done) {
  375. updateUserInformLevel(this.$user, 9999, this.selectedEvents).then(done)
  376. }
  377. }
  378. }
  379. </script>