From 640ec71c74436ced842b478ec866a00ff1b3ee68 Mon Sep 17 00:00:00 2001 From: dengyuxin Date: Wed, 10 Dec 2025 17:19:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- datav/css/visual.css | 485 ++++++++++++- datav/index.html | 383 +++++----- datav/js/chartMap.js | 477 ------------- datav/js/visual.js | 1615 ++++++++++-------------------------------- datav/monitor.html | 256 +++++++ datav/server.js | 24 + datav/test_api.js | 34 + datav/test_proxy.js | 19 + readme.md | 46 ++ 9 files changed, 1403 insertions(+), 1936 deletions(-) create mode 100644 datav/monitor.html create mode 100644 datav/test_api.js create mode 100644 datav/test_proxy.js create mode 100644 readme.md diff --git a/datav/css/visual.css b/datav/css/visual.css index 6832004..23b677c 100644 --- a/datav/css/visual.css +++ b/datav/css/visual.css @@ -1,3 +1,4 @@ +@charset "utf-8"; a,p,h1,h2,h3,h4,h5,h6,body,span,label,div{padding:0;margin:0;font-family:'瀵邦喛钂嬮梿鍛寸拨';} div{font-family:'瀵邦喛钂嬮梿鍛寸拨';} ul{padding:0;margin:0;} @@ -50,20 +51,63 @@ html, body, form{overflow-y:auto;height:100%;} .head_top{position:relative;text-align:center;} .head_top img{display:block;width:80%;margin:0 auto;} -.head_top .head_logo{position:absolute;top:6px;left:50%;transform:translateX(-50%);color:#55bfff;font-size:35px;font-weight:600;z-index:2;} +.head_top .head_logo{position:absolute;top:6px;left:50%;transform:translateX(-50%);color:#55bfff;font-size:35px;font-weight:600;z-index:10;text-shadow: 0 0 10px rgba(0, 216, 255, 0.5);} .head_top .head_decor{margin-top:1px;} +.head_top .decor_side { + position: absolute; + top: 15px; + width: 45px !important; + height: auto !important; + z-index: 11; + opacity: 0.9; + display: block; /* ensure it is visible */ + margin: 0; /* reset margin from generic rule */ +} +.head_top .decor_left { + left: 50%; + margin-left: -170px !important; +} +.head_top .decor_right { + left: 50%; + margin-left: 125px !important; + transform: scaleX(-1); +} +.head_top .decor_bar { + position: absolute; + top: 40px; + width: 25% !important; + height: auto !important; + z-index: 10; + display: block; +} +.head_top .decor_left_outer { + left: 50%; + margin-left: -850px !important; +} +.head_top .decor_right_outer { + left: 50%; + margin-left: 400px !important; +} .head_top p{width:100%;text-align:center;color:#55bfff;position:absolute;bottom: -18px;left: -10px;} .head_top p span{font-family:'yjsz';font-size:20px;} -.visual{height:calc(100% - 33px);padding-top:10px;} +.visual{height:calc(100% - 33px);padding-top:5px;} -.visual_box{height:33.3%;} +.visual_box{height:40%;} +.visual_left .visual_box{height:18%;margin-bottom: 2%;} +.visual_right .visual_box{height:18%;margin-bottom: 2%;} +.visual_left .visual_box:nth-child(1), +.visual_right .visual_box:nth-child(1), +.visual_left .visual_box:nth-child(2), +.visual_right .visual_box:nth-child(2) { + height: 34%; +} .visual_box .visual_title{position:relative;height:35px;margin:5px 0;} .visual_box .visual_title span{color:#fff;font-size:18px;line-height:35px;} .visual_box .visual_title img{width:100%;position:absolute;left:0;bottom:0;} .visual_box .visual_chart{height:calc(100% - 35px);} -.visual_left{width:25%;height:100%;float:left;} +.visual_left{width:25%;height:100%;float:left;margin-top: -15px;} .visual_left .sfzcll{position:relative;} .visual_left .sfzcll a{width:32%;text-align:center;line-height:25px;color:#fff;display:inline-block;} .visual_left .sfzcll .sfzcll_pos_box{width:100%;height:calc(100% - 30px);} @@ -81,17 +125,17 @@ html, body, form{overflow-y:auto;height:100%;} .visual_left .sfzcll .sfzcll_box .sfzcll_smallBk .ygl{color:#00ffc6;} .visual_left .sfzcll .sfzcll_box .sfzcll_smallBk .ygh{color:#ffe400;} -.visual_con{width:50%;height:100%;float:left;padding:25px 20px 0 20px;} -.visual_con .visual_conTop{display:grid;grid-template-columns:repeat(5,1fr);grid-auto-rows:120px;gap:10px;margin-bottom:10px;} +.visual_con{width:50%;height:100%;float:left;padding:0 20px 0 20px;} +.visual_con .visual_conTop{display:grid;grid-template-columns:repeat(5,1fr);grid-auto-rows:80px;gap:10px;margin-bottom:10px;} .visual_con .visual_conTop .visual_conTop_box{height:100%;padding:0;} .visual_con .visual_conTop .visual_conTop1{width:100%;height:100%;float:none;} .visual_con .visual_conTop .visual_conTop1>div{background:url(../images/ksh40.png) no-repeat;background-size:100% 100%;} .visual_con .visual_conTop .visual_conTop2{width:30%;height:100%;float:left;} .visual_con .visual_conTop .visual_conTop2>div{background:url(../images/ksh39.png) no-repeat;background-size:100% 100%;} -.visual_right{width:25%;height:100%;float:right;} -.visual_con .visual_conTop .visual_conTop_box>div{height:100%;} -.visual_con .visual_conTop .visual_conTop_box>div h3{color:#fff;font-size:16px;padding:12px 0 0 16px;margin:0;} -.visual_con .visual_conTop .visual_conTop_box>div p{width:100%;float:none;line-height:1.2;color:#20dbfd;text-shadow:0 0 12px #00d8ff;font-size:32px;font-family: 'yjsz';text-align:left;padding:12px 0 0 16px;margin:0;} +.visual_right{width:25%;height:100%;float:right;margin-top: -15px;} +.visual_con .visual_conTop .visual_conTop_box>div{height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;} +.visual_con .visual_conTop .visual_conTop_box>div h3{color:#fff;font-size:14px;padding:0;margin:0;text-align:center;width:100%;} +.visual_con .visual_conTop .visual_conTop_box>div p{width:100%;float:none;line-height:1.2;color:#20dbfd;text-shadow:0 0 12px #00d8ff;font-size:24px;font-family: 'yjsz';text-align:center;padding:5px 0 0 0;margin:0;} .visual_con .visual_conTop .visual_conTop_box>div .conTop_smil{width:67%;height:60px;float:left;padding-top:23px;} .visual_con .visual_conTop .visual_conTop_box>div .conTop_smil a{display:block;line-height:20px;text-align: left;color:#fff;padding-left:9px;} .visual_con .visual_conTop .visual_conTop_box>div .conTop_smil span{width:32px;display:inline-block;margin-left:3px;} @@ -99,35 +143,408 @@ html, body, form{overflow-y:auto;height:100%;} .visual_con .visual_conTop .visual_conTop_box>div .conTop_smil a.xd{color:#12fe81;} .visual_con .visual_conTop .visual_conTop_box>div .conTop_smil a.null{visibility:hidden;} +.visual_conBot{height:calc(100% - 400px);position:relative;margin-top:10px;} +.visual_conBot>img{position:absolute;z-index:99;} +.visual_conBot .visual_conBot_l{left:0;top:0;} +.visual_conBot .visual_conBot_2{right:0;top:0;} +.visual_conBot .visual_conBot_3{right:0;bottom:0;} +.visual_conBot .visual_conBot_4{left:0;bottom:0;} +.visual_conBot .visual_chart{width:100%;height:100%;position:absolute;z-index:9;} + +/* 订单状态监控模块样式 */ +.visual_conStatus { + height: 90px; + margin-top: 10px; + display: flex; + justify-content: space-between; + padding: 0 10px; +} + +.status_item { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-end; + position: relative; + padding-bottom: 5px; +} + +.status_label { + color: #fff; + font-size: 14px; + margin-bottom: 5px; + z-index: 2; +} + +.status_value_group { + display: flex; + align-items: baseline; + margin-bottom: 15px; + z-index: 2; +} + +.status_value_group .stat-value { + color: #fff; + font-size: 24px; + font-family: 'yjsz'; + font-weight: bold; + text-shadow: 0 0 10px rgba(255, 255, 255, 0.8); +} + +.status_value_group .status_unit { + color: #aaa; + font-size: 12px; + margin-left: 5px; +} + +.status_base { + position: absolute; + bottom: 0; + width: 80%; + height: 30px; + display: flex; + justify-content: center; + align-items: center; +} + +.status_ring { + position: absolute; + bottom: 0; + width: 100%; + height: 100%; + border-radius: 50%; + border: 2px solid rgba(0, 150, 255, 0.5); + background: rgba(0, 80, 160, 0.2); + box-shadow: 0 0 15px rgba(0, 150, 255, 0.4), inset 0 0 10px rgba(0, 150, 255, 0.2); + transform: rotateX(60deg); +} + +.status_light { + position: absolute; + bottom: 10px; + width: 70%; + height: 40px; + background: linear-gradient(to top, rgba(0, 150, 255, 0.4), transparent); + clip-path: polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%); + z-index: 1; +} + +/* 为 status_ring 添加旋转动画 */ +.status_ring::after { + content: ''; + position: absolute; + top: -5px; left: -5px; right: -5px; bottom: -5px; + border-radius: 50%; + border: 2px dashed rgba(0, 216, 255, 0.6); + animation: rotateRing 10s linear infinite; +} + +@keyframes rotateRing { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + .stat-card{display:flex;flex-direction:column;justify-content:center;align-items:flex-start;height:100%;} -.visual_con .visual_conBot{height:calc(100% - 136px);background:url(../images/ksh41.png) no-repeat;background-size:100% 100%;position:relative;} -.visual_con .visual_conBot>img{position:absolute;width:25px;height:25px;} -.visual_con .visual_conBot .visual_conBot_l{position:absolute;left:0;top:0;} -.visual_con .visual_conBot .visual_conBot_2{position:absolute;right:0;top:0;} -.visual_con .visual_conBot .visual_conBot_3{position:absolute;right:0;bottom:0;} -.visual_con .visual_conBot .visual_conBot_4{position:absolute;left:0;bottom:0;} -.visual_con .visual_conBot .visual_chart{width:100%;height:100%;position:absolute;} -.visual_con .visual_conBot .visual_chart_text{color:#fff;position:absolute;top:15px;left:15px;z-index: 99;} -.visual_con .visual_conBot .visual_chart_text h1{font-size:26px;margin-bottom:6px;} -.visual_con .visual_conBot .visual_chart_text h2{font-size:20px;} -.visual_con .visual_conBot .visual_conBot_bot{width:calc(100% - 8px);height:180px;background:rgba(16,54,87,0.5);border:1px solid #345f92;position:absolute;bottom:4px;left:4px;z-index:99;} +/* Order List Styles */ +.order_list_container { + padding: 10px; + display: flex; + flex-direction: column; +} +.order_list_header { + display: flex; + justify-content: space-between; + padding: 8px 10px; + background: rgba(13, 38, 71, 0.8); + border-radius: 4px; + margin-bottom: 5px; +} +.order_list_header span { + color: #00d8ff; + font-size: 14px; + flex: 1; + text-align: center; +} +.order_list_content { + flex: 1; + overflow-y: auto; +} +.order_item { + display: flex; + justify-content: space-between; + padding: 8px 10px; + border-bottom: 1px solid rgba(255,255,255,0.1); + align-items: center; +} +.order_item span { + color: #fff; + font-size: 13px; + flex: 1; + text-align: center; +} +.status-done { color: #00ffc6 !important; } +.status-shipping { color: #ffe400 !important; } +.status-pending { color: #ff6b6b !important; } -.visualSssf_left{width:40%;float:left;color:#fff;padding:10px 20px 0 20px;} -.visualSssf_left h3{color:#fff;font-size:20px;font-weight:600;margin-bottom:10px;} -.visualSssf_left a{width:32%;color:#fff;display:inline-block;margin-bottom:10px;cursor:pointer;} -.visualSssf_left a.active{color:#01f0ff;} -.visualSssf_right{width:60%;height:100%;float:left;} -.visualSssf_right .visualSssf_right_box{width:33%;float:left;height:100%;} +/* 牛只概况列表样式 */ +#cattle_overview_container { + padding: 10px 10px 0 10px; + display: flex; + flex-wrap: wrap; + align-content: flex-start; + overflow-y: auto; + height: 100%; +} -.visualSfzsfl{position:relative;} -.visualSfzsfl .visual_chart{opacity:0.6} -.visualSfzsfl .visual_table{width:60%;position:absolute;z-index: 99;top:40px;left:0;} -.visualSfzsfl .visual_table table{width:100%;color:#fff;text-align:center;} -.visualSfzsfl .visual_table table tr{border-bottom: 1px dashed #ddd;} -.visualSfzsfl .visual_table table tr:first-child{color:#01c0ff;} -.visualSfzsfl .visual_table table tr:last-child{border-bottom: 1px solid #ddd;} +.cattle_item { + width: 48%; + margin-right: 4%; + margin-bottom: 12px; + background: rgba(10, 30, 60, 0.6); + border: 1px solid #134572; + border-radius: 20px; + padding: 5px 8px; + display: flex; + align-items: center; + box-sizing: border-box; + box-shadow: inset 0 0 10px rgba(0, 150, 255, 0.1); + cursor: pointer; + transition: all 0.3s; +} +.cattle_item:hover { + background: rgba(10, 30, 60, 0.9); + border-color: #00d8ff; + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(0, 216, 255, 0.2); +} +.cattle_item:nth-child(2n) { + margin-right: 0; +} +.cattle_icon { + width: 30px; + height: 30px; + border-radius: 50%; + background: rgba(0, 80, 160, 0.5); + border: 1px solid #0096ff; + display: flex; + justify-content: center; + align-items: center; + margin-right: 8px; + flex-shrink: 0; + position: relative; +} +.cattle_icon::after { + content: ''; + position: absolute; + width: 4px; + height: 4px; + background: #00d8ff; + border-radius: 50%; + bottom: 2px; + right: 2px; + box-shadow: 0 0 5px #00d8ff; +} + +.cattle_icon .glyphicon { + color: #8acaff; + font-size: 14px; +} + +.cattle_info { + flex: 1; + display: flex; + justify-content: space-between; + align-items: baseline; + white-space: nowrap; + overflow: hidden; +} + +.cattle_name { + color: #cceeff; + font-size: 13px; + overflow: hidden; + text-overflow: ellipsis; +} + +.cattle_value { + color: #fff; + font-size: 16px; + font-family: 'yjsz'; + margin-left: 5px; +} + +.cattle_unit { + font-size: 12px; + color: #aaa; + margin-left: 2px; + font-family: "Microsoft YaHei"; +} + +/* 牛只行情列表样式 */ +.market_list_container { + padding: 10px; + display: flex; + flex-direction: column; +} + +.market_list_header { + display: flex; + justify-content: space-between; + padding: 8px 0; + background: rgba(13, 38, 71, 0.8); + border-radius: 4px; + margin-bottom: 5px; +} + +.market_list_header span { + color: #aaa; + font-size: 13px; + text-align: center; + font-weight: bold; +} + +.market_list_content { + flex: 1; + overflow-y: auto; +} + +.market_item { + display: flex; + justify-content: space-between; + padding: 8px 0; + border-bottom: 1px solid rgba(255,255,255,0.05); + align-items: center; +} + +.market_item span { + color: #fff; + font-size: 12px; + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +/* 序号列 */ +.market_list_header span:nth-child(1), +.market_item span:nth-child(1) { + flex: 0.5; +} + +/* 省份列 */ +.market_list_header span:nth-child(2), +.market_item span:nth-child(2) { + flex: 1; +} + +/* 地区列 */ +.market_list_header span:nth-child(3), +.market_item span:nth-child(3) { + flex: 1.5; +} + +/* 品种列 */ +.market_list_header span:nth-child(4), +.market_item span:nth-child(4) { + flex: 1; +} + +/* 单价列 */ +.market_list_header span:nth-child(5), +.market_item span:nth-child(5) { + flex: 1; +} + +.market_price { + color: #00d8ff !important; + font-weight: bold; +} + +/* 合计总数模块样式 */ +.total_layout { + display: flex; + flex-direction: column; + justify-content: space-around; + padding: 10px 20px; +} + +.total_row { + flex: 1; + display: flex; + align-items: center; + background: rgba(10, 30, 60, 0.6); + border: 1px solid rgba(0, 216, 255, 0.2); + border-radius: 8px; + margin-bottom: 10px; + padding: 0 15px; + box-shadow: inset 0 0 15px rgba(0, 150, 255, 0.1); +} + +.total_row:last-child { + margin-bottom: 0; +} + +.total_icon_wrapper { + width: 46px; + height: 46px; + background: rgba(0, 80, 160, 0.5); + border: 1px solid #0096ff; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + box-shadow: 0 0 10px rgba(0, 216, 255, 0.3); +} + +.total_icon_wrapper .glyphicon { + font-size: 20px; + color: #00d8ff; +} + +.total_text_wrapper { + margin-left: 20px; + display: flex; + flex-direction: column; + justify-content: center; +} + +.total_label { + color: #cceeff; + font-size: 14px; + margin-bottom: 2px; +} + +.total_data { + display: flex; + align-items: baseline; +} + +.total_data .stat-value { + color: #fff; + font-size: 24px; + font-family: 'yjsz'; + font-weight: bold; + text-shadow: 0 0 10px rgba(0, 216, 255, 0.5); +} + +.total_data .total_unit { + color: #aaa; + font-size: 12px; + margin-left: 5px; +} + +/* 屠宰场概况列表样式 - 复用牛只概况样式逻辑 */ +#slaughterhouse_overview_container { + padding: 10px 10px 0 10px; + display: flex; + flex-wrap: wrap; + align-content: flex-start; + overflow-y: auto; + height: 100%; +} diff --git a/datav/index.html b/datav/index.html index 3e3cbd4..1ceb9f5 100644 --- a/datav/index.html +++ b/datav/index.html @@ -29,153 +29,105 @@ +
+ + + + 标题装饰
+
- 交通流量 + 订单列表
-
- -
-
-
-
- 交通工具流量 - -
-
- -
-
-
-
- 收费站车流量 - -
-
- 运输方式 - 客运量 - 货运量 -
-
- - - - - -
-
- 4347.2万人 -
-
-
-
- 4347.2万人 -
-
-
-
-
- - - - - -
-
- 4347.2万人 -
-
-
-
- 4347.2万人 -
-
-
-
-
- - - - - -
-
- 4347.2万人 -
-
-
-
- 4347.2万人 -
-
-
-
+
+
+ 订单号 + 金额 + 状态
+
+
+
+
+
+
+ 牛只概况 + +
+
+
+
+ 出肉率 + +
+
+
+

采购总额

-

--

+

423536.29元

销售总额

-

--

+

417832.33元

利润

-

--

+

31525元

应收货款

-

--

+

215215.25元

未收货款

-

--

+

564231.321元

实收货款

-

--

+

335421.56元

采购头数

-

--

+

2200头

采购单数

-

--

+

35车

销售单数

-

--

+

55单

@@ -186,89 +138,120 @@
-
-
-

今日实时收费

- 全省数据 - 大同北 - 大同南 - 朔州 - 吕梁北 - 吕梁南 - 太原 - 晋中 - 太旧 - 长治 +
+
+
+
未完成
+
+ -- +
-
-
-
-
+
+
+
+
+
+
+
未到岸
+
+ -- + +
+
+
+
+
+
+
+
未售完
+
+ -- + +
+
+
+
+
+
+
+
已完成
+
+ -- + +
+
+
+
-
- 本月发生事件 + 牛只行情
-
-
-
-
+
+
+ 序号 + 省份 + 地区 + 品种 + 单价(元/斤) +
+
-
-
- 收费站收费量 - -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
小型车中型车大型车
2486万2486万2486万
2486万2486万2486万
2486万2486万2486万
2486万2486万2486万
-
-
- 收费站收费排行 + 屠宰场概况
-
-
-
-
+
+
+
+
+ 合计总数 + +
+
+
+
+ +
+
+
合计总数
+
+ -- + +
+
+
+
+
+ +
+
+
在栏总数
+
+ -- + +
+
+
+
+
+ +
+
+
在途总数
+
+ -- + +
+
@@ -291,10 +274,12 @@ } } + /* var sfzcllH=$('.sfzcll_box').height() var sfzcllHtwo=sfzcllH-2 $('.sfzcll_box').css('line-height',sfzcllH+'px') $('.sfzcll_smallBk>div').css('line-height',sfzcllHtwo+'px') + */ //删除加载动画 $('#load').fadeOut(1000) @@ -342,10 +327,57 @@ success: function(res) { const list = res && (res.data || res.rows || res.result || res.list || res); const first = Array.isArray(list) ? list[0] : list; - renderSalesOverview(first || {}); + const data = first || {}; + + // 模拟测试数据(如果接口未返回) + if (data.toalProcurementAmount === undefined) data.toalProcurementAmount = 423536.29; + if (data.toalSalesAmount === undefined) data.toalSalesAmount = 417832.33; + if (data.profits === undefined) data.profits = 31525; + if (data.accountsReceivable === undefined) data.accountsReceivable = 215215.25; + if (data.uncollectedPayment === undefined) data.uncollectedPayment = 564231.32; + if (data.actualPayment === undefined) data.actualPayment = 335421.56; + if (data.totalPurchase === undefined) data.totalPurchase = 2200; + if (data.totalOrder === undefined) data.totalOrder = 35; + if (data.totalSales === undefined) data.totalSales = 55; + + // 模拟合计总数数据 + if (data.totalCattle === undefined) data.totalCattle = 12580; + if (data.inTransitCattle === undefined) data.inTransitCattle = 1250; + if (data.deliveredCattle === undefined) data.deliveredCattle = 11330; + + // 模拟订单状态数据 + if (data.uncompletedOrders === undefined) data.uncompletedOrders = 28; + if (data.notArrivedOrders === undefined) data.notArrivedOrders = 28; + if (data.unsoldOrders === undefined) data.unsoldOrders = 6; + if (data.completedOrders === undefined) data.completedOrders = 22; + + renderSalesOverview(data); }, error: function() { - renderSalesOverview({}); + const data = {}; + // 模拟测试数据 + data.toalProcurementAmount = 423536.29; + data.toalSalesAmount = 417832.33; + data.profits = 31525; + data.accountsReceivable = 215215.25; + data.uncollectedPayment = 564231.32; + data.actualPayment = 335421.56; + data.totalPurchase = 2200; + data.totalOrder = 35; + data.totalSales = 55; + + // 模拟合计总数数据 + data.totalCattle = 12580; + data.inTransitCattle = 1250; + data.deliveredCattle = 11330; + + // 模拟订单状态数据 + data.uncompletedOrders = 28; + data.notArrivedOrders = 28; + data.unsoldOrders = 6; + data.completedOrders = 22; + + renderSalesOverview(data); } }); }; @@ -353,47 +385,12 @@ fetchSalesOverview(); }) - //交通流量 - var myChart1 = echarts.init(document.getElementById('main1')); - myChart1.setOption(option1); - //交通工具流量 - var myChart2 = echarts.init(document.getElementById('main2')); - myChart2.setOption(option2); - //本月发生事件 - var myChart3 = echarts.init(document.getElementById('main3')); - myChart3.setOption(option3); - var myChart31 = echarts.init(document.getElementById('main31')); - myChart31.setOption(option31); - var mySwiper1 = new Swiper('.visual_swiper1', { - autoplay: true,//可选选项,自动滑动 - speed:800,//可选选项,滑动速度 - autoplay: { - delay: 5000,//1秒切换一次 - }, - }) - //收费站收费排行 - var myChart4 = echarts.init(document.getElementById('main4')); - myChart4.setOption(option4); - var myChart41 = echarts.init(document.getElementById('main41')); - myChart41.setOption(option41); - var mySwiper2 = new Swiper('.visual_swiper2', { - autoplay: true,//可选选项,自动滑动 - direction : 'vertical',//可选选项,滑动方向 - speed:2000,//可选选项,滑动速度 - }) - //今日实时收费 - var myChart5 = echarts.init(document.getElementById('main5')); - myChart5.setOption(option5); - var myChart6 = echarts.init(document.getElementById('main6')); - myChart6.setOption(option6); - var myChart7 = echarts.init(document.getElementById('main7')); - myChart7.setOption(option7); + + //中间地图 var myChart8 = echarts.init(document.getElementById('main8')); myChart8.setOption(option8); - //收费站收费量 - var myChart9 = echarts.init(document.getElementById('main9')); - myChart9.setOption(option9); + diff --git a/datav/js/chartMap.js b/datav/js/chartMap.js index 56de3ab..b0004ef 100644 --- a/datav/js/chartMap.js +++ b/datav/js/chartMap.js @@ -88,480 +88,3 @@ option8 = { data: allData.moveLines }] }; - - -//收费站收费量 -var geoCoordMap = { - "海门":[121.15,31.89], - "鄂尔多斯":[109.781327,39.608266], - "招远":[120.38,37.35], - "舟山":[122.207216,29.985295], - "齐齐哈尔":[123.97,47.33], - "盐城":[120.13,33.38], - "赤峰":[118.87,42.28], - "青岛":[120.33,36.07], - "乳山":[121.52,36.89], - "金昌":[102.188043,38.520089], - "泉州":[118.58,24.93], - "莱西":[120.53,36.86], - "日照":[119.46,35.42], - "胶南":[119.97,35.88], - "南通":[121.05,32.08], - "拉萨":[91.11,29.97], - "云浮":[112.02,22.93], - "梅州":[116.1,24.55], - "文登":[122.05,37.2], - "上海":[121.48,31.22], - "攀枝花":[101.718637,26.582347], - "威海":[122.1,37.5], - "承德":[117.93,40.97], - "厦门":[118.1,24.46], - "汕尾":[115.375279,22.786211], - "潮州":[116.63,23.68], - "丹东":[124.37,40.13], - "太仓":[121.1,31.45], - "曲靖":[103.79,25.51], - "烟台":[121.39,37.52], - "福州":[119.3,26.08], - "瓦房店":[121.979603,39.627114], - "即墨":[120.45,36.38], - "抚顺":[123.97,41.97], - "玉溪":[102.52,24.35], - "张家口":[114.87,40.82], - "阳泉":[113.57,37.85], - "莱州":[119.942327,37.177017], - "湖州":[120.1,30.86], - "汕头":[116.69,23.39], - "昆山":[120.95,31.39], - "宁波":[121.56,29.86], - "湛江":[110.359377,21.270708], - "揭阳":[116.35,23.55], - "荣成":[122.41,37.16], - "连云港":[119.16,34.59], - "葫芦岛":[120.836932,40.711052], - "常熟":[120.74,31.64], - "东莞":[113.75,23.04], - "河源":[114.68,23.73], - "淮安":[119.15,33.5], - "泰州":[119.9,32.49], - "南宁":[108.33,22.84], - "营口":[122.18,40.65], - "惠州":[114.4,23.09], - "江阴":[120.26,31.91], - "蓬莱":[120.75,37.8], - "韶关":[113.62,24.84], - "嘉峪关":[98.289152,39.77313], - "广州":[113.23,23.16], - "延安":[109.47,36.6], - "太原":[112.53,37.87], - "清远":[113.01,23.7], - "中山":[113.38,22.52], - "昆明":[102.73,25.04], - "寿光":[118.73,36.86], - "盘锦":[122.070714,41.119997], - "长治":[113.08,36.18], - "深圳":[114.07,22.62], - "珠海":[113.52,22.3], - "宿迁":[118.3,33.96], - "咸阳":[108.72,34.36], - "铜川":[109.11,35.09], - "平度":[119.97,36.77], - "佛山":[113.11,23.05], - "海口":[110.35,20.02], - "江门":[113.06,22.61], - "章丘":[117.53,36.72], - "肇庆":[112.44,23.05], - "大连":[121.62,38.92], - "临汾":[111.5,36.08], - "吴江":[120.63,31.16], - "石嘴山":[106.39,39.04], - "沈阳":[123.38,41.8], - "苏州":[120.62,31.32], - "茂名":[110.88,21.68], - "嘉兴":[120.76,30.77], - "长春":[125.35,43.88], - "胶州":[120.03336,36.264622], - "银川":[106.27,38.47], - "张家港":[120.555821,31.875428], - "三门峡":[111.19,34.76], - "锦州":[121.15,41.13], - "南昌":[115.89,28.68], - "柳州":[109.4,24.33], - "三亚":[109.511909,18.252847], - "自贡":[104.778442,29.33903], - "吉林":[126.57,43.87], - "阳江":[111.95,21.85], - "泸州":[105.39,28.91], - "西宁":[101.74,36.56], - "宜宾":[104.56,29.77], - "呼和浩特":[111.65,40.82], - "成都":[104.06,30.67], - "大同":[113.3,40.12], - "镇江":[119.44,32.2], - "桂林":[110.28,25.29], - "张家界":[110.479191,29.117096], - "宜兴":[119.82,31.36], - "北海":[109.12,21.49], - "西安":[108.95,34.27], - "金坛":[119.56,31.74], - "东营":[118.49,37.46], - "牡丹江":[129.58,44.6], - "遵义":[106.9,27.7], - "绍兴":[120.58,30.01], - "扬州":[119.42,32.39], - "常州":[119.95,31.79], - "潍坊":[119.1,36.62], - "重庆":[106.54,29.59], - "台州":[121.420757,28.656386], - "南京":[118.78,32.04], - "滨州":[118.03,37.36], - "贵阳":[106.71,26.57], - "无锡":[120.29,31.59], - "本溪":[123.73,41.3], - "克拉玛依":[84.77,45.59], - "渭南":[109.5,34.52], - "马鞍山":[118.48,31.56], - "宝鸡":[107.15,34.38], - "焦作":[113.21,35.24], - "句容":[119.16,31.95], - "北京":[116.46,39.92], - "徐州":[117.2,34.26], - "衡水":[115.72,37.72], - "包头":[110,40.58], - "绵阳":[104.73,31.48], - "乌鲁木齐":[87.68,43.77], - "枣庄":[117.57,34.86], - "杭州":[120.19,30.26], - "淄博":[118.05,36.78], - "鞍山":[122.85,41.12], - "溧阳":[119.48,31.43], - "库尔勒":[86.06,41.68], - "安阳":[114.35,36.1], - "开封":[114.35,34.79], - "济南":[117,36.65], - "德阳":[104.37,31.13], - "温州":[120.65,28.01], - "九江":[115.97,29.71], - "邯郸":[114.47,36.6], - "临安":[119.72,30.23], - "兰州":[103.73,36.03], - "沧州":[116.83,38.33], - "临沂":[118.35,35.05], - "南充":[106.110698,30.837793], - "天津":[117.2,39.13], - "富阳":[119.95,30.07], - "泰安":[117.13,36.18], - "诸暨":[120.23,29.71], - "郑州":[113.65,34.76], - "哈尔滨":[126.63,45.75], - "聊城":[115.97,36.45], - "芜湖":[118.38,31.33], - "唐山":[118.02,39.63], - "平顶山":[113.29,33.75], - "邢台":[114.48,37.05], - "德州":[116.29,37.45], - "济宁":[116.59,35.38], - "荆州":[112.239741,30.335165], - "宜昌":[111.3,30.7], - "义乌":[120.06,29.32], - "丽水":[119.92,28.45], - "洛阳":[112.44,34.7], - "秦皇岛":[119.57,39.95], - "株洲":[113.16,27.83], - "石家庄":[114.48,38.03], - "莱芜":[117.67,36.19], - "常德":[111.69,29.05], - "保定":[115.48,38.85], - "湘潭":[112.91,27.87], - "金华":[119.64,29.12], - "岳阳":[113.09,29.37], - "长沙":[113,28.21], - "衢州":[118.88,28.97], - "廊坊":[116.7,39.53], - "菏泽":[115.480656,35.23375], - "合肥":[117.27,31.86], - "武汉":[114.31,30.52], - "大庆":[125.03,46.58] -}; - -var convertData = function (data) { - var res = []; - for (var i = 0; i < data.length; i++) { - var geoCoord = geoCoordMap[data[i].name]; - if (geoCoord) { - res.push({ - name: data[i].name, - value: geoCoord.concat(data[i].value) - }); - } - } - return res; -}; - -option9 = { - - title: { - text: ' ', - sublink: ' ', - x:'center', - textStyle: { - color: '#fff' - } - }, - tooltip: { - trigger: 'item', - formatter: function (params) { - return params.name + ' : ' + params.value[2]; - } - }, - legend: { - orient: 'vertical', - y: 'bottom', - x:'right', - data:['pm2.5'], - textStyle: { - color: '#fff' - } - }, - visualMap: { - min: 0, - max: 200, - calculable: true, - color: ['#d94e5d','#eac736','#50a3ba'], - textStyle: { - color: '#fff' - } - }, - geo: { - map: 'china', - label: { - emphasis: { - show: false - } - }, - itemStyle: { - normal: { - areaColor: 'rgba(127,199,221,0.1)', - borderColor: '#0177ff' - }, - emphasis: { - areaColor: '#071537'//鼠标指上市时的颜色 - } - } - }, - series: [ - { - name: ' ', - type: 'scatter', - coordinateSystem: 'geo', - data: convertData([ - {name: "海门", value: 9}, - {name: "鄂尔多斯", value: 12}, - {name: "招远", value: 12}, - {name: "舟山", value: 12}, - {name: "齐齐哈尔", value: 14}, - {name: "盐城", value: 15}, - {name: "赤峰", value: 16}, - {name: "青岛", value: 18}, - {name: "乳山", value: 18}, - {name: "金昌", value: 19}, - {name: "泉州", value: 21}, - {name: "莱西", value: 21}, - {name: "日照", value: 21}, - {name: "胶南", value: 22}, - {name: "南通", value: 23}, - {name: "拉萨", value: 24}, - {name: "云浮", value: 24}, - {name: "梅州", value: 25}, - {name: "文登", value: 25}, - {name: "上海", value: 25}, - {name: "攀枝花", value: 25}, - {name: "威海", value: 25}, - {name: "承德", value: 25}, - {name: "厦门", value: 26}, - {name: "汕尾", value: 26}, - {name: "潮州", value: 26}, - {name: "丹东", value: 27}, - {name: "太仓", value: 27}, - {name: "曲靖", value: 27}, - {name: "烟台", value: 28}, - {name: "福州", value: 29}, - {name: "瓦房店", value: 30}, - {name: "即墨", value: 30}, - {name: "抚顺", value: 31}, - {name: "玉溪", value: 31}, - {name: "张家口", value: 31}, - {name: "阳泉", value: 31}, - {name: "莱州", value: 32}, - {name: "湖州", value: 32}, - {name: "汕头", value: 32}, - {name: "昆山", value: 33}, - {name: "宁波", value: 33}, - {name: "湛江", value: 33}, - {name: "揭阳", value: 34}, - {name: "荣成", value: 34}, - {name: "连云港", value: 35}, - {name: "葫芦岛", value: 35}, - {name: "常熟", value: 36}, - {name: "东莞", value: 36}, - {name: "河源", value: 36}, - {name: "淮安", value: 36}, - {name: "泰州", value: 36}, - {name: "南宁", value: 37}, - {name: "营口", value: 37}, - {name: "惠州", value: 37}, - {name: "江阴", value: 37}, - {name: "蓬莱", value: 37}, - {name: "韶关", value: 38}, - {name: "嘉峪关", value: 38}, - {name: "广州", value: 38}, - {name: "延安", value: 38}, - {name: "太原", value: 39}, - {name: "清远", value: 39}, - {name: "中山", value: 39}, - {name: "昆明", value: 39}, - {name: "寿光", value: 40}, - {name: "盘锦", value: 40}, - {name: "长治", value: 41}, - {name: "深圳", value: 41}, - {name: "珠海", value: 42}, - {name: "宿迁", value: 43}, - {name: "咸阳", value: 43}, - {name: "铜川", value: 44}, - {name: "平度", value: 44}, - {name: "佛山", value: 44}, - {name: "海口", value: 44}, - {name: "江门", value: 45}, - {name: "章丘", value: 45}, - {name: "肇庆", value: 46}, - {name: "大连", value: 47}, - {name: "临汾", value: 47}, - {name: "吴江", value: 47}, - {name: "石嘴山", value: 49}, - {name: "沈阳", value: 50}, - {name: "苏州", value: 50}, - {name: "茂名", value: 50}, - {name: "嘉兴", value: 51}, - {name: "长春", value: 51}, - {name: "胶州", value: 52}, - {name: "银川", value: 52}, - {name: "张家港", value: 52}, - {name: "三门峡", value: 53}, - {name: "锦州", value: 54}, - {name: "南昌", value: 54}, - {name: "柳州", value: 54}, - {name: "三亚", value: 54}, - {name: "自贡", value: 56}, - {name: "吉林", value: 56}, - {name: "阳江", value: 57}, - {name: "泸州", value: 57}, - {name: "西宁", value: 57}, - {name: "宜宾", value: 58}, - {name: "呼和浩特", value: 58}, - {name: "成都", value: 58}, - {name: "大同", value: 58}, - {name: "镇江", value: 59}, - {name: "桂林", value: 59}, - {name: "张家界", value: 59}, - {name: "宜兴", value: 59}, - {name: "北海", value: 60}, - {name: "西安", value: 61}, - {name: "金坛", value: 62}, - {name: "东营", value: 62}, - {name: "牡丹江", value: 63}, - {name: "遵义", value: 63}, - {name: "绍兴", value: 63}, - {name: "扬州", value: 64}, - {name: "常州", value: 64}, - {name: "潍坊", value: 65}, - {name: "重庆", value: 66}, - {name: "台州", value: 67}, - {name: "南京", value: 67}, - {name: "滨州", value: 70}, - {name: "贵阳", value: 71}, - {name: "无锡", value: 71}, - {name: "本溪", value: 71}, - {name: "克拉玛依", value: 72}, - {name: "渭南", value: 72}, - {name: "马鞍山", value: 72}, - {name: "宝鸡", value: 72}, - {name: "焦作", value: 75}, - {name: "句容", value: 75}, - {name: "北京", value: 79}, - {name: "徐州", value: 79}, - {name: "衡水", value: 80}, - {name: "包头", value: 80}, - {name: "绵阳", value: 80}, - {name: "乌鲁木齐", value: 84}, - {name: "枣庄", value: 84}, - {name: "杭州", value: 84}, - {name: "淄博", value: 85}, - {name: "鞍山", value: 86}, - {name: "溧阳", value: 86}, - {name: "库尔勒", value: 86}, - {name: "安阳", value: 90}, - {name: "开封", value: 90}, - {name: "济南", value: 92}, - {name: "德阳", value: 93}, - {name: "温州", value: 95}, - {name: "九江", value: 96}, - {name: "邯郸", value: 98}, - {name: "临安", value: 99}, - {name: "兰州", value: 99}, - {name: "沧州", value: 100}, - {name: "临沂", value: 103}, - {name: "南充", value: 104}, - {name: "天津", value: 105}, - {name: "富阳", value: 106}, - {name: "泰安", value: 112}, - {name: "诸暨", value: 112}, - {name: "郑州", value: 113}, - {name: "哈尔滨", value: 114}, - {name: "聊城", value: 116}, - {name: "芜湖", value: 117}, - {name: "唐山", value: 119}, - {name: "平顶山", value: 119}, - {name: "邢台", value: 119}, - {name: "德州", value: 120}, - {name: "济宁", value: 120}, - {name: "荆州", value: 127}, - {name: "宜昌", value: 130}, - {name: "义乌", value: 132}, - {name: "丽水", value: 133}, - {name: "洛阳", value: 134}, - {name: "秦皇岛", value: 136}, - {name: "株洲", value: 143}, - {name: "石家庄", value: 147}, - {name: "莱芜", value: 148}, - {name: "常德", value: 152}, - {name: "保定", value: 153}, - {name: "湘潭", value: 154}, - {name: "金华", value: 157}, - {name: "岳阳", value: 169}, - {name: "长沙", value: 175}, - {name: "衢州", value: 177}, - {name: "廊坊", value: 193}, - {name: "菏泽", value: 194}, - {name: "合肥", value: 229}, - {name: "武汉", value: 273}, - {name: "大庆", value: 279} - ]), - symbolSize: 12, - label: { - normal: { - show: false - }, - emphasis: { - show: false - } - }, - itemStyle: { - emphasis: { - borderColor: '#fff', - borderWidth: 1 - } - } - } - ] -} -//////////////////////收费站收费量 end \ No newline at end of file diff --git a/datav/js/visual.js b/datav/js/visual.js index 0f92ffc..60565bf 100644 --- a/datav/js/visual.js +++ b/datav/js/visual.js @@ -1,1249 +1,400 @@ -//交通流量 -var data = { - id: 'multipleBarsLines', - legendBar: ['高速公路', '城镇公路'], - symbol: ' ', //数值是否带百分号 --默认为空 '' - legendLine: ['环比', '同比'], - xAxis: ['2014', '2015', '2016', '2017', '2018', - '2019' - ], - yAxis: [ - [8, 10, 10, 11, 4, 13], - [10, 7, 8, 8, 7, 9] - ], - lines: [ - [10, 10, 9, 11, 7, 4], - [6, 12, 12, 2, 4, 4] - ], - barColor: ['#009883', '#e66922'], //柱子颜色 必填参数 - lineColor: ['#fd6665', '#fba73b'], // 折线颜色 -} +// 订单列表逻辑 +(function() { + const orders = [ + { id: 'ORD001', amount: '¥12,000', status: '已完成', class: 'status-done' }, + { id: 'ORD002', amount: '¥8,500', status: '运输中', class: 'status-shipping' }, + { id: 'ORD003', amount: '¥15,000', status: '待发货', class: 'status-pending' }, + { id: 'ORD004', amount: '¥9,200', status: '已完成', class: 'status-done' }, + { id: 'ORD005', amount: '¥21,000', status: '运输中', class: 'status-shipping' }, + { id: 'ORD006', amount: '¥6,800', status: '已完成', class: 'status-done' } + ]; -var myData = (function test() { - let yAxis = data.yAxis || [] - let lines = data.lines || [] - let legendBar = data.legendBar || [] - let legendLine = data.legendLine || [] - var symbol = data.symbol || ' ' - let seriesArr = [] - let legendArr = [] - yAxis && yAxis.forEach((item, index) => { - legendArr.push({ - name: legendBar && legendBar.length > 0 && legendBar[index] - }) - seriesArr.push({ - name: legendBar && legendBar.length > 0 && legendBar[index], - type: 'bar', - barGap: '0.5px', - data: item, - barWidth: data.barWidth || 12, - label: { - normal: { - show: false, - formatter: '{c}' + symbol, - position: 'top', - textStyle: { - color: '#000', - fontStyle: 'normal', - fontFamily: '微软雅黑', - textAlign: 'left', - fontSize: 11, - }, - }, - }, - itemStyle: { //图形样式 - normal: { - barBorderRadius:0, - borderWidth:1, - borderColor:'#ddd', - color: data.barColor[index] - }, + function renderOrderList() { + const container = $('.order_list_content'); + if (container.length === 0) return; + + let html = ''; + orders.forEach(order => { + html += ` +
+ ${order.id} + ${order.amount} + ${order.status} +
+ `; + }); + container.html(html); + } + + // 模拟新订单 + setInterval(() => { + const newId = 'ORD' + String(Date.now()).slice(-3); + const amount = '¥' + (Math.floor(Math.random() * 20000) + 5000).toLocaleString(); + const statuses = [ + { text: '已完成', class: 'status-done' }, + { text: '运输中', class: 'status-shipping' }, + { text: '待发货', class: 'status-pending' } + ]; + const status = statuses[Math.floor(Math.random() * statuses.length)]; + + orders.unshift({ + id: newId, + amount: amount, + status: status.text, + class: status.class + }); + + if (orders.length > 10) orders.pop(); // 保持列表长度 + + renderOrderList(); + }, 5000); + + // 初始化 + $(function() { + renderOrderList(); + }); +})(); + +// 牛只概况列表逻辑 +(function() { + const cattleData = [ + { name: '中山仓', value: 10 }, + { name: '横沥仓', value: 23 }, + { name: '三水仓', value: 12 }, + { name: '陆丰仓', value: 30 }, + { name: '博罗仓', value: 21 }, + { name: '梅州仓', value: 34 }, + ]; + + function renderCattleOverview() { + const container = $('#cattle_overview_container'); + if (container.length === 0) return; + + let html = ''; + cattleData.forEach(item => { + html += ` +
+
+ +
+
+ ${item.name} +
+ ${item.value} + +
+
+
+ `; + }); + container.html(html); + } + + // 模拟数据波动 + setInterval(() => { + const index = Math.floor(Math.random() * cattleData.length); + const change = Math.floor(Math.random() * 3) - 1; // -1, 0, 1 + let newVal = cattleData[index].value + change; + if (newVal < 0) newVal = 0; + cattleData[index].value = newVal; + renderCattleOverview(); + }, 3000); + + $(function() { + renderCattleOverview(); + + // 点击跳转到监控页面 + $('#cattle_overview_container').on('click', '.cattle_item', function() { + const name = $(this).data('name'); + if (name) { + window.location.href = 'monitor.html?warehouse=' + encodeURIComponent(name); } - }) - }) + }); + }); +})(); - lines && lines.forEach((item, index) => { - legendArr.push({ - name: legendLine && legendLine.length > 0 && legendLine[index] - }) - seriesArr.push({ - name: legendLine && legendLine.length > 0 && legendLine[index], - type: 'line', - data: item, - itemStyle: { - normal: { - color: data.lineColor[index], +// 牛只行情列表逻辑 +(function() { + let scrollInterval; + + function fetchAndRenderMarketList() { + $.ajax({ + // 使用本地代理接口解决跨域问题 + // 原接口: https://ad.yunmainiu.com/api/cattle-data + // 代理配置在 server.js 中: /api/cattle-market-data -> https://ad.yunmainiu.com/api/cattle-data + url: '/api/cattle-market-data', + method: 'GET', + success: function(response) { + // 尝试解析字符串响应 + if (typeof response === 'string') { + try { + response = JSON.parse(response); + } catch (e) { + console.error('JSON解析失败:', e); + } + } + + let data = []; + // 兼容可能的返回格式:直接数组 或 { data: [] } + if (Array.isArray(response)) { + data = response; + } else if (response && Array.isArray(response.data)) { + data = response.data; + } else if (response && Array.isArray(response.list)) { + data = response.list; + } + + console.log('获取到的牛只行情数据:', data); + renderMarketList(data); + }, + error: function(err) { + console.error('获取牛只行情数据失败:', err); + // 失败时显示空或错误提示,或者保留旧数据 + } + }); + } + + function renderMarketList(data) { + const container = $('.market_list_content'); + if (container.length === 0) return; + + let html = ''; + if (data.length === 0) { + html = '
暂无数据
'; + } else { + data.forEach((item, index) => { + // 接口字段: province(省份), location(地区), type(品种), price(单价) + html += ` +
+ ${index + 1} + ${item.province || '--'} + ${item.location || '--'} + ${item.type || '--'} + ${item.price || '--'} +
+ `; + }); + } + container.html(html); + + // 清除旧的滚动定时器 + if (scrollInterval) { + clearInterval(scrollInterval); + scrollInterval = null; + } + + // 简单的自动滚动效果 + // 需要等待DOM渲染完成后计算高度,这里简单使用setTimeout + setTimeout(() => { + let scrollPos = 0; + // 重新获取DOM元素属性,确保准确 + const scrollHeight = container[0].scrollHeight; + const clientHeight = container[0].clientHeight; + + // 只有当内容高度超过容器高度时才滚动 + if (scrollHeight > clientHeight) { + scrollInterval = setInterval(() => { + scrollPos += 1; + // 当滚动到底部时,回到顶部 + if (scrollPos >= scrollHeight - clientHeight) { + scrollPos = 0; + } + container.scrollTop(scrollPos); + }, 50); + } + }, 100); + } + + $(function() { + fetchAndRenderMarketList(); + + // 每60秒刷新一次数据 + setInterval(fetchAndRenderMarketList, 60000); + }); +})(); + +// 出肉率图表逻辑 +(function() { + // 确保 DOM 加载完成 + $(function() { + const chartDom = document.getElementById('meat_yield_chart'); + if (!chartDom) return; + + const myChart = echarts.init(chartDom); + + const option = { + tooltip: { + trigger: 'axis', + axisPointer: { type: 'shadow' } + }, + grid: { + left: '3%', + right: '10%', + bottom: '3%', + top: '10%', + containLabel: true + }, + xAxis: { + type: 'value', + axisLabel: { + color: '#fff', + fontSize: 12 + }, + splitLine: { + show: true, lineStyle: { - width: 2,//折线宽度 - type: 'solid', + color: 'rgba(255,255,255,0.1)' + } + }, + axisLine: { + show: true, + lineStyle: { + color: '#fff' } } }, - label: { - normal: { - show: false, //折线上方label控制显示隐藏 - position: 'top', - } - }, - symbol: 'circle', - symbolSize: 5 - }) - }) - - return { - seriesArr, - legendArr - } -})() -option1 = { - title: { - show: true, - text: data.title, - subtext: data.subTitle, - link: '1111' - }, - tooltip: { - trigger: 'axis', - formatter: function(params) { - var time = ''; - var str = ''; - for (var i of params) { - time = i.name.replace(/\n/g, '') + '
'; - if (i.data == 'null' || i.data == null) { - str += i.seriesName + ':无数据' + '
' - } else { - str += i.seriesName + ':' + i.data + symbol + '%
' - } - - } - return time + str; - }, - axisPointer: { - type: 'none' - }, - }, - legend: { - right: data.legendRight || '30%', - top: 0, - right:10, - itemGap: 16, - itemWidth: 10, - itemHeight: 10, - data: myData.legendArr, - textStyle: { - color: '#fff', - fontStyle: 'normal', - fontFamily: '微软雅黑', - fontSize: 12, - } - }, - grid: { - x: 0, - y: 30, - x2: 0, - y2: 25, - }, - xAxis: { - type: 'category', - data: data.xAxis, - axisTick: { - show: false, - }, - - axisLine: { - show: false, - }, - axisLabel: { //轴标 - show: true, - interval: '0', - textStyle: { - lineHeight:5, - padding: [2, 2, 0, 2], - height: 50, - fontSize: 12, - color:'#fff', - }, - rich: { - Sunny: { - height: 50, - // width: 60, - padding: [0, 5, 0, 5], - align: 'center', + yAxis: { + type: 'category', + data: ['鲁西黄牛', '西门塔尔', '夏洛莱', '利木赞', '安格斯'], + axisLabel: { + color: '#fff', + fontSize: 12 }, - }, - formatter: function(params, index) { - var newParamsName = ""; - var splitNumber = 5; - var paramsNameNumber = params && params.length; - if (paramsNameNumber && paramsNameNumber <= 4) { - splitNumber = 4; - } else if (paramsNameNumber >= 5 && paramsNameNumber <= 7) { - splitNumber = 4; - } else if (paramsNameNumber >= 8 && paramsNameNumber <= 9) { - splitNumber = 5; - } else if (paramsNameNumber >= 10 && paramsNameNumber <= 14) { - splitNumber = 5; - } else { - params = params && params.slice(0, 15); + axisLine: { + show: true, + lineStyle: { + color: '#fff' + } } - - var provideNumber = splitNumber; //一行显示几个字 - var rowNumber = Math.ceil(paramsNameNumber / provideNumber) || 0; - if (paramsNameNumber > provideNumber) { - for (var p = 0; p < rowNumber; p++) { - var tempStr = ""; - var start = p * provideNumber; - var end = start + provideNumber; - if (p == rowNumber - 1) { - tempStr = params.substring(start, paramsNameNumber); - } else { - tempStr = params.substring(start, end) + "\n"; + }, + series: [ + { + name: '出肉率', + type: 'bar', + data: [45, 52, 58, 55, 60], + itemStyle: { + normal: { + color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [ + { offset: 0, color: '#2b86ff' }, + { offset: 1, color: '#1effc0' } + ]), + barBorderRadius: [0, 5, 5, 0] } - newParamsName += tempStr; - } - - } else { - newParamsName = params; + }, + label: { + show: true, + position: 'right', + formatter: '{c}%', + color: '#fff' + }, + barWidth: '40%' } - params = newParamsName - return '{Sunny|' + params + '}'; - }, - color: '#687284', - }, + ] + }; + + myChart.setOption(option); + + // 窗口大小改变时重置图表大小 + window.addEventListener("resize", function () { + myChart.resize(); + }); - }, - yAxis: { - axisLine: { - show: false - }, - axisTick: { - show: false - }, - axisLabel: { - show: false - }, - splitLine: { - show: true, - lineStyle: { - color: '#F1F3F5', - type: 'solid' - }, - interval: 2 - }, - splitNumber: 4, - }, - series: myData.seriesArr -} -//////////////////////交通流量 end - -//交通工具流量 -option2 = { - - tooltip: {//鼠标指上时的标线 - trigger: 'axis', - axisPointer: { - lineStyle: { - color: '#fff' - } - } - }, - legend: { - icon: 'rect', - itemWidth: 14, - itemHeight: 5, - itemGap: 13, - data: ['小型车', '中型车', '大型车'], - right: '10px', - top: '0px', - textStyle: { - fontSize: 12, - color: '#fff' - } - }, - grid: { - x: 35, - y: 25, - x2: 8, - y2: 25, - }, - xAxis: [{ - type: 'category', - boundaryGap: false, - axisLine: { - lineStyle: { - color: '#57617B' - } - }, - axisLabel: { - textStyle: { - color:'#fff', - }, - }, - data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'] - }], - yAxis: [{ - type: 'value', - axisTick: { - show: false - }, - axisLine: { - lineStyle: { - color: '#57617B' - } - }, - axisLabel: { - margin: 10, - textStyle: { - fontSize: 14 - }, - textStyle: { - color:'#fff', - }, - }, - splitLine: { - lineStyle: { - color: '#57617B' - } - } - }], - series: [{ - name: '小型车', - type: 'line', - smooth: true, - lineStyle: { - normal: { - width: 2 - } - }, - areaStyle: { - normal: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ - offset: 0, - color: 'rgba(137, 189, 27, 0.3)' - }, { - offset: 0.8, - color: 'rgba(137, 189, 27, 0)' - }], false), - shadowColor: 'rgba(0, 0, 0, 0.1)', - shadowBlur: 10 - } - }, - itemStyle: { - normal: { - color: 'rgb(137,189,27)' - } - }, - data: [20,35,34,45,52,41,49,64,24,52.4,24,33] - }, { - name: '中型车', - type: 'line', - smooth: true, - lineStyle: { - normal: { - width: 2 - } - }, - areaStyle: { - normal: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ - offset: 0, - color: 'rgba(0, 136, 212, 0.3)' - }, { - offset: 0.8, - color: 'rgba(0, 136, 212, 0)' - }], false), - shadowColor: 'rgba(0, 0, 0, 0.1)', - shadowBlur: 10 - } - }, - itemStyle: { - normal: { - color: 'rgb(0,136,212)' - } - }, - data: [97.3,99.2,99.3,100.0,99.6,90.6,80.0,91.5,69.8,67.5,90.4,84.9] - }, { - name: '大型车', - type: 'line', - smooth: true, - lineStyle: { - normal: { - width: 2 - } - }, - areaStyle: { - normal: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ - offset: 0, - color: 'rgba(219, 50, 51, 0.3)' - }, { - offset: 0.8, - color: 'rgba(219, 50, 51, 0)' - }], false), - shadowColor: 'rgba(0, 0, 0, 0.1)', - shadowBlur: 10 - } - }, - itemStyle: { - normal: { - color: 'rgb(219,50,51)' - } - }, - data: [84.2,81.0,67.5,62.1,43.7,68.5,51.9,71.8,76.7,67.6,62.9,0] - }, ] -}; -//////////////////////交通工具流量 end - -//本月发生事件1 -var color = ['#e9df3d', '#f79c19', '#21fcd6', '#08c8ff', '#df4131']; -var data = [{ - "name": "超速", - "value": 30 - }, - { - "name": "闯红灯", - "value": 30 - }, - { - "name": "闯禁行", - "value": 42 - }, - { - "name": "违停", - "value": 50 - }, - { - "name": "逆行", - "value": 34 - } -]; - -var max = data[0].value; -data.forEach(function(d) { - max = d.value > max ? d.value : max; -}); - -var renderData = [{ - value: [], - name: "告警类型TOP5", - symbol: 'none', - lineStyle: { - normal: { - color: '#ecc03e', - width: 2 - } - }, - areaStyle: { - normal: { - color: new echarts.graphic.LinearGradient(0, 0, 1, 0, - [{ - offset: 0, - color: 'rgba(203, 158, 24, 0.8)' - }, { - offset: 1, - color: 'rgba(190, 96, 20, 0.8)' - }], - false) - } - } -}]; - - -data.forEach(function(d, i) { - var value = ['', '', '', '', '']; - value[i] = max, - renderData[0].value[i] = d.value; - renderData.push({ - value: value, - symbol: 'circle', - symbolSize: 12, - lineStyle: { - normal: { - color: 'transparent' - } - }, - itemStyle: { - normal: { - color: color[i], - } - } - }) -}) -var indicator = []; - -data.forEach(function(d) { - indicator.push({ - name: d.name, - max: max, - color: '#fff' - }) -}) - - -option3 = { - tooltip: { - show: true, - trigger: "item" - }, - radar: { - center: ["50%", "50%"],//偏移位置 - radius: "80%", - startAngle: 40, // 起始角度 - splitNumber: 4, - shape: "circle", - splitArea: { - areaStyle: { - color: 'transparent' - } - }, - axisLabel: { - show: false, - fontSize: 20, - color: "#000", - fontStyle: "normal", - fontWeight: "normal" - }, - axisLine: { - show: true, - lineStyle: { - color: "rgba(255, 255, 255, 0.5)" - } - }, - splitLine: { - show: true, - lineStyle: { - color: "rgba(255, 255, 255, 0.5)" - } - }, - indicator: indicator - }, - series: [{ - type: "radar", - data: renderData - }] -} -//////////////////////本月发生事件1 end -//本月发生事件2 -var color = ['#e9df3d', '#f79c19', '#21fcd6', '#08c8ff', '#df4131']; -var data = [{ - "name": "超速", - "value": 15 - }, - { - "name": "闯红灯", - "value": 14 - }, - { - "name": "闯禁行", - "value": 23 - }, - { - "name": "违停", - "value": 2 - }, - { - "name": "逆行", - "value": 50 - } -]; - -var max = data[0].value; -data.forEach(function(d) { - max = d.value > max ? d.value : max; -}); - -var renderData = [{ - value: [], - name: "告警类型TOP5", - symbol: 'none', - lineStyle: { - normal: { - color: '#ecc03e', - width: 2 - } - }, - areaStyle: { - normal: { - color: new echarts.graphic.LinearGradient(0, 0, 1, 0, - [{ - offset: 0, - color: 'rgba(203, 158, 24, 0.8)' - }, { - offset: 1, - color: 'rgba(190, 96, 20, 0.8)' - }], - false) - } - } -}]; - - -data.forEach(function(d, i) { - var value = ['', '', '', '', '']; - value[i] = max, - renderData[0].value[i] = d.value; - renderData.push({ - value: value, - symbol: 'circle', - symbolSize: 12, - lineStyle: { - normal: { - color: 'transparent' - } - }, - itemStyle: { - normal: { - color: color[i], - } - } - }) -}) -var indicator = []; - -data.forEach(function(d) { - indicator.push({ - name: d.name, - max: max, - color: '#fff' - }) -}) - - -option31 = { - tooltip: { - show: true, - trigger: "item" - }, - radar: { - center: ["50%", "50%"],//偏移位置 - radius: "80%", - startAngle: 40, // 起始角度 - splitNumber: 4, - shape: "circle", - splitArea: { - areaStyle: { - color: 'transparent' - } - }, - axisLabel: { - show: false, - fontSize: 20, - color: "#000", - fontStyle: "normal", - fontWeight: "normal" - }, - axisLine: { - show: true, - lineStyle: { - color: "rgba(255, 255, 255, 0.5)" - } - }, - splitLine: { - show: true, - lineStyle: { - color: "rgba(255, 255, 255, 0.5)" - } - }, - indicator: indicator - }, - series: [{ - type: "radar", - data: renderData - }] -} -//////////////////////本月发生事件2 end - - - -//收费站收费排行1 -var spirit = '../images.ksh45.png'; - -var maxData = 200; - -option4 = { - "title": { - "text": " ", - "left": "center", - "y": "10", - "textStyle": { - "color": "#fff" - } - }, - - "grid": { - "left": 30, - "top": 0, - "bottom": 10 - }, - "tooltip": { - "trigger": "item", - "textStyle": { - "fontSize": 12 - }, - "formatter": "{b0}:{c0}" - }, - "xAxis": { - "max": 100, - "splitLine": { - "show": false - }, - "axisLine": { - "show": false - }, - "axisLabel": { - "show": false - }, - "axisTick": { - "show": false - } - }, - "yAxis": [ - { - "type": "category", - "inverse": false, - "data": [ - "晋城", - "太旧", - "太原", - "吕梁", - "长治", - ], - "axisLine": { - "show": false - }, - "axisTick": { - "show": false - }, - "axisLabel": { - "margin": -4, - "textStyle": { - "color": "#fff", - "fontSize": 16.25 - } - } - }, - - ], - "series": [ - { - "type": "pictorialBar", - "symbol": "image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAYAAAA4qEECAAADYElEQVR4nO2dz0sUYRjHP7tIdAmxQ1LdlhCKMohAIsgiyEuHjkUEFQTlpejS/xCCBB06RBGBBKIG4cGyH0qHBKE9eKyFqBQPRQeNCt06vGNY7bq7szPfeZLnAwuzM+/zgw/DDvMu70wOIVveLscJOwycA44A24CfwAfgKXAbeFVvovlC/o/vuVwuTj+x0FWiYdGbgXvA8RrjHgAXgIVaCbMU3SKr1BhtwEtgZx1jTwI7gG7ga5pNNUO+9pBMuEN9klfYD9xMqZdEsCj6AHAiRtxZYFeyrSSHRdGnYsblCD8jJrEoek8TsbsT6yJhLIrelFFsqlgUPZtRbKpYFP2kidjxxLpIGIuiB4AvMeLmgJGEe0kMi6I/AVdjxPVSx91hVlgUDXAXuEaY16jFMnAJeJhqR01iVTTAdeAYUFxjzBRwCLgl6agJrM51rDAO7AP2EmbxthPO8vfAc2Ams84axLpoCGKLrH1mm8eC6KPAGaAL2Fpj7AZgY7T9DfhRY/wc4eflPmH+OjOynI8uEGbpukXlJ4Dz84V8aWWHcj46q4thFzCNTjJRren2UrlLWPM3WYjuAMYIk/tq2oCx9lK5Q11YLboFGARaxXVX0woMtpfK0uuTWvRFoFNcsxKdhF5kqEX3iuuthbQXtehG/gdMG2kvlm/B1xUuWoSLFmFF9CRwg2TnM4pRzskEc8bGiugR4ArhNjkpJqKcJv51sSJ63eOiRbhoES5ahIsW4aJFuGgRLlqEixbhokW4aBEuWoSLFuGiRbhoES5ahIsW4aJFuGgRLlqEWvTHKvs/p1izWu5qvaSCWvTlCvtmgeEUaw5TeUVtpV5SQy16COgBRoHXhMWb3aS7PnAhqjEQ1RwFeuYL+aEUa/5DFmtYHkefOEwQVmcBvKD+FQNvgNN/P+pHiV8MRbhoES5ahIsW4aJFuGgRLlqEixbhokW4aBEuWoSLFuGiRbhoES5ahIsW4aJFuGgRLlqEixbhokVYEx3nudGKXE1jTfS6xUWLcNEiXLQIFy3CRYtw0SJctAgXLcJFi3DRIv430eUq2+axJvp7jePPqmzHySXFmuhHwFKVYzNA/6rv/VR/s9BSlMsM1kTPEN4DPkU4I8vAO6APOAgsrhq7GO3ri8aUo5ipKIep1zv9AtipgOACGIrLAAAAAElFTkSuQmCC", - "symbolRepeat": "fixed", - "symbolMargin": "5%", - "symbolClip": true, - "symbolSize": 22.5, - "symbolPosition": "start", - "symbolOffset": [ - 20, - 0 - ], - "symbolBoundingData": 300, - "data": [ - 13, - 42, - 67, - 81, - 86, - - ], - "z": 10 - }, - { - "type": "pictorialBar", - "itemStyle": { - "normal": { - "opacity": 0.3 - } - }, - "label": { - "normal": { - "show": false - } - }, - "animationDuration": 0, - "symbolRepeat": "fixed", - "symbolMargin": "5%", - "symbol": "image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAYAAAA4qEECAAADYElEQVR4nO2dz0sUYRjHP7tIdAmxQ1LdlhCKMohAIsgiyEuHjkUEFQTlpejS/xCCBB06RBGBBKIG4cGyH0qHBKE9eKyFqBQPRQeNCt06vGNY7bq7szPfeZLnAwuzM+/zgw/DDvMu70wOIVveLscJOwycA44A24CfwAfgKXAbeFVvovlC/o/vuVwuTj+x0FWiYdGbgXvA8RrjHgAXgIVaCbMU3SKr1BhtwEtgZx1jTwI7gG7ga5pNNUO+9pBMuEN9klfYD9xMqZdEsCj6AHAiRtxZYFeyrSSHRdGnYsblCD8jJrEoek8TsbsT6yJhLIrelFFsqlgUPZtRbKpYFP2kidjxxLpIGIuiB4AvMeLmgJGEe0kMi6I/AVdjxPVSx91hVlgUDXAXuEaY16jFMnAJeJhqR01iVTTAdeAYUFxjzBRwCLgl6agJrM51rDAO7AP2EmbxthPO8vfAc2Ams84axLpoCGKLrH1mm8eC6KPAGaAL2Fpj7AZgY7T9DfhRY/wc4eflPmH+OjOynI8uEGbpukXlJ4Dz84V8aWWHcj46q4thFzCNTjJRren2UrlLWPM3WYjuAMYIk/tq2oCx9lK5Q11YLboFGARaxXVX0woMtpfK0uuTWvRFoFNcsxKdhF5kqEX3iuuthbQXtehG/gdMG2kvlm/B1xUuWoSLFmFF9CRwg2TnM4pRzskEc8bGiugR4ArhNjkpJqKcJv51sSJ63eOiRbhoES5ahIsW4aJFuGgRLlqEixbhokW4aBEuWoSLFuGiRbhoES5ahIsW4aJFuGgRLlqEWvTHKvs/p1izWu5qvaSCWvTlCvtmgeEUaw5TeUVtpV5SQy16COgBRoHXhMWb3aS7PnAhqjEQ1RwFeuYL+aEUa/5DFmtYHkefOEwQVmcBvKD+FQNvgNN/P+pHiV8MRbhoES5ahIsW4aJFuGgRLlqEixbhokW4aBEuWoSLFuGiRbhoES5ahIsW4aJFuGgRLlqEixbhokVYEx3nudGKXE1jTfS6xUWLcNEiXLQIFy3CRYtw0SJctAgXLcJFi3DRIv430eUq2+axJvp7jePPqmzHySXFmuhHwFKVYzNA/6rv/VR/s9BSlMsM1kTPEN4DPkU4I8vAO6APOAgsrhq7GO3ri8aUo5ipKIep1zv9AtipgOACGIrLAAAAAElFTkSuQmCC", - "symbolSize": 22.5, - "symbolBoundingData": 300, - "symbolPosition": "start", - "symbolOffset": [ - 20, - 0 - ], - "data": [ - 13, - 42, - 67, - 81, - 86, - - ], - "z": 5 - } - ] -}; - - -// Make dynamic data. -function random() { - return +(Math.random() * (maxData - 10)).toFixed(1); -} -setInterval(function () { - var chart = window.myChart4; - if (!chart || !chart.setOption) return; - var dynamicData = [random(), random(), random(), random(), random(), random(), random(), random(), random(), random()]; - chart.setOption({ - series: [{ - data: dynamicData.slice() - }, { - data: dynamicData.slice() - }] + // 模拟数据动态变化 + setInterval(() => { + const newData = option.series[0].data.map(val => { + let change = Math.floor(Math.random() * 3) - 1; + let newVal = val + change; + if (newVal > 70) newVal = 70; + if (newVal < 35) newVal = 35; + return newVal; + }); + + myChart.setOption({ + series: [{ + data: newData + }] + }); + }, 5000); }); -}, 3000); -//////////////////////收费站收费排行2 end +})(); -//收费站收费排行2 -var spirit = '../images.ksh45.png'; +// 屠宰场概况图表逻辑 +(function() { + // 确保 DOM 加载完成 + $(function() { + const chartDom = document.getElementById('slaughterhouse_chart'); + if (!chartDom) return; + + const myChart = echarts.init(chartDom); + + const option = { + tooltip: { + trigger: 'item', + formatter: '{a}
{b}: {c} ({d}%)' + }, + legend: { + orient: 'vertical', + right: 10, + top: 'center', + textStyle: { + color: '#fff' + }, + data: ['正常运行', '检修中', '待运行', '已关闭'] + }, + series: [ + { + name: '屠宰场状态', + type: 'pie', + radius: ['50%', '70%'], + center: ['35%', '50%'], + avoidLabelOverlap: false, + label: { + show: false, + position: 'center' + }, + emphasis: { + label: { + show: true, + fontSize: '20', + fontWeight: 'bold', + color: '#fff' + } + }, + labelLine: { + show: false + }, + data: [ + { value: 12, name: '正常运行', itemStyle: { color: '#37a2da' } }, + { value: 3, name: '检修中', itemStyle: { color: '#ffdb5c' } }, + { value: 5, name: '待运行', itemStyle: { color: '#ff9f7f' } }, + { value: 1, name: '已关闭', itemStyle: { color: '#fb7293' } } + ] + } + ] + }; + + myChart.setOption(option); + + // 窗口大小改变时重置图表大小 + window.addEventListener("resize", function () { + myChart.resize(); + }); -var maxData = 200; - -option41 = { - "title": { - "text": " ", - "left": "center", - "y": "10", - "textStyle": { - "color": "#fff" - } - }, - - "grid": { - "left": 30, - "top": 0, - "bottom": 10 - }, - "tooltip": { - "trigger": "item", - "textStyle": { - "fontSize": 12 - }, - "formatter": "{b0}:{c0}" - }, - "xAxis": { - "max": 100, - "splitLine": { - "show": false - }, - "axisLine": { - "show": false - }, - "axisLabel": { - "show": false - }, - "axisTick": { - "show": false - } - }, - "yAxis": [ - { - "type": "category", - "inverse": false, - "data": [ - "朔州", - "大同", - "运城", - "忻州", - "临汾", - ], - "axisLine": { - "show": false - }, - "axisTick": { - "show": false - }, - "axisLabel": { - "margin": -4, - "textStyle": { - "color": "#fff", - "fontSize": 16.25 - } - } - }, - - ], - "series": [ - { - "type": "pictorialBar", - "symbol": "image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAYAAAA4qEECAAADYElEQVR4nO2dz0sUYRjHP7tIdAmxQ1LdlhCKMohAIsgiyEuHjkUEFQTlpejS/xCCBB06RBGBBKIG4cGyH0qHBKE9eKyFqBQPRQeNCt06vGNY7bq7szPfeZLnAwuzM+/zgw/DDvMu70wOIVveLscJOwycA44A24CfwAfgKXAbeFVvovlC/o/vuVwuTj+x0FWiYdGbgXvA8RrjHgAXgIVaCbMU3SKr1BhtwEtgZx1jTwI7gG7ga5pNNUO+9pBMuEN9klfYD9xMqZdEsCj6AHAiRtxZYFeyrSSHRdGnYsblCD8jJrEoek8TsbsT6yJhLIrelFFsqlgUPZtRbKpYFP2kidjxxLpIGIuiB4AvMeLmgJGEe0kMi6I/AVdjxPVSx91hVlgUDXAXuEaY16jFMnAJeJhqR01iVTTAdeAYUFxjzBRwCLgl6agJrM51rDAO7AP2EmbxthPO8vfAc2Ams84axLpoCGKLrH1mm8eC6KPAGaAL2Fpj7AZgY7T9DfhRY/wc4eflPmH+OjOynI8uEGbpukXlJ4Dz84V8aWWHcj46q4thFzCNTjJRren2UrlLWPM3WYjuAMYIk/tq2oCx9lK5Q11YLboFGARaxXVX0woMtpfK0uuTWvRFoFNcsxKdhF5kqEX3iuuthbQXtehG/gdMG2kvlm/B1xUuWoSLFmFF9CRwg2TnM4pRzskEc8bGiugR4ArhNjkpJqKcJv51sSJ63eOiRbhoES5ahIsW4aJFuGgRLlqEixbhokW4aBEuWoSLFuGiRbhoES5ahIsW4aJFuGgRLlqEWvTHKvs/p1izWu5qvaSCWvTlCvtmgeEUaw5TeUVtpV5SQy16COgBRoHXhMWb3aS7PnAhqjEQ1RwFeuYL+aEUa/5DFmtYHkefOEwQVmcBvKD+FQNvgNN/P+pHiV8MRbhoES5ahIsW4aJFuGgRLlqEixbhokW4aBEuWoSLFuGiRbhoES5ahIsW4aJFuGgRLlqEixbhokVYEx3nudGKXE1jTfS6xUWLcNEiXLQIFy3CRYtw0SJctAgXLcJFi3DRIv430eUq2+axJvp7jePPqmzHySXFmuhHwFKVYzNA/6rv/VR/s9BSlMsM1kTPEN4DPkU4I8vAO6APOAgsrhq7GO3ri8aUo5ipKIep1zv9AtipgOACGIrLAAAAAElFTkSuQmCC", - "symbolRepeat": "fixed", - "symbolMargin": "5%", - "symbolClip": true, - "symbolSize": 22.5, - "symbolPosition": "start", - "symbolOffset": [ - 20, - 0 - ], - "symbolBoundingData": 300, - "data": [ - 51, - 32, - 82, - 42, - 81, - - ], - "z": 10 - }, - { - "type": "pictorialBar", - "itemStyle": { - "normal": { - "opacity": 0.3 - } - }, - "label": { - "normal": { - "show": false - } - }, - "animationDuration": 0, - "symbolRepeat": "fixed", - "symbolMargin": "5%", - "symbol": "image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAYAAAA4qEECAAADYElEQVR4nO2dz0sUYRjHP7tIdAmxQ1LdlhCKMohAIsgiyEuHjkUEFQTlpejS/xCCBB06RBGBBKIG4cGyH0qHBKE9eKyFqBQPRQeNCt06vGNY7bq7szPfeZLnAwuzM+/zgw/DDvMu70wOIVveLscJOwycA44A24CfwAfgKXAbeFVvovlC/o/vuVwuTj+x0FWiYdGbgXvA8RrjHgAXgIVaCbMU3SKr1BhtwEtgZx1jTwI7gG7ga5pNNUO+9pBMuEN9klfYD9xMqZdEsCj6AHAiRtxZYFeyrSSHRdGnYsblCD8jJrEoek8TsbsT6yJhLIrelFFsqlgUPZtRbKpYFP2kidjxxLpIGIuiB4AvMeLmgJGEe0kMi6I/AVdjxPVSx91hVlgUDXAXuEaY16jFMnAJeJhqR01iVTTAdeAYUFxjzBRwCLgl6agJrM51rDAO7AP2EmbxthPO8vfAc2Ams84axLpoCGKLrH1mm8eC6KPAGaAL2Fpj7AZgY7T9DfhRY/wc4eflPmH+OjOynI8uEGbpukXlJ4Dz84V8aWWHcj46q4thFzCNTjJRren2UrlLWPM3WYjuAMYIk/tq2oCx9lK5Q11YLboFGARaxXVX0woMtpfK0uuTWvRFoFNcsxKdhF5kqEX3iuuthbQXtehG/gdMG2kvlm/B1xUuWoSLFmFF9CRwg2TnM4pRzskEc8bGiugR4ArhNjkpJqKcJv51sSJ63eOiRbhoES5ahIsW4aJFuGgRLlqEixbhokW4aBEuWoSLFuGiRbhoES5ahIsW4aJFuGgRLlqEWvTHKvs/p1izWu5qvaSCWvTlCvtmgeEUaw5TeUVtpV5SQy16COgBRoHXhMWb3aS7PnAhqjEQ1RwFeuYL+aEUa/5DFmtYHkefOEwQVmcBvKD+FQNvgNN/P+pHiV8MRbhoES5ahIsW4aJFuGgRLlqEixbhokW4aBEuWoSLFuGiRbhoES5ahIsW4aJFuGgRLlqEixbhokVYEx3nudGKXE1jTfS6xUWLcNEiXLQIFy3CRYtw0SJctAgXLcJFi3DRIv430eUq2+axJvp7jePPqmzHySXFmuhHwFKVYzNA/6rv/VR/s9BSlMsM1kTPEN4DPkU4I8vAO6APOAgsrhq7GO3ri8aUo5ipKIep1zv9AtipgOACGIrLAAAAAElFTkSuQmCC", - "symbolSize": 22.5, - "symbolBoundingData": 300, - "symbolPosition": "start", - "symbolOffset": [ - 20, - 0 - ], - "data": [ - 51, - 32, - 82, - 42, - 81, - - ], - "z": 5 - } - ] -}; - - -// Make dynamic data. -function random() { - return +(Math.random() * (maxData - 10)).toFixed(1); -} -setInterval(function () { - var chart = window.myChart41; - if (!chart || !chart.setOption) return; - var dynamicData = [random(), random(), random(), random(), random(), random(), random(), random(), random(), random()]; - chart.setOption({ - series: [{ - data: dynamicData.slice() - }, { - data: dynamicData.slice() - }] + // 模拟数据动态变化 + setInterval(() => { + const newData = option.series[0].data.map(item => { + let change = Math.floor(Math.random() * 3) - 1; + let newVal = item.value + change; + if (newVal < 0) newVal = 0; + return { ...item, value: newVal }; + }); + + myChart.setOption({ + series: [{ + data: newData + }] + }); + }, 6000); }); -}, 3000); -//////////////////////收费站收费排行2 end - -//今日实时收费 - -var shadowColor = '#374b86'; -var value = 80; -option5 = { - - title: { - //text: `${value}万辆`, - text: `车辆总数`, - subtext: '', - left: 'center', - top: 'center',//top待调整 - textStyle: { - color: '#fff', - fontSize: 16, - fontFamily: 'PingFangSC-Regular' - }, - subtextStyle: { - color: '#ff', - fontSize: 14, - fontFamily: 'PingFangSC-Regular', - top: 'center' - }, - itemGap: -1//主副标题间距 - }, - - series: [{ - name: 'pie1', - type: 'pie', - clockWise: true, - radius: ['65%', '70%'], - itemStyle: { - normal: { - label: { - show: false - }, - labelLine: { - show: false - } - } - }, - hoverAnimation: false, - data: [{ - value: value, - name: 'completed', - itemStyle: { - normal: { - borderWidth: 8, - borderColor: { - colorStops: [{ - offset: 0, - color: '#1d54f7' || '#00cefc' // 0% 处的颜色 - }, { - offset: 1, - color: '#68eaf9' || '#367bec' // 100% 处的颜色 - }] - }, - color: { // 完成的圆环的颜色 - colorStops: [{ - offset: 0, - color: '#1d54f7' || '#00cefc' // 0% 处的颜色 - }, { - offset: 1, - color: '#68eaf9' || '#367bec' // 100% 处的颜色 - }] - }, - label: { - show: false - }, - labelLine: { - show: false - } - } - } - }, { - name: 'gap', - value: 100 - value, - itemStyle: { - normal: { - label: { - show: false - }, - labelLine: { - show: false - }, - color: 'rgba(0, 0, 0, 0)', - borderColor: 'rgba(0, 0, 0, 0)', - borderWidth: 0 - } - } - }] - }] -} - -var shadowColor = '#374b86'; -var value = 85; -option6 = { - - title: { - //text: `${value}万辆`, - text: `今日上线`, - subtext: '', - left: 'center', - top: 'center',//top待调整 - textStyle: { - color: '#fff', - fontSize: 16, - fontFamily: 'PingFangSC-Regular' - }, - subtextStyle: { - color: '#ff', - fontSize: 14, - fontFamily: 'PingFangSC-Regular', - top: 'center' - }, - itemGap: -1//主副标题间距 - }, - - series: [{ - name: 'pie1', - type: 'pie', - clockWise: true, - radius: ['65%', '70%'], - itemStyle: { - normal: { - label: { - show: false - }, - labelLine: { - show: false - } - } - }, - hoverAnimation: false, - data: [{ - value: value, - name: 'completed', - itemStyle: { - normal: { - borderWidth: 8, - borderColor: { - colorStops: [{ - offset: 0, - color: '#02df94' || '#25d6bc' // 0% 处的颜色 - }, { - offset: 1, - color: '#28d3d0' || '#14dbaa' // 100% 处的颜色 - }] - }, - color: { // 完成的圆环的颜色 - colorStops: [{ - offset: 0, - color: '#02df94' || '#25d6bc' // 0% 处的颜色 - }, { - offset: 1, - color: '#28d3d0' || '#14dbaa' // 100% 处的颜色 - }] - }, - label: { - show: false - }, - labelLine: { - show: false - } - } - } - }, { - name: 'gap', - value: 100 - value, - itemStyle: { - normal: { - label: { - show: false - }, - labelLine: { - show: false - }, - color: 'rgba(0, 0, 0, 0)', - borderColor: 'rgba(0, 0, 0, 0)', - borderWidth: 0 - } - } - }] - }] -} - -var shadowColor = '#374b86'; -var value = 46; -option7 = { - - title: { - //text: `${value}万辆`, - text: `今日报警`, - subtext: '', - left: 'center', - top: 'center',//top待调整 - textStyle: { - color: '#fff', - fontSize: 16, - fontFamily: 'PingFangSC-Regular' - }, - subtextStyle: { - color: '#ff', - fontSize: 14, - fontFamily: 'PingFangSC-Regular', - top: 'center' - }, - itemGap: -1//主副标题间距 - }, - - series: [{ - name: 'pie1', - type: 'pie', - clockWise: true, - radius: ['65%', '70%'], - itemStyle: { - normal: { - label: { - show: false - }, - labelLine: { - show: false - } - } - }, - hoverAnimation: false, - data: [{ - value: value, - name: 'completed', - itemStyle: { - normal: { - borderWidth: 8, - borderColor: { - colorStops: [{ - offset: 0, - color: '#eb3600' || '#cc9a00' // 0% 处的颜色 - }, { - offset: 1, - color: '#d0a00e' || '#d0570e' // 100% 处的颜色 - }] - }, - color: { // 完成的圆环的颜色 - colorStops: [{ - offset: 0, - color: '#eb3600' || '#cc9a00' // 0% 处的颜色 - }, { - offset: 1, - color: '#d0a00e' || '#d0570e' // 100% 处的颜色 - }] - }, - label: { - show: false - }, - labelLine: { - show: false - } - } - } - }, { - name: 'gap', - value: 100 - value, - itemStyle: { - normal: { - label: { - show: false - }, - labelLine: { - show: false - }, - color: 'rgba(0, 0, 0, 0)', - borderColor: 'rgba(0, 0, 0, 0)', - borderWidth: 0 - } - } - }] - }] -} -//////////////////////今日实时收费 end - - - - - - - - - - - - - - - - - +})(); diff --git a/datav/monitor.html b/datav/monitor.html new file mode 100644 index 0000000..523cc2f --- /dev/null +++ b/datav/monitor.html @@ -0,0 +1,256 @@ + + + + +仓库监控 + + + + + + +
+ 标题装饰 + + + +
+ +
+

+ 正在连接仓库监控... + 返回大屏 +

+ +
+ +
+
+
+ +
+
+
大门监控
+
+ +
+
+
+ +
+
+
仓库内景 A区
+
+ +
+
+
+ +
+
+
仓库内景 B区
+
+ +
+
+
+ +
+
+
卸货区
+
+ +
+
+
+ +
+
+
饲料区
+
+ +
+
+
+ +
+
+
通道监控
+
+
+
+ + + + + \ No newline at end of file diff --git a/datav/server.js b/datav/server.js index eae33bf..d96c100 100644 --- a/datav/server.js +++ b/datav/server.js @@ -16,6 +16,30 @@ app.use((req, res, next) => { next(); }); +// 专用代理:牛只行情数据 (ad.yunmainiu.com) +// 必须放在通用的 /api 代理之前 +app.use('/api/cattle-market-data', createProxyMiddleware({ + target: 'https://ad.yunmainiu.com', + changeOrigin: true, + secure: false, + pathRewrite: { + '^/': '/api/cattle-data', + }, + onProxyReq: (proxyReq, req, res) => { + console.log(`[牛只行情代理] ${req.method} ${req.url} -> https://ad.yunmainiu.com/api/cattle-data`); + // 伪装请求头,防止被反爬或校验 + proxyReq.setHeader('Host', 'ad.yunmainiu.com'); + proxyReq.setHeader('Referer', 'https://ad.yunmainiu.com/'); + proxyReq.setHeader('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); + }, + onProxyRes: (proxyRes, req, res) => { + console.log(`[牛只行情代理响应] 状态码: ${proxyRes.statusCode}`); + // 允许跨域:覆盖目标服务器的 CORS 设置 + delete proxyRes.headers['access-control-allow-origin']; + proxyRes.headers['Access-Control-Allow-Origin'] = '*'; + } +})); + // API 代理:必须在静态文件服务之前,将 /api 请求代理到 cattletrack.aiotagro.com app.use('/api', createProxyMiddleware({ target: 'https://cattletrack.aiotagro.com', diff --git a/datav/test_api.js b/datav/test_api.js new file mode 100644 index 0000000..b3a25b8 --- /dev/null +++ b/datav/test_api.js @@ -0,0 +1,34 @@ +const https = require('https'); + +const options = { + hostname: 'ad.yunmainiu.com', + port: 443, + path: '/api/cattle-data', + method: 'GET', + headers: { + 'Host': 'ad.yunmainiu.com', + 'Referer': 'https://ad.yunmainiu.com/', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' + } +}; + +const req = https.request(options, (res) => { + console.log('StatusCode:', res.statusCode); + console.log('Headers:', res.headers); + + let data = ''; + res.on('data', (chunk) => { + data += chunk; + }); + + res.on('end', () => { + console.log('Body Length:', data.length); + console.log('Body Preview:', data.substring(0, 500)); + }); +}); + +req.on('error', (e) => { + console.error(e); +}); + +req.end(); \ No newline at end of file diff --git a/datav/test_proxy.js b/datav/test_proxy.js new file mode 100644 index 0000000..16e1674 --- /dev/null +++ b/datav/test_proxy.js @@ -0,0 +1,19 @@ +const http = require('http'); + +http.get('http://127.0.0.1:8081/api/cattle-market-data', (res) => { + console.log('StatusCode:', res.statusCode); + console.log('Headers:', res.headers); + + let data = ''; + res.on('data', (chunk) => { + data += chunk; + }); + + res.on('end', () => { + console.log('Body Length:', data.length); + console.log('Body Preview:', data.substring(0, 500)); + }); + +}).on('error', (e) => { + console.error(e); +}); \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..4fd33c6 --- /dev/null +++ b/readme.md @@ -0,0 +1,46 @@ +# 牛只运输项目 + +## 项目简介 +本项目是一个牛只运输管理系统,旨在提供全方位的牛只运输监控和管理功能。 + +## 项目结构 +- `docs`: 文档目录 +- `admin-system`: 管理后台目录 +- `mini-program`: 小程序APP目录 +- `backend`: 后端服务目录 +- `website`: 官网目录 +- `scripts`: 脚本目录 + +## 文档索引 +请参考 `docs` 目录下的详细文档: + +### 需求文档 +- [整个项目需求文档](docs/整个项目需求文档.md) +- [官网需求文档](docs/官网需求文档.md) +- [后端管理需求文档](docs/后端管理需求文档.md) +- [管理后台需求文档](docs/管理后台需求文档.md) +- [小程序APP需求文档](docs/小程序app需求文档.md) + +### 架构文档 +- [整个项目的架构文档](docs/整个项目的架构文档.md) +- [后端架构文档](docs/后端架构文档.md) +- [小程序架构文档](docs/小程序架构文档.md) +- [管理后台架构文档](docs/管理后台架构文档.md) + +### 详细设计文档 +- [数据库设计文档](docs/数据库设计文档.md) +- [管理后台接口设计文档](docs/管理后台接口设计文档.md) +- [小程序APP接口设计文档](docs/小程序app接口设计文档.md) + +### 开发文档 +- [后端开发文档](docs/后端开发文档.md) +- [小程序APP开发文档](docs/小程序app开发文档.md) +- [管理后台开发文档](docs/管理后台开发文档.md) +- [后端管理开发文档](docs/后端管理开发文档.md) + +### 其他文档 +- [测试文档](docs/测试文档.md) +- [部署文档](docs/部署文档.md) +- [运维文档](docs/运维文档.md) +- [安全文档](docs/安全文档.md) +- [用户手册文档](docs/用户手册文档.md)