MapData.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <template>
  2. <div class="mapdata">
  3. <div id="container" ref="container" style="width:1200px"></div>
  4. <div class="left">
  5. <el-card class="box-card">
  6. <div slot="header" class="clearfix">
  7. <span style="font-size: 18px">地图预览</span>
  8. <span
  9. style="
  10. float: right;
  11. padding: 1px 0;
  12. font-size: 22px;
  13. cursor: pointer;
  14. "
  15. type="text"
  16. @click="goBack"
  17. >×</span
  18. >
  19. </div>
  20. <div style="height: 100%;padding-bottom:10px">
  21. <el-input v-model="value" type="textarea" :rows="34" ></el-input>
  22. </div>
  23. <div class="bottombtn" style="width:100%;height: 35px;padding: 10px 0 0">
  24. <el-button @click="save" type="primary" icon="el-icon-edit" style="float: right; height: 33px; line-height: 2px">保存</el-button>
  25. <el-button @click="reset" type="primary" icon="el-icon-refresh" style="float: right; height: 33px; line-height: 2px;margin: 0 10px">重置</el-button>
  26. <el-button @click="view" type="primary" icon="el-icon-view" style="float: right; height: 33px; line-height: 2px">预览</el-button>
  27. </div>
  28. </el-card>
  29. </div>
  30. </div>
  31. </template>
  32. <script>
  33. import Konva from "konva";
  34. import { getWorkareaInfo,updateWorkarea,getMapData } from '@/api/mes/wa/workarea'
  35. export default {
  36. name: "KonvaExample",
  37. data() {
  38. return {
  39. stage: null,
  40. layer: null,
  41. selectedStates: [], // 用于存储每个元素的选中状态
  42. selectedText: [], // 用于存储未选中的元素文本
  43. rects: [], // 白色r ect合集
  44. texts: [], // 白色text合集
  45. redrects: [], // 红色rect合集
  46. redtexts: [], // 白色text合集
  47. value:'',
  48. form:{},//拿到单个数据
  49. orignData:null,//原始数据
  50. };
  51. },
  52. watch:{
  53. '$route.query.workareaId':{
  54. handler(newValue){
  55. if(newValue){
  56. this.getWorkAreaInfo()
  57. this.initKonva();
  58. }
  59. }
  60. }
  61. },
  62. mounted() {
  63. this.$nextTick(()=>{
  64. this.getWorkAreaInfo()
  65. })
  66. console.log(this.$route.query.workareaId,'workareaId');
  67. },
  68. methods: {
  69. goBack(){
  70. this.$router.push('/mes/md/workarea');
  71. },
  72. getWorkAreaInfo(){
  73. const workareaId=this.$route.query.workareaId;
  74. const sopId=''
  75. const ticketId=''
  76. getWorkareaInfo(workareaId).then((response) => {
  77. console.log(response,'工作区域信息')
  78. this.form=response.data
  79. })
  80. getMapData(workareaId,sopId,ticketId).then(response => {
  81. console.log(response,'工作区域预览接口调用');
  82. this.form.map=response.data;
  83. if (response.data) {
  84. try {
  85. this.value = JSON.stringify(response.data, null, 4);
  86. this.orignData=this.value
  87. } catch (err) {}
  88. }
  89. this.initKonva();
  90. // console.log(this.value,'Value')
  91. })
  92. },
  93. // 重置
  94. reset(){
  95. this.value = this.orignData;
  96. this.initKonva(); // 重新初始化 Konva
  97. },
  98. // 预览
  99. view(){
  100. if(this.isJson(this.value)){
  101. this.form.map=this.value
  102. this.initKonva();
  103. }else {
  104. this.$message({
  105. type: 'error',
  106. message: '地图数据格式不正确,请输入有效的 JSON 格式!'
  107. });
  108. }
  109. },
  110. save() {
  111. this.$confirm('请确认是否保存修改内容', '提示', {
  112. confirmButtonText: '确定',
  113. cancelButtonText: '取消',
  114. type: 'warning'
  115. }).then(() => {
  116. // 校验 this.value 是否为有效的 JSON
  117. if (this.isJson(this.value)) {
  118. const mapData = typeof this.value === 'string' ? this.value : JSON.stringify(this.value);
  119. const formData = {
  120. ...this.form,
  121. map: mapData
  122. };
  123. console.log( formData,'map')
  124. updateWorkarea(formData).then(response => {
  125. console.log(response, '修改车间区域地图');
  126. this.$router.push('/mes/md/workarea');
  127. this.$message({
  128. type: 'success',
  129. message: '保存成功!'
  130. });
  131. });
  132. } else {
  133. this.$message({
  134. type: 'error',
  135. message: '地图数据格式不正确,请输入有效的 JSON 格式!'
  136. });
  137. }
  138. }).catch(() => {
  139. // 取消操作
  140. });
  141. },
  142. // 校验字符串是否为有效的 JSON
  143. isJson(str) {
  144. try {
  145. JSON.parse(str);
  146. return true;
  147. } catch (e) {
  148. return false;
  149. }
  150. },
  151. initKonva() {
  152. // 创建舞台
  153. this.stage = new Konva.Stage({
  154. container: this.$refs.container, // 容器元素
  155. width: 1200,
  156. height: 860,
  157. });
  158. // 创建图层
  159. this.layer = new Konva.Layer();
  160. // 创建底图
  161. const bgImage = new Image();
  162. bgImage.src = require("@/assets/images/table.png");
  163. bgImage.onload = () => {
  164. const knovaImage = new Konva.Image({
  165. x: 330,
  166. y: 10,
  167. image: bgImage,
  168. width: 500,
  169. height: 790,
  170. draggable: false,
  171. });
  172. this.layer.add(knovaImage);
  173. this.layer.draw();
  174. };
  175. // 绘制无限网格
  176. this.drawGrid(50, 50, "#e0e0e0"); // 每个单元格50x50,浅灰色网格
  177. // 渲染数据
  178. const imageSrc = require("@/assets/images/localSetIcon.jpg"); // 图片路径
  179. this.renderGrid(imageSrc, 6, 3, 450, 100, 120, 100, 50, 50, 60, 25);
  180. // 将图层添加到舞台
  181. this.stage.add(this.layer);
  182. this.layer.draw();
  183. // 禁止舞台拖拽
  184. this.stage.draggable(false);
  185. },
  186. // 绘制无限网格
  187. drawGrid(cellWidth, cellHeight, gridColor) {
  188. const width = 1200;
  189. const height = 860;
  190. // 绘制竖线
  191. for (let i = 0; i <= width; i += cellWidth) {
  192. const verticalLine = new Konva.Line({
  193. points: [i, 0, i, height],
  194. stroke: gridColor,
  195. strokeWidth: 1,
  196. });
  197. this.layer.add(verticalLine);
  198. }
  199. // 绘制横线
  200. for (let j = 0; j <= height; j += cellHeight) {
  201. const horizontalLine = new Konva.Line({
  202. points: [0, j, width, j],
  203. stroke: gridColor,
  204. strokeWidth: 1,
  205. });
  206. this.layer.add(horizontalLine);
  207. }
  208. this.layer.draw();
  209. },
  210. renderGrid(imageSrc) {
  211. this.selectedStates = []; // 用数组来存储选中状态
  212. this.rects = [];
  213. this.texts = [];
  214. this.redrects = [];
  215. this.redtexts = [];
  216. this.selectedText = [];
  217. const positions=JSON.parse(this.value)
  218. // const positions = [
  219. // { row: 2, col: 9, pointName: "E-1" },
  220. // { row: 2, col: 11, pointName: "E-2" },
  221. // { row: 2, col: 13, pointName: "E-3" },
  222. // { row: 4, col: 9, pointName: "E-4" },
  223. // { row: 4, col: 11, pointName: "E-5" },
  224. // { row: 4, col: 13, pointName: "E-6" },
  225. // { row: 6, col: 9, pointName: "E-7" },
  226. // { row: 6, col: 11, pointName: "E-8" },
  227. // { row: 6, col: 13, pointName: "E-9" },
  228. // { row: 8, col: 9, pointName: "E-10" },
  229. // { row: 8, col: 11, pointName: "E-11" },
  230. // { row: 8, col: 13, pointName: "E-12" },
  231. // { row: 10, col: 9, pointName: "E-13" },
  232. // { row: 10, col: 11, pointName: "E-14" },
  233. // { row: 10, col: 13, pointName: "E-15" },
  234. // { row: 12, col: 9, pointName: "E-16" },
  235. // { row: 12, col: 11, pointName: "E-17" },
  236. // { row: 12, col: 13, pointName: "E-18" },
  237. // ];
  238. positions.forEach((pos, index) => {
  239. const x = pos.col * 50; // 每个单元格宽度为50
  240. const y = pos.row * 50; // 每个单元格高度为50
  241. const labelText = pos.pointName; // 对应的文字
  242. const point = new Image();
  243. point.src=pos.pointIcon
  244. // point.src = imageSrc;
  245. point.onload = () => {
  246. const knovaImage = new Konva.Image({
  247. x: x,
  248. y: y,
  249. image: point,
  250. width: 50,
  251. height: 50,
  252. draggable: false,
  253. });
  254. this.layer.add(knovaImage);
  255. // 普通矩形
  256. const rect = new Konva.Rect({
  257. x: x - 3,
  258. y: y + 55,
  259. width: 60,
  260. height: 25,
  261. cornerRadius: 10,
  262. stroke: "red",
  263. strokeWidth: 2,
  264. fill: "white",
  265. });
  266. this.layer.add(rect);
  267. this.rects.push(rect); // 用数组存储
  268. // 普通文字
  269. const text = new Konva.Text({
  270. x: x + 12,
  271. y: y + 60,
  272. fontSize: 20,
  273. text: labelText,
  274. fontFamily: "Calibri",
  275. fill: "red",
  276. });
  277. this.layer.add(text);
  278. this.texts.push(text); // 用数组存储
  279. this.layer.draw();
  280. };
  281. });
  282. },
  283. },
  284. };
  285. </script>
  286. <style scoped lang="scss">
  287. #container {
  288. width: 100%;
  289. height: 100%;
  290. }
  291. .mapdata{
  292. width: 100%;
  293. height: 100%;
  294. display: flex;
  295. }
  296. .left{
  297. flex: 1;
  298. display: flex;
  299. flex-direction: column;
  300. }
  301. </style>