Răsfoiți Sursa

添加AI分析功能

liling 3 săptămâni în urmă
părinte
comite
2ed9f3d23b

+ 9 - 0
src/api/system.js

@@ -92,6 +92,14 @@ function GetMaoGaoDetail(v){
         params: null
     })
 }
+//染整线工艺对比分析
+function GetYrGyComper(v){
+    return request({
+        url: `api/yr/compare`,
+        method: "get",
+        params: v
+    })
+}
 function getSystemCode(data) {
     return request({
         url: `/getSysParamList`,
@@ -131,4 +139,5 @@ export default {
     GetFacProduction,
     GetProductionLneInfo,
     Get03Data,
+    GetYrGyComper,
 }

BIN
src/assets/image/icon-ai1.png


BIN
src/assets/image/icon-ai2.png


BIN
src/assets/image/tip-l.png


BIN
src/assets/image/tip-m.png


BIN
src/assets/image/tip-r.png


BIN
src/assets/image/tip3.png


+ 4 - 4
src/pages/components/Fac.vue

@@ -253,7 +253,7 @@ export default {
                         */
                         return;
                     }
-                    FacStockData = res.data.stock||{};
+                    FacStockData = (res.data!=null && res.data.stock)||{};
                     deviceStatData.value = res.data;
                     LoadSCLine(buttonCode1.value=='' ? 'Length':buttonCode1.value);
                     LoadUsedLine(buttonCode2.value==''?'price':buttonCode2.value);
@@ -294,7 +294,7 @@ export default {
                                         continue
                                     }
                                     */
-                                    dataText = dataText.replace("{"+attr+"}",dataMap[attr].toString().padEnd(6," "));
+                                    dataText = dataText.replace("{"+attr+"}",dataMap[attr].toString().padEnd(7," "));
                                 }
                                 //更新GIS标记内容
                                 opt["text"]=dataText;
@@ -348,7 +348,7 @@ export default {
                 options.pos =[78.97850799560547, -7.938839912414551, 31.4000244140625];// [obj02Aabb.aabb[0][0], obj02Aabb.aabb[0][1]-30, obj02Aabb.aabb[0][2]+45];
                 //options.parentNode=tmp.item;
                 options.imgId = imgid
-                options.imgSize = [240, 140];
+                options.imgSize = [265, 140];
                 var markPtr = await player.Native.GisMarker.create(options);
                 MarkerMapFac["FAC"][markPtr]=options;
                 //await player.Native.GisMarker.update(markPtr, options);
@@ -389,7 +389,7 @@ export default {
                 options.pos = [7.242690563201904, -137.442626953125, 46.22212219238281];// [obj02Aabb.aabb[0][0]+100, obj02Aabb.aabb[0][1]+10, obj02Aabb.aabb[0][2]+75];
                 //options.parentNode=tmp.item;
                 options.imgId = imgid
-                options.imgSize = [250, 140];
+                options.imgSize = [265, 140];
                 var markPtr = await player.Native.GisMarker.create(options);
                 MarkerMapFac["FAC"][markPtr]=options;
                 //await player.Native.GisMarker.update(markPtr, options);

+ 5 - 0
src/pages/components/In02.vue

@@ -24,6 +24,10 @@
                 <img v-if="AutoPlayer" src="../../assets/image/auto3d_start.png">
                 <img v-else src="../../assets/image/auto3d_stop.png">
             </div>
+            <div title="AI分析"
+                style="cursor: pointer;height: 38px;width: 38px;float: right;margin: 0 10px;" @click.stop="OpenBPBWin">
+                <img src="../../assets/image/icon-ai1.png">
+            </div>
         </div>
         <div v-if="isShowFuncMenuList" id="func_menulist">
             <div  id="maogao_btn" title="" style="cursor: pointer;" @click="OpenMaoGaoWin">毛高比重</div>
@@ -1864,6 +1868,7 @@ export default {
             HideWindow,
             clickalarmtr,
             openStopView,
+            OpenBPBWin,
             indexjsondata,
             alarmjsondata,
             scxljsondata,

+ 30 - 0
src/pages/components/In03-ai_comp.vue

@@ -0,0 +1,30 @@
+<template>
+    <div class="dataContent">
+        <div>{{ params }}</div>
+    </div>
+</template>
+<script>
+    import { ref ,watch,onUnmounted,onMounted} from 'vue';
+    import api from "@/api/system"; 
+    import {useRouter} from 'vue-router';
+    export default {
+        props:{
+
+        },
+        setup(props,{emit}) {
+            const route = useRouter(); // 获取当前路由对象
+            const params = ref(''); // 初始化 hash 值
+            onMounted(()=>{    
+                params.value=route.currentRoute.value.hash.slice(1);
+            })
+            return{
+                params,
+            }
+        }
+    }
+</script>
+<style>
+    .dataContent{
+        color: rgb(255, 255, 255);background-color: rgba(2, 62, 81, 0.5);font-size: 16px;margin: 20px;padding: 10px;border: 1px solid #007586;width: 95%;
+    }
+</style>

+ 483 - 156
src/pages/components/In03.vue

@@ -1,171 +1,197 @@
 <template>
-    <!--这是印花模块的模块展示内容-->
-    <div for="IN03"  id="top" class="top top03" style="padding: 32px 0 0px 0;" @click="switchIndex">
-            <div title="进入数据消费平台"
-                style="cursor: pointer;height: 38px;width: 38px;text-align: center;float: right;margin: 0px 49px 0px 10px;"
-                @click.stop="toAdmin"><img src="../../assets/image/toAdmin.png">
-            </div>
-            <div title="返回主视图"
-                style="cursor: pointer;height: 38px;width: 38px;text-align: center;float: right;margin: 0 10px;"
-                @click.stop="backMasterViewByFac"><img src="../../assets/image/view.png">
+    <div  @click="HideWindow">
+        <!--这是印花模块的模块展示内容-->
+        <div for="IN03"  id="top" class="top top03" style="padding: 32px 0 0px 0;" @click="switchIndex">
+                <div title="进入数据消费平台"
+                    style="cursor: pointer;height: 38px;width: 38px;text-align: center;float: right;margin: 0px 49px 0px 10px;"
+                    @click.stop="toAdmin"><img src="../../assets/image/toAdmin.png">
+                </div>
+                <div title="返回主视图"
+                    style="cursor: pointer;height: 38px;width: 38px;text-align: center;float: right;margin: 0 10px;"
+                    @click.stop="backMasterViewByFac"><img src="../../assets/image/view.png">
+                </div>
+                <div title="AI分析" ref="icon_btn_ai"
+                    style="cursor: pointer;height: 38px;width: 38px;float: right;margin: 0 10px;" @click.stop="OpenAI">
+                    <img src="../../assets/image/icon-ai1.png">
+                </div>
+        </div>
+        <div class="bg20"></div>
+        <div v-if="isShowAI" class="abs aiPanel" @click.stop="void(0)">            
+            <div class="triangle2"></div>
+            <div class="triangle"></div>
+            <div v-for="(p,index) in compProctList" style="margin-top:10px">
+                <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>
+                <span style="margin-right: 5px;margin-left: 5px;">日期</span><el-date-picker v-model="p.compDate" type="date" :value-format="'YYYY-MM-DD'" placeholder="选择日期"></el-date-picker>
+                <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>
+                <!--<span> 到 </span>
+                <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>
+                
+                <el-button v-if="index==compProctList.length-1 && compProctList.length<cxList.length" style="margin:10px" @click="addAILine" title="添加产线">+</el-button>
+                <el-button v-else style="margin:10px" @click="removeAILine(index)" title="移除该产线">-</el-button>-->
             </div>
-    </div>
-    <div class="bg20"></div>
-    <template v-if="showIndexData=='index'">
-        <div class="abs" style="left:50%;top:10%;width: 210px;margin-left:-105px;text-align: center;">
-            <div>请选择要查看的产线</div>
-            <div class="cx">
-                <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>
-                <div  @click="switchCX(0)" :class="currentCXNo==0?'btn active':'btn'" :style="{width:'94%', backgroundImage: currentCXNo==0 ?`url(${btnFrontBg})`:''}">全部</div>
+            <div v-if="compProctList.length>1 " style="text-align: center;">
+                <el-button style="margin:10px" @click.stop="compAILine">AI工艺比对分析</el-button>
+                <el-button style="margin:10px" @click.stop="HideWindow">关闭</el-button>
             </div>
         </div>
-        <div class="abs title_row" style="left: 3%;top:6%;font-weight: normal;">
-            <div class="title_left_line"></div><span>产线状态</span><span style="color:#27e6ff">(今日)</span>
-        </div>
-        <div class="abs data_row" style="left: 3%;top:8%;font-weight: normal;">
-            <div style="margin-left: 10px;"><table cellspacing="0">
-                <tbody>
-                    <tr style="background-color:transparent">
-                        <td style="border:0">
-                            <div class="littleFont">产线<span style="color:#27e6ff">(开动)</span></div>
-                            <div style="font-size: 32px;">{{ ReplaceNull(deviceStatData.status.openProd,'-') }}<span style="font-size: 12px;">条</span></div>
-                        </td>
-                        <td style="border:0;padding-left: 40px;">
-                            <div class="littleFont">设备<span style="color:#27e6ff">(开机)</span></div>
-                            <div style="font-size:24px;height: 38px;line-height: 48px;color: #27e6ff;">{{ ReplaceNull(deviceStatData.status.open,'-') }}<span style="font-size: 12px;"> 台</span></div>
-                        </td>
-                        <td style="border:0;padding-left: 40px;">
-                            <div class="littleFont">设备<span style="color:#27e6ff">(总数)</span></div>
-                            <div style="font-size:24px;height: 38px;line-height: 48px;color: #27e6ff;">{{ ReplaceNull(deviceStatData.status.total,'-') }}<span style="font-size: 12px;"> 台</span></div>
-                        </td>
-                    </tr>
-                </tbody>
-            </table></div>
-        </div>
-        <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>
-        <div class="abs data_row" style="left: auto;top:8%;font-weight: normal;right: 3%;">
-            <div style="margin-left: 10px;"><table cellspacing="0">
-                <tbody>
-                    <tr style="background-color:transparent">
-                        <td style="border:0">
-                            <div class="littleFont">白坯<span style="color:#27e6ff">(投放量)</span></div>
-                            <div style="font-size: 32px;">{{ ReplaceNull(deviceStatData.status.baiPei,'-') }}<span style="font-size: 12px;">米</span></div>
-                        </td>
-                        <td style="border:0;padding-left: 40px;">
-                            <div class="littleFont">产量<span style="color:#27e6ff">(米数)</span></div>
-                            <div style="font-size:24px;height: 38px;line-height: 48px;color: #27e6ff;">{{ ReplaceNull(deviceStatData.status.length,'-') }}<span style="font-size: 12px;"> 米</span></div>
-                        </td>
-                        <td style="border:0;padding-left: 40px;">
-                            <div class="littleFont">产量<span style="color:#27e6ff">(重量)</span></div>
-                            <div style="font-size:24px;height: 38px;line-height: 48px;color: #27e6ff;">{{ReplaceNull(deviceStatData.status.weight,'-') }}<span style="font-size: 12px;"> 吨</span></div>
-                        </td>
-                    </tr>
-                </tbody>
-            </table></div>
-        </div>
-        <div class="abs bottompanel">
-            <div style="width: 15%;height:calc(184px*var(--hRate));display: flex;">
-                <div style="width: 70%;height: 100%;border-right: 1px solid #1a7c90;">
-                    <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>
-                    <div style="padding-left: 5px;color: #27e6ff;margin-top: calc(52px*var(--hRate));width: 88%;">
-                        <div style="color: #fff;"><span>开机数</span><span style="float: right;">总数</span></div>
-                        <div style="font-size: 22px;margin-top: calc(16px*var(--hRate));"><span>{{ ReplaceNull(effInfo.open,'-') }}<span class="littleFont">台</span></span>
-                            <span style="float: right;">{{ ReplaceNull(effInfo.total,'-') }}<span class="littleFont">台</span></span>
-                        </div>
-                        <div style="position: relative;margin-top: calc(16px*var(--hRate));">
-                            <div class="abs fac_progress_value" :style="{width:(effInfo.open/effInfo.total*100)+'%'}"></div>
-                            <div class="abs fac_progress" style="background-color: #5f686e;"></div>
-                        </div>
-                    </div>
+        <template v-if="showIndexData=='index'">
+            <div class="abs" style="left:50%;top:10%;width: 210px;margin-left:-105px;text-align: center;">
+                <div>请选择要查看的产线</div>
+                <div class="cx">
+                    <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>
+                    <div  @click="switchCX(0)" :class="currentCXNo==0?'btn active':'btn'" :style="{width:'94%', backgroundImage: currentCXNo==0 ?`url(${btnFrontBg})`:''}">全部</div>
                 </div>
-                <div style="width: 30%;height: 100%;margin-left: 4%;">
-                    <div style="color: #fff;"><span>单位能耗</span></div>
-                    <div style="font-size: 22px;margin-top: calc(16px*var(--hRate));;color: red;">
-                        <span>{{ ReplaceNull(effInfo.energy,'-') }}<span class="littleFont">元/米</span></span>
+            </div>
+            <div class="abs title_row" style="left: 3%;top:6%;font-weight: normal;">
+                <div class="title_left_line"></div><span>产线状态</span><span style="color:#27e6ff">(今日)</span>
+            </div>
+            <div class="abs data_row" style="left: 3%;top:8%;font-weight: normal;">
+                <div style="margin-left: 10px;"><table cellspacing="0">
+                    <tbody>
+                        <tr style="background-color:transparent">
+                            <td style="border:0">
+                                <div class="littleFont">产线<span style="color:#27e6ff">(开动)</span></div>
+                                <div style="font-size: 32px;">{{ ReplaceNull(deviceStatData.status.openProd,'-') }}<span style="font-size: 12px;">条</span></div>
+                            </td>
+                            <td style="border:0;padding-left: 40px;">
+                                <div class="littleFont">设备<span style="color:#27e6ff">(开机)</span></div>
+                                <div style="font-size:24px;height: 38px;line-height: 48px;color: #27e6ff;">{{ ReplaceNull(deviceStatData.status.open,'-') }}<span style="font-size: 12px;"> 台</span></div>
+                            </td>
+                            <td style="border:0;padding-left: 40px;">
+                                <div class="littleFont">设备<span style="color:#27e6ff">(总数)</span></div>
+                                <div style="font-size:24px;height: 38px;line-height: 48px;color: #27e6ff;">{{ ReplaceNull(deviceStatData.status.total,'-') }}<span style="font-size: 12px;"> 台</span></div>
+                            </td>
+                        </tr>
+                    </tbody>
+                </table></div>
+            </div>
+            <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>
+            <div class="abs data_row" style="left: auto;top:8%;font-weight: normal;right: 3%;">
+                <div style="margin-left: 10px;"><table cellspacing="0">
+                    <tbody>
+                        <tr style="background-color:transparent">
+                            <td style="border:0">
+                                <div class="littleFont">白坯<span style="color:#27e6ff">(投放量)</span></div>
+                                <div style="font-size: 32px;">{{ ReplaceNull(deviceStatData.status.baiPei,'-') }}<span style="font-size: 12px;">米</span></div>
+                            </td>
+                            <td style="border:0;padding-left: 40px;">
+                                <div class="littleFont">产量<span style="color:#27e6ff">(米数)</span></div>
+                                <div style="font-size:24px;height: 38px;line-height: 48px;color: #27e6ff;">{{ ReplaceNull(deviceStatData.status.length,'-') }}<span style="font-size: 12px;"> 米</span></div>
+                            </td>
+                            <td style="border:0;padding-left: 40px;">
+                                <div class="littleFont">产量<span style="color:#27e6ff">(重量)</span></div>
+                                <div style="font-size:24px;height: 38px;line-height: 48px;color: #27e6ff;">{{ReplaceNull(deviceStatData.status.weight,'-') }}<span style="font-size: 12px;"> 吨</span></div>
+                            </td>
+                        </tr>
+                    </tbody>
+                </table></div>
+            </div>
+            <div class="abs bottompanel">
+                <div style="width: 15%;height:calc(184px*var(--hRate));display: flex;">
+                    <div style="width: 70%;height: 100%;border-right: 1px solid #1a7c90;">
+                        <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>
+                        <div style="padding-left: 5px;color: #27e6ff;margin-top: calc(52px*var(--hRate));width: 88%;">
+                            <div style="color: #fff;"><span>开机数</span><span style="float: right;">总数</span></div>
+                            <div style="font-size: 22px;margin-top: calc(16px*var(--hRate));"><span>{{ ReplaceNull(effInfo.open,'-') }}<span class="littleFont">台</span></span>
+                                <span style="float: right;">{{ ReplaceNull(effInfo.total,'-') }}<span class="littleFont">台</span></span>
+                            </div>
+                            <div style="position: relative;margin-top: calc(16px*var(--hRate));">
+                                <div class="abs fac_progress_value" :style="{width:(effInfo.open/effInfo.total*100)+'%'}"></div>
+                                <div class="abs fac_progress" style="background-color: #5f686e;"></div>
+                            </div>
+                        </div>
                     </div>
-                    <div style="color: #fff;margin-top: calc(26px*var(--hRate));"><span>开机率</span></div>
-                    <div style="font-size: 22px;margin-top: calc(16px*var(--hRate));color:#27e6ff ;">
-                        <span>{{ ReplaceNull(effInfo.ratio,'-') }}<span class="littleFont">%</span></span>
+                    <div style="width: 30%;height: 100%;margin-left: 4%;">
+                        <div style="color: #fff;"><span>单位能耗</span></div>
+                        <div style="font-size: 22px;margin-top: calc(16px*var(--hRate));;color: red;">
+                            <span>{{ ReplaceNull(effInfo.energy,'-') }}<span class="littleFont">元/米</span></span>
+                        </div>
+                        <div style="color: #fff;margin-top: calc(26px*var(--hRate));"><span>开机率</span></div>
+                        <div style="font-size: 22px;margin-top: calc(16px*var(--hRate));color:#27e6ff ;">
+                            <span>{{ ReplaceNull(effInfo.ratio,'-') }}<span class="littleFont">%</span></span>
+                        </div>
                     </div>
                 </div>
-            </div>
-            <div :style="{width: '26%',marginLeft:'1%',marginRight: isFullScreen?'2%':'0'}">
-                <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>
-                    <div class="data_row scxl_block">
-                        <div :style="{padding: '10px',width: isFullScreen?'96%':'89%'}"><table cellspacing="0" style="width: 100%;font-size: 14px;text-align: center;">
-                            <thead>
-                                <tr style="font-weight:normal;color: #1fc1d7;background-color: #2dbcd436;">
-                                    <td style="border:0">班组</td>
-                                    <td style="border:0">生产时间(H)</td>
-                                    <td style="border:0">已生产数(米)</td>
-                                    <td style="border:0">总重量(吨)</td>
-                                    <td style="border:0">稼动率(%)</td>
-                                </tr>
-                            </thead>
-                            <tbody>
-                                <tr style="font-weight:normal;background-color:transparent;color: #ffffff;font-size: 14px;">
-                                    <td style="border:0">A班</td>
-                                    <td style="border:0">{{ ReplaceNull(effInfo.timeA,'-') }}</td>
-                                    <td style="border:0">{{ ReplaceNull(effInfo.lengthA,'-') }}</td>
-                                    <td style="border:0">{{ ReplaceNull(effInfo.weightA,'-') }}</td>
-                                    <td style="border:0">{{ ReplaceNull((effInfo.effA*100).toFixed(0),'-') }}%</td>
-                                </tr>
-                                <tr style="font-weight:normal;background-color:transparent;color: #ffffff;background-color: #2dbcd436;font-size: 14px;">
-                                    <td style="border:0">B班</td>
-                                    <td style="border:0">{{ ReplaceNull(effInfo.timeB,'-') }}</td>
-                                    <td style="border:0">{{ ReplaceNull(effInfo.lengthB,'-') }}</td>
-                                    <td style="border:0">{{ ReplaceNull(effInfo.weightB,'-') }}</td>
-                                    <td style="border:0">{{ ReplaceNull((effInfo.effB*100).toFixed(0),'-') }}%</td>
-                                </tr>
-                            </tbody>
-                        </table>
-                        <div style="width: 100%;display: flex;margin-top: calc(42px*var(--hRate));font-size: 14px;justify-content: center;text-align: center;" >
-                            <div style="width: 50%;">
-                                <div style="color: #fff;"><span>米数</span></div>
-                                <div style="font-size: 22px;color:#27e6ff">
-                                    <span>{{ ReplaceNull(effInfo.length,'-') }}<span class="littleFont">米</span></span>
+                <div :style="{width: '26%',marginLeft:'1%',marginRight: isFullScreen?'2%':'0'}">
+                    <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>
+                        <div class="data_row scxl_block">
+                            <div :style="{padding: '10px',width: isFullScreen?'96%':'89%'}"><table cellspacing="0" style="width: 100%;font-size: 14px;text-align: center;">
+                                <thead>
+                                    <tr style="font-weight:normal;color: #1fc1d7;background-color: #2dbcd436;">
+                                        <td style="border:0">班组</td>
+                                        <td style="border:0">生产时间(H)</td>
+                                        <td style="border:0">已生产数(米)</td>
+                                        <td style="border:0">总重量(吨)</td>
+                                        <td style="border:0">稼动率(%)</td>
+                                    </tr>
+                                </thead>
+                                <tbody>
+                                    <tr style="font-weight:normal;background-color:transparent;color: #ffffff;font-size: 14px;">
+                                        <td style="border:0">A班</td>
+                                        <td style="border:0">{{ ReplaceNull(effInfo.timeA,'-') }}</td>
+                                        <td style="border:0">{{ ReplaceNull(effInfo.lengthA,'-') }}</td>
+                                        <td style="border:0">{{ ReplaceNull(effInfo.weightA,'-') }}</td>
+                                        <td style="border:0">{{ ReplaceNull((effInfo.effA*100).toFixed(0),'-') }}%</td>
+                                    </tr>
+                                    <tr style="font-weight:normal;background-color:transparent;color: #ffffff;background-color: #2dbcd436;font-size: 14px;">
+                                        <td style="border:0">B班</td>
+                                        <td style="border:0">{{ ReplaceNull(effInfo.timeB,'-') }}</td>
+                                        <td style="border:0">{{ ReplaceNull(effInfo.lengthB,'-') }}</td>
+                                        <td style="border:0">{{ ReplaceNull(effInfo.weightB,'-') }}</td>
+                                        <td style="border:0">{{ ReplaceNull((effInfo.effB*100).toFixed(0),'-') }}%</td>
+                                    </tr>
+                                </tbody>
+                            </table>
+                            <div style="width: 100%;display: flex;margin-top: calc(42px*var(--hRate));font-size: 14px;justify-content: center;text-align: center;" >
+                                <div style="width: 50%;">
+                                    <div style="color: #fff;"><span>米数</span></div>
+                                    <div style="font-size: 22px;color:#27e6ff">
+                                        <span>{{ ReplaceNull(effInfo.length,'-') }}<span class="littleFont">米</span></span>
+                                    </div>
                                 </div>
-                            </div>
-                            <div style="width: 50%;">
-                                <div style="color: #fff;"><span>重量</span></div>
-                                <div style="font-size: 22px;color:#27e6ff">
-                                    <span>{{ ReplaceNull(effInfo.weight,'-') }}<span class="littleFont">吨</span></span>
+                                <div style="width: 50%;">
+                                    <div style="color: #fff;"><span>重量</span></div>
+                                    <div style="font-size: 22px;color:#27e6ff">
+                                        <span>{{ ReplaceNull(effInfo.weight,'-') }}<span class="littleFont">吨</span></span>
+                                    </div>
                                 </div>
                             </div>
                         </div>
+                        </div>
+                </div>
+                <div style="width: 26%;margin-right: 2%;">
+                    <div class="title_row" style="line-height: 30px;"><div class="title_left_line" style="margin-top: 7px;"></div>
+                        <span>生产趋势</span><span style="color:#27e6ff">(30天)</span>
+                        <span style="margin-left: auto !important;">
+                            <span :class="buttonCode1=='Length'?'fac_btn active':'fac_btn'" @click="LoadSCLine('Length')">米数</span>
+                            <span :class="buttonCode1=='Weight'?'fac_btn active':'fac_btn'" @click="LoadSCLine('Weight')">重量</span>
+                        </span>
                     </div>
-                    </div>
-            </div>
-            <div style="width: 26%;margin-right: 2%;">
-                <div class="title_row" style="line-height: 30px;"><div class="title_left_line" style="margin-top: 7px;"></div>
-                    <span>生产趋势</span><span style="color:#27e6ff">(30天)</span>
-                    <span style="margin-left: auto !important;">
-                        <span :class="buttonCode1=='Length'?'fac_btn active':'fac_btn'" @click="LoadSCLine('Length')">米数</span>
-                        <span :class="buttonCode1=='Weight'?'fac_btn active':'fac_btn'" @click="LoadSCLine('Weight')">重量</span>
-                    </span>
+                    <div :class="isFullScreen?'data_row sc_qushi_block_full':'data_row sc_qushi_block'" ref="echarts_sc_qushi"></div>
                 </div>
-                <div :class="isFullScreen?'data_row sc_qushi_block_full':'data_row sc_qushi_block'" ref="echarts_sc_qushi"></div>
-            </div>
-            <div style="width: 26%;">
-                <div class="title_row" style="line-height: 30px;"><div class="title_left_line" style="margin-top: 7px;"></div>
-                    <span>能耗趋势</span><span style="color:#27e6ff">(30天)</span>
-                    <span style="margin-left: auto !important;">
-                        <span :class="buttonCode2=='price'?'fac_btn active':'fac_btn'" @click="LoadUsedLine('price')">折算</span>
-                        <span :class="buttonCode2=='electricity'?'fac_btn active':'fac_btn'" @click="LoadUsedLine('electricity')">电</span>
-                        <span :class="buttonCode2=='steam'?'fac_btn active':'fac_btn'" @click="LoadUsedLine('steam')">气</span>
-                        <span :class="buttonCode2=='water'?'fac_btn active':'fac_btn'" @click="LoadUsedLine('water')">水</span>
-                    </span>
+                <div style="width: 26%;">
+                    <div class="title_row" style="line-height: 30px;"><div class="title_left_line" style="margin-top: 7px;"></div>
+                        <span>能耗趋势</span><span style="color:#27e6ff">(30天)</span>
+                        <span style="margin-left: auto !important;">
+                            <span :class="buttonCode2=='price'?'fac_btn active':'fac_btn'" @click="LoadUsedLine('price')">折算</span>
+                            <span :class="buttonCode2=='electricity'?'fac_btn active':'fac_btn'" @click="LoadUsedLine('electricity')">电</span>
+                            <span :class="buttonCode2=='steam'?'fac_btn active':'fac_btn'" @click="LoadUsedLine('steam')">气</span>
+                            <span :class="buttonCode2=='water'?'fac_btn active':'fac_btn'" @click="LoadUsedLine('water')">水</span>
+                        </span>
+                    </div>
+                    <div :class="isFullScreen?'data_row used_qushi_block_full':'data_row used_qushi_block'" ref="echarts_used_qushi"></div>
                 </div>
-                <div :class="isFullScreen?'data_row used_qushi_block_full':'data_row used_qushi_block'" ref="echarts_used_qushi"></div>
             </div>
-        </div>
-    </template>
+        </template>
+    </div>
 </template>
 <script>
 import { ref ,watch,onUnmounted,onMounted} from 'vue';
 import {useRouter} from 'vue-router';
 import api from "@/api/system";
 import * as echarts from 'echarts';
+import { ElDatePicker,ElMessage } from 'element-plus';
+import 'element-plus/dist/index.css'; // 确保导入样式文件
 export default {
     props:{
         clickEvent:{
@@ -185,6 +211,18 @@ export default {
     },
     setup(props,{emit}) {
         const router = useRouter();
+        const isShowAI = ref(false);
+        const icon_btn_ai = ref(null);
+        const compProctList=ref([{
+            ai_prouct_no:'',
+            compDate:new Date().Format("yyyy-MM-dd"),
+            compDateHour1:''
+        },{
+            ai_prouct_no:'',
+            compDate:new Date().Format("yyyy-MM-dd"),
+            compDateHour1:''
+        }]);
+        const hourList=ref([]);
         let lines={};
         let oldLineState={};
         let deviceStatData=ref({'status':{},'eff':[]});
@@ -210,6 +248,7 @@ export default {
         let lineArrow001=null;
         let lineArrow002=null;
         let getDataTimer = null;
+        //产线列表
         const cxList=ref([
             {"name":1,active:false,index:1},
             {"name":2,active:false,index:2},
@@ -220,6 +259,18 @@ export default {
             {"name":7,active:false,index:7},
             {"name":8,active:false,index:8},
         ])
+        let compMarkerts={};
+        //产线提示框位置,元素顺序为默认位置,左位置和右位置
+        const markerPos=[
+                    [[-140, 87, 11],[-130, 87, 11],[-80, 87, 11]],
+                    [[-130, 75, 11],[-130, 75, 11],[-80, 75, 11]],
+                    [[-120, 64, 11],[-130, 64, 11],[-80, 64, 11]],
+                    [[-110, 53, 11],[-130, 53, 11],[-80, 53, 11]],
+                    [[-101, 43, 11],[-130, 43, 11],[-80, 43, 11]],
+                    [[-94, 33, 11],[-130, 33, 11],[-80, 33, 11]],
+                    [[-87, 21, 11],[-130, 21, 11],[-80, 21, 11]],
+                    [[-80, 10, 11],[-130, 10, 11],[-80, 10, 11]]
+        ];
         const btnFrontBg = require('@/assets/image/nav_btn_front.png');
         watch(() => props.clickEvent, newVal=> {
             if(newVal==null){
@@ -280,22 +331,25 @@ export default {
                                 }
                             }
             })();
-            if(window.LINELIST==null){
-                var rootItem = await player.Native.ModelTree.getRootItems();
-                var rootObj=null;
-                for (var i = 0; i < rootItem.length; i++) {
+            var rootItem = await player.Native.ModelTree.getRootItems();
+            var rootObj=null;
+            for (var i = 0; i < rootItem.length; i++) {
                     if(rootItem[i].name=="T_03"){
                         rootObj = rootItem[i]
                         break;
                     }
-                }
-                if(rootObj==null){
+            }
+            if(rootObj==null){
                     console.log('未找到该模型的根节点')
                     window.location.reload();
                     return;
-                }
-                var items = await player.Native.ModelTree.getSubItems(rootObj.item)
-                if(items.length==1 && items[0].name=='RootNode') rootObj = items[0];
+            }
+            var items = await player.Native.ModelTree.getSubItems(rootObj.item)
+            for(let i=0;i<items.length;i++){
+                if(items[i].name=='RootNode') rootObj = items[i];
+            }
+            if(window.LINELIST==null){
+
                 //获取产线列表
                 items =  await player.Native.ModelTree.getSubItems(rootObj.item);
                 items.forEach(ele=>{
@@ -303,8 +357,9 @@ export default {
                     //if(ele.name=='Line001') lineArrow001=ele;
                     //if(ele.name=='Line002') lineArrow002=ele;
                 })
-                window.LINELIST = lines;
+                window.LINELIST = lines;                
             }
+            drawLineNo(rootObj);
             updateLineState();
             if(window.IN03Markers==null){
                 window.IN03Markers = [];
@@ -356,6 +411,70 @@ export default {
                 console.log('--------创建标记总耗时:',new Date().getTime()-t1)
             }
         }
+        //绘制编号
+        async function drawLineNo(rootObj){
+            if(player!=null && player.Native!=null){
+                (async()=>{
+                            let marklst = await player.Native.GisMarker.getMarkerList();
+                            if(marklst!=null){
+                                for(var i=0;i<marklst.length;i++){
+                                    if(player!=null && player.Native!=null)player.Native.GisMarker.destroy(marklst[i].id)
+                                }
+                            }
+                })();
+            }
+                //隐藏模型产线编号
+				let imgId = await player.Native.GisMarker.loadImage("data://icon/rz-new/pp.png");
+                window.IN03Markers = {};
+                for(let i=0;i<8;i++){
+                    let objectTxt = "Text00"+(i+1);                    
+                    let object = await player.Native.ModelTree.findItemByName(objectTxt, rootObj.item,true,3);
+                    player.Native.ModelTree.setItemVisible([object.item],false);
+                    objectTxt = "Plane0"+(11+i+1);
+                    object = await player.Native.ModelTree.findItemByName(objectTxt, rootObj.item,true,3);
+                    player.Native.ModelTree.setItemVisible([object.item],false);
+                    let line = i+1;
+                    var options = {
+						"text": line,
+						// "parentNode": parentObj.item,
+						"visible": true,
+						"maxLod": 350,
+						//"minLod": 0,
+						"textFontSize": 18,
+						// "size": [48, 48],
+						// "textColor": parseInt("0xFFFFFFFF"),
+						"contentPadding": [5, 5, 5, 5],
+						"nodeOffset": [0, -24],
+						"userData": "line|"+line
+					};
+                    options.pos = markerPos[i][0];
+					//options.parentNode=tmp.item;
+					options.imgId = imgId
+					options.imgSize = [16, 24];
+					var markPtr = await player.Native.GisMarker.create(options);
+                    window.IN03Markers[markPtr] = options;
+                }
+                //标记点击
+                player.Native.GisMarker.EventGisMarkerLClick.connect((event) => {
+                    let markerLClickObj = window.IN03Markers[event.markerId];
+                    if(markerLClickObj==null){
+                        //emit('markerLClick',{});
+                        markerLClickObj = compMarkerts[event.markerId];
+                        if(markerLClickObj!=null){
+                            var params = JSON.stringify(compProctList.value);
+                            emit('OpenIframeWin',{class:'newwin in03Win',src:'/in03-ai-comp#'+params,title:'AI工艺对比分析'});
+                        }
+                        return;
+                    }
+                    setTimeout(function(dataType){
+                        if(dataType==null) return;
+                        dataType = dataType.split("|");
+                        if(dataType[0]=='line') switchCX(dataType[1]);                        
+                    },100,markerLClickObj["userData"]);
+                    //emit('markerLClick',markerLClickObj);
+                    return;
+                });
+        }
         //更新产线状态颜色
         async function updateLineState(){
             updateLineStateTimer = setTimeout(() => {
@@ -651,14 +770,170 @@ export default {
             [0.001388561848385436, 0.544853112866498, 0.838530355619688], 1);
             }
         }
+        function HideWindow(){
+            if(isShowAI.value){
+                player.Native.Camera.moveTo([-90.4534875451608, -201.60779996809177, 156.1529830648182],
+                [-80.69618225097656,21.59876251220703,11.815500259399414],
+                [0.001388561848385436, 0.544853112866498, 0.838530355619688], 1);
+            }
+            isShowAI.value=false;
+            for(var k in  compMarkerts){
+                if(player!=null && player.Native!=null)player.Native.GisMarker.destroy(k);
+            }
+        }
         //切换到数据消费后台
         function toAdmin(){
             window.open(process.env.VUE_APP_SSO+'?role='+(showIndexData=='index'?"producer":"manager"));
         }
+        function OpenAI(){
+            isShowAI.value=true;
+        }
+        function addAILine(){
+            compProctList.value.push({
+                ai_prouct_no:'',
+                compDate:'',
+                compDateHour1:''
+            });
+        }
+        function removeAILine(ind){
+            let tmpList=[];
+            for(let i=0;i<compProctList.value.length;i++){
+                if(i!=ind){
+                    tmpList.push(compProctList.value[i]);
+                }
+            }
+            compProctList.value = tmpList;
+        }
+        async function compAILine(){
+            if(compProctList.value[0].ai_prouct_no=='' || compProctList.value[1].ai_prouct_no==''){
+                ElMessage({
+                    message:'请选择需要分析的产线!',
+                    type:'error',
+                    customClass: 'custom-message'
+                });
+                return;
+            }
+            if(compProctList.value[0].compDate=='' || compProctList.value[1].compDate==''|| compProctList.value[0].compDateHour1==''|| compProctList.value[1].compDateHour1==''){
+                ElMessage({
+                    message:'请选择需要分析的日期和时点!',
+                    type:'error',
+                    customClass: 'custom-message'
+                });
+                return;
+            }
+            for(var k in  compMarkerts){
+                if(player!=null && player.Native!=null)player.Native.GisMarker.destroy(k);
+            }
+            var loadingMsg = ElMessage({
+                    message:'正在进行工艺分析中...',
+                    type:'info',
+                    customClass: 'custom-message',
+                    duration:0
+            });
+            compMarkerts = {};
+            var lineNo1 = compProctList.value[0].ai_prouct_no*1;
+            var lineNo2 = compProctList.value[1].ai_prouct_no*1;        
+            ///api/yr/compare?line1=1&line2=2&time1=2025-05-13%2008:00:00&time2=2025-05-13%2009:00:00
+            var v={
+                line1:lineNo1,
+                line2:lineNo2,
+                time1:compProctList.value[0].compDate+" "+compProctList.value[0].compDateHour1+":00:00",
+                time2:compProctList.value[1].compDate+" "+compProctList.value[1].compDateHour1+":00:00",
+            };
+            api.GetYrGyComper(v).then((res)=>{
+                loadingMsg.close();
+                if(res.code!=200 || res.data==null){
+                    ElMessage({
+                        message:'获取数据失败!',
+                        type:'error',
+                        customClass: 'custom-message'
+                    });
+                    return;
+                }
+                var line1Data=res.data[0];
+                var line2Data=res.data[1];
+                MarkLineComper(line1Data,line2Data);
+            })
+        }
+        async function MarkLineComper(line1Data,line2Data){
+            player.Native.Camera.moveTo([-94.61742308377592, -231.88112394996935, 91.21216074507522],
+            [-80.69618225097656,21.59876251220703,11.815500259399414],
+            [-0.0033254334820971166, 0.29907134022370024, 0.9542249603468546], 1);
+            var lineNo1 = compProctList.value[0].ai_prouct_no*1;
+            var lineNo2 = compProctList.value[1].ai_prouct_no*1;
+            var imgid = await player.Native.GisMarker.loadImage(lineNo1==lineNo2?"data://icon/qietu/tip-m.png":"data://icon/qietu/tip-r.png");
+                var tipText = "";
+                if(lineNo1!=lineNo2){
+                    tipText = lineNo1+"#产线("+compProctList.value[0].compDate+")\r             "+compProctList.value[0].compDateHour1
+                    +"时      \r       合格率(%):"+line1Data.rate
+                    +"       \r       重  量(T):"+line1Data.weight
+                    +"       \r       米  长(m):"+line1Data.length
+                    +"       \r       水(m3)   :"+line1Data.water
+                    +"       \r       电(kWh)  :"+line1Data.electricity
+                    +"       \r       气(GJ)   :"+line1Data.gas;
+                }else{
+                    tipText = lineNo1+"#产线("+compProctList.value[0].compDate+")\r     "+
+                        compProctList.value[0].compDateHour1+"时           "+
+                        compProctList.value[1].compDateHour1+"时\r合格率(%):"+line1Data.rate+"    合格率(%):"+line2Data.rate
+                        +"    \r重  量(T):"+line1Data.weight.toString().padEnd(5," ")+"    重  量(T):"+line2Data.weight.toString().padEnd(5," ")
+                        +"    \r米  长(m):"+line1Data.length.toString().padEnd(5," ")+"    米  长(m):"+line2Data.length.toString().padEnd(5," ")
+                        +"    \r水(m3)   :"+line1Data.water.toString().padEnd(5," ")+"    水(m3)   :"+line2Data.water.toString().padEnd(5," ")
+                        +"    \r电(kWh)  :"+line1Data.electricity.toString().padEnd(5," ")+"    电(kWh)  :"+line2Data.electricity.toString().padEnd(5," ")
+                        +"    \r气(GJ)   :"+line1Data.gas.toString().padEnd(5," ")+"    气(GJ)   :"+line2Data.gas.toString().padEnd(5," ");
+                }
+                var options = {
+                                    "text": tipText,
+                                    "visible": true,
+                                    //"maxLod": 130,
+                                    "minLod": 0,
+                                    "textFontSize":16,
+                                    "textColor": parseInt("0xffffffff"),
+                                    "contentPadding":[10,5,10,10],
+                                    "nodeOffset": lineNo1==lineNo2 ? [-130,-175]:[-200,-175],
+                                    "userData":"comp|"
+                };
+                options.pos = lineNo1==lineNo2 ? markerPos[lineNo1-1][0] : markerPos[lineNo1-1][1];
+                options.imgId = imgid
+                options.imgSize = lineNo1!=lineNo2 ? [260, 170] :[310, 170];
+                var ptr = await player.Native.GisMarker.create(options);
+                compMarkerts[ptr] = options;            
+                if(lineNo1!=lineNo2){
+                    var options = {
+                                    "text": lineNo2+"#产线("+compProctList.value[1].compDate+")\r             "+compProctList.value[1].compDateHour1
+                                    +"时      \r       合格率(%):"+line2Data.rate
+                                    +"       \r       重  量(T):"+line2Data.weight
+                                    +"       \r       米  长(m):"+line2Data.length
+                                    +"       \r       水(m3)   :"+line2Data.water
+                                    +"       \r       电(kWh)  :"+line2Data.electricity
+                                    +"       \r       气(GJ)   :"+line2Data.gas,
+                                    "visible": true,
+                                    //"maxLod": 130,
+                                    "minLod": 0,
+                                    "textFontSize":16,
+                                    "textColor": parseInt("0xffffffff"),
+                                    "contentPadding":[10,5,10,10],
+                                    "nodeOffset":[-50,-170],
+                                    "userData":"comp|"
+                    };
+                    options.pos = markerPos[lineNo2-1][2];
+                    var imgid = await player.Native.GisMarker.loadImage("data://icon/qietu/tip-l.png");
+                    options.imgId = imgid
+                    options.imgSize = [260, 170];
+                    var ptr = await player.Native.GisMarker.create(options);
+                    compMarkerts[ptr] = options; 
+                }
+        }
         onMounted(()=>{
             if(BODY_H_RATE>0.9) isFullScreen.value=true;
             else isFullScreen.value=false;
             oldLineState = window.IN345LINE;//初始化产线初始状态
+            var hour1Opts = [];
+            for (var i = 0; i < 24; i++) {
+                if(i<10) hour1Opts.push({"name":'0'+i+'时',"code":'0'+i});
+                else hour1Opts.push({"name":i+'时',"code":i});
+            }
+            hourList.value = hour1Opts;
+            window.IN03Markers=null;
         })
         onUnmounted(()=>{
             clearTimeout(getDataTimer);
@@ -676,6 +951,7 @@ export default {
             window.IN03Markers=null;
         })
         return{
+            HideWindow,
             switchIndex,
             echarts_sc_qushi,
             echarts_used_qushi,
@@ -693,11 +969,27 @@ export default {
             LoadSCLine,
             backMasterViewByFac,
             toAdmin,
+            OpenAI,
+            isShowAI,
+            icon_btn_ai,
+            compProctList,
+            hourList,
+            addAILine,
+            removeAILine,
+            compAILine,
         }
     }
 }
 </script>
 <style scope="IN03">
+.custom-message {
+  top: 40% !important; /* 例如,将消息框定位到距离顶部50px */
+  left: 50% !important;
+  transform: translateX(-50%);
+}
+.el-popper{
+    z-index: 99999 !important;
+}
 .bg20{
     z-index: 1; pointer-events: none;position: absolute;
     top: calc(22px * var(--hRate));
@@ -787,4 +1079,39 @@ export default {
     border: 1px solid #008899;
     background: rgb(0 85 102 / 40%);
 }
+.aiPanel{
+    width: 460px;
+    height: auto;
+    right: 2%;
+    top: 7.5% !important;
+    left: auto !important;
+    border: 1px solid #008899;
+    background: rgb(0 85 102 / 92%);
+    z-index: 10000 !important;
+    border-radius: 5px;
+    padding: 5px;
+    font-size: 14px;
+}
+.aiPanel .triangle{
+        width: 0;
+        height: 0;
+        position: absolute;
+        top: -10px;
+        right: 130px;
+        border-width: 6px;
+        border-style: solid;
+        border-color:transparent transparent rgb(0 85 102 / 92%) transparent  ;
+        border-radius: 4rpx;
+}
+.aiPanel .triangle2{
+        width: 0;
+        height: 0;
+        position: absolute;
+        top: -12px;
+        right: 130px;
+        border-width: 6px;
+        border-style: solid;
+        border-color:transparent transparent #008899 transparent  ;
+        border-radius: 4rpx;
+}
 </style>

+ 7 - 0
src/router/index.js

@@ -53,6 +53,13 @@ const routes = [
         }
     },
     {
+        path:"/in03-ai-comp",
+        component: () => import("@/pages/components/In03-ai_comp.vue"),
+        meta: {
+            name: "in03-ai-comp"
+        }
+    },
+    {
         path:"/in02-device-info",
         component: () => import("@/pages/components/In02_device_info.vue"),
         meta: {