地质所 沉降监测网建设项目
suerwei
2024-06-22 0b8e43d5f5fd889ffcb715dafdaa6d4511532665
摄像头列表功能
12个文件已修改
8个文件已添加
1906 ■■■■ 已修改文件
javaweb-plus/javaweb-admin/src/main/java/com/javaweb/web/controller/system/SysIndexController.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-admin/src/main/resources/static/images/icon/blue.png 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-admin/src/main/resources/static/images/icon/red.png 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-admin/src/main/resources/static/images/icon/yellow.png 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-admin/src/main/resources/templates/main.html 362 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-admin/src/main/resources/templates/main4.html 772 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-admin/src/main/resources/templates/system/camera_tub/camera_list.html 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-admin/src/main/resources/templates/system/camera_tub/player2.html 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-admin/src/main/resources/templates/system/camera_tub/tub_list.html 296 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-cms/src/main/java/com/javaweb/geo/controller/ProjectCameraController.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-cms/src/main/java/com/javaweb/geo/domain/Project.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-cms/src/main/java/com/javaweb/geo/domain/ProjectCamera.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-cms/src/main/java/com/javaweb/geo/mapper/ProjectCameraMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-cms/src/main/java/com/javaweb/geo/service/IProjectCameraService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-cms/src/main/java/com/javaweb/geo/service/impl/ProjectCameraServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-cms/src/main/resources/mapper/geo/ProjectCameraMapper.xml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-cms/src/main/resources/templates/geo/project/info.html 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-cms/src/main/resources/templates/geo/projectCamera/add.html 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-cms/src/main/resources/templates/geo/projectCamera/projectCamera.html 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-cms/src/main/resources/templates/geo/projectCamera/projectCamera2.html 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
javaweb-plus/javaweb-admin/src/main/java/com/javaweb/web/controller/system/SysIndexController.java
@@ -6,18 +6,20 @@
import java.util.Map;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.javaweb.cms.util.CmsConstants;
import com.javaweb.common.core.domain.AjaxResult;
import com.javaweb.common.utils.Arith;
import com.javaweb.geo.domain.Hole;
import com.javaweb.geo.domain.HoleMedia;
import com.javaweb.geo.domain.Project;
import com.javaweb.geo.domain.TubLog;
import com.javaweb.geo.domain.*;
import com.javaweb.geo.enums.RecordType;
import com.javaweb.geo.mapper.ProjectCameraMapper;
import com.javaweb.geo.mapper.TubLogMapper;
import com.javaweb.geo.service.IHoleMediaService;
import com.javaweb.geo.service.IHoleService;
import com.javaweb.geo.service.IProjectCameraService;
import com.javaweb.geo.service.IProjectService;
import com.javaweb.geo.vo.IndexVo;
import com.javaweb.geo.vo.ProjectProcessVO;
@@ -26,7 +28,7 @@
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.*;
import com.javaweb.common.config.Global;
import com.javaweb.common.core.controller.BaseController;
import com.javaweb.framework.util.ShiroUtils;
@@ -34,10 +36,6 @@
import com.javaweb.system.domain.SysUser;
import com.javaweb.system.service.ISysMenuService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
@@ -48,6 +46,14 @@
 */
@Controller
public class SysIndexController extends BaseController {
    private String prefix = "system/camera_tub";
    private String appkey = "af786eacc71d43ef9393c028cf4face7";
    private String secret = "9ad87671f63d2258af6fd9b2e5fa6005";
    private String postUrl ="https://open.ys7.com/api/lapp/token/get";
    @Autowired
    private ISysMenuService menuService;
@@ -69,6 +75,9 @@
    @Autowired
    private ProjectCameraMapper projectCameraMapper;
    @Autowired
    private IProjectCameraService cameraService;
    private String getAdminIndex() {
        return configService.selectConfigByKey(CmsConstants.KEY_ADMIN_INDEX);
@@ -77,6 +86,16 @@
    @RequestMapping("/admin")
    public String admin() {
        return "forward:/index";
    }
    @RequestMapping("/system/camera")
    public String cameraList() {
        return prefix + "/camera_list";
    }
    @RequestMapping("/system/tub")
    public String tubList() {
        return prefix + "/tub_list";
    }
    // 系统首页
@@ -267,4 +286,94 @@
        return  ajaxResult;
    }
    /**
     * 获取在线摄像头的信息
     * @return
     */
    @ResponseBody
    @GetMapping("/system/stat/cameraData")
    public AjaxResult cameraData() {
        AjaxResult ajaxResult = new AjaxResult();
        List<ProjectCamera> cameraDataList = cameraService.selectCameraDataOnLine();
        ajaxResult.put("cameraData",cameraDataList);
        return ajaxResult;
    }
    /**
     * 根据projectId获取在线摄像头的信息
     * @return
     */
    @ResponseBody
    @GetMapping("/system/stat/cameraData/{projectId}")
    public AjaxResult cameraData2(@PathVariable("projectId") String projectId) {
        AjaxResult ajaxResult = new AjaxResult();
        ProjectCamera param = new ProjectCamera();
        param.setProjectId(projectId);
        List<ProjectCamera> cameraDataList = cameraService.selectProjectCameraList(param);
        if (!ObjectUtils.isEmpty(cameraDataList)){
            for (ProjectCamera item : cameraDataList) {
                String url = item.getIp();
                Map<String, Object> paramMap = new HashMap<>();
                paramMap.put("appKey", appkey);
                paramMap.put("appSecret", secret);
                HttpResponse response = HttpRequest.post(postUrl) .form(paramMap).execute();
                String body = response.body();
                JSONObject jsonObject = JSONUtil.parseObj(body);
                String code = jsonObject.getStr("code");
                StringBuffer buffer = new StringBuffer();
                if(code.equals("200")){
                    JSONObject data  = (JSONObject) jsonObject.get("data");
                    String token = data.getStr("accessToken");
                    buffer.append("https://open.ys7.com/console/jssdk/pc.html?accessToken=");
                    buffer.append(token);
                    buffer.append("&url=");
                    buffer.append(url);
                }
                logger.debug(buffer.toString());
                item.setUrl(buffer.toString());
            }
        }
        ajaxResult.put("cameraDataList",cameraDataList);
        return ajaxResult;
    }
    /**
     * 根据projectId获取在线摄像头的信息
     * @return
     */
    @GetMapping("/player")
    public String player(String projectId,ModelMap mmap) {
        ProjectCamera param = new ProjectCamera();
        param.setProjectId(projectId);
        List<ProjectCamera> cameraDataList = cameraService.selectProjectCameraList(param);
        if (!ObjectUtils.isEmpty(cameraDataList)){
            for (ProjectCamera item : cameraDataList) {
                String url = item.getIp();
                Map<String, Object> paramMap = new HashMap<>();
                paramMap.put("appKey", appkey);
                paramMap.put("appSecret", secret);
                HttpResponse response = HttpRequest.post(postUrl) .form(paramMap).execute();
                String body = response.body();
                JSONObject jsonObject = JSONUtil.parseObj(body);
                String code = jsonObject.getStr("code");
                StringBuffer buffer = new StringBuffer();
                if(code.equals("200")){
                    JSONObject data  = (JSONObject) jsonObject.get("data");
                    String token = data.getStr("accessToken");
                    buffer.append("https://open.ys7.com/console/jssdk/pc.html?accessToken=");
                    buffer.append(token);
                    buffer.append("&url=");
                    buffer.append(url);
                }
                item.setUrl(buffer.toString());
            }
        }
        mmap.put("cameraDataList",cameraDataList);
        return prefix + "/player2";
    }
}
javaweb-plus/javaweb-admin/src/main/resources/static/images/icon/blue.png
javaweb-plus/javaweb-admin/src/main/resources/static/images/icon/red.png
javaweb-plus/javaweb-admin/src/main/resources/static/images/icon/yellow.png
javaweb-plus/javaweb-admin/src/main/resources/templates/main.html
@@ -18,86 +18,10 @@
    [v-cloak]{
        display: none;
    }
    .el-card__header{
        height: 40px;
        padding: 8px 20px;
    }
    .active-red{
        width: 20px;
        height: 20px;
        border-radius: 50%;
        font-size: 14px;
        color: white;
        background: #F56C6C;
        text-align: center;
        line-height: 20px;
        float: left;
    }
    .active-yellow{
        width: 20px;
        height: 20px;
        border-radius: 50%;
        font-size: 14px;
        color: white;
        background: #E6A23C;
        text-align: center;
        line-height: 20px;
        float: left;
    }
    .active-blue{
        width: 20px;
        height: 20px;
        border-radius: 50%;
        font-size: 14px;
        color: white;
        background: #67C23A;
        text-align: center;
        line-height: 20px;
        float: left;
    }
    .cdcode{
        width: 15%;
        float: left;
        margin-left: 10px;
        font-size: 16px;
        line-height: 20px;
    }
    .cdstatus{
        width: 15%;
        float: left;
        margin-left: 0px;
        font-size: 16px;
        line-height: 20px;
    }
    .cdprocess{
        width: 60%;
        float: left;
        margin-left: 10px;
    }
    .rankrow{
        margin-top: 12px;
        cursor: pointer;
    }
    .ilblock{
        border-left: 1px solid #e3e5e7;
        padding: 0 40px;
        align-content: center;
    }
    .ilblock>span{
        display: block;
        line-height: 30px;
    }
    <!-- 表格样式 -->
    .el-table, .el-table__expanded-cell {
        background-color: transparent;
        color: #4D4D4D;
        font-size: 13px;
    }
    .el-table th,
    .el-table tr,
    .el-table td {
@@ -108,235 +32,26 @@
        font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
        font-weight: Normal;
    }
    .el-table::before {
        height: 0px;
    }
    .el-table__body tr,
    .el-table__body td {
        padding: 0;
        height: 22px;
    }
    .el-table__row.warning-row {
        background:rgb(252,212,165);
    }
    .el-table__body-wrapper::-webkit-scrollbar-track {
        background-color: rgb(252,212,165);
    }
    .el-table__body-wrapper::-webkit-scrollbar {
        width: 10px;
        opacity: 0.5;
    }
    .el-table__body-wrapper::-webkit-scrollbar-thumb {
        border-radius: 15px;
        background-color:rgb(252,212,165);
    .custom-icon:hover {
        color: #0981ea;
        cursor: pointer;
    }
</style>
</head>
<body class="gray-bg">
    <div class="content" id="app" v-cloak>
        <el-row style="height: 127px;">
            <el-col :span="6">
                <el-card class="box-card">
                    <div style="flex:4;padding-right: 20px;" >
                        <div>
                            <li class="el-icon-s-promotion" style="font-size: 18px;margin-right: 5px;margin-left: -5px;color: #409eff;"></li>
                            <span style="color:rgba(0,0,0,.65);font-size: 15px;font-weight: bold;">场地数量</span>
                        </div>
                        <div style="text-align: center;">
                        <span style="color:#ED1C24;font-size: 30px;word-break: break-all;line-height: 70px">34
                        </span>
                        </div>
                    </div>
                    <div style="flex:6;" class="ilblock">
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            协调中
                            <span style="float: right">{{indexDataCount.projectStatus0}}</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #f56c6c">-->
                        </span>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            待开工
                            <span style="float: right">{{indexDataCount.projectStatus1}}</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #e6a23c">-->
                        </span>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            进行中
                            <span style="float: right">{{indexDataCount.projectStatus2}}</span>
<!--                            <li class="el-icon-caret-top" style="color: #409eff">-->
                        </span>
                    </div>
                </el-card>
            </el-col>
            <el-col :span="6">
                <el-card class="box-card">
                    <div style="flex:4;padding-right: 20px;">
                        <div>
                            <li class="el-icon-coin" style="font-size: 18px;margin-right: 5px;margin-left: -5px;color: #085abe"></li>
                            <span style="color:rgba(0,0,0,.65);font-size: 15px;font-weight: bold;">钻孔进尺</span>
                        </div>
                        <div style="text-align: center">
                        <span style="color:#1894F6;font-size: 30px;word-break: break-all;line-height: 70px;">647
                        </span>
                        </div>
                    </div>
                    <div style="flex:6;" class="ilblock">
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            总进尺 <span style="float: right">{{indexDataCount.footageCount}}m</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #f56c6c">-->
                        </span>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            已完成   <span style="float: right">{{indexDataCount.footageCplCount}}m</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #409eff">-->
                        </span>
                    </div>
                </el-card>
            </el-col>
            <el-col :span="6">
                <el-card class="box-card">
                    <div style="flex:4;padding-right: 20px;">
                        <div>
                            <li class="el-icon-video-camera" style="font-size: 18px;margin-right: 5px;margin-left: -5px;color: #11d713"></li>
                            <span style="color:rgba(0,0,0,.65);font-size: 15px;font-weight: bold;">实时监控</span>
                        </div>
                        <div style="text-align: center">
                        <span style="color:#F7931E;font-size: 30px;word-break: break-all;line-height: 70px">68
                        </span>
                        </div>
                    </div>
                    <div style="flex:6;" class="ilblock">
                        <div>
                        </div>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            已安装  <span style="float: right">{{indexDataCount.cameraCount}}</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #f56c6c">-->
                        </span>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            未安装   <span style="float: right">{{indexDataCount.cameraCountNaN}}</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #409eff">-->
                        </span>
                    </div>
                </el-card>
            </el-col>
            <el-col :span="6">
                <el-card class="box-card">
                    <div style="flex:4;padding-right: 20px;">
                        <div>
                            <li class="el-icon-s-order" style="font-size: 18px;margin-right: 5px;margin-left: -5px;color: #917ed0"></li>
                            <span style="color:rgba(0,0,0,.65);font-size: 15px;font-weight: bold;">资料文件</span>
                        </div>
                        <div style="text-align: center">
                        <span style="color:#F7931E;font-size: 30px;word-break: break-all;line-height: 70px;">
                            {{indexDataCount.fileCount}}
                        </span>
                        </div>
                    </div>
                    <div style="flex:6;" class="ilblock">
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            施工资料  <span style="float: right">0</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #f56c6c">-->
                        </span>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            安全资料   <span style="float: right">0</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #409eff">-->
                        </span>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            质量资料   <span style="float: right">0</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #409eff">-->
                        </span>
                    </div>
                </el-card>
            </el-col>
        </el-row>
        <el-row>
            <el-col :span="16">
                <el-card class="box-card">
                    <div style="height: 200px;width: 100%;">
                        <h3>材料统计</h3>
                        <el-col :span="10" style="height: 200px;">
                            <div style="margin-top: 15px">
                                <template>
                                    <el-table :data="tubLogs" border size="small" style="width: 100%"
                                              :header-cell-style="{color: '#4D4D4D',background: '#F7931E',fontWeight: '400'}"
                                              :row-class-name="tableRowClassName">
                                        <!--                                    <el-table-column prop="code" label="序号"></el-table-column>-->
                                        <el-table-column prop="tubName" label="名称"></el-table-column>
                                        <el-table-column prop="inboundNumber" label="入库数量"></el-table-column>
                                        <el-table-column prop="outboundNumber" label="出库数量"></el-table-column>
                                        <el-table-column prop="unit" label="单位"></el-table-column>
                                    </el-table>
                                </template>
                            </div>
                        </el-col>
                        <el-col :span="14" style="height: 200px;">
                            <div id="column-chart" style="height: 180px; width: 100%;"></div>
                        </el-col>
                    </div>
                </el-card>
                <el-card class="box-card" style="margin-top: 20px;">
                    <div id="map_div" style="width: 100%;height: 550px;margin-top: -5px"></div>
                </el-card>
            </el-col>
            <el-col :span="8">
                <el-card class="box-card">
                    <div style="height: 200px;width: 100%">
                        <div style="width: 100%;height: 20px;">
                            <h3>项目总体进度(%)</h3>
                        </div>
                        <div id="Chart1" style="width: 80%;height: 180px;margin-left: 10%;"></div>
                    </div>
                </el-card>
                <el-card class="box-card" style="margin-top: 20px;">
                    <div style="width: 100%">
                        <div style="width: 100%;height: 20px;margin-bottom: 10px;text-align: center;">
                            <h3>场地详细进度(%)</h3>
                        </div>
                        <div style="width: 100%;height: 500px;overflow: auto">
                            <el-row class="rankrow" v-for='entity in stationProcessData' @click.native='viewStation(entity)'>
                                <el-col :span="2" >
                                    <div v-if="entity.status=='协调中'" class="active-red">{{entity.ranking}}</div>
                                    <div v-if="entity.status=='待开工'" class="active-yellow">{{entity.ranking}}</div>
                                    <div v-if="entity.status=='进行中'" class="active-blue">{{entity.ranking}}</div>
                                </el-col>
                                <el-col :span="7">
                                    <div style="font-size: 16px">{{entity.station}}</div>
                                </el-col >
                                <el-col :span="5">
                                    <div style="font-size: 16px">{{entity.status}}</div>
                                </el-col>
                                <el-col :span="8">
                                    <div>
                                        <el-progress :stroke-width="10" :percentage="entity.value"></el-progress>
                                    </div>
                                </el-col>
                            </el-row>
                        </div>
                    </div>
                </el-card>
            </el-col>
        </el-row>
        <div id="map_div" style="position:fixed;width: 100%;height: 100vh;margin-top: -5px"></div>
        <div style="position:fixed;top: 5px">
            <li onclick="careraFunction()" class="el-icon-video-camera custom-icon" style="font-size: 100px;margin-right: 5px;margin-left: -5px;"></li>
            <li onclick="tubFunction()" class="el-icon-user custom-icon" style="font-size: 100px;margin-right: 5px;margin-left: -5px;"></li>
        </div>
        <div id="Chart1" style="position:fixed;width: 300px;height: 300px;bottom: -60px;right: -40px"></div>
    </div>
@@ -361,9 +76,9 @@
        loadMap();
        getReallyData();
        totalProcess();
        stationProcess();
        indexCount();
        tubLogs();
        //stationProcess();
        //indexCount();
        //tubLogs();
    })
    //场地和地图点击联动
    function viewStation(station) {
@@ -460,6 +175,19 @@
        $.ajaxSettings.async = false;
    }
    //摄像头列表
    function careraFunction() {
        let url = ctx + "/system/camera";
        $.modal.openTab("摄像头列表",url);
    }
    //管材统计
    function tubFunction() {
        let url = ctx + "/system/tub";
        $.modal.openTab("管材统计",url);
    }
    //场地进度
    function stationProcess() {
        let url = ctx + "/system/stat/projectProcess";
@@ -508,6 +236,8 @@
            map.addOverLay(countriesOverlay1)
            countriesOverlay.bringToBack();
        });
        //map.setStyle("indigo");
    }
    function init(sel, transform) {
@@ -559,17 +289,35 @@
    }
    //地图上展示项目点
    function showProjectPoint(data){
        var projectIcon = new T.Icon({
            iconUrl: '/bjfw/images/icon/6.png',
            iconSize: new T.Point(30, 30),
            iconAnchor: new T.Point(6, 40),
        });
        var projectIcon;
        for(let i =0;i<data.length;i++){
            if (data[i].status === '1'){
                projectIcon = new T.Icon({
                    iconUrl: '/bjfw/images/icon/yellow.png',
                    iconSize: new T.Point(30, 30),
                    iconAnchor: new T.Point(6, 40),
                });
            }else if (data[i].status === '2'){
                projectIcon = new T.Icon({
                    iconUrl: '/bjfw/images/icon/blue.png',
                    iconSize: new T.Point(30, 30),
                    iconAnchor: new T.Point(6, 40),
                });
            }else {
                projectIcon = new T.Icon({
                    iconUrl: '/bjfw/images/icon/red.png',
                    iconSize: new T.Point(30, 30),
                    iconAnchor: new T.Point(6, 40),
                });
            }
            let lng = data[i].lng;
            let lat = data[i].lat;
            let marker = new T.Marker(new T.LngLat(lng, lat), { title: "场地位置",icon:projectIcon});
            let proj = infoWindowProject(data[i]);
            addClickHandler(proj, marker);
            map.addOverLay(marker);
        }
@@ -585,7 +333,7 @@
                "<font style='font-weight: bolder;'>场地编号 :</font>" + e.code + "<br>" +
                "<font style='font-weight: bolder;'>场地名字 :</font>" + e.fullName + "<br>" +
                "<font style='font-weight: bolder;'>负责人 :</font>" + e.leader + "<br>" +
                "<a class='btn' onclick=viewdata(" +"'" + ids+ "'" + ")>场地数据</a>" +
                "<a class='btn' onclick=viewdata(" +"'" + ids+ "'" + ")>场地数据</a>" + "<br>" +
                "</div>" +
                "</div>" +
                "</div>";
@@ -597,6 +345,7 @@
    function addClickHandler(content, marker) {
        marker.addEventListener("click", function (e) {
            console.log("你点击了",content);
            openInfo(content, e)
        });
    }
@@ -621,7 +370,7 @@
        $.ajaxSettings.async = false;
        var option = {
            backgroundColor: "#fff",
            backgroundColor: "transparent",
            series: [
                {
                    type: "gauge",
@@ -760,11 +509,6 @@
        Chart1.setOption(option);
    }
</script>
</body>
</html>
javaweb-plus/javaweb-admin/src/main/resources/templates/main4.html
New file
@@ -0,0 +1,772 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('弹层组件')" />
<link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet" />
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet" />
<link href="../static/css/main/animate.min.css" th:href="@{/css/main/animate.min.css}" rel="stylesheet" />
<link href="../static/css/main/style.min862f.css" th:href="@{/css/main/style.min862f.css}" rel="stylesheet" />
<link rel="stylesheet" th:href="@{/css/custom/main.css}" />
<link href="../static/js/elementUI/index.css" th:href="@{/js/elementUI/index.css}" rel="stylesheet" />
<style type="text/css">
    .content {
        width: 100%;
        background-color: rgba(0,0,0,0.01) !important;
        padding:10px;
    }
    [v-cloak]{
        display: none;
    }
    .el-card__header{
        height: 40px;
        padding: 8px 20px;
    }
    .active-red{
        width: 20px;
        height: 20px;
        border-radius: 50%;
        font-size: 14px;
        color: white;
        background: #F56C6C;
        text-align: center;
        line-height: 20px;
        float: left;
    }
    .active-yellow{
        width: 20px;
        height: 20px;
        border-radius: 50%;
        font-size: 14px;
        color: white;
        background: #E6A23C;
        text-align: center;
        line-height: 20px;
        float: left;
    }
    .active-blue{
        width: 20px;
        height: 20px;
        border-radius: 50%;
        font-size: 14px;
        color: white;
        background: #67C23A;
        text-align: center;
        line-height: 20px;
        float: left;
    }
    .cdcode{
        width: 15%;
        float: left;
        margin-left: 10px;
        font-size: 16px;
        line-height: 20px;
    }
    .cdstatus{
        width: 15%;
        float: left;
        margin-left: 0px;
        font-size: 16px;
        line-height: 20px;
    }
    .cdprocess{
        width: 60%;
        float: left;
        margin-left: 10px;
    }
    .rankrow{
        margin-top: 12px;
        cursor: pointer;
    }
    .ilblock{
        border-left: 1px solid #e3e5e7;
        padding: 0 40px;
        align-content: center;
    }
    .ilblock>span{
        display: block;
        line-height: 30px;
    }
    <!-- 表格样式 -->
    .el-table, .el-table__expanded-cell {
        background-color: transparent;
        color: #4D4D4D;
        font-size: 13px;
    }
    .el-table th,
    .el-table tr,
    .el-table td {
        background-color: transparent;
        border: 0px;
        color: #4D4D4D;
        font-size: 13px;
        font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
        font-weight: Normal;
    }
    .el-table::before {
        height: 0px;
    }
    .el-table__body tr,
    .el-table__body td {
        padding: 0;
        height: 22px;
    }
    .el-table__row.warning-row {
        background:rgb(252,212,165);
    }
    .el-table__body-wrapper::-webkit-scrollbar-track {
        background-color: rgb(252,212,165);
    }
    .el-table__body-wrapper::-webkit-scrollbar {
        width: 10px;
        opacity: 0.5;
    }
    .el-table__body-wrapper::-webkit-scrollbar-thumb {
        border-radius: 15px;
        background-color:rgb(252,212,165);
    }
</style>
</head>
<body class="gray-bg">
    <div class="content" id="app" v-cloak>
        <el-row style="height: 127px;">
            <el-col :span="6">
                <el-card class="box-card">
                    <div style="flex:4;padding-right: 20px;" >
                        <div>
                            <li class="el-icon-s-promotion" style="font-size: 18px;margin-right: 5px;margin-left: -5px;color: #409eff;"></li>
                            <span style="color:rgba(0,0,0,.65);font-size: 15px;font-weight: bold;">场地数量</span>
                        </div>
                        <div style="text-align: center;">
                        <span style="color:#ED1C24;font-size: 30px;word-break: break-all;line-height: 70px">34
                        </span>
                        </div>
                    </div>
                    <div style="flex:6;" class="ilblock">
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            协调中
                            <span style="float: right">{{indexDataCount.projectStatus0}}</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #f56c6c">-->
                        </span>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            待开工
                            <span style="float: right">{{indexDataCount.projectStatus1}}</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #e6a23c">-->
                        </span>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            进行中
                            <span style="float: right">{{indexDataCount.projectStatus2}}</span>
<!--                            <li class="el-icon-caret-top" style="color: #409eff">-->
                        </span>
                    </div>
                </el-card>
            </el-col>
            <el-col :span="6">
                <el-card class="box-card">
                    <div style="flex:4;padding-right: 20px;">
                        <div>
                            <li class="el-icon-coin" style="font-size: 18px;margin-right: 5px;margin-left: -5px;color: #085abe"></li>
                            <span style="color:rgba(0,0,0,.65);font-size: 15px;font-weight: bold;">钻孔进尺</span>
                        </div>
                        <div style="text-align: center">
                        <span style="color:#1894F6;font-size: 30px;word-break: break-all;line-height: 70px;">647
                        </span>
                        </div>
                    </div>
                    <div style="flex:6;" class="ilblock">
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            总进尺 <span style="float: right">{{indexDataCount.footageCount}}m</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #f56c6c">-->
                        </span>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            已完成   <span style="float: right">{{indexDataCount.footageCplCount}}m</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #409eff">-->
                        </span>
                    </div>
                </el-card>
            </el-col>
            <el-col :span="6">
                <el-card class="box-card">
                    <div style="flex:4;padding-right: 20px;">
                        <div>
                            <li class="el-icon-video-camera" style="font-size: 18px;margin-right: 5px;margin-left: -5px;color: #11d713"></li>
                            <span style="color:rgba(0,0,0,.65);font-size: 15px;font-weight: bold;">实时监控</span>
                        </div>
                        <div style="text-align: center">
                        <span style="color:#F7931E;font-size: 30px;word-break: break-all;line-height: 70px">68
                        </span>
                        </div>
                    </div>
                    <div style="flex:6;" class="ilblock">
                        <div>
                        </div>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            已安装  <span style="float: right">{{indexDataCount.cameraCount}}</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #f56c6c">-->
                        </span>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            未安装   <span style="float: right">{{indexDataCount.cameraCountNaN}}</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #409eff">-->
                        </span>
                    </div>
                </el-card>
            </el-col>
            <el-col :span="6">
                <el-card class="box-card">
                    <div style="flex:4;padding-right: 20px;">
                        <div>
                            <li class="el-icon-s-order" style="font-size: 18px;margin-right: 5px;margin-left: -5px;color: #917ed0"></li>
                            <span style="color:rgba(0,0,0,.65);font-size: 15px;font-weight: bold;">资料文件</span>
                        </div>
                        <div style="text-align: center">
                        <span style="color:#F7931E;font-size: 30px;word-break: break-all;line-height: 70px;">
                            {{indexDataCount.fileCount}}
                        </span>
                        </div>
                    </div>
                    <div style="flex:6;" class="ilblock">
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            施工资料  <span style="float: right">0</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #f56c6c">-->
                        </span>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            安全资料   <span style="float: right">0</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #409eff">-->
                        </span>
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            质量资料   <span style="float: right">0</span>
<!--                            <li class="el-icon-caret-bottom" style="color: #409eff">-->
                        </span>
                    </div>
                </el-card>
            </el-col>
        </el-row>
        <el-row>
            <el-col :span="16">
                <el-card class="box-card">
                    <div style="height: 200px;width: 100%;">
                        <h3>材料统计</h3>
                        <el-col :span="10" style="height: 200px;">
                            <div style="margin-top: 15px">
                                <template>
                                    <el-table :data="tubLogs" border size="small" style="width: 100%"
                                              :header-cell-style="{color: '#4D4D4D',background: '#F7931E',fontWeight: '400'}"
                                              :row-class-name="tableRowClassName">
                                        <!--                                    <el-table-column prop="code" label="序号"></el-table-column>-->
                                        <el-table-column prop="tubName" label="名称"></el-table-column>
                                        <el-table-column prop="inboundNumber" label="入库数量"></el-table-column>
                                        <el-table-column prop="outboundNumber" label="出库数量"></el-table-column>
                                        <el-table-column prop="unit" label="单位"></el-table-column>
                                    </el-table>
                                </template>
                            </div>
                        </el-col>
                        <el-col :span="14" style="height: 200px;">
                            <div id="column-chart" style="height: 180px; width: 100%;"></div>
                        </el-col>
                    </div>
                </el-card>
                <el-card class="box-card" style="margin-top: 20px;">
                    <div id="map_div" style="width: 100%;height: 550px;margin-top: -5px"></div>
                </el-card>
            </el-col>
            <el-col :span="8">
                <el-card class="box-card">
                    <div style="height: 200px;width: 100%">
                        <div style="width: 100%;height: 20px;">
                            <h3>项目总体进度(%)</h3>
                        </div>
                        <div id="Chart1" style="width: 80%;height: 180px;margin-left: 10%;"></div>
                    </div>
                </el-card>
                <el-card class="box-card" style="margin-top: 20px;">
                    <div style="width: 100%">
                        <div style="width: 100%;height: 20px;margin-bottom: 10px;text-align: center;">
                            <h3>场地详细进度(%)</h3>
                        </div>
                        <div style="width: 100%;height: 500px;overflow: auto">
                            <el-row class="rankrow" v-for='entity in stationProcessData' @click.native='viewStation(entity)'>
                                <el-col :span="2" >
                                    <div v-if="entity.status=='协调中'" class="active-red">{{entity.ranking}}</div>
                                    <div v-if="entity.status=='待开工'" class="active-yellow">{{entity.ranking}}</div>
                                    <div v-if="entity.status=='进行中'" class="active-blue">{{entity.ranking}}</div>
                                </el-col>
                                <el-col :span="7">
                                    <div style="font-size: 16px">{{entity.station}}</div>
                                </el-col >
                                <el-col :span="5">
                                    <div style="font-size: 16px">{{entity.status}}</div>
                                </el-col>
                                <el-col :span="8">
                                    <div>
                                        <el-progress :stroke-width="10" :percentage="entity.value"></el-progress>
                                    </div>
                                </el-col>
                            </el-row>
                        </div>
                    </div>
                </el-card>
            </el-col>
        </el-row>
    </div>
    <script th:src="@{/js/jquery.min.js}"></script>
    <script th:src="@{/js/bootstrap.min.js}"></script>
    <script th:src="@{/ajax/libs/flot/jquery.flot.js}"></script>
    <script th:src="@{/ajax/libs/report/echarts/echarts-all.js}"></script>
    <script th:src="@{/js/tdt.js}" type="text/javascript"></script>
    <script src="http://lbs.tianditu.gov.cn/js/lib/d3/d3.min.js" type="text/javascript"></script>
    <script src="http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/D3SvgOverlay.js" type="text/javascript"></script>
    <script th:src="@{/js/custom/main.js}"></script>
    <script th:src="@{/js/vue.min.js}"></script>
    <script th:src="@{/js/elementUI/index.js}"></script>
    <th:block th:include="include :: sparkline-js" />
    <th:block th:include="include :: footer" />
    <script th:inline="javascript">
    $(function() {
        loadMap();
        getReallyData();
        totalProcess();
        stationProcess();
        indexCount();
        tubLogs();
    })
    //场地和地图点击联动
    function viewStation(station) {
        var lng = station.lng;
        var lat = station.lat;
        map.centerAndZoom(new T.LngLat(lng, lat), 13);
    }
    function tubLogs() {
        const chart = echarts.init(document.getElementById("column-chart"));
        const option = {
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow'
                }
            },
            legend: {},
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis: [
                {
                    type: 'category',
                    data: []
                }
            ],
            yAxis: [
                {
                    type: 'value'
                }
            ],
            series: [
                {
                    name: '出库',
                    type: 'bar',
                    emphasis: {
                        focus: 'series'
                    },
                    data: [],
                    itemStyle: {
                        // 修改柱子的颜色
                        color: '#e2b507'
                    }
                },
                {
                    name: '入库',
                    type: 'bar',
                    stack: 'Ad',
                    emphasis: {
                        focus: 'series'
                    },
                    data: [],
                    itemStyle: {
                        // 修改柱子的颜色
                        color: '#2992c6'
                    }
                },
            ]
        };
        let url = ctx + "/system/stat/tubLogData";
        $.ajaxSettings.async = false;
        $.get(url,{},function(res){
            vm.tubLogs = res.tubLogs;
            res.tubLogs.forEach(function(value, index, array) {
                const tubName = value.tubName;
                const inboundNumber = value.inboundNumber;
                const outboundNumber = value.outboundNumber;
                const unit = value.unit;
                option.xAxis[0].data[index] = tubName;
                option.series[0].data[index] = outboundNumber;
                option.series[1].data[index] = inboundNumber;
            });
            chart.setOption(option, true);
        })
        $.ajaxSettings.async = false;
    }
    //首页第一行个数统计
    function indexCount() {
        let url = ctx + "/system/stat/indexDataCount";
        $.ajaxSettings.async = false;
        $.get(url,{},function(res){
            vm.indexDataCount = res.data;
            vm.indexDataCount.cameraCountNaN = 68 -vm.indexDataCount.cameraCount;
        })
        $.ajaxSettings.async = false;
    }
    //场地进度
    function stationProcess() {
        let url = ctx + "/system/stat/projectProcess";
        $.ajaxSettings.async = false;
        $.get(url,{},function(res){
            vm.stationProcessData = res.projectData;
        })
        $.ajaxSettings.async = false;
    }
    var vm = new Vue({
        el: "#app",
        data() {
            return {
                stationProcessData: [],
                indexDataCount :"",
                tubLogs:[],
            };
        },
        methods: {
            tableRowClassName({ row, rowIndex }) {
                if (rowIndex % 2 == 0) {
                    return "";
                } else {
                    return "warning-row";
                }
            },
        }
    });
    // 加载地图
    let map=null;
    var countries = [];
    var countriesOverlay = new T.D3Overlay(init,redraw);
    var countriesOverlay1 = new T.D3Overlay(init1,redraw1);
    function loadMap() {
        map = new T.Map('map_div');
        map.centerAndZoom(new T.LngLat(116.38, 40.2), 9);
        var control = new T.Control.Zoom();
        control.setPosition(T_ANCHOR_TOP_RIGHT);
        map.addControl(control);// 添加缩放平移控件
        var scale = new T.Control.Scale();// 创建比例尺控件对象
        d3.json("/bjfw/js/custom/beijing.json", function (data) {
            countries = data.features;
            map.addOverLay(countriesOverlay)
            countriesOverlay.bringToBack();
            map.addOverLay(countriesOverlay1)
            countriesOverlay.bringToBack();
        });
        //map.setStyle("indigo");
    }
    function init(sel, transform) {
        var upd = sel.selectAll('path.geojson').data(countries);
        upd.enter()
                .append('path')
                .attr("class", "geojson")
                .attr('stroke', 'grey')
                .attr('fill', function (d, i) {
                    //return d3.hsl(Math.random() * 360, 0.9, 0.5)
                    return "transparent"
                })
                .attr('fill-opacity', '0')
    }
    function redraw(sel, transform) {
        sel.selectAll('path.geojson').each(
                function (d, i) {
                    d3.select(this).attr('d', transform.pathFromGeojson)
                }
        )
    }
    function init1(sel, transform) {
        var upd = sel.selectAll('path.geojson1').data(countries);
        upd.enter()
                .append('path')
                .attr("class", "geojson1")
                .attr('stroke', 'grey')
                .attr('fill', function (d, i) {
                    return d3.hsl(Math.random() * 360, 0.9, 0.5)
                })
                .attr('fill-opacity', '0.1')
    }
    function redraw1(sel, transform) {
        sel.selectAll('path.geojson1').each(
                function (d, i) {
                    d3.select(this).attr('d', transform.pathFromGeojson)
                }
        )
    }
    // 获取数据库真实数据
    function getReallyData() {
        let url = window.location.protocol + "//" + window.location.host + "/bjfw/system/stat/project";
        $.get(url,function(res){
            var data = res.projects;
            showProjectPoint(data);
        })
    }
    //地图上展示项目点
    function showProjectPoint(data){
        var projectIcon = new T.Icon({
            iconUrl: '/bjfw/images/icon/6.png',
            iconSize: new T.Point(30, 30),
            iconAnchor: new T.Point(6, 40),
        });
        for(let i =0;i<data.length;i++){
            let lng = data[i].lng;
            let lat = data[i].lat;
            let marker = new T.Marker(new T.LngLat(lng, lat), { title: "场地位置",icon:projectIcon});
            let proj = infoWindowProject(data[i]);
            addClickHandler(proj, marker);
            map.addOverLay(marker);
        }
    }
    function infoWindowProject(e){
        let ids = e.ids + "";
        var sContent =
                "<div style='margin:0px;'>" +
                "<div>" +
                "<div style='margin:1px 0px 1px 2px;width: 200px;'>" +
                "<font style='font-weight: bolder;'>场地编号 :</font>" + e.code + "<br>" +
                "<font style='font-weight: bolder;'>场地名字 :</font>" + e.fullName + "<br>" +
                "<font style='font-weight: bolder;'>负责人 :</font>" + e.leader + "<br>" +
                "<a class='btn' onclick=viewdata(" +"'" + ids+ "'" + ")>场地数据</a>" +
                "</div>" +
                "</div>" +
                "</div>";
        return sContent;
    }
    function viewdata (id) {
        $.modal.openTab("场地导航",ctx+ "/geo/project/navigate?ids="+id);
    }
    function addClickHandler(content, marker) {
        marker.addEventListener("click", function (e) {
            openInfo(content, e)
        });
    }
    function openInfo(content, e) {
        var point = e.lnglat;
        var markerInfoWin = new T.InfoWindow(content, { offset: new T.Point(0, -30) }); // 创建信息窗口对象
        map.openInfoWindow(markerInfoWin, point); //开启信息窗口
    }
    //总进度仪表盘
    function totalProcess() {
        var Chart1 = echarts.init(document.getElementById('Chart1'));
        var pointerData = 0; // 仪表指针数据
        let url = ctx + "/system/stat/totalProcess";
        $.ajaxSettings.async = false;
        $.get(url,{},function(res){
            pointerData = res.pointerData;
            pointerData = (pointerData*100).toFixed(0);
        });
        $.ajaxSettings.async = false;
        var option = {
            backgroundColor: "#fff",
            series: [
                {
                    type: "gauge",
                    radius: 80,
                    z: 1,
                    startAngle: 225,
                    endAngle: -45,
                    splitNumber: 50,
                    title: {
                        color: "red",
                    },
                    splitLine: {
                        show: true,
                        length: 15,
                        distance: -10,
                        lineStyle: {
                            color: "#fff",
                            width: 1,
                        },
                    },
                    detail: {
                        show: true,
                        offsetCenter: [0, 60],
                        fontSize: 22,
                        formatter: (val) => [`{a|${val}}`, `{b|%}`].join(""),
                        rich: {
                            a: {
                                fontSize: 20,
                                color: "rgba(84, 108, 198, 0.65)",
                            },
                            b: {
                                fontSize: 24,
                                color: "rgba(84, 108, 198, 0.65)",
                            },
                        },
                    },
                    // 仪表盘的线,颜色值为一个数组
                    axisLine: {
                        show: true,
                        // 两端是否设置为圆角;在5.0之后的版本有效
                        roundCap: false,
                        lineStyle: {
                            width: 15,
                            shadowColor: "#0093ee", //默认透明
                            shadowOffsetX: 0,
                            shadowOffsetY: 0,
                            shadowBlur: 20,
                            opacity: 1,
                            color: [
                                [
                                    pointerData / 100,
                                    {
                                        x: 0,
                                        y: 0,
                                        x1: 1,
                                        y1: 0,
                                        colorStops: [
                                            {
                                                offset: 0,
                                                color: "rgba(0, 255, 255, 0.6)",
                                            },
                                            {
                                                offset: 1,
                                                color: "rgba(0, 0, 255, .6)",
                                            },
                                        ],
                                    },
                                ],
                                [1, "rgba(0,0,0,0.15)"],
                            ],
                        },
                    },
                    // 仪表盘刻度标签
                    axisLabel: {
                        show: true,
                        color: "rgba(84, 108, 198, 0.65)",
                        fontSize: 14,
                        distance: 20,
                        formatter: (val) => {
                            const num = Math.floor(val);
                            return num % 20 === 0 ? num : "";
                        },
                    },
                    // 刻度
                    axisTick: {
                        show: false,
                    },
                    // 指针,此设置仅对5.0以上的版本生效
                    anchor: {
                        show: true,
                        icon: "circle",
                        showAbove: true,
                        size: 20,
                        itemStyle: {
                            borderWidth: 6,
                            borderColor: "rgba(84, 108, 198, 0.85)",
                        },
                    },
                    data: [pointerData],
                },
                {
                    // 背景渐变色
                    type: "pie",
                    radius: "80%",
                    // 不响应及触发鼠标事件
                    silent: true,
                    // 关闭背景动画
                    animation: false,
                    z: 0,
                    itemStyle: {
                        color: {
                            type: "radial", // 径向渐变
                            x: 0.5,
                            y: 0.5,
                            r: 0.25,
                            colorStops: [
                                {
                                    offset: 0,
                                    color: "rgba(84, 103, 198, 0.6)",
                                },
                                {
                                    offset: 0.1,
                                    color: "rgba(84, 103, 198, 0.35)",
                                },
                                {
                                    offset: 1,
                                    color: "rgba(84, 103, 198, 0)",
                                },
                            ],
                        },
                    },
                    data: [pointerData],
                },
            ],
        };
        Chart1.setOption(option);
    }
</script>
</body>
</html>
javaweb-plus/javaweb-admin/src/main/resources/templates/system/camera_tub/camera_list.html
New file
@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('弹层组件')" />
<link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet" />
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet" />
<link href="../static/css/main/animate.min.css" th:href="@{/css/main/animate.min.css}" rel="stylesheet" />
<link href="../static/css/main/style.min862f.css" th:href="@{/css/main/style.min862f.css}" rel="stylesheet" />
<link rel="stylesheet" th:href="@{/css/custom/main.css}" />
<link href="../static/js/elementUI/index.css" th:href="@{/js/elementUI/index.css}" rel="stylesheet" />
<style type="text/css">
    .custom-icon {
        font-size: 120px;
        margin-right: 5px;
        margin-left: -5px;
    }
    .icon-container:hover .custom-icon,
    .icon-container:hover .custom-font{
        color: #0981ea;
        cursor: pointer;
    }
</style>
</head>
<body class="gray-bg">
    <div class="content" id="app" v-cloak>
            <el-row>
                <el-col :span="4" v-for="(item, index) in cameraData" :key="item.projectId">
                    <div class="icon-container" style="margin-left: 40px;">
                        <li @click="handleClick(item.projectId)" class="el-icon-video-camera-solid  custom-icon"></li>
                        <h2 @click="handleClick(item.projectId)" class="custom-font" style="margin-top: 0px;margin-left: 0px;margin-bottom: 0px">{{item.projectName}}({{item.projectCode}})</h2>
                    </div>
                </el-col>
            </el-row>
    </div>
    <script th:src="@{/js/jquery.min.js}"></script>
    <script th:src="@{/js/bootstrap.min.js}"></script>
    <script th:src="@{/ajax/libs/flot/jquery.flot.js}"></script>
    <script th:src="@{/js/custom/main.js}"></script>
    <script th:src="@{/js/vue.min.js}"></script>
    <script th:src="@{/js/elementUI/index.js}"></script>
    <th:block th:include="include :: sparkline-js" />
    <th:block th:include="include :: footer" />
<script th:inline="javascript">
    $(function() {
        // 获取摄像头列表
        getCareraList();
    })
    var vm = new Vue({
        el: "#app",
        data() {
            return {
                cameraData: [],
            };
        },
        methods: {
            // 摄像头点击事件
            handleClick(projectId) {
                $.modal.open('视频播放', ctx + "/player?projectId="+projectId , 1300,580);
            },
            handleClose(done) {
                this.$confirm('确认关闭?')
                        .then(_ => {
                            done();
                        })
                        .catch(_ => {
                            $("#palyerIframe0").attr("src",'about:blank');
                            $("#palyerIframe1").attr("src",'about:blank');
                        });
            },
        }
    });
    function getCareraList() {
        let url = ctx + "/system/stat/cameraData";
        $.ajaxSettings.async = false;
        $.get(url,{},function(res){
            vm.cameraData = res.cameraData;
        })
        $.ajaxSettings.async = false;
    }
</script>
</body>
</html>
javaweb-plus/javaweb-admin/src/main/resources/templates/system/camera_tub/player2.html
New file
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
    <th:block th:include="include :: header('视频播放')" />
</head>
<body class="white-bg">
    <div class="wrapper wrapper-content animated fadeInRight ibox-content">
        <div>
            <iframe style="margin-left: 20px" id ="palyerIframe0"
                    src=""
                    width="600px"
                    height="400px;"
                    allowfullscreen>
            </iframe>
            <iframe style="margin-left: 20px" id ="palyerIframe1"
                    src=""
                    width="600px"
                    height="400px;"
                    allowfullscreen>
            </iframe>
        </div>
    </div>
    <th:block th:include="include :: footer" />
    <script th:src="@{/ajax/libs/EZUIKit/ezuikit.js}"></script>
    <script th:inline="javascript">
        var prefix = ctx + "geo/projectCamera";
        var cameraDataList = [[${cameraDataList}]];
        cameraDataList.forEach(function(value, index, array) {
            const playerUrl = value.url;
            $("#palyerIframe" + index).attr("src",playerUrl);
        });
    </script>
</body>
</html>
javaweb-plus/javaweb-admin/src/main/resources/templates/system/camera_tub/tub_list.html
New file
@@ -0,0 +1,296 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
    <th:block th:include="include :: header('弹层组件')" />
    <link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet" />
    <link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet" />
    <link href="../static/css/main/animate.min.css" th:href="@{/css/main/animate.min.css}" rel="stylesheet" />
    <link href="../static/css/main/style.min862f.css" th:href="@{/css/main/style.min862f.css}" rel="stylesheet" />
    <link rel="stylesheet" th:href="@{/css/custom/main.css}" />
    <link href="../static/js/elementUI/index.css" th:href="@{/js/elementUI/index.css}" rel="stylesheet" />
    <style type="text/css">
        .content {
            width: 100%;
            background-color: rgba(0,0,0,0.01) !important;
            padding:10px;
        }
        [v-cloak]{
            display: none;
        }
        .active-red{
            width: 20px;
            height: 20px;
            border-radius: 50%;
            font-size: 14px;
            color: white;
            background: #F56C6C;
            text-align: center;
            line-height: 20px;
            float: left;
        }
        .active-yellow{
            width: 20px;
            height: 20px;
            border-radius: 50%;
            font-size: 14px;
            color: white;
            background: #E6A23C;
            text-align: center;
            line-height: 20px;
            float: left;
        }
        .active-blue{
            width: 20px;
            height: 20px;
            border-radius: 50%;
            font-size: 14px;
            color: white;
            background: #67C23A;
            text-align: center;
            line-height: 20px;
            float: left;
        }
        .rankrow{
            margin-top: 12px;
            cursor: pointer;
        }
        .ilblock{
            border-left: 1px solid #e3e5e7;
            padding: 0 40px;
            align-content: center;
        }
        .ilblock>span{
            display: block;
            line-height: 30px;
        }
        .el-table th,
        .el-table tr,
        .el-table td {
            background-color: transparent;
            border: 0px;
            color: #4D4D4D;
            font-size: 13px;
            font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
            font-weight: Normal;
        }
        .el-table::before {
            height: 0px;
        }
        .el-table__body tr,
        .el-table__body td {
            padding: 0;
            height: 22px;
        }
    </style>
</head>
<body class="gray-bg">
<div class="content" id="app" v-cloak>
    <el-row style="height: 127px;">
        <el-col :span="24">
            <el-card class="box-card">
                <div style="flex:4;padding-right: 20px;">
                    <div>
                        <li class="el-icon-s-order" style="font-size: 18px;margin-right: 5px;margin-left: -5px;color: #917ed0"></li>
                        <span style="color:rgba(0,0,0,.65);font-size: 15px;font-weight: bold;">资料文件</span>
                    </div>
                    <div style="text-align: center">
                        <span style="color:#F7931E;font-size: 30px;word-break: break-all;line-height: 70px;">
                            {{indexDataCount.fileCount}}
                        </span>
                    </div>
                </div>
                <div style="flex:6;" class="ilblock">
                        <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            施工资料  <span style="float: right">0</span>
                            <!--                            <li class="el-icon-caret-bottom" style="color: #f56c6c">-->
                        </span>
                    <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            安全资料   <span style="float: right">0</span>
                        <!--                            <li class="el-icon-caret-bottom" style="color: #409eff">-->
                        </span>
                    <span style="color:rgba(0,0,0,.87);font-size: 15px;">
                            质量资料   <span style="float: right">0</span>
                        <!--                            <li class="el-icon-caret-bottom" style="color: #409eff">-->
                        </span>
                </div>
            </el-card>
        </el-col>
    </el-row>
    <el-row>
        <el-col :span="24">
            <el-card class="box-card">
                <div style="height: 70vh;width: 100%;">
                    <h3>材料统计</h3>
                    <el-col :span="10" style="height: 200px;">
                        <div style="margin-top: 15px">
                            <template>
                                <el-table :data="tubLogs" border size="small" style="width: 100%"
                                          :header-cell-style="{color: '#4D4D4D',background: '#F7931E',fontWeight: '400'}"
                                          :row-class-name="tableRowClassName">
                                    <!--                                    <el-table-column prop="code" label="序号"></el-table-column>-->
                                    <el-table-column prop="tubName" label="名称"></el-table-column>
                                    <el-table-column prop="inboundNumber" label="入库数量"></el-table-column>
                                    <el-table-column prop="outboundNumber" label="出库数量"></el-table-column>
                                    <el-table-column prop="unit" label="单位"></el-table-column>
                                </el-table>
                            </template>
                        </div>
                    </el-col>
                    <el-col :span="14" style="height: 200px;">
                        <div id="column-chart" style="height: 380px; width: 100%;"></div>
                    </el-col>
                </div>
            </el-card>
        </el-col>
    </el-row>
</div>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>
<script th:src="@{/ajax/libs/flot/jquery.flot.js}"></script>
<script th:src="@{/ajax/libs/report/echarts/echarts-all.js}"></script>
<script th:src="@{/js/custom/main.js}"></script>
<script th:src="@{/js/vue.min.js}"></script>
<script th:src="@{/js/elementUI/index.js}"></script>
<th:block th:include="include :: sparkline-js" />
<th:block th:include="include :: footer" />
<script th:inline="javascript">
    $(function() {
        indexCount();
        tubLogs();
    })
    function tubLogs() {
        const chart = echarts.init(document.getElementById("column-chart"));
        const option = {
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow'
                }
            },
            legend: {},
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis: [
                {
                    type: 'category',
                    data: []
                }
            ],
            yAxis: [
                {
                    type: 'value'
                }
            ],
            series: [
                {
                    name: '出库',
                    type: 'bar',
                    emphasis: {
                        focus: 'series'
                    },
                    data: [],
                    itemStyle: {
                        // 修改柱子的颜色
                        color: '#e2b507'
                    }
                },
                {
                    name: '入库',
                    type: 'bar',
                    stack: 'Ad',
                    emphasis: {
                        focus: 'series'
                    },
                    data: [],
                    itemStyle: {
                        // 修改柱子的颜色
                        color: '#2992c6'
                    }
                },
            ]
        };
        let url = ctx + "/system/stat/tubLogData";
        $.ajaxSettings.async = false;
        $.get(url,{},function(res){
            vm.tubLogs = res.tubLogs;
            res.tubLogs.forEach(function(value, index, array) {
                const tubName = value.tubName;
                const inboundNumber = value.inboundNumber;
                const outboundNumber = value.outboundNumber;
                const unit = value.unit;
                option.xAxis[0].data[index] = tubName;
                option.series[0].data[index] = outboundNumber;
                option.series[1].data[index] = inboundNumber;
            });
            chart.setOption(option, true);
        })
        $.ajaxSettings.async = false;
    }
    //首页第一行个数统计
    function indexCount() {
        let url = ctx + "/system/stat/indexDataCount";
        $.ajaxSettings.async = false;
        $.get(url,{},function(res){
            vm.indexDataCount = res.data;
            vm.indexDataCount.cameraCountNaN = 68 -vm.indexDataCount.cameraCount;
        })
        $.ajaxSettings.async = false;
    }
    var vm = new Vue({
        el: "#app",
        data() {
            return {
                stationProcessData: [],
                indexDataCount :"",
                tubLogs:[],
            };
        },
        methods: {
            tableRowClassName({ row, rowIndex }) {
                if (rowIndex % 2 == 0) {
                    return "";
                } else {
                    return "warning-row";
                }
            },
        }
    });
</script>
</body>
</html>
javaweb-plus/javaweb-cms/src/main/java/com/javaweb/geo/controller/ProjectCameraController.java
@@ -51,6 +51,12 @@
        return prefix + "/projectCamera";
    }
    @RequiresPermissions("geo:projectCamera:view2")
    @GetMapping("/view2")
    public String projectCamera2() {
        return prefix + "/projectCamera2";
    }
    /**
     * 查询监控设备列表
     */
@@ -70,8 +76,6 @@
        List<ProjectCamera> list = projectCameraService.selectProjectCameraList(projectCamera);
        return AjaxResult.success(list);
    }
    @GetMapping("/cameraPlayerUrl")
    @ResponseBody
@@ -124,7 +128,8 @@
     * 新增监控设备
     */
    @GetMapping("/add")
    public String add() {
    public String add(String projectId, ModelMap mmap) {
        mmap.put("projectId", projectId);
        return prefix + "/add";
    }
javaweb-plus/javaweb-cms/src/main/java/com/javaweb/geo/domain/Project.java
@@ -160,7 +160,7 @@
        return url;
    }
    public void settianUrl(String url) {
    public void setUrl(String url) {
        this.url = url;
    }
javaweb-plus/javaweb-cms/src/main/java/com/javaweb/geo/domain/ProjectCamera.java
@@ -21,6 +21,12 @@
    /** 项目id */
    private String projectId;
    /** 项目名称 */
    private String projectName;
    /** 项目编号 */
    private String projectCode;
    /** 名称 */
    @Excel(name = "名称")
    private String name;
@@ -40,6 +46,9 @@
    /** Ip地址 */
    @Excel(name = "Ip地址")
    private String ip;
    /** 视频播放路径 */
    private String url;
    public void setId(String id) 
    {
@@ -64,7 +73,23 @@
        this.name = name;
    }
    public String getName()
    public String getProjectName() {
        return projectName;
    }
    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }
    public String getProjectCode() {
        return projectCode;
    }
    public void setProjectCode(String projectCode) {
        this.projectCode = projectCode;
    }
    public String getName()
    {
        return name;
    }
@@ -105,6 +130,14 @@
        return ip;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
javaweb-plus/javaweb-cms/src/main/java/com/javaweb/geo/mapper/ProjectCameraMapper.java
@@ -60,4 +60,10 @@
    public int deleteProjectCameraByIds(String[] ids);
    public Integer count();
    /**
     * 获取在线摄像头的信息
     * @return
     */
    List<ProjectCamera> selectCameraDataOnLine();
}
javaweb-plus/javaweb-cms/src/main/java/com/javaweb/geo/service/IProjectCameraService.java
@@ -58,4 +58,10 @@
     * @return 结果
     */
    public int deleteProjectCameraById(String id);
    /**
     * 获取在线摄像头的信息
     * @return
     */
    List<ProjectCamera> selectCameraDataOnLine();
}
javaweb-plus/javaweb-cms/src/main/java/com/javaweb/geo/service/impl/ProjectCameraServiceImpl.java
@@ -92,4 +92,13 @@
    public int deleteProjectCameraById(String id) {
        return projectCameraMapper.deleteProjectCameraById(id);
    }
    /**
     * 获取在线摄像头的信息
     * @return
     */
    @Override
    public List<ProjectCamera> selectCameraDataOnLine() {
        return projectCameraMapper.selectCameraDataOnLine();
    }
}
javaweb-plus/javaweb-cms/src/main/resources/mapper/geo/ProjectCameraMapper.xml
@@ -7,6 +7,8 @@
    <resultMap type="ProjectCamera" id="ProjectCameraResult">
        <result property="id"    column="id"    />
        <result property="projectId"    column="project_id"    />
        <result property="projectName"    column="project_name"    />
        <result property="projectCode"    column="project_code"    />
        <result property="name"    column="name"    />
        <result property="code"    column="code"    />
        <result property="lng"    column="lng"    />
@@ -40,7 +42,25 @@
    <select id ="count" resultType="Integer">
       select  count(*) from js_project_camera
    </select>
    <select id="selectCameraDataOnLine" resultMap="ProjectCameraResult">
        SELECT
            a.id,
            a.project_id,
            b.full_name AS project_name,
            b.`code` AS project_code,
            a.NAME,
            a.CODE,
            a.lng,
            a.lat,
            a.ip,
            a.create_by,
            a.create_time
        FROM
            js_project_camera a
            LEFT JOIN js_project b ON a.project_id = b.ids GROUP BY a.project_id;
    </select>
    <insert id="insertProjectCamera" parameterType="ProjectCamera">
        insert into js_project_camera
        <trim prefix="(" suffix=")" suffixOverrides=",">
javaweb-plus/javaweb-cms/src/main/resources/templates/geo/project/info.html
@@ -120,7 +120,7 @@
            </el-col>
            <el-col :span="10" >
                <el-card class="box-card card-yellow" style="height: 320px;margin-right: 20px;">
                <el-card class="box-card card-blue" style="height: 320px;margin-right: 20px;">
                    <div slot="header" class="clearfix">
                        <span>钻孔分布图</span>
                    </div>
@@ -181,7 +181,7 @@
        <el-row style="height: 200px;">
            <el-col :span="24">
                <el-card class="box-card  card-yellow"  style="height: 320px;margin-top: 20px">
                <el-card class="box-card  card-blue"  style="height: 320px;margin-top: 20px">
                        <div slot="header" class="clearfix">
                            <span>材料统计</span>
                        </div>
javaweb-plus/javaweb-cms/src/main/resources/templates/geo/projectCamera/add.html
@@ -41,13 +41,17 @@
    <th:block th:include="include :: footer" />
    <script th:inline="javascript">
        var prefix = ctx + "geo/projectCamera"
        var projectId = [[${projectId}]];
        $("#form-projectCamera-add").validate({
            focusCleanup: true
        });
        function submitHandler() {
            if ($.validate.form()) {
                $.operate.save(prefix + "/add", $('#form-projectCamera-add').serialize());
                let formData = $('#form-projectCamera-add').serialize();
                let data = formData + "&projectId=" + projectId;
                $.operate.save(prefix + "/add", data);
            }
        }
    </script>
javaweb-plus/javaweb-cms/src/main/resources/templates/geo/projectCamera/projectCamera.html
@@ -55,11 +55,12 @@
        var editFlag = [[${@permission.hasPermi('geo:projectCamera:edit')}]];
        var removeFlag = [[${@permission.hasPermi('geo:projectCamera:remove')}]];
        var prefix = ctx + "geo/projectCamera";
        var projectId=[[${projectId}]];
        $(function() {
            var options = {
                url: prefix + "/list",
                createUrl: prefix + "/add",
                url: prefix + "/list?projectId="+projectId,
                createUrl: prefix + "/add?projectId="+projectId,
                updateUrl: prefix + "/edit/{id}",
                removeUrl: prefix + "/remove",
                exportUrl: prefix + "/export",
@@ -99,7 +100,7 @@
                    formatter: function(value, row, index) {
                        var actions = [];
                        actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
                        actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
                        actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a> ');
                        actions.push('<a class="btn btn-info btn-xs ' + '" href="javascript:void(0)" onclick="player(\'' + row.id + '\')"><i class="fa fa-video-camera"></i>播放</a>');
                        return actions.join('');
                    }
javaweb-plus/javaweb-cms/src/main/resources/templates/geo/projectCamera/projectCamera2.html
New file
@@ -0,0 +1,117 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <th:block th:include="include :: header('监控设备列表')" />
</head>
<body class="gray-bg">
     <div class="container-div">
        <div class="row">
            <div class="col-sm-12 search-collapse">
                <form id="formId">
                    <div class="select-list">
                        <ul>
                            <li>
                                <p>名称:</p>
                                <input type="text" name="name"/>
                            </li>
                            <li>
                                <p>视频编号:</p>
                                <input type="text" name="code"/>
                            </li>
                            <li>
                                <p>Ip地址:</p>
                                <input type="text" name="ip"/>
                            </li>
                            <li>
                                <a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
                                <a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
                            </li>
                        </ul>
                    </div>
                </form>
            </div>
            <div class="btn-group-sm" id="toolbar" role="group">
<!--                <a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="geo:projectCamera:add">-->
<!--                    <i class="fa fa-plus"></i> 添加-->
<!--                </a>-->
                <a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="geo:projectCamera:edit">
                    <i class="fa fa-edit"></i> 修改
                </a>
<!--                <a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="geo:projectCamera:remove">-->
<!--                    <i class="fa fa-remove"></i> 删除-->
<!--                </a>-->
<!--                <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="geo:projectCamera:export">-->
<!--                    <i class="fa fa-download"></i> 导出-->
<!--                </a>-->
            </div>
            <div class="col-sm-12 select-table table-striped">
                <table id="bootstrap-table"></table>
            </div>
        </div>
    </div>
    <th:block th:include="include :: footer" />
    <script th:inline="javascript">
        var editFlag = [[${@permission.hasPermi('geo:projectCamera:edit')}]];
        var removeFlag = [[${@permission.hasPermi('geo:projectCamera:remove')}]];
        var prefix = ctx + "geo/projectCamera";
        var projectId=[[${projectId}]];
        $(function() {
            var options = {
                url: prefix + "/list",
                createUrl: prefix + "/add",
                updateUrl: prefix + "/edit/{id}",
                removeUrl: prefix + "/remove",
                exportUrl: prefix + "/export",
                modalName: "监控设备",
                columns: [{
                    checkbox: true
                },
                {
                    field : 'id',
                    title : '主键',
                    visible: false
                },
                {
                    field : 'name',
                    title : '名称'
                },
                {
                    field : 'code',
                    title : '视频编号'
                },
                {
                    field : 'lng',
                    title : '经度'
                },
                {
                    field : 'lat',
                    title : '纬度'
                },
                {
                    field : 'ip',
                    title : 'Ip地址',
                    visible: false
                },
                {
                    title: '操作',
                    align: 'center',
                    formatter: function(value, row, index) {
                        var actions = [];
                        actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
                        //actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a> ');
                        actions.push('<a class="btn btn-info btn-xs ' + '" href="javascript:void(0)" onclick="player(\'' + row.id + '\')"><i class="fa fa-video-camera"></i>播放</a>');
                        return actions.join('');
                    }
                }]
            };
            $.table.init(options);
        });
        function  player(id) {
            $.modal.open('视频播放', prefix + "/player?id="+id);
        }
    </script>
</body>
</html>