1
This commit is contained in:
@@ -1,8 +1,14 @@
|
|||||||
-- biz_plans 新增:可访问接口列表 + 每月API调用次数上限
|
-- 在「与后端 app 相同」的 MySQL 库中执行(否则会一直报 Unknown column)。
|
||||||
ALTER TABLE `biz_plans`
|
-- 可重复执行:若列已存在会报错,可忽略对应语句或改用 scripts/migrate_biz_plan_api_columns.js
|
||||||
ADD COLUMN `allowed_apis` JSON DEFAULT NULL COMMENT '可访问的接口路径列表,null=不限制' AFTER `enabled_features`,
|
|
||||||
ADD COLUMN `api_call_quota` INT NOT NULL DEFAULT 0 COMMENT '每月API总调用次数上限,0=不限制' AFTER `allowed_apis`;
|
|
||||||
|
|
||||||
-- biz_usage_monthly 新增:当月API调用总次数
|
SET NAMES utf8mb4;
|
||||||
|
|
||||||
|
-- biz_plans(分两条,方便只缺其中一列时单独执行)
|
||||||
|
ALTER TABLE `biz_plans`
|
||||||
|
ADD COLUMN `allowed_apis` JSON DEFAULT NULL COMMENT '可访问的接口路径列表,null=不限制';
|
||||||
|
ALTER TABLE `biz_plans`
|
||||||
|
ADD COLUMN `api_call_quota` INT NOT NULL DEFAULT 0 COMMENT '每月API总调用次数上限,0=不限制';
|
||||||
|
|
||||||
|
-- biz_usage_monthly
|
||||||
ALTER TABLE `biz_usage_monthly`
|
ALTER TABLE `biz_usage_monthly`
|
||||||
ADD COLUMN `api_call_count` INT NOT NULL DEFAULT 0 COMMENT '当月API转发总调用次数' AFTER `active_user_count`;
|
ADD COLUMN `api_call_count` INT NOT NULL DEFAULT 0 COMMENT '当月API转发总调用次数';
|
||||||
|
|||||||
@@ -79,6 +79,7 @@
|
|||||||
<FormItem label="friend_count"><Input v-model="form.friend_count" type="number" /></FormItem>
|
<FormItem label="friend_count"><Input v-model="form.friend_count" type="number" /></FormItem>
|
||||||
<FormItem label="sns_count"><Input v-model="form.sns_count" type="number" /></FormItem>
|
<FormItem label="sns_count"><Input v-model="form.sns_count" type="number" /></FormItem>
|
||||||
<FormItem label="active_user_count"><Input v-model="form.active_user_count" type="number" /></FormItem>
|
<FormItem label="active_user_count"><Input v-model="form.active_user_count" type="number" /></FormItem>
|
||||||
|
<FormItem label="api_call_count(转发调用)"><Input v-model="form.api_call_count" type="number" /></FormItem>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
@@ -122,6 +123,7 @@ export default {
|
|||||||
{ title: 'friend', key: 'friend_count', minWidth: 72 },
|
{ title: 'friend', key: 'friend_count', minWidth: 72 },
|
||||||
{ title: 'sns', key: 'sns_count', minWidth: 72 },
|
{ title: 'sns', key: 'sns_count', minWidth: 72 },
|
||||||
{ title: 'active_user', key: 'active_user_count', minWidth: 100 },
|
{ title: 'active_user', key: 'active_user_count', minWidth: 100 },
|
||||||
|
{ title: 'api_calls', key: 'api_call_count', minWidth: 88 },
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'a',
|
key: 'a',
|
||||||
@@ -178,6 +180,7 @@ export default {
|
|||||||
friend_count: 0,
|
friend_count: 0,
|
||||||
sns_count: 0,
|
sns_count: 0,
|
||||||
active_user_count: 0,
|
active_user_count: 0,
|
||||||
|
api_call_count: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.modal = true
|
this.modal = true
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ module.exports = (db) => {
|
|||||||
const biz_api_call_log = db.define(
|
const biz_api_call_log = db.define(
|
||||||
"biz_api_call_log",
|
"biz_api_call_log",
|
||||||
{
|
{
|
||||||
id: {
|
|
||||||
type: Sequelize.BIGINT.UNSIGNED,
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true,
|
|
||||||
},
|
|
||||||
user_id: {
|
user_id: {
|
||||||
type: Sequelize.BIGINT.UNSIGNED,
|
type: Sequelize.BIGINT.UNSIGNED,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ module.exports = (db) => {
|
|||||||
const biz_api_token = db.define(
|
const biz_api_token = db.define(
|
||||||
"biz_api_token",
|
"biz_api_token",
|
||||||
{
|
{
|
||||||
id: {
|
|
||||||
type: Sequelize.BIGINT.UNSIGNED,
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true,
|
|
||||||
},
|
|
||||||
user_id: {
|
user_id: {
|
||||||
type: Sequelize.BIGINT.UNSIGNED,
|
type: Sequelize.BIGINT.UNSIGNED,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ module.exports = (db) => {
|
|||||||
const biz_audit_log = db.define(
|
const biz_audit_log = db.define(
|
||||||
"biz_audit_log",
|
"biz_audit_log",
|
||||||
{
|
{
|
||||||
id: {
|
|
||||||
type: Sequelize.BIGINT.UNSIGNED,
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true,
|
|
||||||
},
|
|
||||||
admin_user_id: {
|
admin_user_id: {
|
||||||
type: Sequelize.BIGINT.UNSIGNED,
|
type: Sequelize.BIGINT.UNSIGNED,
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ module.exports = (db) => {
|
|||||||
const biz_plan = db.define(
|
const biz_plan = db.define(
|
||||||
"biz_plan",
|
"biz_plan",
|
||||||
{
|
{
|
||||||
id: {
|
|
||||||
type: Sequelize.BIGINT.UNSIGNED,
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true,
|
|
||||||
},
|
|
||||||
plan_code: {
|
plan_code: {
|
||||||
type: Sequelize.STRING(64),
|
type: Sequelize.STRING(64),
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ module.exports = (db) => {
|
|||||||
const biz_subscription = db.define(
|
const biz_subscription = db.define(
|
||||||
"biz_subscription",
|
"biz_subscription",
|
||||||
{
|
{
|
||||||
id: {
|
|
||||||
type: Sequelize.BIGINT.UNSIGNED,
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true,
|
|
||||||
},
|
|
||||||
user_id: {
|
user_id: {
|
||||||
type: Sequelize.BIGINT.UNSIGNED,
|
type: Sequelize.BIGINT.UNSIGNED,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ module.exports = (db) => {
|
|||||||
const biz_usage_monthly = db.define(
|
const biz_usage_monthly = db.define(
|
||||||
"biz_usage_monthly",
|
"biz_usage_monthly",
|
||||||
{
|
{
|
||||||
id: {
|
|
||||||
type: Sequelize.BIGINT.UNSIGNED,
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true,
|
|
||||||
},
|
|
||||||
user_id: {
|
user_id: {
|
||||||
type: Sequelize.BIGINT.UNSIGNED,
|
type: Sequelize.BIGINT.UNSIGNED,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ module.exports = (db) => {
|
|||||||
const biz_user = db.define(
|
const biz_user = db.define(
|
||||||
"biz_user",
|
"biz_user",
|
||||||
{
|
{
|
||||||
id: {
|
|
||||||
type: Sequelize.BIGINT.UNSIGNED,
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true,
|
|
||||||
},
|
|
||||||
name: {
|
name: {
|
||||||
type: Sequelize.STRING(100),
|
type: Sequelize.STRING(100),
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
|
|||||||
@@ -68,7 +68,8 @@
|
|||||||
"load": "node __tests__/loadtest-both.js",
|
"load": "node __tests__/loadtest-both.js",
|
||||||
"api": " nodemon ./app.js ",
|
"api": " nodemon ./app.js ",
|
||||||
"serve": "cd ./admin&&npm run dev -- --port 9001 ",
|
"serve": "cd ./admin&&npm run dev -- --port 9001 ",
|
||||||
"build": "cd ./admin&&npm run build "
|
"build": "cd ./admin&&npm run build ",
|
||||||
|
"migrate:plan_api": "node scripts/migrate_biz_plan_api_columns.js"
|
||||||
},
|
},
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
|
|||||||
73
scripts/migrate_biz_plan_api_columns.js
Normal file
73
scripts/migrate_biz_plan_api_columns.js
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* 为 biz_plans / biz_usage_monthly 补齐套餐 API 权限相关字段(可重复执行)
|
||||||
|
*/
|
||||||
|
const mysql = require("mysql2/promise");
|
||||||
|
const config = require("../config/config");
|
||||||
|
|
||||||
|
async function column_exists(conn, schema, table, column) {
|
||||||
|
const [rows] = await conn.query(
|
||||||
|
`SELECT COUNT(*) AS c FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND COLUMN_NAME = ?`,
|
||||||
|
[schema, table, column]
|
||||||
|
);
|
||||||
|
return Number(rows[0].c) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function table_exists(conn, schema, table) {
|
||||||
|
const [rows] = await conn.query(
|
||||||
|
`SELECT COUNT(*) AS c FROM information_schema.TABLES
|
||||||
|
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?`,
|
||||||
|
[schema, table]
|
||||||
|
);
|
||||||
|
return Number(rows[0].c) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const db = config.db;
|
||||||
|
if (!db || !db.database) {
|
||||||
|
throw new Error("config.db.database 未配置");
|
||||||
|
}
|
||||||
|
const conn = await mysql.createConnection({
|
||||||
|
host: db.host,
|
||||||
|
port: db.port || 3306,
|
||||||
|
user: db.username,
|
||||||
|
password: db.password,
|
||||||
|
database: db.database,
|
||||||
|
});
|
||||||
|
const schema = db.database;
|
||||||
|
try {
|
||||||
|
if (!(await table_exists(conn, schema, "biz_plans"))) {
|
||||||
|
console.warn("跳过 biz_plans:当前库中不存在该表(请确认连接的是已部署订阅模块的库)");
|
||||||
|
} else if (!(await column_exists(conn, schema, "biz_plans", "allowed_apis"))) {
|
||||||
|
await conn.query(
|
||||||
|
"ALTER TABLE `biz_plans` ADD COLUMN `allowed_apis` JSON DEFAULT NULL COMMENT '可访问的接口路径列表,null=不限制'"
|
||||||
|
);
|
||||||
|
console.log("已添加 biz_plans.allowed_apis");
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(await table_exists(conn, schema, "biz_plans")) &&
|
||||||
|
!(await column_exists(conn, schema, "biz_plans", "api_call_quota"))
|
||||||
|
) {
|
||||||
|
await conn.query(
|
||||||
|
"ALTER TABLE `biz_plans` ADD COLUMN `api_call_quota` INT NOT NULL DEFAULT 0 COMMENT '每月API总调用次数上限,0=不限制'"
|
||||||
|
);
|
||||||
|
console.log("已添加 biz_plans.api_call_quota");
|
||||||
|
}
|
||||||
|
if (!(await table_exists(conn, schema, "biz_usage_monthly"))) {
|
||||||
|
console.warn("跳过 biz_usage_monthly:当前库中不存在该表");
|
||||||
|
} else if (!(await column_exists(conn, schema, "biz_usage_monthly", "api_call_count"))) {
|
||||||
|
await conn.query(
|
||||||
|
"ALTER TABLE `biz_usage_monthly` ADD COLUMN `api_call_count` INT NOT NULL DEFAULT 0 COMMENT '当月API转发总调用次数'"
|
||||||
|
);
|
||||||
|
console.log("已添加 biz_usage_monthly.api_call_count");
|
||||||
|
}
|
||||||
|
console.log("字段检查完成");
|
||||||
|
} finally {
|
||||||
|
await conn.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((e) => {
|
||||||
|
console.error(e);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user