持续优化
This commit is contained in:
@@ -64,34 +64,6 @@ const Ota = sequelize.define('Ota', {
|
||||
defaultValue: 0,
|
||||
comment: '是否灰度,1-是,0-否',
|
||||
},
|
||||
pawVerCode: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 0,
|
||||
field: 'pawVerCode',
|
||||
comment: '配对版本号',
|
||||
},
|
||||
pawVerName: {
|
||||
type: DataTypes.STRING(20),
|
||||
allowNull: false,
|
||||
defaultValue: '',
|
||||
field: 'pawVerName',
|
||||
comment: '配对版本名称',
|
||||
},
|
||||
pawUrl: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: false,
|
||||
defaultValue: '',
|
||||
field: 'pawUrl',
|
||||
comment: '配对版本 URL',
|
||||
},
|
||||
pawMd5: {
|
||||
type: DataTypes.STRING(32),
|
||||
allowNull: false,
|
||||
defaultValue: '',
|
||||
field: 'pawMd5',
|
||||
comment: '配对版本 MD5',
|
||||
},
|
||||
startTime: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
@@ -110,6 +82,12 @@ const Ota = sequelize.define('Ota', {
|
||||
defaultValue: 1,
|
||||
comment: '是否可用',
|
||||
},
|
||||
create_at: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false,
|
||||
defaultValue: DataTypes.NOW,
|
||||
comment: '创建时间',
|
||||
},
|
||||
}, {
|
||||
tableName: 'ota',
|
||||
comment: 'OTA 升级版本',
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Dashboard 路由 — 首页统计数据
|
||||
*/
|
||||
const router = require('express').Router();
|
||||
const { Op } = require('sequelize');
|
||||
const Model = require('../models/Model');
|
||||
const Ota = require('../models/Ota');
|
||||
const logger = require('../config/logger');
|
||||
const { ApiResponse } = require('../utils/response');
|
||||
const { authMiddleware } = require('../middleware/auth');
|
||||
|
||||
// 所有 dashboard 接口需登录
|
||||
router.use(authMiddleware);
|
||||
|
||||
/**
|
||||
* GET /api/dashboard/today
|
||||
* 返回今日新增的耳机型号和 OTA 数据
|
||||
*/
|
||||
router.get('/api/dashboard/today', async (req, res) => {
|
||||
try {
|
||||
// 今日 00:00:00 (UTC+8)
|
||||
const now = new Date();
|
||||
const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
||||
|
||||
// 今日新增型号
|
||||
const newModels = await Model.findAll({
|
||||
where: {
|
||||
create_at: { [Op.gte]: todayStart },
|
||||
},
|
||||
order: [['id', 'DESC']],
|
||||
attributes: ['id', 'brand_name', 'name', 'create_at'],
|
||||
});
|
||||
|
||||
// 今日新增 OTA
|
||||
const newOtas = await Ota.findAll({
|
||||
where: {
|
||||
create_at: { [Op.gte]: todayStart },
|
||||
},
|
||||
order: [['id', 'DESC']],
|
||||
attributes: ['id', 'verName', 'model', 'create_at'],
|
||||
});
|
||||
|
||||
return res.json(
|
||||
ApiResponse.success({
|
||||
models: newModels.map((m) => ({
|
||||
id: m.id,
|
||||
brand_name: m.brand_name,
|
||||
name: m.name,
|
||||
create_at: m.create_at ? m.create_at.toISOString() : null,
|
||||
})),
|
||||
otas: newOtas.map((o) => ({
|
||||
id: o.id,
|
||||
verName: o.verName,
|
||||
model: o.model,
|
||||
create_at: o.create_at ? o.create_at.toISOString() : null,
|
||||
})),
|
||||
})
|
||||
);
|
||||
} catch (e) {
|
||||
logger.error(`Error getting dashboard today stats: ${e.message}`);
|
||||
return res.json(ApiResponse.error(`获取统计数据失败:${e.message}`));
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -7,5 +7,6 @@ const modelsRouter = require('./models');
|
||||
const otaRouter = require('./ota');
|
||||
const shareCodeLogsRouter = require('./shareCodeLogs');
|
||||
const usersRouter = require('./users');
|
||||
const dashboardRouter = require('./dashboard');
|
||||
|
||||
module.exports = [authRouter, brandsRouter, modelsRouter, otaRouter, shareCodeLogsRouter, usersRouter];
|
||||
module.exports = [authRouter, brandsRouter, modelsRouter, otaRouter, shareCodeLogsRouter, usersRouter, dashboardRouter];
|
||||
|
||||
@@ -281,13 +281,10 @@ function otaToDict(ota) {
|
||||
hw: ota.hw,
|
||||
target: ota.target,
|
||||
beta: ota.beta,
|
||||
pawVerCode: ota.pawVerCode,
|
||||
pawVerName: ota.pawVerName,
|
||||
pawUrl: ota.pawUrl,
|
||||
pawMd5: ota.pawMd5,
|
||||
startTime: ota.startTime ? ota.startTime.toISOString() : null,
|
||||
endTime: ota.endTime ? ota.endTime.toISOString() : null,
|
||||
status: ota.status,
|
||||
create_at: ota.create_at ? ota.create_at.toISOString() : null,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,6 @@ const OtaCreateSchema = z.object({
|
||||
hw: z.number().int().optional().default(0),
|
||||
target: z.number().int().min(0).max(1).optional().default(0),
|
||||
beta: z.number().int().min(0).max(1).optional().default(0),
|
||||
pawVerCode: z.number().int().optional().default(0),
|
||||
pawVerName: z.string().max(20).optional().default(''),
|
||||
pawUrl: z.string().max(255).optional().default(''),
|
||||
pawMd5: z.string().length(32).optional().default(''),
|
||||
startTime: z.string().optional().nullable(),
|
||||
endTime: z.string().optional().nullable(),
|
||||
status: z.number().int().min(0).max(1).optional().default(1),
|
||||
@@ -31,10 +27,6 @@ const OtaUpdateSchema = z.object({
|
||||
hw: z.number().int().optional().nullable(),
|
||||
target: z.number().int().min(0).max(1).optional().nullable(),
|
||||
beta: z.number().int().min(0).max(1).optional().nullable(),
|
||||
pawVerCode: z.number().int().optional().nullable(),
|
||||
pawVerName: z.string().max(20).optional().nullable(),
|
||||
pawUrl: z.string().max(255).optional().nullable(),
|
||||
pawMd5: z.string().length(32).optional().nullable(),
|
||||
startTime: z.string().optional().nullable(),
|
||||
endTime: z.string().optional().nullable(),
|
||||
status: z.number().int().min(0).max(1).optional().nullable(),
|
||||
|
||||
Reference in New Issue
Block a user