review:【antd】【iot】首页统计

This commit is contained in:
YunaiV
2025-11-21 09:17:19 +08:00
parent 23b87b13c4
commit c38d746c25
8 changed files with 29 additions and 10 deletions

View File

@@ -1,7 +1,8 @@
import { requestClient } from '#/api/request'; import { requestClient } from '#/api/request';
export namespace IotStatisticsApi { export namespace IotStatisticsApi {
/** IoT 统计摘要数据 */ // TODO @haohao需要跟后端对齐必要的 ReqVO、RespVO
/** 统计摘要数据 */
export interface StatisticsSummary { export interface StatisticsSummary {
productCategoryCount: number; productCategoryCount: number;
productCount: number; productCount: number;
@@ -22,7 +23,7 @@ export namespace IotStatisticsApi {
[key: string]: number; [key: string]: number;
} }
/** IoT 消息统计数据类型 */ /** 消息统计数据类型 */
export interface DeviceMessageSummary { export interface DeviceMessageSummary {
statType: number; statType: number;
upstreamCounts: TimeValueItem[]; upstreamCounts: TimeValueItem[];
@@ -60,6 +61,7 @@ export function getDeviceMessageSummaryByDate(
); );
} }
// TODO @haohao貌似这里没用到是不是后面哪里用或者可以删除哈
/** 获取设备消息统计摘要 */ /** 获取设备消息统计摘要 */
export function getDeviceMessageSummary(statType: number) { export function getDeviceMessageSummary(statType: number) {
return requestClient.get<IotStatisticsApi.DeviceMessageSummary>( return requestClient.get<IotStatisticsApi.DeviceMessageSummary>(

View File

@@ -1,6 +1,5 @@
/** /** 设备数量饼图配置 */
* 设备数量饼图配置 // TODO @haohao貌似没用到
*/
export function getDeviceCountChartOptions( export function getDeviceCountChartOptions(
productCategoryDeviceCounts: Record<string, number>, productCategoryDeviceCounts: Record<string, number>,
): any { ): any {

View File

@@ -101,6 +101,7 @@ export function useIotHome() {
}; };
} }
// TODO @haohao是不是删除下哈
/** 格式化数字 - 大数字显示为 K/M */ /** 格式化数字 - 大数字显示为 K/M */
export function formatNumber(num: number): string { export function formatNumber(num: number): string {
if (num >= 1_000_000) { if (num >= 1_000_000) {

View File

@@ -3,9 +3,7 @@ import { Page } from '@vben/common-ui';
import { Col, Row } from 'ant-design-vue'; import { Col, Row } from 'ant-design-vue';
// 导入业务逻辑
import { useIotHome } from './data'; import { useIotHome } from './data';
// 导入组件
import ComparisonCard from './modules/comparison-card.vue'; import ComparisonCard from './modules/comparison-card.vue';
import DeviceCountCard from './modules/device-count-card.vue'; import DeviceCountCard from './modules/device-count-card.vue';
import DeviceStateCountCard from './modules/device-state-count-card.vue'; import DeviceStateCountCard from './modules/device-state-count-card.vue';
@@ -13,7 +11,7 @@ import MessageTrendCard from './modules/message-trend-card.vue';
defineOptions({ name: 'IoTHome' }); defineOptions({ name: 'IoTHome' });
// 使用业务逻辑 Hook // TODO @haohao相关的方法拿到 index.vue 里data.ts 只放 schema
const { loading, statsData } = useIotHome(); const { loading, statsData } = useIotHome();
</script> </script>

View File

@@ -6,6 +6,8 @@ import { createIconifyIcon } from '@vben/icons';
import { Card } from 'ant-design-vue'; import { Card } from 'ant-design-vue';
// TODO @haohao这个可以迁移到 packages/effects/common-ui/src/components/card/comparison-card
defineOptions({ name: 'ComparisonCard' }); defineOptions({ name: 'ComparisonCard' });
const props = defineProps<{ const props = defineProps<{
@@ -59,6 +61,7 @@ const IconComponent = computed(() => iconMap[props.icon] || iconMap.menu);
</template> </template>
<style scoped> <style scoped>
/** TODO tindwind */
.stat-card { .stat-card {
height: 160px; height: 160px;
cursor: pointer; cursor: pointer;

View File

@@ -28,13 +28,17 @@ const hasData = computed(() => {
/** 初始化图表 */ /** 初始化图表 */
function initChart() { function initChart() {
if (!hasData.value) return; if (!hasData.value) {
return;
}
// TODO @haohaoawait nextTick();
nextTick(() => { nextTick(() => {
const data = Object.entries( const data = Object.entries(
props.statsData.productCategoryDeviceCounts, props.statsData.productCategoryDeviceCounts,
).map(([name, value]) => ({ name, value })); ).map(([name, value]) => ({ name, value }));
// TODO @haohao看看 chart-options 怎么提取出去,类似 apps/web-antd/src/views/mall/statistics/member/modules/area-chart-options.ts 写法
renderEcharts({ renderEcharts({
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
@@ -132,6 +136,7 @@ onMounted(() => {
</template> </template>
<style scoped> <style scoped>
/** TODO tindwind */
.chart-card { .chart-card {
height: 100%; height: 100%;
} }

View File

@@ -31,6 +31,7 @@ const hasData = computed(() => {
}); });
/** 获取仪表盘配置 */ /** 获取仪表盘配置 */
// TODO @haohao看看 chart-options 怎么提取出去,类似 apps/web-antd/src/views/mall/statistics/member/modules/area-chart-options.ts 写法
const getGaugeOption = (value: number, color: string, title: string): any => { const getGaugeOption = (value: number, color: string, title: string): any => {
return { return {
series: [ series: [
@@ -81,8 +82,11 @@ const getGaugeOption = (value: number, color: string, title: string): any => {
/** 初始化图表 */ /** 初始化图表 */
function initCharts() { function initCharts() {
if (!hasData.value) return; if (!hasData.value) {
return;
}
// TODO @haohaoawait nextTick();
nextTick(() => { nextTick(() => {
// 在线设备 // 在线设备
renderOnlineChart( renderOnlineChart(
@@ -147,6 +151,7 @@ onMounted(() => {
</template> </template>
<style scoped> <style scoped>
/** TODO tindwind */
.chart-card { .chart-card {
height: 100%; height: 100%;
} }

View File

@@ -24,6 +24,8 @@ const messageData = ref<IotStatisticsApi.DeviceMessageSummaryByDate[]>([]);
const activeTimeRange = ref('7d'); // 当前选中的时间范围 const activeTimeRange = ref('7d'); // 当前选中的时间范围
const dateRange = ref<[Dayjs, Dayjs] | undefined>(undefined); const dateRange = ref<[Dayjs, Dayjs] | undefined>(undefined);
// TODO @haohao这个貌似没迁移对。它是时间范围、事件间隔
const queryParams = reactive<IotStatisticsApi.DeviceMessageReq>({ const queryParams = reactive<IotStatisticsApi.DeviceMessageReq>({
interval: 1, // 按天 interval: 1, // 按天
times: [], times: [],
@@ -34,6 +36,7 @@ const hasData = computed(() => {
return messageData.value && messageData.value.length > 0; return messageData.value && messageData.value.length > 0;
}); });
// TODO @haohao注释风格应该是 /** */ 在方法上;然后变量在字段后面 // 。。。
// 设置时间范围 // 设置时间范围
function setTimeRange(range: string) { function setTimeRange(range: string) {
activeTimeRange.value = range; activeTimeRange.value = range;
@@ -64,6 +67,7 @@ function setTimeRange(range: string) {
} }
} }
// TODO @haohao可以使用 formatDateTime
queryParams.times = [ queryParams.times = [
start.format('YYYY-MM-DD HH:mm:ss'), start.format('YYYY-MM-DD HH:mm:ss'),
end.format('YYYY-MM-DD HH:mm:ss'), end.format('YYYY-MM-DD HH:mm:ss'),
@@ -78,6 +82,7 @@ function handleDateChange() {
activeTimeRange.value = ''; // 清空快捷选择 activeTimeRange.value = ''; // 清空快捷选择
queryParams.interval = 1; // 按天 queryParams.interval = 1; // 按天
queryParams.times = [ queryParams.times = [
// TODO @haohao可以使用 formatDateTime
dateRange.value[0].startOf('day').format('YYYY-MM-DD HH:mm:ss'), dateRange.value[0].startOf('day').format('YYYY-MM-DD HH:mm:ss'),
dateRange.value[1].endOf('day').format('YYYY-MM-DD HH:mm:ss'), dateRange.value[1].endOf('day').format('YYYY-MM-DD HH:mm:ss'),
]; ];
@@ -110,6 +115,7 @@ function initChart() {
const upstreamData = messageData.value.map((item) => item.upstreamCount); const upstreamData = messageData.value.map((item) => item.upstreamCount);
const downstreamData = messageData.value.map((item) => item.downstreamCount); const downstreamData = messageData.value.map((item) => item.downstreamCount);
// TODO @haohao看看 chart-options 怎么提取出去,类似 apps/web-antd/src/views/mall/statistics/member/modules/area-chart-options.ts 写法
renderEcharts({ renderEcharts({
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',