equipManage.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. <template>
  2. <div class="innerMargin">
  3. <el-card class="box-card">
  4. <div style="cursor: default">
  5. <div class="search-box">
  6. <div class="filter-box">
  7. <el-select
  8. size="small"
  9. v-model="queryInfo.device_type_id"
  10. clearable
  11. placeholder="请选择设备类型"
  12. @change="searchChange()"
  13. >
  14. <el-option label="杀虫灯" value="2"></el-option>
  15. <el-option label="测报灯" value="3"></el-option>
  16. <el-option label="智能性诱" value="4"></el-option>
  17. <el-option label="环境监测" value="5"></el-option>
  18. <el-option label="监控设备" value="6"></el-option>
  19. <el-option label="孢子仪" value="7"></el-option>
  20. <el-option label="性诱设备" value="8"></el-option>
  21. <el-option label="糖醋测报" value="9"></el-option>
  22. <el-option label="灾害预警" value="1112"></el-option>
  23. </el-select>
  24. <el-input
  25. style="cursor: pointer"
  26. size="small"
  27. clearable
  28. @change="searchChange()"
  29. placeholder="请输入设备ID"
  30. v-model="queryInfo.f_id"
  31. >
  32. <i slot="suffix" class="el-input__icon el-icon-search"></i>
  33. </el-input>
  34. </div>
  35. <el-date-picker
  36. style="cursor: pointer"
  37. size="small"
  38. @change="DateChange()"
  39. v-model="timeRange"
  40. type="daterange"
  41. range-separator="至"
  42. start-placeholder="开始日期"
  43. end-placeholder="结束日期"
  44. ></el-date-picker>
  45. </div>
  46. <el-row :gutter="10">
  47. <el-col
  48. :xs="24"
  49. :sm="24"
  50. :md="12"
  51. :lg="6"
  52. :xl="4"
  53. v-for="item in dataList"
  54. :key="item.id"
  55. >
  56. <el-card class="box-card pad0">
  57. <i class="del-icon el-icon-delete" @click="delEquip(item.d_id)"></i>
  58. <div class="img-box">
  59. <template v-if="item.device_type_id == '2'">
  60. <img src="@/assets/images/equipdistribute/scdIconOn.png" />
  61. </template>
  62. <template v-if="item.device_type_id == '3'">
  63. <img src="@/assets/images/equipdistribute/cbdIconOn.png" />
  64. </template>
  65. <template v-if="item.device_type_id == '4'">
  66. <img src="@/assets/images/equipdistribute/znxyOn.png" />
  67. </template>
  68. <template v-if="item.device_type_id == '5'">
  69. <img src="@/assets/images/equipdistribute/hjjcIconOn.png" />
  70. </template>
  71. <template v-if="item.device_type_id == '6'">
  72. <img src="@/assets/images/equipdistribute/jkIconOn.png" />
  73. </template>
  74. <template v-if="item.device_type_id == '7'">
  75. <img src="@/assets/images/equipdistribute/bzyIconOn.png" />
  76. </template>
  77. <template v-if="item.device_type_id == '8'">
  78. <img src="@/assets/images/equipdistribute/xyOn.png" />
  79. </template>
  80. <template v-if="item.device_type_id == '9'">
  81. <img src="@/assets/images/equipdistribute/tccbOn.png" />
  82. </template>
  83. <template v-if="item.device_type_id == '11'">
  84. <img src="@/assets/images/equipdistribute/warnOn11.png" />
  85. </template>
  86. <template v-if="item.device_type_id == '12'">
  87. <img src="@/assets/images/equipdistribute/warnOn12.png" />
  88. </template>
  89. <div class="equipName">
  90. <span>
  91. {{ item.device_name || "无" }}
  92. </span>
  93. <span class="editNameIcon" @click="modifyName(item.device_id, item.device_name)">
  94. <i class="el-icon-edit-outline"></i>
  95. </span>
  96. </div>
  97. </div>
  98. <div class="detail">
  99. <p>
  100. 设备ID
  101. <span>{{ item.device_id }}</span>
  102. </p>
  103. <p>
  104. 适配用户
  105. <span>{{ item.device_user || "无" }}</span>
  106. </p>
  107. <p v-if="item.name">
  108. 设备组名称
  109. <span>{{ item.name || "无" }}</span>
  110. </p>
  111. <p v-else>
  112. 设备名称
  113. <span>{{ item.device_name || "无" }}</span>
  114. </p>
  115. <p>
  116. 位置
  117. <span>{{ item.device_location || "无" }}</span>
  118. </p>
  119. <p>
  120. 设备添加时间
  121. <span>{{ (item.creat_time * 1000) | formatTime }}</span>
  122. </p>
  123. </div>
  124. <div class="bottom">
  125. <span v-if="item.device_type_id == '11' || item.device_type_id == '12'" @click="modifyGroupName(item.device_id, item.device_name)">
  126. <i class="el-icon-edit-outline"></i> 修改设备组
  127. </span>
  128. <span @click="addPosition(item.device_id, item.lng, item.lat)">
  129. <i class="el-icon-location-outline"></i> 添加位置
  130. </span>
  131. <span @click="addFault(item.device_id, item.device_type_id)">
  132. <i class="el-icon-edit-outline"></i> 故障上报
  133. </span>
  134. </div>
  135. </el-card>
  136. </el-col>
  137. </el-row>
  138. <!-- 暂无数据 -->
  139. <div class="expertDiagnosis_referral_units_not" v-if="dataList.length <= 0">
  140. <img
  141. :src="$imghost + zanwu"
  142. alt
  143. class="expertDiagnosis_referral_units_notImg"
  144. />
  145. </div>
  146. <el-pagination
  147. v-if="dataList.length > 0"
  148. background
  149. layout="prev, pager, next, jumper"
  150. :page-size="12"
  151. :total="totalNum"
  152. @current-change="changePage"
  153. ></el-pagination>
  154. <!-- 添加定位弹框 -->
  155. <el-dialog
  156. class="map_dialog"
  157. title="添加定位"
  158. :visible.sync="addLocationDialogVisible"
  159. width="800px"
  160. top="180px"
  161. @closed="addLocationDialogClosed"
  162. >
  163. <el-form
  164. :inline="true"
  165. :model="locationForm"
  166. class="demo-form-inline"
  167. size="mini"
  168. >
  169. <el-form-item label="经度">
  170. <el-input clearable v-model="locationForm.lng"></el-input>
  171. </el-form-item>
  172. <el-form-item label="维度">
  173. <el-input clearable v-model="locationForm.lat"></el-input>
  174. </el-form-item>
  175. <el-form-item>
  176. <el-button type="primary" size="mini" @click="locationSearch"
  177. >定位</el-button
  178. >
  179. </el-form-item>
  180. <el-form-item label="">
  181. <el-input
  182. placeholder="请输入地区检索"
  183. v-model="addr"
  184. clearable
  185. @change="addrChange()"
  186. ></el-input>
  187. </el-form-item>
  188. </el-form>
  189. <div class="amap-demo" id="mapContainer2"></div>
  190. <span slot="footer" class="dialog-footer">
  191. <el-button @click="addLocationDialogVisible = false">取 消</el-button>
  192. <el-button type="primary" @click="addLocationSubm">确 定</el-button>
  193. </span>
  194. </el-dialog>
  195. <!-- 故障上报 -->
  196. <el-dialog
  197. class="map_dialog"
  198. title="故障上报"
  199. v-if="addFaultDialogVisible"
  200. :visible.sync="addFaultDialogVisible"
  201. width="500px"
  202. @closed="addLocationDialogClosed"
  203. >
  204. <el-form
  205. ref="editFaultform"
  206. :rules="editFaultrules"
  207. :model="editFault"
  208. label-width="80px"
  209. >
  210. <el-form-item label="设备ID">
  211. <el-input v-model="editFault.imei" disabled></el-input>
  212. </el-form-item>
  213. <el-form-item label="联系人" prop="user">
  214. <el-input v-model="editFault.user"></el-input>
  215. </el-form-item>
  216. <el-form-item label="联系电话" prop="tel">
  217. <el-input
  218. type="text"
  219. maxlength="11"
  220. v-model="editFault.tel"
  221. ></el-input>
  222. </el-form-item>
  223. <el-form-item label="故障原因" prop="detail">
  224. <el-input type="textarea" v-model="editFault.detail"></el-input>
  225. </el-form-item>
  226. </el-form>
  227. <span slot="footer" class="dialog-footer">
  228. <el-button @click="addFaultDialogVisible = false">取 消</el-button>
  229. <el-button type="primary" @click="addFaultSubm">确 定</el-button>
  230. </span>
  231. </el-dialog>
  232. </div>
  233. </el-card>
  234. </div>
  235. </template>
  236. <script>
  237. import AMap from "AMap";
  238. export default {
  239. data() {
  240. var checkphone = (rule, value, callback) => {
  241. let phoneReg = /(^1[3|4|5|6|7|8|9]\d{9}$)|(^09\d{8}$)/;
  242. if (value == "") {
  243. callback(new Error("请输入手机号"));
  244. } else if (!phoneReg.test(value)) {
  245. //引入methods中封装的检查手机格式的方法
  246. callback(new Error("请输入正确的手机号!"));
  247. } else {
  248. callback();
  249. }
  250. };
  251. return {
  252. zanwu: "/images/expertDiagnosis/zanwu.png",
  253. timeRange: "",
  254. queryInfo: {
  255. f_id: "",
  256. page: 1,
  257. device_type_id: null,
  258. start_time: "",
  259. end_time: "",
  260. },
  261. dataList: [],
  262. totalNum: 0,
  263. addr: "",
  264. locationForm: {
  265. lat: "",
  266. lng: "",
  267. },
  268. editFault: {
  269. imei: "",
  270. user: "",
  271. tel: "",
  272. detail: "",
  273. type: "",
  274. },
  275. device_id: "",
  276. center: [], //默认地图中心
  277. addLocationDialogVisible: false,
  278. addFaultDialogVisible: false,
  279. editFaultrules: {
  280. user: { required: true, message: "请输入联系人", trigger: "blur" },
  281. tel: { required: true, validator: checkphone, trigger: "blur" },
  282. detail: { required: true, message: "请输入故障原因", trigger: "blur" },
  283. },
  284. address: "", //地图信息框显示的地址
  285. };
  286. },
  287. mounted() {
  288. this.getList();
  289. },
  290. beforeMount() {},
  291. methods: {
  292. init() {
  293. var map = new AMap.Map("mapContainer2", {
  294. center: this.center,
  295. resizeEnable: true,
  296. zoom: 10,
  297. lang: "ch",
  298. });
  299. AMap.plugin(["AMap.ToolBar", "AMap.Geocoder"], () => {
  300. map.addControl(new AMap.ToolBar());
  301. this.geocoder = new AMap.Geocoder({
  302. city: "全国",
  303. radius: 1000,
  304. });
  305. });
  306. setTimeout(() => {
  307. var marker = new AMap.Marker({
  308. position: this.center,
  309. });
  310. marker.setMap(map);
  311. },1000);
  312. this.map = map;
  313. this.testevent();
  314. },
  315. // 地图点击事件
  316. testevent() {
  317. this.map.on("click", (ev) => {
  318. var lnglat = [ev.lnglat.lng, ev.lnglat.lat];
  319. this.locationForm = { lng: lnglat[0], lat: lnglat[1] };
  320. this.map.clearMap();
  321. var marker = new AMap.Marker({
  322. position: lnglat,
  323. });
  324. marker.setMap(this.map);
  325. this.getAddress(lnglat);
  326. setTimeout(() => {
  327. new AMap.InfoWindow({
  328. content: "<h5>" + "当前选中地址" + "</h5>" + this.address,
  329. offset: new AMap.Pixel(0, -32),
  330. }).open(this.map, lnglat);
  331. }, 100);
  332. });
  333. },
  334. // 经纬度转化为详细地址
  335. getAddress(lnglat) {
  336. AMap.plugin("AMap.Geocoder", () => {
  337. this.geocoder.getAddress(lnglat, (status, result) => {
  338. if (status === "complete" && result.info === "OK") {
  339. this.address = result.regeocode.formattedAddress;
  340. }
  341. });
  342. });
  343. },
  344. //获取设备列表
  345. getList() {
  346. this.$axios({
  347. method: "POST",
  348. url: "/api/api_gateway?method=device.device_manage.device_info",
  349. data: this.qs.stringify({
  350. device_id: this.queryInfo.f_id,
  351. page: this.queryInfo.page,
  352. page_size: 12,
  353. device_type_id: this.queryInfo.device_type_id,
  354. start_time: this.queryInfo.start_time,
  355. end_time: this.queryInfo.end_time,
  356. }),
  357. }).then((res) => {
  358. if (res.data.message == "") {
  359. this.dataList = res.data.data.data;
  360. this.totalNum = res.data.data.counts;
  361. }
  362. });
  363. },
  364. searchChange() {
  365. this.queryInfo.page = 1;
  366. this.getList();
  367. },
  368. DateChange(val) {
  369. this.queryInfo.page = 1;
  370. if (this.timeRange) {
  371. this.queryInfo.start_time = parseInt(
  372. new Date(this.timeRange[0]).getTime() / 1000
  373. );
  374. this.queryInfo.end_time = parseInt(
  375. new Date(this.timeRange[1]).getTime() / 1000
  376. );
  377. this.getList();
  378. } else {
  379. this.queryInfo.start_time = "";
  380. this.queryInfo.end_time = "";
  381. this.getList();
  382. }
  383. },
  384. addrChange() {
  385. var marker = new AMap.Marker();
  386. this.geocoder.getLocation(this.addr, (status, result) => {
  387. if (status === "complete" && result.geocodes.length) {
  388. var lnglat = result.geocodes[0].location;
  389. marker.setPosition(lnglat);
  390. this.map.add(marker);
  391. this.map.setFitView(marker);
  392. this.locationForm = {
  393. lat: lnglat.lat,
  394. lng: lnglat.lng,
  395. };
  396. } else {
  397. this.$message.error("根据地址查询位置失败");
  398. }
  399. });
  400. },
  401. // 修改设备名称
  402. modifyName(id, device_name) {
  403. let value = device_name;
  404. this.$prompt("", "修改设备名称", {
  405. confirmButtonText: "确定",
  406. cancelButtonText: "取消",
  407. inputPlaceholder: device_name,
  408. })
  409. .then(({ value }) => {
  410. if (value) {
  411. this.$axios({
  412. method: "POST",
  413. url: "/api/api_gateway?method=forecast.worm_lamp.revise_device",
  414. data: this.qs.stringify({
  415. device_id: id,
  416. device_name: value,
  417. }),
  418. }).then((res) => {
  419. if (res.data.message == "") {
  420. this.getList();
  421. this.$message({
  422. type: "success",
  423. message: "修改成功",
  424. });
  425. }
  426. });
  427. } else {
  428. this.$message({
  429. type: "info",
  430. message: "内容不能为空",
  431. });
  432. }
  433. })
  434. .catch(() => {
  435. // this.$message({
  436. // type: "info",
  437. // message: "取消输入",
  438. // });
  439. });
  440. },
  441. // 修改设备组名称
  442. modifyGroupName(id, device_name) {
  443. let value = device_name;
  444. this.$prompt("", "修改设备组名称", {
  445. confirmButtonText: "确定",
  446. cancelButtonText: "取消",
  447. inputPlaceholder: device_name,
  448. })
  449. .then(({ value }) => {
  450. if (value) {
  451. this.$axios({
  452. method: "POST",
  453. url: "/api/api_gateway?method=weather.weather.warning_change",
  454. data: this.qs.stringify({
  455. device_id: id,
  456. name: value,
  457. }),
  458. }).then((res) => {
  459. if (res.data.message == "") {
  460. this.getList();
  461. this.$message({
  462. type: "success",
  463. message: "修改成功",
  464. });
  465. }else{
  466. this.$message({
  467. type: "error",
  468. message: res.data.message,
  469. });
  470. }
  471. });
  472. } else {
  473. this.$message({
  474. type: "info",
  475. message: "内容不能为空",
  476. });
  477. }
  478. })
  479. .catch(() => {
  480. });
  481. },
  482. //通过经纬度搜索定位
  483. locationSearch() {
  484. if (this.locationForm.lat && this.locationForm.lng) {
  485. this.map.clearMap();
  486. let lnglat = [this.locationForm.lng, this.locationForm.lat];
  487. var marker = new AMap.Marker({
  488. position: lnglat,
  489. });
  490. marker.setMap(this.map);
  491. this.map.setFitView();
  492. } else {
  493. this.$message.warning("请输入经纬度!");
  494. return fasle;
  495. }
  496. },
  497. //点击“添加定位”按钮
  498. addPosition(device_id, lng, lat) {
  499. this.device_id = device_id;
  500. this.center = [lng, lat];
  501. this.locationForm.lng = lng;
  502. this.locationForm.lat = lat;
  503. this.addLocationDialogVisible = true;
  504. setTimeout(() => {
  505. this.init();
  506. }, 0);
  507. },
  508. // 故障上报
  509. addFault(device_id, type) {
  510. this.device_id = device_id;
  511. this.editFault.imei = device_id;
  512. this.editFault.type = type;
  513. this.addFaultDialogVisible = true;
  514. },
  515. changePage(val) {
  516. console.log(val);
  517. this.queryInfo.page = val;
  518. this.getList();
  519. },
  520. //关闭定位弹框时调用
  521. addLocationDialogClosed() {
  522. this.locationForm = { lat: "", lng: "" };
  523. this.center = [];
  524. this.map = null;
  525. },
  526. //选择定位点后,提交
  527. addLocationSubm() {
  528. this.$axios({
  529. method: "POST",
  530. url: "/api/api_gateway?method=forecast.worm_lamp.revise_device",
  531. data: this.qs.stringify({
  532. device_id: this.device_id,
  533. lat: this.locationForm.lat,
  534. lng: this.locationForm.lng,
  535. }),
  536. }).then((res) => {
  537. if (res.data.message == "") {
  538. this.getList();
  539. this.addLocationDialogVisible = false;
  540. this.$message({
  541. type: "success",
  542. message: "定位成功",
  543. });
  544. } else {
  545. this.$message({
  546. type: "error",
  547. message: "定位失败",
  548. });
  549. }
  550. });
  551. },
  552. addFaultSubm() {
  553. this.$refs.editFaultform.validate((valid) => {
  554. if (valid) {
  555. this.$axios({
  556. method: "POST",
  557. url:
  558. "/api/api_gateway?method=after_sale.after_sale_manage.aftersale_apply",
  559. data: this.qs.stringify({
  560. device_id: this.device_id,
  561. errordesc: this.editFault.detail,
  562. errorimg: [],
  563. addr: "",
  564. user: this.editFault.user,
  565. userphone: this.editFault.tel,
  566. repairtime: "",
  567. d_type: this.editFault.type,
  568. is_pc: "1", //0 手机 1 电脑
  569. errorvideo: "",
  570. }),
  571. }).then((res) => {
  572. if (res.data.message == "") {
  573. this.$message({
  574. type: "success",
  575. message: "修改成功",
  576. });
  577. this.addFaultDialogVisible = false;
  578. } else {
  579. this.$message({
  580. type: "error",
  581. message: res.data.message,
  582. });
  583. }
  584. });
  585. } else {
  586. return false;
  587. }
  588. });
  589. },
  590. //删除设备
  591. delEquip(d_id) {
  592. this.$confirm("确定删除此设备么?", "提示", {
  593. confirmButtonText: "确定",
  594. cancelButtonText: "取消",
  595. type: "warning",
  596. })
  597. .then(() => {
  598. this.$axios({
  599. method: "POST",
  600. url: "/api/api_gateway?method=device.device_manage.delete_device",
  601. data: this.qs.stringify({
  602. d_id,
  603. }),
  604. }).then((res) => {
  605. if (res.data.message == "") {
  606. this.$message({
  607. type: "success",
  608. message: "删除成功!",
  609. });
  610. this.getList();
  611. } else {
  612. this.$message({
  613. type: "error",
  614. message: res.data.message,
  615. });
  616. }
  617. });
  618. })
  619. .catch(() => {
  620. this.$message({
  621. type: "info",
  622. message: "已取消删除",
  623. });
  624. });
  625. },
  626. },
  627. };
  628. </script>
  629. <style lang='less' scoped>
  630. .search-box {
  631. display: flex;
  632. justify-content: flex-left;
  633. justify-content: space-between;
  634. margin-bottom: 10px;
  635. .filter-box > div {
  636. margin-right: 15px;
  637. }
  638. .el-input {
  639. width: 200px;
  640. }
  641. .el-date-editor--daterange {
  642. width: 222px;
  643. }
  644. }
  645. .el-card.selected {
  646. border: 1px solid #14a478;
  647. }
  648. .el-card.pad0 {
  649. position: relative;
  650. .del-icon {
  651. display: none;
  652. font-size: 16px;
  653. position: absolute;
  654. right: 10px;
  655. top: 10px;
  656. color: red;
  657. cursor: pointer;
  658. }
  659. &:hover {
  660. .del-icon,.editNameIcon {
  661. display: inline-block;
  662. }
  663. }
  664. .editNameIcon{
  665. display: none;
  666. }
  667. .img-box {
  668. text-align: center;
  669. border-bottom: 1px solid #e1e1e1;
  670. padding: 20px 0;
  671. img {
  672. height: 55px;
  673. }
  674. .equipName{
  675. height: 30px;
  676. span:nth-child(1){
  677. line-height: 23px;
  678. }
  679. span:nth-child(2){
  680. cursor: pointer;
  681. font-size: 18px;
  682. font-weight: 800;
  683. color: green;
  684. }
  685. }
  686. }
  687. .detail {
  688. border-bottom: 1px solid #e1e1e1;
  689. padding: 10px 0;
  690. padding: 0 20px;
  691. p {
  692. display: flex;
  693. justify-content: space-between;
  694. font-size: 13px;
  695. line-height: 34px;
  696. color: #666;
  697. }
  698. }
  699. .bottom {
  700. display: flex;
  701. font-size: 13px;
  702. color: #666;
  703. line-height: 50px;
  704. span {
  705. flex: 1;
  706. text-align: center;
  707. cursor: pointer;
  708. border-left: 1px solid #e1e1e1;
  709. i {
  710. font-size: 16px;
  711. }
  712. }
  713. span:first-child {
  714. border-left: none;
  715. }
  716. }
  717. }
  718. .amap-demo {
  719. width: 100%;
  720. height: 400px;
  721. }
  722. .map_dialog /deep/ .el-dialog__body {
  723. padding: 20px 20px 0 20px;
  724. }
  725. </style>