mesProductArcWeldingInfo.html 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. <% layout('/layouts/default.html', {title: '焊接过程参数管理', libs: ['validate']}){ %>
  2. <div class="main-content">
  3. <div class="box box-main">
  4. <div class="box-header with-border">
  5. <div class="box-title">
  6. <i class="fa icon-note"></i> ${text(mesProductArcWelding.isNewRecord ? '新增焊接过程参数管理' : '焊接过程参数管理详情')}
  7. </div>
  8. <div class="box-tools pull-right">
  9. <button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
  10. </button>
  11. </div>
  12. </div>
  13. <div id="app">
  14. <div class="alert alert-info" style="margin-bottom: 10px;">{{ weldingTypeText }},已解析 {{ myData.length }} 条参数记录</div>
  15. <div ref="vChart" style="width: 100%;height: 500px;"></div>
  16. <br>
  17. <br>
  18. <div ref="iChart" style="width: 100%;height:500px;"></div>
  19. <br>
  20. <br>
  21. <div v-if="showThirdChart" ref="speedChart" style="width: 100%;height:500px;"></div>
  22. <br>
  23. <br>
  24. <div class="col-sm-12">
  25. <table class="table table-bordered" style="table-layout: fixed;white-space: normal;">
  26. <thead>
  27. <tr>
  28. <template v-for="n in welderCount">
  29. <th>{{ firstMetricName }}{{n}}</th>
  30. <th>{{ secondMetricName }}{{n}}</th>
  31. <th v-if="showThirdChart">{{ thirdMetricName }}{{n}}</th>
  32. <th v-if="!isNewJson">错误码{{n}}</th>
  33. <th v-if="!isNewJson">JOB号{{n}}</th>
  34. </template>
  35. <th>记录时间</th>
  36. </tr>
  37. </thead>
  38. <tbody>
  39. <tr v-for="(item,index) in myData" :key="index">
  40. <template v-for="n in welderCount">
  41. <td>{{ item['V' + n] }}</td>
  42. <td>{{ item['I' + n] }}</td>
  43. <td v-if="showThirdChart">{{ item['speed' + n] }}</td>
  44. <td v-if="!isNewJson">{{ item['code' + n] }}</td>
  45. <td v-if="!isNewJson">{{ item['JOB' + n] }}</td>
  46. </template>
  47. <td>{{ item.createDate }}</td>
  48. </tr>
  49. </tbody>
  50. </table>
  51. </div>
  52. </div>
  53. <div class="box-footer">
  54. <div class="row">
  55. <div class="col-sm-offset-2 col-sm-10">
  56. <button type="button" class="btn btn-sm btn-default" id="btnCancel"
  57. onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}
  58. </button>
  59. </div>
  60. </div>
  61. </div>
  62. </div>
  63. </div>
  64. <% } %>
  65. <script>
  66. $("#inputForm").validate({
  67. submitHandler: function (form) {
  68. js.ajaxSubmitForm($(form), function (data) {
  69. js.showMessage(data.message);
  70. if (data.result == Global.TRUE) {
  71. js.closeCurrentTabPage(function (contentWindow) {
  72. contentWindow.page();
  73. });
  74. }
  75. }, "json");
  76. }
  77. });
  78. </script>
  79. <script src="${ctxStatic}/echarts/4.2/echarts.min.js"></script>
  80. <script src="${ctxStatic}/common/elementui2.15.5/vue-2.6.14.js"></script>
  81. <script>
  82. const convertToArrayOfObjects = (arr, welderCount) => {
  83. return arr.map(str => {
  84. const values = str.split('|');
  85. const obj = {};
  86. for (let i = 0; i < welderCount; i++) {
  87. const baseIndex = i * 5;
  88. if (baseIndex + 4 >= values.length) break;
  89. obj['V' + (i + 1)] = parseFloat(values[baseIndex]) || 0;
  90. obj['I' + (i + 1)] = parseFloat(values[baseIndex + 1]) || 0;
  91. obj['speed' + (i + 1)] = parseFloat(values[baseIndex + 2]) || 0;
  92. obj['code' + (i + 1)] = parseInt(values[baseIndex + 3], 10) || 0;
  93. obj['JOB' + (i + 1)] = parseInt(values[baseIndex + 4], 10) || 0;
  94. }
  95. obj.createDate = values[welderCount * 5] || '';
  96. return obj;
  97. });
  98. };
  99. const unescapeHtml = (str) => {
  100. if (!str) return str;
  101. return str.replace(/&quot;/g, '"')
  102. .replace(/&amp;/g, '&')
  103. .replace(/&lt;/g, '<')
  104. .replace(/&gt;/g, '>')
  105. .replace(/&#39;/g, "'")
  106. .replace(/&nbsp;/g, ' ');
  107. };
  108. const normalizeContent = (content) => {
  109. if (!content) return '';
  110. let text = unescapeHtml(content).trim();
  111. for (let i = 0; i < 2; i++) {
  112. if (!text.startsWith('"')) break;
  113. try {
  114. const parsed = JSON.parse(text);
  115. if (typeof parsed !== 'string') break;
  116. text = parsed.trim();
  117. } catch (e) {
  118. break;
  119. }
  120. }
  121. if (text.startsWith('{\\') || text.startsWith('[\\')) {
  122. text = text.replace(/\\"/g, '"')
  123. .replace(/\\\\/g, '\\');
  124. }
  125. return text;
  126. };
  127. const parseJsonContent = (content) => {
  128. const text = normalizeContent(content);
  129. if (!text.startsWith('{')) return null;
  130. try {
  131. return JSON.parse(text);
  132. } catch (e) {
  133. console.error('解析JSON格式content出错:', e, text);
  134. return null;
  135. }
  136. };
  137. const getWelderCount = (content) => {
  138. if (!content || content === '' || content === '[]') return 2;
  139. try {
  140. content = normalizeContent(content);
  141. const json = parseJsonContent(content);
  142. if (json) {
  143. const first = json.samples && json.samples.length > 0 ? json.samples[0] : {};
  144. let count = 0;
  145. if (first.robot1Current !== undefined || first.robot1Voltage !== undefined || first.robot1Pressure !== undefined) count++;
  146. if (first.robot2Current !== undefined || first.robot2Voltage !== undefined || first.robot2Pressure !== undefined) count++;
  147. return count || 2;
  148. }
  149. let strArr;
  150. if (content.startsWith('[')) {
  151. strArr = JSON.parse(content);
  152. } else if (content.startsWith('"')) {
  153. strArr = JSON.parse(content);
  154. } else {
  155. strArr = content.slice(2, -2).split('","');
  156. }
  157. if (!strArr || strArr.length === 0 || !strArr[0]) return 2;
  158. const firstRecord = strArr[0];
  159. const values = firstRecord.split('|');
  160. const fieldCount = values.length - 1;
  161. return Math.floor(fieldCount / 5) || 2;
  162. } catch (e) {
  163. console.error('解析焊机数量出错:', e);
  164. return 2;
  165. }
  166. };
  167. const convertNewJsonContent = (content) => {
  168. const json = parseJsonContent(content);
  169. if (!json) return [];
  170. const samples = json.samples || [];
  171. return samples.map(sample => {
  172. const obj = {};
  173. obj.V1 = parseFloat(sample.robot1Voltage || 0) || 0;
  174. obj.I1 = parseFloat(sample.robot1Current || 0) || 0;
  175. obj.speed1 = parseFloat(sample.robot1Pressure || sample.robot1WeldTime || 0) || 0;
  176. obj.code1 = 0;
  177. obj.JOB1 = '';
  178. obj.V2 = parseFloat(sample.robot2Voltage || 0) || 0;
  179. obj.I2 = parseFloat(sample.robot2Current || 0) || 0;
  180. obj.speed2 = parseFloat(sample.robot2Pressure || sample.robot2WeldTime || 0) || 0;
  181. obj.code2 = 0;
  182. obj.JOB2 = '';
  183. obj.createDate = sample.time || '';
  184. return obj;
  185. });
  186. };
  187. const parseContent = (content) => {
  188. if (!content || content === '' || content === '[]') return [];
  189. try {
  190. content = normalizeContent(content);
  191. if (parseJsonContent(content)) {
  192. return convertNewJsonContent(content);
  193. }
  194. let strArr;
  195. if (content.startsWith('[')) {
  196. strArr = JSON.parse(content);
  197. } else if (content.startsWith('"')) {
  198. strArr = JSON.parse(content);
  199. } else {
  200. strArr = content.slice(2, -2).split('","');
  201. }
  202. if (!strArr || strArr.length === 0) return [];
  203. const welderCount = getWelderCount(content);
  204. return convertToArrayOfObjects(strArr, welderCount);
  205. } catch (e) {
  206. console.error('解析content出错:', e, content);
  207. return [];
  208. }
  209. };
  210. new Vue({
  211. el: '#app',
  212. data: {
  213. content: ${toJson(mesProductArcWelding.content!'')},
  214. welderCount: 2,
  215. vChart: null,
  216. iChart: null,
  217. speedChart: null
  218. },
  219. computed: {
  220. myData() {
  221. return parseContent(this.content);
  222. },
  223. contentJson() {
  224. return parseJsonContent(this.content);
  225. },
  226. isNewJson() {
  227. return !!this.contentJson;
  228. },
  229. weldingType() {
  230. return this.contentJson && this.contentJson.weldingType ? this.contentJson.weldingType : 'old';
  231. },
  232. weldingTypeText() {
  233. if (this.weldingType === 'spot') return '点焊过程参数';
  234. if (this.weldingType === 'arc') return '弧焊过程参数';
  235. return '焊接过程参数';
  236. },
  237. firstMetricName() {
  238. return this.weldingType === 'spot' ? '电流' : '电压';
  239. },
  240. secondMetricName() {
  241. return this.weldingType === 'spot' ? '压力' : '电流';
  242. },
  243. thirdMetricName() {
  244. return this.weldingType === 'spot' ? '焊接时间' : '送丝速度';
  245. },
  246. showThirdChart() {
  247. return this.weldingType === 'spot';
  248. },
  249. timeArr() {
  250. if (!this.myData || this.myData.length === 0) return [];
  251. const arr = [];
  252. for (let i = 0; i < this.myData.length; i++) {
  253. const createDate = this.myData[i].createDate;
  254. if (createDate) {
  255. arr.push(createDate.length > 14 ? createDate.slice(11) : createDate);
  256. }
  257. }
  258. return arr;
  259. },
  260. vOption() {
  261. const series = [];
  262. const legendData = [];
  263. for (let i = 1; i <= this.welderCount; i++) {
  264. legendData.push(this.firstMetricName + i);
  265. const arr = [];
  266. for (let j = 0; j < this.myData.length; j++) {
  267. arr.push(this.myData[j]['V' + i]);
  268. }
  269. series.push({
  270. name: this.firstMetricName + i,
  271. type: 'line',
  272. data: arr,
  273. smooth: true,
  274. showSymbol: true,
  275. symbolSize: 8
  276. });
  277. }
  278. return {
  279. title: { text: this.firstMetricName + '变化折线图' },
  280. tooltip: { trigger: 'axis' },
  281. legend: { data: legendData },
  282. grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
  283. toolbox: { feature: { saveAsImage: {} } },
  284. xAxis: { type: 'category', name: '时间', boundaryGap: false, data: this.timeArr },
  285. yAxis: { name: this.firstMetricName, type: 'value' },
  286. series: series
  287. };
  288. },
  289. iOption() {
  290. const series = [];
  291. const legendData = [];
  292. for (let i = 1; i <= this.welderCount; i++) {
  293. legendData.push(this.secondMetricName + i);
  294. const arr = [];
  295. for (let j = 0; j < this.myData.length; j++) {
  296. arr.push(this.myData[j]['I' + i]);
  297. }
  298. series.push({
  299. name: this.secondMetricName + i,
  300. type: 'line',
  301. data: arr,
  302. smooth: true,
  303. showSymbol: true,
  304. symbolSize: 8
  305. });
  306. }
  307. return {
  308. title: { text: this.secondMetricName + '变化折线图' },
  309. tooltip: { trigger: 'axis' },
  310. legend: { data: legendData },
  311. grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
  312. toolbox: { feature: { saveAsImage: {} } },
  313. xAxis: { type: 'category', name: '时间', boundaryGap: false, data: this.timeArr },
  314. yAxis: { name: this.secondMetricName, type: 'value' },
  315. series: series
  316. };
  317. },
  318. speedOption() {
  319. const series = [];
  320. const legendData = [];
  321. for (let i = 1; i <= this.welderCount; i++) {
  322. legendData.push(this.thirdMetricName + i);
  323. const arr = [];
  324. for (let j = 0; j < this.myData.length; j++) {
  325. arr.push(this.myData[j]['speed' + i]);
  326. }
  327. series.push({
  328. name: this.thirdMetricName + i,
  329. type: 'line',
  330. data: arr,
  331. smooth: true,
  332. showSymbol: true,
  333. symbolSize: 8
  334. });
  335. }
  336. return {
  337. title: { text: this.thirdMetricName + '变化折线图' },
  338. tooltip: { trigger: 'axis' },
  339. legend: { data: legendData },
  340. grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
  341. toolbox: { feature: { saveAsImage: {} } },
  342. xAxis: { type: 'category', name: '时间', boundaryGap: false, data: this.timeArr },
  343. yAxis: { name: this.thirdMetricName, type: 'value' },
  344. series: series
  345. };
  346. }
  347. },
  348. watch: {
  349. myData: {
  350. handler() {
  351. if (this.vChart) {
  352. this.welderCount = getWelderCount(this.content);
  353. this.vChart.setOption(this.vOption, true);
  354. this.iChart.setOption(this.iOption, true);
  355. if (this.speedChart) { this.speedChart.setOption(this.speedOption, true); }
  356. }
  357. },
  358. deep: true
  359. }
  360. },
  361. mounted() {
  362. if (this.content && this.content !== '' && this.content !== '[]') {
  363. this.welderCount = getWelderCount(this.content);
  364. }
  365. this.$nextTick(() => {
  366. this.vChart = echarts.init(this.$refs.vChart)
  367. this.iChart = echarts.init(this.$refs.iChart)
  368. if (this.$refs.speedChart) {
  369. this.speedChart = echarts.init(this.$refs.speedChart)
  370. }
  371. this.vChart.setOption(this.vOption);
  372. this.iChart.setOption(this.iOption);
  373. if (this.speedChart) {
  374. this.speedChart.setOption(this.speedOption);
  375. }
  376. });
  377. }
  378. })
  379. </script>