devicePerson-list.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. <template>
  2. <div>
  3. <el-breadcrumb separator=">">
  4. <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
  5. <el-breadcrumb-item>
  6. <a href="#">基础信息管理</a>
  7. </el-breadcrumb-item>
  8. <el-breadcrumb-item>
  9. <a href="#">设备人员管理</a>
  10. </el-breadcrumb-item>
  11. </el-breadcrumb>
  12. <el-divider></el-divider>
  13. <!--
  14. 要resetFields起作用,必须配置:model和prop
  15. -->
  16. <el-form
  17. ref="queryForm"
  18. :model="queryModel"
  19. :rules="ruleValidate"
  20. inline
  21. class="demo-form-inline"
  22. >
  23. <div>
  24. <el-form-item label="姓名" prop="name">
  25. <el-input type="text" size="mini" v-model="queryModel.name"></el-input>
  26. </el-form-item>
  27. <el-form-item label="手机号" prop="phone">
  28. <el-input type="text" size="mini" v-model="queryModel.phone"></el-input>
  29. </el-form-item>
  30. <el-form-item label="身份证" prop="idCard">
  31. <el-input type="text" size="mini" v-model="queryModel.idCard"></el-input>
  32. </el-form-item>
  33. <el-form-item>
  34. <el-button
  35. type="primary"
  36. size="mini"
  37. icon="ios-search"
  38. @click="handleQuery"
  39. :loading="loading"
  40. >查询</el-button>&nbsp;
  41. <el-button
  42. type="info"
  43. size="mini"
  44. style="margin-left: 8px"
  45. @click="handleReset('queryForm')"
  46. >重置</el-button>&nbsp;
  47. </el-form-item>
  48. </div>
  49. <div>
  50. <el-form-item label="单位" prop="parentId">
  51. <el-select-tree
  52. size="mini"
  53. :props="props"
  54. :options="companyResult"
  55. v-model="queryModel.parentId"
  56. height="200"
  57. ></el-select-tree>&nbsp;
  58. <el-checkbox v-model="queryModel.subordinate">是否包含下级单位</el-checkbox>
  59. </el-form-item>
  60. <el-form-item label="绑定设备名称" prop="deviceId">
  61. <el-select
  62. v-model="queryModel.deviceId"
  63. size="mini"
  64. filterable
  65. clearable
  66. remote
  67. style="width:220px;"
  68. placeholder="请输入关键词"
  69. :remote-method="queryDevice"
  70. >
  71. <el-option
  72. v-for="device in deviceResult"
  73. :key="device.id"
  74. :label="device.aliasName"
  75. :value="device.id"
  76. ></el-option>
  77. </el-select>
  78. </el-form-item>
  79. <el-form-item label="是否上传照片" prop="isUploadPhoto">
  80. <el-select
  81. v-model="queryModel.isUploadPhoto"
  82. size="mini"
  83. filterable
  84. placeholder="请选择"
  85. style="width:120px"
  86. >
  87. <el-option value label="全部"></el-option>
  88. <el-option value="1" label="已上传"></el-option>
  89. <el-option value="0" label="未上传"></el-option>
  90. </el-select>
  91. </el-form-item>
  92. <el-form-item label="是否同步" prop="isBound">
  93. <el-select
  94. v-model="queryModel.isBound"
  95. size="mini"
  96. filterable
  97. placeholder="请选择"
  98. style="width:120px"
  99. >
  100. <el-option value label="全部"></el-option>
  101. <el-option value="1" label="已同步"></el-option>
  102. <el-option value="0" label="未同步"></el-option>
  103. </el-select>
  104. </el-form-item>
  105. </div>
  106. <!-- <div>
  107. <el-form-item v-if="position1Show" :label="position1" prop="position1">
  108. <el-input type="text" size="mini" v-model="queryModel.position1"></el-input>
  109. </el-form-item>
  110. <el-form-item v-if="position2Show" :label="position2" prop="position2">
  111. <el-input type="text" size="mini" v-model="queryModel.position2"></el-input>
  112. </el-form-item>
  113. <el-form-item v-if="position3Show" :label="position3" prop="position3">
  114. <el-input type="text" size="mini" v-model="queryModel.position3"></el-input>
  115. </el-form-item>
  116. <el-form-item v-if="position4Show" :label="position4" prop="position4">
  117. <el-input type="text" size="mini" v-model="queryModel.position4"></el-input>
  118. </el-form-item>
  119. <el-form-item v-if="position5Show" :label="position5" prop="position5">
  120. <el-input type="text" size="mini" v-model="queryModel.position5"></el-input>
  121. </el-form-item>
  122. </div> -->
  123. </el-form>
  124. <el-divider></el-divider>
  125. <el-row class="button-group">
  126. <el-button
  127. type="primary"
  128. size="small"
  129. plain
  130. icon="el-icon-refresh"
  131. :disabled="multipleSelection.length==0"
  132. @click="dataSync"
  133. >数据同步</el-button>
  134. </el-row>
  135. <el-table
  136. ref="formTable"
  137. :data="tableData"
  138. v-loading="loading"
  139. stripe
  140. :height="tableHeight"
  141. @sort-change="sortChange"
  142. @selection-change="handleSelectionChange"
  143. >
  144. <el-table-column type="selection" width="55"></el-table-column>
  145. <el-table-column prop="personInfo.id" label="序号" width="80" fixed="left"></el-table-column>
  146. <el-table-column prop="personInfo.name" label="姓名" width="80" fixed="left"></el-table-column>
  147. <el-table-column prop="personInfo.faceImageUrl" label="人员照片" width="80" fixed="left">
  148. <template v-if="row.personInfo.faceImageUrl" slot-scope="{row}">
  149. <a :href="row.personInfo.faceImageUrl" target="_blank">
  150. <el-avatar
  151. :size="48"
  152. shape="circle"
  153. :src="row.personInfo.faceImageUrl+'?x-oss-process=image/resize,m_fill,w_64,h_64'"
  154. :key="row.personInfo.id"
  155. ></el-avatar>
  156. </a>
  157. </template>
  158. </el-table-column>
  159. <el-table-column prop="personInfo.companyName" label="单位" width="250"></el-table-column>
  160. <el-table-column prop="personInfo.phone" label="手机号" width="180"></el-table-column>
  161. <el-table-column prop="personInfo.idCard" label="身份证" width="100" show-overflow-tooltip></el-table-column>
  162. <el-table-column prop="deviceInfo.aliasName" label="绑定设备" width="150" show-overflow-tooltip></el-table-column>
  163. <el-table-column prop="isBound" label="是否同步到设备" width="150" show-overflow-tooltip>
  164. <template slot-scope="{row}">{{row.isBound ? "是" : "否"}}</template>
  165. </el-table-column>
  166. <el-table-column
  167. prop="personInfo.position1"
  168. :label="position1"
  169. width="180"
  170. v-if="position1Show"
  171. ></el-table-column>
  172. <el-table-column
  173. prop="personInfo.position2"
  174. :label="position2"
  175. width="180"
  176. v-if="position2Show"
  177. ></el-table-column>
  178. <el-table-column
  179. prop="personInfo.position3"
  180. :label="position3"
  181. width="180"
  182. v-if="position3Show"
  183. ></el-table-column>
  184. <el-table-column
  185. prop="personInfo.position4"
  186. :label="position4"
  187. width="180"
  188. v-if="position4Show"
  189. ></el-table-column>
  190. <el-table-column
  191. prop="personInfo.position5"
  192. :label="position5"
  193. width="180"
  194. v-if="position5Show"
  195. ></el-table-column>
  196. <el-table-column prop="personInfo.openId" label="是否绑定公众号" width="180">
  197. <template slot-scope="{row}">{{row.personInfo.openId == null ? "否" : "是"}}</template>
  198. </el-table-column>
  199. <!-- <el-table-column prop="personInfo.faceBound" label="是否同步人脸信息" width="180">
  200. <template slot-scope="{row}">{{row.personInfo.faceBound ? "是" : "否"}}</template>
  201. </el-table-column>-->
  202. <el-table-column prop="personInfo.popedom" label="用户身份" width="200">
  203. <template slot-scope="{row}">
  204. <el-row>
  205. <el-col :span="10" v-if="row.personInfo.popedom.indexOf('1')!= -1">个人用户</el-col>
  206. <el-col :span="10" v-if="row.personInfo.popedom.indexOf('2')!= -1">单位管理员</el-col>
  207. <el-col :span="10" v-if="row.personInfo.popedom.indexOf('3')!= -1">监管专员</el-col>
  208. </el-row>
  209. </template>
  210. </el-table-column>
  211. <el-table-column label="人脸授权">
  212. <template slot-scope="{row}">
  213. <el-switch
  214. v-model="row.personInfo.faceEnabled"
  215. active-color="#13ce66"
  216. inactive-color="#ff4949"
  217. disabled
  218. ></el-switch>
  219. </template>
  220. </el-table-column>
  221. <el-table-column label="刷卡授权">
  222. <template slot-scope="{row}">
  223. <el-switch
  224. v-model="row.personInfo.cardEnabled"
  225. active-color="#13ce66"
  226. inactive-color="#ff4949"
  227. disabled
  228. ></el-switch>
  229. </template>
  230. </el-table-column>
  231. <el-table-column label="手机授权">
  232. <template slot-scope="{row}">
  233. <el-switch
  234. v-model="row.personInfo.appEnabled"
  235. active-color="#13ce66"
  236. inactive-color="#ff4949"
  237. disabled
  238. ></el-switch>
  239. </template>
  240. </el-table-column>
  241. <!-- <el-table-column label="密码">
  242. <template slot-scope="{row}">
  243. <el-switch v-model="row.passwordEnabled" @change="enabledTo(row.id,'face')" active-color="#13ce66" inactive-color="#ff4949"></el-switch>
  244. </template>
  245. </el-table-column>-->
  246. <el-table-column label="访客授权">
  247. <template slot-scope="{row}">
  248. <el-switch
  249. v-model="row.personInfo.guestEnabled"
  250. active-color="#13ce66"
  251. inactive-color="#ff4949"
  252. disabled
  253. ></el-switch>
  254. </template>
  255. </el-table-column>
  256. <el-table-column label="接收微信通知">
  257. <template slot-scope="{row}">
  258. <el-switch
  259. v-model="row.personInfo.wechatNoticeEnabled"
  260. active-color="#13ce66"
  261. inactive-color="#ff4949"
  262. disabled
  263. ></el-switch>
  264. </template>
  265. </el-table-column>
  266. <el-table-column label="操作" width="80" fixed="right">
  267. <template slot-scope="{row}">
  268. <el-row>
  269. <el-col>
  270. <span v-if="row.isBound">
  271. <el-link
  272. type="primary"
  273. :underline="false"
  274. :disabled="true"
  275. @click="uploadData(row)"
  276. >数据同步</el-link>
  277. </span>
  278. <span v-else>
  279. <el-link type="primary" :underline="false" @click="uploadData(row)">数据同步</el-link>
  280. </span>
  281. </el-col>
  282. </el-row>
  283. </template>
  284. </el-table-column>
  285. </el-table>
  286. <el-pagination
  287. :current-page.sync="pageIndex"
  288. :total="totalElements"
  289. :page-sizes="pageSizeList"
  290. @current-change="changePage"
  291. @size-change="pageSizeChange"
  292. layout="total, sizes, prev, pager, next, jumper"
  293. ></el-pagination>
  294. </div>
  295. </template>
  296. <script>
  297. import Constant from "@/constant";
  298. import personInfoApi from "@/api/base/personInfo";
  299. import companyInfoApi from "@/api/base/companyInfo";
  300. import companyPositionApi from "@/api/base/companyPosition";
  301. import deviceInfoApi from "@/api/base/deviceInfo";
  302. import personDeviceRelationApi from "@/api/base/personDeviceRelation";
  303. import SelectTree from "@/components/SelectTree";
  304. import { getToken } from "@/utils/auth"; // get token from cookie
  305. import NProgress from "nprogress"; // progress bar
  306. import "nprogress/nprogress.css"; // progress bar style
  307. export default {
  308. name: "BaseDevicePersonList",
  309. data() {
  310. var self = this;
  311. return {
  312. ruleValidate: {
  313. parentId: [{ required: true, message: "请选择单位", trigger: "blur" }],
  314. deviceId: [{ required: true, message: "请选择设备", trigger: "blur" }]
  315. },
  316. queryModel: {
  317. companyCode: "",
  318. parentId: "",
  319. name: "",
  320. phone: "",
  321. idCard: "",
  322. isBound: "",
  323. isUploadPhoto: "",
  324. subordinate: false,
  325. position1: "",
  326. position2: "",
  327. position3: "",
  328. position4: "",
  329. position5: "",
  330. deviceId: ""
  331. },
  332. loading: false,
  333. tableData: [],
  334. pageIndex: 1,
  335. pageSize: 30,
  336. totalPages: 0,
  337. totalElements: 0,
  338. field: "",
  339. direction: "",
  340. pageSizeList: [30, 100, 500],
  341. multipleSelection: [],
  342. showModal: false,
  343. modalTitle: "",
  344. businessKey: "",
  345. companyResult: [],
  346. uploadCompanyId: "",
  347. batchImportVisible: false,
  348. batchImportFileList: [],
  349. disabled: false,
  350. position1: "",
  351. position2: "",
  352. position3: "",
  353. position4: "",
  354. position5: "",
  355. position1Show: false,
  356. position2Show: false,
  357. position3Show: false,
  358. position4Show: false,
  359. position5Show: false,
  360. personId: "",
  361. deviceResult: [],
  362. boundDeviceId: "",
  363. boundUnDeviceId: "",
  364. xlsLoading: false,
  365. tableHeight: 400,
  366. boundDeviceDisabled: false,
  367. treeData: [],
  368. props: {
  369. // 配置项(必选)
  370. value: "id",
  371. label: "name",
  372. children: "children"
  373. }
  374. };
  375. },
  376. created() {
  377. var self = this;
  378. companyInfoApi.list().then(function(response) {
  379. var jsonData = response.data;
  380. if (jsonData.result) {
  381. if (jsonData.data != null && jsonData.data != "") {
  382. self.companyResult = jsonData.data;
  383. }
  384. }
  385. });
  386. companyPositionApi.detailForCompany().then(function(response) {
  387. var jsonData = response.data.data;
  388. if (jsonData.position1Name != null && jsonData.position1Name != "") {
  389. self.position1 = jsonData.position1Name;
  390. self.position1Show = true;
  391. }
  392. if (jsonData.position2Name != null && jsonData.position2Name != "") {
  393. self.position2 = jsonData.position2Name;
  394. self.position2Show = true;
  395. }
  396. if (jsonData.position3Name != null && jsonData.position3Name != "") {
  397. self.position3 = jsonData.position3Name;
  398. self.position3Show = true;
  399. }
  400. if (jsonData.position4Name != null && jsonData.position4Name != "") {
  401. self.position4 = jsonData.position4Name;
  402. self.position4Show = true;
  403. }
  404. if (jsonData.position5Name != null && jsonData.position5Name != "") {
  405. self.position5 = jsonData.position5Name;
  406. self.position5Show = true;
  407. }
  408. });
  409. this.queryDevice("");
  410. this.loadTree();
  411. },
  412. methods: {
  413. queryDevice(aliasName) {
  414. var self = this;
  415. var formData = new FormData();
  416. formData.append("companyId", self.queryModel.parentId);
  417. formData.append("aliasName", aliasName);
  418. formData.append("limit", 10);
  419. deviceInfoApi.query(formData).then(function(response) {
  420. var jsonData = response.data;
  421. if (jsonData.result) {
  422. if (jsonData.data != null && jsonData.data != "") {
  423. self.deviceResult = jsonData.data;
  424. }
  425. }
  426. });
  427. },
  428. getSelectedValue(value) {
  429. this.queryModel.parentId = value;
  430. },
  431. loadTree() {
  432. var formData = new FormData();
  433. companyInfoApi.loadChildren(formData).then(resp => {
  434. var jsonData = resp.data;
  435. if (jsonData.result) {
  436. this.treeData = jsonData.data;
  437. } else {
  438. this.$message.error(jsonData.message + "");
  439. }
  440. });
  441. },
  442. loadChildren(tree, treeNode, resolve) {
  443. console.log(tree);
  444. var formData = new FormData();
  445. formData.append("parentId", tree.id);
  446. companyInfoApi.loadChildren(formData).then(resp => {
  447. var jsonData = resp.data;
  448. if (jsonData.result) {
  449. resolve(jsonData.data);
  450. } else {
  451. this.$message.error(jsonData.message + "");
  452. }
  453. });
  454. },
  455. handleQuery() {
  456. var self = this;
  457. this.$refs["queryForm"].validate(valid => {
  458. if (valid) {
  459. self.changePage(1);
  460. }
  461. });
  462. },
  463. changePage(pageIndex) {
  464. var self = this;
  465. self.loading = true;
  466. self.pageIndex = pageIndex;
  467. var formData = new FormData();
  468. formData.append("pageIndex", self.pageIndex);
  469. formData.append("pageSize", self.pageSize);
  470. if (self.queryModel.parentId == null) {
  471. self.queryModel.parentId = "";
  472. }
  473. formData.append("companyCode", self.queryModel.companyCode);
  474. formData.append("parentId", self.queryModel.parentId);
  475. formData.append("subordinate", self.queryModel.subordinate);
  476. formData.append("name", self.queryModel.name);
  477. formData.append("phone", self.queryModel.phone);
  478. formData.append("idCard", self.queryModel.idCard);
  479. formData.append("isBound", self.queryModel.isBound);
  480. formData.append("isUploadPhoto", self.queryModel.isUploadPhoto);
  481. formData.append("position1", self.queryModel.position1);
  482. formData.append("position2", self.queryModel.position2);
  483. formData.append("position3", self.queryModel.position3);
  484. formData.append("position4", self.queryModel.position4);
  485. formData.append("position5", self.queryModel.position5);
  486. formData.append("deviceId", self.queryModel.deviceId);
  487. if (this.field != null) {
  488. formData.append("field", this.field);
  489. }
  490. if (this.direction != null) {
  491. formData.append("direction", this.direction);
  492. }
  493. personDeviceRelationApi
  494. .devicePersonList(formData)
  495. .then(function(response) {
  496. self.loading = false;
  497. var jsonData = response.data.data;
  498. self.tableData = jsonData.data;
  499. self.totalPages = jsonData.totalPages;
  500. self.totalElements = jsonData.recordsTotal;
  501. //45为分页栏的高度
  502. //页面高度-列表上面的高度-分页栏高度
  503. self.tableHeight =
  504. window.innerHeight - self.$refs.formTable.$el.offsetTop - 45;
  505. })
  506. .catch(error => {
  507. self.loading = false;
  508. // self.$message.error(error + "");
  509. });
  510. },
  511. pageSizeChange(pageSize) {
  512. this.pageSize = pageSize;
  513. this.changePage(this.pageIndex);
  514. },
  515. sortChange(data) {
  516. this.field = data.column.field;
  517. this.changePage(this.pageIndex);
  518. },
  519. handleSelectionChange(val) {
  520. this.multipleSelection = val;
  521. },
  522. handleReset(name) {
  523. this.$refs[name].resetFields();
  524. },
  525. uploadData(record) {
  526. //同步人脸数据
  527. var self = this;
  528. self.loading = true;
  529. var uploadSync = new Array(0);
  530. uploadSync.push(record.personInfo.id);
  531. var formData = new FormData();
  532. formData.append("personId", uploadSync);
  533. formData.append("deviceId", record.deviceId);
  534. personDeviceRelationApi
  535. .devicePersonSync(formData)
  536. .then(function(response) {
  537. var jsonData = response.data;
  538. self.loading = false;
  539. if (jsonData.result) {
  540. if (jsonData.data) {
  541. self.changePage(self.pageIndex);
  542. self.$message({
  543. type: "success",
  544. message: "同步成功!"
  545. });
  546. } else {
  547. if (jsonData.message != null) {
  548. //下载有错误信息提示的报表
  549. //window.open(response.data);
  550. self.$message({
  551. showClose: true,
  552. dangerouslyUseHTMLString: true,
  553. message:
  554. "错误" +
  555. `,<a href="${jsonData.message}" target="_blank">点击下载错误报表</a>&nbsp;`,
  556. duration: 30000
  557. });
  558. }
  559. }
  560. } else {
  561. self.$message({
  562. type: "warning",
  563. message: jsonData.message
  564. });
  565. }
  566. });
  567. },
  568. dataSync() {
  569. //批量同步人脸
  570. var self = this;
  571. var idList = this.multipleSelection.map(record => {
  572. return record.personInfo.id;
  573. });
  574. this.$confirm("是否确认同步选中项?", "提示", {
  575. confirmButtonText: "确定",
  576. cancelButtonText: "取消",
  577. type: "warning"
  578. })
  579. .then(() => {
  580. self.loading = true;
  581. var formData = new FormData();
  582. formData.append("personIds", idList);
  583. formData.append("deviceId", self.queryModel.deviceId);
  584. personDeviceRelationApi
  585. .devicePersonsSync(formData)
  586. .then(function(response) {
  587. var jsonData = response.data;
  588. self.loading = false;
  589. if (jsonData.result) {
  590. if (jsonData.data) {
  591. self.changePage(self.pageIndex);
  592. self.$message({
  593. type: "success",
  594. message: "同步成功!"
  595. });
  596. } else {
  597. if (jsonData.message != null) {
  598. //下载有错误信息提示的报表
  599. //window.open(response.data);
  600. self.$message({
  601. showClose: true,
  602. dangerouslyUseHTMLString: true,
  603. message:
  604. "错误" +
  605. `,<a href="${jsonData.message}" target="_blank">点击下载错误报表</a>&nbsp;`,
  606. duration: 30000
  607. });
  608. }
  609. }
  610. } else {
  611. self.$message({
  612. type: "warning",
  613. message: jsonData.message
  614. });
  615. }
  616. });
  617. })
  618. .catch(() => {
  619. self.loading = false;
  620. });
  621. }
  622. },
  623. async mounted() {
  624. var self = this;
  625. this.queryDevice("");
  626. },
  627. components: {
  628. "el-select-tree": SelectTree
  629. }
  630. };
  631. </script>
  632. <style lang="scss" scoped>
  633. .el-breadcrumb {
  634. margin: 10px;
  635. line-height: 20px;
  636. }
  637. .el-divider {
  638. margin: 5px 0;
  639. }
  640. .demo-form-inline {
  641. margin-left: 10px;
  642. text-align: left;
  643. }
  644. .button-group {
  645. margin-left: 10px;
  646. text-align: left;
  647. }
  648. .el-select-dropdown__wrap .el-scrollbar__wrap {
  649. margin: 0px;
  650. max-height: 10;
  651. overflow: scroll;
  652. }
  653. </style>