Account.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  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. staticClass: 'u-width',
  166. props: {
  167. value: data.informLevel
  168. },
  169. on: {
  170. change: val => this.updateInformLevel(val, data)
  171. }
  172. }, [
  173. data.informLevel === 9999 && h('i', {
  174. slot: 'prefix',
  175. staticClass: 'l-flex--row center el-icon-edit u-font-size--md has-active',
  176. staticStyle: {
  177. height: '100%'
  178. },
  179. on: { click: e => {
  180. e.stopPropagation()
  181. this.onEditEvents(data)
  182. } }
  183. }),
  184. h('el-option', {
  185. key: 'none',
  186. props: {
  187. value: -1,
  188. label: '不预警'
  189. }
  190. }),
  191. h('el-option', {
  192. key: 'info',
  193. props: {
  194. value: 0,
  195. label: `${AlarmLevelInfo[0]}及以上`
  196. }
  197. }),
  198. h('el-option', {
  199. key: 'warning',
  200. props: {
  201. value: 1,
  202. label: `${AlarmLevelInfo[1]}及以上`
  203. }
  204. }),
  205. h('el-option', {
  206. key: 'error',
  207. props: {
  208. value: 2,
  209. label: AlarmLevelInfo[2]
  210. }
  211. }),
  212. h('el-option', {
  213. key: 'terror',
  214. props: {
  215. value: 9999,
  216. label: AlarmLevelInfo[9999]
  217. }
  218. })
  219. ]) },
  220. { type: 'tag', render: ({ userId, enabled }) => userId === this.userId
  221. ? null
  222. : {
  223. type: enabled ? 'success' : 'danger',
  224. label: enabled ? '启用' : '禁用'
  225. }, on: this.onToggle },
  226. { type: 'invoke', use: ({ userId }) => userId !== this.userId, render: [
  227. { label: '设置', on: this.onSettings }
  228. ] }
  229. ]
  230. },
  231. user: {},
  232. treeProps: { label: 'name', children: 'children' },
  233. events: CustomEvents,
  234. selectedEvents: []
  235. }
  236. },
  237. computed: {
  238. ...mapGetters(['tenant', 'userId']),
  239. expandKeys () {
  240. let groups = this.groups
  241. const group = this.group
  242. const arr = []
  243. const marks = group.path.split('/').filter(Boolean)
  244. let cpath = '/'
  245. while (marks.length > 1) {
  246. cpath += marks.shift()
  247. const tpath = cpath
  248. const temp = groups.find(({ path }) => path === tpath)
  249. arr.push(temp.path)
  250. groups = temp.children
  251. cpath += '/'
  252. }
  253. return arr.length ? arr : [this.tenant]
  254. },
  255. groupMap () {
  256. const map = {}
  257. this.createMap(this.groups, map)
  258. return map
  259. }
  260. },
  261. watch: {
  262. group () {
  263. this.$refs.table.pageTo(1)
  264. }
  265. },
  266. methods: {
  267. createMap (arr, map) {
  268. arr?.forEach(({ path, name, children }) => {
  269. map[path] = name
  270. this.createMap(children, map)
  271. })
  272. },
  273. getUsersByDepartment (params) {
  274. return getUsersByDepartment({
  275. departmentId: this.group.id,
  276. ...params
  277. })
  278. },
  279. onSettings (user) {
  280. this.user = user
  281. this.$refs.dialog.show()
  282. },
  283. onDel () {
  284. this.$refs.dialog.hide()
  285. this.$refs.table.decrease(1)
  286. },
  287. onGroupChange () {
  288. this.$refs.table.pageTo()
  289. },
  290. onAdd () {
  291. this.user = {
  292. username: '',
  293. name: ''
  294. }
  295. this.$department = { id: this.group.id, path: this.group.path, name: this.group.name }
  296. this.$refs.editDialog.show()
  297. },
  298. onGroupClick ({ id, path, name }) {
  299. this.$department = { id, path, name }
  300. },
  301. onSave (done) {
  302. const { username } = this.user
  303. if (!username) {
  304. this.$message({
  305. type: 'warning',
  306. message: '请填写用户账号'
  307. })
  308. return
  309. }
  310. if (username.length < 4) {
  311. this.$message({
  312. type: 'warning',
  313. message: '用户账号过短'
  314. })
  315. return
  316. }
  317. if (!/^[\da-zA-Z]{4,}$/.test(username)) {
  318. this.$message({
  319. type: 'warning',
  320. message: '用户账号格式错误'
  321. })
  322. return
  323. }
  324. addUser({
  325. ...this.user,
  326. ...(
  327. this.$department.id
  328. ? { departmentId: this.$department.id, departmentName: this.$department.name }
  329. : { departmentName: '顶层部门' }
  330. )
  331. }).then(() => {
  332. done()
  333. if (this.$department.path.indexOf(this.group.path) === 0) {
  334. this.$refs.table.pageTo(1)
  335. }
  336. })
  337. },
  338. onEditName (user, { newVal, oldVal }) {
  339. if (newVal === oldVal) {
  340. return
  341. }
  342. user.name = newVal
  343. updateUserName(user.userId, newVal).catch(() => {
  344. user.name = oldVal
  345. })
  346. },
  347. onToggle (user) {
  348. const enabled = [1, 0][user.enabled]
  349. this.$confirm(
  350. `${enabled ? '启用' : '停用'}账号${user.userName}?`,
  351. '操作确认',
  352. { type: 'warning' }
  353. ).then(() => toggleUser(
  354. user,
  355. enabled
  356. )).then(() => {
  357. user.enabled = enabled
  358. })
  359. },
  360. updateInformLevel (val, user) {
  361. updateUserInformLevel(user, val).then(() => {
  362. user.informLevel = val
  363. if (val === 9999) {
  364. this.onEditEvents(user)
  365. }
  366. })
  367. },
  368. onEditEvents (user) {
  369. this.$user = user
  370. getUserInforms(user).then(({ data }) => {
  371. this.selectedEvents = data
  372. this.$refs.eventDialog.show()
  373. })
  374. },
  375. onConfirmEvents (done) {
  376. updateUserInformLevel(this.$user, 9999, this.selectedEvents).then(done)
  377. }
  378. }
  379. }
  380. </script>