index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. <template>
  2. <div>
  3. <com-head :options="headList">
  4. <el-form label-width="84px" inline="true">
  5. <el-form-item label="用户名称:">
  6. <el-input
  7. v-model="search.state.nickName"
  8. placeholder="请输入"
  9. ></el-input>
  10. </el-form-item>
  11. <el-form-item label="所属架构:">
  12. <com-company v-model="search.state.deptId" />
  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" @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%"
  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="departmentName"
  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. v-if="auth.update || auth.updatePwd || auth.delete"
  62. >
  63. <template v-if="row.id !== ADMIN_USER_ID && row.id !== user.info.id">
  64. <span class="oper-span" @click="updateInfo(row)" v-if="auth.update"
  65. v-power="'edit'">编辑</span
  66. >
  67. <span
  68. class="oper-span"
  69. v-power="'disabled'"
  70. @click="changeUserStatus(row)"
  71. v-if="auth.delete"
  72. style="color: var(--primaryColor)"
  73. >
  74. {{ row.status ? "禁用" : "启用" }}
  75. </span>
  76. </template>
  77. </el-table-column>
  78. </el-table>
  79. <com-pagination
  80. @size-change="pag.sizeChange"
  81. @current-change="pag.currentChange"
  82. :current-page="pag.state.currPage"
  83. :page-size="pag.state.size"
  84. layout="total, sizes, prev, pager, next, jumper"
  85. :total="pag.state.total"
  86. />
  87. </div>
  88. <com-dialog
  89. title="编辑用户"
  90. v-model:show="oper.state.show"
  91. @submit="operItem"
  92. width="540"
  93. >
  94. <el-form ref="form" :model="form" label-width="90px" class="user-from">
  95. <el-form-item label="用户姓名" class="mandatory" >
  96. <el-input
  97. v-model="editName"
  98. placeholder="请输入"
  99. ></el-input>
  100. </el-form-item>
  101. </el-form>
  102. </com-dialog>
  103. <com-dialog
  104. title="新增用户"
  105. v-model:show="newShow"
  106. @submit="newSubmit"
  107. width="540"
  108. >
  109. <el-form ref="form" :model="form" label-width="90px" class="user-from">
  110. <el-form-item label="用户姓名" class="mandatory" >
  111. <el-input
  112. v-model="newData.nickName"
  113. placeholder="请输入"
  114. ></el-input>
  115. </el-form-item>
  116. <el-form-item label="用户角色" class="roleName mandatory">
  117. <com-role v-model="newData.roleId" style="width: 100%" allText="请选择" hideAll :notDefault="true" />
  118. </el-form-item>
  119. <el-form-item label="所属架构:" v-if="user.roleKey == 'admin'">
  120. <com-select v-model="newData.deptId" />
  121. </el-form-item>
  122. <el-form-item label="用户账号" class="mandatory">
  123. <el-input
  124. v-model="newData.userName"
  125. placeholder="请输入11位手机号码作为用户账号"
  126. ></el-input>
  127. </el-form-item>
  128. <el-form-item label="登录密码" class="mandatory">
  129. <el-input
  130. v-model="newData.psw"
  131. placeholder="请输入8-16位数字、英文大小写组合密码"
  132. type="password"
  133. ></el-input>
  134. </el-form-item>
  135. </el-form>
  136. </com-dialog>
  137. </div>
  138. </template>
  139. <script>
  140. import { reactive, ref, toRefs } from "vue";
  141. import getTableState from "@/state/tableRef";
  142. import comDialog from "@/components/dialog";
  143. import comHead from "@/components/head";
  144. import comCompany from "@/components/company-select";
  145. import comPagination from "@/components/pagination";
  146. import roleCompany from "@/components/role-select";
  147. import comSelect from "@/components/company-select";
  148. import auth from "@/state/viewAuth";
  149. import user from "@/state/user";
  150. import axios from "axios";
  151. // import { encryption } from "@/util";
  152. // import { PSW, PHONE } from "@/constant/REG";
  153. import { ADMIN_USER_ID } from "@/constant";
  154. import { getUserList, updateUser, changeUserStatus,userAdd,userEdit } from "@/request/config";
  155. import { getApp } from "../../app";
  156. export default {
  157. name: "user",
  158. setup() {
  159. const state = getTableState({
  160. getUrl: getUserList,
  161. updateUrl: updateUser,
  162. operAttr: {
  163. nickName: "",
  164. userName: "",
  165. deptId: "",
  166. password: "",
  167. confirmPwd: "",
  168. roleId: "",
  169. maxlevel: 1,
  170. },
  171. searchAttr: { nickName: "", status: "", deptId: "" },
  172. });
  173. const headList = ref([{ name: "用户管理", value: 2 }]);
  174. const operRoleId = ref("");
  175. const updateInfo = (row) => {
  176. if (!row.status) {
  177. return getApp().$message.error("请先启用用户", "提示");
  178. }
  179. operRoleId.value = row.roleId;
  180. state.oper.value.readyUpdate(row);
  181. };
  182. const newAddclick = () =>{
  183. data.newShow = true
  184. }
  185. const data = reactive({
  186. newShow: false,
  187. editName:'',//修改编辑用户名称
  188. newData:{
  189. userName: "",
  190. userId: "",
  191. password: "",
  192. userRole: "",
  193. }
  194. });
  195. return {
  196. ...state,
  197. ...toRefs(data),
  198. headList,
  199. updateInfo,
  200. auth,
  201. user,
  202. operRoleId,
  203. ADMIN_USER_ID,
  204. newAddclick
  205. };
  206. },
  207. methods: {
  208. async newSubmit(){
  209. console.log('newSubmit',this.user,this.newData);
  210. if (!this.newData.nickName) {
  211. return this.$message.error("请输入用户姓名", "提示");
  212. }
  213. if (!this.newData.roleId) {
  214. return this.$message.error("请选择用户角色", "提示");
  215. }
  216. if (!this.newData.userName) {
  217. return this.$message.error("请选择用户账户", "提示");
  218. }
  219. if (!this.newData.psw) {
  220. return this.$message.error("请输入登录密码", "提示");
  221. }
  222. await axios.post(userAdd, {
  223. nickName:this.newData.nickName,
  224. password:this.newData.psw,
  225. userName:this.newData.userName,
  226. roleId:this.newData.roleId,
  227. deptId:this.newData.deptId
  228. // ...this.newData
  229. });
  230. this.$message({message: '新增成功', type: 'success'});
  231. // await this.$confirm('每个组织只能创建一个总管理员~', '新增用户')
  232. this.newData = {}
  233. this.newShow = false
  234. this.dataList.refer();
  235. },
  236. async operItem() {
  237. if (!this.editName) {
  238. return this.$message.error("请输入用户名称", "提示");
  239. }
  240. console.log('state.oper',this.oper);
  241. await axios.post(userEdit, {
  242. id:this.oper.state.id,
  243. nickName:this.editName,
  244. });
  245. this.$message({message: '编辑成功', type: 'success'});
  246. this.oper.reset();
  247. this.editName = ''
  248. this.dataList.refer();
  249. // const updatePhone = this.oper.state.__oldData
  250. // ? this.oper.state.__oldData.userName !== this.oper.state.userName
  251. // : true;
  252. // if (updatePhone && !PHONE.REG.test(this.oper.state.userName)) {
  253. // return this.$message.error(PHONE.tip, "提示");
  254. // }
  255. // if (this.oper.state.password !== this.oper.state.confirmPwd) {
  256. // return this.$message.error("两次密码不一致!", "提示");
  257. // }
  258. // if (!this.oper.state.roleId) {
  259. // return this.$message.error("请选择用户角色", "提示");
  260. // }
  261. // if (
  262. // !this.operRoleId &&
  263. // !(await this.$confirm(
  264. // "用户被启用后,可正常登录使用。确定要启用吗?",
  265. // "提示"
  266. // ))
  267. // ) {
  268. // return;
  269. // }
  270. // if (this.oper.state.id) {
  271. // let updateState = {
  272. // ...this.oper.state,
  273. // password: void 0,
  274. // confirmPwd: void 0,
  275. // updatePwd: void 0,
  276. // userId: this.oper.state.id,
  277. // };
  278. // if (!updatePhone) {
  279. // delete updateState.userName;
  280. // }
  281. // let state = { ...this.oper.state };
  282. // await this.oper.update(updateState);
  283. // await this.changeUserStatus(state, true);
  284. // } else if (this.oper.state.password === this.oper.state.confirmPwd) {
  285. // if (PSW.REG.test(this.oper.state.password)) {
  286. // let cryPsw = encryption(this.oper.state.password);
  287. // this.oper.insert({
  288. // ...this.oper.state,
  289. // password: cryPsw,
  290. // confirmPwd: cryPsw,
  291. // updatePwd: void 0,
  292. // });
  293. // } else {
  294. // this.$message.error(PSW.tip, "提示");
  295. // }
  296. // }
  297. },
  298. async changeUserStatus(row, d) {
  299. // if (!d && (!row.roleId && !row.status)) {
  300. // this.operRoleId = row.roleId
  301. // return this.oper.readyUpdate(row)
  302. // }
  303. let msg = row.status
  304. ? `用户被禁用后,无法登录使用,无法编辑场景(可将该用户关联的相机绑定到其它管理员)。确定要禁用吗?`
  305. : `用户被启用后,可正常登录使用。确定要启用吗?`;
  306. try {
  307. if (d || (await this.$confirm(msg, "提示"))) {
  308. await axios.post(changeUserStatus, {
  309. status: Number(!row.status),
  310. userId: row.id,
  311. });
  312. this.dataList.refer();
  313. }
  314. return true;
  315. } catch {
  316. return false;
  317. }
  318. },
  319. },
  320. components: {
  321. "com-dialog": comDialog,
  322. "com-head": comHead,
  323. "com-company": comCompany,
  324. "com-role": roleCompany,
  325. "com-pagination": comPagination,
  326. "com-select": comSelect
  327. },
  328. };
  329. </script>
  330. <style lang="scss" scoped>
  331. .body-layer{
  332. .body-but{
  333. text-align: right;
  334. margin-bottom: 15px;
  335. }
  336. }
  337. .table-ctrl-right {
  338. .search-scene {
  339. margin: 0 20px 0 26px;
  340. }
  341. i {
  342. margin-left: 20px;
  343. font-size: 1.7rem;
  344. vertical-align: middle;
  345. cursor: pointer;
  346. &.active {
  347. color: var(--primaryColor);
  348. }
  349. }
  350. }
  351. .user-from {
  352. // width: 380px;
  353. margin: 0 auto;
  354. }
  355. .tip {
  356. position: fixed;
  357. left: 50%;
  358. top: 50%;
  359. z-index: 999;
  360. &::before {
  361. content: "密码重置为Fcb20210225,可登录修改";
  362. position: absolute;
  363. width: 205px;
  364. left: 50%;
  365. transform: translateX(-50%);
  366. bottom: 100%;
  367. border-radius: 4px;
  368. padding: 10px;
  369. z-index: 2000;
  370. font-size: 12px;
  371. line-height: 1.2;
  372. min-width: 10px;
  373. word-wrap: break-word;
  374. background: #303133;
  375. color: #fff;
  376. margin-bottom: 6px;
  377. }
  378. &::after {
  379. content: "";
  380. position: absolute;
  381. display: block;
  382. width: 0;
  383. height: 0;
  384. bottom: 100%;
  385. left: 50%;
  386. transform: translateX(-50%);
  387. border-color: transparent;
  388. border-style: solid;
  389. border-width: 6px;
  390. border-top-color: #303133;
  391. border-bottom-width: 0;
  392. }
  393. }
  394. .maker {
  395. font-weight: 400;
  396. color: #969799;
  397. line-height: 20px;
  398. }
  399. </style>
  400. <style>
  401. .user-table.el-table .cell {
  402. overflow: inherit;
  403. }
  404. </style>