index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. <template>
  2. <el-container>
  3. <el-main class="page-main">
  4. <el-card>
  5. <el-container>
  6. <el-aside class="tree-aside" :width="treeWidth">
  7. <tree title="组织架构" :fetch="this.$api.sysOrg.tree" :data-query="treeQuery" :call-back="getTreeDataCallBack" :click="treeClick" />
  8. </el-aside>
  9. <el-container>
  10. <el-header height="82">
  11. <el-form
  12. ref="searchForm"
  13. :model="dataQuery"
  14. :size="size"
  15. label-position="left"
  16. label-width="80px"
  17. >
  18. <el-row :gutter="20">
  19. <el-col :span="6">
  20. <el-form-item label="账号:" prop="login_id" class="notice-input" label-width="60px">
  21. <el-input v-model="dataQuery.login_id" placeholder="请输入帐号" clearable @keyup.enter.native="search" />
  22. </el-form-item>
  23. </el-col>
  24. <el-col :span="6">
  25. <el-form-item label="名称:" prop="name" class="notice-input" label-width="60px">
  26. <el-input v-model="dataQuery.name" placeholder="请输入名称" clearable @keyup.enter.native="search" />
  27. </el-form-item>
  28. </el-col>
  29. <el-col :span="12" style="text-align: right">
  30. <el-form-item>
  31. <el-button type="primary" icon="el-icon-search" :size="size" @click="search">查询</el-button>
  32. <el-button icon="el-icon-refresh" :size="size" @click="resetFields">重置</el-button>
  33. </el-form-item>
  34. </el-col>
  35. </el-row>
  36. <el-row>
  37. <el-button
  38. type="primary"
  39. icon="el-icon-plus"
  40. :size="size"
  41. @click="create"
  42. >新建
  43. </el-button>
  44. <el-button
  45. v-if="checkPermission(['update_password'])"
  46. type="success"
  47. icon="el-icon-edit"
  48. :size="size"
  49. @click="updatePassword"
  50. >修改密码
  51. </el-button>
  52. <el-button :size="size" @click="deleteBatch">批量删除</el-button>
  53. </el-row>
  54. </el-form>
  55. </el-header>
  56. <el-main class="table-main">
  57. <sheet
  58. ref="qtable"
  59. :api="this.$api.sysUser.page"
  60. :columns="tableColumns"
  61. :data-query="dataQuery"
  62. :operates="operates"
  63. :float-type="'right'"
  64. :select-type="'selection'"
  65. header-name="searchForm"
  66. />
  67. </el-main>
  68. </el-container>
  69. </el-container>
  70. </el-card>
  71. </el-main>
  72. <el-dialog
  73. :title="dialogStatus==='create'?'新建用户':'编辑用户'"
  74. :visible.sync="dialogVisible"
  75. width="50%"
  76. @close="dialogClose"
  77. >
  78. <el-form
  79. ref="tempForm"
  80. :size="size"
  81. :rules="rules"
  82. :model="temp"
  83. label-width="85px"
  84. >
  85. <el-form-item label="账号:" prop="login_id">
  86. <el-input v-model="temp.login_id" placeholder="请输入账号" />
  87. </el-form-item>
  88. <el-form-item label="用户名:" prop="name">
  89. <el-input v-model="temp.name" placeholder="请输入用户名" />
  90. </el-form-item>
  91. <el-form-item v-if="dialogStatus === 'create'" label="密码:" prop="password">
  92. <el-input v-model="temp.password" placeholder="请输入密码" />
  93. </el-form-item>
  94. <el-form-item label="机构:">
  95. <el-select v-model="temp.org_id" style="width: 100%" placeholder="请选择机构">
  96. <el-option
  97. v-for="item in orgs"
  98. :key="item.id"
  99. :label="item.name"
  100. :value="item.id"
  101. />
  102. </el-select>
  103. </el-form-item>
  104. <el-form-item label="邮箱:" prop="email">
  105. <el-input v-model="temp.email" placeholder="请输入邮箱" />
  106. </el-form-item>
  107. <el-form-item label="手机:" prop="mobile">
  108. <el-input v-model="temp.mobile" placeholder="请输入手机" />
  109. </el-form-item>
  110. <el-form-item v-if="dialogStatus=='update'" label="角色:" prop="type">
  111. <el-select v-model="temp.user_role" style="width: 100%" multiple placeholder="请选择角色">
  112. <el-option
  113. v-for="item in options"
  114. :key="item.id"
  115. :label="item.name"
  116. :value="item.id"
  117. />
  118. </el-select>
  119. </el-form-item>
  120. <el-form-item label="信息模板:" prop="temp_id">
  121. <el-select v-model="temp.temp_id" style="width: 100%" placeholder="请选择模板" @change="tempChange">
  122. <el-option
  123. v-for="item in templs"
  124. :key="item.id"
  125. :label="item.name"
  126. :value="item.id"
  127. />
  128. </el-select>
  129. </el-form-item>
  130. <el-form-item
  131. v-for="(item, i) in temp_items"
  132. :key="item.id"
  133. :label="item.name + ':'"
  134. label-position="right"
  135. class="notice-input"
  136. :prop="item.id"
  137. >
  138. <el-input v-if="item.type == 0" v-model.number="temp_items[i].value" placeholder="请输入" clearable />
  139. <el-input v-if="item.type == 2" v-model="temp_items[i].value" placeholder="请输入" clearable />
  140. <!--<template v-if="item.type == 3">-->
  141. <!--<el-table :data="temp_items[i].value" class="tb-edit" style="width: 100%" highlight-current-row @row-click="handleCurrentChange">-->
  142. <!--<el-table-column v-for="col of JSON.parse(temp_items[i].content)" :prop="col.prop" :label="col.label" :width="col.width">-->
  143. <!--<template scope="scope">-->
  144. <!--<el-input v-model="temp_items[i].value[scope.$index][col.prop]" size="small" placeholder="请输入内容" @change="handleEdit(scope.$index, scope.row.prop)" /> <span>{{ temp_items[i].value[scope.$index][col.prop] }}</span>-->
  145. <!--</template>-->
  146. <!--</el-table-column>-->
  147. <!--<el-table-column label="操作">-->
  148. <!--<template scope="scope">-->
  149. <!--<el-button size="small" type="text" @click="handleDelete(scope.$index, i)">删除</el-button>-->
  150. <!--<el-button v-if="scope.$index == temp_items[i].value.length - 1" size="small" type="text" @click="addRow(i)">添加</el-button>-->
  151. <!--</template>-->
  152. <!--</el-table-column>-->
  153. <!--</el-table>-->
  154. <!--</template>-->
  155. </el-form-item>
  156. </el-form>
  157. <footer slot="footer" class="dialog-footer">
  158. <el-button :size="size" @click="dialogVisible = false">取 消</el-button>
  159. <el-button :size="size" type="primary" @click="dialogStatus==='create'?createData():updateData()">确 定
  160. </el-button>
  161. </footer>
  162. </el-dialog>
  163. <!--修改密码-->
  164. <el-dialog title="修改密码" :visible.sync="updatePswDialog" width="30%">
  165. <el-form ref="updatePswForm" :size="size" :rules="rules" :model="temp" label-width="85px">
  166. <el-form-item label="账号:" prop="login_id">
  167. <el-input v-model="temp.login_id" placeholder="请输入账号" />
  168. </el-form-item>
  169. <el-form-item label="用户名:" prop="name">
  170. <el-input v-model="temp.name" placeholder="请输入用户名" />
  171. </el-form-item>
  172. <el-form-item label="密码:" prop="password">
  173. <el-input v-model="temp.password" placeholder="请输入密码" />
  174. </el-form-item>
  175. </el-form>
  176. <footer slot="footer" class="dialog-footer">
  177. <el-button :size="size" @click="updatePswDialog = false">取 消</el-button>
  178. <el-button :size="size" type="primary" @click="updatePws">确 定
  179. </el-button>
  180. </footer>
  181. </el-dialog>
  182. </el-container>
  183. </template>
  184. <script>
  185. import { mapGetters } from 'vuex'
  186. import { copyObject } from '@/utils/index'
  187. import checkPermission from '@/utils/permission'
  188. import Tree from '@/components/Tree'
  189. import Sheet from '@/components/Sheet'
  190. export default {
  191. name: 'User',
  192. components: {
  193. Tree,
  194. Sheet
  195. },
  196. data() {
  197. return {
  198. tableColumns: [
  199. { prop: 'login_id', label: '账号', align: 'center', minWidth: 180, maxWidth: 220 },
  200. { prop: 'name', label: '名称', align: 'center', minWidth: 150, maxWidth: 180 },
  201. { prop: 'org_name', label: '机构', align: 'center', minWidth: 150, maxWidth: 180 },
  202. { prop: 'role_name', label: '角色', align: 'center', minWidth: 150, maxWidth: 180 },
  203. { prop: 'email', label: '邮箱', align: 'center', minWidth: 150, maxWidth: 180 },
  204. { prop: 'mobile', label: '手机', align: 'center', minWidth: 150, maxWidth: 180 }
  205. ],
  206. operates: {
  207. list: [
  208. { label: '编辑', show: true, type: 'text', method: (row) => { this.edit(row) } },
  209. { label: '删除', show: true, type: 'text', method: (row) => { this.deleteData(row) } }
  210. ],
  211. width: 100,
  212. fixed: 'right'
  213. },
  214. dataQuery: {
  215. page: 1,
  216. rows: 10,
  217. login_id: '',
  218. name: '',
  219. cn_org_id: ''
  220. },
  221. rules: {
  222. name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
  223. login_id: [{ required: true, message: '请输入账号', trigger: 'blur' }],
  224. password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
  225. },
  226. treeQuery: { del_falg: 0 },
  227. temp: {
  228. id: undefined,
  229. login_id: '',
  230. name: '',
  231. password: '',
  232. email: '',
  233. mobile: '',
  234. type: 0,
  235. org_id: '',
  236. temp_value: '',
  237. temp_id: '',
  238. user_role: []
  239. },
  240. dataLoading: false,
  241. dialogStatus: '',
  242. dialogVisible: false,
  243. updatePswDialog: false,
  244. orgs: [],
  245. options: [],
  246. templs: [],
  247. temp_items: []
  248. }
  249. },
  250. computed: {
  251. inheritanceArray() {
  252. if (this.temp.inheritance === '' || this.temp.inheritance === undefined) {
  253. return []
  254. }
  255. let array = this.temp.inheritance.split('|').reverse()
  256. array = array.slice(1, array.length - 2)
  257. array.push(array[array.length - 1])
  258. return array
  259. },
  260. parent() {
  261. return this.inheritanceArray[this.inheritanceArray.length - 1]
  262. },
  263. ...mapGetters([
  264. 'size',
  265. 'minMainHeight',
  266. 'treeWidth'
  267. ])
  268. },
  269. mounted() {
  270. // 设置表头查询表单高度,使table高度自适应
  271. var height = this.$refs.searchForm.$el.offsetHeight
  272. this.$store.dispatch('app/pageTableHeaderHeight', { height: height })
  273. },
  274. destroyed() {
  275. // 页面注销,设置pageTableHeaderHeight为0
  276. this.$store.dispatch('app/pageTableHeaderHeight', { height: 0 })
  277. },
  278. created() {
  279. this.getOrgs()
  280. this.getRoles()
  281. this.FindUserTempl()
  282. },
  283. methods: {
  284. checkPermission,
  285. tempChange(temp_id) {
  286. this.getTempDetail(temp_id)
  287. },
  288. handleCurrentChange(row, event, column) {
  289. console.log(row, event, column, event.currentTarget)
  290. },
  291. handleEdit(index, row, col) {
  292. debugger
  293. },
  294. handleDelete(index, dataIndex) {
  295. this.temp_items[dataIndex].value.splice(index, 1)
  296. },
  297. addRow(dataIndex) {
  298. const obj = {}
  299. JSON.parse(this.temp_items[dataIndex].content).forEach(item => {
  300. obj[item.prop] = ''
  301. })
  302. this.temp_items[dataIndex].value.push(obj)
  303. },
  304. getTempDetail(temp_id) {
  305. this.$api.system.FindUserTemplateDetailPage({ page: 1, rows: 100, 'temp_id': temp_id }).then(res => {
  306. this.temp_items = res.data.content
  307. // temp_value回填
  308. var tempValue
  309. if (this.temp.temp_value !== '' && this.temp.temp_value !== undefined) {
  310. tempValue = JSON.parse(this.temp.temp_value)
  311. } else {
  312. tempValue = []
  313. }
  314. this.temp_items.forEach((item, i) => {
  315. tempValue.forEach(value => {
  316. if (item.id === value.id) {
  317. if (item.type === 3) {
  318. this.temp_items[i].value = value.value
  319. } else {
  320. this.temp_items[i].value = value.value
  321. }
  322. }
  323. })
  324. // 如果列表内容是空,默认添加一行空行
  325. if (item.type === 3 && this.temp_items[i].value === '') {
  326. var row = {}
  327. JSON.parse(this.temp_items[i].content).forEach(col => {
  328. row[col.prop] = '请输入'
  329. })
  330. this.temp_items[i].value = [row]
  331. }
  332. })
  333. })
  334. },
  335. FindUserTempl() {
  336. this.$api.sysUserTemplate.page({ page: 1, rows: 100 }).then(res => {
  337. if (res.code === 200) {
  338. this.templs = res.data.content
  339. }
  340. })
  341. },
  342. getOrgs() {
  343. const pageData = { 'page': 1, 'rows': 100 }
  344. this.$api.sysOrg.page(pageData).then(res => {
  345. if (res.code === 200) {
  346. this.orgs = res.data.content
  347. } else {
  348. this.$message({
  349. message: '失败',
  350. type: 'fail'
  351. })
  352. }
  353. })
  354. },
  355. getRoles() {
  356. const pageData = { 'page': 1, 'rows': 100 }
  357. this.$api.sysRole.page(pageData).then(res => {
  358. if (res.code === 200) {
  359. this.options = res.data.content
  360. } else {
  361. this.$message({
  362. message: '失败',
  363. type: 'fail'
  364. })
  365. }
  366. })
  367. },
  368. treeClick(node) {
  369. this.dataQuery.cn_org_id = node.id
  370. this.$refs.qtable.getData()
  371. },
  372. getTreeDataCallBack(tree) {},
  373. handleChange(value) {
  374. this.temp.parent = value[value.length - 1]
  375. },
  376. createData() {
  377. this.$refs['tempForm'].validate((valid) => {
  378. if (valid) {
  379. this.temp.temp_value = JSON.stringify(this.temp_items)
  380. this.$api.user.create(this.temp).then((res) => {
  381. this.dialogVisible = false
  382. if (res.code === 200) {
  383. this.$message({
  384. message: '创建成功',
  385. type: 'success'
  386. })
  387. this.$refs.qtable.getData()
  388. } else {
  389. this.$message({
  390. message: res.msg,
  391. type: 'error'
  392. })
  393. }
  394. })
  395. }
  396. })
  397. },
  398. updatePassword() {
  399. if (this.$refs.qtable.selectionData.length === 1) {
  400. this.temp = this.$refs.qtable.selectionData[0]
  401. this.temp.password = ''
  402. this.updatePswDialog = true
  403. } else {
  404. this.$message({
  405. message: '请选择一条记录',
  406. type: 'error'
  407. })
  408. }
  409. },
  410. updatePws() {
  411. this.$api.system.UpdatePassword(this.temp).then(res => {
  412. if (res.code === 200) {
  413. this.updatePswDialog = false
  414. this.$message({
  415. message: '修改成功',
  416. type: 'success'
  417. })
  418. } else {
  419. this.dialogVisible = false
  420. this.$message({
  421. message: '修改失败',
  422. type: 'error'
  423. })
  424. }
  425. })
  426. },
  427. updateData() {
  428. this.$refs['tempForm'].validate((valid) => {
  429. if (valid) {
  430. this.temp.temp_value = JSON.stringify(this.temp_items)
  431. this.$api.user.update(this.temp).then((res) => {
  432. if (res.code === 200) {
  433. this.dialogVisible = false
  434. this.$message({
  435. message: '修改成功',
  436. type: 'success'
  437. })
  438. this.$refs.qtable.getData()
  439. } else {
  440. this.dialogVisible = false
  441. this.$message({
  442. message: '修改失败',
  443. type: 'error'
  444. })
  445. }
  446. })
  447. }
  448. })
  449. },
  450. deleteData(row) {
  451. this.$confirm('确认删除这个用户吗?', '提示', {
  452. type: 'warning'
  453. }).then(() => {
  454. const data = [{ id: row.id }]
  455. this.$api.user.del(data).then((res) => {
  456. if (res.code === 200) {
  457. this.$refs.qtable.getData()
  458. this.$message({
  459. message: '删除成功',
  460. type: 'success'
  461. })
  462. } else {
  463. this.$message({
  464. message: '删除失败',
  465. type: 'error'
  466. })
  467. }
  468. })
  469. })
  470. },
  471. deleteBatch() {
  472. const ids = []
  473. this.$refs.qtable.multipleSelection.forEach(row => {
  474. ids.push({ id: row.id })
  475. })
  476. this.$confirm('确认批量删除选中数据吗?', '提示', {
  477. type: 'warning'
  478. }).then(() => {
  479. this.$api.user.del(ids).then(res => {
  480. if (res.code === 200) {
  481. this.$refs.qtable.getData()
  482. this.$message({
  483. message: '删除成功',
  484. type: 'success'
  485. })
  486. } else {
  487. this.$message({
  488. message: '删除失败',
  489. type: 'error'
  490. })
  491. }
  492. })
  493. }).catch(() => {
  494. })
  495. },
  496. search() {
  497. this.$refs.qtable.getData()
  498. },
  499. resetFields() {
  500. this.$refs['searchForm'].resetFields()
  501. this.$refs.qtable.getData()
  502. },
  503. dialogClose() {
  504. this.$refs['tempForm'].resetFields()
  505. },
  506. create() {
  507. this.dialogStatus = 'create'
  508. this.dialogVisible = true
  509. this.$nextTick(() => {
  510. this.$refs['tempForm'].clearValidate()
  511. })
  512. this.temp.temp_id = this.templs.filter((currentValue, index, arr) => {
  513. if (currentValue.default === 1) {
  514. return currentValue.id
  515. }
  516. })[0].id
  517. this.getTempDetail(this.temp.temp_id)
  518. },
  519. edit(row) {
  520. this.dialogStatus = 'update'
  521. this.dialogVisible = true
  522. this.$nextTick(() => {
  523. this.$refs['tempForm'].clearValidate()
  524. copyObject(row, this.temp)
  525. if (row.user_role === '') {
  526. this.temp.user_role = []
  527. } else {
  528. this.temp.user_role = row.user_role.split(',')
  529. }
  530. if (row.temp_id !== '') {
  531. this.getTempDetail(row.temp_id)
  532. } else {
  533. this.temp.temp_id = this.templs.filter((currentValue, index, arr) => {
  534. if (currentValue.type === 1) {
  535. return currentValue.id
  536. }
  537. })[0].id
  538. this.getTempDetail(this.temp.temp_id)
  539. }
  540. })
  541. }
  542. }
  543. }
  544. </script>
  545. <style>
  546. .tb-edit .el-input {
  547. display: none
  548. }
  549. .tb-edit .current-row .el-input {
  550. display: block
  551. }
  552. .tb-edit .current-row .el-input+span {
  553. display: none
  554. }
  555. </style>