Files
autoAiWorkSys/api/controller_admin/version.js
张成 7858459118 1
2025-11-26 12:39:21 +08:00

518 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 版本管理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, '状态更新成功');
}
};