step1.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. <template>
  2. <div id="handsonStep1">
  3. <div class="btns-view">
  4. <el-button style="float:right;margin-top:4px;margin-left:10px;width:120px;" @click="saveData">保存</el-button>
  5. <el-button style="float:right;margin-top:4px;width:120px;" @click="addRow">新增行</el-button>
  6. <el-button style="float:right;margin-top:4px;width:120px;" @click="downData">导出配置点位表</el-button>
  7. <el-button style="float:right;margin-top:4px;width:120px;" @click="updateExcel = true">导入Excel</el-button>
  8. <el-button style="float:right;margin-top:4px;width:120px;" @click="downloadExcel = true">导出Excel模板</el-button>
  9. <el-checkbox style="float:right;line-height:40px;" @change="getData" v-model="checked">只显示使用的原始点位</el-checkbox>
  10. <el-button @click="clickPointVal">获取原始点位当前值</el-button>
  11. </div>
  12. <div id="handsontableSteps1" class="middle_sty" v-loading="isLoading">
  13. <handsontable-component v-if="!!allData.length" @delete="delePoint" ref="handsontable" @mouseDown="clickTable" @change="changeHand"></handsontable-component>
  14. <div v-else class="center">
  15. <i class="iconwushuju iconfont"></i>
  16. 暂无数据
  17. </div>
  18. </div>
  19. <own-dialog :width="'500px'" :index="true" title="位置标签" :dialogVisible="localtionDialog" @cancel="closeFalg">
  20. <localtion-falg :renderData="renderData" @changeTag="changeLoc"></localtion-falg>
  21. </own-dialog>
  22. <own-dialog :width="'300px'" :index="true" title="导出excel模板" :dialogVisible="downloadExcel" @cancel="close">
  23. <div class="center">
  24. <el-button type="text" @click="download">下载模板</el-button>
  25. </div>
  26. </own-dialog>
  27. <own-dialog :width="'500px'" :index="true" :footer="footer" title="导入excel" :dialogVisible="updateExcel" @confirm="sureOfUpload" @cancel="close">
  28. <div class="center" style="height:100px;">
  29. <upload-file accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" @change="changeFile"></upload-file>
  30. </div>
  31. <div>
  32. <el-radio class="radio-left" v-model="radio" label="1">默认使用导入的全部原始点位</el-radio>
  33. <el-radio class="radio-left" v-model="radio" label="2">默认不使用导入的全部原始点位</el-radio>
  34. </div>
  35. </own-dialog>
  36. <div class="right">
  37. <pagination :page="pages" @change="changePage"></pagination>
  38. </div>
  39. </div>
  40. </template>
  41. <script>
  42. import tools from "@/utils/scan/tools"
  43. import handsontableComponent from "@/components/common/handsontable"
  44. import getHeaderSetting from "@/utils/point_edit/handson_header"
  45. import ownDialog from "@/components/el_pack/dialog"
  46. import localtionFalg from "@/components/config_point/location_flag"
  47. import pagination from "@/components/common/myPagination"
  48. // import "@/assets/js/chosen.jquery.min";
  49. // import "@/assets/js/handsontable-chosen-editor";
  50. // import Handsontable from "handsontable-pro"
  51. import {
  52. mapGetters,
  53. mapActions
  54. } from "vuex";
  55. import {
  56. changeHeader,
  57. showTypes
  58. } from "@/utils/handsontable/delType"
  59. import {
  60. queryPoint,
  61. updatePoint,
  62. createPoint,
  63. downloadTemplete,
  64. uploadPointFile,
  65. deletePoint,
  66. getPointValue
  67. } from "@/fetch/point_http"
  68. import uploadFile from "@/components/common/uploadFile"
  69. import axios from 'axios'
  70. export default {
  71. data() {
  72. return {
  73. checked: false,
  74. settings: {},
  75. hot: null,
  76. changeFlag: true, //是否发生修改
  77. localtionDialog: false,
  78. renderData: {},
  79. allData: [],
  80. copyMain: [],
  81. pages: {
  82. size: 50,
  83. sizes: [10, 30, 50, 100, 150, 200],
  84. total: 0,
  85. currentPage: 0
  86. },
  87. oldPage: {
  88. currentPage: 0,
  89. size: 10
  90. },
  91. downloadExcel: false,
  92. isLoading: false,
  93. updateExcel: false,
  94. radio: '1',
  95. file: "", //上传的文件
  96. footer: {
  97. cancel: '取消',
  98. confirm: '确定'
  99. }
  100. }
  101. },
  102. computed: {
  103. ...mapGetters("project", [
  104. "datasourceId",
  105. "protocolType"
  106. ]),
  107. projectId () {
  108. return this.$store.getters['layout/projectId']
  109. }
  110. },
  111. created() {},
  112. mounted() {
  113. if (!this.datasourceId) {
  114. this.$router.push({
  115. path: "/point/pointsetting"
  116. })
  117. } else {
  118. this.getData()
  119. }
  120. },
  121. methods: {
  122. //关闭弹窗
  123. close() {
  124. this.downloadExcel = false
  125. this.updateExcel = false
  126. this.getData()
  127. },
  128. closeFalg() {
  129. this.localtionDialog = false
  130. },
  131. clickPointVal(){
  132. let data = this.hot.getSourceData()
  133. if(!data || !data.length){
  134. return false
  135. }
  136. let param = {
  137. data: {
  138. DataSourceId: this.datasourceId,
  139. PointIds: data.map(item => {
  140. return item.Id
  141. })
  142. },
  143. type: this.protocolType
  144. }
  145. getPointValue(param,res => {
  146. if(!!res.Content && res.Content.length){
  147. data.map(item => {
  148. res.Content.map(child => {
  149. if(item.Id == child.PointId){
  150. item.pointValue = child.Data.Data
  151. item.pointDate = child.Data.Time
  152. }
  153. })
  154. return item
  155. })
  156. }
  157. })
  158. },
  159. changeLoc(val) {
  160. this.renderData.LocationFlag = val
  161. this.changeFlag = false
  162. },
  163. downData() {
  164. let param = {
  165. method: 'post',
  166. url: `/pointconfig/point/${this.protocolType}/pointlist-export`,
  167. data: {
  168. DataSourceId: this.datasourceId
  169. },
  170. responseType: 'blob',
  171. headers: {
  172. ProjectId: this.projectId
  173. }
  174. }
  175. axios(param).then(function(res) {
  176. var blob = new Blob([res.data], {
  177. type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
  178. });
  179. var fileName = res.headers['content-disposition'];
  180. if (fileName)
  181. fileName = fileName.substring(fileName.indexOf('=') + 1);
  182. if ('download' in document.createElement('a')) { // 非IE下载
  183. const elink = document.createElement('a')
  184. elink.download = fileName
  185. elink.style.display = 'none'
  186. elink.href = URL.createObjectURL(blob)
  187. document.body.appendChild(elink)
  188. elink.click()
  189. URL.revokeObjectURL(elink.href) // 释放URL 对象
  190. document.body.removeChild(elink)
  191. } else { // IE10+下载
  192. navigator.msSaveBlob(blob, fileName)
  193. }
  194. }).catch(function(err) {
  195. })
  196. },
  197. //删除点位
  198. delePoint(delData) {
  199. let param = {
  200. data: delData.map(item => {
  201. return item.Id
  202. }),
  203. type: this.protocolType
  204. }
  205. console.log(delData,'delllll')
  206. if (!delData.length) {
  207. return false
  208. }
  209. if(!!delData){
  210. console.log(delData,'delData')
  211. if(!delData[0].Id){
  212. return false
  213. }
  214. }
  215. this.$confirm('你确定要删除点位吗?').then(_ => {
  216. deletePoint(param, res => {
  217. this.$message.success("删除成功")
  218. this.getData()
  219. })
  220. }).catch(_ => {
  221. this.$message("取消删除")
  222. this.getData()
  223. })
  224. },
  225. //下载excel模板
  226. download() {
  227. axios({
  228. method: 'post',
  229. url: `/pointconfig/point/${this.protocolType}/template-export`,
  230. data: {
  231. DataSourceId: this.datasourceId
  232. },
  233. headers: {
  234. ProjectId: this.projectId
  235. },
  236. responseType: 'blob'
  237. }).then(function(res) {
  238. console.log(res)
  239. var blob = new Blob([res.data], {
  240. type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
  241. });
  242. var fileName = res.headers['content-disposition'];
  243. if (fileName)
  244. fileName = fileName.substring(fileName.indexOf('=') + 1);
  245. if ('download' in document.createElement('a')) { // 非IE下载
  246. const elink = document.createElement('a')
  247. elink.download = fileName
  248. elink.style.display = 'none'
  249. elink.href = URL.createObjectURL(blob)
  250. document.body.appendChild(elink)
  251. elink.click()
  252. URL.revokeObjectURL(elink.href) // 释放URL 对象
  253. document.body.removeChild(elink)
  254. } else { // IE10+下载
  255. navigator.msSaveBlob(blob, fileName)
  256. }
  257. }).catch(function(err) {
  258. })
  259. },
  260. //点击表格
  261. clickTable(info, row) {
  262. let activeCell = this.hot.getActiveEditor()
  263. if(activeCell.prop == "Used"){
  264. info.Used = !info.Used
  265. }
  266. if (activeCell.prop == "LocationFlag") {
  267. this.renderData = info
  268. this.localtionDialog = true
  269. }
  270. },
  271. addRow() {
  272. if (!!this.allData.length) {
  273. let data = this.hot.getSourceData()
  274. data.unshift({
  275. Used: true,
  276. LocationFlag: []
  277. })
  278. this.hot.loadData(data)
  279. this.hot.updateSettings({
  280. maxRows: data.length
  281. })
  282. } else {
  283. this.allData = [{
  284. Used: true,
  285. LocationFlag: []
  286. }]
  287. this.createHot()
  288. }
  289. },
  290. //页面发生更改
  291. changePage() {
  292. if (!this.changeFlag) {
  293. //发生更改,提示是否保存
  294. this.$confirm('存在数据未保存, 是否继续?', '提示', {
  295. confirmButtonText: '确定',
  296. cancelButtonText: '取消',
  297. type: 'warning'
  298. }).then(() => {
  299. this.getData()
  300. }).catch(() => {
  301. this.pages.currentPage = this.oldPage.currentPage
  302. this.pages.size = this.oldPage.size
  303. return false
  304. });
  305. } else {
  306. this.getData()
  307. }
  308. },
  309. getData() {
  310. // width = (document.getElementById("app").clientWidth - 50) / header.length
  311. this.isLoading = true
  312. let param = {
  313. type: this.protocolType,
  314. data: {
  315. Filters: {
  316. DatasourceId: this.datasourceId,
  317. },
  318. "PageNumber": this.pages.currentPage || 1,
  319. "PageSize": this.pages.size,
  320. }
  321. }
  322. if (this.checked) {
  323. param.data.Filters.Used = true
  324. }
  325. this.oldPage = {
  326. size: this.pages.size,
  327. currentPage: this.pages.currentPage
  328. }
  329. queryPoint(param, res => {
  330. this.isLoading = false
  331. this.changeFlag = true
  332. this.allData = res.Content || []
  333. this.copyMain = JSON.parse(JSON.stringify(res.Content))
  334. this.pages.total = res.Total
  335. this.createHot()
  336. })
  337. },
  338. //创建实例
  339. createHot() {
  340. let header, width, settings
  341. header = getHeaderSetting(this.protocolType)
  342. settings = {
  343. data: this.allData,
  344. colHeaders: changeHeader(header),
  345. columns: showTypes(header),
  346. rowHeights: 30,
  347. maxRows: this.allData.length,
  348. contextMenu: {
  349. items: {
  350. remove_row: {
  351. name: "删除点位"
  352. }
  353. }
  354. }
  355. }
  356. if (!this.allData.length) {
  357. return false
  358. }
  359. this.$nextTick(_ => {
  360. this.hot = this.$refs.handsontable.init(settings)
  361. })
  362. },
  363. //修改提示
  364. changeHand(changeData, source) {
  365. if (!!changeData) {
  366. let tableData = this.hot.getSourceData()
  367. for(let i = 0; i < tableData.length; i++){
  368. let forFlag = true
  369. if(!tools.isObjectValueEqual(this.copyMain[i],tableData[i])) {
  370. this.changeFlag = false
  371. forFlag = false
  372. break
  373. } else if (i == tableData.length - 1 && forFlag) {
  374. this.changeFlag = true
  375. }
  376. }
  377. }
  378. return false
  379. },
  380. //保存
  381. saveData() {
  382. if (!!this.hot) {
  383. console.log(this.hot.getSourceData(),'getSourceData')
  384. let data = this.hot.getSourceData(),
  385. updateList = [],
  386. arr1 = [],
  387. createList = [];
  388. data.map(item => {
  389. if (!!item.Id) {
  390. delete item.CreateTime
  391. delete item.LastUpdate
  392. if(item.hasOwnProperty('pointDate')){
  393. delete item.pointDate
  394. }
  395. if(item.hasOwnProperty('pointValue')){
  396. delete item.pointValue
  397. }
  398. arr1.push(item)
  399. updateList.push(item)
  400. } else {
  401. createList.push(item)
  402. }
  403. })
  404. console.log(updateList,createList, arr1, "updateList")
  405. if (createList.length || updateList.length) {
  406. let flag = true
  407. if (createList.length) {
  408. for (let i = 0; i < createList.length; i++) {
  409. if (!(
  410. (createList[i].hasOwnProperty("SlaveId") &&
  411. createList[i].SlaveId &&
  412. createList[i].hasOwnProperty("RegistersAddress") &&
  413. createList[i].RegistersAddress &&
  414. createList[i].hasOwnProperty("RegistersQuality") &&
  415. createList[i].RegistersQuality &&
  416. createList[i].hasOwnProperty("ConvertType") &&
  417. createList[i].ConvertType
  418. ) ||
  419. (createList[i].hasOwnProperty("DeviceId") &&
  420. createList[i].DeviceId &&
  421. createList[i].hasOwnProperty("InstanceNumber") &&
  422. createList[i].InstanceNumber &&
  423. createList[i].hasOwnProperty("DataType") &&
  424. createList[i].DataType
  425. ) ||
  426. (createList[i].hasOwnProperty("Item") &&
  427. createList[i].Item
  428. ) ||
  429. (createList[i].hasOwnProperty("GroupAddress") &&
  430. createList[i].GroupAddress
  431. ) ||
  432. (createList[i].hasOwnProperty("Topic") &&
  433. createList[i].Topic
  434. ) ||
  435. (createList[i].hasOwnProperty("Exchange") &&
  436. createList[i].Exchange &&
  437. createList[i].hasOwnProperty("Type") &&
  438. createList[i].Type &&
  439. createList[i].hasOwnProperty("RoutingKey") &&
  440. createList[i].RoutingKey
  441. )
  442. )) {
  443. this.$message("请输入所有必填字段(带“*”列为必填列)")
  444. flag = false
  445. return false
  446. } else if (!(createList[i].hasOwnProperty("Description") && createList[i].Description)) {
  447. this.$message("请输入全部的原始点位描述")
  448. flag = false
  449. return false
  450. }
  451. }
  452. }
  453. if (flag) {
  454. this.createList(createList)
  455. if (updateList.length) {
  456. this.update(updateList)
  457. }
  458. }
  459. }
  460. } else {
  461. this.$message.error("请确保存在数据")
  462. }
  463. },
  464. async createList(createList) {
  465. for (let i = 0; i < createList.length; i++) {
  466. await this.create(createList[i])
  467. }
  468. this.changeFlag = true
  469. },
  470. async create(obj) {
  471. for (let key in obj) {
  472. if (key == "LocationFlag" && obj[key] == "") {
  473. obj[key] = []
  474. }
  475. if (obj[key] === "") {
  476. obj[key] = null
  477. }
  478. }
  479. obj.DatasourceId = this.datasourceId
  480. obj.ProjectId = this.projectId
  481. await createPoint({
  482. data: obj,
  483. type: this.protocolType
  484. }, res => {
  485. obj.Id = res.Id
  486. this.getData()
  487. })
  488. },
  489. /**
  490. * @param {更新list} updateList
  491. *
  492. * 更新点位
  493. */
  494. update(updateList) {
  495. updatePoint({
  496. data: {
  497. Content: updateList
  498. },
  499. type: this.protocolType
  500. }, res => {
  501. this.getData()
  502. })
  503. },
  504. //没有保存的时候弹窗
  505. noSaveData() {
  506. return this.changeFlag
  507. },
  508. //上传文件
  509. changeFile(file) {
  510. this.file = file[0] || ''
  511. },
  512. //确定上传
  513. sureOfUpload() {
  514. if (!!this.file) {
  515. //有文件进行上传
  516. let param = {
  517. data: new FormData(),
  518. type: this.protocolType
  519. };
  520. param.data.set('DataSourceId', this.datasourceId)
  521. param.data.set('Used', this.radio == 1 ? true : false)
  522. param.data.set('multipartFile', this.file.raw)
  523. uploadPointFile(param, res => {
  524. this.$message.success("上传成功")
  525. this.getData()
  526. this.updateExcel = false
  527. })
  528. } else {
  529. this.$message.info("请选择文件")
  530. }
  531. }
  532. },
  533. components: {
  534. handsontableComponent,
  535. ownDialog,
  536. localtionFalg,
  537. pagination,
  538. uploadFile
  539. },
  540. }
  541. </script>
  542. <style lang="scss" scoped>
  543. .radio-left {
  544. display: block;
  545. line-height: 30px;
  546. margin-left: 100px;
  547. }
  548. #handsonStep1 {
  549. flex: 1;
  550. display: flex;
  551. flex-flow: column;
  552. padding-bottom: 10px;
  553. .btns-view {
  554. height: 40px;
  555. line-height: 40px;
  556. margin-bottom: 10px;
  557. padding: 0 10px;
  558. }
  559. #handsontableSteps1 {
  560. flex: 1;
  561. overflow: hidden;
  562. position: relative;
  563. margin: 0 10px;
  564. }
  565. }
  566. </style>