index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. <template>
  2. <div>
  3. <com-head :options="headList">
  4. <el-form label-width="84px" inline="true">
  5. <el-form-item label="所属架构:">
  6. <com-company :checkStrictly="true" v-model="search.state.departmentId" />
  7. </el-form-item>
  8. <el-form-item label="用户账号:">
  9. <el-input v-model="search.state.userName" placeholder="请输入手机号"></el-input>
  10. </el-form-item>
  11. <el-form-item label="用户姓名:">
  12. <el-input v-model="search.state.nickName" placeholder="请输入"></el-input>
  13. </el-form-item>
  14. <el-form-item label="状态:">
  15. <el-select v-model="search.state.status" placeholder="全部">
  16. <el-option label="全部" :value="''"></el-option>
  17. <el-option label="启用" :value="1"></el-option>
  18. <el-option label="禁用" :value="0"></el-option>
  19. </el-select>
  20. </el-form-item>
  21. <el-form-item class="searh-btns">
  22. <el-button type="primary" @click="search.submit">查询</el-button>
  23. <el-button type="primary" plain @click="search.reset">重置</el-button>
  24. </el-form-item>
  25. </el-form>
  26. </com-head>
  27. <div class="body-layer" style="padding-top: 8px">
  28. <div class="body-but">
  29. <el-button type="primary" :disabled="getRoke('add')" @click="newAddclick">新增用户</el-button>
  30. <!-- <h3 style="visibility: hidden;">用户列表</h3> -->
  31. </div>
  32. <el-table
  33. class="user-table"
  34. ref="multipleTable"
  35. :data="dataList.state"
  36. tooltip-effect="dark"
  37. style="width: 100%;max-height:480px"
  38. @row-click="selectRow"
  39. >
  40. <el-table-column label="序号" width="55" v-slot:default="{ $index }">
  41. <div style="text-align: center">
  42. {{ pag.state.size * (pag.state.currPage - 1) + $index + 1 }}
  43. </div>
  44. </el-table-column>
  45. <el-table-column
  46. label="手机号(账号)"
  47. prop="userName"
  48. ></el-table-column>
  49. <el-table-column label="用户名称" prop="nickName"></el-table-column>
  50. <el-table-column
  51. label="所属架构"
  52. prop="deptName"
  53. ></el-table-column>
  54. <el-table-column label="角色" prop="roleName"></el-table-column>
  55. <el-table-column label="状态" v-slot:default="{ row }">
  56. {{ row.status ? "启用" : "禁用" }}
  57. </el-table-column>
  58. <el-table-column
  59. label="操作"
  60. v-slot:default="{ row }"
  61. >
  62. <!-- v-if="auth.update || auth.updatePwd || auth.delete" v-if="auth.update"-->
  63. <!-- row.roleKey == roleKey[user.roleKey] -->
  64. <template v-if="user.roleKey !== 'admin-ordinary'">
  65. <span class="oper-span" @click="updateInfo(row)"
  66. v-power="'edit'">编辑</span
  67. >
  68. <!-- v-if="auth.delete" -->
  69. <span
  70. class="oper-span"
  71. v-power="'disabled'"
  72. @click="changeUserStatus(row)"
  73. :class="{disable:user.info.id == row.id}"
  74. style="color: var(--primaryColor)"
  75. >
  76. {{ row.status ? "禁用" : "启用" }}
  77. </span>
  78. <span :class="user.info.id == row.id?'disable oper-span':'oper-span'" style="color: var(--primaryColor)" @click="delInfo(row)" v-power="'del'">删除</span
  79. >
  80. </template>
  81. </el-table-column>
  82. </el-table>
  83. <com-pagination
  84. @size-change="pag.sizeChange"
  85. @current-change="pag.currentChange"
  86. :current-page="pag.state.currPage"
  87. :page-size="pag.state.size"
  88. layout="total, sizes, prev, pager, next, jumper"
  89. :total="pag.state.total"
  90. />
  91. </div>
  92. <com-dialog
  93. title="编辑用户"
  94. v-model:show="oper.state.show"
  95. @submit="operItem"
  96. width="540"
  97. >
  98. <el-form ref="form" :model="form" label-width="90px" class="user-from">
  99. <el-form-item label="用户姓名" class="mandatory" >
  100. <el-input
  101. v-model.trim="editData.editName"
  102. placeholder="请输入"
  103. maxlength="30"
  104. ></el-input>
  105. </el-form-item>
  106. <el-form-item label="所属架构" class="mandatory" v-if="user.roleKey !== 'admin-ordinary'">
  107. <el-cascader
  108. style="width: 100%"
  109. v-model="editData.deptIdList"
  110. @change="editChange"
  111. :options="treedata"
  112. :props="{ checkStrictly: true, label: 'name', value: 'id' }"
  113. ></el-cascader>
  114. </el-form-item>
  115. <el-form-item label="用户角色" class="roleName mandatory">
  116. <com-role :deptId="relationDeptId" v-model="editData.roleId" style="width: 100%" allText="请选择" hideAll :notDefault="true" />
  117. </el-form-item>
  118. </el-form>
  119. </com-dialog>
  120. <com-dialog
  121. title="新增用户"
  122. @quit="newData = {};deptIdList=[]"
  123. v-model:show="newShow"
  124. @submit="newSubmit"
  125. width="540"
  126. >
  127. <el-form ref="form" :model="form" label-width="90px" class="user-from">
  128. <el-form-item label="用户姓名" class="mandatory" >
  129. <el-input
  130. maxlength="30"
  131. v-model="newData.nickName"
  132. placeholder="请输入"
  133. ></el-input>
  134. </el-form-item>
  135. <el-form-item label="所属架构" class="mandatory" v-if="user.roleKey !== 'admin-ordinary'">
  136. <el-cascader
  137. style="width: 100%"
  138. v-model="newData.deptIdList"
  139. @change="addChange"
  140. :options="treedata"
  141. :props="{ checkStrictly: true, label: 'name', value: 'id' }"
  142. ></el-cascader>
  143. </el-form-item>
  144. <el-form-item label="用户角色" class="roleName mandatory">
  145. <com-role :disabled="!relationDeptId" :deptId="relationDeptId" v-model="newData.roleId" style="width: 100%" allText="请选择" hideAll :notDefault="true" />
  146. </el-form-item>
  147. <el-form-item label="用户账号" class="mandatory">
  148. <el-input
  149. v-model.trim="newData.userName"
  150. placeholder="请输入11位手机号码作为用户账号"
  151. ></el-input>
  152. </el-form-item>
  153. <el-form-item label="登录密码" class="mandatory">
  154. <el-input
  155. v-model="newData.psw"
  156. placeholder="请输入8-16位数字、英文大小写组合密码"
  157. :type="flag?'password':'text'"
  158. >
  159. <template v-slot:suffix>
  160. <img v-if="flag" @click="flag = !flag" style="width:20px; margin: 10px;" src="@/assets/image/pasword.png" alt="">
  161. <i v-else class="icon-style el-icon-view" style="font-size:20px;margin: 10px;" size="20" @click="flag = !flag"></i>
  162. </template>
  163. </el-input>
  164. </el-form-item>
  165. </el-form>
  166. </com-dialog>
  167. </div>
  168. </template>
  169. <script>
  170. import { reactive, ref, toRefs,onMounted } from "vue";
  171. import getTableState from "@/state/tableRef";
  172. import comDialog from "@/components/dialog";
  173. import comHead from "@/components/head";
  174. import comCompany from "@/components/company-select";
  175. import comPagination from "@/components/pagination";
  176. import roleCompany from "@/components/role-select";
  177. // import comSelect from "@/components/company-select";
  178. import auth from "@/state/viewAuth";
  179. import user from "@/state/user";
  180. import axios from "axios";
  181. import {PHONE,EPSW} from '@/constant/REG'
  182. import { ADMIN_USER_ID } from "@/constant";
  183. import { getRoke } from '@/util'
  184. import { getTreeselect,getUserList, updateUser, deleUser, changeUserStatus,userAdd,userEdit } from "@/request/config";
  185. import { getApp } from "../../app";
  186. export default {
  187. name: "user",
  188. setup() {
  189. const flag = ref(true)
  190. const state = getTableState({
  191. getUrl: getUserList,
  192. updateUrl: updateUser,
  193. operAttr: {
  194. nickName: "",
  195. userName: "",
  196. deptId: "",
  197. password: "",
  198. confirmPwd: "",
  199. roleId: "",
  200. maxlevel: 1,
  201. },
  202. searchAttr: { nickName: "", status: "", deptId: "",userName:"",departmentId:'' },
  203. });
  204. const headList = ref([{ name: "用户管理", value: 2 }]);
  205. const roleKey = ref({ 'admin': "admin-dept", 'admin-dept': 'admin-ordinary' });
  206. const operRoleId = ref("");
  207. const updateInfo = (row) => {
  208. if (!row.status) {
  209. return getApp().$message.error("请先启用用户", "提示");
  210. }
  211. // let superiorValue = val.ancestors && val.ancestors.split(',').slice(1)
  212. let deptIdList = row.deptIdList&&row.deptIdList.split(',') || []
  213. deptIdList.push(row.deptId)
  214. data.editData = {
  215. editName:row.nickName,
  216. roleId:row.roleId,
  217. deptIdList:deptIdList,
  218. }
  219. console.log('updateInfo',row,data.editData)
  220. data.relationDeptId = row.deptId
  221. operRoleId.value = row.roleId;
  222. state.oper.value.readyUpdate(row);
  223. };
  224. const delInfo = async (row) => {
  225. let isOk = await getApp().$confirm('用户被删除后,无法登陆使用,无法编辑场景(可将该用户关联的相机绑定到其他管理员),确认要删除组织吗?', '删除')
  226. if (isOk) {
  227. await axios.post(deleUser, { id:row.id, });
  228. getApp().$message({message: '操作成功', type: 'success'});
  229. state.search.value.submit();
  230. }
  231. }
  232. const getTreedata = async () => {
  233. let res = await axios.get(getTreeselect, {});
  234. data.treedata = res.data;
  235. console.log('data.treedata',data.treedata);
  236. // getApp().$ref.treeBox.setCurrentKey(user.info.id)
  237. };
  238. const newAddclick = () =>{
  239. data.newShow = true
  240. }
  241. const data = reactive({
  242. relationDeptId:'',
  243. newShow: false,
  244. editData:{
  245. editName:'',
  246. roleId:'',
  247. deptIdList:'',
  248. },//修改编辑用户名称
  249. deptIdList:[],
  250. treedata:[],
  251. newData:{
  252. userName: "",
  253. userId: "",
  254. password: "",
  255. userRole: "",
  256. deptIdList:null
  257. }
  258. });
  259. onMounted(async () => {
  260. getTreedata();
  261. });
  262. return {
  263. ...state,
  264. ...toRefs(data),
  265. flag,
  266. getTreedata,
  267. headList,
  268. delInfo,
  269. updateInfo,
  270. auth,
  271. user,
  272. operRoleId,
  273. ADMIN_USER_ID,
  274. roleKey,
  275. newAddclick,
  276. getRoke
  277. };
  278. },
  279. methods: {
  280. async newSubmit(){
  281. console.log('newSubmit',this.user,this.newData);
  282. let deptIdList = this.newData.deptIdList
  283. let deptId = deptIdList&& deptIdList[deptIdList.length - 1];
  284. if (!this.newData.nickName) {
  285. return this.$message.error("请输入用户姓名", "提示");
  286. }
  287. if(!deptId){
  288. return this.$message.error("请选择用户所属架构", "提示");
  289. }
  290. if (!this.newData.roleId) {
  291. return this.$message.error("请选择用户角色", "提示");
  292. }
  293. console.log(PHONE.REG.test(this.newData.userName),this.newData.userName)
  294. if (!this.newData.userName) {
  295. return this.$message.error("请选择用户账户", "提示");
  296. }else if(!PHONE.REG.test(this.newData.userName)){
  297. return this.$message.error(PHONE.tip, "提示");
  298. }
  299. if (!this.newData.psw) {
  300. return this.$message.error("请输入登录密码", "提示");
  301. }else if(!EPSW.REG.test(this.newData.psw)){
  302. return this.$message.error(EPSW.tip, "提示");
  303. }
  304. let apiinfo = await axios.post(userAdd, {
  305. nickName:this.newData.nickName,
  306. password:this.newData.psw,
  307. userName:this.newData.userName,
  308. roleId:this.newData.roleId,
  309. deptId:deptId,
  310. deptIdList:deptIdList.toString()
  311. });
  312. this.$message({message: apiinfo.msg || '成功', type: 'success'});
  313. // await this.$confirm('每个组织只能创建一个总管理员~', '新增用户')
  314. this.newData = {
  315. userName: "",
  316. userId: "",
  317. password: "",
  318. userRole: "",
  319. deptIdList:null
  320. }
  321. this.newShow = false
  322. this.dataList.refer();
  323. },
  324. async operItem() {
  325. console.log('state.oper',this.editData);
  326. if (!this.editData.editName) {
  327. return this.$message.error("请输入用户名称", "提示");
  328. }
  329. if (!this.editData.deptIdList) {
  330. return this.$message.error("请选择用户所属架构", "提示");
  331. }
  332. if (!this.editData.roleId) {
  333. return this.$message.error("请选择用户角色", "提示");
  334. }
  335. console.log('state.oper',this.oper);
  336. let deptId = this.editData.deptIdList[this.editData.deptIdList.length - 1];
  337. await axios.post(userEdit, {
  338. id:this.oper.state.id,
  339. nickName:this.editData.editName,
  340. roleId:this.editData.roleId,
  341. deptId:deptId,
  342. deptIdList:this.editData.deptIdList.toString()
  343. });
  344. this.$message({message: '编辑成功', type: 'success'});
  345. this.oper.reset();
  346. this.editData = {
  347. editName:'',
  348. roleId:'',
  349. deptIdList:'',
  350. }
  351. this.dataList.refer();
  352. },
  353. async changeUserStatus(row, d) {
  354. let msg = row.status
  355. ? `用户被禁用后,无法登录使用,无法编辑场景(可将该用户关联的相机绑定到其它管理员)。确定要禁用吗?`
  356. : `用户被启用后,可正常登录使用。确定要启用吗?`;
  357. try {
  358. if (d || (await this.$confirm(msg, "提示"))) {
  359. await axios.post(changeUserStatus, {
  360. status: Number(!row.status),
  361. userId: row.id,
  362. });
  363. this.dataList.refer();
  364. }
  365. return true;
  366. } catch {
  367. return false;
  368. }
  369. },
  370. editChange(val){
  371. console.log('relationDeptId',val);
  372. this.relationDeptId = val&&val[val.length - 1] || '';
  373. },
  374. addChange(val){
  375. this.relationDeptId = val&&val[val.length - 1] || '';
  376. }
  377. },
  378. components: {
  379. "com-dialog": comDialog,
  380. "com-head": comHead,
  381. "com-company": comCompany,
  382. "com-role": roleCompany,
  383. "com-pagination": comPagination,
  384. // "com-select": comSelect
  385. },
  386. };
  387. </script>
  388. <style lang="scss" scoped>
  389. .body-layer{
  390. .body-but{
  391. text-align: right;
  392. margin-bottom: 15px;
  393. }
  394. }
  395. .table-ctrl-right {
  396. .search-scene {
  397. margin: 0 20px 0 26px;
  398. }
  399. i {
  400. margin-left: 20px;
  401. font-size: 1.7rem;
  402. vertical-align: middle;
  403. cursor: pointer;
  404. &.active {
  405. color: var(--primaryColor);
  406. }
  407. }
  408. }
  409. .user-from {
  410. // width: 380px;
  411. margin: 0 auto;
  412. }
  413. .tip {
  414. position: fixed;
  415. left: 50%;
  416. top: 50%;
  417. z-index: 999;
  418. &::before {
  419. content: "密码重置为Fcb20210225,可登录修改";
  420. position: absolute;
  421. width: 205px;
  422. left: 50%;
  423. transform: translateX(-50%);
  424. bottom: 100%;
  425. border-radius: 4px;
  426. padding: 10px;
  427. z-index: 2000;
  428. font-size: 12px;
  429. line-height: 1.2;
  430. min-width: 10px;
  431. word-wrap: break-word;
  432. background: #303133;
  433. color: #fff;
  434. margin-bottom: 6px;
  435. }
  436. &::after {
  437. content: "";
  438. position: absolute;
  439. display: block;
  440. width: 0;
  441. height: 0;
  442. bottom: 100%;
  443. left: 50%;
  444. transform: translateX(-50%);
  445. border-color: transparent;
  446. border-style: solid;
  447. border-width: 6px;
  448. border-top-color: #303133;
  449. border-bottom-width: 0;
  450. }
  451. }
  452. .maker {
  453. font-weight: 400;
  454. color: #969799;
  455. line-height: 20px;
  456. }
  457. </style>
  458. <style>
  459. .user-table.el-table .cell {
  460. overflow: inherit;
  461. }
  462. .user-table.el-table th, .el-table td{
  463. overflow: hidden;
  464. text-overflow: ellipsis;
  465. white-space: nowrap;
  466. }
  467. </style>