diff --git a/yanzhu-bigscreen/src/api/aiWarning.js b/yanzhu-bigscreen/src/api/aiWarning.js
new file mode 100644
index 00000000..f291ca95
--- /dev/null
+++ b/yanzhu-bigscreen/src/api/aiWarning.js
@@ -0,0 +1,32 @@
+import request from "@/utils/request";
+
+// 查询AI设备数据列表
+const list = (data) => {
+    return request({
+        url: `/manage/devAiProjectData/list`,
+        method: 'get',
+        params: data,
+    })
+}
+
+// 统计AI预警数据
+const getDaysTrendView = (projectId) => {
+    return request({
+        url: `/manage/devAiProjectData/getDaysTrendView/${projectId || 0}`,
+        method: 'get'
+    })
+}
+
+// 统计AI预警数据
+const groupCountByAlarmType = (projectId, now) => {
+    return request({
+        url: `/manage/devAiProjectData/groupCountByAlarmType/${projectId || 0}?now=${now}`,
+        method: 'get'
+    })
+}
+
+export default {
+    list,
+    getDaysTrendView,
+    groupCountByAlarmType
+}
diff --git a/yanzhu-bigscreen/src/api/index.js b/yanzhu-bigscreen/src/api/index.js
index ecd1c1b0..bdeaef43 100644
--- a/yanzhu-bigscreen/src/api/index.js
+++ b/yanzhu-bigscreen/src/api/index.js
@@ -8,6 +8,7 @@ import videoMonitor from "./videoMonitor";
 import safety from "./safety";
 import tower from "./tower";
 import powerIot from "./powerIot";
+import aiWarning from "./aiWarning";
 export default {
   http: axios,
   downFile: download,
@@ -20,4 +21,5 @@ export default {
   safety,
   tower,
   powerIot,
+  aiWarning,
 };
diff --git a/yanzhu-bigscreen/src/api/powerIot.js b/yanzhu-bigscreen/src/api/powerIot.js
index d5e677c7..0c5eacc4 100644
--- a/yanzhu-bigscreen/src/api/powerIot.js
+++ b/yanzhu-bigscreen/src/api/powerIot.js
@@ -32,8 +32,6 @@ const findIotWarnings = (proId,pointId) => {
     });
 };
 
-
-
 export default {
     findProAllConfigPoint,
     findConfigPointInfo,
diff --git a/yanzhu-bigscreen/src/components/header.vue b/yanzhu-bigscreen/src/components/header.vue
index 2ec51871..0f85eb2c 100644
--- a/yanzhu-bigscreen/src/components/header.vue
+++ b/yanzhu-bigscreen/src/components/header.vue
@@ -35,7 +35,7 @@
                                     <button type="button" :class="nav == 309 ? 'active' : ''" class="sub-btn"
                                         @click="doNav(309)">视频监控</button>
                                     <button type="button" :class="nav == 310 ? 'active' : ''" class="sub-btn"
-                                        @click="doNav(310)">AI测控</button>
+                                        @click="doNav(310)">AI预警</button>
                                     <button type="button" :class="nav == 311 ? 'active' : ''" class="sub-btn"
                                         @click="doNav(311)">标准化管理</button>
                                 </div>
@@ -211,7 +211,10 @@ export default {
                     break;
                 case 306:
                     this.$router.push("/powerIot");
-                    break;    
+                    break;
+                case 310:
+                    this.$router.push("/aiWarning");
+                    break; 
                 case 4:
                     this.$router.push("/prjQuality");
                     break;
diff --git a/yanzhu-bigscreen/src/router/index.js b/yanzhu-bigscreen/src/router/index.js
index f6297e32..ed0e97a8 100644
--- a/yanzhu-bigscreen/src/router/index.js
+++ b/yanzhu-bigscreen/src/router/index.js
@@ -82,6 +82,15 @@ const routes = [
         /* webpackChunkName: "safetyCheck" */ "../views/safety/powerIot.vue"
       ),
   },
+  {
+    path: "/aiWarning",
+    name: "aiWarning",
+    meta: { nav: 310 },
+    component: () =>
+      import(
+        /* webpackChunkName: "safetyCheck" */ "../views/safety/aiWarning.vue"
+      ),
+  },
   {
     path: "/photography",
     name: "photography",
diff --git a/yanzhu-bigscreen/src/views/projectDetail.vue b/yanzhu-bigscreen/src/views/projectDetail.vue
index a550feab..b4caa443 100644
--- a/yanzhu-bigscreen/src/views/projectDetail.vue
+++ b/yanzhu-bigscreen/src/views/projectDetail.vue
@@ -136,7 +136,7 @@
                     <template v-if="photographyList && photographyList.length > 0">
                         <el-carousel height="100%" :autoplay="false">
                             <el-carousel-item v-for="(item, idx) in photographyList" :key="idx">
-                                <video controls="controls" class="photography-video" autoplay="autoplay" loop="loop">
+                                <video controls="controls" class="photography-video" loop="loop">
                                     <source :src="item.videoUrl" type="video/mp4" :key="item.videoUrl" />您的浏览器不支持Video标签。
                                 </video>
                                 <div class="photography-list-title">{{ item.videoDate }}</div>
diff --git a/yanzhu-bigscreen/src/views/safety/aiWarning.vue b/yanzhu-bigscreen/src/views/safety/aiWarning.vue
new file mode 100644
index 00000000..1fbf064e
--- /dev/null
+++ b/yanzhu-bigscreen/src/views/safety/aiWarning.vue
@@ -0,0 +1,411 @@
+<template>
+  <div class="project-ai-warning main-page">
+    <el-col :span="6">
+      <module-one-1-1 label="今日预警" style="position: relative">
+        <project-overview-chart
+          :key="'ai1' + overviewDay"
+          :sp="''"
+          :maintitle="overviewTotalDay"
+          :legend-opt="legendOpt1"
+          :typedata="typeDistributionDataDay"
+          :text="overviewTextDay"
+          :height="230"
+        ></project-overview-chart>
+      </module-one-1-1>
+      <module-one-1-1 label="预警概况">
+        <project-overview-chart
+          :key="'ai2' + overview"
+          :sp="''"
+          :maintitle="overviewTotal"
+          :legend-opt="legendOpt2"
+          :typedata="typeDistributionData"
+          :text="overviewText"
+          :height="230"
+        ></project-overview-chart>
+      </module-one-1-1>
+      <module-one-1-1 label="每日预警趋势">
+        <trend-chart-line :height="280" :data="warningData"></trend-chart-line>
+      </module-one-1-1>
+    </el-col>
+    <el-col :span="18">
+      <module-one-1-3 label="今日预警详情" :key="todayKey" style="position: relative">
+        <div class="today-list ai-list" v-if="todayList.length > 0">
+          <div v-for="(it, idx) in todayList" :key="idx" class="today-item ai-item">
+            <div class="item-left">
+              <el-image
+                style="width: 180px; height: 100px"
+                :src="it.imageUrl + '.min.jpg'"
+                :preview-src-list="[it.imageUrl]"
+              >
+              </el-image>
+            </div>
+            <div class="item-right">
+              <div class="item-row">
+                <div>预警名称:</div>
+                <div style="color: rgba(1, 169, 255, 1)">{{ it.alarmTypeName }}</div>
+              </div>
+              <div class="item-row">
+                <div>预警时间:</div>
+                <div style="color: rgba(1, 169, 255, 1)">{{ it.createTime }}</div>
+              </div>
+            </div>
+          </div>
+        </div>
+        <el-pagination
+          v-if="todayList.length > 0"
+          layout="total,prev, pager, next"
+          :hide-on-single-page="false"
+          @current-change="handleTodayCurrentChange"
+          :total="todayPage.total"
+          :page-size="todayPage.pageSize"
+          :current-page.sync="todayPage.pageIndex"
+          class="bg-pagination"
+        ></el-pagination>
+
+        <div v-if="todayList.length == 0" class="not-data">暂无预警数据</div>
+      </module-one-1-3>
+      <module-one-2-3 label="预警概况明细" style="position: relative">
+        <div style="position: absolute; right: 0px; top: 4px">
+          <el-date-picker
+            class="bg-date-picker"
+            v-model="selDate"
+            type="daterange"
+            popper-class="bg-date-picker-pop"
+            :editable="false"
+            @change="dtChange"
+            :picker-options="pickerOptions"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            value-format="yyyy-MM-dd"
+          ></el-date-picker>
+        </div>
+        <div class="ai-nav">
+          <div
+            class="nav-item ai-content-nav-con ai-content-nav"
+            :class="selType == 0 ? 'active' : ''"
+            @click="doSelType(0)"
+          >
+            全部
+          </div>
+          <div
+            class="nav-item ai-content-nav-con ai-content-nav"
+            v-for="(it, idx) in aiTypes"
+            :class="selType == it.value ? 'active' : ''"
+            @click="doSelType(it.value)"
+            :key="it.value"
+          >
+            {{ it.label }}
+          </div>
+        </div>
+        <div class="data-list">
+          <div class="ai-list" v-if="listDatas.length > 0">
+            <div v-for="(it, idx) in listDatas" :key="idx" class="today-item ai-item">
+              <div class="item-left">
+                <el-image
+                  style="width: 180px; height: 100px"
+                  :src="it.imageUrl + '.min.jpg'"
+                  :preview-src-list="[it.imageUrl]"
+                >
+                </el-image>
+              </div>
+              <div class="item-right">
+                <div class="item-row">
+                  <div>预警名称:</div>
+                  <div style="color: rgba(1, 169, 255, 1)">
+                    {{ it.alarmTypeName }}
+                  </div>
+                </div>
+                <div class="item-row">
+                  <div>预警时间:</div>
+                  <div style="color: rgba(1, 169, 255, 1)">{{ it.createTime }}</div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <el-pagination
+            v-if="listDatas.length > 0"
+            layout="total,prev, pager, next"
+            :hide-on-single-page="false"
+            @current-change="handleListCurrentChange"
+            :total="listPage.total"
+            :page-size="listPage.pageSize"
+            :current-page.sync="listPage.pageIndex"
+            class="bg-pagination"
+          ></el-pagination>
+          <div v-if="listDatas.length == 0" class="not-data">暂无预警数据</div>
+        </div>
+      </module-one-2-3>
+    </el-col>
+  </div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      overview: 0,
+      overviewDay: 0,
+      overviewTotal: 0,
+      legendOpt1: {
+        icon: "rect",
+        textStyle: {
+          color: "#c3dbfd",
+          fontSize: 15,
+          rich: {
+            name: {
+              color: "#c3dbfd",
+              padding: [0, 20, 0, 0],
+            },
+            percent: {
+              color: "#4676FD",
+            },
+          },
+        },
+      },
+      legendOpt2: {
+        icon: "rect",
+        textStyle: {
+          color: "#c3dbfd",
+          fontSize: 14,
+          rich: {
+            name: {
+              color: "#c3dbfd",
+              padding: [0, 20, 0, 0],
+            },
+            percent: {
+              color: "#4676FD",
+            },
+          },
+        },
+      },
+      overviewText: "累计预警",
+      //预警概况
+      typeDistributionData: [],
+      overviewTextDay: "今日预警",
+      overviewTotalDay: 0,
+      typeDistributionDataDay: [],
+      todayPage: {
+        pageSize: 6,
+        pageIndex: 1,
+        total: 0,
+      },
+      listPage: {
+        pageSize: 12,
+        pageIndex: 1,
+        total: 0,
+      },
+      todayList: [],
+      todayKey: 0,
+      listDatas: [],
+      selDate: [],
+      aiTypes: [],
+      selType: 0,
+      pickerOptions: {
+        shortcuts: [
+          {
+            text: "最近一周",
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+              picker.$emit("pick", [start, end]);
+            },
+          },
+          {
+            text: "最近一个月",
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+              picker.$emit("pick", [start, end]);
+            },
+          },
+          {
+            text: "最近三个月",
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+              picker.$emit("pick", [start, end]);
+            },
+          },
+        ],
+      },
+      intervalTimes: null,
+      warningData:[]
+    };
+  },
+  mounted() {
+    this.$store.dispatch("ChangeNav", 310);
+    this.$bus.$on("projectChange", (prj) => {
+      this.selProject = prj;
+      this.init();
+    });
+    this.selProject = this.$store.getters.selProject;
+    this.init();
+  },
+  methods: {
+    init() {
+      if (!this.selProject) {
+        return;
+      }
+      this.$api.dict("aibox_alarm_type").then((d) => {
+        this.aiTypes = d || [];
+      });
+      this.loadList();
+      this.loadTodayList();
+      this.getAiVideoAlertorTypeCount();
+      this.daysTrendView();
+    },
+    doSelType(n) {
+      if (this.selType != n) {
+        this.selType = n;
+        this.listPage.pageIndex = 1;
+        this.loadList();
+      }
+    },
+    dtChange(init) {
+      this.listPage.pageIndex = 1;
+      this.loadList();
+    },
+    handleTodayCurrentChange(n) {
+      this.todayPage.pageIndex = n;
+      this.loadTodayList();
+    },
+    handleListCurrentChange(n) {
+      this.listPage.pageIndex = n;
+      this.loadList();
+    },
+    loadList() {
+      let postData = {
+        pageNum: this.listPage.pageIndex,
+        pageSize: this.listPage.pageSize,
+        projectId: this.selProject.id,
+      };
+      if(this.selDate.length>0){
+        let _params = {
+          beginTime: this.selDate[0],
+          endTime: this.selDate[1]
+        }
+        postData.params = _params;
+      }
+      if (this.selType != 0) {
+        postData.alarmType = this.selType;
+      }
+      this.$api.aiWarning
+        .list(postData)
+        .then((d) => {
+          this.listPage.total = d.total || 0;
+          this.listDatas = d.rows || [];
+          this.listKey++;
+        });
+    },
+    loadTodayList() {
+      let postData = {
+        pageNum: this.todayPage.pageIndex,
+        pageSize: this.todayPage.pageSize,
+        projectId: this.selProject.id,
+        params: {
+          date: new Date(),
+        },
+      };
+      this.$api.aiWarning
+        .list(postData)
+        .then((d) => {
+          this.todayPage.total = d.total || 0;
+          this.todayList = d.rows || [];
+          this.todayKey++;
+        });
+    },
+    getAiVideoAlertorTypeCount() {
+      //今日视图
+      this.$api.aiWarning.groupCountByAlarmType(this.selProject.id, "Y").then((response) => {
+        if (response.data) {
+          let sum = 0;
+          response.data.forEach((datum) => {
+            sum += datum.value;
+          });
+          this.overviewTotalDay = sum;
+          this.typeDistributionDataDay = response.data;
+          this.overviewDay++;
+        }
+      });
+
+      //累计视图
+      this.$api.aiWarning.groupCountByAlarmType(this.selProject.id, "N").then((response) => {
+        if (response.data) {
+          let sum = 0;
+          response.data.forEach((datum) => {
+            sum += datum.value;
+          });
+          this.overviewTotal = sum;
+          this.typeDistributionData = response.data;
+          this.overview++;
+        }
+      });
+    },
+    daysTrendView(){
+      this.$api.aiWarning.getDaysTrendView(this.selProject.id).then((response) => {
+        if (response.data) {
+          let _data1 = [];
+          let _date8 = [];
+          response.data.forEach((datum) => {
+            _data1.push(datum.total);
+            _date8.push(datum.dayStr);
+          });
+          let _lineData = [];
+          _lineData.push(_data1);
+          let _color = ['#0078e7'];
+          let _legend = ['预警总数'];
+          let _trendData = {'lineData':_lineData,'color':_color,'legend':_legend,'date':_date8};
+          this.warningData = _trendData;
+        }
+      });
+    },
+    initIntervalTimes(){
+      this.intervalTimes = setInterval(this.init, 150000); // 每2.5分钟刷新一次
+    },
+  },
+};
+</script>
+<style lang="less" scope>
+.project-ai-warning {
+  .project-overview-chart{
+    .chart-overview-gif{
+      margin-left: -10px !important;
+    }
+  }
+  .ai-list {
+    padding: 0px 24px 8px;
+    .ai-item {
+      display: inline-flex;
+      margin: 12px 12px 0px 0px;
+      width: calc(33% - 12px);
+      color: #ccc;
+      line-height: 24px;
+      .item-right {
+        padding-left: 12px;
+      }
+    }
+  }
+  .data-list {
+    .ai-list {
+      .ai-item {
+        margin-bottom: 8px;
+      }
+    }
+  }
+  .ai-nav {
+    padding: 12px;
+    .nav-item {
+      display: inline-block;
+      margin-left: 12px;
+      text-align: center;
+      padding: 0px 8px;
+      &:first-child {
+        margin-left: 0px;
+      }
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/DevAiProjectData.java b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/DevAiProjectData.java
index 8d440b7a..522b84f6 100644
--- a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/DevAiProjectData.java
+++ b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/DevAiProjectData.java
@@ -66,9 +66,12 @@ public class DevAiProjectData extends BaseEntity
     private String channelName;
 
     /** 报警类型 */
-    @Excel(name = "报警类型")
     private String alarmType;
 
+    /** 报警类型 */
+    @Excel(name = "报警类型")
+    private String alarmTypeName;
+
     /** 告警编号 */
     @Excel(name = "告警编号")
     private String alarmId;
@@ -204,6 +207,15 @@ public class DevAiProjectData extends BaseEntity
     {
         return alarmType;
     }
+
+    public String getAlarmTypeName() {
+        return alarmTypeName;
+    }
+
+    public void setAlarmTypeName(String alarmTypeName) {
+        this.alarmTypeName = alarmTypeName;
+    }
+
     public void setAlarmId(String alarmId)
     {
         this.alarmId = alarmId;
diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/ProPlanSchedule.java b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/ProPlanSchedule.java
new file mode 100644
index 00000000..ac6dd3b2
--- /dev/null
+++ b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/ProPlanSchedule.java
@@ -0,0 +1,255 @@
+package com.yanzhu.manage.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yanzhu.common.core.annotation.Excel;
+import com.yanzhu.common.core.web.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.util.Date;
+
+/**
+ * 项目进度对象 pro_plan_schedule
+ * 
+ * @author yanzhu
+ * @date 2025-04-14
+ */
+public class ProPlanSchedule extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键 */
+    private Long id;
+
+    /** 公司主键 */
+    @Excel(name = "公司主键")
+    private Long comId;
+
+    /** 项目主键 */
+    @Excel(name = "项目主键")
+    private Long projectId;
+
+    /** 计划主键 */
+    @Excel(name = "计划主键")
+    private Long planId;
+
+    /** 任务编号 */
+    @Excel(name = "任务编号")
+    private Long taskId;
+
+    /** 任务唯一编号 */
+    @Excel(name = "任务唯一编号")
+    private String taskUniqueId;
+
+    /** 任务名称 */
+    @Excel(name = "任务名称")
+    private String taskName;
+
+    /** BIM构建 */
+    @Excel(name = "BIM构建")
+    private String bimId;
+
+    /** 进度百分比 */
+    @Excel(name = "进度百分比")
+    private Long schedulePercent;
+
+    /** 完成时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date finishDate;
+
+    /** 进度描述 */
+    @Excel(name = "进度描述")
+    private String description;
+
+    /** 施工作业图 */
+    @Excel(name = "施工作业图")
+    private String images;
+
+    /** 是否有效 */
+    @Excel(name = "是否有效")
+    private Long isDel;
+
+    /** 填报人编号 */
+    @Excel(name = "填报人编号")
+    private Long createUserId;
+
+    /** 创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date createDate;
+
+    /** 修改时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "修改时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date updateDate;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+    public void setComId(Long comId) 
+    {
+        this.comId = comId;
+    }
+
+    public Long getComId() 
+    {
+        return comId;
+    }
+    public void setProjectId(Long projectId) 
+    {
+        this.projectId = projectId;
+    }
+
+    public Long getProjectId() 
+    {
+        return projectId;
+    }
+    public void setPlanId(Long planId) 
+    {
+        this.planId = planId;
+    }
+
+    public Long getPlanId() 
+    {
+        return planId;
+    }
+    public void setTaskId(Long taskId) 
+    {
+        this.taskId = taskId;
+    }
+
+    public Long getTaskId() 
+    {
+        return taskId;
+    }
+    public void setTaskUniqueId(String taskUniqueId) 
+    {
+        this.taskUniqueId = taskUniqueId;
+    }
+
+    public String getTaskUniqueId() 
+    {
+        return taskUniqueId;
+    }
+    public void setTaskName(String taskName) 
+    {
+        this.taskName = taskName;
+    }
+
+    public String getTaskName() 
+    {
+        return taskName;
+    }
+    public void setBimId(String bimId) 
+    {
+        this.bimId = bimId;
+    }
+
+    public String getBimId() 
+    {
+        return bimId;
+    }
+    public void setSchedulePercent(Long schedulePercent) 
+    {
+        this.schedulePercent = schedulePercent;
+    }
+
+    public Long getSchedulePercent() 
+    {
+        return schedulePercent;
+    }
+    public void setFinishDate(Date finishDate) 
+    {
+        this.finishDate = finishDate;
+    }
+
+    public Date getFinishDate() 
+    {
+        return finishDate;
+    }
+    public void setDescription(String description) 
+    {
+        this.description = description;
+    }
+
+    public String getDescription() 
+    {
+        return description;
+    }
+    public void setImages(String images) 
+    {
+        this.images = images;
+    }
+
+    public String getImages() 
+    {
+        return images;
+    }
+    public void setIsDel(Long isDel) 
+    {
+        this.isDel = isDel;
+    }
+
+    public Long getIsDel() 
+    {
+        return isDel;
+    }
+    public void setCreateUserId(Long createUserId) 
+    {
+        this.createUserId = createUserId;
+    }
+
+    public Long getCreateUserId() 
+    {
+        return createUserId;
+    }
+    public void setCreateDate(Date createDate) 
+    {
+        this.createDate = createDate;
+    }
+
+    public Date getCreateDate() 
+    {
+        return createDate;
+    }
+    public void setUpdateDate(Date updateDate) 
+    {
+        this.updateDate = updateDate;
+    }
+
+    public Date getUpdateDate() 
+    {
+        return updateDate;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("comId", getComId())
+            .append("projectId", getProjectId())
+            .append("planId", getPlanId())
+            .append("taskId", getTaskId())
+            .append("taskUniqueId", getTaskUniqueId())
+            .append("taskName", getTaskName())
+            .append("bimId", getBimId())
+            .append("schedulePercent", getSchedulePercent())
+            .append("finishDate", getFinishDate())
+            .append("description", getDescription())
+            .append("images", getImages())
+            .append("isDel", getIsDel())
+            .append("createBy", getCreateBy())
+            .append("createUserId", getCreateUserId())
+            .append("createDate", getCreateDate())
+            .append("updateBy", getUpdateBy())
+            .append("updateDate", getUpdateDate())
+            .toString();
+    }
+}
diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/DevAiProjectDataMapper.java b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/DevAiProjectDataMapper.java
index 797e1d4f..bfb92cee 100644
--- a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/DevAiProjectDataMapper.java
+++ b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/DevAiProjectDataMapper.java
@@ -1,6 +1,8 @@
 package com.yanzhu.manage.mapper;
 
 import java.util.List;
+import java.util.Map;
+
 import com.yanzhu.manage.domain.DevAiProjectData;
 
 /**
@@ -58,4 +60,20 @@ public interface DevAiProjectDataMapper
      * @return 结果
      */
     public int deleteDevAiProjectDataByIds(Long[] ids);
+
+    /**
+     * 最近预警趋势
+     *
+     * @param devAiProjectData 查询条件
+     * @return 结果
+     */
+    public List<Map<String, Object>> findDaysTrendView(DevAiProjectData devAiProjectData);
+
+    /**
+     * 设备数据统计
+     *
+     * @param devAiProjectData 查询条件
+     * @return 结果
+     */
+    public List<Map<String, Object>> groupCountByAlarmType(DevAiProjectData devAiProjectData);
 }
diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/ProPlanScheduleMapper.java b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/ProPlanScheduleMapper.java
new file mode 100644
index 00000000..c8188957
--- /dev/null
+++ b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/ProPlanScheduleMapper.java
@@ -0,0 +1,61 @@
+package com.yanzhu.manage.mapper;
+
+import java.util.List;
+import com.yanzhu.manage.domain.ProPlanSchedule;
+
+/**
+ * 项目进度Mapper接口
+ * 
+ * @author yanzhu
+ * @date 2025-04-14
+ */
+public interface ProPlanScheduleMapper 
+{
+    /**
+     * 查询项目进度
+     * 
+     * @param id 项目进度主键
+     * @return 项目进度
+     */
+    public ProPlanSchedule selectProPlanScheduleById(Long id);
+
+    /**
+     * 查询项目进度列表
+     * 
+     * @param proPlanSchedule 项目进度
+     * @return 项目进度集合
+     */
+    public List<ProPlanSchedule> selectProPlanScheduleList(ProPlanSchedule proPlanSchedule);
+
+    /**
+     * 新增项目进度
+     * 
+     * @param proPlanSchedule 项目进度
+     * @return 结果
+     */
+    public int insertProPlanSchedule(ProPlanSchedule proPlanSchedule);
+
+    /**
+     * 修改项目进度
+     * 
+     * @param proPlanSchedule 项目进度
+     * @return 结果
+     */
+    public int updateProPlanSchedule(ProPlanSchedule proPlanSchedule);
+
+    /**
+     * 删除项目进度
+     * 
+     * @param id 项目进度主键
+     * @return 结果
+     */
+    public int deleteProPlanScheduleById(Long id);
+
+    /**
+     * 批量删除项目进度
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteProPlanScheduleByIds(Long[] ids);
+}
diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/security/utils/DictUtils.java b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/security/utils/DictUtils.java
index eae76f0c..79c6ab1c 100644
--- a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/security/utils/DictUtils.java
+++ b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/security/utils/DictUtils.java
@@ -45,6 +45,27 @@ public class DictUtils
         return null;
     }
 
+    /**
+     * 获取字典缓存
+     *
+     * @param key 参数键
+     * @return dictDatas 字典数据列表
+     */
+    public static SysDictData getDictCache(String key, String value)
+    {
+        JSONArray arrayCache = SpringUtils.getBean(RedisService.class).getCacheObject(getCacheKey(key));
+        if (StringUtils.isNotNull(arrayCache))
+        {
+            List<SysDictData> dictList = arrayCache.toList(SysDictData.class);
+            for(SysDictData dictData:dictList){
+                if(Objects.equals(value,dictData.getDictValue())){
+                    return dictData;
+                }
+            }
+        }
+        return null;
+    }
+
     /**
      * 获取字典缓存
      *
diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/DevAiProjectDataMapper.xml b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/DevAiProjectDataMapper.xml
index 45897f8e..4820a24a 100644
--- a/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/DevAiProjectDataMapper.xml
+++ b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/DevAiProjectDataMapper.xml
@@ -18,6 +18,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="channelId"    column="channel_id"    />
         <result property="channelName"    column="channel_name"    />
         <result property="alarmType"    column="alarm_type"    />
+        <result property="alarmTypeName"    column="alarm_type_name"    />
         <result property="alarmId"    column="alarm_id"    />
         <result property="plateNo"    column="plate_no"    />
         <result property="alarmVideourl"    column="alarm_videoURL"    />
@@ -27,9 +28,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectDevAiProjectDataVo">
-        select dapd.id, dapd.com_id, sd.dept_name as com_name, dapd.project_id, pi.project_name, dapd.device_id, dapd.device_name, dapd.serial_number, dapd.IPC_serial_num, dapd.image_url, dapd.channel_id, dapd.channel_name, dapd.alarm_type, dapd.alarm_id, dapd.plate_no, dapd.alarm_videoURL, dapd.alarm_video_name, dapd.create_time, dapd.is_del from dev_ai_project_data dapd
+        select dapd.id, dapd.com_id, sd.dept_name as com_name, dapd.project_id, pi.project_name, dapd.device_id, dapd.device_name, dapd.serial_number, dapd.IPC_serial_num, dapd.image_url, dapd.channel_id, dapd.channel_name, dapd.alarm_type, sdd.dict_label as alarm_type_name, dapd.alarm_id, dapd.plate_no, dapd.alarm_videoURL, dapd.alarm_video_name, dapd.create_time, dapd.is_del from dev_ai_project_data dapd
         left join pro_project_info pi on pi.id = dapd.project_id
         left join sys_dept sd on sd.dept_id = dapd.com_id
+        left join sys_dict_data sdd on sdd.dict_value = dapd.alarm_type and sdd.dict_type = 'aibox_alarm_type'
     </sql>
 
     <select id="selectDevAiProjectDataList" parameterType="DevAiProjectData" resultMap="DevAiProjectDataResult">
@@ -43,6 +45,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="deviceName != null  and deviceName != ''"> and (dapd.device_name like concat('%', #{deviceName}, '%') or dapd.serial_number like concat('%', #{deviceName}, '%'))</if>
             <if test="channelName != null  and channelName != ''"> and dapd.channel_name like concat('%', #{channelName}, '%')</if>
             <if test="alarmType != null "> and dapd.alarm_type = #{alarmType}</if>
+            <if test="params.date != null"> and date(dapd.create_time) = date(#{params.date})</if>
             <if test="params.beginTime != null and params.beginTime != '' and params.endTime != null and params.endTime != ''"> and dapd.create_time between #{params.beginTime} and #{params.endTime}</if>
             <if test="isDel != null  and isDel != ''"> and dapd.is_del = #{isDel}</if>
             and dapd.is_del != 2
@@ -128,4 +131,30 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{id}
         </foreach>
     </update>
+
+    <select id="findDaysTrendView" parameterType="DevAiProjectData" resultType="map">
+        select date(create_time) as create_time, count(1) as total from dev_ai_project_data
+        <where>
+            <if test="projectId != null "> and project_id = #{projectId}</if>
+            <if test="deviceName != null  and deviceName != ''"> and device_name like concat('%', #{deviceName}, '%')</if>
+            <if test="alarmType != null "> and alarm_type = #{alarmType}</if>
+            <if test="params.beginTime != null and params.beginTime != '' and params.endTime != null and params.endTime != ''"> and date(create_time) between #{params.beginTime} and #{params.endTime}</if>
+            and is_del='0'
+        </where>
+        group by date(create_time)
+    </select>
+
+    <select id="groupCountByAlarmType" parameterType="DevAiProjectData" resultType="map">
+        select dapd.alarm_type as type,sdd.dict_label as name, count(1) as value from dev_ai_project_data dapd
+        left join sys_dict_data sdd on sdd.dict_type='aibox_alarm_type' and sdd.dict_value=dapd.alarm_type
+        <where>
+            <if test="projectId != null "> and dapd.project_id = #{projectId}</if>
+            <if test="deviceName != null  and deviceName != ''"> and dapd.device_name like concat('%', #{deviceName}, '%')</if>
+            <if test="alarmType != null "> and dapd.alarm_type = #{alarmType}</if>
+            <if test="params.date != null"> and date(dapd.create_time) = date(#{params.date})</if>
+            and dapd.is_del='0'
+        </where>
+        GROUP BY dapd.alarm_type
+    </select>
+
 </mapper>
\ No newline at end of file
diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/ProPlanScheduleMapper.xml b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/ProPlanScheduleMapper.xml
new file mode 100644
index 00000000..06d47020
--- /dev/null
+++ b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/ProPlanScheduleMapper.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.yanzhu.manage.mapper.ProPlanScheduleMapper">
+    
+    <resultMap type="ProPlanSchedule" id="ProPlanScheduleResult">
+        <result property="id"    column="id"    />
+        <result property="comId"    column="com_id"    />
+        <result property="projectId"    column="project_id"    />
+        <result property="planId"    column="plan_id"    />
+        <result property="taskId"    column="task_id"    />
+        <result property="taskUniqueId"    column="task_unique_id"    />
+        <result property="taskName"    column="task_name"    />
+        <result property="bimId"    column="bim_id"    />
+        <result property="schedulePercent"    column="schedule_percent"    />
+        <result property="finishDate"    column="finish_date"    />
+        <result property="description"    column="description"    />
+        <result property="images"    column="images"    />
+        <result property="isDel"    column="is_del"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createUserId"    column="create_user_id"    />
+        <result property="createDate"    column="create_date"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateDate"    column="update_date"    />
+    </resultMap>
+
+    <sql id="selectProPlanScheduleVo">
+        select id, com_id, project_id, plan_id, task_id, task_unique_id, task_name, bim_id, schedule_percent, finish_date, description, images, is_del, create_by, create_user_id, create_date, update_by, update_date from pro_plan_schedule
+    </sql>
+
+    <select id="selectProPlanScheduleList" parameterType="ProPlanSchedule" resultMap="ProPlanScheduleResult">
+        <include refid="selectProPlanScheduleVo"/>
+        <where>  
+            <if test="comId != null "> and com_id = #{comId}</if>
+            <if test="projectId != null "> and project_id = #{projectId}</if>
+            <if test="planId != null "> and plan_id = #{planId}</if>
+            <if test="taskId != null "> and task_id = #{taskId}</if>
+            <if test="taskUniqueId != null  and taskUniqueId != ''"> and task_unique_id = #{taskUniqueId}</if>
+            <if test="taskName != null  and taskName != ''"> and task_name like concat('%', #{taskName}, '%')</if>
+            <if test="bimId != null  and bimId != ''"> and bim_id = #{bimId}</if>
+            <if test="isDel != null "> and is_del = #{isDel}</if>
+            <if test="createUserId != null "> and create_user_id = #{createUserId}</if>
+        </where>
+    </select>
+    
+    <select id="selectProPlanScheduleById" parameterType="Long" resultMap="ProPlanScheduleResult">
+        <include refid="selectProPlanScheduleVo"/>
+        where id = #{id}
+    </select>
+        
+    <insert id="insertProPlanSchedule" parameterType="ProPlanSchedule" useGeneratedKeys="true" keyProperty="id">
+        insert into pro_plan_schedule
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="comId != null">com_id,</if>
+            <if test="projectId != null">project_id,</if>
+            <if test="planId != null">plan_id,</if>
+            <if test="taskId != null">task_id,</if>
+            <if test="taskUniqueId != null">task_unique_id,</if>
+            <if test="taskName != null">task_name,</if>
+            <if test="bimId != null">bim_id,</if>
+            <if test="schedulePercent != null">schedule_percent,</if>
+            <if test="finishDate != null">finish_date,</if>
+            <if test="description != null">description,</if>
+            <if test="images != null">images,</if>
+            <if test="isDel != null">is_del,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createUserId != null">create_user_id,</if>
+            <if test="createDate != null">create_date,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateDate != null">update_date,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="comId != null">#{comId},</if>
+            <if test="projectId != null">#{projectId},</if>
+            <if test="planId != null">#{planId},</if>
+            <if test="taskId != null">#{taskId},</if>
+            <if test="taskUniqueId != null">#{taskUniqueId},</if>
+            <if test="taskName != null">#{taskName},</if>
+            <if test="bimId != null">#{bimId},</if>
+            <if test="schedulePercent != null">#{schedulePercent},</if>
+            <if test="finishDate != null">#{finishDate},</if>
+            <if test="description != null">#{description},</if>
+            <if test="images != null">#{images},</if>
+            <if test="isDel != null">#{isDel},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createUserId != null">#{createUserId},</if>
+            <if test="createDate != null">#{createDate},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateDate != null">#{updateDate},</if>
+         </trim>
+    </insert>
+
+    <update id="updateProPlanSchedule" parameterType="ProPlanSchedule">
+        update pro_plan_schedule
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="comId != null">com_id = #{comId},</if>
+            <if test="projectId != null">project_id = #{projectId},</if>
+            <if test="planId != null">plan_id = #{planId},</if>
+            <if test="taskId != null">task_id = #{taskId},</if>
+            <if test="taskUniqueId != null">task_unique_id = #{taskUniqueId},</if>
+            <if test="taskName != null">task_name = #{taskName},</if>
+            <if test="bimId != null">bim_id = #{bimId},</if>
+            <if test="schedulePercent != null">schedule_percent = #{schedulePercent},</if>
+            <if test="finishDate != null">finish_date = #{finishDate},</if>
+            <if test="description != null">description = #{description},</if>
+            <if test="images != null">images = #{images},</if>
+            <if test="isDel != null">is_del = #{isDel},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createUserId != null">create_user_id = #{createUserId},</if>
+            <if test="createDate != null">create_date = #{createDate},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateDate != null">update_date = #{updateDate},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteProPlanScheduleById" parameterType="Long">
+        delete from pro_plan_schedule where id = #{id}
+    </delete>
+
+    <delete id="deleteProPlanScheduleByIds" parameterType="String">
+        delete from pro_plan_schedule where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>
\ No newline at end of file
diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/system/SysUserMapper.xml b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/system/SysUserMapper.xml
index dc07036d..2d7cadf0 100644
--- a/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/system/SysUserMapper.xml
@@ -74,13 +74,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		    left join sys_role r on r.role_id = ur.role_id
         	left join sys_user_ext ex on u.user_id=ex.user_id
     </sql>
-    
+
     <select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
 		select u.user_id, u.com_id, u.dept_id, u.nick_name, u.user_name,  u.email, u.avatar, u.phonenumber, u.sex, u.status,ex.user_type,ex.work_type,
 		       u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader
 		from sys_user u
 		left join sys_dept d on u.dept_id = d.dept_id
-		left join sys_user_ext ex on u.user_id=ex.user_id
+		left join sys_user_ext ex on u.user_id = ex.user_id and u.dept_id = ex.project_id
 		where u.del_flag = '0' and ex.user_type != '99'
 		<if test="userId != null and userId != 0">
 			AND u.user_id = #{userId}
diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/DevAiProjectDataController.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/DevAiProjectDataController.java
index 08e36f8e..3d379d85 100644
--- a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/DevAiProjectDataController.java
+++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/DevAiProjectDataController.java
@@ -1,19 +1,26 @@
 package com.yanzhu.manage.controller;
 
+import com.yanzhu.common.core.utils.StringUtils;
 import com.yanzhu.common.core.utils.poi.ExcelUtil;
 import com.yanzhu.common.core.web.controller.BaseController;
 import com.yanzhu.common.core.web.domain.AjaxResult;
 import com.yanzhu.common.core.web.page.TableDataInfo;
 import com.yanzhu.common.log.annotation.Log;
 import com.yanzhu.common.log.enums.BusinessType;
+import com.yanzhu.common.redis.service.RedisService;
 import com.yanzhu.common.security.annotation.RequiresPermissions;
+import com.yanzhu.device.domain.DevIotDatas;
 import com.yanzhu.manage.domain.DevAiProjectData;
 import com.yanzhu.manage.service.IDevAiProjectDataService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
-import java.util.List;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 /**
  * AI设备数据Controller
@@ -25,13 +32,16 @@ import java.util.List;
 @RequestMapping("/devAiProjectData")
 public class DevAiProjectDataController extends BaseController
 {
+    @Autowired
+    private RedisService redisService;
+
     @Autowired
     private IDevAiProjectDataService devAiProjectDataService;
 
     /**
      * 查询AI设备数据列表
+     * @RequiresPermissions("manage:devAiProjectData:list")
      */
-    @RequiresPermissions("manage:devAiProjectData:list")
     @GetMapping("/list")
     public TableDataInfo list(DevAiProjectData devAiProjectData)
     {
@@ -95,4 +105,71 @@ public class DevAiProjectDataController extends BaseController
     {
         return toAjax(devAiProjectDataService.deleteDevAiProjectDataByIds(ids));
     }
+
+    /**
+     * 统计AI预警数据
+     */
+    @GetMapping("/getDaysTrendView/{proId}")
+    public AjaxResult getDaysTrendView(@PathVariable("proId") Long proId)
+    {
+        String key = "PUBLIC_AIBOX_listView::"+proId;
+        Object obj = redisService.getCacheObject(key);
+        if(obj!=null){
+            return success(obj);
+        }
+        DevAiProjectData dataQuery = new DevAiProjectData();
+        dataQuery.setProjectId(proId);
+        // 获取当前日期
+        LocalDate today = LocalDate.now();
+        // 获取最近${X}天的日期
+        LocalDate todayAgo = today.minusDays(7);
+        Map<String, Object> params = new HashMap<>();
+        params.put("beginTime",today.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        params.put("endTime",todayAgo.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        dataQuery.setParams(params);
+        List<Map<String, Object>> list = devAiProjectDataService.findDaysTrendView(dataQuery);
+
+        List<Map<String, Object>>  daysTrendList = new ArrayList<>();
+        for (LocalDate date = todayAgo; !date.isAfter(today); date = date.plusDays(1)) {
+            Map<String, Object> dayMap = new HashMap<>();
+            dayMap.put("createTime",date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+            dayMap.put("dayStr",date.format(DateTimeFormatter.ofPattern("MM/dd")));
+            dayMap.put("total",0);
+            daysTrendList.add(dayMap);
+        }
+
+        for (Map<String, Object> date : daysTrendList) {
+            List<Map<String, Object>> _list = list.stream().filter(map -> StringUtils.eqObj(map.get("create_time"),date.get("createTime"))).collect(Collectors.toList());
+            if (_list.size()>0) {
+                date.put("total", _list.get(0).get("total"));
+            }
+        }
+
+        redisService.setCacheObject(key, daysTrendList, 2L, TimeUnit.MINUTES);
+        return success(daysTrendList);
+    }
+
+    /**
+     * 统计AI预警数据
+     */
+    @GetMapping("/groupCountByAlarmType/{proId}")
+    public AjaxResult groupCountByAlarmType(@PathVariable("proId") Long proId, String toDay)
+    {
+        String key = "PUBLIC_AIBOX_groupCountByAlarmType::"+proId+"_"+toDay;
+        Object obj = redisService.getCacheObject(key);
+        if(obj!=null){
+            return success(obj);
+        }
+        DevAiProjectData dataQuery = new DevAiProjectData();
+        dataQuery.setProjectId(proId);
+        //查询当天数据
+        if(toDay!=null && "Y".equals(toDay)){
+            Map<String, Object> params = new HashMap<>();
+            params.put("date",new Date());
+            dataQuery.setParams(params);
+        }
+        List<Map<String, Object>> list = devAiProjectDataService.groupCountByAlarmType(dataQuery);
+        redisService.setCacheObject(key, list, 2L, TimeUnit.MINUTES);
+        return success(list);
+    }
 }
diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/ProPlanScheduleController.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/ProPlanScheduleController.java
new file mode 100644
index 00000000..2c493680
--- /dev/null
+++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/ProPlanScheduleController.java
@@ -0,0 +1,98 @@
+package com.yanzhu.manage.controller;
+
+import com.yanzhu.common.core.utils.poi.ExcelUtil;
+import com.yanzhu.common.core.web.controller.BaseController;
+import com.yanzhu.common.core.web.domain.AjaxResult;
+import com.yanzhu.common.core.web.page.TableDataInfo;
+import com.yanzhu.common.log.annotation.Log;
+import com.yanzhu.common.log.enums.BusinessType;
+import com.yanzhu.common.security.annotation.RequiresPermissions;
+import com.yanzhu.manage.domain.ProPlanSchedule;
+import com.yanzhu.manage.service.IProPlanScheduleService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 项目进度Controller
+ * 
+ * @author yanzhu
+ * @date 2025-04-14
+ */
+@RestController
+@RequestMapping("/schedule")
+public class ProPlanScheduleController extends BaseController
+{
+    @Autowired
+    private IProPlanScheduleService proPlanScheduleService;
+
+    /**
+     * 查询项目进度列表
+     */
+    @RequiresPermissions("manage:schedule:list")
+    @GetMapping("/list")
+    public TableDataInfo list(ProPlanSchedule proPlanSchedule)
+    {
+        startPage();
+        List<ProPlanSchedule> list = proPlanScheduleService.selectProPlanScheduleList(proPlanSchedule);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出项目进度列表
+     */
+    @RequiresPermissions("manage:schedule:export")
+    @Log(title = "项目进度", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, ProPlanSchedule proPlanSchedule)
+    {
+        List<ProPlanSchedule> list = proPlanScheduleService.selectProPlanScheduleList(proPlanSchedule);
+        ExcelUtil<ProPlanSchedule> util = new ExcelUtil<ProPlanSchedule>(ProPlanSchedule.class);
+        util.exportExcel(response, list, "项目进度数据");
+    }
+
+    /**
+     * 获取项目进度详细信息
+     */
+    @RequiresPermissions("manage:schedule:query")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(proPlanScheduleService.selectProPlanScheduleById(id));
+    }
+
+    /**
+     * 新增项目进度
+     */
+    @RequiresPermissions("manage:schedule:add")
+    @Log(title = "项目进度", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody ProPlanSchedule proPlanSchedule)
+    {
+        return toAjax(proPlanScheduleService.insertProPlanSchedule(proPlanSchedule));
+    }
+
+    /**
+     * 修改项目进度
+     */
+    @RequiresPermissions("manage:schedule:edit")
+    @Log(title = "项目进度", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody ProPlanSchedule proPlanSchedule)
+    {
+        return toAjax(proPlanScheduleService.updateProPlanSchedule(proPlanSchedule));
+    }
+
+    /**
+     * 删除项目进度
+     */
+    @RequiresPermissions("manage:schedule:remove")
+    @Log(title = "项目进度", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(proPlanScheduleService.deleteProPlanScheduleByIds(ids));
+    }
+}
diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/ProProjectInfoSubdeptsUsersController.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/ProProjectInfoSubdeptsUsersController.java
index 2d520602..7a3d8a4f 100644
--- a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/ProProjectInfoSubdeptsUsersController.java
+++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/ProProjectInfoSubdeptsUsersController.java
@@ -21,6 +21,8 @@ import com.yanzhu.manage.enums.SubDeptsEnums;
 import com.yanzhu.manage.enums.UserPostEnums;
 import com.yanzhu.manage.service.IProProjectInfoSubdeptsUsersService;
 import com.yanzhu.manage.service.IUniService;
+import com.yanzhu.security.utils.DictUtils;
+import com.yanzhu.system.api.domain.SysDictData;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -377,7 +379,7 @@ public class ProProjectInfoSubdeptsUsersController extends BaseController
             List<Map<String,Object>> checkUserList = new ArrayList<>();
             for(ProProjectInfoSubdeptsUsers user:list){
                 // 组装整改单位信息
-                if(!Objects.equals(user.getSubDeptType(), SubDeptsEnums.JSDW.getCode())){
+                //if(!Objects.equals(user.getSubDeptType(), SubDeptsEnums.JSDW.getCode())){
                     List<Map<String,Object>> _lordSentList = lordSentList.stream().filter(map -> StringUtils.eqObj(map.get("subDeptId"),user.getSubDeptId())).collect(Collectors.toList());
                     if(_lordSentList.size()==0){
                         Map<String,Object> data = new HashMap<>();
@@ -386,7 +388,7 @@ public class ProProjectInfoSubdeptsUsersController extends BaseController
                         data.put("subDeptTypeName",user.getSubDeptTypeName());
                         lordSentList.add(data);
                     }
-                }
+                //}
                 // 组装抄送单位信息
                 List<Map<String,Object>> _copySendList = copySendList.stream().filter(map -> StringUtils.eqObj(map.get("subDeptId"),user.getSubDeptId())).collect(Collectors.toList());
                 if(_copySendList.size()==0){
@@ -420,12 +422,27 @@ public class ProProjectInfoSubdeptsUsersController extends BaseController
                 for(Map<String,Object> data:lordSentList){
                     List<Map<String,Object>> userList = new ArrayList<>();
                     for(ProProjectInfoSubdeptsUsers user:list){
-                        if(!Objects.equals(user.getSubDeptType(),SubDeptsEnums.JSDW.getCode()) && StringUtils.eqObj(data.get("subDeptId"),user.getSubDeptId())){
+                        //if(!Objects.equals(user.getSubDeptType(),SubDeptsEnums.JSDW.getCode()) && StringUtils.eqObj(data.get("subDeptId"),user.getSubDeptId())){
+                        if(StringUtils.eqObj(data.get("subDeptId"),user.getSubDeptId())){
                             Map<String,Object> userMap = new HashMap<>();
                             userMap.put("userId",user.getUserId());
                             userMap.put("userName",user.getUserName());
                             userMap.put("userPhone",user.getUserPhone());
-                            userMap.put("userPostName",StringUtils.eqObj(user.getUserPost(), UserPostEnums.BZZ.getCode())?user.getCraftPostName()+UserPostEnums.BZZ.getInfo():user.getCraftPostName());
+                            String userPost = "";
+                            if(Objects.equals(user.getSubDeptType(),SubDeptsEnums.JSDW.getCode())){
+                                if(user.getWorkType()!=null){
+                                    SysDictData dictData = DictUtils.getDictCache("user_work_type",user.getWorkType().toString());
+                                    if(dictData!=null){
+                                        if(StringUtils.isNotEmpty(dictData.getRemark())){
+                                            userPost += dictData.getRemark();
+                                        }
+                                        userPost += dictData.getDictLabel();
+                                    }
+                                }
+                            }else{
+                                userPost = StringUtils.eqObj(user.getUserPost(), UserPostEnums.BZZ.getCode())?user.getCraftPostName()+UserPostEnums.BZZ.getInfo():user.getCraftPostName();
+                            }
+                            userMap.put("userPostName",userPost);
                             userMap.put("state",false);
                             userList.add(userMap);
                         }
diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IDevAiProjectDataService.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IDevAiProjectDataService.java
index 9240c43e..52ece4b6 100644
--- a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IDevAiProjectDataService.java
+++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IDevAiProjectDataService.java
@@ -1,6 +1,8 @@
 package com.yanzhu.manage.service;
 
 import java.util.List;
+import java.util.Map;
+
 import com.yanzhu.manage.domain.DevAiProjectData;
 import com.yanzhu.manage.domain.DevAiProjectDataVO;
 import com.yanzhu.manage.domain.DevBGAiDataVO;
@@ -77,4 +79,20 @@ public interface IDevAiProjectDataService
      * @return 结果
      */
     public int deleteDevAiProjectDataById(Long id);
+
+    /**
+     * 最近预警趋势
+     *
+     * @param devAiProjectData 查询条件
+     * @return 结果
+     */
+    public List<Map<String, Object>> findDaysTrendView(DevAiProjectData devAiProjectData);
+
+    /**
+     * 设备数据统计
+     *
+     * @param devAiProjectData 查询条件
+     * @return 结果
+     */
+    public List<Map<String, Object>> groupCountByAlarmType(DevAiProjectData devAiProjectData);
 }
diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IProPlanScheduleService.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IProPlanScheduleService.java
new file mode 100644
index 00000000..12b8f78f
--- /dev/null
+++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IProPlanScheduleService.java
@@ -0,0 +1,61 @@
+package com.yanzhu.manage.service;
+
+import java.util.List;
+import com.yanzhu.manage.domain.ProPlanSchedule;
+
+/**
+ * 项目进度Service接口
+ * 
+ * @author yanzhu
+ * @date 2025-04-14
+ */
+public interface IProPlanScheduleService 
+{
+    /**
+     * 查询项目进度
+     * 
+     * @param id 项目进度主键
+     * @return 项目进度
+     */
+    public ProPlanSchedule selectProPlanScheduleById(Long id);
+
+    /**
+     * 查询项目进度列表
+     * 
+     * @param proPlanSchedule 项目进度
+     * @return 项目进度集合
+     */
+    public List<ProPlanSchedule> selectProPlanScheduleList(ProPlanSchedule proPlanSchedule);
+
+    /**
+     * 新增项目进度
+     * 
+     * @param proPlanSchedule 项目进度
+     * @return 结果
+     */
+    public int insertProPlanSchedule(ProPlanSchedule proPlanSchedule);
+
+    /**
+     * 修改项目进度
+     * 
+     * @param proPlanSchedule 项目进度
+     * @return 结果
+     */
+    public int updateProPlanSchedule(ProPlanSchedule proPlanSchedule);
+
+    /**
+     * 批量删除项目进度
+     * 
+     * @param ids 需要删除的项目进度主键集合
+     * @return 结果
+     */
+    public int deleteProPlanScheduleByIds(Long[] ids);
+
+    /**
+     * 删除项目进度信息
+     * 
+     * @param id 项目进度主键
+     * @return 结果
+     */
+    public int deleteProPlanScheduleById(Long id);
+}
diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/DevAiProjectDataServiceImpl.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/DevAiProjectDataServiceImpl.java
index 463a78f2..c9b91f19 100644
--- a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/DevAiProjectDataServiceImpl.java
+++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/DevAiProjectDataServiceImpl.java
@@ -65,8 +65,10 @@ public class DevAiProjectDataServiceImpl implements IDevAiProjectDataService
     @Override
     public List<DevAiProjectData> selectDevAiProjectDataList(DevAiProjectData devAiProjectData)
     {
-        devAiProjectData.setActiveComId(SecurityUtils.getLoginUser().getSysUser().getActiveComId());
-        devAiProjectData.setActiveProjectId(SecurityUtils.getLoginUser().getSysUser().getActiveProjectId());
+        if(devAiProjectData.getProjectId()==null){
+            devAiProjectData.setActiveComId(SecurityUtils.getLoginUser().getSysUser().getActiveComId());
+            devAiProjectData.setActiveProjectId(SecurityUtils.getLoginUser().getSysUser().getActiveProjectId());
+        }
         return devAiProjectDataMapper.selectDevAiProjectDataList(devAiProjectData);
     }
 
@@ -265,4 +267,26 @@ public class DevAiProjectDataServiceImpl implements IDevAiProjectDataService
     {
         return devAiProjectDataMapper.deleteDevAiProjectDataById(id);
     }
+
+    /**
+     * 最近预警趋势
+     *
+     * @param devAiProjectData 查询条件
+     * @return 结果
+     */
+    @Override
+    public List<Map<String, Object>> findDaysTrendView(DevAiProjectData devAiProjectData){
+        return devAiProjectDataMapper.findDaysTrendView(devAiProjectData);
+    }
+
+    /**
+     * 设备数据统计
+     *
+     * @param devAiProjectData 查询条件
+     * @return 结果
+     */
+    @Override
+    public List<Map<String, Object>> groupCountByAlarmType(DevAiProjectData devAiProjectData) {
+        return devAiProjectDataMapper.groupCountByAlarmType(devAiProjectData);
+    }
 }
diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProPlanScheduleServiceImpl.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProPlanScheduleServiceImpl.java
new file mode 100644
index 00000000..b7accae0
--- /dev/null
+++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProPlanScheduleServiceImpl.java
@@ -0,0 +1,97 @@
+package com.yanzhu.manage.service.impl;
+
+import com.yanzhu.common.core.context.SecurityContextHolder;
+import com.yanzhu.manage.domain.ProPlanSchedule;
+import com.yanzhu.manage.mapper.ProPlanScheduleMapper;
+import com.yanzhu.manage.service.IProPlanScheduleService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 项目进度Service业务层处理
+ * 
+ * @author yanzhu
+ * @date 2025-04-14
+ */
+@Service
+public class ProPlanScheduleServiceImpl implements IProPlanScheduleService 
+{
+    @Autowired
+    private ProPlanScheduleMapper proPlanScheduleMapper;
+
+    /**
+     * 查询项目进度
+     * 
+     * @param id 项目进度主键
+     * @return 项目进度
+     */
+    @Override
+    public ProPlanSchedule selectProPlanScheduleById(Long id)
+    {
+        return proPlanScheduleMapper.selectProPlanScheduleById(id);
+    }
+
+    /**
+     * 查询项目进度列表
+     * 
+     * @param proPlanSchedule 项目进度
+     * @return 项目进度
+     */
+    @Override
+    public List<ProPlanSchedule> selectProPlanScheduleList(ProPlanSchedule proPlanSchedule)
+    {
+        return proPlanScheduleMapper.selectProPlanScheduleList(proPlanSchedule);
+    }
+
+    /**
+     * 新增项目进度
+     * 
+     * @param proPlanSchedule 项目进度
+     * @return 结果
+     */
+    @Override
+    public int insertProPlanSchedule(ProPlanSchedule proPlanSchedule)
+    {
+        proPlanSchedule.setCreateBy(SecurityContextHolder.getUserName());
+        return proPlanScheduleMapper.insertProPlanSchedule(proPlanSchedule);
+    }
+
+    /**
+     * 修改项目进度
+     * 
+     * @param proPlanSchedule 项目进度
+     * @return 结果
+     */
+    @Override
+    public int updateProPlanSchedule(ProPlanSchedule proPlanSchedule)
+    {
+        proPlanSchedule.setUpdateBy(SecurityContextHolder.getUserName());
+        return proPlanScheduleMapper.updateProPlanSchedule(proPlanSchedule);
+    }
+
+    /**
+     * 批量删除项目进度
+     * 
+     * @param ids 需要删除的项目进度主键
+     * @return 结果
+     */
+    @Override
+    public int deleteProPlanScheduleByIds(Long[] ids)
+    {
+        return proPlanScheduleMapper.deleteProPlanScheduleByIds(ids);
+    }
+
+    /**
+     * 删除项目进度信息
+     * 
+     * @param id 项目进度主键
+     * @return 结果
+     */
+    @Override
+    public int deleteProPlanScheduleById(Long id)
+    {
+        return proPlanScheduleMapper.deleteProPlanScheduleById(id);
+    }
+}