index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. <template>
  2. <div class="app-container">
  3. <el-row :gutter="20">
  4. <el-col :span="4" :xs="24">
  5. <div class="head-container">
  6. <el-input v-model="areaName" placeholder="请输入区块名称" clearable size="small" prefix-icon="el-icon-search"
  7. style="margin-bottom: 20px" />
  8. </div>
  9. <div class="head-container">
  10. <el-tree :data="areaOptions" :props="defaultProps" :expand-on-click-node="false" :filter-node-method="filterNode" ref="tree"
  11. node-key="id" default-expand-all highlight-current @node-click="handleNodeClick" style="height: calc(100vh - 50px); overflow-y: auto;" />
  12. </div>
  13. </el-col>
  14. <el-tabs v-model="activeTab" @tab-click="handleTabClick">
  15. <el-tab-pane label="电表" name="电表"></el-tab-pane>
  16. <el-tab-pane label="水表" name="水表"></el-tab-pane>
  17. </el-tabs>
  18. <el-col :span="20" :xs="24">
  19. <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
  20. <el-form-item label="设备代码" prop="deviceCode">
  21. <el-input v-model="queryParams.deviceCode" placeholder="请输入设备代码" clearable @keyup.enter.native="handleQuery" />
  22. </el-form-item>
  23. <el-form-item label="设备名称" prop="deviceName">
  24. <el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable @keyup.enter.native="handleQuery" />
  25. </el-form-item>
  26. <el-form-item label="计量标签" prop="objTag">
  27. <el-select v-model="queryParams.objTag" placeholder="请选择计量标签" clearable>
  28. <el-option v-for="item in objTagOptions" :key="item.code" :label="item.name" :value="item.code">
  29. </el-option>
  30. </el-select>
  31. </el-form-item>
  32. <el-form-item label="采集方式" prop="colMode">
  33. <el-select v-model="queryParams.colMode" placeholder="请选择采集方式" clearable>
  34. <el-option v-for="item in colModeOptions" :key="item.code" :label="item.name" :value="item.code">
  35. </el-option>
  36. </el-select>
  37. </el-form-item>
  38. <el-form-item>
  39. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  40. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  41. </el-form-item>
  42. </el-form>
  43. <el-row :gutter="10" class="mb8">
  44. <el-col :span="1.5">
  45. <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['ems:device:add']">新增
  46. </el-button>
  47. </el-col>
  48. <el-col :span="1.5">
  49. <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
  50. v-hasPermi="['ems:device:edit']">修改</el-button>
  51. </el-col>
  52. <el-col :span="1.5">
  53. <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
  54. v-hasPermi="['ems:device:remove']">删除</el-button>
  55. </el-col>
  56. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  57. </el-row>
  58. <el-table v-loading="loading" :data="deviceList" @selection-change="handleSelectionChange">
  59. <el-table-column type="selection" width="55" align="center" />
  60. <el-table-column label="设备编号" align="left" prop="deviceCode" />
  61. <el-table-column label="设备名称" align="left" prop="deviceName" width="200px"/>
  62. <el-table-column label="安装位置" align="left" prop="location" width="200px"/>
  63. <el-table-column label="计量标签" align="center" prop="objTag">
  64. <template slot-scope="scope">
  65. {{formatDict(scope.row.objTag,'objTagOptions')}}
  66. </template>
  67. </el-table-column>
  68. <el-table-column label="采集方式" align="center" prop="colMode">
  69. <template slot-scope="scope">
  70. <span>{{ getColModeName(scope.row.colMode) }}</span>
  71. </template>
  72. </el-table-column>
  73. <el-table-column label="周期时长(秒)" align="center" prop="colCycle">
  74. <template slot-scope="scope">
  75. <span>{{ scope.row.colCycle}}</span>
  76. </template>
  77. </el-table-column>
  78. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  79. <template slot-scope="scope">
  80. <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['basecfg:device:edit']">
  81. 修改</el-button>
  82. <el-button size="mini" type="text" icon="el-icon-delete" class="deleteBtn" @click="handleDelete(scope.row)" v-hasPermi="['basecfg:device:remove']">
  83. 删除</el-button>
  84. </template>
  85. </el-table-column>
  86. </el-table>
  87. <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
  88. @pagination="getList" />
  89. <!-- 添加或修改计量设备对话框 -->
  90. <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
  91. <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  92. <!-- 归属区域 -->
  93. <el-form-item label="归属区域" prop="areaCode">
  94. <el-select v-model="form.areaCode" placeholder="请选择归属区域" @change="handleAreaChange">
  95. <el-option v-for="item in areaOptions" :label="item.label" :value="item.id" :key="item.id" />
  96. </el-select>
  97. </el-form-item>
  98. <el-form-item label="归属子区" prop="locationRef">
  99. <el-select v-model="form.locationRef" placeholder="请选择归属子区">
  100. <el-option v-for="item in subAreaOptions" :label="item.label" :value="item.id" :key="item.id" />
  101. </el-select>
  102. </el-form-item>
  103. <el-form-item label="设备编号" prop="deviceCode">
  104. <el-input v-model="form.deviceCode" placeholder="请输入设备编号" />
  105. </el-form-item>
  106. <el-form-item label="设备名称" prop="deviceName">
  107. <el-input v-model="form.deviceName" placeholder="请输入设备代码" />
  108. </el-form-item>
  109. <el-form-item label="安装位置" prop="location">
  110. <el-input v-model="form.location" placeholder="请输入设备安装位置" />
  111. </el-form-item>
  112. <el-form-item label="计量标签" prop="objTag">
  113. <el-radio-group v-model="form.objTag" size="medium">
  114. <el-radio v-for="(item, index) in objTagOptions" :key="index" :label="item.code" :disabled="item.disabled">{{item.name}}
  115. </el-radio>
  116. </el-radio-group>
  117. </el-form-item>
  118. <el-form-item label="采集方式" prop="colMode">
  119. <el-radio-group v-model="form.colMode" size="medium" @change="colModeChange">
  120. <el-radio v-for="(item, index) in colModeOptions" :key="index" :label="item.code" :disabled="item.disabled">{{item.name}}
  121. </el-radio>
  122. </el-radio-group>
  123. </el-form-item>
  124. <!-- 周期时长 -->
  125. <el-form-item v-if="form.colMode !== 1" label="周期时长" prop="colCycle">
  126. <template v-if="form.colMode === 0">
  127. <el-input v-model="form.colCycle" :min="1" :max="86400" placeholder="请输入周期时长(秒)" />
  128. </template>
  129. <template v-else>
  130. </template>
  131. </el-form-item>
  132. <el-form-item label="倍率" prop="magnification">
  133. <el-input-number v-model="form.magnification" :min="0" :max="99" ></el-input-number>
  134. </el-form-item>
  135. <el-form-item label="规格描述" prop="specDesc">
  136. <el-input v-model="form.specDesc" placeholder="请输入规格描述" />
  137. </el-form-item>
  138. </el-form>
  139. <div slot="footer" class="dialog-footer">
  140. <el-button type="primary" @click="submitForm">确 定</el-button>
  141. <el-button @click="cancel">取 消</el-button>
  142. </div>
  143. </el-dialog>
  144. </el-col>
  145. </el-row>
  146. </div>
  147. </template>
  148. <script>
  149. import { listDevice, getDevice, delDevice, addDevice, updateDevice, listAreaDevice } from '@/api/device/meterDevice'
  150. import { areaTreeSelect } from '@/api/basecfg/area'
  151. import Treeselect from '@riophae/vue-treeselect'
  152. import '@riophae/vue-treeselect/dist/vue-treeselect.css'
  153. export default {
  154. name: 'Device',
  155. components: { Treeselect },
  156. data() {
  157. return {
  158. activeTab: '电表',
  159. // 遮罩层
  160. loading: true,
  161. // 选中数组
  162. ids: [],
  163. // 非单个禁用
  164. single: true,
  165. // 非多个禁用
  166. multiple: true,
  167. // 显示搜索条件
  168. showSearch: true,
  169. // 总条数
  170. total: 0,
  171. // 计量设备表格数据
  172. deviceList: [],
  173. // 弹出层标题
  174. title: '',
  175. // 是否显示弹出层
  176. open: false,
  177. areaMod: false,
  178. // 区域名称
  179. areaName: undefined,
  180. objCodeOptions: [],
  181. areaOptions: [],
  182. subAreaOptions: [],
  183. selectObjCode: null,
  184. defaultProps: {
  185. children: 'children',
  186. label: 'label'
  187. },
  188. // 能源分类树
  189. emsClsOptions: [
  190. { code: 45, name: '电表' },
  191. { code: 70, name: '水表' }
  192. ],
  193. objTagOptions: [
  194. { code: 0, name: '公摊表' },
  195. { code: 1, name: '个户表' }
  196. ],
  197. colCycleOptions: [
  198. { code: 0, name: '实时' },
  199. { code: 1, name: '分钟' },
  200. { code: 2, name: '小时' },
  201. { code: 3, name: '天' },
  202. { code: 4, name: '月' }
  203. ],
  204. colModeOptions: [
  205. { code: 0, name: '自动抄表' },
  206. { code: 1, name: '手动抄表' }
  207. ],
  208. // 查询参数
  209. queryParams: {
  210. pageNum: 1,
  211. pageSize: 10,
  212. areaCode: null,
  213. bldgCode: null,
  214. deviceCode: null,
  215. locationRef:null,
  216. meterCls: null,
  217. objTag: null,
  218. colCycle: null,
  219. colMode: null,
  220. magnification: null,
  221. specDesc: null
  222. },
  223. // 表单参数
  224. form: {
  225. areaCode: null,
  226. },
  227. // 表单校验
  228. rules: {
  229. areaCode: [{ required: true, message: '选择服务区', trigger: 'blur' }],
  230. deviceCode: [{ required: true, message: '设备代码不能为空', trigger: 'blur' }],
  231. meterCls: [{ required: true, message: '计量类别不能为空', trigger: 'blur' }],
  232. }
  233. }
  234. },
  235. watch: {
  236. areaName(val) {
  237. this.$refs.tree.filter(val)
  238. }
  239. },
  240. created() {
  241. this.getAreaTree('0', 2)
  242. this.getList()
  243. },
  244. methods: {
  245. /**归属子区*/
  246. loadSubAreaOptions(areaCode) {
  247. areaTreeSelect(areaCode, 2).then((response) => {
  248. this.subAreaOptions = response.data || [];
  249. })
  250. },
  251. /**归属区域*/
  252. handleAreaChange() {
  253. this.loadSubAreaOptions(this.form.areaCode);
  254. },
  255. handleTabClick(tab) {
  256. this.activeTab = tab.name;
  257. this.getList();
  258. },
  259. colModeChange(val) {
  260. if (val === 1) {
  261. this.form.colCycle = 4
  262. } else {
  263. this.form.colCycle = null
  264. }
  265. },
  266. /** 查询计量设备列表 */
  267. getList() {
  268. this.loading = true;
  269. let meterCls = '';
  270. if (this.activeTab === '电表') {
  271. meterCls = 45;
  272. } else if (this.activeTab === '水表') {
  273. meterCls = 70;
  274. }
  275. const params = {
  276. locationRef: this.$refs.tree.getCurrentNode()?.id,
  277. meterCls,
  278. objTag: this.queryParams.objTag,
  279. colMode: this.queryParams.colMode,
  280. pageNum: this.queryParams.pageNum,
  281. pageSize: this.queryParams.pageSize
  282. };
  283. listAreaDevice(params).then(response => {
  284. this.deviceList = response.rows;
  285. this.total = response.total;
  286. this.loading = false;
  287. })
  288. },
  289. // 取消按钮
  290. cancel() {
  291. this.open = false
  292. this.reset()
  293. },
  294. // 表单重置
  295. reset() {
  296. this.form = {
  297. id: null,
  298. deviceCode: null,
  299. deviceName: null,
  300. deviceLocation:null,
  301. locationRef:null,
  302. location:null,
  303. meterCls: null,
  304. colCycle: null,
  305. colMode: null,
  306. specDesc: null,
  307. magnification :1
  308. }
  309. this.objCode = null
  310. this.areaMod = false
  311. this.resetForm('form')
  312. },
  313. /** 搜索按钮操作 */
  314. handleQuery() {
  315. this.queryParams.pageNum = 1
  316. this.getList()
  317. },
  318. /** 重置按钮操作 */
  319. resetQuery() {
  320. this.resetForm('queryForm')
  321. this.handleQuery()
  322. },
  323. handleSelectionChange(selection) {
  324. this.ids = selection.map(item => item.id)
  325. this.single = selection.length !== 1
  326. this.multiple = !selection.length
  327. },
  328. /** 新增按钮操作 */
  329. handleAdd() {
  330. this.reset();
  331. this.open = true;
  332. this.areaMod = true;
  333. this.form.magnification = 1;
  334. /** 加载归属子区*/
  335. this.loadSubAreaOptions(this.form.areaCode);
  336. if (this.activeTab === '电表') {
  337. this.title = '添加电表';
  338. this.form.meterCls = 45;
  339. } else if (this.activeTab === '水表') {
  340. this.title = '添加水表';
  341. this.form.meterCls = 70;
  342. }
  343. },
  344. /** 修改按钮操作 */
  345. handleUpdate(row) {
  346. this.reset()
  347. const id = row.id || this.ids
  348. getDevice(id).then(response => {
  349. this.form = response.data;
  350. /** 加载归属子区*/
  351. this.loadSubAreaOptions(this.form.areaCode);
  352. this.open = true;
  353. if (this.activeTab === '电表') {
  354. this.title = '修改电表';
  355. } else if (this.activeTab === '水表') {
  356. this.title = '修改水表';
  357. }
  358. })
  359. },
  360. /** 提交按钮 */
  361. submitForm() {
  362. this.$refs['form'].validate(valid => {
  363. if (valid) {
  364. if (this.form.id != null) {
  365. updateDevice(this.form).then(response => {
  366. this.$modal.msgSuccess('修改成功')
  367. this.open = false
  368. this.getList()
  369. })
  370. } else {
  371. addDevice(this.form).then(response => {
  372. this.$modal.msgSuccess('新增成功')
  373. this.open = false
  374. this.getList()
  375. })
  376. }
  377. }
  378. })
  379. },
  380. /** 删除按钮操作 */
  381. handleDelete(row) {
  382. const ids = row.id || this.ids
  383. this.$modal
  384. .confirm('是否确认删除计量设备编号为"' + ids + '"的数据项?')
  385. .then(function() {
  386. return delDevice(ids)
  387. })
  388. .then(() => {
  389. this.getList()
  390. this.$modal.msgSuccess('删除成功')
  391. })
  392. .catch(() => {})
  393. },
  394. formatDict(val, options, key = 'code', text = 'name') {
  395. let name = ''
  396. this[options].forEach(item => {
  397. if (val === item[key]) {
  398. name = item[text]
  399. }
  400. })
  401. return name
  402. },
  403. getColModeName(colMode) {
  404. const modeMap = {
  405. 0: '自动抄表',
  406. 1: '手动抄表'
  407. }
  408. return modeMap[colMode] || '未知'
  409. },
  410. /** 查询区域树结构 */
  411. getAreaTree(areaCode, layer) {
  412. areaTreeSelect(areaCode, layer).then(response => {
  413. this.areaOptions = response.data || [];
  414. this.$nextTick(() => {
  415. //触发第一个节点
  416. this.triggerFirstNodeClick();
  417. });
  418. })
  419. },
  420. triggerFirstNodeClick() {
  421. const tree = this.$refs.tree;
  422. const firstNode = this.areaOptions[0];
  423. if (firstNode) {
  424. tree.setCurrentKey(firstNode.id);
  425. this.handleNodeClick(firstNode);
  426. }
  427. },
  428. // 筛选节点
  429. filterNode(value, data) {
  430. if (!value) return true
  431. return data.label.indexOf(value) !== -1
  432. },
  433. // 节点单击事件
  434. handleNodeClick(data) {
  435. this.queryParams.areaCode = data.id;
  436. this.queryParams.locationRef = data.id;
  437. this.handleQuery();
  438. }
  439. }
  440. }
  441. </script>