PlanCheckPoint_master104.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902
  1. <!-- 步骤2 -->
  2. <template>
  3. <div v-show="currentStep == 1" :class="className">
  4. <div class="title">测点导入</div>
  5. <div class="buttons">
  6. <div class="left">
  7. <!-- 批量删除 -->
  8. <div class="clear item">
  9. <el-button
  10. class="dark-button"
  11. icon="el-icon-delete"
  12. :disabled="!showDel"
  13. @click="multDelete()"
  14. >批量删除</el-button>
  15. </div>
  16. </div>
  17. <div class="right">
  18. <div class="item">
  19. <!-- 添加新测点 -->
  20. <el-button
  21. class="light-button"
  22. icon="el-icon-refresh-right"
  23. @click="updataTableData()"
  24. >刷新</el-button>
  25. </div>
  26. <div class="item">
  27. <!-- 导入即是上传文件 -->
  28. <el-upload
  29. ref="upload"
  30. :action="importCsvActionStr"
  31. :show-file-list="false"
  32. :auto-upload="false"
  33. accept=".csv"
  34. :on-change="submitUpload"
  35. >
  36. <el-button
  37. class="light-button"
  38. icon="el-icon-upload2"
  39. >导入</el-button>
  40. </el-upload>
  41. </div>
  42. <div class="export item">
  43. <el-button
  44. class="light-button"
  45. icon="el-icon-download"
  46. @click="getPlanExport()"
  47. >导出</el-button>
  48. </div>
  49. <div class="item">
  50. <!-- 添加新测点 -->
  51. <el-button
  52. class="dark-button"
  53. icon="el-icon-plus"
  54. @click="addCheckPoint()"
  55. >添加</el-button>
  56. </div>
  57. </div>
  58. </div>
  59. <div class="table-container">
  60. <el-table ref="multipleTable" v-loading="vloading" class="table-fixed" type="index" :data="tableData" :height="tableHeight" stripe @selection-change="handleSelectionChange">
  61. <el-table-column
  62. type="selection"
  63. />
  64. <!-- <el-table-column prop="id" label="序号" width="100" /> -->
  65. <el-table-column prop="iec104" label="104点号" width="100">
  66. <!-- rs.offset -->
  67. <template slot-scope="scope">
  68. <el-input
  69. v-model="scope.row.iec104"
  70. class="table-column-input"
  71. type="number"
  72. disabled
  73. />
  74. </template>
  75. </el-table-column>
  76. <el-table-column prop="name" label="* 测点名称" width="200">
  77. <template slot-scope="scope">
  78. <el-input
  79. v-model="scope.row.name"
  80. class="table-column-input"
  81. clearable
  82. placeholder="请输入名称"
  83. maxlength="32"
  84. />
  85. </template>
  86. </el-table-column>
  87. <el-table-column prop="name" label="设备分组" width="200">
  88. <template slot-scope="scope">
  89. <el-input
  90. v-model="scope.row.groupingName"
  91. class="table-column-input"
  92. clearable
  93. placeholder="请输入设备名称"
  94. maxlength="32"
  95. />
  96. </template>
  97. </el-table-column>
  98. <el-table-column prop="range" label="* 点号类型">
  99. <!-- rs.range -->
  100. <template slot-scope="scope">
  101. <el-select
  102. v-model="scope.row.range"
  103. class="table-column-input"
  104. placeholder=""
  105. :disabled="Boolean(scope.row.id)"
  106. >
  107. <el-option
  108. v-for="item in checkPointFuctionOptions"
  109. :key="item.id"
  110. :label="item.name"
  111. :value="item.id"
  112. />
  113. </el-select>
  114. </template>
  115. </el-table-column>
  116. <el-table-column prop="offset" label="* 点号">
  117. <!-- rs.offset -->
  118. <template slot-scope="scope">
  119. <el-input
  120. v-model="scope.row.offset"
  121. class="table-column-input"
  122. type="number"
  123. :disabled="Boolean(scope.row.id)"
  124. />
  125. </template>
  126. </el-table-column>
  127. <el-table-column v-if="false" prop="relationTag" label="关联遥信点号(仅遥控可关联)">
  128. <template slot-scope="scope">
  129. <el-input
  130. v-if="scope.row.range=='COIL_STATUS'"
  131. v-model="scope.row.relationTag"
  132. class="table-column-input"
  133. placeholder="请输入遥信点号"
  134. type="number"
  135. />
  136. </template>
  137. </el-table-column>
  138. <el-table-column v-if="false" prop="relationTag" label="关联遥测点号(仅遥调可关联)">
  139. <template slot-scope="scope">
  140. <el-input
  141. v-if="scope.row.range=='HOLDING_REGISTER'"
  142. v-model="scope.row.relationTag"
  143. class="table-column-input"
  144. placeholder="请输入遥测点号"
  145. type="number"
  146. />
  147. </template>
  148. </el-table-column>
  149. <el-table-column prop="scaling" label="倍率" width="80">
  150. <!-- scaling -->
  151. <template slot-scope="scope">
  152. <el-input
  153. v-model="scope.row.scaling"
  154. class="table-column-input"
  155. clearable
  156. type="number"
  157. maxlength="32"
  158. />
  159. </template>
  160. </el-table-column>
  161. <el-table-column prop="adjust" label="偏移量" width="80">
  162. <template slot-scope="scope">
  163. <el-input
  164. v-model="scope.row.adjust"
  165. class="table-column-input"
  166. clearable
  167. type="number"
  168. maxlength="32"
  169. />
  170. </template>
  171. </el-table-column>
  172. <el-table-column label="操作" width="180" fixed="right">
  173. <template slot-scope="scope">
  174. <el-button
  175. class="table-act"
  176. type="text"
  177. icon="el-icon-edit"
  178. size="small"
  179. @click="editClick(scope.row, scope.$index)"
  180. >
  181. 编辑
  182. </el-button>
  183. <el-button
  184. class="table-act"
  185. type="text"
  186. icon="el-icon-s-order"
  187. size="small"
  188. @click="saveClick(scope.row,scope.$index)"
  189. >保存</el-button>
  190. <el-button
  191. class="table-act"
  192. type="text"
  193. icon="el-icon-delete"
  194. size="small"
  195. @click="delClick(scope.row, scope.$index)"
  196. >删除</el-button>
  197. </template>
  198. </el-table-column>
  199. </el-table>
  200. </div>
  201. <!-- 编辑弹出的模态框套表单 -->
  202. <el-dialog title="测点信息" :close-on-click-modal="false" :visible.sync="dialogFormVisible">
  203. <el-form ref="form" :model="form">
  204. <el-form-item label="*测点名称" :label-width="formLabelWidth">
  205. <el-input v-model="form.name" autocomplete="off" maxlength="32" placeholder="请输入测点名称" />
  206. </el-form-item>
  207. <el-form-item label="设备分组" :label-width="formLabelWidth">
  208. <el-input v-model="form.groupingName" maxlength="20" placeholder="请输入设备分组" />
  209. </el-form-item>
  210. <el-form-item class="modelInput" label="*点号类型" :label-width="formLabelWidth">
  211. <template slot-scope="scope">
  212. <el-select
  213. :key="toString(scope.row)"
  214. v-model="form.range"
  215. clearable
  216. placeholder=""
  217. >
  218. <el-option
  219. v-for="item in checkPointFuctionOptions"
  220. :key="item.id"
  221. :label="item.name"
  222. :value="item.id"
  223. />
  224. </el-select>
  225. </template>
  226. </el-form-item>
  227. <el-form-item label="*点号" :label-width="formLabelWidth">
  228. <el-input v-model="form.offset" maxlength="6" />
  229. </el-form-item>
  230. <el-form-item v-if="false" label="关联遥信点号 (仅遥控可关联)" :label-width="formLabelWidth">
  231. <el-input v-if="form.range=='COIL_STATUS'" v-model="form.relationTag" maxlength="6" placeholder="请输入遥信点号" />
  232. <el-input v-else v-model="form.relationTag" disabled />
  233. </el-form-item>
  234. <el-form-item v-if="false" label="关联遥测点号 (仅遥调可关联)" :label-width="formLabelWidth">
  235. <el-input v-if="form.range=='HOLDING_REGISTER'" v-model="form.relationTag" maxlength="6" placeholder="请输入遥测点号" />
  236. <el-input v-else v-model="form.relationTag" disabled />
  237. </el-form-item>
  238. <el-form-item label="倍率" :label-width="formLabelWidth">
  239. <el-input v-model="form.scaling" maxlength="5" />
  240. </el-form-item>
  241. <el-form-item label="偏移量" :label-width="formLabelWidth">
  242. <el-input v-model="form.adjust" maxlength="6" />
  243. </el-form-item>
  244. </el-form>
  245. <div slot="footer" class="dialog-footer">
  246. <el-button @click="dialogFormVisible = false">取 消</el-button>
  247. <el-button type="primary" @click="saveForm">确 定</el-button>
  248. </div>
  249. </el-dialog>
  250. <!-- 分页 -->
  251. <pagination
  252. background
  253. layout="pager"
  254. :limit="pageLimit"
  255. :total="paginationTotalElements"
  256. :current-page.sync="paginationNumber"
  257. :page="paginationNumber"
  258. @pagination="getPlanCheckPoint"
  259. />
  260. <!-- 底部按钮 -->
  261. <div class="bottom-button">
  262. <div class="cancel-plan">
  263. <el-button class="light-button" @click="backStep">上一步</el-button>
  264. </div>
  265. <div class="save-plan">
  266. <el-button class="dark-button" @click="submitPlan()">下一步</el-button>
  267. </div>
  268. </div>
  269. <!-- 检查本地存储是否成功 -->
  270. <!-- <el-button @click="checkStore()">checkStore</el-button> -->
  271. </div>
  272. </template>
  273. <script>
  274. import { planExport } from '@/api/plan'
  275. import { dictOptions } from '@/api/dict'
  276. import Pagination from '@/components/Pagination'
  277. import { delRecord, editRow, httpGet, putData } from '@/api/common-action'
  278. export default {
  279. components: { Pagination },
  280. props: {
  281. className: {
  282. type: String,
  283. default: 'steps-bar-default'
  284. },
  285. currentStep: {
  286. type: Number,
  287. default: 1
  288. },
  289. currentPlanData: {
  290. type: Object,
  291. default: function() {
  292. return
  293. }
  294. }
  295. },
  296. data() {
  297. return {
  298. vloading: true,
  299. // 表格默认数据
  300. tableData: [],
  301. tmpCheckPointId: 0,
  302. tmpTableData: [],
  303. // 每页显示多少条
  304. pageLimit: 20,
  305. paginationNumber: 1,
  306. // 一共多少条
  307. paginationTotalElements: 0,
  308. // 一共多少页
  309. // paginationTotalPages: 1,
  310. // 导入csv 请求参数
  311. importCsvActionStr: '#',
  312. // 功能码选项
  313. checkPointFuctionOptions: [],
  314. // 值类型列表
  315. valueTypeVale: '',
  316. valueTypeOptions: [],
  317. // 批量删除显示控制
  318. showDel: false,
  319. // 选中的arr
  320. delarr: [],
  321. dialogFormVisible: false,
  322. // 模态框内表单
  323. form: {},
  324. formLabelWidth: '120px',
  325. // 模态框表单内数据
  326. modalFromArr: [],
  327. stepIndex: '',
  328. tableHeight: '',
  329. // 多选框选中数据
  330. multipleSelection: ''
  331. }
  332. },
  333. watch: {
  334. multipleSelection(nv, ov) {
  335. if (nv.length === 0) {
  336. // console.log('nv = ', nv)
  337. this.showDel = false
  338. }
  339. },
  340. 'tableData': {
  341. handler() {
  342. this.$nextTick(() => {
  343. this.$refs.multipleTable.doLayout()
  344. })
  345. true
  346. },
  347. deep: true
  348. }
  349. },
  350. // computed: {
  351. // totalOfEle: () => {
  352. // console.log(this.tableData)
  353. // return this.tableData.length
  354. // }
  355. // },
  356. created() {
  357. const marginBottom = 500
  358. this.tableHeight = window.innerHeight - marginBottom
  359. },
  360. mounted() {
  361. this.$nextTick(() => {
  362. // 网页加载完成后执行
  363. this.importCsvActionStr = `/product/model/0/models.csv`
  364. if (this.currentPlanData.id > 0) {
  365. // 如果获取到了PlanId再加载详细信息
  366. this.getPlanCheckPoint()
  367. this.importCsvActionStr = `/product/model/${this.currentPlanData.product}/models.csv`
  368. }
  369. this.initFunctions()
  370. })
  371. },
  372. methods: {
  373. // 检查本地存储是否成功
  374. // checkStore() {
  375. // console.log('checkStore start ')
  376. // const planFromDataStorage = localStorage.getItem('planFromData')
  377. // console.log('planFromData=',planFromDataStorage)
  378. // }
  379. // 文件限制
  380. // handleExceed(files, fileList) {
  381. // this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
  382. // },
  383. // 初始化
  384. async initFunctions() {
  385. // 获取当前
  386. // 获取功能码选项 131
  387. let res = await dictOptions('131')
  388. this.checkPointFuctionOptions = res
  389. // 获取值类型列表
  390. res = await dictOptions('132')
  391. this.valueTypeOptions = res
  392. // console.log('获取值类型列表 this.valueTypeOptions=', this.valueTypeOptions)
  393. this.valueTypeVale = this.valueTypeOptions[0]
  394. },
  395. // 上一步
  396. backStep() {
  397. let currentStep = this.currentStep
  398. currentStep--
  399. this.$emit('changeStep', currentStep)
  400. },
  401. // 新加测试点
  402. addCheckPoint() {
  403. // console.log('addCheckPoint 新加测试点', this.valueTypeOptions)
  404. this.tmpCheckPointId++
  405. const newTable = {
  406. tmpCheckPointId: this.tmpCheckPointId,
  407. name: '',
  408. groupingName: '',
  409. relationTag: '',
  410. range: this.checkPointFuctionOptions[0].id,
  411. offset: 0,
  412. dataType: this.valueTypeOptions[0].id,
  413. swapByte: false,
  414. swapWord: false,
  415. scaling: 1,
  416. adjust: 0,
  417. value: 0,
  418. // point104: 0,
  419. id: null
  420. }
  421. this.tableData.unshift(newTable)
  422. // 保存到临时表格数据中
  423. this.tmpTableData.push(newTable)
  424. this.tmpTableData.forEach((element) => {
  425. // console.log(`this.tmpTableData element=${element.tmpCheckPointId}`)
  426. })
  427. },
  428. // 导入
  429. submitUpload() {
  430. this.$refs.upload.submit()
  431. // 上传之后刷新页面查看上传结果
  432. this.getPlanCheckPoint()
  433. },
  434. // 导出
  435. async getPlanExport() {
  436. // /product/model/:product/models.csv
  437. planExport(this.currentPlanData.product).then((response) => {
  438. const link = document.createElement('a')
  439. const blob = new Blob([response], {
  440. type: 'application/vnd.ms-excel;charset=utf-8'
  441. })
  442. link.style.display = 'none'
  443. link.href = URL.createObjectURL(blob)
  444. link.setAttribute('download', `导出数据.csv`)
  445. document.body.appendChild(link)
  446. link.click()
  447. document.body.removeChild(link)
  448. // this.msgSuccess('导出成功')
  449. })
  450. },
  451. // 清除
  452. planClear() {
  453. // console.log('planClear 清除')
  454. this.tableData = []
  455. },
  456. // 获取测点表格数据
  457. async getPlanCheckPoint(pageObj) {
  458. this.vloading = true
  459. // 翻页时pageObj对象才会有值,属性分别为page和limit
  460. if (pageObj == null) {
  461. pageObj = {
  462. page: 0,
  463. limit: this.pageLimit
  464. }
  465. this.paginationNumber = 0
  466. } else {
  467. this.pageLimit = pageObj.limit
  468. }
  469. // 返回值
  470. /* {
  471. adjust:0 //偏移量
  472. dataType:null //值类型
  473. id:null //
  474. name:"中文" //测点名称
  475. offset:0 //104点号
  476. range:null //测点类型
  477. scaling:1 //倍率
  478. swapByte: 0, //字内交换
  479. swapWord: 0, //字节交换
  480. value:0 //先不用管- 测点查询
  481. "manual": null, //先不用管 -单测点查询
  482. "stepSeconds": 0, //先不用管 -单测点查询
  483. "pollingCycle": 0, //先不用管 -单测点查询
  484. "disable": null //先不用管 -单测点查询
  485. }
  486. totalPages 总页数
  487. number 第几页
  488. 删除默认 tableData数据 */
  489. const getUrl = `product/model/${this.currentPlanData.product}/paging?page=${pageObj.page}&size=${pageObj.limit}`
  490. httpGet(getUrl).then((response) => {
  491. this.vloading = false
  492. if (response == null || response.content == null || response.content.length === 0) {
  493. this.tableData = []
  494. this.paginationNumber = 0
  495. this.paginationTotalPages = 0
  496. this.paginationTotalElements = 0
  497. return
  498. }
  499. // 计算104点号
  500. // response.content.map((item, index) => {
  501. // item.point104 = this.calPoint104(item.range, item.offset)
  502. // })
  503. this.tableData = response.content
  504. this.paginationTotalPages = response.totalPages
  505. this.paginationTotalElements = parseInt(response.totalElements)
  506. this.paginationNumber = response.number * 1 + 1
  507. })
  508. },
  509. // 表格重排
  510. tableLayout() {
  511. this.$nextTick(() => {
  512. this.$refs.multipleTable.doLayout()
  513. })
  514. },
  515. // input失焦 添加数据
  516. // inputBlur(inputBlurData) {
  517. // // 2023-05-29 应后端要求,取消失焦保存
  518. // // console.log('inputBlur inputBlurData=', inputBlurData)
  519. // // // 后端不支持多条数据一起添加,所以这里失焦就添加数据,不需要再判断是否是临时添加数据
  520. // // // 此处 // /product/model/:product 中的 :product 是上一步添加方案时返回的 product 的值
  521. // // const editPath = `/product/model/${this.currentPlanData.product}`
  522. // // const editData = this.getSubmitTableRowData(inputBlurData)
  523. // // console.log('inputBlur editData=', editData)
  524. // // editRow(editPath, editData)
  525. // },
  526. async saveClick(row, index) {
  527. // if (row.offset > 65535) {
  528. // this.$message({
  529. // type: 'error',
  530. // message: `寄存器地址不能大于65535`,
  531. // offset: window.screen.height / 3
  532. // })
  533. // return
  534. // }
  535. const editPath = `/product/model/${this.currentPlanData.product}`
  536. const editData = row
  537. // const editData = this.getSubmitTableRowData(row)
  538. console.log('saveClick editData=', editData)
  539. // 校验必填项目
  540. let isNotPassMesage = ''
  541. let v = editData.name || ''
  542. v = v.toString().replace(/ /gi, '')
  543. if (v === '') {
  544. isNotPassMesage = '必填项(测点名称)不能为空'
  545. }
  546. v = editData.range == null ? '' : editData.range
  547. v = v.toString().replace(/ /gi, '')
  548. if (v === '') {
  549. isNotPassMesage = '必填项(点号类型)不能为空'
  550. }
  551. v = editData.offset == null ? '' : editData.offset
  552. v = v.toString().replace(/ /gi, '')
  553. if (v === '') {
  554. isNotPassMesage = '必填项(点号)不能为空'
  555. }
  556. if (isNotPassMesage !== '') {
  557. this.$message({
  558. type: 'error',
  559. message: isNotPassMesage,
  560. offset: window.screen.height / 3
  561. })
  562. return
  563. }
  564. const res = await editRow(editPath, editData)
  565. if (res) {
  566. this.$set(this.tableData[index], 'id', res.id)
  567. this.$set(this.tableData[index], 'modbus', res.modbus)
  568. this.$set(this.tableData[index], 'iec104', res.iec104)
  569. this.$message({
  570. type: 'success',
  571. message: `${res.name} 保存成功.`,
  572. offset: window.screen.height / 3
  573. })
  574. }
  575. },
  576. delClick(row) {
  577. // return
  578. this.$confirm('此操作将永久删除该记录, 是否继续?', `删除:${row.name}`, {
  579. confirmButtonText: '确定',
  580. cancelButtonText: '取消',
  581. type: 'warning'
  582. }).then(async() => {
  583. if (row.id != null && row.id > 0) {
  584. // // :product 产品名称
  585. // // :tag 标签编号
  586. const delUrl = `/product/model/${this.currentPlanData.product}/${row.id}`
  587. await delRecord(delUrl)
  588. .then((response) => {
  589. // console.log('delRecord rs=', response)
  590. // 后端成功执行后,前端再删除选中行
  591. // this.tableData.splice(index, 1)
  592. // this.tableData = this.tableData.filter(item => item.id !== row.id)
  593. const newData = this.tableData.filter(item => item.id !== row.id)
  594. this.tableData = [...newData]
  595. })
  596. } else {
  597. // 如果是新增的临时行,直接删除选中行
  598. // this.tableData.splice(index, 1)
  599. // this.tableData = this.tableData.filter(item => item.tmpCheckPointId !== row.tmpCheckPointId)
  600. const newData = this.tableData.filter(item => item.tmpCheckPointId !== row.tmpCheckPointId)
  601. // console.log('newData=', newData)
  602. this.tableData = [...newData]
  603. }
  604. }).catch(() => {
  605. this.$message({
  606. type: 'info',
  607. message: '已取消删除',
  608. offset: window.screen.height / 3
  609. })
  610. })
  611. },
  612. // 刷新
  613. updataTableData() {
  614. this.planClear()
  615. this.getPlanCheckPoint()
  616. },
  617. // 提交
  618. // 提交 下一步
  619. submitPlan() {
  620. // console.log(`this.tmpTableData=`, this.tmpTableData)
  621. let currentStep = this.currentStep
  622. const noName = this.tableData.some(item => ((!item.name) || (!item.range) || (!item.offset.toString())))
  623. if (noName) {
  624. this.$message({
  625. type: 'error',
  626. message: '必填项不能为空',
  627. offset: window.screen.height / 3
  628. })
  629. return
  630. }
  631. if (currentStep < 3) {
  632. // 如果没有数据
  633. if (!this.tableData.length) {
  634. currentStep = currentStep + 1
  635. this.$emit('changeStep', currentStep)
  636. return
  637. }
  638. // 不接受数组提交,只能单条提交,所以使用遍历提交
  639. this.tableData.forEach((item, index) => {
  640. const tableRowData = this.getSubmitTableRowData(item)
  641. // 保存步骤
  642. const editPath = `/product/model/${this.currentPlanData.product}`
  643. editRow(editPath, tableRowData).then(res => {
  644. // console.log('PlanCheckPoint submitPlan currentStep=', currentStep)
  645. // console.log('PlanCheckPoint submitPlan index=', index)
  646. if (index === this.tableData.length - 1) {
  647. // 如果是最后一条数据 提交成功,下一步
  648. currentStep = currentStep + 1
  649. this.$emit('changeStep', currentStep)
  650. }
  651. })
  652. })
  653. } else {
  654. // 已经是最后一步了
  655. }
  656. },
  657. // 公用函数
  658. // 获取提交的行数据
  659. getSubmitTableRowData(rowData) {
  660. if (rowData.id > 0 || rowData.tmpCheckPointId > 0) {
  661. let submitRowData = []
  662. // {
  663. // adjust:0 //偏移量
  664. // dataType:null //值类型
  665. // id:null //
  666. // name:"中文" //测点名称
  667. // offset:0 //寄存器地址
  668. // range:null //功能码
  669. // scaling:1 //倍率
  670. // swapByte: 0, //字内交换
  671. // swapWord: 0, //字节交换
  672. // value:0 //先不用管- 测点查询
  673. // "manual": null, //先不用管 -单测点查询
  674. // "stepSeconds": 0, //先不用管 -单测点查询
  675. // "pollingCycle": 0, //先不用管 -单测点查询
  676. // "disable": null //先不用管 -单测点查询
  677. // }
  678. if (!rowData.id) {
  679. rowData.id = null
  680. }
  681. // 组织出待提交数据
  682. // {"tmpCheckPointId":2,"name":"","range":"COIL_STATUS","offset":0,"dataType":"BOOL","swapByte":false,"swapWord":false,"scaling":1,"adjust":0,"value":0,"id":null}
  683. submitRowData = {
  684. id: rowData.id,
  685. groupingName: rowData.groupingName,
  686. relationTag: rowData.relationTag,
  687. name: rowData.name,
  688. range: rowData.range,
  689. offset: rowData.offset,
  690. dataType: rowData.dataType,
  691. swapByte: rowData.swapByte,
  692. swapWord: rowData.swapWord,
  693. scaling: rowData.scaling,
  694. adjust: rowData.adjust,
  695. value: rowData.value
  696. }
  697. return submitRowData
  698. } else {
  699. return []
  700. }
  701. },
  702. // 批量删除
  703. async multDelete() {
  704. /* const delUrl = `/product/model/${this.currentPlanData.product}/${item.id}`
  705. delRecord(delUrl).then((response) => {
  706. console.log('delRecord rs=', response)
  707. // 后端成功执行后,前端再删除选中行
  708. // this.tableData.splice(index, 1)
  709. // this.tableData = this.tableData.filter(item => item.id !== row.id)
  710. const newData = this.tableData.filter(par => par.id !== item.id)
  711. this.tableData = [...newData]
  712. }).catch((err) => {
  713. console.log('delRecord err rs=', err)
  714. }) */
  715. // 后端执行完成后,开始前端操作
  716. // 遍历 `tableData` 数组
  717. for (let i = 0; i < this.tableData.length; i++) {
  718. const item = this.tableData[i]
  719. // 判断当前行数据是否被选中
  720. if (this.multipleSelection.includes(item)) {
  721. // 如果选中,则从 开始删除
  722. if (item.id > 0) {
  723. // 如果 id > 0 则表示 是已经保存在后端的数据了,需要向后端发送删除请求
  724. const delUrl = `/product/model/${this.currentPlanData.product}/${item.id}`
  725. await delRecord(delUrl).then((response) => {
  726. // 后端成功执行后,前端再删除选中行
  727. this.tableData.splice(i, 1)
  728. i-- // 因为 `splice` 方法会修改数组长度,所以需要将 `i` 减去 1,避免漏删下一个元素
  729. })
  730. } else {
  731. // 如果是新增未保存过的数据,直接删除
  732. this.tableData.splice(i, 1)
  733. i-- // 因为 `splice` 方法会修改数组长度,所以需要将 `i` 减去 1,避免漏删下一个元素
  734. }
  735. }
  736. }
  737. // this.showDel = false
  738. },
  739. // 多选按钮状态改变 handleSelectionChange
  740. handleSelectionChange(val) {
  741. // 选中行存入临时变量中
  742. this.multipleSelection = val
  743. // console.log('handleSelectionChange val', val)
  744. // 批量删除按钮激活
  745. this.showDel = true
  746. },
  747. editClick(row, index) {
  748. // 单测点查询接口 /product/model/:product/:tag
  749. // 获取测点详细信息
  750. if (row.id) {
  751. const getUrl = `/product/model/${this.currentPlanData.product}/${row.id}`
  752. // console.log('PlanCheckPoint editClick getUrl=', getUrl)
  753. httpGet(getUrl).then(res => {
  754. this.form = res
  755. // this.form.swapByte = Boolean(res.swapByte)
  756. // this.form.swapWord = Boolean(res.swapWord)
  757. // console.log('PlanCheckPoint editClick this.form=', this.form)
  758. })
  759. } else {
  760. this.form = this.tableData[index]
  761. }
  762. this.stepIndex = index
  763. this.dialogFormVisible = true
  764. },
  765. saveForm() {
  766. // 修改测点接口 /product/model/:product
  767. if (this.form.id) {
  768. let isNotPassMesage = ''
  769. let v = this.form.name || ''
  770. v = v.toString().replace(/ /gi, '')
  771. if (v === '') {
  772. isNotPassMesage = '必填项(测点名称)不能为空'
  773. }
  774. v = this.form.range || ''
  775. v = v.toString().replace(/ /gi, '')
  776. if (v === '') {
  777. isNotPassMesage = '必填项(点号类型)不能为空'
  778. }
  779. v = this.form.offset == null ? '' : this.form.offset
  780. v = v.toString().replace(/ /gi, '')
  781. if (v === '') {
  782. isNotPassMesage = '必填项(点号)不能为空'
  783. }
  784. if (isNotPassMesage !== '') {
  785. this.$message({
  786. type: 'error',
  787. message: isNotPassMesage,
  788. offset: window.screen.height / 3
  789. })
  790. return
  791. }
  792. const putUrl = `/product/model/${this.currentPlanData.product}`
  793. putData(putUrl, this.form).then(res => {
  794. // 保存表单
  795. // console.log('saveForm putData 1 tableData=', this.tableData)
  796. if (res == null) {
  797. return
  798. }
  799. // res.point104 = this.calPoint104(res.range, res.offset)
  800. this.$set(this.tableData, this.stepIndex, res)
  801. this.dialogFormVisible = false
  802. })
  803. } else {
  804. this.$set(this.tableData, this.stepIndex, this.form)
  805. this.dialogFormVisible = false
  806. }
  807. }
  808. }
  809. }
  810. </script>
  811. <style lang="scss" scoped>
  812. .plan-check-point {
  813. // border: 1px #f00 solid;
  814. text-align: center;
  815. font-size: 16px;
  816. width: 100%;
  817. padding:0 20px;
  818. .title {
  819. font-size: 20px;
  820. font-weight: bold;
  821. padding: 10px 0 10px 0;
  822. }
  823. .buttons {
  824. display: flex;
  825. justify-content: space-between;
  826. text-align: left;
  827. padding-bottom: 20px;
  828. .left,.right {
  829. width: 50%;
  830. }
  831. .right{
  832. display: flex;
  833. justify-content: right;
  834. }
  835. .item {
  836. margin: 0 10px;
  837. }
  838. }
  839. .modelInput{
  840. text-align: left;
  841. }
  842. // 分页
  843. .page-bar {
  844. display: flex;
  845. justify-content: center;
  846. // padding: 20px;
  847. .el-pagination.is-background {
  848. .el-pager {
  849. .number {
  850. color: #00706b;
  851. border: 1px #00706b solid;
  852. background-color: #fff;
  853. }
  854. }
  855. }
  856. }
  857. // 底部步骤按钮
  858. .bottom-button{
  859. margin-top: 20px;
  860. }
  861. .table-container{
  862. height: 100%;
  863. }
  864. // ::v-deep .pagination-container{
  865. // margin-top: 0;
  866. // }
  867. ::v-deep {
  868. // 表格输入框
  869. .table-column-input {
  870. .el-input__inner {
  871. border: none;
  872. background: transparent;
  873. padding-left: 0;
  874. }
  875. .el-input__inner:focus {
  876. border: 1px #00706b solid;
  877. }
  878. }
  879. }
  880. }
  881. ::v-deep input::-webkit-outer-spin-button,
  882. ::v-deep input::-webkit-inner-spin-button {
  883. -webkit-appearance: none !important;
  884. }
  885. ::v-deep input[type='number'] {
  886. -moz-appearance: textfield !important;
  887. }
  888. </style>