新增分享码日志管理,美化界面,优化代码上传脚本
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
const { DataTypes } = require('sequelize');
|
||||
const sequelize = require('../config/database');
|
||||
|
||||
const ShareCodeLog = sequelize.define('ShareCodeLog', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true,
|
||||
autoIncrement: true,
|
||||
comment: '主键',
|
||||
},
|
||||
mac_addr: {
|
||||
type: DataTypes.STRING(17),
|
||||
allowNull: false,
|
||||
comment: '设备 MAC 地址,如 AA:BB:CC:DD:EE:FF',
|
||||
},
|
||||
share_code: {
|
||||
type: DataTypes.CHAR(5),
|
||||
allowNull: false,
|
||||
comment: '分享码(5位字符)',
|
||||
},
|
||||
action: {
|
||||
type: DataTypes.ENUM('export', 'import'),
|
||||
allowNull: false,
|
||||
comment: '操作类型:export=导出分享码,import=导入分享码',
|
||||
},
|
||||
ip_addr: {
|
||||
type: DataTypes.STRING(45),
|
||||
allowNull: false,
|
||||
defaultValue: '',
|
||||
comment: '用户 IP 地址(支持 IPv4/IPv6)',
|
||||
},
|
||||
eq_data: {
|
||||
type: DataTypes.JSON,
|
||||
allowNull: false,
|
||||
comment: 'EQ 数据快照(JSON)',
|
||||
},
|
||||
expire_at: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
comment: '分享码到期时间(导出时快照,导入可为空)',
|
||||
},
|
||||
create_at: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false,
|
||||
defaultValue: DataTypes.NOW,
|
||||
comment: '操作时间',
|
||||
},
|
||||
}, {
|
||||
tableName: 'share_code_log',
|
||||
comment: '分享码流水表',
|
||||
indexes: [
|
||||
{ name: 'idx_mac_addr', fields: ['mac_addr'] },
|
||||
{ name: 'idx_share_code', fields: ['share_code'] },
|
||||
{ name: 'idx_create_at', fields: ['create_at'] },
|
||||
],
|
||||
});
|
||||
|
||||
module.exports = ShareCodeLog;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const Brand = require('./Brand');
|
||||
const Model = require('./Model');
|
||||
const Ota = require('./Ota');
|
||||
const ShareCodeLog = require('./ShareCodeLog');
|
||||
|
||||
module.exports = { Brand, Model, Ota };
|
||||
module.exports = { Brand, Model, Ota, ShareCodeLog };
|
||||
|
||||
@@ -5,5 +5,6 @@ const authRouter = require('./auth');
|
||||
const brandsRouter = require('./brands');
|
||||
const modelsRouter = require('./models');
|
||||
const otaRouter = require('./ota');
|
||||
const shareCodeLogsRouter = require('./shareCodeLogs');
|
||||
|
||||
module.exports = [authRouter, brandsRouter, modelsRouter, otaRouter];
|
||||
module.exports = [authRouter, brandsRouter, modelsRouter, otaRouter, shareCodeLogsRouter];
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* 分享码日志路由
|
||||
*/
|
||||
const router = require('express').Router();
|
||||
const { Op } = require('sequelize');
|
||||
const ShareCodeLog = require('../models/ShareCodeLog');
|
||||
const logger = require('../config/logger');
|
||||
const { ApiResponse } = require('../utils/response');
|
||||
const { authMiddleware } = require('../middleware/auth');
|
||||
|
||||
// 全部接口需登录
|
||||
router.use(authMiddleware);
|
||||
|
||||
// GET /api/share-code/logs
|
||||
router.get('/api/share-code/logs', async (req, res) => {
|
||||
try {
|
||||
const skip = parseInt(req.query.skip || '0', 10);
|
||||
const limit = Math.min(parseInt(req.query.limit || '100', 10), 1000);
|
||||
|
||||
const macAddr = (req.query.mac_addr || '').trim();
|
||||
const shareCode = (req.query.share_code || '').trim();
|
||||
const action = (req.query.action || '').trim();
|
||||
const ipAddr = (req.query.ip_addr || '').trim();
|
||||
|
||||
const startAt = (req.query.start_at || '').trim();
|
||||
const endAt = (req.query.end_at || '').trim();
|
||||
|
||||
const sortBy = (req.query.sort_by || 'id').trim();
|
||||
const sortOrder = (req.query.sort_order || 'desc').toLowerCase();
|
||||
|
||||
const where = {};
|
||||
if (macAddr) where.mac_addr = { [Op.like]: `%${macAddr}%` };
|
||||
if (shareCode) where.share_code = { [Op.like]: `%${shareCode}%` };
|
||||
if (ipAddr) where.ip_addr = { [Op.like]: `%${ipAddr}%` };
|
||||
if (action === 'export' || action === 'import') where.action = action;
|
||||
|
||||
if (startAt || endAt) {
|
||||
const range = {};
|
||||
if (startAt) {
|
||||
const d = new Date(startAt);
|
||||
if (!Number.isNaN(d.getTime())) range[Op.gte] = d;
|
||||
}
|
||||
if (endAt) {
|
||||
const d = new Date(endAt);
|
||||
if (!Number.isNaN(d.getTime())) range[Op.lte] = d;
|
||||
}
|
||||
if (Object.keys(range).length) where.create_at = range;
|
||||
}
|
||||
|
||||
const total = await ShareCodeLog.count({ where });
|
||||
|
||||
const orderDir = sortOrder === 'asc' ? 'ASC' : 'DESC';
|
||||
const orderCol = sortBy === 'create_at' ? 'create_at' : 'id';
|
||||
|
||||
const rows = await ShareCodeLog.findAll({
|
||||
where,
|
||||
offset: skip,
|
||||
limit,
|
||||
order: [[orderCol, orderDir]],
|
||||
});
|
||||
|
||||
logger.info(`Found ${rows.length} share_code_log rows, total=${total}`);
|
||||
|
||||
if (!rows.length) {
|
||||
return res.json(ApiResponse.noData('empty'));
|
||||
}
|
||||
|
||||
const items = rows.map((r) => ({
|
||||
id: r.id,
|
||||
mac_addr: r.mac_addr,
|
||||
share_code: r.share_code,
|
||||
action: r.action,
|
||||
ip_addr: r.ip_addr,
|
||||
eq_data: r.eq_data,
|
||||
expire_at: r.expire_at ? r.expire_at.toISOString() : null,
|
||||
create_at: r.create_at ? r.create_at.toISOString() : null,
|
||||
}));
|
||||
|
||||
return res.json(ApiResponse.success({ items, total, skip, limit }));
|
||||
} catch (e) {
|
||||
logger.error(`Error getting share code logs: ${e.message}`);
|
||||
return res.json(ApiResponse.error('error'));
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
Reference in New Issue
Block a user