v1.0.51: 部署配套 - ①config/database.php 支持 env 注入(DB_HOST/PORT/NAME/USER/PASS/CHARSET,缺省回落本地开发);②新增sql/schema_v1.0.51_base.sql全量业务库基准schema(仓库原仅增量迁移,27表按代码反推重建,含source_channels种子);③新增deploy/容器化编排(php8.2-fpm+nginx+mysql8.0,web暴露宿主8081,DB仅内网,对齐license_server既有compose风格):Dockerfile/nginx/default.conf/mysql初始化(01导入基准+字典/02种子超管角色与admin账号及12个迁移版本标记)/.env.example;④.gitignore防护.env与运行产物. 已在服务器106.55.169.92用一次性mysql:8.0容器验证:27表+字典(3632区域/12来源渠道)+admin/超管+cert版本标记全部导入成功

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
qianqiuwanzi
2026-09-17 15:30:19 +08:00
parent c86f08c325
commit 43bd11db0b
9 changed files with 744 additions and 9 deletions
+13
View File
@@ -0,0 +1,13 @@
# 本地环境变量/口令(部署时 cp .env.example .env 填写,切勿提交)
deploy/.env
# 运行期产物
runtime/logs/*
runtime/session/*
!runtime/logs/.gitkeep
!runtime/session/.gitkeep
static/uploads/*
# 系统/编辑器
Thumbs.db
.DS_Store
+21 -9
View File
@@ -1,13 +1,25 @@
<?php
/**
* 数据库配置文件
* 返回数组,供 api/common/db.php 读取
* 数据库配置文件(返回数组,供 api/common/db.php 读取)
*
* 取值优先级:
* 1. 环境变量 DB_HOST / DB_PORT / DB_NAME / DB_USER / DB_PASS / DB_CHARSET
* (容器化部署时由 docker-compose 的 environment: 注入,杜绝明文口令入库)
* 2. 回退到下方硬编码默认值(本地开发 127.0.0.1)
*
* 变更记录:
* v1.0.51 支持 env 注入,为 docker 容器化部署准备(服务器 106.55.169.92 长期目标)
*/
$env = function ($k, $d = null) {
$v = getenv($k);
return ($v === false || $v === '') ? $d : $v;
};
return [
'host' => '127.0.0.1',
'port' => 3306,
'dbname' => 'mysuperlink',
'username' => 'mysuperlink_root',
'password' => '123456',
'charset' => 'utf8mb4',
];
'host' => $env('DB_HOST', '127.0.0.1'),
'port' => (int)$env('DB_PORT', 3306),
'dbname' => $env('DB_NAME', 'mysuperlink'),
'username' => $env('DB_USER', 'mysuperlink_root'),
'password' => $env('DB_PASS', '123456'),
'charset' => $env('DB_CHARSET', 'utf8mb4'),
];
+8
View File
@@ -0,0 +1,8 @@
# SuperLink 部署环境变量(复制为 .env 并填写后再 docker compose up)
# 注意:.env 含口令,不要提交到 git(已加入 .gitignore)
# 数据库
DB_NAME=mysuperlink
DB_USER=mysuperlink_root
DB_PASS=ChangeMe_DB_Pass_2026
DB_ROOT_PASS=ChangeMe_Root_Pass_2026
+65
View File
@@ -0,0 +1,65 @@
# SuperLink 部署编排(对齐服务器 license_server 既有 compose 风格)
# 服务:db(MySQL8) / app(PHP-FPM) / web(nginx)
# 使用:cp .env.example .env 并填好口令;docker compose up -d --build
# 访问:http://<服务器IP>:8081/
name: mysuperlink
services:
db:
image: mysql:8.0
restart: unless-stopped
env_file: .env
environment:
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASS}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --default-authentication-plugin=mysql_native_password
volumes:
- db_data:/var/lib/mysql
- ./mysql/initdb/01_schema_base.sh:/docker-entrypoint-initdb.d/01_schema_base.sh:ro
- .:/repo # 挂载部署目录,init 脚本 source 仓库 sql
- ../../sql:/repo/sql:ro # 仓库 sql 目录(基准 + 字典 + 迁移)
- ../../config:/repo/config:ro
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -u$$MYSQL_USER -p$$MYSQL_PASSWORD --silent"]
interval: 5s
timeout: 5s
retries: 30
start_period: 30s
app:
build: ./php
restart: unless-stopped
env_file: .env
environment:
DB_HOST: db
DB_PORT: "3306"
DB_NAME: ${DB_NAME}
DB_USER: ${DB_USER}
DB_PASS: ${DB_PASS}
DB_CHARSET: utf8mb4
volumes:
- ../../:/var/www/html
depends_on:
db:
condition: service_healthy
web:
image: nginx:1.25-alpine
restart: unless-stopped
ports:
- "8081:80"
environment:
- TZ=Asia/Shanghai
volumes:
- ../../:/var/www/html:ro
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- app
volumes:
db_data:
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
# SuperLink 首次初始化(仅空数据卷时由 mysql 镜像 entrypoint 执行):
# 1) 导入基准建库脚本(业务表全量定义)
# 2) 导入数据字典种子(官方 Excel 生成)
# 说明:大文件用 .sh 以 mysql < 方式导入;admin/角色/版本标记放 02_admin.sql。
set -euo pipefail
echo ">> SuperLink init: import base schema (${MYSQL_DATABASE})"
mysql --user=root --password="${MYSQL_ROOT_PASSWORD}" --default-character-set=utf8mb4 "${MYSQL_DATABASE}" < /repo/sql/schema_v1.0.51_base.sql
echo ">> SuperLink init: import dict_seed.sql"
mysql --user=root --password="${MYSQL_ROOT_PASSWORD}" --default-character-set=utf8mb4 "${MYSQL_DATABASE}" < /repo/sql/dict_seed.sql
echo ">> SuperLink init: schema + dict ok"
+40
View File
@@ -0,0 +1,40 @@
-- ============================================================
-- SuperLink 首次初始化:种子超管角色 + 管理员账号 + 迁移版本标记
-- 由 mysql 镜像 entrypoint 在空数据卷时执行;entrypoint 已自动 USE ${MYSQL_DATABASE}
-- 说明:
-- - base schema(v1.0.51_base) 已内建 v1.0.16→v1.0.51 的全部业务表,
-- 故在此把各迁移文件标记为"已应用",避免 tools/migrate.php up 重复执行。
-- - 管理员账号:admin / Admin@123456(bcrypt 密码,请在首次登录后立即修改)
-- ============================================================
-- 1) 超级管理员角色:权限 = 全部业务模块(与前端菜单标识一致)
INSERT INTO `system_roles` (`role_name`, `permissions`, `is_active`)
SELECT '超级管理员', '["dashboard","company","person","media","need","marketing","channel","document","preliminary","system","log"]', 1
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `system_roles` WHERE `role_name` = '超级管理员');
-- 2) 管理员账号(bcrypt,Admin@123456)
INSERT INTO `system_users` (`username`, `password`, `real_name`, `role_id`, `is_active`)
SELECT 'admin',
'$2y$10$1nNvyQx/fVtrPHOkFTUwV.HNbWFkea75Cx3ICil.9BnoJpCrSAeCm',
'管理员',
(SELECT `id` FROM `system_roles` WHERE `role_name` = '超级管理员' LIMIT 1),
1
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `system_users` WHERE `username` = 'admin');
-- 3) 迁移版本标记(version 去掉 migration_ 前缀,checksum = 迁移文件 md5)
INSERT INTO `schema_versions` (`version`, `checksum`) VALUES
('v1.0.16','73e9594d7ab151791c4ba315e5e87156'),
('v1.0.18','cdfd4eb98e92047c2aa35325908e6f2e'),
('v1.0.20','860b09d92e810620b3bd71d126833611'),
('v1.0.25','c6b545a9dfe0bff7aad8b94849785135'),
('v1.0.27','f1db249ac23697a4981559436306f542'),
('v1.0.30','8faa7dccea9c361d0b8fe4e0c11384f3'),
('v1.0.40','70b9cedf240555bca58f46148c0d380e'),
('v1.0.41','247b6bc7718b9f1d7d5ea28ed9b8a3e2'),
('v1.0.47','10b64a2551e7eb8f1f5bdc8e87c6c06a'),
('v1.0.48','f507f2964d9bf7f8c885d69119c6d041'),
('v1.0.50','edaa2a71a4adf716591ece61ed9fc09f'),
('v1.0.51','3251bf0bca9236e201dc419770f7f5dc')
ON DUPLICATE KEY UPDATE `checksum` = VALUES(`checksum`);
+53
View File
@@ -0,0 +1,53 @@
server {
listen 80;
server_name _;
root /var/www/html;
index index.html;
charset utf-8;
sendfile on;
tcp_nopush on;
client_max_body_size 200m;
server_tokens off;
# 禁止点开隐藏文件/目录及运行日志
location ~ /\. {
deny all;
}
# 静态资源长缓存(uploads/css/js/libs)
location ~* \.(?:css|js|png|jpg|jpeg|gif|svg|ico|woff2?)$ {
expires 7d;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
# 上传目录允许写入(由 php-fpm 侧保证写入者权限)
location /static/uploads {
access_log off;
expires 30d;
try_files $uri =404;
}
# PHP 交给 php-fpm
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_read_timeout 300;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
# 其余静态页面
location / {
try_files $uri $uri/ =404;
}
error_page 404 =404 /index.html;
gzip on;
gzip_types text/plain text/css application/json application/javascript image/svg+xml;
}
+11
View File
@@ -0,0 +1,11 @@
# SuperLink PHP-FPM 运行镜像
# 说明:官方 php:8.2-fpm 已内置 pdo_mysql / mbstring / fileinfo 等所需扩展,
# 仅显式安装 pdo_mysql 以备未来镜像变化,并设定可写目录权限。
FROM php:8.2-fpm
# 显式启用 PDO MySQL(官方镜像默认已含,这里保证 manifest 一致)
RUN docker-php-ext-install pdo_mysql \
&& mkdir -p /var/www/html/runtime/logs /var/www/html/runtime/session \
&& chown -R www-data:www-data /var/www/html/runtime
WORKDIR /var/www/html
+522
View File
@@ -0,0 +1,522 @@
-- ============================================================
-- SuperLink 基准建库脚本(Fresh Install Base Schema) v1.0.51
-- 用途:全新部署时一次性建立全部业务表(当前形态,含历次迁移结果)。
-- 由仓库"增量迁移缺失基准 schema"这一现状补建:主业务表定义从
-- api 代码字段白名单 + INSERT/SELECT 语句反推,字典/属性/计划等表
-- 直接采用迁移文件中的 CREATE TABLE 原文。
-- 约定:v1.0.16 后所有业务表时间字段为 DATE;id 一律 INT UNSIGNED AUTO_INCREMENT;
-- 字符集 utf8mb4 / 排序 utf8mb4_unicode_ci。
-- 执行顺序:本文件 → dict_seed.sql → 系统初始数据(admin)。
-- ============================================================
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ------------------------------------------------------------
-- 0) 数据字典(定义见 migration_v1.0.16 / v1.0.18,数据由 dict_seed.sql 注入)
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `data_dict_country` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`code` VARCHAR(50) NOT NULL COMMENT '国家/地区编码',
`name` VARCHAR(100) NOT NULL COMMENT '国家/地区中文名',
`sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序',
`is_active` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '启用状态',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='国家地区编码字典';
CREATE TABLE IF NOT EXISTS `data_dict_area` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`code` VARCHAR(50) NOT NULL COMMENT '行政区划编码',
`name` VARCHAR(100) NOT NULL COMMENT '行政区划名称',
`parent_code` VARCHAR(50) DEFAULT NULL COMMENT '上级行政区划编码',
`sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序',
`is_active` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '启用状态',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`),
KEY `idx_parent` (`parent_code`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='行政区划编码字典';
CREATE TABLE IF NOT EXISTS `data_dict_industry` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`code` VARCHAR(50) NOT NULL COMMENT '行业编码',
`name` VARCHAR(100) NOT NULL COMMENT '行业名称',
`parent_code` VARCHAR(50) DEFAULT NULL COMMENT '上级行业编码',
`sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序',
`is_active` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '启用状态',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`),
KEY `idx_parent` (`parent_code`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='招标行业分类字典';
CREATE TABLE IF NOT EXISTS `data_dict_certificate` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`code` VARCHAR(50) NULL DEFAULT NULL COMMENT '证书类型枚举编码',
`name` VARCHAR(100) NOT NULL COMMENT '证书类型名称',
`sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序',
`is_active` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '启用状态',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='证书类型枚举字典';
CREATE TABLE IF NOT EXISTS `data_dict_company_type` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`code` VARCHAR(50) NULL DEFAULT NULL COMMENT '企业类型编码',
`name` VARCHAR(100) NOT NULL COMMENT '企业类型名称',
`sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序',
`is_active` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '启用状态',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='企业类型字典(对应 companies.legal_form)';
CREATE TABLE IF NOT EXISTS `source_channels` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` VARCHAR(50) NOT NULL COMMENT '渠道名称',
`sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序',
`is_active` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '启用状态',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='来源渠道字典';
-- 来源渠道默认数据
INSERT INTO `source_channels` (`name`, `sort_order`) VALUES
('展会', 1), ('SNS/社交媒体', 2), ('竞价广告', 3), ('搜索引擎自然流量', 4),
('行业媒体/门户', 5), ('转介绍', 6), ('电话销售', 7), ('邮件营销', 8),
('地推', 9), ('代理商/渠道', 10), ('官网咨询', 11), ('其他', 99);
-- 企业类型字典默认数据
INSERT INTO `data_dict_company_type` (`code`, `name`, `sort_order`) VALUES
('llc', '有限责任公司', 1), ('joint_stock', '股份有限公司', 2), ('partnership', '合伙企业', 3),
('sole_proprietorship', '个人独资企业', 4), ('state_owned', '国有企业', 5), ('collective', '集体所有制企业', 6),
('foreign_invested', '外商投资企业', 7), ('joint_venture', '中外合资企业', 8), ('other', '其他', 99);
-- ------------------------------------------------------------
-- 1) 客户主体:企业
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `companies` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`display_name` VARCHAR(191) NOT NULL DEFAULT '' COMMENT '显示名称',
`name_zh` VARCHAR(191) DEFAULT NULL COMMENT '中文名',
`business_role` VARCHAR(50) DEFAULT NULL COMMENT '业务类型',
`country` VARCHAR(100) DEFAULT NULL COMMENT '国家/地区',
`registration_number` VARCHAR(100) DEFAULT NULL COMMENT '统一社会信用代码/注册号',
`address` VARCHAR(255) DEFAULT NULL COMMENT '地址',
`legal_form` VARCHAR(50) DEFAULT NULL COMMENT '企业类型(公司)',
`legal_representative` VARCHAR(100) DEFAULT NULL COMMENT '法定代表人',
`business_scope` TEXT DEFAULT NULL COMMENT '经营范围',
`established_date` DATE DEFAULT NULL COMMENT '成立日期',
`registered_capital` VARCHAR(50) DEFAULT NULL COMMENT '注册资本',
`industry` VARCHAR(100) DEFAULT NULL COMMENT '行业',
`industry_subdivision` VARCHAR(100) DEFAULT NULL COMMENT '行业细分',
`latest_employee_count` INT DEFAULT NULL COMMENT '最新员工数',
`latest_annual_revenue` VARCHAR(50) DEFAULT NULL COMMENT '年营收',
`is_listed` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否上市 0/1',
`stock_code` VARCHAR(30) DEFAULT NULL COMMENT '股票代码',
`website` VARCHAR(255) DEFAULT NULL COMMENT '官网',
`source_channel` VARCHAR(50) DEFAULT NULL COMMENT '来源渠道',
`source_detail` VARCHAR(255) DEFAULT NULL COMMENT '来源详情',
`is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '有效 0/1',
`is_incomplete` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '完整度不达标标记',
`created_at` DATE DEFAULT NULL COMMENT '创建日期',
`updated_at` DATE DEFAULT NULL COMMENT '更新日期',
PRIMARY KEY (`id`),
KEY `idx_is_active` (`is_active`),
KEY `idx_source_channel` (`source_channel`),
KEY `idx_name_zh` (`name_zh`),
KEY `idx_industry` (`industry`),
KEY `idx_created_at` (`created_at`),
KEY `idx_incomplete` (`is_incomplete`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='企业表';
-- ------------------------------------------------------------
-- 2) 客户主体:人员
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `persons` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`union_id` VARCHAR(64) DEFAULT NULL COMMENT '外部/统一ID(去重线索)',
`full_name` VARCHAR(100) DEFAULT NULL COMMENT '姓名',
`gender` VARCHAR(20) DEFAULT NULL COMMENT '性别(男/女/未知)',
`nationality` VARCHAR(50) DEFAULT NULL COMMENT '国籍',
`id_type` VARCHAR(30) DEFAULT NULL COMMENT '证件类型',
`id_number` VARCHAR(100) DEFAULT NULL COMMENT '身份证号码',
`education` VARCHAR(30) DEFAULT NULL COMMENT '学历',
`graduated_from` VARCHAR(191) DEFAULT NULL COMMENT '毕业院校',
`hometown` VARCHAR(100) DEFAULT NULL COMMENT '家乡',
`work_location` VARCHAR(100) DEFAULT NULL COMMENT '工作所在地',
`source_channel` VARCHAR(50) DEFAULT NULL COMMENT '来源渠道',
`source_detail` VARCHAR(255) DEFAULT NULL COMMENT '来源详情',
`is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '有效 0/1',
`is_incomplete` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '完整度不达标标记',
`created_at` DATE DEFAULT NULL COMMENT '创建日期',
`updated_at` DATE DEFAULT NULL COMMENT '更新日期',
PRIMARY KEY (`id`),
KEY `idx_is_active` (`is_active`),
KEY `idx_full_name` (`full_name`),
KEY `idx_source_channel` (`source_channel`),
KEY `idx_work_location` (`work_location`),
KEY `idx_incomplete` (`is_incomplete`),
KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='人员表';
-- ------------------------------------------------------------
-- 3) 社媒/联系方式(多态归属:owner_type='company'|'person',platform 可为 phone/email/社媒名)
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `social_accounts` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`owner_type` VARCHAR(20) NOT NULL COMMENT '归属类型 company/person',
`owner_id` INT UNSIGNED NOT NULL COMMENT '归属主体ID',
`platform` VARCHAR(30) NOT NULL COMMENT '平台:phone/email/wechat/weibo/douyin/...',
`account_id` VARCHAR(191) NOT NULL COMMENT '账号号/手机/邮箱',
`profile_url` VARCHAR(500) DEFAULT NULL COMMENT '主页链接',
`remark` VARCHAR(255) DEFAULT NULL COMMENT '备注',
`is_primary` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否常用 1/0',
`is_defult` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否常用(备用字段)1/0',
`is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '有效 0/1',
`is_incomplete`TINYINT(1) NOT NULL DEFAULT 0 COMMENT '完整度标记',
`created_at` DATE DEFAULT NULL COMMENT '创建日期',
PRIMARY KEY (`id`),
KEY `idx_owner` (`owner_type`, `owner_id`),
KEY `idx_platform` (`platform`),
KEY `idx_account` (`account_id`),
KEY `idx_incomplete` (`is_incomplete`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='社媒账号/联系方式表';
-- ------------------------------------------------------------
-- 4) 媒体商业属性(一人/一账号的多条商业评估)
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `media_commercial_attributes` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`social_account_id` INT UNSIGNED NOT NULL COMMENT '关联 social_accounts.id',
`account_level` VARCHAR(50) DEFAULT NULL COMMENT '账号等级',
`content_categories` VARCHAR(255) DEFAULT NULL COMMENT '内容领域',
`follower_count` INT DEFAULT NULL COMMENT '粉丝数',
`avg_read_count` INT DEFAULT NULL COMMENT '平均阅读',
`certification_type` VARCHAR(50) DEFAULT NULL COMMENT '认证类型',
`special_requirements` TEXT DEFAULT NULL COMMENT '特殊要求',
`media_remark` TEXT DEFAULT NULL COMMENT '评估备注',
`is_incomplete` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '完整度标记',
`created_at` DATE DEFAULT NULL COMMENT '创建日期',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_social_account` (`social_account_id`),
KEY `idx_incomplete` (`is_incomplete`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='媒体商业属性表';
-- ------------------------------------------------------------
-- 5) 需求(企业需求线索)
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `company_needs` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`company_id` INT UNSIGNED DEFAULT NULL COMMENT '关联企业',
`contact_person` VARCHAR(100) DEFAULT NULL COMMENT '联系人',
`contact_phone` VARCHAR(50) DEFAULT NULL COMMENT '联系电话',
`contact_email` VARCHAR(100) DEFAULT NULL COMMENT '联系邮箱',
`need_category` VARCHAR(100) DEFAULT NULL COMMENT '需求类别',
`target_product_category` VARCHAR(100) DEFAULT NULL COMMENT '目标产品品类',
`application_scenario` VARCHAR(255) DEFAULT NULL COMMENT '应用场景',
`description` TEXT DEFAULT NULL COMMENT '需求描述',
`status` VARCHAR(30) DEFAULT NULL COMMENT '状态',
`is_valid` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '有效 0/1',
`is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '启用 0/1',
`created_at` DATE DEFAULT NULL COMMENT '创建日期',
`updated_at` DATE DEFAULT NULL COMMENT '更新日期',
PRIMARY KEY (`id`),
KEY `idx_company` (`company_id`),
KEY `idx_category` (`need_category`),
KEY `idx_is_valid` (`is_valid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='需求表';
-- ------------------------------------------------------------
-- 6) 人员工作履历
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `person_work_experiences` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`person_id` INT UNSIGNED NOT NULL COMMENT '关联人员',
`company_id` INT UNSIGNED DEFAULT NULL COMMENT '任职企业',
`position` VARCHAR(191) DEFAULT NULL COMMENT '职位',
`department` VARCHAR(100) DEFAULT NULL COMMENT '部门',
`job_level` VARCHAR(50) DEFAULT NULL COMMENT '职级',
`start_date` DATE DEFAULT NULL COMMENT '开始时间',
`end_date` DATE DEFAULT NULL COMMENT '结束时间',
`is_current` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否现任 1/0',
`created_at` DATE DEFAULT NULL COMMENT '创建日期',
PRIMARY KEY (`id`),
KEY `idx_person` (`person_id`),
KEY `idx_company` (`company_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='人员工作履历表';
-- ------------------------------------------------------------
-- 7) 企业产品(类别 + 定位 + 系列)
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `company_products` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`company_id` INT UNSIGNED NOT NULL COMMENT '关联企业',
`category_name` VARCHAR(100) NOT NULL COMMENT '产品类别名',
`category_description` VARCHAR(255) DEFAULT NULL COMMENT '类别说明',
`positioning` TEXT DEFAULT NULL COMMENT '产品基本定位(商业定位介绍)',
`series` VARCHAR(200) DEFAULT NULL COMMENT '包含系列',
`is_core` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否核心产品',
`is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '启用 0/1',
`created_at` DATE DEFAULT NULL COMMENT '创建日期',
PRIMARY KEY (`id`),
KEY `idx_company` (`company_id`),
KEY `idx_core` (`is_core`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='企业产品表';
-- 产品参数 EAV(定义见 migration_v1.0.18)
CREATE TABLE IF NOT EXISTS `company_products_attr` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`industry` VARCHAR(100) NOT NULL,
`attr_name` VARCHAR(50) NOT NULL,
`attr_type` ENUM('string','number','boolean','date') NOT NULL DEFAULT 'string',
`unit` VARCHAR(20) DEFAULT NULL,
`sort_order` INT NOT NULL DEFAULT 0,
`is_active` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_industry_attr` (`industry`, `attr_name`),
KEY `idx_industry` (`industry`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='产品参数属性定义表(EAV)';
CREATE TABLE IF NOT EXISTS `company_products_attr_value` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`product_id` INT UNSIGNED NOT NULL,
`attr_id` INT UNSIGNED NOT NULL,
`value_string` TEXT DEFAULT NULL,
`value_number` DECIMAL(20,4) DEFAULT NULL,
`value_boolean` TINYINT(1) DEFAULT NULL,
`value_date` DATE DEFAULT NULL,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_product_attr` (`product_id`, `attr_id`),
KEY `idx_product` (`product_id`),
KEY `idx_attr` (`attr_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='产品参数值表(EAV)';
-- ------------------------------------------------------------
-- 8) 企业文档
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `company_documents` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`company_id` INT UNSIGNED DEFAULT NULL COMMENT '关联企业',
`doc_name` VARCHAR(255) NOT NULL COMMENT '文档名称',
`storage_path` VARCHAR(500) DEFAULT NULL COMMENT '存储路径',
`file_type` VARCHAR(30) DEFAULT NULL COMMENT '文件类型(pdf/word/xlsx/图片)',
`is_current` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否现行 1/0',
`document_source` VARCHAR(100) DEFAULT NULL COMMENT '文档来源',
`tags` VARCHAR(255) DEFAULT NULL COMMENT '标签',
`publish_date` DATE DEFAULT NULL COMMENT '发布日期',
`created_at` DATE DEFAULT NULL COMMENT '创建日期',
`update_time` DATETIME DEFAULT NULL COMMENT '更新时间',
`is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '有效 0/1',
PRIMARY KEY (`id`),
KEY `idx_company` (`company_id`),
KEY `idx_file_type` (`file_type`),
KEY `idx_active` (`is_active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='企业文档表';
-- ------------------------------------------------------------
-- 9) 财务与资质
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `company_financials` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`company_id` INT UNSIGNED NOT NULL COMMENT '关联企业',
`fiscal_year` INT NOT NULL COMMENT '财年',
`employee_count` INT DEFAULT NULL,
`total_revenue` DECIMAL(20,2) DEFAULT NULL,
`net_profit` DECIMAL(20,2) DEFAULT NULL,
`total_assets` DECIMAL(20,2) DEFAULT NULL,
`total_liabilities` DECIMAL(20,2) DEFAULT NULL,
`owner_equity` DECIMAL(20,2) DEFAULT NULL,
`gross_margin` DECIMAL(10,4) DEFAULT NULL,
`net_margin` DECIMAL(10,4) DEFAULT NULL,
`debt_ratio` DECIMAL(10,4) DEFAULT NULL,
`financial_report_url` VARCHAR(500) DEFAULT NULL,
`data_source` VARCHAR(100) DEFAULT '手动录入',
`created_at` DATE DEFAULT NULL COMMENT '创建日期',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_company_year` (`company_id`, `fiscal_year`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='企业年度财务明细表';
CREATE TABLE IF NOT EXISTS `company_certifications` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`company_id` INT UNSIGNED NOT NULL COMMENT '关联企业',
`certification_type_id` INT UNSIGNED DEFAULT NULL COMMENT '证书类型(字典)',
`certificate_number` VARCHAR(100) DEFAULT NULL COMMENT '证书编号',
`level` VARCHAR(50) DEFAULT NULL COMMENT '级别',
`issuing_authority` VARCHAR(200) DEFAULT NULL COMMENT '颁证机构',
`issue_date` DATE DEFAULT NULL COMMENT '发证日期',
`expiry_date` DATE DEFAULT NULL COMMENT '有效期至',
`created_at` DATE DEFAULT NULL COMMENT '创建日期',
PRIMARY KEY (`id`),
KEY `idx_company` (`company_id`),
KEY `idx_cert_type` (`certification_type_id`),
CONSTRAINT `fk_company_cert_dict` FOREIGN KEY (`certification_type_id`)
REFERENCES `data_dict_certificate` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='企业资质认证表';
CREATE TABLE IF NOT EXISTS `company_relations` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`company_id` INT UNSIGNED DEFAULT NULL COMMENT '企业A',
`related_company_id` INT UNSIGNED DEFAULT NULL COMMENT '关联企业B',
`related_company_name` VARCHAR(191) DEFAULT NULL COMMENT '关联企业名称',
`relation_type` VARCHAR(50) DEFAULT NULL COMMENT '关系类型',
`established_date` DATE DEFAULT NULL COMMENT '关系建立日期',
`note` VARCHAR(255) DEFAULT NULL COMMENT '备注',
`is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '有效 0/1',
`created_at` DATE DEFAULT NULL COMMENT '创建日期',
`updated_at` DATE DEFAULT NULL COMMENT '更新日期',
PRIMARY KEY (`id`),
KEY `idx_company` (`company_id`),
KEY `idx_related` (`related_company_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='企业关联关系表';
-- ------------------------------------------------------------
-- 10) 硬数据碎片(preliminary_data,v1.0.48 重构后形态)
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `preliminary_data` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`source_type` VARCHAR(20) DEFAULT NULL COMMENT '碎片类型 company/person/product/need/mixed',
`company_name` VARCHAR(191) DEFAULT NULL COMMENT '企业名(核心)',
`person_name` VARCHAR(100) DEFAULT NULL COMMENT '联系人(核心)',
`contact_phone` VARCHAR(50) DEFAULT NULL COMMENT '联系电话(核心)',
`contact_email` VARCHAR(100) DEFAULT NULL COMMENT '联系邮箱(核心)',
`industry` VARCHAR(100) DEFAULT NULL COMMENT '行业',
`registration_number` VARCHAR(100) DEFAULT NULL COMMENT '注册号(重要)',
`business_role` VARCHAR(50) DEFAULT NULL COMMENT '业务类型(重要)',
`country` VARCHAR(100) DEFAULT NULL COMMENT '国家/地区(重要)',
`address` VARCHAR(255) DEFAULT NULL COMMENT '地址(重要)',
`work_location` VARCHAR(100) DEFAULT NULL COMMENT '工作所在地(重要)',
`id_number` VARCHAR(100) DEFAULT NULL COMMENT '身份证号码(重要)',
`platform` VARCHAR(50) DEFAULT NULL COMMENT '社媒平台(核心)',
`account_id` VARCHAR(200) DEFAULT NULL COMMENT '社媒账号ID(核心)',
`profile_url` VARCHAR(500) DEFAULT NULL COMMENT '主页链接(重要)',
`source_channel` VARCHAR(50) DEFAULT NULL COMMENT '来源渠道',
`source_detail` VARCHAR(255) DEFAULT NULL COMMENT '来源详情',
`converted_type` VARCHAR(20) DEFAULT NULL COMMENT '转换目标类型 companies/persons/...',
`converted_id` VARCHAR(64) DEFAULT NULL COMMENT '转换后目标表ID(非空=已转换/已处理)',
`recorded_by` INT UNSIGNED DEFAULT NULL COMMENT '录入用户',
`label` VARCHAR(50) DEFAULT NULL COMMENT '标签',
`remark` TEXT DEFAULT NULL COMMENT '备注',
`is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '有效 0/1',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '录入时间',
`processed_at` DATETIME DEFAULT NULL COMMENT '处理时间',
PRIMARY KEY (`id`),
KEY `idx_source_type` (`source_type`),
KEY `idx_converted` (`converted_id`),
KEY `idx_is_active` (`is_active`),
KEY `idx_channel` (`source_channel`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='硬数据碎片表';
-- ------------------------------------------------------------
-- 11) 渠道新增计划(定义见 migration_v1.0.18,补 cost 列)
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `channel_plans` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`channel_type` VARCHAR(50) NOT NULL COMMENT '渠道类别(= source_channel 枚举)',
`source_detail` VARCHAR(255) DEFAULT NULL COMMENT '来源详情',
`industry` VARCHAR(100) DEFAULT NULL COMMENT '所属行业',
`cost` DECIMAL(12,2) DEFAULT NULL COMMENT '计划成本/投入',
`start_date` DATE DEFAULT NULL COMMENT '时间窗口开始',
`end_date` DATE DEFAULT NULL COMMENT '时间窗口结束',
`remark` VARCHAR(255) DEFAULT NULL COMMENT '备注说明',
`status` ENUM('待启动','已执行','错过') NOT NULL DEFAULT '待启动' COMMENT '状态反馈',
`is_active` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '启用状态',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_channel_type` (`channel_type`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='渠道新增计划表';
-- ------------------------------------------------------------
-- 12) 系统:用户 / 角色 / 日志 / 登录尝试 / 迁移版本
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `system_users` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL COMMENT '登录账号',
`password` VARCHAR(190) NOT NULL COMMENT '密码(bcrypt)',
`real_name` VARCHAR(100) DEFAULT NULL COMMENT '真实姓名',
`role_id` INT UNSIGNED DEFAULT NULL COMMENT '角色',
`is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '启用 0/1',
`last_login_time` DATETIME DEFAULT NULL COMMENT '最后登录时间',
`last_login_ip` VARCHAR(45) DEFAULT NULL COMMENT '最后登录IP',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`),
KEY `idx_role` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统用户表';
CREATE TABLE IF NOT EXISTS `system_roles` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`role_name` VARCHAR(50) NOT NULL COMMENT '角色名',
`permissions` TEXT DEFAULT NULL COMMENT '权限集(JSON 数组)',
`is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '启用 0/1',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_active` (`is_active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统角色表';
CREATE TABLE IF NOT EXISTS `system_logs` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT UNSIGNED DEFAULT NULL COMMENT '操作用户ID',
`username` VARCHAR(50) DEFAULT NULL COMMENT '操作账号',
`action` VARCHAR(50) DEFAULT NULL COMMENT '操作动作',
`module` VARCHAR(50) DEFAULT NULL COMMENT '操作模块',
`target_table` VARCHAR(50) DEFAULT NULL COMMENT '目标表',
`target_id` INT UNSIGNED DEFAULT NULL COMMENT '目标ID',
`content` TEXT DEFAULT NULL COMMENT '操作内容(JSON)',
`ip` VARCHAR(45) DEFAULT NULL COMMENT '来源IP',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_user` (`user_id`),
KEY `idx_module` (`module`),
KEY `idx_created` (`created_at`),
KEY `idx_target` (`target_table`, `target_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统操作日志表';
CREATE TABLE IF NOT EXISTS `system_login_attempts` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL DEFAULT '',
`ip` VARCHAR(45) NOT NULL DEFAULT '',
`success` TINYINT NOT NULL DEFAULT 0,
`attempt_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_ip_user_time` (`ip`, `username`, `attempt_time`),
KEY `idx_attempt_time` (`attempt_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='登录尝试记录(限流/防爆破)';
CREATE TABLE IF NOT EXISTS `schema_versions` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`version` VARCHAR(64) NOT NULL,
`applied_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`checksum` CHAR(32) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_version` (`version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据库迁移版本表';
-- ------------------------------------------------------------
-- 13) 文档链接(competitor_data / 归档)
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `document_links` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`company_id` INT UNSIGNED DEFAULT NULL COMMENT '关联企业',
`doc_name` VARCHAR(255) DEFAULT NULL COMMENT '文档名称',
`url` VARCHAR(500) DEFAULT NULL COMMENT '链接',
`file_type` VARCHAR(30) DEFAULT NULL COMMENT '类型',
`source` VARCHAR(100) DEFAULT NULL COMMENT '来源',
`publish_date` DATE DEFAULT NULL COMMENT '发布日期',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`is_active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '有效 0/1',
PRIMARY KEY (`id`),
KEY `idx_company` (`company_id`),
KEY `idx_active` (`is_active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='文档链接表';
SET FOREIGN_KEY_CHECKS = 1;