In03.vue 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385
  1. <template>
  2. <div @click="HideWindow">
  3. <!--这是印花模块的模块展示内容-->
  4. <div for="IN03" id="top" class="top top03" style="padding: 32px 0 0px 0;" @click="switchIndex">
  5. <div title="进入数据消费平台"
  6. style="cursor: pointer;height: 38px;width: 38px;text-align: center;float: right;margin: 0px 49px 0px 10px;"
  7. @click.stop="toAdmin"><img src="../../assets/image/toAdmin.png">
  8. </div>
  9. <div title="返回主视图"
  10. style="cursor: pointer;height: 38px;width: 38px;text-align: center;float: right;margin: 0 10px;"
  11. @click.stop="backMasterViewByFac"><img src="../../assets/image/view.png">
  12. </div>
  13. <div title="AI分析" ref="icon_btn_ai"
  14. style="cursor: pointer;height: 38px;width: 38px;float: right;margin: 0 10px;" @click.stop="OpenAI">
  15. <img src="../../assets/image/icon-ai1.png">
  16. </div>
  17. </div>
  18. <div class="bg20"></div>
  19. <div v-if="isShowAI" class="abs aiPanel" @click.stop="void(0)">
  20. <div class="triangle2"></div>
  21. <div class="triangle"></div>
  22. <div v-for="(p,index) in compProctList" style="margin-top:10px">
  23. <span style="margin-right: 5px;">产线</span><el-select style="width: 100px;" v-model="p.ai_prouct_no"><el-option v-for="item in cxList" :key="item.index" :label="item.name" :value="item.index"></el-option> </el-select>
  24. <span style="margin-right: 5px;margin-left: 5px;">时段</span><el-date-picker v-model="p.compDateHour1" type="datetime" date-format="YYYY-MM-DD" time-format="HH" format="YYYY-MM-DD HH" :value-format="'YYYY-MM-DD HH'" placeholder="开始时间"></el-date-picker>
  25. <!--<span style="margin-right: 5px;margin-left: 5px;">时点</span><el-select style="width: 100px;" v-model="p.compDateHour1"><el-option v-for="item in hourList" :key="item.code" :label="item.name" :value="item.code"></el-option> </el-select>-->
  26. <span> 到 </span>
  27. <el-date-picker v-model="p.compDateHour2" type="datetime" date-format="YYYY-MM-DD" time-format="HH" format="YYYY-MM-DD HH" :value-format="'YYYY-MM-DD HH'" placeholder="结束时间"></el-date-picker>
  28. <!--<el-select style="width: 100px;" v-model="p.compDateHour2"><el-option v-for="item in hourList" :key="item.code" :label="item.name" :value="item.code"></el-option> </el-select>
  29. <el-button v-if="index==compProctList.length-1 && compProctList.length<cxList.length" style="margin:10px" @click="addAILine" title="添加产线">+</el-button>
  30. <el-button v-else style="margin:10px" @click="removeAILine(index)" title="移除该产线">-</el-button>-->
  31. </div>
  32. <div v-if="compProctList.length>1 " style="text-align: center;">
  33. <el-button style="margin:10px" @click.stop="compAILine">AI工艺比对分析</el-button>
  34. <el-button style="margin:10px" @click.stop="HideWindow">关闭</el-button>
  35. </div>
  36. </div>
  37. <template v-if="showIndexData=='index'">
  38. <div class="abs" style="left:50%;top:10%;width: 210px;margin-left:-105px;text-align: center;">
  39. <div>请选择要查看的产线</div>
  40. <div class="cx">
  41. <span @click="switchCX(item.index)" :class="item.active?'btn active':'btn'" v-for="item in cxList" :style="{backgroundImage: item.active?`url(${btnFrontBg})`:''}">{{ item.name }}</span>
  42. <div @click="switchCX(0)" :class="currentCXNo==0?'btn active':'btn'" :style="{width:'94%', backgroundImage: currentCXNo==0 ?`url(${btnFrontBg})`:''}">全部</div>
  43. </div>
  44. </div>
  45. <div class="abs title_row" style="left: 3%;top:6%;font-weight: normal;">
  46. <div class="title_left_line"></div><span>产线状态</span><span style="color:#27e6ff">(今日)</span>
  47. </div>
  48. <div class="abs data_row" style="left: 3%;top:8%;font-weight: normal;">
  49. <div style="margin-left: 10px;"><table cellspacing="0">
  50. <tbody>
  51. <tr style="background-color:transparent">
  52. <td style="border:0">
  53. <div class="littleFont">产线<span style="color:#27e6ff">(开动)</span></div>
  54. <div style="font-size: 32px;">
  55. <NumberAnimation :value="ReplaceNull(deviceStatData.status.openProd,'0')" :decimal="0" />
  56. <span style="font-size: 12px;">条</span>
  57. </div>
  58. </td>
  59. <td style="border:0;padding-left: 40px;">
  60. <div class="littleFont">设备<span style="color:#27e6ff">(开机)</span></div>
  61. <div style="font-size:24px;height: 38px;line-height: 48px;color: #27e6ff;">
  62. <NumberAnimation :value="ReplaceNull(deviceStatData.status.open,'0')" :decimal="0" />
  63. <span style="font-size: 12px;"> 台</span>
  64. </div>
  65. </td>
  66. <td style="border:0;padding-left: 40px;">
  67. <div class="littleFont">设备<span style="color:#27e6ff">(总数)</span></div>
  68. <div style="font-size:24px;height: 38px;line-height: 48px;color: #27e6ff;">
  69. <NumberAnimation :value="ReplaceNull(deviceStatData.status.total,'0')" :decimal="0" />
  70. <span style="font-size: 12px;"> 台</span>
  71. </div>
  72. </td>
  73. </tr>
  74. </tbody>
  75. </table></div>
  76. </div>
  77. <div class="abs title_row" style="left: auto;top:6%;font-weight: normal;right: 14%;"><div class="title_left_line"></div><span>生产情况</span><span style="color:#27e6ff">(今日)</span></div>
  78. <div class="abs data_row" style="left: auto;top:8%;font-weight: normal;right: 3%;">
  79. <div style="margin-left: 10px;"><table cellspacing="0">
  80. <tbody>
  81. <tr style="background-color:transparent">
  82. <td style="border:0">
  83. <div class="littleFont">白坯<span style="color:#27e6ff">(投放量)</span></div>
  84. <div style="font-size: 32px;">
  85. <NumberAnimation :value="ReplaceNull(deviceStatData.status.baiPei,'0')" :decimal="0" />
  86. <span style="font-size: 12px;">米</span>
  87. </div>
  88. </td>
  89. <td style="border:0;padding-left: 40px;">
  90. <div class="littleFont">产量<span style="color:#27e6ff">(米数)</span></div>
  91. <div style="font-size:24px;height: 38px;line-height: 48px;color: #27e6ff;">
  92. <NumberAnimation :value="ReplaceNull(deviceStatData.status.length,'0')" :decimal="0" />
  93. <span style="font-size: 12px;"> 米</span>
  94. </div>
  95. </td>
  96. <td style="border:0;padding-left: 40px;">
  97. <div class="littleFont">产量<span style="color:#27e6ff">(重量)</span></div>
  98. <div style="font-size:24px;height: 38px;line-height: 48px;color: #27e6ff;">
  99. <NumberAnimation :value="ReplaceNull(deviceStatData.status.weight,'0')" :decimal="2" />
  100. <span style="font-size: 12px;"> 吨</span>
  101. </div>
  102. </td>
  103. </tr>
  104. </tbody>
  105. </table></div>
  106. </div>
  107. <div class="abs bottompanel">
  108. <div style="width: 15%;height:calc(184px*var(--hRate));display: flex;">
  109. <div style="width: 70%;height: 100%;border-right: 1px solid #1a7c90;">
  110. <div class="title_row" style="font-weight: normal;margin-top: 10px;"><span style="font-size: 48px;letter-spacing: 5px;margin-right: 20%;">{{currentCXNo==0?'全部':currentCXNo+'号'}}</span><span style="color:#fff;line-height: 48px;">产线</span></div>
  111. <div style="padding-left: 5px;color: #27e6ff;margin-top: calc(52px*var(--hRate));width: 88%;">
  112. <div style="color: #fff;"><span>开机数</span><span style="float: right;">总数</span></div>
  113. <div style="font-size: 22px;margin-top: calc(16px*var(--hRate));"><span>{{ ReplaceNull(effInfo.open,'-') }}<span class="littleFont">台</span></span>
  114. <span style="float: right;">{{ ReplaceNull(effInfo.total,'-') }}<span class="littleFont">台</span></span>
  115. </div>
  116. <div style="position: relative;margin-top: calc(16px*var(--hRate));">
  117. <div class="abs fac_progress_value" :style="{width:(effInfo.open/effInfo.total*100)+'%'}"></div>
  118. <div class="abs fac_progress" style="background-color: #5f686e;"></div>
  119. </div>
  120. </div>
  121. </div>
  122. <div style="width: 30%;height: 100%;margin-left: 4%;">
  123. <div style="color: #fff;"><span>单位能耗</span></div>
  124. <div style="font-size: 22px;margin-top: calc(16px*var(--hRate));;color: red;">
  125. <span>{{ ReplaceNull(effInfo.energy,'-') }}<span class="littleFont">元/米</span></span>
  126. </div>
  127. <div style="color: #fff;margin-top: calc(26px*var(--hRate));"><span>开机率</span></div>
  128. <div style="font-size: 22px;margin-top: calc(16px*var(--hRate));color:#27e6ff ;">
  129. <span>{{ ReplaceNull(effInfo.ratio,'-') }}<span class="littleFont">%</span></span>
  130. </div>
  131. </div>
  132. </div>
  133. <div :style="{width: '26%',marginLeft:'1%',marginRight: isFullScreen?'2%':'0'}">
  134. <div class="title_row" style="font-weight: normal;line-height: 30px;"><div class="title_left_line" style="margin-top: 7px;"></div><span>生产效率</span><span style="color:#27e6ff">(今日)</span></div>
  135. <div class="data_row scxl_block">
  136. <div :style="{padding: '10px',width: isFullScreen?'96%':'89%'}"><table cellspacing="0" style="width: 100%;font-size: 14px;text-align: center;">
  137. <thead>
  138. <tr style="font-weight:normal;color: #1fc1d7;background-color: #2dbcd436;">
  139. <td style="border:0">班组</td>
  140. <td style="border:0">生产时间(H)</td>
  141. <td style="border:0">已生产数(米)</td>
  142. <td style="border:0">总重量(吨)</td>
  143. <!--<td style="border:0">稼动率(%)</td>-->
  144. </tr>
  145. </thead>
  146. <tbody>
  147. <tr style="font-weight:normal;background-color:transparent;color: #ffffff;font-size: 14px;">
  148. <td style="border:0">A班</td>
  149. <td style="border:0">
  150. <NumberAnimation :value="ReplaceNull(effInfo.timeA,'0')" :decimal="0" />
  151. </td>
  152. <td style="border:0">
  153. <NumberAnimation :value="ReplaceNull(effInfo.lengthA,'0')" :decimal="0" />
  154. </td>
  155. <td style="border:0">
  156. <NumberAnimation :value="ReplaceNull(effInfo.weightA,'0')" :decimal="2" />
  157. </td>
  158. <!--<td style="border:0">{{ ReplaceNull((effInfo.effA*100).toFixed(0),'-') }}%</td>-->
  159. </tr>
  160. <tr style="font-weight:normal;background-color:transparent;color: #ffffff;background-color: #2dbcd436;font-size: 14px;">
  161. <td style="border:0">B班</td>
  162. <td style="border:0">
  163. <NumberAnimation :value="ReplaceNull(effInfo.timeB,'0')" :decimal="0" />
  164. </td>
  165. <td style="border:0">
  166. <NumberAnimation :value="ReplaceNull(effInfo.lengthB,'0')" :decimal="0" />
  167. </td>
  168. <td style="border:0">
  169. <NumberAnimation :value="ReplaceNull(effInfo.weightB,'0')" :decimal="2" />
  170. </td>
  171. <!--<td style="border:0">{{ ReplaceNull((effInfo.effB*100).toFixed(0),'-') }}%</td>-->
  172. </tr>
  173. </tbody>
  174. </table>
  175. <div style="width: 100%;display: flex;margin-top: calc(42px*var(--hRate));font-size: 14px;justify-content: center;text-align: center;" >
  176. <div style="width: 50%;">
  177. <div style="color: #fff;"><span>米数</span></div>
  178. <div style="font-size: 22px;color:#27e6ff">
  179. <span>
  180. <NumberAnimation :value="ReplaceNull(effInfo.length,'0')" :decimal="0" />
  181. <span class="littleFont">米</span>
  182. </span>
  183. </div>
  184. </div>
  185. <div style="width: 50%;">
  186. <div style="color: #fff;"><span>重量</span></div>
  187. <div style="font-size: 22px;color:#27e6ff">
  188. <span>
  189. <NumberAnimation :value="ReplaceNull(effInfo.weight,'0')" :decimal="2" />
  190. <span class="littleFont">吨</span>
  191. </span>
  192. </div>
  193. </div>
  194. </div>
  195. </div>
  196. </div>
  197. </div>
  198. <div style="width: 26%;margin-right: 2%;">
  199. <div class="title_row" style="line-height: 30px;"><div class="title_left_line" style="margin-top: 7px;"></div>
  200. <span>生产趋势</span><span style="color:#27e6ff">(30天)</span>
  201. <span style="margin-left: auto !important;">
  202. <span :class="buttonCode1=='Length'?'fac_btn active':'fac_btn'" @click="LoadSCLine('Length')">米数</span>
  203. <span :class="buttonCode1=='Weight'?'fac_btn active':'fac_btn'" @click="LoadSCLine('Weight')">重量</span>
  204. </span>
  205. </div>
  206. <div :class="isFullScreen?'data_row sc_qushi_block_full':'data_row sc_qushi_block'" ref="echarts_sc_qushi"></div>
  207. </div>
  208. <div style="width: 26%;">
  209. <div class="title_row" style="line-height: 30px;"><div class="title_left_line" style="margin-top: 7px;"></div>
  210. <span>能耗趋势</span><span style="color:#27e6ff">(30天)</span>
  211. <span style="margin-left: auto !important;">
  212. <span :class="buttonCode2=='price'?'fac_btn active':'fac_btn'" @click="LoadUsedLine('price')">折算</span>
  213. <span :class="buttonCode2=='electricity'?'fac_btn active':'fac_btn'" @click="LoadUsedLine('electricity')">电</span>
  214. <span :class="buttonCode2=='steam'?'fac_btn active':'fac_btn'" @click="LoadUsedLine('steam')">气</span>
  215. <span :class="buttonCode2=='water'?'fac_btn active':'fac_btn'" @click="LoadUsedLine('water')">水</span>
  216. </span>
  217. </div>
  218. <div :class="isFullScreen?'data_row used_qushi_block_full':'data_row used_qushi_block'" ref="echarts_used_qushi"></div>
  219. </div>
  220. </div>
  221. </template>
  222. </div>
  223. </template>
  224. <script>
  225. import { ref ,watch,onUnmounted,onMounted} from 'vue';
  226. import {useRouter} from 'vue-router';
  227. import api from "@/api/system";
  228. import * as echarts from 'echarts';
  229. import { ElDatePicker,ElMessage } from 'element-plus';
  230. import 'element-plus/dist/index.css'; // 确保导入样式文件
  231. import NumberAnimation from './NumberAnimation.vue';
  232. export default {
  233. components: {
  234. NumberAnimation
  235. },
  236. props:{
  237. clickEvent:{
  238. type:Object,
  239. required: true,
  240. default:{}
  241. },
  242. in03ModelLoadState:{
  243. type:Boolean
  244. },
  245. userTimeout:{
  246. type:Boolean
  247. },
  248. userRole:{
  249. type:String
  250. }
  251. },
  252. setup(props,{emit}) {
  253. const router = useRouter();
  254. const isShowAI = ref(false);
  255. const icon_btn_ai = ref(null);
  256. const compProctList=ref([{
  257. ai_prouct_no:'',
  258. compDate:new Date().Format("yyyy-MM-dd"),
  259. compDateHour1:new Date(new Date().getTime() - 3600000).Format("yyyy-MM-dd hh")+":00:00",
  260. compDateHour2:new Date(new Date().getTime() - 3600000).Format("yyyy-MM-dd hh")+":00:00"
  261. },{
  262. ai_prouct_no:'',
  263. compDate:new Date().Format("yyyy-MM-dd"),
  264. compDateHour1:new Date(new Date().getTime() - 3600000).Format("yyyy-MM-dd hh")+":00:00",
  265. compDateHour2:new Date(new Date().getTime() - 3600000).Format("yyyy-MM-dd hh")+":00:00"
  266. }]);
  267. const hourList=ref([]);
  268. let lines={};
  269. let oldLineState={};
  270. let deviceStatData=ref({'status':{},'eff':[]});
  271. const effInfo = ref({});
  272. const dataTypeUnit={
  273. 'Length':'米',
  274. 'Weight':'吨',
  275. 'price':'元/米',
  276. 'electricity':'kwh',
  277. 'steam':'GJ',
  278. 'water':'m³',
  279. };
  280. let updateLineStateTimer = null;
  281. const showIndexData=ref('');
  282. const currentCXNo = ref(0);
  283. const buttonCode1=ref('');
  284. const buttonCode2 = ref('');
  285. const echarts_sc_qushi = ref(null);
  286. const echarts_used_qushi = ref(null);
  287. let echartsEleIns_1=null;
  288. let echartsEleIns_0=null;
  289. const isFullScreen = ref(false); //是否全屏模式
  290. let lineArrow001=null;
  291. let lineArrow002=null;
  292. let getDataTimer = null;
  293. let lineCurr = null;
  294. let lineMarkerLoaded = false;
  295. //产线列表
  296. const cxList=ref([
  297. {"name":1,active:false,index:1},
  298. {"name":2,active:false,index:2},
  299. {"name":3,active:false,index:3},
  300. {"name":4,active:false,index:4},
  301. {"name":5,active:false,index:5},
  302. {"name":6,active:false,index:6},
  303. {"name":7,active:false,index:7},
  304. {"name":8,active:false,index:8},
  305. ])
  306. let compMarkerts={};
  307. //产线提示框位置,元素顺序为默认位置,左位置和右位置
  308. const markerPos=[
  309. [[-140, 89, 13],[-130, 89, 11],[-80, 89, 11]],
  310. [[-130, 77, 13],[-130, 77, 11],[-80, 77, 11]],
  311. [[-120, 66, 13],[-130, 66, 11],[-80, 66, 11]],
  312. [[-110, 55, 13],[-130, 55, 11],[-80, 55, 11]],
  313. [[-101, 44, 13],[-130, 44, 11],[-80, 44, 11]],
  314. [[-94, 33, 13],[-130, 33, 11],[-80, 33, 11]],
  315. [[-87, 22, 13],[-130, 22, 11],[-80, 22, 11]],
  316. [[-80, 11, 13],[-130, 11, 11],[-80, 11, 11]]
  317. ];
  318. //温度速度提示框位置,元素顺序为默认位置,左位置和右位置
  319. const tmpMarkerPos=[
  320. [-198, 89, 60],
  321. [-198, 77, 60],
  322. [-198, 66, 60],
  323. [-198, 55, 60],
  324. [-198, 44, 60],
  325. [-198, 33, 60],
  326. [-198, 22, 60],
  327. [-198, 11, 60],
  328. ];
  329. //订单花色提示框位置,元素顺序为默认位置,左位置和右位置
  330. const orderMarkerPos=[
  331. [-30, 89, 13],
  332. [-30, 77, 13],
  333. [-30, 66, 13],
  334. [-30, 55, 13],
  335. [-30, 44, 13],
  336. [-30, 33, 13],
  337. [-30, 22, 13],
  338. [-30, 11, 13],
  339. ];
  340. const btnFrontBg = require('@/assets/image/nav_btn_front.png');
  341. watch(() => props.clickEvent, newVal=> {
  342. if(newVal==null){
  343. return;
  344. }
  345. //console.log('印花模型点击:',newVal)
  346. },{deep:true,immediate:true})
  347. watch(() => props.in03ModelLoadState, newVal=> {
  348. if(newVal){
  349. console.log('印花模型加载状态:',newVal)
  350. clearTimeout(getDataTimer);
  351. setTimeout(() => {
  352. DataFull.GetData();
  353. }, 100);
  354. init();
  355. }
  356. },{deep:true,immediate:true})
  357. watch(() => props.userTimeout, newVal=> {
  358. console.log('userTimeout value:',newVal)
  359. if(newVal){
  360. //if (!AutoPlayer.value && window.CurrentTargetType=='IN02') switchAutoPlayer(); //开启自动漫游
  361. }
  362. },{deep:true,immediate:true})
  363. watch(() => props.userRole, newVal=> {
  364. showIndexData.value = newVal;
  365. },{deep:true,immediate:true})
  366. let DataFull={
  367. GetData:function(){
  368. getDataTimer = setTimeout(function () {
  369. //每1分钟主动查询一次数据
  370. DataFull.GetData();
  371. }, 60*1000);
  372. api.Get03Data().then((res)=>{
  373. if(window.CurrentTargetType!='IN03') return;
  374. if (res == null || player.Native==null) {
  375. return
  376. }
  377. if(res.code!=200){
  378. return;
  379. }
  380. deviceStatData.value = res.data;
  381. effInfo.value = res.data.eff[currentCXNo.value]; //产线信息
  382. LoadSCLine(buttonCode1.value=='' ? 'Length':buttonCode1.value);
  383. LoadUsedLine(buttonCode2.value==''?'price':buttonCode2.value);
  384. lineCurr = res.data.curr||[];
  385. showLineInfo();
  386. });
  387. }
  388. }
  389. async function init(){
  390. backMasterViewByFac();
  391. (async()=>{
  392. let marklst = await player.Native.GisMarker.getMarkerList();
  393. if(marklst!=null){
  394. for(var i=0;i<marklst.length;i++){
  395. if(player!=null && player.Native!=null)player.Native.GisMarker.destroy(marklst[i].id)
  396. }
  397. }
  398. })();
  399. var rootItem = await player.Native.ModelTree.getRootItems();
  400. var rootObj=null;
  401. for (var i = 0; i < rootItem.length; i++) {
  402. if(rootItem[i].name=="T_03"){
  403. rootObj = rootItem[i]
  404. break;
  405. }
  406. }
  407. if(rootObj==null){
  408. console.log('未找到该模型的根节点')
  409. window.location.reload();
  410. return;
  411. }
  412. var items = await player.Native.ModelTree.getSubItems(rootObj.item)
  413. for(let i=0;i<items.length;i++){
  414. if(items[i].name=='RootNode') rootObj = items[i];
  415. }
  416. if(window.LINELIST==null){
  417. //获取产线列表
  418. items = await player.Native.ModelTree.getSubItems(rootObj.item);
  419. items.forEach(ele=>{
  420. if(ele.name.indexOf('#线')>-1) lines[ele.name] = ele.item;
  421. //if(ele.name=='Line001') lineArrow001=ele;
  422. //if(ele.name=='Line002') lineArrow002=ele;
  423. })
  424. window.LINELIST = lines;
  425. }
  426. drawLineNo(rootObj);
  427. updateLineState();
  428. if(window.IN03Markers==null){
  429. window.IN03Markers = [];
  430. //初始化产线名称标记
  431. var rootItem = await player.Native.ModelTree.getRootItems();
  432. var rootObj=null;
  433. for (var i = 0; i < rootItem.length; i++) {
  434. if(rootItem[i].name=="T_03"){
  435. rootObj = rootItem[i]
  436. break;
  437. }
  438. }
  439. if(rootObj==null){
  440. console.log('未找到该模型的根节点')
  441. return;
  442. }
  443. return;
  444. let t1 = new Date().getTime();
  445. var items = await player.Native.ModelTree.getSubItems(rootObj.item)
  446. if(items.length==1 && items[0].name=='RootNode') rootObj = items[0];
  447. //获取产线列表
  448. items = await player.Native.ModelTree.getSubItems(rootObj.item);
  449. let markersDef = IN345MARKERS['IN03'];
  450. for(let i=0; i<items.length; i++){
  451. if(items[i].name.indexOf('#线')==-1) continue;
  452. let curLineDef = markersDef[items[i].name];
  453. if(curLineDef==null ||curLineDef.length==0) continue;
  454. var findName = curLineDef[curLineDef.length-1];
  455. let object = await player.Native.ModelTree.findItemByName(findName, items[i].item,true,3);
  456. if( object!=null ){
  457. var xyz = await player.Native.ModelTree.getItemShapeInfo(object.item);
  458. var xyz2 = [(xyz.aabb[0][0]) , (xyz.aabb[0][1] ) , (xyz.aabb[0][2]) ];
  459. // 创建设备编号标记
  460. var options = {
  461. "text": items[i].name,
  462. "visible": true,
  463. //"maxLod": 110,
  464. //"minLod": 0.1,
  465. "textFontSize": 15,
  466. "textColor": parseInt("0x000fffff"),
  467. "userData":"IN03"
  468. };
  469. options.pos = [xyz2[0]-7, xyz2[1]+2, 15]
  470. var markPtr = await player.Native.GisMarker.create(options);
  471. player.Native.GisMarker.update(markPtr, options);
  472. window.IN03Markers.push(markPtr);
  473. }
  474. }
  475. console.log('--------创建标记总耗时:',new Date().getTime()-t1)
  476. }
  477. }
  478. //绘制编号
  479. async function drawLineNo(rootObj){
  480. if(player!=null && player.Native!=null){
  481. (async()=>{
  482. let marklst = await player.Native.GisMarker.getMarkerList();
  483. if(marklst!=null){
  484. for(var i=0;i<marklst.length;i++){
  485. if(player!=null && player.Native!=null)player.Native.GisMarker.destroy(marklst[i].id)
  486. }
  487. }
  488. //隐藏模型产线编号
  489. let imgId = await player.Native.GisMarker.loadImage("data://icon/rz-new/pp.png");
  490. window.IN03Markers = {};
  491. for(let i=0;i<8;i++){
  492. player.Native.ModelTree.findItemByName("Text00"+(i+1), rootObj.item,true,3).then(res=>{
  493. player.Native.ModelTree.setItemVisible([res.item],false);
  494. });
  495. player.Native.ModelTree.findItemByName("Plane0"+(11+i+1), rootObj.item,true,3).then(res=>{
  496. player.Native.ModelTree.setItemVisible([res.item],false);
  497. });
  498. let line = i+1;
  499. //产线编号标记
  500. var options = {
  501. "text": line,
  502. // "parentNode": parentObj.item,
  503. "visible": true,
  504. //"maxLod": 350,
  505. //"minLod": 0,
  506. "textFontSize": 18,
  507. // "size": [48, 48],
  508. "textColor": parseInt("0xFFFFFFFF"),
  509. "backgroundColor": parseInt("0x00000050"),
  510. "contentPadding": [5, 5, 5, 5],
  511. "nodeOffset": [0, -24],
  512. "userData": "line|"+line
  513. };
  514. options.pos = markerPos[i][0];
  515. //options.parentNode=tmp.item;
  516. options.imgId = imgId
  517. options.imgSize = [16, 24];
  518. player.Native.GisMarker.create(options).then(markPtr=>{
  519. window.IN03Markers[markPtr] = options;
  520. });
  521. //产线温度、速度标记
  522. let optTmp = JSON.parse(JSON.stringify(options));
  523. optTmp.pos = tmpMarkerPos[i];
  524. optTmp.userData = "tmp|"+line;
  525. optTmp.textFontSize = "14";
  526. optTmp.imgSize = [316, 18];
  527. optTmp.textColor = parseInt("0xe5cd10FF");
  528. player.Native.GisMarker.create(optTmp).then(markPtr=>{
  529. window.IN03Markers[markPtr] = optTmp;
  530. });
  531. //产线订单花色标记.1\2号产线没有
  532. if(line>2){
  533. let optOrder = JSON.parse(JSON.stringify(options));
  534. optOrder.pos = orderMarkerPos[i];
  535. optOrder.userData = "order|"+line;
  536. optOrder.textFontSize = "14";
  537. optOrder.imgSize = [300, 18];
  538. optOrder.textColor = parseInt("0xe5cd10FF");
  539. player.Native.GisMarker.create(optOrder).then(markPtr=>{
  540. window.IN03Markers[markPtr] = optOrder;
  541. });
  542. }
  543. }
  544. //标记点击
  545. player.Native.GisMarker.EventGisMarkerLClick.connect((event) => {
  546. let markerLClickObj = window.IN03Markers[event.markerId];
  547. if(markerLClickObj==null){
  548. //emit('markerLClick',{});
  549. markerLClickObj = compMarkerts[event.markerId];
  550. if(markerLClickObj!=null){
  551. var params = JSON.stringify(compProctList.value);
  552. emit('OpenIframeWin',{class:'newwin in03AiCompWin',src:'/in03-ai-comp#'+params,title:'AI工艺比对详情'});
  553. }
  554. return;
  555. }
  556. setTimeout(function(dataType){
  557. if(dataType==null) return;
  558. dataType = dataType.split("|");
  559. if(dataType[0]=='line') switchCX(dataType[1]);
  560. },100,markerLClickObj["userData"]);
  561. //emit('markerLClick',markerLClickObj);
  562. return;
  563. });
  564. //加载产线数据
  565. showLineInfo();
  566. })();
  567. }
  568. }
  569. //显示产线生产信息
  570. //4楼左边显示产线的定型温度dxTmp、烫光温度tgTmp以及速度speed
  571. //4楼楼右边显示产线的订单号order和花色color
  572. async function showLineInfo(){
  573. if(player==null || player.Native==null || lineCurr==null) return;
  574. let lineDataInfo = {};
  575. lineCurr.forEach(function(item){
  576. lineDataInfo[item.line] = item;
  577. });
  578. let getCnt = 0;
  579. for(let markerPtr in window.IN03Markers){
  580. let markerOpt = window.IN03Markers[markerPtr];
  581. if(markerOpt["userData"]==null) continue;
  582. let datatype = markerOpt["userData"].split("|")[0];
  583. if(datatype=='line'){
  584. continue;
  585. }
  586. let line = markerOpt["userData"].split("|")[1];
  587. if(lineDataInfo[line]==null) continue;
  588. if(datatype=="tmp") {
  589. markerOpt["text"] = line+"# 定型温度:"+ (lineDataInfo[line].dxTmp||"--")+" 烫光温度:"+ (lineDataInfo[line].tgTmp||"--")+" 速度:"+ (lineDataInfo[line].speed||"--");
  590. }
  591. if(datatype=="order") {
  592. markerOpt["text"] = line+"# 订单号:"+ (lineDataInfo[line].order||"--")+" 花色:"+ (lineDataInfo[line].color||"--");
  593. }
  594. player.Native.GisMarker.update(markerPtr, markerOpt);
  595. getCnt++;
  596. }
  597. if(getCnt<14){
  598. setTimeout(() => {
  599. //未完全加载板板,重新加载
  600. showLineInfo()
  601. }, 200);
  602. }
  603. }
  604. //更新产线状态颜色
  605. async function updateLineState(){
  606. updateLineStateTimer = setTimeout(() => {
  607. updateLineState();
  608. }, 1000*60);
  609. if(window.LINELIST==null || player==null || player.Native==null) return;
  610. for(let name in window.LINELIST){
  611. if(oldLineState[name]==window.IN345LINE[name]) continue;
  612. if(!window.IN345LINE[name]){
  613. //产线未开
  614. await player.Native.ModelTree.setItemColor(window.LINELIST[name], parseInt("0x666666ff"), true)
  615. }else{
  616. //await player.Native.ModelTree.restoreItemColor(window.LINELIST[name]);//这句有BUG,会导致API调用失败,重而导致ws断开国家利益.暂时不用
  617. }
  618. }
  619. oldLineState = JSON.parse(JSON.stringify(window.IN345LINE));
  620. }
  621. function switchIndex(){
  622. if(showIndexData.value=='index'){
  623. router.push('/datamain');
  624. }else{
  625. router.push('/main');
  626. }
  627. }
  628. function switchCX(ind){
  629. currentCXNo.value = ind;
  630. let tmp=cxList.value;
  631. for (let index = 0; index < tmp.length; index++) {
  632. const element = tmp[index];
  633. if(element.index==ind) tmp[index].active = true;
  634. else tmp[index].active = false;
  635. }
  636. cxList.value = tmp;
  637. if(ind==0){
  638. emit('OpenIframeWin',{class:'newwin in03Win',src:'/in03-all-data',title:'染整段(产线数据)'});
  639. }
  640. effInfo.value = deviceStatData.value.eff[ind]; //产线信息
  641. LoadSCLine(buttonCode1.value);
  642. LoadUsedLine(buttonCode2.value);
  643. }
  644. function LoadSCLine(dataType) {
  645. buttonCode1.value = dataType;
  646. let data = deviceStatData.value.prodTrade;
  647. //生产趋势
  648. //获取数据中weight、aweight、bweight
  649. var t = echarts_sc_qushi.value;
  650. var dataLine = [];
  651. var times = [];
  652. var v_series = [];
  653. for (var i = 0; i < data.length; i++) {
  654. var tv = data[i]['date'];
  655. times.push([tv,data[i].tips]);
  656. let line = data[i].line[currentCXNo.value];
  657. if(dataType=='Length'){
  658. dataLine.push({value:line['length'],type:'Length'});
  659. }else{
  660. dataLine.push({value:line['weight'],type:'Weight'});
  661. }
  662. }
  663. if (dataLine.length == 0) {
  664. return
  665. }
  666. v_series.push({
  667. name: currentCXNo.value==0?"全部产线":currentCXNo.value+'号产线', type: 'line', //symbol: 'none',
  668. data: dataLine,
  669. itemStyle: {
  670. normal: {
  671. color: '#fbc16b', // 这里设置折线的颜色
  672. lineStyle: {
  673. color: '#fbc16b' // 这里同时设置线头的颜色
  674. }
  675. }
  676. }
  677. });
  678. var opt = {
  679. title: {
  680. show: false, //不显示标题
  681. text: '',
  682. textStyle: {
  683. color: "rgb(89, 151, 229)",
  684. fontWeight: "bold"
  685. },
  686. top: "0px",
  687. left: "30px"
  688. },
  689. legend: {
  690. show: true, //不显示图例
  691. inactiveColor: "#04417A",
  692. data: "",
  693. icon:"circle",
  694. textStyle: {color: "#fff"},
  695. top: "5",
  696. left: "10px",
  697. },
  698. tooltip: {
  699. trigger: 'axis',
  700. backgroundColor: '#fff',
  701. textStyle: {
  702. color: '#5c6c7c'
  703. },
  704. padding: [10, 10],
  705. extraCssText: 'box-shadow: 1px 0 2px 0 rgba(163,163,163,0.5)',
  706. formatter: function (params) {
  707. let xv='';
  708. let result = '';
  709. params.forEach(function (item) {
  710. xv=`${item.name}`;
  711. xv = xv.split(',')[1]+'<br>';
  712. result += ` ${item.marker} ${item.seriesName}: ${item.value}(`+dataTypeUnit[item.data.type]+`)<br/>`;
  713. });
  714. return xv+result;
  715. }
  716. },
  717. grid: {
  718. left: '5%',
  719. right: '5%',
  720. bottom: '0',
  721. top: '15%',
  722. containLabel: true
  723. },
  724. xAxis: {
  725. type: 'category',
  726. boundaryGap: true,
  727. axisLabel: {
  728. rotate: 45,
  729. color: "#26e2fb",
  730. formatter:function(v){
  731. return v.split(',')[0]
  732. }
  733. },
  734. axisTick:{
  735. show:false
  736. },
  737. data: times
  738. },
  739. yAxis: {
  740. type: 'value',
  741. nameTextStyle: {
  742. color: "#26e2fb"
  743. },
  744. axisLine:{
  745. show:true
  746. },
  747. axisLabel: {
  748. color: "#26e2fb"
  749. },
  750. splitLine: {
  751. lineStyle: {
  752. color: "#7DA7CD",
  753. type: "dashed",
  754. width: 1
  755. }
  756. }
  757. },
  758. series: v_series
  759. };
  760. if(echartsEleIns_1!=null){
  761. echartsEleIns_1.dispose();
  762. }
  763. echartsEleIns_1 = echarts.init(t);
  764. echartsEleIns_1.setOption(opt);
  765. }
  766. function LoadUsedLine(dataType){
  767. buttonCode2.value = dataType;
  768. let data = deviceStatData.value.energyTrade;
  769. //能耗趋势
  770. var t = echarts_used_qushi.value;
  771. var times = [];
  772. var v_series = [];
  773. var week_aefficiency = [];
  774. for (var i = 0; i < data.length; i++) {
  775. times.push([data[i]['date'],data[i].tips]);
  776. let line = data[i].line[currentCXNo.value];
  777. if(line[dataType]!=null) week_aefficiency.push({value:line[dataType],type:dataType});
  778. }
  779. if (week_aefficiency.length> 0) {
  780. v_series.push({
  781. name: currentCXNo.value==0?"全部产线":currentCXNo.value+'号产线', type: 'line', //symbol: 'none',
  782. data: week_aefficiency,
  783. symbol: 'circle', // 使用圆作为折点标记
  784. symbolSize: 6,
  785. itemStyle: {
  786. normal: {
  787. color: '#fbc16b', // 这里设置折线的颜色
  788. lineStyle: {
  789. color: '#fbc16b' // 这里同时设置线头的颜色
  790. }
  791. }
  792. },
  793. });
  794. }
  795. var opt = {
  796. title: {
  797. show: false, //不显示标题
  798. text: '',
  799. textStyle: {
  800. color: "rgb(89, 151, 229)",
  801. fontWeight: "bold"
  802. },
  803. top: "0px",
  804. left: "30px"
  805. },
  806. tooltip: {
  807. trigger: 'axis',
  808. formatter: function (params) {
  809. let xv='';
  810. let result = '';
  811. params.forEach(function (item) {
  812. xv=`${item.name}`;
  813. xv = xv.split(',')[1]+'<br>';
  814. result += ` ${item.marker} ${item.seriesName}: ${item.value}(`+dataTypeUnit[item.data.type]+`)<br/>`;
  815. });
  816. return xv+result;
  817. }
  818. },
  819. legend: {
  820. show: true, //不显示图例
  821. inactiveColor: "#04417A",
  822. data: "",
  823. textStyle: {color: "#fff"},
  824. top: "5",
  825. left:"10px",
  826. icon:"circle",
  827. },
  828. grid: {
  829. left: '3%',
  830. right: '5%',
  831. bottom: '0',
  832. top: '15%',
  833. containLabel: true
  834. },
  835. xAxis: {
  836. type: 'category',
  837. boundaryGap: false,
  838. axisLabel: {
  839. rotate: 45,
  840. color: "#26e2fb",
  841. formatter:function(v){
  842. return v.split(',')[0]
  843. }
  844. },
  845. axisLine:{
  846. show:true
  847. },
  848. axisTick:{
  849. show:false,
  850. },
  851. data: times
  852. },
  853. yAxis: {
  854. type: 'value',
  855. nameTextStyle: {
  856. color: "#26e2fb"
  857. },
  858. axisLine:{
  859. show:true
  860. },
  861. axisTick:{
  862. show:false,
  863. },
  864. axisLabel: {
  865. color: "#26e2fb"
  866. },
  867. splitLine: {
  868. lineStyle: {
  869. color: "#7DA7CD",
  870. type: "dashed",
  871. width: 1
  872. }
  873. }
  874. },
  875. series: v_series
  876. };
  877. if(echartsEleIns_0!=null){
  878. echartsEleIns_0.dispose();
  879. }
  880. echartsEleIns_0 = echarts.init(t);
  881. echartsEleIns_0.setOption(opt);
  882. }
  883. function backMasterViewByFac(){
  884. if(player==null || player.Native==null) return;
  885. if(window.CurrentTargetType!='IN03') return
  886. if(BODY_H_RATE>0.9){
  887. //全屏模式下的视角
  888. player.Native.Camera.moveTo([-91.64839019242504, -186.23753805841608, 166.78946395819892],
  889. [-80.69618225097656,21.59876251220703,11.815500259399414],
  890. [0.0014405644117746175, 0.5652582237894268, 0.8249127621831281], 1);
  891. }else{
  892. //非全屏模式下的视角
  893. player.Native.Camera.moveTo([-96.28250048486545,-174.9589162690673,138.93124701014426],
  894. [ -87.68050285922813,21.819011918402026,11.68395414100361],
  895. [ 0.0013062340462677805,0.5429710874519466,0.8397503747804266], 1);
  896. }
  897. }
  898. function HideWindow(){
  899. if(isShowAI.value){
  900. player.Native.Camera.moveTo([-96.28250048486545,-174.9589162690673,138.93124701014426],
  901. [ -87.68050285922813,21.819011918402026,11.68395414100361],
  902. [ 0.0013062340462677805,0.5429710874519466,0.8397503747804266], 1);
  903. }
  904. isShowAI.value=false;
  905. for(var k in compMarkerts){
  906. if(player!=null && player.Native!=null)player.Native.GisMarker.destroy(k);
  907. }
  908. }
  909. //切换到数据消费后台
  910. function toAdmin(){
  911. window.open(process.env.VUE_APP_SSO+'?role='+(showIndexData=='index'?"producer":"manager"));
  912. }
  913. function OpenAI(){
  914. isShowAI.value=true;
  915. }
  916. function addAILine(){
  917. compProctList.value.push({
  918. ai_prouct_no:'',
  919. compDate:'',
  920. compDateHour1:'',
  921. compDateHour2:''
  922. });
  923. }
  924. function removeAILine(ind){
  925. let tmpList=[];
  926. for(let i=0;i<compProctList.value.length;i++){
  927. if(i!=ind){
  928. tmpList.push(compProctList.value[i]);
  929. }
  930. }
  931. compProctList.value = tmpList;
  932. }
  933. async function compAILine(){
  934. var lineNo1 = compProctList.value[0].ai_prouct_no*1;
  935. var lineNo2 = compProctList.value[1].ai_prouct_no*1;
  936. var v={
  937. line1:lineNo1,
  938. line2:lineNo2,
  939. s1:compProctList.value[0].compDateHour1,
  940. e1:compProctList.value[0].compDateHour2,
  941. s2:compProctList.value[1].compDateHour1,
  942. e2:compProctList.value[1].compDateHour2,
  943. };
  944. if(v.line1=='' || v.line2==''){
  945. ElMessage({
  946. message:'请选择需要分析的产线!',
  947. type:'error',
  948. customClass: 'custom-message'
  949. });
  950. return;
  951. }
  952. if(v.s1==''|| v.s2==''){
  953. ElMessage({
  954. message:'请选择需要分析的日期和时点!',
  955. type:'error',
  956. customClass: 'custom-message'
  957. });
  958. return;
  959. }
  960. if(v.s1.indexOf("00:00")==-1) v.s1=v.s1+":00:00"
  961. if(v.s2.indexOf("00:00")==-1) v.s2=v.s2+":00:00"
  962. if(v.e1=="") v.e1 = v.s1;
  963. if(v.e2=="") v.e2 = v.s2;
  964. if(v.e1.indexOf("00:00")==-1) v.e1=v.e1+":00:00"
  965. if(v.e2.indexOf("00:00")==-1) v.e2=v.e2+":00:00"
  966. if(lineNo1==lineNo2 && v.s1==v.s2 && v.e1==v.e2){
  967. ElMessage({
  968. message:'对比分析的产线、时段不能完全相同!',
  969. type:'error',
  970. customClass: 'custom-message'
  971. });
  972. return;
  973. }
  974. for(var k in compMarkerts){
  975. if(player!=null && player.Native!=null)player.Native.GisMarker.destroy(k);
  976. }
  977. var loadingMsg = ElMessage({
  978. message:'正在进行工艺分析中...',
  979. type:'info',
  980. customClass: 'custom-message',
  981. duration:0
  982. });
  983. compMarkerts = {};
  984. ///api/yr/compare?line1=1&line2=2&time1=2025-05-13%2008:00:00&time2=2025-05-13%2009:00:00
  985. fetch(process.env.VUE_APP_API+'/api/yr/compare', {
  986. method: 'POST', // 指定请求方法为POST
  987. headers: {
  988. 'Content-Type': 'application/json', // 设置请求头为JSON格式
  989. },
  990. body: JSON.stringify(v) // 将数据转换为JSON字符串作为请求体
  991. })
  992. .then(response => response.json()) // 解析JSON格式的响应数据
  993. .then(res => {
  994. loadingMsg.close();
  995. if(res.code!=200 || res.data==null){
  996. ElMessage({
  997. message:res.msg,
  998. type:'error',
  999. customClass: 'custom-message'
  1000. });
  1001. return;
  1002. }
  1003. var line1Data=res.data[0];
  1004. var line2Data=res.data[1];
  1005. MarkLineComper(line1Data,line2Data,v);
  1006. }).catch((error) => {
  1007. console.error('请求失败:', error);
  1008. });
  1009. }
  1010. function ReplaceNull(v,defaultValue){
  1011. if(v==null) return defaultValue;
  1012. return v;
  1013. }
  1014. async function MarkLineComper(line1Data,line2Data,v){
  1015. player.Native.Camera.moveTo([-94.61742308377592, -231.88112394996935, 91.21216074507522],
  1016. [-80.69618225097656,21.59876251220703,11.815500259399414],
  1017. [-0.0033254334820971166, 0.29907134022370024, 0.9542249603468546], 1);
  1018. var lineNo1 = compProctList.value[0].ai_prouct_no*1;
  1019. var lineNo2 = compProctList.value[1].ai_prouct_no*1;
  1020. line1Data['qz']=line1Data.qz||{};
  1021. line2Data['qz']=line2Data.qz||{};
  1022. line1Data['hz']=line1Data.qz||{};
  1023. line2Data['hz']=line2Data.qz||{};
  1024. var dt = "";
  1025. var imgid = await player.Native.GisMarker.loadImage(lineNo1==lineNo2?"data://icon/qietu/tip-m.png":"data://icon/qietu/tip-r.png");
  1026. var tipText = "";
  1027. if(lineNo1!=lineNo2){
  1028. if(v.s1==v.e1) dt = v.s1.substring(5).replace(":00:00","")+"时";
  1029. else if(v.s1.substring(0,10)==v.e1.substring(0,10)){
  1030. dt = v.s1.substring(5).replace(":00:00","")+"时 到 "+v.e1.substring(10).replace(":00:00","")+"时";
  1031. }
  1032. else{
  1033. dt = v.s1.substring(5).replace(":00:00","")+"时 到 "+v.e1.substring(5).replace(":00:00","")+"时";
  1034. }
  1035. /*
  1036. tipText = lineNo1+"#产线\r"+dt
  1037. +" \r 合格率(%):"+line1Data.rate
  1038. +" \r 重 量(T):"+line1Data.weight
  1039. +" \r 米 长(m):"+line1Data.length
  1040. +" \r 水(m3) :"+line1Data.water
  1041. +" \r 电(kWh) :"+line1Data.electricity
  1042. +" \r 气(GJ) :"+line1Data.gas
  1043. +" \r ...";
  1044. */
  1045. /*
  1046. tipText = lineNo1+"#产线\r"+dt
  1047. +" \r 产 能(米):"+ReplaceNull(line1Data.length,'-')
  1048. +"\r———————————————"
  1049. +" \r 定  型(次):"+ReplaceNull(line1Data.qz.dx,'-')
  1050. +" \r 前 高  梳(次):"+ReplaceNull(line1Data.qz.gs,'-')
  1051. +" \r 整 双棍烫光(次):"+ReplaceNull(line1Data.qz.tg,'-')
  1052. +" \r 双棍刷毛(次):"+ReplaceNull(line1Data.qz.sm,'-')
  1053. //+" \r 电(kWh) :"+(line1Data.qz.elect||'-')
  1054. //+" \r 热 油(GJ) :"+(line1Data.qz.oil||'-')
  1055. +" \r ...";
  1056. */
  1057. tipText = lineNo1+"#产线\r"+dt
  1058. +" \r 产 能(米):"+ReplaceNull(line1Data.length,'-')
  1059. +" \r 白坯投放(米):"+ReplaceNull(line1Data.bp,'-')
  1060. +" \r 电(kWh)   :"+ReplaceNull(line1Data.elect,'-')
  1061. +" \r 导热油(GJ) :"+ReplaceNull(line1Data.oil,'-')
  1062. +" \r ...";
  1063. }else{
  1064. var dt1="";
  1065. var dt2="";
  1066. var dtPadLen = 19;
  1067. var dataPadLen = 5;
  1068. var tipWidth = 400;
  1069. if(v.s1==v.e1) dt1 = v.s1.substring(5).replace(":00:00","")+"时";
  1070. else if(v.s1.substring(0,10)==v.e1.substring(0,10)){
  1071. dt1 = v.s1.substring(5).replace(":00:00","")+"时 到 "+v.e1.substring(11).replace(":00:00","")+"时";
  1072. dataPadLen = 7;
  1073. }else{
  1074. dt1 = v.s1.substring(5).replace(":00:00","")+"时 到 "+v.e1.substring(5).replace(":00:00","")+"时";
  1075. dtPadLen = 24;
  1076. dataPadLen = 12;
  1077. tipWidth = 500;
  1078. }
  1079. if(v.s2==v.e2) dt2 = v.s2.substring(5).replace(":00:00","")+"时";
  1080. else if(v.s2.substring(0,10)==v.e2.substring(0,10)){
  1081. dt2 = v.s2.substring(5).replace(":00:00","")+"时 到 "+v.e2.substring(11).replace(":00:00","")+"时";
  1082. }else{
  1083. dt2 = v.s2.substring(5).replace(":00:00","")+"时 到 "+v.e2.substring(5).replace(":00:00","")+"时";
  1084. }
  1085. /*
  1086. tipText = lineNo1+"#产线\r"+
  1087. dt1.padEnd(dtPadLen," ")+
  1088. dt2+"\r合格率(%):"+line1Data.rate.toString().padEnd(dataPadLen," ")+" 合格率(%):"+line2Data.rate
  1089. +" \r重 量(T):"+line1Data.weight.toString().padEnd(dataPadLen," ")+" 重 量(T):"+line2Data.weight.toString().padEnd(5," ")
  1090. +" \r米 长(m):"+line1Data.length.toString().padEnd(dataPadLen," ")+" 米 长(m):"+line2Data.length.toString().padEnd(5," ")
  1091. +" \r水(m3) :"+line1Data.water.toString().padEnd(dataPadLen," ")+" 水(m3) :"+line2Data.water.toString().padEnd(5," ")
  1092. +" \r电(kWh) :"+line1Data.electricity.toString().padEnd(dataPadLen," ")+" 电(kWh) :"+line2Data.electricity.toString().padEnd(5," ")
  1093. +" \r气(GJ) :"+line1Data.gas.toString().padEnd(dataPadLen," ")+" 气(GJ) :"+line2Data.gas.toString().padEnd(5," ");
  1094. */
  1095. /*
  1096. tipText = lineNo1+"#产线\r"+
  1097. dt1.padEnd(dtPadLen," ")+" "+dt2
  1098. +" \r产能(米):"+ReplaceNull(line1Data.length,'-')+" 产能(米):"+ReplaceNull(line2Data.length,'-')
  1099. +"\r————————————————————————"
  1100. +" \r 定  型(次):"+ReplaceNull(line1Data.qz.dx,'-').toString().padEnd(dataPadLen," ")+" 定  型(次):"+ReplaceNull(line2Data.qz.dx,'-').toString().padEnd(5," ")
  1101. +" \r前 高  梳(次):"+ReplaceNull(line1Data.qz.gs,'-').toString().padEnd(dataPadLen," ")+" 前 高  梳(次):"+ReplaceNull(line2Data.qz.gs,'-').toString().padEnd(5," ")
  1102. +" \r整 双棍烫光(次):"+ReplaceNull(line1Data.qz.tg,'-').toString().padEnd(dataPadLen," ")+" 整 双棍烫光(次):"+ReplaceNull(line2Data.qz.tg,'-').toString().padEnd(5," ")
  1103. +" \r 双棍刷毛(次):"+ReplaceNull(line1Data.qz.sm,'-').toString().padEnd(dataPadLen," ")+" 双棍刷毛(次):"+ReplaceNull(line2Data.qz.sm,'-').toString().padEnd(5," ")
  1104. //+" \r电(kWh) :"+line1Data.qz.elect.toString().padEnd(dataPadLen," ")+" 电(kWh) :"+line2Data.qz.elect.toString().padEnd(5," ")
  1105. //+" \r热 油(GJ) :"+line1Data.qz.oil.toString().padEnd(dataPadLen," ")+" 热 油(GJ) :"+line2Data.qz.oil.toString().padEnd(5," ");
  1106. +"\r ...";
  1107. }
  1108. */
  1109. tipText = lineNo1+"#产线\r"+
  1110. dt1.padEnd(dtPadLen," ")+" "+dt2
  1111. +" \r产 能(米):"+ReplaceNull(line1Data.length,'-')+" 产 能(米):"+ReplaceNull(line2Data.length,'-')
  1112. +" \r白坯投放(米):"+ReplaceNull(line1Data.bp,'-').toString().padEnd(dataPadLen," ")+" 白坯投放(米):"+ReplaceNull(line2Data.bp,'-').toString().padEnd(5," ")
  1113. +" \r电(kWh) :"+ReplaceNull(line1Data.elect,'-').toString().padEnd(dataPadLen," ")+" 电(kWh) :"+ReplaceNull(line2Data.elect,'-').toString().padEnd(5," ")
  1114. +" \r热 油(GJ) :"+ReplaceNull(line1Data.oil,'-').toString().padEnd(dataPadLen," ")+" 热 油(GJ) :"+ReplaceNull(line2Data.oil,'-').toString().padEnd(5," ")
  1115. +"\r ...";
  1116. }
  1117. var options = {
  1118. "text": tipText,
  1119. "visible": true,
  1120. //"maxLod": 130,
  1121. "minLod": 0,
  1122. "textFontSize":16,
  1123. "textColor": parseInt("0xffffffff"),
  1124. "contentPadding":[10,5,10,10],
  1125. "nodeOffset": lineNo1==lineNo2 ? [-130,-150]:[-200,-150],
  1126. "userData":"comp|"
  1127. };
  1128. options.pos = lineNo1==lineNo2 ? markerPos[lineNo1-1][0] : markerPos[lineNo1-1][1];
  1129. options.imgId = imgid
  1130. options.imgSize = lineNo1!=lineNo2 ? [260, 150] :[tipWidth, 150];
  1131. var ptr = await player.Native.GisMarker.create(options);
  1132. compMarkerts[ptr] = options;
  1133. if(lineNo1!=lineNo2){
  1134. if(v.s2==v.e2) dt = v.s2.substring(5).replace(":00:00","")+"时";
  1135. else if(v.s2.substring(0,10)==v.e2.substring(0,10)){
  1136. dt = v.s2.substring(5).replace(":00:00","")+"时 到 "+v.e2.substring(11).replace(":00:00","")+"时";
  1137. }
  1138. else{
  1139. dt = v.s2.substring(5).replace(":00:00","")+"时 到 "+v.e2.substring(5).replace(":00:00","")+"时";
  1140. }
  1141. /*
  1142. var tipText = lineNo2+"#产线\r"+dt
  1143. +" \r 产 能(米):"+ReplaceNull(line2Data.length,'-')
  1144. +"\r———————————————"
  1145. +" \r 定  型(次):"+ReplaceNull(line2Data.qz.dx,'-')
  1146. +" \r 前 高  梳(次):"+ReplaceNull(line2Data.qz.gs,'-')
  1147. +" \r 整 双棍烫光(次):"+ReplaceNull(line2Data.qz.tg,'-')
  1148. +" \r 双棍刷毛(次):"+ReplaceNull(line2Data.qz.sm,'-')
  1149. //+" \r 电(kWh) :"+(line2Data.qz.elect||'-')
  1150. //+" \r 热 油(GJ) :"+(line2Data.qz.oil||'-')
  1151. +" \r ...";
  1152. */
  1153. var tipText = lineNo2+"#产线\r"+dt
  1154. +" \r 产 能(米):"+ReplaceNull(line2Data.length,'-')
  1155. +" \r 白坯投放(米):"+ReplaceNull(line2Data.bp,'-')
  1156. +" \r 电(kWh)   :"+ReplaceNull(line2Data.elect,'-')
  1157. +" \r 导热油(GJ) :"+ReplaceNull(line2Data.oil,'-')
  1158. +" \r ...";
  1159. var options = {
  1160. "text": tipText,
  1161. "visible": true,
  1162. //"maxLod": 130,
  1163. "minLod": 0,
  1164. "textFontSize":16,
  1165. "textColor": parseInt("0xffffffff"),
  1166. "contentPadding":[10,5,10,10],
  1167. "nodeOffset":[-50,-150],
  1168. "userData":"comp|"
  1169. };
  1170. options.pos = markerPos[lineNo2-1][2];
  1171. var imgid = await player.Native.GisMarker.loadImage("data://icon/qietu/tip-l.png");
  1172. options.imgId = imgid
  1173. options.imgSize = [260, 150];
  1174. var ptr = await player.Native.GisMarker.create(options);
  1175. compMarkerts[ptr] = options;
  1176. }
  1177. }
  1178. onMounted(()=>{
  1179. if(BODY_H_RATE>0.9) isFullScreen.value=true;
  1180. else isFullScreen.value=false;
  1181. oldLineState = window.IN345LINE;//初始化产线初始状态
  1182. var hour1Opts = [];
  1183. for (var i = 0; i < 24; i++) {
  1184. if(i<10) hour1Opts.push({"name":'0'+i+'时',"code":'0'+i});
  1185. else hour1Opts.push({"name":i+'时',"code":i});
  1186. }
  1187. hourList.value = hour1Opts;
  1188. window.IN03Markers=null;
  1189. })
  1190. onUnmounted(()=>{
  1191. clearTimeout(getDataTimer);
  1192. clearTimeout(updateLineStateTimer);
  1193. if(player!=null && player.Native!=null){
  1194. (async()=>{
  1195. let marklst = await player.Native.GisMarker.getMarkerList();
  1196. if(marklst!=null){
  1197. for(var i=0;i<marklst.length;i++){
  1198. if(player!=null && player.Native!=null)player.Native.GisMarker.destroy(marklst[i].id)
  1199. }
  1200. }
  1201. })();
  1202. }
  1203. window.IN03Markers=null;
  1204. })
  1205. return{
  1206. HideWindow,
  1207. switchIndex,
  1208. echarts_sc_qushi,
  1209. echarts_used_qushi,
  1210. showIndexData,
  1211. deviceStatData,
  1212. effInfo,
  1213. btnFrontBg,
  1214. cxList,
  1215. currentCXNo,
  1216. switchCX,
  1217. buttonCode1,
  1218. buttonCode2,
  1219. isFullScreen,
  1220. LoadUsedLine,
  1221. LoadSCLine,
  1222. backMasterViewByFac,
  1223. toAdmin,
  1224. OpenAI,
  1225. isShowAI,
  1226. icon_btn_ai,
  1227. compProctList,
  1228. hourList,
  1229. addAILine,
  1230. removeAILine,
  1231. compAILine,
  1232. }
  1233. }
  1234. }
  1235. </script>
  1236. <style scope="IN03">
  1237. .custom-message {
  1238. top: 40% !important; /* 例如,将消息框定位到距离顶部50px */
  1239. left: 50% !important;
  1240. transform: translateX(-50%);
  1241. }
  1242. .el-popper{
  1243. z-index: 99999 !important;
  1244. }
  1245. .el-time-spinner__wrapper{
  1246. width: 100% !important;
  1247. }
  1248. .el-scrollbar:nth-of-type(2){
  1249. display: none !important;
  1250. }
  1251. .bg20{
  1252. z-index: 1; pointer-events: none;position: absolute;
  1253. top: calc(22px * var(--hRate));
  1254. left: 0;
  1255. width: 1877.54px;
  1256. height: 96%;
  1257. margin-left: 19px;
  1258. border: 2px solid #17666e;
  1259. border-top: 0px;
  1260. background:url('../../assets/image/bg.png');
  1261. -webkit-mask-image: linear-gradient(to top, #0b313de5 10%, transparent 20%,transparent 50%, #0b313de5 100%);
  1262. mask-image: linear-gradient(to top, #0b313de5 0%,transparent 15%,transparent 70%, #0b313de5 100%);
  1263. /*
  1264. background:url('../../assets/image/000.png');
  1265. -webkit-mask-image:radial-gradient(circle, transparent 26%, #95afc5 54%);
  1266. background:
  1267. repeating-linear-gradient(
  1268. 45deg,
  1269. #ccc 0, #ccc 10px,
  1270. transparent 10px, transparent 20px
  1271. ),
  1272. repeating-linear-gradient(
  1273. -45deg,
  1274. #ccc 0, #ccc 10px,
  1275. transparent 10px, transparent 20px
  1276. );
  1277. background-size: 20px 20px;
  1278. */
  1279. }
  1280. .bottompanel{
  1281. display: flex;
  1282. left: 3% !important;
  1283. top: calc(728px * var(--hRate)) !important;
  1284. width: 96%;
  1285. height: calc(360px * var(--hRate));
  1286. }
  1287. .cx{
  1288. width: 100%;
  1289. margin-top: 20px;
  1290. height: 110px;
  1291. color: #27e6ff;
  1292. font-size: 16px;
  1293. }
  1294. .cx .btn{
  1295. width: 40px;
  1296. height: 40px;
  1297. border: 1px solid #008899;
  1298. line-height: 40px;
  1299. text-align: center;
  1300. display: inline-block;
  1301. float: left;
  1302. margin: 5px;
  1303. border-radius: 5px;
  1304. cursor: pointer;
  1305. background-size: cover;
  1306. background-repeat: no-repeat;
  1307. background-position: center;
  1308. }
  1309. .cx .btn:hover,.cx .btn.active{
  1310. color: #ffffff;
  1311. border-color: #0cd7f0 !important;
  1312. }
  1313. .scxl_block{
  1314. font-weight: normal;
  1315. background-image: url('../../assets/image/t03_sc_bg.png');
  1316. height: calc(250px*var(--hRate));
  1317. width: auto;
  1318. background-size: contain;
  1319. background-repeat: no-repeat;
  1320. font-weight: normal !important;
  1321. }
  1322. .used_qushi_block,.sc_qushi_block{
  1323. height: calc(250px*var(--hRate));
  1324. width: 100%;
  1325. border: 1px solid #008899;
  1326. background: rgb(0 85 102 / 40%);
  1327. }
  1328. .used_qushi_block_full,.sc_qushi_block_full{
  1329. height: calc(230px*var(--hRate));
  1330. width: 100%;
  1331. border: 1px solid #008899;
  1332. background: rgb(0 85 102 / 40%);
  1333. }
  1334. .aiPanel{
  1335. width: 500px;
  1336. height: auto;
  1337. right: 2%;
  1338. top: 7.5% !important;
  1339. left: auto !important;
  1340. border: 1px solid #008899;
  1341. background: rgb(0 85 102 / 92%);
  1342. z-index: 10000 !important;
  1343. border-radius: 5px;
  1344. padding: 5px;
  1345. font-size: 14px;
  1346. }
  1347. .aiPanel .triangle{
  1348. width: 0;
  1349. height: 0;
  1350. position: absolute;
  1351. top: -10px;
  1352. right: 130px;
  1353. border-width: 6px;
  1354. border-style: solid;
  1355. border-color:transparent transparent rgb(0 85 102 / 92%) transparent ;
  1356. border-radius: 4rpx;
  1357. }
  1358. .aiPanel .triangle2{
  1359. width: 0;
  1360. height: 0;
  1361. position: absolute;
  1362. top: -12px;
  1363. right: 130px;
  1364. border-width: 6px;
  1365. border-style: solid;
  1366. border-color:transparent transparent #008899 transparent ;
  1367. border-radius: 4rpx;
  1368. }
  1369. </style>