diff --git a/_docs/sql/alter_plan_api_permission.sql b/_docs/sql/alter_plan_api_permission.sql
index 2aeb535..cb992a0 100644
--- a/_docs/sql/alter_plan_api_permission.sql
+++ b/_docs/sql/alter_plan_api_permission.sql
@@ -1,8 +1,14 @@
--- biz_plans 新增:可访问接口列表 + 每月API调用次数上限
-ALTER TABLE `biz_plans`
- 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`;
+-- 在「与后端 app 相同」的 MySQL 库中执行(否则会一直报 Unknown column)。
+-- 可重复执行:若列已存在会报错,可忽略对应语句或改用 scripts/migrate_biz_plan_api_columns.js
--- 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`
- 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转发总调用次数';
diff --git a/admin/src/views/subscription/usage.vue b/admin/src/views/subscription/usage.vue
index 60aaf6d..ab6bda9 100644
--- a/admin/src/views/subscription/usage.vue
+++ b/admin/src/views/subscription/usage.vue
@@ -79,6 +79,7 @@
+
@@ -122,6 +123,7 @@ export default {
{ title: 'friend', key: 'friend_count', minWidth: 72 },
{ title: 'sns', key: 'sns_count', minWidth: 72 },
{ title: 'active_user', key: 'active_user_count', minWidth: 100 },
+ { title: 'api_calls', key: 'api_call_count', minWidth: 88 },
{
title: '操作',
key: 'a',
@@ -178,6 +180,7 @@ export default {
friend_count: 0,
sns_count: 0,
active_user_count: 0,
+ api_call_count: 0,
}
}
this.modal = true
diff --git a/api/model/biz_api_call_log.js b/api/model/biz_api_call_log.js
index b7e2daa..c87a0e2 100644
--- a/api/model/biz_api_call_log.js
+++ b/api/model/biz_api_call_log.js
@@ -4,11 +4,7 @@ module.exports = (db) => {
const biz_api_call_log = db.define(
"biz_api_call_log",
{
- id: {
- type: Sequelize.BIGINT.UNSIGNED,
- primaryKey: true,
- autoIncrement: true,
- },
+
user_id: {
type: Sequelize.BIGINT.UNSIGNED,
allowNull: false,
diff --git a/api/model/biz_api_token.js b/api/model/biz_api_token.js
index da42fc0..a6df43d 100644
--- a/api/model/biz_api_token.js
+++ b/api/model/biz_api_token.js
@@ -4,11 +4,7 @@ module.exports = (db) => {
const biz_api_token = db.define(
"biz_api_token",
{
- id: {
- type: Sequelize.BIGINT.UNSIGNED,
- primaryKey: true,
- autoIncrement: true,
- },
+
user_id: {
type: Sequelize.BIGINT.UNSIGNED,
allowNull: false,
diff --git a/api/model/biz_audit_log.js b/api/model/biz_audit_log.js
index 29a67b6..02ee526 100644
--- a/api/model/biz_audit_log.js
+++ b/api/model/biz_audit_log.js
@@ -4,11 +4,7 @@ module.exports = (db) => {
const biz_audit_log = db.define(
"biz_audit_log",
{
- id: {
- type: Sequelize.BIGINT.UNSIGNED,
- primaryKey: true,
- autoIncrement: true,
- },
+
admin_user_id: {
type: Sequelize.BIGINT.UNSIGNED,
allowNull: true,
diff --git a/api/model/biz_plan.js b/api/model/biz_plan.js
index 22ed382..ff8b958 100644
--- a/api/model/biz_plan.js
+++ b/api/model/biz_plan.js
@@ -4,11 +4,7 @@ module.exports = (db) => {
const biz_plan = db.define(
"biz_plan",
{
- id: {
- type: Sequelize.BIGINT.UNSIGNED,
- primaryKey: true,
- autoIncrement: true,
- },
+
plan_code: {
type: Sequelize.STRING(64),
allowNull: false,
@@ -64,6 +60,6 @@ module.exports = (db) => {
comment: "套餐",
}
);
- // biz_plan.sync({ alter: true });
+ // biz_plan.sync({ alter: true });
return biz_plan;
};
diff --git a/api/model/biz_subscription.js b/api/model/biz_subscription.js
index aa0920e..6c35a4c 100644
--- a/api/model/biz_subscription.js
+++ b/api/model/biz_subscription.js
@@ -4,11 +4,7 @@ module.exports = (db) => {
const biz_subscription = db.define(
"biz_subscription",
{
- id: {
- type: Sequelize.BIGINT.UNSIGNED,
- primaryKey: true,
- autoIncrement: true,
- },
+
user_id: {
type: Sequelize.BIGINT.UNSIGNED,
allowNull: false,
diff --git a/api/model/biz_usage_monthly.js b/api/model/biz_usage_monthly.js
index 362e1e3..56b9a17 100644
--- a/api/model/biz_usage_monthly.js
+++ b/api/model/biz_usage_monthly.js
@@ -4,11 +4,7 @@ module.exports = (db) => {
const biz_usage_monthly = db.define(
"biz_usage_monthly",
{
- id: {
- type: Sequelize.BIGINT.UNSIGNED,
- primaryKey: true,
- autoIncrement: true,
- },
+
user_id: {
type: Sequelize.BIGINT.UNSIGNED,
allowNull: false,
diff --git a/api/model/biz_user.js b/api/model/biz_user.js
index d85bec6..18fbcfb 100644
--- a/api/model/biz_user.js
+++ b/api/model/biz_user.js
@@ -4,11 +4,7 @@ module.exports = (db) => {
const biz_user = db.define(
"biz_user",
{
- id: {
- type: Sequelize.BIGINT.UNSIGNED,
- primaryKey: true,
- autoIncrement: true,
- },
+
name: {
type: Sequelize.STRING(100),
allowNull: false,
diff --git a/package.json b/package.json
index 12ab027..d447c16 100644
--- a/package.json
+++ b/package.json
@@ -68,7 +68,8 @@
"load": "node __tests__/loadtest-both.js",
"api": " nodemon ./app.js ",
"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"
}
diff --git a/scripts/migrate_biz_plan_api_columns.js b/scripts/migrate_biz_plan_api_columns.js
new file mode 100644
index 0000000..826bb40
--- /dev/null
+++ b/scripts/migrate_biz_plan_api_columns.js
@@ -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);
+});