step1.vue 23 KB

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