1
This commit is contained in:
517
api/controller_admin/version.js
Normal file
517
api/controller_admin/version.js
Normal file
@@ -0,0 +1,517 @@
|
||||
/**
|
||||
* 版本管理API - 后台管理
|
||||
* 提供版本信息的CRUD操作和版本控制功能
|
||||
*/
|
||||
|
||||
const Framework = require("../../framework/node-core-framework.js");
|
||||
const version_service = require('../services/version_service.js');
|
||||
const config = require('../../config/config.js');
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* @swagger
|
||||
* /admin_api/version/list:
|
||||
* post:
|
||||
* summary: 获取版本列表
|
||||
* description: 分页获取所有版本信息
|
||||
* tags: [后台-版本管理]
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* seachOption:
|
||||
* type: object
|
||||
* description: 搜索条件
|
||||
* properties:
|
||||
* key:
|
||||
* type: string
|
||||
* description: 搜索字段(version/platform/arch)
|
||||
* value:
|
||||
* type: string
|
||||
* description: 搜索值
|
||||
* platform:
|
||||
* type: string
|
||||
* description: 平台筛选(win32/darwin/linux)
|
||||
* arch:
|
||||
* type: string
|
||||
* description: 架构筛选(x64/ia32/arm64)
|
||||
* status:
|
||||
* type: integer
|
||||
* description: 状态筛选(1:启用 0:禁用)
|
||||
* pageOption:
|
||||
* type: object
|
||||
* description: 分页选项
|
||||
* properties:
|
||||
* page:
|
||||
* type: integer
|
||||
* description: 页码
|
||||
* pageSize:
|
||||
* type: integer
|
||||
* description: 每页数量
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 获取成功
|
||||
*/
|
||||
'POST /version/list': async (ctx) => {
|
||||
const models = Framework.getModels();
|
||||
const { version_info } = models;
|
||||
const { op } = models;
|
||||
const body = ctx.getBody();
|
||||
|
||||
const seachOption = body.seachOption || {};
|
||||
const pageOption = body.pageOption || {};
|
||||
|
||||
// 获取分页参数
|
||||
const page = pageOption.page || 1;
|
||||
const pageSize = pageOption.pageSize || 20;
|
||||
const limit = pageSize;
|
||||
const offset = (page - 1) * pageSize;
|
||||
|
||||
const where = {};
|
||||
|
||||
// 平台筛选
|
||||
if (seachOption.platform) {
|
||||
where.platform = seachOption.platform;
|
||||
}
|
||||
|
||||
// 架构筛选
|
||||
if (seachOption.arch) {
|
||||
where.arch = seachOption.arch;
|
||||
}
|
||||
|
||||
// 状态筛选
|
||||
if (seachOption.status !== undefined && seachOption.status !== null) {
|
||||
where.status = seachOption.status;
|
||||
}
|
||||
|
||||
// 搜索:版本号、平台、架构
|
||||
if (seachOption.key && seachOption.value) {
|
||||
const key = seachOption.key;
|
||||
const value = seachOption.value;
|
||||
|
||||
if (key === 'version') {
|
||||
where.version = { [op.like]: `%${value}%` };
|
||||
} else if (key === 'platform') {
|
||||
where.platform = { [op.like]: `%${value}%` };
|
||||
} else if (key === 'arch') {
|
||||
where.arch = { [op.like]: `%${value}%` };
|
||||
}
|
||||
}
|
||||
|
||||
const result = await version_info.findAndCountAll({
|
||||
where,
|
||||
limit,
|
||||
offset,
|
||||
order: [['create_time', 'DESC']]
|
||||
});
|
||||
|
||||
return ctx.success({
|
||||
rows: result.rows,
|
||||
count: result.count
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /admin_api/version/detail:
|
||||
* post:
|
||||
* summary: 获取版本详情
|
||||
* description: 根据版本ID获取详细信息
|
||||
* tags: [后台-版本管理]
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - id
|
||||
* properties:
|
||||
* id:
|
||||
* type: integer
|
||||
* description: 版本ID
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 获取成功
|
||||
*/
|
||||
'POST /version/detail': async (ctx) => {
|
||||
const models = Framework.getModels();
|
||||
const { version_info } = models;
|
||||
const { id } = ctx.getBody();
|
||||
|
||||
if (!id) {
|
||||
return ctx.fail('版本ID不能为空');
|
||||
}
|
||||
|
||||
const version = await version_info.findByPk(id);
|
||||
|
||||
if (!version) {
|
||||
return ctx.fail('版本不存在');
|
||||
}
|
||||
|
||||
return ctx.success(version);
|
||||
},
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /admin_api/version/create:
|
||||
* post:
|
||||
* summary: 创建版本
|
||||
* description: 创建新版本信息
|
||||
* tags: [后台-版本管理]
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - version
|
||||
* - platform
|
||||
* - arch
|
||||
* - download_url
|
||||
* - file_path
|
||||
* properties:
|
||||
* version:
|
||||
* type: string
|
||||
* description: 版本号(x.y.z 格式)
|
||||
* platform:
|
||||
* type: string
|
||||
* description: 平台类型
|
||||
* arch:
|
||||
* type: string
|
||||
* description: 架构类型
|
||||
* download_url:
|
||||
* type: string
|
||||
* description: 下载地址
|
||||
* file_path:
|
||||
* type: string
|
||||
* description: 服务器文件路径
|
||||
* file_size:
|
||||
* type: integer
|
||||
* description: 文件大小(字节)
|
||||
* file_hash:
|
||||
* type: string
|
||||
* description: SHA256 哈希值
|
||||
* release_notes:
|
||||
* type: string
|
||||
* description: 更新日志
|
||||
* force_update:
|
||||
* type: integer
|
||||
* description: 是否强制更新(1:是 0:否)
|
||||
* status:
|
||||
* type: integer
|
||||
* description: 状态(1:启用 0:禁用)
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 创建成功
|
||||
*/
|
||||
'POST /version/create': async (ctx) => {
|
||||
const models = Framework.getModels();
|
||||
const { version_info } = models;
|
||||
const body = ctx.getBody();
|
||||
|
||||
// 参数验证
|
||||
if (!body.version) {
|
||||
return ctx.fail('版本号不能为空');
|
||||
}
|
||||
if (!body.platform) {
|
||||
return ctx.fail('平台类型不能为空');
|
||||
}
|
||||
if (!body.arch) {
|
||||
return ctx.fail('架构类型不能为空');
|
||||
}
|
||||
if (!body.download_url) {
|
||||
return ctx.fail('下载地址不能为空');
|
||||
}
|
||||
if (!body.file_path) {
|
||||
return ctx.fail('文件路径不能为空');
|
||||
}
|
||||
|
||||
// 验证版本号格式
|
||||
if (!version_service.is_valid_version(body.version)) {
|
||||
return ctx.fail('版本号格式错误,应为 x.y.z 格式');
|
||||
}
|
||||
|
||||
// 验证平台类型
|
||||
if (!version_service.is_valid_platform(body.platform)) {
|
||||
return ctx.fail('平台类型错误,应为 win32/darwin/linux');
|
||||
}
|
||||
|
||||
// 验证架构类型
|
||||
if (!version_service.is_valid_arch(body.arch)) {
|
||||
return ctx.fail('架构类型错误,应为 x64/ia32/arm64');
|
||||
}
|
||||
|
||||
// 检查版本是否已存在
|
||||
const existing = await version_info.findOne({
|
||||
where: {
|
||||
version: body.version,
|
||||
platform: body.platform,
|
||||
arch: body.arch
|
||||
}
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
return ctx.fail('该版本已存在');
|
||||
}
|
||||
|
||||
// 如果提供了文件路径,计算文件大小和哈希
|
||||
if (body.file_path) {
|
||||
try {
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const full_path = path.resolve(body.file_path);
|
||||
|
||||
if (fs.existsSync(full_path)) {
|
||||
// 计算文件大小
|
||||
if (!body.file_size) {
|
||||
const stats = fs.statSync(full_path);
|
||||
body.file_size = stats.size;
|
||||
}
|
||||
|
||||
// 计算文件哈希
|
||||
if (!body.file_hash) {
|
||||
body.file_hash = await version_service.calculate_file_hash(full_path);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('计算文件信息失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 创建版本
|
||||
const version = await version_info.create({
|
||||
version: body.version,
|
||||
platform: body.platform,
|
||||
arch: body.arch,
|
||||
download_url: body.download_url,
|
||||
file_path: body.file_path,
|
||||
file_size: body.file_size || 0,
|
||||
file_hash: body.file_hash || '',
|
||||
release_notes: body.release_notes || '',
|
||||
force_update: body.force_update || 0,
|
||||
status: body.status !== undefined ? body.status : 1
|
||||
});
|
||||
|
||||
return ctx.success(version, '版本创建成功');
|
||||
},
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /admin_api/version/update:
|
||||
* post:
|
||||
* summary: 更新版本
|
||||
* description: 更新版本信息
|
||||
* tags: [后台-版本管理]
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - id
|
||||
* properties:
|
||||
* id:
|
||||
* type: integer
|
||||
* description: 版本ID
|
||||
* version:
|
||||
* type: string
|
||||
* description: 版本号
|
||||
* platform:
|
||||
* type: string
|
||||
* description: 平台类型
|
||||
* arch:
|
||||
* type: string
|
||||
* description: 架构类型
|
||||
* download_url:
|
||||
* type: string
|
||||
* description: 下载地址
|
||||
* file_path:
|
||||
* type: string
|
||||
* description: 文件路径
|
||||
* release_notes:
|
||||
* type: string
|
||||
* description: 更新日志
|
||||
* force_update:
|
||||
* type: integer
|
||||
* description: 是否强制更新
|
||||
* status:
|
||||
* type: integer
|
||||
* description: 状态
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 更新成功
|
||||
*/
|
||||
'POST /version/update': async (ctx) => {
|
||||
const models = Framework.getModels();
|
||||
const { version_info } = models;
|
||||
const { op } = models;
|
||||
const body = ctx.getBody();
|
||||
|
||||
if (!body.id) {
|
||||
return ctx.fail('版本ID不能为空');
|
||||
}
|
||||
|
||||
const version = await version_info.findByPk(body.id);
|
||||
if (!version) {
|
||||
return ctx.fail('版本不存在');
|
||||
}
|
||||
|
||||
// 如果更新了版本号、平台或架构,检查是否重复
|
||||
if (body.version || body.platform || body.arch) {
|
||||
const check_version = body.version || version.version;
|
||||
const check_platform = body.platform || version.platform;
|
||||
const check_arch = body.arch || version.arch;
|
||||
|
||||
const existing = await version_info.findOne({
|
||||
where: {
|
||||
version: check_version,
|
||||
platform: check_platform,
|
||||
arch: check_arch,
|
||||
id: { [op.ne]: body.id }
|
||||
}
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
return ctx.fail('该版本已存在');
|
||||
}
|
||||
}
|
||||
|
||||
// 如果更新了文件路径,重新计算文件大小和哈希
|
||||
if (body.file_path && body.file_path !== version.file_path) {
|
||||
try {
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const full_path = path.resolve(body.file_path);
|
||||
|
||||
if (fs.existsSync(full_path)) {
|
||||
const stats = fs.statSync(full_path);
|
||||
body.file_size = stats.size;
|
||||
body.file_hash = await version_service.calculate_file_hash(full_path);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('计算文件信息失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新版本
|
||||
await version_info.update({
|
||||
version: body.version,
|
||||
platform: body.platform,
|
||||
arch: body.arch,
|
||||
download_url: body.download_url,
|
||||
file_path: body.file_path,
|
||||
file_size: body.file_size,
|
||||
file_hash: body.file_hash,
|
||||
release_notes: body.release_notes,
|
||||
force_update: body.force_update,
|
||||
status: body.status
|
||||
}, {
|
||||
where: { id: body.id }
|
||||
});
|
||||
|
||||
return ctx.success(null, '版本更新成功');
|
||||
},
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /admin_api/version/delete:
|
||||
* post:
|
||||
* summary: 删除版本
|
||||
* description: 删除指定的版本信息
|
||||
* tags: [后台-版本管理]
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - id
|
||||
* properties:
|
||||
* id:
|
||||
* type: integer
|
||||
* description: 版本ID
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 删除成功
|
||||
*/
|
||||
'POST /version/delete': async (ctx) => {
|
||||
const models = Framework.getModels();
|
||||
const { version_info } = models;
|
||||
const { id } = ctx.getBody();
|
||||
|
||||
if (!id) {
|
||||
return ctx.fail('版本ID不能为空');
|
||||
}
|
||||
|
||||
const result = await version_info.destroy({
|
||||
where: { id }
|
||||
});
|
||||
|
||||
if (result === 0) {
|
||||
return ctx.fail('版本不存在');
|
||||
}
|
||||
|
||||
return ctx.success(null, '版本删除成功');
|
||||
},
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /admin_api/version/update_status:
|
||||
* post:
|
||||
* summary: 更新版本状态
|
||||
* description: 启用或禁用版本
|
||||
* tags: [后台-版本管理]
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - id
|
||||
* - status
|
||||
* properties:
|
||||
* id:
|
||||
* type: integer
|
||||
* description: 版本ID
|
||||
* status:
|
||||
* type: integer
|
||||
* description: 状态(1:启用 0:禁用)
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 更新成功
|
||||
*/
|
||||
'POST /version/update_status': async (ctx) => {
|
||||
const models = Framework.getModels();
|
||||
const { version_info } = models;
|
||||
const { id, status } = ctx.getBody();
|
||||
|
||||
if (!id) {
|
||||
return ctx.fail('版本ID不能为空');
|
||||
}
|
||||
|
||||
if (status === undefined || status === null) {
|
||||
return ctx.fail('状态不能为空');
|
||||
}
|
||||
|
||||
const result = await version_info.update({
|
||||
status: status
|
||||
}, {
|
||||
where: { id }
|
||||
});
|
||||
|
||||
if (result[0] === 0) {
|
||||
return ctx.fail('版本不存在');
|
||||
}
|
||||
|
||||
return ctx.success(null, '状态更新成功');
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user