Browse Source

提交页面

master
主管理员 1 month ago
parent
commit
c7331c72bb
3 changed files with 245 additions and 168 deletions
  1. +24
    -0
      admin-hanhai-vue/src/api/exhibit.js
  2. +110
    -148
      admin-hanhai-vue/src/components/ExhibitDataBoard.vue
  3. +111
    -20
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/service/impl/ConfigServiceImpl.java

+ 24
- 0
admin-hanhai-vue/src/api/exhibit.js View File

@ -0,0 +1,24 @@
import { getAction } from '@/api/manage'
// 展品相关API接口
// 配置-数量统计
export const queryCount = (params) => getAction("/exhibit/config/queryCount", params);
// 配置-查看轮播图列表
export const queryBannerList = (params) => getAction("/exhibit/config/queryBannerList", params);
// 配置-查看部门列表
export const queryDepartmentList = (params) => getAction("/exhibit/config/queryDepartmentList", params);
// 配置-查询系统配置列表
export const queryConfigList = (params) => getAction("/exhibit/config/queryConfigList", params);
// 配置-查询系统配置详情
export const queryConfigByParamCode = (params) => getAction("/exhibit/config/queryConfigByParamCode", params);
// 配置-查询展品分类列表
export const queryCategoryList = (params) => getAction("/exhibit/config/queryCategoryList", params);
// 配置-查询常见故障情况
export const queryMalfunctionDescList = (params) => getAction("/exhibit/config/queryMalfunctionDescList", params);

+ 110
- 148
admin-hanhai-vue/src/components/ExhibitDataBoard.vue View File

@ -1,87 +1,82 @@
<template>
<div class="exhibit-data-board">
<a-row :gutter="24" class="data-cards">
<a-col :xs="24" :sm="12" :md="6" v-for="(item, index) in dataItems" :key="index">
<a-card class="data-card" :class="item.cardClass">
<div class="card-content">
<div class="icon-wrapper">
<a-icon :type="item.icon" class="data-icon" />
</div>
<div class="data-info">
<div class="data-title">{{ item.title }}</div>
<div class="data-value">
<ICountUp
:endVal="item.value"
:options="countUpOptions"
@ready="onReady"
/>
</div>
<div class="data-unit" v-if="item.unit">{{ item.unit }}</div>
</div>
<div class="data-cards">
<a-card class="data-card" :class="item.cardClass" v-for="(item, index) in dataItems" :key="index">
<div class="card-content">
<div class="icon-wrapper">
<a-icon :type="item.icon" class="data-icon" />
</div>
<div class="card-footer" v-if="item.description">
<span class="description">{{ item.description }}</span>
<div class="data-info">
<div class="data-title">{{ item.title }}</div>
<div class="data-value">
<ICountUp
:endVal="item.value"
:options="countUpOptions"
@ready="onReady"
/>
</div>
<div class="data-unit" v-if="item.unit">{{ item.unit }}</div>
</div>
</a-card>
</a-col>
</a-row>
</div>
<div class="card-footer" v-if="item.description">
<span class="description">{{ item.description }}</span>
</div>
</a-card>
</div>
<!-- 统计率数据行 -->
<a-row :gutter="24" class="rate-cards" style="margin-top: 24px;">
<a-col :xs="24" :sm="12" :md="8" v-for="(item, index) in rateItems" :key="index">
<a-card class="rate-card" :class="item.cardClass">
<div class="rate-content">
<div class="rate-icon">
<a-icon :type="item.icon" />
</div>
<div class="rate-info">
<div class="rate-title">{{ item.title }}</div>
<div class="rate-value">
<ICountUp
:endVal="item.value"
:options="rateCountUpOptions"
@ready="onReady"
/>
<span class="rate-symbol">%</span>
</div>
</div>
<div class="rate-trend" :class="item.trend">
<a-icon :type="item.trend === 'up' ? 'arrow-up' : 'arrow-down'" />
<span>{{ item.trendValue }}%</span>
</div>
<div class="rate-cards" style="margin-top: 24px;">
<a-card class="rate-card" :class="item.cardClass" v-for="(item, index) in rateItems" :key="index">
<div class="rate-content">
<div class="rate-icon">
<a-icon :type="item.icon" />
</div>
</a-card>
</a-col>
</a-row>
<!-- 维修保养统计 -->
<a-row :gutter="24" class="maintenance-cards" style="margin-top: 24px;">
<a-col :xs="24" :sm="12" :md="6" v-for="(item, index) in maintenanceItems" :key="index">
<a-card class="maintenance-card">
<div class="maintenance-content">
<div class="maintenance-header">
<a-icon :type="item.icon" class="maintenance-icon" />
<span class="maintenance-title">{{ item.title }}</span>
</div>
<div class="maintenance-value">
<div class="rate-info">
<div class="rate-title">{{ item.title }}</div>
<div class="rate-value">
<ICountUp
:endVal="item.value"
:options="countUpOptions"
:options="rateCountUpOptions"
@ready="onReady"
/>
<span class="rate-symbol">%</span>
</div>
<div class="maintenance-footer">
<span class="maintenance-desc">{{ item.description }}</span>
</div>
</div>
</a-card>
</a-col>
</a-row>
<div class="rate-trend" :class="item.trend">
<a-icon :type="item.trend === 'up' ? 'arrow-up' : 'arrow-down'" />
<span>{{ item.trendValue }}%</span>
</div>
</div>
</a-card>
</div>
<!-- 维修保养统计 -->
<div class="maintenance-cards" style="margin-top: 24px;">
<a-card class="maintenance-card" v-for="(item, index) in maintenanceItems" :key="index">
<div class="maintenance-content">
<div class="maintenance-header">
<a-icon :type="item.icon" class="maintenance-icon" />
<span class="maintenance-title">{{ item.title }}</span>
</div>
<div class="maintenance-value">
<ICountUp
:endVal="item.value"
:options="countUpOptions"
@ready="onReady"
/>
</div>
<div class="maintenance-footer">
<span class="maintenance-desc">{{ item.description }}</span>
</div>
</div>
</a-card>
</div>
</div>
</template>
<script>
import ICountUp from 'vue-countup-v2'
import { queryCount } from '@/api/exhibit'
export default {
name: 'ExhibitDataBoard',
@ -104,93 +99,33 @@ export default {
decimalPlaces: 1,
duration: 2.5
},
dataItems: [
{
title: '展品数量',
value: 1256,
icon: 'database',
cardClass: 'primary-card',
description: '总展品数量'
},
{
title: '维护中数量',
value: 89,
icon: 'tool',
cardClass: 'warning-card',
description: '正在维护的展品'
},
{
title: '无法使用数量',
value: 23,
icon: 'exclamation-circle',
cardClass: 'danger-card',
description: '故障无法使用'
},
{
title: '其它',
value: 45,
icon: 'question-circle',
cardClass: 'info-card',
description: '其他状态展品'
}
],
rateItems: [
{
title: '完好率',
value: 92.5,
icon: 'check-circle',
cardClass: 'success-rate',
trend: 'up',
trendValue: 2.3
},
{
title: '维修率',
value: 7.1,
icon: 'setting',
cardClass: 'warning-rate',
trend: 'down',
trendValue: 1.2
},
{
title: '故障率',
value: 1.8,
icon: 'warning',
cardClass: 'danger-rate',
trend: 'down',
trendValue: 0.5
}
],
maintenanceItems: [
{
title: '维修次数',
value: 156,
icon: 'wrench',
description: '本月维修总次数'
},
{
title: '保养次数',
value: 89,
icon: 'safety-certificate',
description: '本月保养总次数'
},
{
title: '维修次数/最多展品',
value: 12,
icon: 'bar-chart',
description: '单个展品最多维修次数'
},
{
title: '平均维修时长',
value: 4.5,
icon: 'clock-circle',
description: '小时'
}
]
dataItems: [],
rateItems: [],
maintenanceItems: []
}
},
mounted() {
this.loadStatisticsData()
},
methods: {
onReady(instance, CountUp) {
// CountUp
},
async loadStatisticsData() {
try {
const response = await queryCount()
if (response.success) {
const data = response.result
this.dataItems = data.dataItems || []
this.rateItems = data.rateItems || []
this.maintenanceItems = data.maintenanceItems || []
} else {
this.$message.error('获取统计数据失败:' + response.message)
}
} catch (error) {
console.error('获取统计数据失败:', error)
this.$message.error('获取统计数据失败')
}
}
}
}
@ -203,7 +138,16 @@ export default {
min-height: 100vh;
}
.data-cards {
display: flex;
flex-wrap: wrap;
gap: 24px;
margin-bottom: 16px;
}
.data-cards .data-card {
flex: 1;
min-width: 250px;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
@ -281,7 +225,16 @@ export default {
}
/* 统计率卡片样式 */
.rate-cards {
display: flex;
flex-wrap: wrap;
gap: 24px;
margin-bottom: 16px;
}
.rate-cards .rate-card {
flex: 1;
min-width: 280px;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
@ -353,7 +306,16 @@ export default {
}
/* 维修保养卡片样式 */
.maintenance-cards {
display: flex;
flex-wrap: wrap;
gap: 24px;
margin-bottom: 16px;
}
.maintenance-cards .maintenance-card {
flex: 1;
min-width: 200px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;


+ 111
- 20
jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/service/impl/ConfigServiceImpl.java View File

@ -27,6 +27,7 @@ import org.jeecg.modules.exhibitShowpiece.service.IExhibitShowpieceService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -278,41 +279,131 @@ public class ConfigServiceImpl implements ConfigService {
log.info("开始查询统计信息");
//返回信息
String massege = "";
Map<String, Object> map = new HashMap<>();
Map<String, Object> result = new HashMap<>();
try{
//展品数量
long showpieceNum = exhibitShowpieceService.count();
map.put("showpieceNum", showpieceNum);
//维护中的数量
long repairingNum = exhibitMalfunctionService.lambdaQuery().notIn(ExhibitMalfunction::getStatus, "2").count();
map.put("repairingNum", repairingNum);
//无法使用数量
long cannotUseNum = exhibitMalfunctionService.lambdaQuery().notIn(ExhibitMalfunction::getStatus, "2").eq(ExhibitMalfunction::getIsAffectUse, "1").count();
map.put("cannotUseNum", cannotUseNum);
//完好率
double undamaged = (showpieceNum - repairingNum) * 1.0 / showpieceNum;
String undamagedRate = String.format("%.2f", undamaged * 100) + "%";
map.put("undamagedRate", undamagedRate);
//维修率(暂不处理)
//维修次数
long repairedNum = exhibitMalfunctionService.count();
map.put("repairedNum", repairedNum);
//保养次数
long maintenancedNum = exhibitMaintenanceService.count();
map.put("maintenancedNum", maintenancedNum);
//维修次数最多的展品
// 第一行基础数据统计
List<Map<String, Object>> dataItems = new ArrayList<>();
Map<String, Object> item1 = new HashMap<>();
item1.put("title", "展品数量");
item1.put("value", showpieceNum);
item1.put("icon", "database");
item1.put("cardClass", "primary-card");
item1.put("description", "总展品数量");
dataItems.add(item1);
Map<String, Object> item2 = new HashMap<>();
item2.put("title", "维护中数量");
item2.put("value", repairingNum);
item2.put("icon", "tool");
item2.put("cardClass", "warning-card");
item2.put("description", "正在维护的展品");
dataItems.add(item2);
Map<String, Object> item3 = new HashMap<>();
item3.put("title", "无法使用数量");
item3.put("value", cannotUseNum);
item3.put("icon", "exclamation-circle");
item3.put("cardClass", "danger-card");
item3.put("description", "故障无法使用");
dataItems.add(item3);
// Map<String, Object> item4 = new HashMap<>();
// item4.put("title", "其它");
// item4.put("value", showpieceNum - repairingNum - cannotUseNum);
// item4.put("icon", "question-circle");
// item4.put("cardClass", "info-card");
// item4.put("description", "其他状态展品");
// dataItems.add(item4);
// 第二行统计率数据
List<Map<String, Object>> rateItems = new ArrayList<>();
//完好率
double undamaged = showpieceNum > 0 ? (showpieceNum - repairingNum) * 1.0 / showpieceNum : 0;
double undamagedRate = undamaged * 100;
Map<String, Object> rate1 = new HashMap<>();
rate1.put("title", "完好率");
rate1.put("value", Double.parseDouble(String.format("%.1f", undamagedRate)));
rate1.put("icon", "check-circle");
rate1.put("cardClass", "success-rate");
// rate1.put("trend", "up");
// rate1.put("trendValue", 2.3);
rateItems.add(rate1);
//维修率
double repairRate = showpieceNum > 0 ? repairingNum * 100.0 / showpieceNum : 0;
Map<String, Object> rate2 = new HashMap<>();
rate2.put("title", "维修率");
rate2.put("value", Double.parseDouble(String.format("%.1f", repairRate)));
rate2.put("icon", "setting");
rate2.put("cardClass", "warning-rate");
// rate2.put("trend", "down");
// rate2.put("trendValue", 1.2);
rateItems.add(rate2);
//故障率
// double faultRate = showpieceNum > 0 ? cannotUseNum * 100.0 / showpieceNum : 0;
// Map<String, Object> rate3 = new HashMap<>();
// rate3.put("title", "故障率");
// rate3.put("value", Double.parseDouble(String.format("%.1f", faultRate)));
// rate3.put("icon", "warning");
// rate3.put("cardClass", "danger-rate");
// // rate3.put("trend", "down");
// // rate3.put("trendValue", 0.5);
// rateItems.add(rate3);
// 第三行维修保养统计
List<Map<String, Object>> maintenanceItems = new ArrayList<>();
Map<String, Object> maintenance1 = new HashMap<>();
maintenance1.put("title", "维修次数");
maintenance1.put("value", repairedNum);
maintenance1.put("icon", "wrench");
maintenance1.put("description", "维修总次数");
maintenanceItems.add(maintenance1);
Map<String, Object> maintenance2 = new HashMap<>();
maintenance2.put("title", "保养次数");
maintenance2.put("value", maintenancedNum);
maintenance2.put("icon", "safety-certificate");
maintenance2.put("description", "保养总次数");
maintenanceItems.add(maintenance2);
// TODO: 需要实现查询数据库的逻辑
/*
Map<String, Object> maintenance3 = new HashMap<>();
maintenance3.put("title", "维修次数/最多展品");
maintenance3.put("value", 12); // 这里可以根据实际需求查询最多维修次数的展品
maintenance3.put("icon", "bar-chart");
maintenance3.put("description", "单个展品最多维修次数");
maintenanceItems.add(maintenance3);
Map<String, Object> maintenance4 = new HashMap<>();
maintenance4.put("title", "平均维修时长");
maintenance4.put("value", 4.5); // 这里可以根据实际需求计算平均维修时长
maintenance4.put("icon", "clock-circle");
maintenance4.put("description", "小时");
maintenance4.put("unit", "小时");
maintenanceItems.add(maintenance4);
*/
result.put("dataItems", dataItems);
result.put("rateItems", rateItems);
result.put("maintenanceItems", maintenanceItems);
log.info("统计信息查询结束");
return Result.OK("统计信息", map);
return Result.OK("统计信息", result);
}catch (Exception e){
log.error("统计信息查询失败");
e.printStackTrace();


Loading…
Cancel
Save