LIJIAN преди 1 месец
родител
ревизия
a76ac8d3e3

+ 14 - 2
ema-admin/src/main/java/com/ema/admin/modules/assets/controller/AssetsInfoController.java

@@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.beans.factory.annotation.Autowired;
 import com.ema.admin.modules.assets.entity.AssetsInfo;
 import com.ema.admin.modules.assets.vo.AssetsInfoQueryVo;
+import com.ema.admin.modules.assets.vo.AssetsStatisticsVo;
 import com.ema.admin.modules.assets.service.AssetsInfoService;
 import org.springframework.web.bind.annotation.RestController;
 import io.swagger.annotations.Api;
@@ -35,7 +36,7 @@ public class AssetsInfoController {
     /**
      * 添加。
      *
-     * @param assetsInfo 
+     * @param assetsInfo
      * @return {@code true} 添加成功,{@code false} 添加失败
      */
     @PostMapping("save")
@@ -59,7 +60,7 @@ public class AssetsInfoController {
     /**
      * 根据主键更新。
      *
-     * @param assetsInfo 
+     * @param assetsInfo
      * @return {@code true} 更新成功,{@code false} 更新失败
      */
     @PutMapping("update")
@@ -103,4 +104,15 @@ public class AssetsInfoController {
         return assetsInfoService.page(queryVo);
     }
 
+    /**
+     * 获取资产统计信息
+     *
+     * @return 统计信息
+     */
+    @GetMapping("statistics")
+    @ApiOperation("获取资产统计信息")
+    public AssetsStatisticsVo getStatistics() {
+        return assetsInfoService.getStatistics();
+    }
+
 }

+ 8 - 0
ema-admin/src/main/java/com/ema/admin/modules/assets/service/AssetsInfoService.java

@@ -4,6 +4,7 @@ import com.mybatisflex.core.paginate.Page;
 import com.mybatisflex.core.service.IService;
 import com.ema.admin.modules.assets.entity.AssetsInfo;
 import com.ema.admin.modules.assets.vo.AssetsInfoQueryVo;
+import com.ema.admin.modules.assets.vo.AssetsStatisticsVo;
 
 /**
  *  资产信息表 服务层。
@@ -21,4 +22,11 @@ public interface AssetsInfoService extends IService<AssetsInfo> {
      */
     Page<AssetsInfo> page(AssetsInfoQueryVo queryVo);
 
+    /**
+     * 获取资产统计信息
+     *
+     * @return 统计信息
+     */
+    AssetsStatisticsVo getStatistics();
+
 }

+ 78 - 0
ema-admin/src/main/java/com/ema/admin/modules/assets/service/impl/AssetsInfoServiceImpl.java

@@ -3,6 +3,7 @@ package com.ema.admin.modules.assets.service.impl;
 import cn.hutool.core.util.StrUtil;
 import com.ema.admin.modules.assets.entity.AssetsInfo;
 import com.ema.admin.modules.assets.vo.AssetsInfoQueryVo;
+import com.ema.admin.modules.assets.vo.AssetsStatisticsVo;
 import com.ema.admin.modules.assets.mapper.AssetsInfoMapper;
 import com.ema.admin.modules.assets.service.AssetsInfoService;
 import com.mybatisflex.core.paginate.Page;
@@ -10,6 +11,12 @@ import com.mybatisflex.core.query.QueryWrapper;
 import com.mybatisflex.spring.service.impl.ServiceImpl;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 /**
  *  资产信息表 服务层实现。
  *
@@ -31,4 +38,75 @@ public class AssetsInfoServiceImpl extends ServiceImpl<AssetsInfoMapper, AssetsI
         queryWrapper.orderBy(AssetsInfo::getCreateTime, false);
         return this.page(new Page<>(queryVo.getPageNumber(), queryVo.getPageSize()), queryWrapper);
     }
+
+    @Override
+    public AssetsStatisticsVo getStatistics() {
+        AssetsStatisticsVo vo = new AssetsStatisticsVo();
+
+        // 查询所有资产
+        List<AssetsInfo> allAssets = this.list();
+
+        // 资产总数
+        long totalCount = allAssets.size();
+        vo.setTotalCount(totalCount);
+
+        // 资产总价值
+        BigDecimal totalValue = allAssets.stream()
+                .filter(a -> a.getPurchaseValue() != null)
+                .map(AssetsInfo::getPurchaseValue)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        vo.setTotalValue(totalValue);
+
+        // 已盘点数量
+        long invstkYesCount = allAssets.stream()
+                .filter(a -> "1".equals(a.getInvstkStatus()))
+                .count();
+        vo.setInvstkYesCount(invstkYesCount);
+
+        // 未盘点数量
+        long invstkNoCount = totalCount - invstkYesCount;
+        vo.setInvstkNoCount(invstkNoCount);
+
+        // 盘点率
+        double invstkRate = totalCount > 0 ? (double) invstkYesCount / totalCount * 100 : 0;
+        vo.setInvstkRate(Math.round(invstkRate * 100.0) / 100.0);
+
+        // 资产类型分布
+        Map<String, Long> typeCountMap = new HashMap<>();
+        Map<String, BigDecimal> typeValueMap = new HashMap<>();
+        for (AssetsInfo asset : allAssets) {
+            String type = asset.getAssetType();
+            if (StrUtil.isNotBlank(type)) {
+                typeCountMap.merge(type, 1L, Long::sum);
+                if (asset.getPurchaseValue() != null) {
+                    typeValueMap.merge(type, asset.getPurchaseValue(), BigDecimal::add);
+                }
+            }
+        }
+        List<AssetsStatisticsVo.TypeCount> typeDistribution = new ArrayList<>();
+        typeCountMap.forEach((type, count) -> {
+            AssetsStatisticsVo.TypeCount tc = new AssetsStatisticsVo.TypeCount();
+            tc.setName(type);
+            tc.setCount(count);
+            tc.setValue(typeValueMap.getOrDefault(type, BigDecimal.ZERO));
+            typeDistribution.add(tc);
+        });
+        vo.setTypeDistribution(typeDistribution);
+
+        // 使用状态分布(从资产状态历史表获取最新状态,需要关联查询,这里简化为从资产表统计)
+        // 由于资产表没有直接的使用状态字段,这里返回空列表或根据invstkStatus统计
+        Map<String, Long> statusCountMap = new HashMap<>();
+        statusCountMap.put("已盘点", invstkYesCount);
+        statusCountMap.put("未盘点", invstkNoCount);
+        List<AssetsStatisticsVo.TypeCount> statusDistribution = new ArrayList<>();
+        statusCountMap.forEach((status, count) -> {
+            AssetsStatisticsVo.TypeCount sc = new AssetsStatisticsVo.TypeCount();
+            sc.setName(status);
+            sc.setCount(count);
+            statusDistribution.add(sc);
+        });
+        vo.setStatusDistribution(statusDistribution);
+
+        return vo;
+    }
 }

+ 95 - 0
ema-admin/src/main/java/com/ema/admin/modules/assets/vo/AssetsStatisticsVo.java

@@ -0,0 +1,95 @@
+package com.ema.admin.modules.assets.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 资产统计VO
+ *
+ * @author LIJIAN
+ * @since 2026-05-15
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@ApiModel("资产统计")
+public class AssetsStatisticsVo {
+
+    /**
+     * 资产总数
+     */
+    @ApiModelProperty("资产总数")
+    private Long totalCount;
+
+    /**
+     * 资产总价值
+     */
+    @ApiModelProperty("资产总价值")
+    private BigDecimal totalValue;
+
+    /**
+     * 已盘点数量
+     */
+    @ApiModelProperty("已盘点数量")
+    private Long invstkYesCount;
+
+    /**
+     * 未盘点数量
+     */
+    @ApiModelProperty("未盘点数量")
+    private Long invstkNoCount;
+
+    /**
+     * 盘点率
+     */
+    @ApiModelProperty("盘点率")
+    private Double invstkRate;
+
+    /**
+     * 资产类型分布
+     */
+    @ApiModelProperty("资产类型分布")
+    private List<TypeCount> typeDistribution;
+
+    /**
+     * 使用状态分布
+     */
+    @ApiModelProperty("使用状态分布")
+    private List<TypeCount> statusDistribution;
+
+    /**
+     * 资产类型数量
+     */
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class TypeCount {
+        /**
+         * 类型名称
+         */
+        @ApiModelProperty("类型名称")
+        private String name;
+
+        /**
+         * 数量
+         */
+        @ApiModelProperty("数量")
+        private Long count;
+
+        /**
+         * 金额
+         */
+        @ApiModelProperty("金额")
+        private BigDecimal value;
+    }
+}

+ 2 - 1
ema-admin/src/main/resources/web/js/config.js

@@ -114,7 +114,8 @@ var Config = {
             save: '/assetsInfo/save',
             update: '/assetsInfo/update',
             remove: '/assetsInfo/remove',
-            getInfo: '/assetsInfo/getInfo'
+            getInfo: '/assetsInfo/getInfo',
+            statistics: '/assetsInfo/statistics'
         },
 
         // 资产状态历史

+ 276 - 63
ema-admin/src/main/resources/web/pages/home.html

@@ -7,80 +7,202 @@
     <link rel="stylesheet" href="../lib/layui/css/layui.css">
     <style>
         body { padding: 20px; background: #f5f5f5; }
-        .home-title { font-size: 24px; font-weight: 600; margin-bottom: 20px; color: #333; }
-        .stat-card { background: #fff; border-radius: 8px; padding: 20px; margin-bottom: 20px; }
-        .stat-card .stat-icon { width: 60px; height: 60px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 28px; color: #fff; }
-        .stat-card .stat-num { font-size: 32px; font-weight: 600; color: #333; }
-        .stat-card .stat-text { color: #999; font-size: 14px; }
-        .info-card { background: #fff; border-radius: 8px; padding: 20px; margin-bottom: 20px; }
-        .info-card .card-title { font-size: 16px; font-weight: 600; color: #333; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #eee; }
-        .info-list li { padding: 10px 0; border-bottom: 1px dashed #eee; display: flex; justify-content: space-between; }
+        .home-title { font-size: 24px; font-weight: 600; margin-bottom: 20px; color: #333; display: flex; justify-content: space-between; align-items: center; }
+        .home-title .welcome { color: #666; font-size: 14px; font-weight: normal; }
+        .home-title .date-time { color: #999; font-size: 13px; font-weight: normal; }
+        .stat-card { background: #fff; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); border: 1px solid #e8e8e8; }
+        .stat-card .stat-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; }
+        .stat-card .stat-icon { width: 50px; height: 50px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 24px; color: #fff; }
+        .stat-card .stat-body { display: flex; align-items: center; gap: 20px; }
+        .stat-card .stat-info { flex: 1; }
+        .stat-card .stat-num { font-size: 28px; font-weight: 600; color: #333; line-height: 1; }
+        .stat-card .stat-text { color: #999; font-size: 14px; margin-top: 5px; }
+        .stat-card .stat-trend { font-size: 12px; padding: 3px 8px; border-radius: 4px; }
+        .stat-card .stat-trend.up { color: #52c41a; background: rgba(82,196,26,0.1); }
+        .stat-card .stat-trend.down { color: #ff4d4f; background: rgba(255,77,79,0.1); }
+        .info-card { background: #fff; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); border: 1px solid #e8e8e8; }
+        .info-card .card-title { font-size: 16px; font-weight: 600; color: #333; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #e8e8e8; display: flex; justify-content: space-between; align-items: center; }
+        .info-card .card-title .more { font-size: 13px; color: #999; font-weight: normal; cursor: pointer; }
+        .info-card .card-title .more:hover { color: #1E9FFF; }
+        .info-list { margin: 0; padding: 0; list-style: none; }
+        .info-list li { padding: 12px 0; border-bottom: 1px solid #f0f0f0; display: flex; justify-content: space-between; align-items: center; }
         .info-list li:last-child { border-bottom: none; }
-        .quick-menu { display: flex; flex-wrap: wrap; gap: 15px; }
-        .quick-menu a { width: 120px; height: 80px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 8px; display: flex; flex-direction: column; align-items: center; justify-content: center; color: #fff; text-decoration: none; transition: transform 0.3s; }
-        .quick-menu a:hover { transform: translateY(-5px); box-shadow: 0 5px 20px rgba(102, 126, 234, 0.4); }
-        .quick-menu a i { font-size: 28px; margin-bottom: 8px; }
-        .quick-menu a span { font-size: 13px; }
+        .info-list li .label { color: #666; font-size: 14px; }
+        .info-list li .value { color: #333; font-size: 14px; font-weight: 500; }
+        .log-item { display: flex; padding: 12px 0; border-bottom: 1px solid #f0f0f0; }
+        .log-item:last-child { border-bottom: none; }
+        .log-item .log-icon { width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-right: 12px; flex-shrink: 0; font-size: 14px; color: #fff; }
+        .log-item .log-content { flex: 1; min-width: 0; }
+        .log-item .log-title { color: #333; font-size: 14px; margin-bottom: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
+        .log-item .log-meta { color: #999; font-size: 12px; display: flex; gap: 15px; }
+        .log-item .log-meta span { display: flex; align-items: center; gap: 4px; }
+        .empty-data { text-align: center; padding: 40px 0; color: #999; font-size: 14px; }
+        .row { display: flex; gap: 20px; margin-bottom: 20px; }
+        .row .col { flex: 1; min-width: 0; }
+        .row .col-half { flex: 0 0 calc(50% - 10px); }
+        .row .col-third { flex: 0 0 calc(33.333% - 14px); }
+        .section-title { font-size: 18px; font-weight: 600; color: #333; margin: 30px 0 15px 0; padding-left: 12px; border-left: 4px solid #1E9FFF; }
+        /* 资产统计样式 */
+        .assets-stat-row { display: flex; gap: 15px; margin-bottom: 15px; }
+        .assets-stat-item { flex: 1; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 8px; padding: 15px; color: #fff; text-align: center; }
+        .assets-stat-item.green { background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); }
+        .assets-stat-item.orange { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }
+        .assets-stat-item.blue { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); }
+        .assets-stat-item .stat-value { font-size: 28px; font-weight: 600; }
+        .assets-stat-item .stat-label { font-size: 13px; opacity: 0.9; margin-top: 4px; }
+        .assets-stat-item .stat-value.yuan { font-size: 20px; }
+        .distribution-list { display: flex; flex-direction: column; gap: 12px; }
+        .distribution-item { display: flex; align-items: center; gap: 12px; }
+        .distribution-item .dist-label { width: 80px; color: #666; font-size: 14px; flex-shrink: 0; }
+        .distribution-item .dist-bar-wrap { flex: 1; height: 20px; background: #f5f5f5; border-radius: 10px; overflow: hidden; }
+        .distribution-item .dist-bar { height: 100%; border-radius: 10px; transition: width 0.5s ease; min-width: 4px; }
+        .distribution-item .dist-bar.blue { background: linear-gradient(90deg, #667eea, #764ba2); }
+        .distribution-item .dist-bar.green { background: linear-gradient(90deg, #11998e, #38ef7d); }
+        .distribution-item .dist-bar.orange { background: linear-gradient(90deg, #f093fb, #f5576c); }
+        .distribution-item .dist-bar.cyan { background: linear-gradient(90deg, #4facfe, #00f2fe); }
+        .distribution-item .dist-count { width: 60px; text-align: right; color: #333; font-size: 14px; font-weight: 500; flex-shrink: 0; }
+        .distribution-item .dist-value { width: 100px; text-align: right; color: #999; font-size: 13px; flex-shrink: 0; }
+        .invstk-status { display: flex; align-items: center; gap: 20px; }
+        .invstk-circle { position: relative; width: 120px; height: 120px; }
+        .invstk-circle svg { transform: rotate(-90deg); }
+        .invstk-circle .circle-bg { fill: none; stroke: #f0f0f0; stroke-width: 10; }
+        .invstk-circle .circle-progress { fill: none; stroke: #52c41a; stroke-width: 10; stroke-linecap: round; transition: stroke-dashoffset 1s ease; }
+        .invstk-circle .circle-text { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; }
+        .invstk-circle .circle-text .percent { font-size: 24px; font-weight: 600; color: #333; }
+        .invstk-circle .circle-text .label { font-size: 12px; color: #999; }
+        .invstk-legend { display: flex; flex-direction: column; gap: 10px; justify-content: center; }
+        .invstk-legend-item { display: flex; align-items: center; gap: 8px; font-size: 14px; }
+        .invstk-legend-item .dot { width: 10px; height: 10px; border-radius: 50%; }
+        .invstk-legend-item .dot.yes { background: #52c41a; }
+        .invstk-legend-item .dot.no { background: #f0f0f0; }
+        .invstk-legend-item .text { color: #666; }
+        .invstk-legend-item .count { color: #333; font-weight: 500; margin-left: auto; }
+        @media (max-width: 1200px) {
+            .row .col-third { flex: 0 0 calc(50% - 10px); }
+        }
+        @media (max-width: 768px) {
+            .row { flex-direction: column; }
+            .row .col-half, .row .col-third { flex: 1; }
+            .assets-stat-row { flex-wrap: wrap; }
+            .assets-stat-item { flex: 0 0 calc(50% - 8px); }
+        }
     </style>
 </head>
 <body>
-    <div class="home-title">欢迎使用 EMA 管理系统</div>
-    
-    <div class="layui-row layui-col-space15">
-        <!-- 快捷入口 -->
-        <div class="layui-col-md12">
+
+    <div class="home-title">
+        <div>
+            <span>工作台</span>
+            <span class="welcome" id="welcomeMsg"> 您好, 欢迎使用EMA 管理系统 </span>
+        </div>
+        <span class="date-time" id="currentTime"></span>
+    </div>
+
+    <div class="section-title">资产统计</div>
+    <div class="row">
+        <div class="col col-half">
+            <div class="info-card">
+                <div class="card-title">
+                    <span>资产概览</span>
+                    <span class="more" onclick="parent.openTab('assets/assets_list.html', '资产管理', 'assets_list');">资产管理 ></span>
+                </div>
+                <div class="assets-stat-row">
+                    <div class="assets-stat-item blue">
+                        <div class="stat-value" id="assetsTotalCount">-</div>
+                        <div class="stat-label">资产总数</div>
+                    </div>
+                    <div class="assets-stat-item green">
+                        <div class="stat-value yuan" id="assetsTotalValue">-</div>
+                        <div class="stat-label">资产总价值(元)</div>
+                    </div>
+                    <div class="assets-stat-item orange">
+                        <div class="stat-value" id="assetsInvstkRate">-</div>
+                        <div class="stat-label">盘点完成率(%)</div>
+                    </div>
+                </div>
+                <div class="invstk-status">
+                    <div class="invstk-circle">
+                        <svg width="120" height="120" viewBox="0 0 120 120">
+                            <circle class="circle-bg" cx="60" cy="60" r="50"></circle>
+                            <circle class="circle-progress" id="invstkProgress" cx="60" cy="60" r="50"
+                                    stroke-dasharray="314.16" stroke-dashoffset="314.16"></circle>
+                        </svg>
+                        <div class="circle-text">
+                            <div class="percent" id="invstkPercent">0%</div>
+                            <div class="label">盘点率</div>
+                        </div>
+                    </div>
+                    <div class="invstk-legend">
+                        <div class="invstk-legend-item">
+                            <span class="dot yes"></span>
+                            <span class="text">已盘点</span>
+                            <span class="count" id="invstkYesCount">0</span>
+                        </div>
+                        <div class="invstk-legend-item">
+                            <span class="dot no"></span>
+                            <span class="text">未盘点</span>
+                            <span class="count" id="invstkNoCount">0</span>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="col col-half">
             <div class="info-card">
-                <div class="card-title">快捷入口</div>
-                <div class="quick-menu">
-                    <a href="javascript:parent.openTab('user/user_list.html', '用户管理', 'user_list');" class="open-tab" data-url="user/user_list.html" data-title="用户管理">
-                        <i class="layui-icon layui-icon-user"></i>
-                        <span>用户管理</span>
-                    </a>
-                    <a href="javascript:parent.openTab('role/role_list.html', '角色管理', 'role_list');" class="open-tab" data-url="role/role_list.html" data-title="角色管理">
-                        <i class="layui-icon layui-icon-group"></i>
-                        <span>角色管理</span>
-                    </a>
-                    <a href="javascript:parent.openTab('menu/menu_list.html', '菜单管理', 'menu_list');" class="open-tab" data-url="menu/menu_list.html" data-title="菜单管理">
-                        <i class="layui-icon layui-icon-app"></i>
-                        <span>菜单管理</span>
-                    </a>
-                    <a href="javascript:parent.openTab('department/department_list.html', '部门管理', 'department_list');" class="open-tab" data-url="department/department_list.html" data-title="部门管理">
-                        <i class="layui-icon layui-icon-link"></i>
-                        <span>部门管理</span>
-                    </a>
-                    <a href="javascript:parent.openTab('dict/dict_type_list.html', '字典管理', 'dict_type_list');" class="open-tab" data-url="dict/dict_type_list.html" data-title="字典管理">
-                        <i class="layui-icon layui-icon-note"></i>
-                        <span>字典管理</span>
-                    </a>
-                    <a href="javascript:parent.openTab('job/job_list.html', '定时任务', 'job_list');" class="open-tab" data-url="job/job_list.html" data-title="定时任务">
-                        <i class="layui-icon layui-icon-clock"></i>
-                        <span>定时任务</span>
-                    </a>
+                <div class="card-title">
+                    <span>资产类型分布</span>
+                </div>
+                <div class="distribution-list" id="typeDistribution">
+                    <div class="empty-data">暂无数据</div>
                 </div>
             </div>
         </div>
-        
-        <!-- 系统信息 -->
-        <div class="layui-col-md6">
+    </div>
+    <div class="section-title">信息概览</div>
+    <div class="row">
+        <div class="col col-half">
             <div class="info-card">
-                <div class="card-title">系统信息</div>
+                <div class="card-title">
+                    <span>系统信息</span>
+                </div>
                 <ul class="info-list">
-                    <li><span>当前用户</span><span id="currentUser">-</span></li>
-                    <li><span>登录账号</span><span id="loginAccount">-</span></li>
-                    <li><span>登录时间</span><span id="loginTime">-</span></li>
-                    <li><span>系统版本</span><span>v1.0.0</span></li>
+                    <li>
+                        <span class="label">当前用户</span>
+                        <span class="value" id="currentUser">-</span>
+                    </li>
+                    <li>
+                        <span class="label">登录账号</span>
+                        <span class="value" id="loginAccount">-</span>
+                    </li>
+                    <li>
+                        <span class="label">登录时间</span>
+                        <span class="value" id="loginTime">-</span>
+                    </li>
+                    <li>
+                        <span class="label">系统版本</span>
+                        <span class="value">v1.0.0</span>
+                    </li>
+                    <li>
+                        <span class="label">服务器环境</span>
+                        <span class="value">Linux / Java</span>
+                    </li>
                 </ul>
             </div>
         </div>
-        <div class="layui-col-md6">
+        <div class="col col-half">
             <div class="info-card">
-                <div class="card-title">操作日志</div>
-                <ul class="info-list" id="recentLogs">
-                    <li><span>暂无数据</span></li>
-                </ul>
+                <div class="card-title">
+                    <span>操作日志</span>
+                    <span class="more" onclick="parent.openTab('log/log_list.html', '操作日志', 'log_list');">查看更多 ></span>
+                </div>
+                <div id="recentLogs">
+                    <div class="empty-data">暂无数据</div>
+                </div>
             </div>
         </div>
     </div>
+
+
     <script src="../lib/jquery.min.js"></script>
     <script src="../lib/layui/layui.js"></script>
     <script src="../js/config.js"></script>
@@ -89,30 +211,121 @@
         layui.use(['layer'], function() {
             var layer = layui.layer;
             var $ = layui.jquery;
-            
+
+            // 更新时间显示
+            function updateTime() {
+                var now = new Date();
+                var year = now.getFullYear();
+                var month = String(now.getMonth() + 1).padStart(2, '0');
+                var day = String(now.getDate()).padStart(2, '0');
+                var hours = String(now.getHours()).padStart(2, '0');
+                var minutes = String(now.getMinutes()).padStart(2, '0');
+                var seconds = String(now.getSeconds()).padStart(2, '0');
+                $('#currentTime').text(year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds);
+            }
+            updateTime();
+            setInterval(updateTime, 1000);
+
             // 获取用户信息
             var userInfo = Common.getUserInfo();
             if (userInfo) {
                 $('#currentUser').text(userInfo.name || '-');
                 $('#loginAccount').text(userInfo.account || '-');
-                $('#loginTime').text(Common.formatDate(new Date(), 'yyyy-MM-dd HH:mm:ss'));
+                $('#welcomeMsg').text('您好,' + (userInfo.name || userInfo.account || '') + ',欢迎使用 EMA 管理系统');
             }
-            
+            $('#loginTime').text(Common.formatDate(new Date(), 'yyyy-MM-dd HH:mm:ss'));
+
+            // 加载资产统计
+            loadAssetsStatistics();
 
             // 加载最近日志
             loadRecentLogs();
 
+            function loadAssetsStatistics() {
+                Common.get(Config.api.assets.statistics, function(res) {
+                    if (res.code === 200 && res.data) {
+                        var data = res.data;
+                        // 资产总数
+                        $('#assetsTotalCount').text(data.totalCount || 0);
+                        // 资产总价值
+                        var totalValue = data.totalValue || 0;
+                        if (totalValue >= 10000) {
+                            $('#assetsTotalValue').text((totalValue / 10000).toFixed(2) + '万');
+                        } else {
+                            $('#assetsTotalValue').text(totalValue.toFixed(2));
+                        }
+                        // 盘点率
+                        $('#assetsInvstkRate').text(data.invstkRate ? data.invstkRate.toFixed(1) : '0');
+                        // 已盘点/未盘点
+                        $('#invstkYesCount').text(data.invstkYesCount || 0);
+                        $('#invstkNoCount').text(data.invstkNoCount || 0);
+                        // 更新圆形进度
+                        var rate = data.invstkRate || 0;
+                        var circumference = 314.16; // 2 * PI * 50
+                        var offset = circumference * (1 - rate / 100);
+                        $('#invstkProgress').attr('stroke-dashoffset', offset);
+                        $('#invstkPercent').text(rate.toFixed(1) + '%');
+                        
+                        // 资产类型分布
+                        var typeDist = data.typeDistribution || [];
+                        renderTypeDistribution(typeDist);
+                    }
+                });
+            }
+
+            function renderTypeDistribution(typeDist) {
+                if (!typeDist || typeDist.length === 0) {
+                    $('#typeDistribution').html('<div class="empty-data">暂无数据</div>');
+                    return;
+                }
+                // 计算总数用于百分比
+                var total = typeDist.reduce(function(sum, item) { return sum + (item.count || 0); }, 0);
+                var colors = ['blue', 'green', 'orange', 'cyan'];
+                var html = '';
+                typeDist.forEach(function(item, index) {
+                    var percent = total > 0 ? (item.count / total * 100).toFixed(1) : 0;
+                    var color = colors[index % colors.length];
+                    var value = item.value || 0;
+                    var valueStr = value >= 10000 ? (value / 10000).toFixed(2) + '万' : value.toFixed(2);
+                    html += '<div class="distribution-item">';
+                    html += '<span class="dist-label">' + (item.name || '-') + '</span>';
+                    html += '<div class="dist-bar-wrap">';
+                    html += '<div class="dist-bar ' + color + '" style="width: ' + percent + '%;"></div>';
+                    html += '</div>';
+                    html += '<span class="dist-count">' + item.count + ' (' + percent + '%)</span>';
+                    html += '<span class="dist-value">¥' + valueStr + '</span>';
+                    html += '</div>';
+                });
+                $('#typeDistribution').html(html);
+            }
+
             function loadRecentLogs() {
                 Common.post(Config.api.operLog.page, { pageNumber: 1, pageSize: 5, type: 0 }, function(res) {
                     if (res.code === 200 && res.data) {
                         var logs = res.data.records || [];
                         var html = '';
                         if (logs.length > 0) {
-                            logs.forEach(function(log) {
-                                html += '<li><span>' + log.userId + '</span><span>' + (log.operationName || log.title || '-') + '</span><span>' + log.operTime + '</span></li>';
+                            var iconColors = ['#1890ff', '#52c41a', '#fa8c16', '#f5222d', '#722ed1'];
+                            logs.forEach(function(log, index) {
+                                var color = iconColors[index % iconColors.length];
+                                var operationName = log.operationName || log.title || '系统操作';
+                                var userName = log.userId || '未知用户';
+                                var operTime = log.operTime || '';
+                                html += '<div class="log-item">';
+                                html += '<div class="log-icon" style="background:' + color + ';">';
+                                html += '<i class="layui-icon layui-icon-util"></i>';
+                                html += '</div>';
+                                html += '<div class="log-content">';
+                                html += '<div class="log-title">' + operationName + '</div>';
+                                html += '<div class="log-meta">';
+                                html += '<span><i class="layui-icon layui-icon-username"></i>' + userName + '</span>';
+                                html += '<span><i class="layui-icon layui-icon-time"></i>' + operTime + '</span>';
+                                html += '</div>';
+                                html += '</div>';
+                                html += '</div>';
                             });
                         } else {
-                            html = '<li><span>暂无数据</span></li>';
+                            html = '<div class="empty-data">暂无数据</div>';
                         }
                         $('#recentLogs').html(html);
                     }