diff --git a/deploy/config.yaml.example b/deploy/config.yaml.example new file mode 100644 index 0000000..7a9ee17 --- /dev/null +++ b/deploy/config.yaml.example @@ -0,0 +1,152 @@ + @echo off + chcp 437 + setlocal enabledelayedexpansion + + set DEPLOY_DIR=%~dp0..\deploy + set DB_NAME=seeyon_fs + + if "%~1"=="" ( + echo Usage: deploy.bat 1/2/3/4 + echo 1=MySQL 2=PostgreSQL 3=SQLServer 4=Oracle + pause >nul + exit /b 1 + ) + set DB_TYPE=%~1 + + echo. + echo ================================ + echo Build DB type: %DB_TYPE% + echo ================================ + echo. + + echo Remove old deploy... + if exist %DEPLOY_DIR% rmdir /s /q %DEPLOY_DIR% + + mkdir %DEPLOY_DIR%\data\storage\hot 2>nul + mkdir %DEPLOY_DIR%\data\storage\cold 2>nul + mkdir %DEPLOY_DIR%\data\storage\public 2>nul + mkdir %DEPLOY_DIR%\data\storage\slave 2>nul + + echo Building... + set GOPROXY=https://goproxy.cn + go build -ldflags="-s -w" -o %DEPLOY_DIR%\server.exe main.go + + if errorlevel 1 ( + echo Build failed + pause >nul + exit /b 1 + ) + + copy config.yaml %DEPLOY_DIR%\config.yaml.example >nul + xcopy /E /I /Q sql %DEPLOY_DIR%\sql >nul + + + :: -------------- start.bat -------------- + ( + echo @echo off + echo cd %%~dp0 + echo if not exist config.yaml ( + echo copy config.yaml.example config.yaml + echo echo Please edit config.yaml first. + echo pause >nul + echo exit /b 1 + echo ^) + echo server.exe + echo pause >nul + ) > %DEPLOY_DIR%\start.bat + + + :: -------------- start.sh -------------- + ( + echo #!/bin/bash + echo cd "$(dirname "$0")" + echo if [ ! -f config.yaml ]; then + echo cp config.yaml.example config.yaml + echo echo "Please edit config.yaml first." + echo exit 1 + echo fi + echo chmod +x server + echo ./server + ) > %DEPLOY_DIR%\start.sh + + + :: -------------- init-db.bat -------------- + ( + echo @echo off + echo cd %%~dp0 + echo echo Database: %DB_NAME% + echo. + ) > %DEPLOY_DIR%\init-db.bat + + if %DB_TYPE%==1 ( + echo set /p "pwd=MySQL root password: " +echo mysql -uroot -p%%pwd% -e "CREATE DATABASE IF NOT EXISTS %DB_NAME%" + echo mysql -uroot -p%%pwd% %DB_NAME% ^< sql\mysql\init.sql + ) >> %DEPLOY_DIR%\init-db.bat + + if %DB_TYPE%==2 ( + echo set /p "pwd=Postgres password: " +echo set PGPASSWORD=%%pwd% +echo psql -U postgres -c "CREATE DATABASE %DB_NAME%" 2^>nul + echo psql -U postgres -d%DB_NAME% -f sql\postgres\init.sql + ) >> %DEPLOY_DIR%\init-db.bat + + if %DB_TYPE%==3 ( + echo set /p "pwd=SQL Server sa password: " +echo sqlcmd -U sa -P %%pwd% -Q "CREATE DATABASE [%DB_NAME%]" + echo sqlcmd -U sa -P %%pwd% -d%DB_NAME% -i sql\sqlserver\init.sql + ) >> %DEPLOY_DIR%\init-db.bat + + if %DB_TYPE%==4 ( + echo echo Oracle: create user/tablespace then run sql/oracle/init.sql + ) >> %DEPLOY_DIR%\init-db.bat + + ( + echo echo. + echo Initialize done. + echo pause >nul + ) >> %DEPLOY_DIR%\init-db.bat + + + :: -------------- init-db.sh -------------- + ( + echo #!/bin/bash + echo cd "$(dirname "$0")" + echo echo "Database: %DB_NAME%" + echo. + ) > %DEPLOY_DIR%\init-db.sh + + if %DB_TYPE%==1 ( + echo read -sp "MySQL password: " pwd +echo echo +echo mysql -uroot -p"$pwd" -e "CREATE DATABASE IF NOT EXISTS %DB_NAME%" + echo mysql -uroot -p"$pwd" %DB_NAME% < sql/mysql/init.sql + ) >> %DEPLOY_DIR%\init-db.sh + + if %DB_TYPE%==2 ( + echo read -sp "Postgres password: " pwd +echo echo +echo export PGPASSWORD="$pwd" + echo psql -U postgres -c "CREATE DATABASE %DB_NAME%" 2>/dev/null + echo psql -U postgres -d%DB_NAME% -f sql/postgres/init.sql + ) >> %DEPLOY_DIR%\init-db.sh + + if %DB_TYPE%==3 ( + echo read -sp "SQL Server sa password: " pwd +echo echo +echo sqlcmd -U sa -P "$pwd" -Q "CREATE DATABASE [%DB_NAME%]" + echo sqlcmd -U sa -P "$pwd" -d%DB_NAME% -i sql/sqlserver/init.sql + ) >> %DEPLOY_DIR%\init-db.sh + + if %DB_TYPE%==4 ( + echo echo "Oracle: create user/tablespace then run sql/oracle/init.sql" + ) >> %DEPLOY_DIR%\init-db.sh + + echo. + echo Build success: %DEPLOY_DIR% + echo. + echo Just run: + echo init-db.bat # 输入一次密码即可 + echo start.bat + echo. + pause >nul \ No newline at end of file diff --git a/deploy/init-db.bat b/deploy/init-db.bat new file mode 100644 index 0000000..0d6e053 --- /dev/null +++ b/deploy/init-db.bat @@ -0,0 +1,6 @@ +@echo off +cd %~dp0 +set /p "db=DB name: " +set /p "sa_pwd=SQLServer sa pwd: " +sqlcmd -S . -U sa -P %sa_pwd% -Q "CREATE DATABASE %db%" +sqlcmd -S . -U sa -P %sa_pwd% -d %db% -i sql\sqlserver\init.sql diff --git a/deploy/server.exe b/deploy/server.exe new file mode 100644 index 0000000..0dd2462 Binary files /dev/null and b/deploy/server.exe differ diff --git a/deploy/sql/mysql/init.sql b/deploy/sql/mysql/init.sql new file mode 100644 index 0000000..29305fa --- /dev/null +++ b/deploy/sql/mysql/init.sql @@ -0,0 +1,281 @@ +-- ============================================= +-- 文件管理系统 - MySQL 初始化脚本 +-- ============================================= + +CREATE DATABASE IF NOT EXISTS seeyon_fs DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +USE seeyon_fs; + +-- ========== 用户与权限 ========== + +CREATE TABLE IF NOT EXISTS fs_user ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + username VARCHAR(64) UNIQUE NOT NULL, + password VARCHAR(256) NOT NULL, + email VARCHAR(128), + nickname VARCHAR(64), + avatar VARCHAR(512), + role VARCHAR(32) DEFAULT 'user', + dept_id BIGINT DEFAULT 0, + status TINYINT DEFAULT 1, + storage_quota BIGINT DEFAULT 10737418240, + used_storage BIGINT DEFAULT 0, + must_change_pwd TINYINT DEFAULT 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_role ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(64) UNIQUE NOT NULL, + display_name VARCHAR(64) NOT NULL, + description VARCHAR(256), + is_system TINYINT DEFAULT 0, + status TINYINT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_permission ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + code VARCHAR(64) UNIQUE NOT NULL, + name VARCHAR(64) NOT NULL, + resource VARCHAR(32) NOT NULL, + action VARCHAR(32) NOT NULL, + description VARCHAR(256) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_role_permission ( + role_id BIGINT NOT NULL, + permission_id BIGINT NOT NULL, + PRIMARY KEY (role_id, permission_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_user_role ( + user_id BIGINT NOT NULL, + role_id BIGINT NOT NULL, + PRIMARY KEY (user_id, role_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== SSO ========== + +CREATE TABLE IF NOT EXISTS fs_sso_provider ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(64) NOT NULL, + type VARCHAR(32) NOT NULL, + display_name VARCHAR(64) NOT NULL, + icon VARCHAR(512), + config JSON, + auto_create TINYINT DEFAULT 1, + default_role VARCHAR(32) DEFAULT 'user', + status TINYINT DEFAULT 1, + sort_order INT DEFAULT 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_sso_session ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + user_id BIGINT NOT NULL, + provider_id BIGINT NOT NULL, + external_id VARCHAR(256) NOT NULL, + access_token VARCHAR(1024), + refresh_token VARCHAR(1024), + expires_at DATETIME, + last_login_at DATETIME, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + INDEX idx_user (user_id), + INDEX idx_provider_external (provider_id, external_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 组织架构 ========== + +CREATE TABLE IF NOT EXISTS fs_department ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + code VARCHAR(64), + parent_id BIGINT DEFAULT 0, + sort_order INT DEFAULT 0, + status TINYINT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 文件管理 ========== + +CREATE TABLE IF NOT EXISTS fs_folder ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + biz_id VARCHAR(128) DEFAULT '', + name VARCHAR(256) NOT NULL, + parent_id BIGINT DEFAULT 0, + owner_id BIGINT NOT NULL, + path VARCHAR(1024) NOT NULL, + status TINYINT DEFAULT 1, + version INT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_parent (parent_id), + INDEX idx_owner (owner_id), + INDEX idx_biz (biz_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_file ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(256) NOT NULL, + extension VARCHAR(32), + folder_id BIGINT NOT NULL, + owner_id BIGINT NOT NULL, + size BIGINT DEFAULT 0, + md5 VARCHAR(32), + sha256 VARCHAR(64), + storage_key VARCHAR(512) NOT NULL, + storage_policy_id BIGINT DEFAULT 1, + mime_type VARCHAR(128), + is_favorite TINYINT DEFAULT 0, + status TINYINT DEFAULT 1, + download_count INT DEFAULT 0, + version INT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_folder (folder_id), + INDEX idx_owner (owner_id), + INDEX idx_md5 (md5), + INDEX idx_status (status) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_file_permission ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + file_id BIGINT NOT NULL, + user_id BIGINT DEFAULT 0, + role_id BIGINT DEFAULT 0, + perm_level VARCHAR(16) DEFAULT 'read', + grant_by BIGINT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + INDEX idx_fp_user_file (user_id, file_id), + INDEX idx_fp_role_file (role_id, file_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_share ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + file_id BIGINT NOT NULL, + owner_id BIGINT NOT NULL, + share_code VARCHAR(32) UNIQUE NOT NULL, + password VARCHAR(64), + expire_at DATETIME, + max_download INT DEFAULT 0, + download_count INT DEFAULT 0, + allow_preview TINYINT DEFAULT 1, + allow_download TINYINT DEFAULT 1, + status TINYINT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 存储策略 ========== + +CREATE TABLE IF NOT EXISTS fs_storage_policy ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(64) NOT NULL, + type VARCHAR(32) NOT NULL, + policy_type VARCHAR(32) DEFAULT '', + config JSON, + status TINYINT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_storage_assignment ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + policy_id BIGINT NOT NULL, + user_id BIGINT DEFAULT 0, + group_id BIGINT DEFAULT 0, + is_default TINYINT DEFAULT 0, + priority INT DEFAULT 0, + storage_quota BIGINT DEFAULT 0, + access_mode VARCHAR(32), + status TINYINT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_policy (policy_id), + INDEX idx_user (user_id), + INDEX idx_group (group_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 开放平台 ========== + +CREATE TABLE IF NOT EXISTS fs_app ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + app_id VARCHAR(64) UNIQUE NOT NULL, + app_secret VARCHAR(128) NOT NULL, + app_name VARCHAR(128) NOT NULL, + status TINYINT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_app_user ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + app_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + INDEX idx_app (app_id), + INDEX idx_user (user_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 分片上传 ========== + +CREATE TABLE IF NOT EXISTS fs_upload_session ( + id VARCHAR(64) PRIMARY KEY, + file_name VARCHAR(256) NOT NULL, + file_size BIGINT NOT NULL, + chunk_size BIGINT NOT NULL, + total_chunks INT NOT NULL, + uploaded INT DEFAULT 0, + md5 VARCHAR(64), + sha256 VARCHAR(64), + folder_id BIGINT DEFAULT 0, + owner_id BIGINT NOT NULL, + policy_id BIGINT DEFAULT 0, + file_id BIGINT DEFAULT 0, + status TINYINT DEFAULT 1, + temp_dir VARCHAR(512), + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 操作日志 ========== + +CREATE TABLE IF NOT EXISTS fs_operation_log ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + user_id BIGINT NOT NULL, + username VARCHAR(64), + action VARCHAR(32) NOT NULL, + resource VARCHAR(32) NOT NULL, + target_id BIGINT DEFAULT 0, + target_name VARCHAR(256), + detail TEXT, + ip VARCHAR(64), + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + INDEX idx_user (user_id), + INDEX idx_created (created_at) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 备份 ========== + +CREATE TABLE IF NOT EXISTS fs_backup_policy ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + type VARCHAR(32) NOT NULL, + config JSON, + status TINYINT DEFAULT 1, + last_run DATETIME, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_backup_log ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + policy_id BIGINT NOT NULL, + status TINYINT DEFAULT 1, + file_path VARCHAR(512), + file_size BIGINT DEFAULT 0, + detail TEXT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + INDEX idx_policy (policy_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/deploy/sql/oracle/init.sql b/deploy/sql/oracle/init.sql new file mode 100644 index 0000000..a7e68b6 --- /dev/null +++ b/deploy/sql/oracle/init.sql @@ -0,0 +1,436 @@ +-- ============================================= +-- 文件管理系统 - Oracle 初始化脚本 +-- 注意: 需要 Oracle 12c+ (IDENTITY 支持) +-- ============================================= + +-- ========== 用户与权限 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_user ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + username VARCHAR2(64) UNIQUE NOT NULL, + password VARCHAR2(256) NOT NULL, + email VARCHAR2(128), + nickname VARCHAR2(64), + avatar VARCHAR2(512), + role VARCHAR2(32) DEFAULT ''user'', + dept_id NUMBER DEFAULT 0, + status NUMBER(3) DEFAULT 1, + storage_quota NUMBER DEFAULT 10737418240, + used_storage NUMBER DEFAULT 0, + must_change_pwd NUMBER(3) DEFAULT 0, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_role ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR2(64) UNIQUE NOT NULL, + display_name VARCHAR2(64) NOT NULL, + description VARCHAR2(256), + is_system NUMBER(3) DEFAULT 0, + status NUMBER(3) DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_permission ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + code VARCHAR2(64) UNIQUE NOT NULL, + name VARCHAR2(64) NOT NULL, + resource VARCHAR2(32) NOT NULL, + action VARCHAR2(32) NOT NULL, + description VARCHAR2(256) + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_role_permission ( + role_id NUMBER NOT NULL, + permission_id NUMBER NOT NULL, + PRIMARY KEY (role_id, permission_id) + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_user_role ( + user_id NUMBER NOT NULL, + role_id NUMBER NOT NULL, + PRIMARY KEY (user_id, role_id) + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== SSO ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_sso_provider ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR2(64) NOT NULL, + type VARCHAR2(32) NOT NULL, + display_name VARCHAR2(64) NOT NULL, + icon VARCHAR2(512), + config CLOB, + auto_create NUMBER(3) DEFAULT 1, + default_role VARCHAR2(32) DEFAULT ''user'', + status NUMBER(3) DEFAULT 1, + sort_order NUMBER DEFAULT 0, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_sso_session ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + user_id NUMBER NOT NULL, + provider_id NUMBER NOT NULL, + external_id VARCHAR2(256) NOT NULL, + access_token VARCHAR2(1024), + refresh_token VARCHAR2(1024), + expires_at TIMESTAMP, + last_login_at TIMESTAMP, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_sso_user ON fs_sso_session(user_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_sso_provider_ext ON fs_sso_session(provider_id, external_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 组织架构 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_department ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR2(128) NOT NULL, + code VARCHAR2(64), + parent_id NUMBER DEFAULT 0, + sort_order NUMBER DEFAULT 0, + status NUMBER(3) DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 文件管理 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_folder ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + biz_id VARCHAR2(128) DEFAULT '''', + name VARCHAR2(256) NOT NULL, + parent_id NUMBER DEFAULT 0, + owner_id NUMBER NOT NULL, + path VARCHAR2(1024) NOT NULL, + status NUMBER(3) DEFAULT 1, + version NUMBER DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_folder_parent ON fs_folder(parent_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_folder_owner ON fs_folder(owner_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_folder_biz ON fs_folder(biz_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_file ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR2(256) NOT NULL, + extension VARCHAR2(32), + folder_id NUMBER NOT NULL, + owner_id NUMBER NOT NULL, + size NUMBER DEFAULT 0, + md5 VARCHAR2(32), + sha256 VARCHAR2(64), + storage_key VARCHAR2(512) NOT NULL, + storage_policy_id NUMBER DEFAULT 1, + mime_type VARCHAR2(128), + is_favorite NUMBER(3) DEFAULT 0, + status NUMBER(3) DEFAULT 1, + download_count NUMBER DEFAULT 0, + version NUMBER DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_file_folder ON fs_file(folder_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_file_owner ON fs_file(owner_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_file_md5 ON fs_file(md5)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_file_permission ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + file_id NUMBER NOT NULL, + user_id NUMBER DEFAULT 0, + role_id NUMBER DEFAULT 0, + perm_level VARCHAR2(16) DEFAULT ''read'', + grant_by NUMBER NOT NULL, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_fp_user_file ON fs_file_permission(user_id, file_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_fp_role_file ON fs_file_permission(role_id, file_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_share ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + file_id NUMBER NOT NULL, + owner_id NUMBER NOT NULL, + share_code VARCHAR2(32) UNIQUE NOT NULL, + password VARCHAR2(64), + expire_at TIMESTAMP, + max_download NUMBER DEFAULT 0, + download_count NUMBER DEFAULT 0, + allow_preview NUMBER(3) DEFAULT 1, + allow_download NUMBER(3) DEFAULT 1, + status NUMBER(3) DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 存储策略 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_storage_policy ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR2(64) NOT NULL, + type VARCHAR2(32) NOT NULL, + policy_type VARCHAR2(32) DEFAULT '''', + config CLOB, + status NUMBER(3) DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_storage_assignment ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + policy_id NUMBER NOT NULL, + user_id NUMBER DEFAULT 0, + group_id NUMBER DEFAULT 0, + is_default NUMBER(3) DEFAULT 0, + priority NUMBER DEFAULT 0, + storage_quota NUMBER DEFAULT 0, + access_mode VARCHAR2(32), + status NUMBER(3) DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_assign_policy ON fs_storage_assignment(policy_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_assign_user ON fs_storage_assignment(user_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_assign_group ON fs_storage_assignment(group_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 开放平台 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_app ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + app_id VARCHAR2(64) UNIQUE NOT NULL, + app_secret VARCHAR2(128) NOT NULL, + app_name VARCHAR2(128) NOT NULL, + status NUMBER(3) DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_app_user ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + app_id NUMBER NOT NULL, + user_id NUMBER NOT NULL, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 分片上传 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_upload_session ( + id VARCHAR2(64) PRIMARY KEY, + file_name VARCHAR2(256) NOT NULL, + file_size NUMBER NOT NULL, + chunk_size NUMBER NOT NULL, + total_chunks NUMBER NOT NULL, + uploaded NUMBER DEFAULT 0, + md5 VARCHAR2(64), + sha256 VARCHAR2(64), + folder_id NUMBER DEFAULT 0, + owner_id NUMBER NOT NULL, + policy_id NUMBER DEFAULT 0, + file_id NUMBER DEFAULT 0, + status NUMBER(3) DEFAULT 1, + temp_dir VARCHAR2(512), + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 操作日志 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_operation_log ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + user_id NUMBER NOT NULL, + username VARCHAR2(64), + action VARCHAR2(32) NOT NULL, + resource VARCHAR2(32) NOT NULL, + target_id NUMBER DEFAULT 0, + target_name VARCHAR2(256), + detail CLOB, + ip VARCHAR2(64), + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_log_user ON fs_operation_log(user_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_log_created ON fs_operation_log(created_at)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 备份 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_backup_policy ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR2(128) NOT NULL, + type VARCHAR2(32) NOT NULL, + config CLOB, + status NUMBER(3) DEFAULT 1, + last_run TIMESTAMP, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_backup_log ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + policy_id NUMBER NOT NULL, + status NUMBER(3) DEFAULT 1, + file_path VARCHAR2(512), + file_size NUMBER DEFAULT 0, + detail CLOB, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_backup_policy ON fs_backup_log(policy_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ diff --git a/deploy/sql/sqlserver/init.sql b/deploy/sql/sqlserver/init.sql new file mode 100644 index 0000000..3d153dc --- /dev/null +++ b/deploy/sql/sqlserver/init.sql @@ -0,0 +1,346 @@ +-- ============================================= +-- 文件管理系统 - SQL Server 初始化脚本 +-- ============================================= + +IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'seeyon_fs') +BEGIN + CREATE DATABASE seeyon_fs; +END +GO + +USE seeyon_fs; +GO + +-- ========== 用户与权限 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_user') +CREATE TABLE fs_user ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + username NVARCHAR(64) UNIQUE NOT NULL, + password NVARCHAR(256) NOT NULL, + email NVARCHAR(128), + nickname NVARCHAR(64), + avatar NVARCHAR(512), + role NVARCHAR(32) DEFAULT 'user', + dept_id BIGINT DEFAULT 0, + status TINYINT DEFAULT 1, + storage_quota BIGINT DEFAULT 10737418240, + used_storage BIGINT DEFAULT 0, + must_change_pwd TINYINT DEFAULT 0, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_role') +CREATE TABLE fs_role ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + name NVARCHAR(64) UNIQUE NOT NULL, + display_name NVARCHAR(64) NOT NULL, + description NVARCHAR(256), + is_system TINYINT DEFAULT 0, + status TINYINT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_permission') +CREATE TABLE fs_permission ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + code NVARCHAR(64) UNIQUE NOT NULL, + name NVARCHAR(64) NOT NULL, + resource NVARCHAR(32) NOT NULL, + action NVARCHAR(32) NOT NULL, + description NVARCHAR(256) +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_role_permission') +CREATE TABLE fs_role_permission ( + role_id BIGINT NOT NULL, + permission_id BIGINT NOT NULL, + PRIMARY KEY (role_id, permission_id) +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_user_role') +CREATE TABLE fs_user_role ( + user_id BIGINT NOT NULL, + role_id BIGINT NOT NULL, + PRIMARY KEY (user_id, role_id) +); +GO + +-- ========== SSO ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_sso_provider') +CREATE TABLE fs_sso_provider ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + name NVARCHAR(64) NOT NULL, + type NVARCHAR(32) NOT NULL, + display_name NVARCHAR(64) NOT NULL, + icon NVARCHAR(512), + config NVARCHAR(MAX), + auto_create TINYINT DEFAULT 1, + default_role NVARCHAR(32) DEFAULT 'user', + status TINYINT DEFAULT 1, + sort_order INT DEFAULT 0, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_sso_session') +CREATE TABLE fs_sso_session ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + user_id BIGINT NOT NULL, + provider_id BIGINT NOT NULL, + external_id NVARCHAR(256) NOT NULL, + access_token NVARCHAR(1024), + refresh_token NVARCHAR(1024), + expires_at DATETIME2, + last_login_at DATETIME2, + created_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_sso_user') + CREATE INDEX idx_sso_user ON fs_sso_session(user_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_sso_provider_ext') + CREATE INDEX idx_sso_provider_ext ON fs_sso_session(provider_id, external_id); +GO + +-- ========== 组织架构 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_department') +CREATE TABLE fs_department ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + name NVARCHAR(128) NOT NULL, + code NVARCHAR(64), + parent_id BIGINT DEFAULT 0, + sort_order INT DEFAULT 0, + status TINYINT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +GO + +-- ========== 文件管理 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_folder') +CREATE TABLE fs_folder ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + biz_id NVARCHAR(128) DEFAULT '', + name NVARCHAR(256) NOT NULL, + parent_id BIGINT DEFAULT 0, + owner_id BIGINT NOT NULL, + path NVARCHAR(1024) NOT NULL, + status TINYINT DEFAULT 1, + version INT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_folder_parent') + CREATE INDEX idx_folder_parent ON fs_folder(parent_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_folder_owner') + CREATE INDEX idx_folder_owner ON fs_folder(owner_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_folder_biz') + CREATE INDEX idx_folder_biz ON fs_folder(biz_id); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_file') +CREATE TABLE fs_file ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + name NVARCHAR(256) NOT NULL, + extension NVARCHAR(32), + folder_id BIGINT NOT NULL, + owner_id BIGINT NOT NULL, + size BIGINT DEFAULT 0, + md5 NVARCHAR(32), + sha256 NVARCHAR(64), + storage_key NVARCHAR(512) NOT NULL, + storage_policy_id BIGINT DEFAULT 1, + mime_type NVARCHAR(128), + is_favorite TINYINT DEFAULT 0, + status TINYINT DEFAULT 1, + download_count INT DEFAULT 0, + version INT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_file_folder') + CREATE INDEX idx_file_folder ON fs_file(folder_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_file_owner') + CREATE INDEX idx_file_owner ON fs_file(owner_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_file_md5') + CREATE INDEX idx_file_md5 ON fs_file(md5); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_file_status') + CREATE INDEX idx_file_status ON fs_file(status); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_file_permission') +CREATE TABLE fs_file_permission ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + file_id BIGINT NOT NULL, + user_id BIGINT DEFAULT 0, + role_id BIGINT DEFAULT 0, + perm_level NVARCHAR(16) DEFAULT 'read', + grant_by BIGINT NOT NULL, + created_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_fp_user_file') + CREATE INDEX idx_fp_user_file ON fs_file_permission(user_id, file_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_fp_role_file') + CREATE INDEX idx_fp_role_file ON fs_file_permission(role_id, file_id); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_share') +CREATE TABLE fs_share ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + file_id BIGINT NOT NULL, + owner_id BIGINT NOT NULL, + share_code NVARCHAR(32) UNIQUE NOT NULL, + password NVARCHAR(64), + expire_at DATETIME2, + max_download INT DEFAULT 0, + download_count INT DEFAULT 0, + allow_preview TINYINT DEFAULT 1, + allow_download TINYINT DEFAULT 1, + status TINYINT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE() +); +GO + +-- ========== 存储策略 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_storage_policy') +CREATE TABLE fs_storage_policy ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + name NVARCHAR(64) NOT NULL, + type NVARCHAR(32) NOT NULL, + policy_type NVARCHAR(32) DEFAULT '', + config NVARCHAR(MAX), + status TINYINT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE() +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_storage_assignment') +CREATE TABLE fs_storage_assignment ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + policy_id BIGINT NOT NULL, + user_id BIGINT DEFAULT 0, + group_id BIGINT DEFAULT 0, + is_default TINYINT DEFAULT 0, + priority INT DEFAULT 0, + storage_quota BIGINT DEFAULT 0, + access_mode NVARCHAR(32), + status TINYINT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_assign_policy') + CREATE INDEX idx_assign_policy ON fs_storage_assignment(policy_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_assign_user') + CREATE INDEX idx_assign_user ON fs_storage_assignment(user_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_assign_group') + CREATE INDEX idx_assign_group ON fs_storage_assignment(group_id); +GO + +-- ========== 开放平台 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_app') +CREATE TABLE fs_app ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + app_id NVARCHAR(64) UNIQUE NOT NULL, + app_secret NVARCHAR(128) NOT NULL, + app_name NVARCHAR(128) NOT NULL, + status TINYINT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_app_user') +CREATE TABLE fs_app_user ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + app_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + created_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_app_user_app') + CREATE INDEX idx_app_user_app ON fs_app_user(app_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_app_user_user') + CREATE INDEX idx_app_user_user ON fs_app_user(user_id); +GO + +-- ========== 分片上传 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_upload_session') +CREATE TABLE fs_upload_session ( + id NVARCHAR(64) PRIMARY KEY, + file_name NVARCHAR(256) NOT NULL, + file_size BIGINT NOT NULL, + chunk_size BIGINT NOT NULL, + total_chunks INT NOT NULL, + uploaded INT DEFAULT 0, + md5 NVARCHAR(64), + sha256 NVARCHAR(64), + folder_id BIGINT DEFAULT 0, + owner_id BIGINT NOT NULL, + policy_id BIGINT DEFAULT 0, + file_id BIGINT DEFAULT 0, + status TINYINT DEFAULT 1, + temp_dir NVARCHAR(512), + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +GO + +-- ========== 操作日志 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_operation_log') +CREATE TABLE fs_operation_log ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + user_id BIGINT NOT NULL, + username NVARCHAR(64), + action NVARCHAR(32) NOT NULL, + resource NVARCHAR(32) NOT NULL, + target_id BIGINT DEFAULT 0, + target_name NVARCHAR(256), + detail NVARCHAR(MAX), + ip NVARCHAR(64), + created_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_log_user') + CREATE INDEX idx_log_user ON fs_operation_log(user_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_log_created') + CREATE INDEX idx_log_created ON fs_operation_log(created_at); +GO + +-- ========== 备份 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_backup_policy') +CREATE TABLE fs_backup_policy ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + name NVARCHAR(128) NOT NULL, + type NVARCHAR(32) NOT NULL, + config NVARCHAR(MAX), + status TINYINT DEFAULT 1, + last_run DATETIME2, + created_at DATETIME2 DEFAULT GETDATE() +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_backup_log') +CREATE TABLE fs_backup_log ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + policy_id BIGINT NOT NULL, + status TINYINT DEFAULT 1, + file_path NVARCHAR(512), + file_size BIGINT DEFAULT 0, + detail NVARCHAR(MAX), + created_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_backup_policy') + CREATE INDEX idx_backup_policy ON fs_backup_log(policy_id); +GO diff --git a/deploy/start.bat b/deploy/start.bat new file mode 100644 index 0000000..6d7f93a --- /dev/null +++ b/deploy/start.bat @@ -0,0 +1,5 @@ +@echo off +cd %~dp0 +if not exist config.yaml copy config.yaml.example config.yaml +server.exe +pause diff --git a/deploy/start.sh b/deploy/start.sh new file mode 100644 index 0000000..15281ba --- /dev/null +++ b/deploy/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash +cd "$(dirname "$0")" +if [ ! -f config.yaml ]; then cp config.yaml.example config.yaml; fi +./server diff --git a/server/myapp b/server/myapp new file mode 100644 index 0000000..a034844 Binary files /dev/null and b/server/myapp differ diff --git a/server/server.exe~ b/server/server.exe~ new file mode 100644 index 0000000..b04c512 Binary files /dev/null and b/server/server.exe~ differ diff --git a/server/sql/mysql/init.sql b/server/sql/mysql/init.sql new file mode 100644 index 0000000..29305fa --- /dev/null +++ b/server/sql/mysql/init.sql @@ -0,0 +1,281 @@ +-- ============================================= +-- 文件管理系统 - MySQL 初始化脚本 +-- ============================================= + +CREATE DATABASE IF NOT EXISTS seeyon_fs DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +USE seeyon_fs; + +-- ========== 用户与权限 ========== + +CREATE TABLE IF NOT EXISTS fs_user ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + username VARCHAR(64) UNIQUE NOT NULL, + password VARCHAR(256) NOT NULL, + email VARCHAR(128), + nickname VARCHAR(64), + avatar VARCHAR(512), + role VARCHAR(32) DEFAULT 'user', + dept_id BIGINT DEFAULT 0, + status TINYINT DEFAULT 1, + storage_quota BIGINT DEFAULT 10737418240, + used_storage BIGINT DEFAULT 0, + must_change_pwd TINYINT DEFAULT 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_role ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(64) UNIQUE NOT NULL, + display_name VARCHAR(64) NOT NULL, + description VARCHAR(256), + is_system TINYINT DEFAULT 0, + status TINYINT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_permission ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + code VARCHAR(64) UNIQUE NOT NULL, + name VARCHAR(64) NOT NULL, + resource VARCHAR(32) NOT NULL, + action VARCHAR(32) NOT NULL, + description VARCHAR(256) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_role_permission ( + role_id BIGINT NOT NULL, + permission_id BIGINT NOT NULL, + PRIMARY KEY (role_id, permission_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_user_role ( + user_id BIGINT NOT NULL, + role_id BIGINT NOT NULL, + PRIMARY KEY (user_id, role_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== SSO ========== + +CREATE TABLE IF NOT EXISTS fs_sso_provider ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(64) NOT NULL, + type VARCHAR(32) NOT NULL, + display_name VARCHAR(64) NOT NULL, + icon VARCHAR(512), + config JSON, + auto_create TINYINT DEFAULT 1, + default_role VARCHAR(32) DEFAULT 'user', + status TINYINT DEFAULT 1, + sort_order INT DEFAULT 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_sso_session ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + user_id BIGINT NOT NULL, + provider_id BIGINT NOT NULL, + external_id VARCHAR(256) NOT NULL, + access_token VARCHAR(1024), + refresh_token VARCHAR(1024), + expires_at DATETIME, + last_login_at DATETIME, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + INDEX idx_user (user_id), + INDEX idx_provider_external (provider_id, external_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 组织架构 ========== + +CREATE TABLE IF NOT EXISTS fs_department ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + code VARCHAR(64), + parent_id BIGINT DEFAULT 0, + sort_order INT DEFAULT 0, + status TINYINT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 文件管理 ========== + +CREATE TABLE IF NOT EXISTS fs_folder ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + biz_id VARCHAR(128) DEFAULT '', + name VARCHAR(256) NOT NULL, + parent_id BIGINT DEFAULT 0, + owner_id BIGINT NOT NULL, + path VARCHAR(1024) NOT NULL, + status TINYINT DEFAULT 1, + version INT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_parent (parent_id), + INDEX idx_owner (owner_id), + INDEX idx_biz (biz_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_file ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(256) NOT NULL, + extension VARCHAR(32), + folder_id BIGINT NOT NULL, + owner_id BIGINT NOT NULL, + size BIGINT DEFAULT 0, + md5 VARCHAR(32), + sha256 VARCHAR(64), + storage_key VARCHAR(512) NOT NULL, + storage_policy_id BIGINT DEFAULT 1, + mime_type VARCHAR(128), + is_favorite TINYINT DEFAULT 0, + status TINYINT DEFAULT 1, + download_count INT DEFAULT 0, + version INT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_folder (folder_id), + INDEX idx_owner (owner_id), + INDEX idx_md5 (md5), + INDEX idx_status (status) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_file_permission ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + file_id BIGINT NOT NULL, + user_id BIGINT DEFAULT 0, + role_id BIGINT DEFAULT 0, + perm_level VARCHAR(16) DEFAULT 'read', + grant_by BIGINT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + INDEX idx_fp_user_file (user_id, file_id), + INDEX idx_fp_role_file (role_id, file_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_share ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + file_id BIGINT NOT NULL, + owner_id BIGINT NOT NULL, + share_code VARCHAR(32) UNIQUE NOT NULL, + password VARCHAR(64), + expire_at DATETIME, + max_download INT DEFAULT 0, + download_count INT DEFAULT 0, + allow_preview TINYINT DEFAULT 1, + allow_download TINYINT DEFAULT 1, + status TINYINT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 存储策略 ========== + +CREATE TABLE IF NOT EXISTS fs_storage_policy ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(64) NOT NULL, + type VARCHAR(32) NOT NULL, + policy_type VARCHAR(32) DEFAULT '', + config JSON, + status TINYINT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_storage_assignment ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + policy_id BIGINT NOT NULL, + user_id BIGINT DEFAULT 0, + group_id BIGINT DEFAULT 0, + is_default TINYINT DEFAULT 0, + priority INT DEFAULT 0, + storage_quota BIGINT DEFAULT 0, + access_mode VARCHAR(32), + status TINYINT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_policy (policy_id), + INDEX idx_user (user_id), + INDEX idx_group (group_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 开放平台 ========== + +CREATE TABLE IF NOT EXISTS fs_app ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + app_id VARCHAR(64) UNIQUE NOT NULL, + app_secret VARCHAR(128) NOT NULL, + app_name VARCHAR(128) NOT NULL, + status TINYINT DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_app_user ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + app_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + INDEX idx_app (app_id), + INDEX idx_user (user_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 分片上传 ========== + +CREATE TABLE IF NOT EXISTS fs_upload_session ( + id VARCHAR(64) PRIMARY KEY, + file_name VARCHAR(256) NOT NULL, + file_size BIGINT NOT NULL, + chunk_size BIGINT NOT NULL, + total_chunks INT NOT NULL, + uploaded INT DEFAULT 0, + md5 VARCHAR(64), + sha256 VARCHAR(64), + folder_id BIGINT DEFAULT 0, + owner_id BIGINT NOT NULL, + policy_id BIGINT DEFAULT 0, + file_id BIGINT DEFAULT 0, + status TINYINT DEFAULT 1, + temp_dir VARCHAR(512), + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 操作日志 ========== + +CREATE TABLE IF NOT EXISTS fs_operation_log ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + user_id BIGINT NOT NULL, + username VARCHAR(64), + action VARCHAR(32) NOT NULL, + resource VARCHAR(32) NOT NULL, + target_id BIGINT DEFAULT 0, + target_name VARCHAR(256), + detail TEXT, + ip VARCHAR(64), + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + INDEX idx_user (user_id), + INDEX idx_created (created_at) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ========== 备份 ========== + +CREATE TABLE IF NOT EXISTS fs_backup_policy ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + type VARCHAR(32) NOT NULL, + config JSON, + status TINYINT DEFAULT 1, + last_run DATETIME, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS fs_backup_log ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + policy_id BIGINT NOT NULL, + status TINYINT DEFAULT 1, + file_path VARCHAR(512), + file_size BIGINT DEFAULT 0, + detail TEXT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + INDEX idx_policy (policy_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/server/sql/oracle/init.sql b/server/sql/oracle/init.sql new file mode 100644 index 0000000..a7e68b6 --- /dev/null +++ b/server/sql/oracle/init.sql @@ -0,0 +1,436 @@ +-- ============================================= +-- 文件管理系统 - Oracle 初始化脚本 +-- 注意: 需要 Oracle 12c+ (IDENTITY 支持) +-- ============================================= + +-- ========== 用户与权限 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_user ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + username VARCHAR2(64) UNIQUE NOT NULL, + password VARCHAR2(256) NOT NULL, + email VARCHAR2(128), + nickname VARCHAR2(64), + avatar VARCHAR2(512), + role VARCHAR2(32) DEFAULT ''user'', + dept_id NUMBER DEFAULT 0, + status NUMBER(3) DEFAULT 1, + storage_quota NUMBER DEFAULT 10737418240, + used_storage NUMBER DEFAULT 0, + must_change_pwd NUMBER(3) DEFAULT 0, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_role ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR2(64) UNIQUE NOT NULL, + display_name VARCHAR2(64) NOT NULL, + description VARCHAR2(256), + is_system NUMBER(3) DEFAULT 0, + status NUMBER(3) DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_permission ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + code VARCHAR2(64) UNIQUE NOT NULL, + name VARCHAR2(64) NOT NULL, + resource VARCHAR2(32) NOT NULL, + action VARCHAR2(32) NOT NULL, + description VARCHAR2(256) + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_role_permission ( + role_id NUMBER NOT NULL, + permission_id NUMBER NOT NULL, + PRIMARY KEY (role_id, permission_id) + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_user_role ( + user_id NUMBER NOT NULL, + role_id NUMBER NOT NULL, + PRIMARY KEY (user_id, role_id) + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== SSO ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_sso_provider ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR2(64) NOT NULL, + type VARCHAR2(32) NOT NULL, + display_name VARCHAR2(64) NOT NULL, + icon VARCHAR2(512), + config CLOB, + auto_create NUMBER(3) DEFAULT 1, + default_role VARCHAR2(32) DEFAULT ''user'', + status NUMBER(3) DEFAULT 1, + sort_order NUMBER DEFAULT 0, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_sso_session ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + user_id NUMBER NOT NULL, + provider_id NUMBER NOT NULL, + external_id VARCHAR2(256) NOT NULL, + access_token VARCHAR2(1024), + refresh_token VARCHAR2(1024), + expires_at TIMESTAMP, + last_login_at TIMESTAMP, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_sso_user ON fs_sso_session(user_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_sso_provider_ext ON fs_sso_session(provider_id, external_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 组织架构 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_department ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR2(128) NOT NULL, + code VARCHAR2(64), + parent_id NUMBER DEFAULT 0, + sort_order NUMBER DEFAULT 0, + status NUMBER(3) DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 文件管理 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_folder ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + biz_id VARCHAR2(128) DEFAULT '''', + name VARCHAR2(256) NOT NULL, + parent_id NUMBER DEFAULT 0, + owner_id NUMBER NOT NULL, + path VARCHAR2(1024) NOT NULL, + status NUMBER(3) DEFAULT 1, + version NUMBER DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_folder_parent ON fs_folder(parent_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_folder_owner ON fs_folder(owner_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_folder_biz ON fs_folder(biz_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_file ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR2(256) NOT NULL, + extension VARCHAR2(32), + folder_id NUMBER NOT NULL, + owner_id NUMBER NOT NULL, + size NUMBER DEFAULT 0, + md5 VARCHAR2(32), + sha256 VARCHAR2(64), + storage_key VARCHAR2(512) NOT NULL, + storage_policy_id NUMBER DEFAULT 1, + mime_type VARCHAR2(128), + is_favorite NUMBER(3) DEFAULT 0, + status NUMBER(3) DEFAULT 1, + download_count NUMBER DEFAULT 0, + version NUMBER DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_file_folder ON fs_file(folder_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_file_owner ON fs_file(owner_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_file_md5 ON fs_file(md5)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_file_permission ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + file_id NUMBER NOT NULL, + user_id NUMBER DEFAULT 0, + role_id NUMBER DEFAULT 0, + perm_level VARCHAR2(16) DEFAULT ''read'', + grant_by NUMBER NOT NULL, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_fp_user_file ON fs_file_permission(user_id, file_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_fp_role_file ON fs_file_permission(role_id, file_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_share ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + file_id NUMBER NOT NULL, + owner_id NUMBER NOT NULL, + share_code VARCHAR2(32) UNIQUE NOT NULL, + password VARCHAR2(64), + expire_at TIMESTAMP, + max_download NUMBER DEFAULT 0, + download_count NUMBER DEFAULT 0, + allow_preview NUMBER(3) DEFAULT 1, + allow_download NUMBER(3) DEFAULT 1, + status NUMBER(3) DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 存储策略 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_storage_policy ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR2(64) NOT NULL, + type VARCHAR2(32) NOT NULL, + policy_type VARCHAR2(32) DEFAULT '''', + config CLOB, + status NUMBER(3) DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_storage_assignment ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + policy_id NUMBER NOT NULL, + user_id NUMBER DEFAULT 0, + group_id NUMBER DEFAULT 0, + is_default NUMBER(3) DEFAULT 0, + priority NUMBER DEFAULT 0, + storage_quota NUMBER DEFAULT 0, + access_mode VARCHAR2(32), + status NUMBER(3) DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_assign_policy ON fs_storage_assignment(policy_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_assign_user ON fs_storage_assignment(user_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_assign_group ON fs_storage_assignment(group_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 开放平台 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_app ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + app_id VARCHAR2(64) UNIQUE NOT NULL, + app_secret VARCHAR2(128) NOT NULL, + app_name VARCHAR2(128) NOT NULL, + status NUMBER(3) DEFAULT 1, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_app_user ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + app_id NUMBER NOT NULL, + user_id NUMBER NOT NULL, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 分片上传 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_upload_session ( + id VARCHAR2(64) PRIMARY KEY, + file_name VARCHAR2(256) NOT NULL, + file_size NUMBER NOT NULL, + chunk_size NUMBER NOT NULL, + total_chunks NUMBER NOT NULL, + uploaded NUMBER DEFAULT 0, + md5 VARCHAR2(64), + sha256 VARCHAR2(64), + folder_id NUMBER DEFAULT 0, + owner_id NUMBER NOT NULL, + policy_id NUMBER DEFAULT 0, + file_id NUMBER DEFAULT 0, + status NUMBER(3) DEFAULT 1, + temp_dir VARCHAR2(512), + created_at TIMESTAMP DEFAULT SYSTIMESTAMP, + updated_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 操作日志 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_operation_log ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + user_id NUMBER NOT NULL, + username VARCHAR2(64), + action VARCHAR2(32) NOT NULL, + resource VARCHAR2(32) NOT NULL, + target_id NUMBER DEFAULT 0, + target_name VARCHAR2(256), + detail CLOB, + ip VARCHAR2(64), + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_log_user ON fs_operation_log(user_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_log_created ON fs_operation_log(created_at)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +-- ========== 备份 ========== + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_backup_policy ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR2(128) NOT NULL, + type VARCHAR2(32) NOT NULL, + config CLOB, + status NUMBER(3) DEFAULT 1, + last_run TIMESTAMP, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE TABLE fs_backup_log ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + policy_id NUMBER NOT NULL, + status NUMBER(3) DEFAULT 1, + file_path VARCHAR2(512), + file_size NUMBER DEFAULT 0, + detail CLOB, + created_at TIMESTAMP DEFAULT SYSTIMESTAMP + )'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ + +BEGIN + EXECUTE IMMEDIATE 'CREATE INDEX idx_backup_policy ON fs_backup_log(policy_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; +END; +/ diff --git a/server/sql/sqlserver/init.sql b/server/sql/sqlserver/init.sql new file mode 100644 index 0000000..3d153dc --- /dev/null +++ b/server/sql/sqlserver/init.sql @@ -0,0 +1,346 @@ +-- ============================================= +-- 文件管理系统 - SQL Server 初始化脚本 +-- ============================================= + +IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'seeyon_fs') +BEGIN + CREATE DATABASE seeyon_fs; +END +GO + +USE seeyon_fs; +GO + +-- ========== 用户与权限 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_user') +CREATE TABLE fs_user ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + username NVARCHAR(64) UNIQUE NOT NULL, + password NVARCHAR(256) NOT NULL, + email NVARCHAR(128), + nickname NVARCHAR(64), + avatar NVARCHAR(512), + role NVARCHAR(32) DEFAULT 'user', + dept_id BIGINT DEFAULT 0, + status TINYINT DEFAULT 1, + storage_quota BIGINT DEFAULT 10737418240, + used_storage BIGINT DEFAULT 0, + must_change_pwd TINYINT DEFAULT 0, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_role') +CREATE TABLE fs_role ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + name NVARCHAR(64) UNIQUE NOT NULL, + display_name NVARCHAR(64) NOT NULL, + description NVARCHAR(256), + is_system TINYINT DEFAULT 0, + status TINYINT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_permission') +CREATE TABLE fs_permission ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + code NVARCHAR(64) UNIQUE NOT NULL, + name NVARCHAR(64) NOT NULL, + resource NVARCHAR(32) NOT NULL, + action NVARCHAR(32) NOT NULL, + description NVARCHAR(256) +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_role_permission') +CREATE TABLE fs_role_permission ( + role_id BIGINT NOT NULL, + permission_id BIGINT NOT NULL, + PRIMARY KEY (role_id, permission_id) +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_user_role') +CREATE TABLE fs_user_role ( + user_id BIGINT NOT NULL, + role_id BIGINT NOT NULL, + PRIMARY KEY (user_id, role_id) +); +GO + +-- ========== SSO ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_sso_provider') +CREATE TABLE fs_sso_provider ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + name NVARCHAR(64) NOT NULL, + type NVARCHAR(32) NOT NULL, + display_name NVARCHAR(64) NOT NULL, + icon NVARCHAR(512), + config NVARCHAR(MAX), + auto_create TINYINT DEFAULT 1, + default_role NVARCHAR(32) DEFAULT 'user', + status TINYINT DEFAULT 1, + sort_order INT DEFAULT 0, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_sso_session') +CREATE TABLE fs_sso_session ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + user_id BIGINT NOT NULL, + provider_id BIGINT NOT NULL, + external_id NVARCHAR(256) NOT NULL, + access_token NVARCHAR(1024), + refresh_token NVARCHAR(1024), + expires_at DATETIME2, + last_login_at DATETIME2, + created_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_sso_user') + CREATE INDEX idx_sso_user ON fs_sso_session(user_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_sso_provider_ext') + CREATE INDEX idx_sso_provider_ext ON fs_sso_session(provider_id, external_id); +GO + +-- ========== 组织架构 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_department') +CREATE TABLE fs_department ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + name NVARCHAR(128) NOT NULL, + code NVARCHAR(64), + parent_id BIGINT DEFAULT 0, + sort_order INT DEFAULT 0, + status TINYINT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +GO + +-- ========== 文件管理 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_folder') +CREATE TABLE fs_folder ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + biz_id NVARCHAR(128) DEFAULT '', + name NVARCHAR(256) NOT NULL, + parent_id BIGINT DEFAULT 0, + owner_id BIGINT NOT NULL, + path NVARCHAR(1024) NOT NULL, + status TINYINT DEFAULT 1, + version INT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_folder_parent') + CREATE INDEX idx_folder_parent ON fs_folder(parent_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_folder_owner') + CREATE INDEX idx_folder_owner ON fs_folder(owner_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_folder_biz') + CREATE INDEX idx_folder_biz ON fs_folder(biz_id); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_file') +CREATE TABLE fs_file ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + name NVARCHAR(256) NOT NULL, + extension NVARCHAR(32), + folder_id BIGINT NOT NULL, + owner_id BIGINT NOT NULL, + size BIGINT DEFAULT 0, + md5 NVARCHAR(32), + sha256 NVARCHAR(64), + storage_key NVARCHAR(512) NOT NULL, + storage_policy_id BIGINT DEFAULT 1, + mime_type NVARCHAR(128), + is_favorite TINYINT DEFAULT 0, + status TINYINT DEFAULT 1, + download_count INT DEFAULT 0, + version INT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_file_folder') + CREATE INDEX idx_file_folder ON fs_file(folder_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_file_owner') + CREATE INDEX idx_file_owner ON fs_file(owner_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_file_md5') + CREATE INDEX idx_file_md5 ON fs_file(md5); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_file_status') + CREATE INDEX idx_file_status ON fs_file(status); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_file_permission') +CREATE TABLE fs_file_permission ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + file_id BIGINT NOT NULL, + user_id BIGINT DEFAULT 0, + role_id BIGINT DEFAULT 0, + perm_level NVARCHAR(16) DEFAULT 'read', + grant_by BIGINT NOT NULL, + created_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_fp_user_file') + CREATE INDEX idx_fp_user_file ON fs_file_permission(user_id, file_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_fp_role_file') + CREATE INDEX idx_fp_role_file ON fs_file_permission(role_id, file_id); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_share') +CREATE TABLE fs_share ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + file_id BIGINT NOT NULL, + owner_id BIGINT NOT NULL, + share_code NVARCHAR(32) UNIQUE NOT NULL, + password NVARCHAR(64), + expire_at DATETIME2, + max_download INT DEFAULT 0, + download_count INT DEFAULT 0, + allow_preview TINYINT DEFAULT 1, + allow_download TINYINT DEFAULT 1, + status TINYINT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE() +); +GO + +-- ========== 存储策略 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_storage_policy') +CREATE TABLE fs_storage_policy ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + name NVARCHAR(64) NOT NULL, + type NVARCHAR(32) NOT NULL, + policy_type NVARCHAR(32) DEFAULT '', + config NVARCHAR(MAX), + status TINYINT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE() +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_storage_assignment') +CREATE TABLE fs_storage_assignment ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + policy_id BIGINT NOT NULL, + user_id BIGINT DEFAULT 0, + group_id BIGINT DEFAULT 0, + is_default TINYINT DEFAULT 0, + priority INT DEFAULT 0, + storage_quota BIGINT DEFAULT 0, + access_mode NVARCHAR(32), + status TINYINT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_assign_policy') + CREATE INDEX idx_assign_policy ON fs_storage_assignment(policy_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_assign_user') + CREATE INDEX idx_assign_user ON fs_storage_assignment(user_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_assign_group') + CREATE INDEX idx_assign_group ON fs_storage_assignment(group_id); +GO + +-- ========== 开放平台 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_app') +CREATE TABLE fs_app ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + app_id NVARCHAR(64) UNIQUE NOT NULL, + app_secret NVARCHAR(128) NOT NULL, + app_name NVARCHAR(128) NOT NULL, + status TINYINT DEFAULT 1, + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_app_user') +CREATE TABLE fs_app_user ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + app_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + created_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_app_user_app') + CREATE INDEX idx_app_user_app ON fs_app_user(app_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_app_user_user') + CREATE INDEX idx_app_user_user ON fs_app_user(user_id); +GO + +-- ========== 分片上传 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_upload_session') +CREATE TABLE fs_upload_session ( + id NVARCHAR(64) PRIMARY KEY, + file_name NVARCHAR(256) NOT NULL, + file_size BIGINT NOT NULL, + chunk_size BIGINT NOT NULL, + total_chunks INT NOT NULL, + uploaded INT DEFAULT 0, + md5 NVARCHAR(64), + sha256 NVARCHAR(64), + folder_id BIGINT DEFAULT 0, + owner_id BIGINT NOT NULL, + policy_id BIGINT DEFAULT 0, + file_id BIGINT DEFAULT 0, + status TINYINT DEFAULT 1, + temp_dir NVARCHAR(512), + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 DEFAULT GETDATE() +); +GO + +-- ========== 操作日志 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_operation_log') +CREATE TABLE fs_operation_log ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + user_id BIGINT NOT NULL, + username NVARCHAR(64), + action NVARCHAR(32) NOT NULL, + resource NVARCHAR(32) NOT NULL, + target_id BIGINT DEFAULT 0, + target_name NVARCHAR(256), + detail NVARCHAR(MAX), + ip NVARCHAR(64), + created_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_log_user') + CREATE INDEX idx_log_user ON fs_operation_log(user_id); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_log_created') + CREATE INDEX idx_log_created ON fs_operation_log(created_at); +GO + +-- ========== 备份 ========== + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_backup_policy') +CREATE TABLE fs_backup_policy ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + name NVARCHAR(128) NOT NULL, + type NVARCHAR(32) NOT NULL, + config NVARCHAR(MAX), + status TINYINT DEFAULT 1, + last_run DATETIME2, + created_at DATETIME2 DEFAULT GETDATE() +); +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'fs_backup_log') +CREATE TABLE fs_backup_log ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + policy_id BIGINT NOT NULL, + status TINYINT DEFAULT 1, + file_path NVARCHAR(512), + file_size BIGINT DEFAULT 0, + detail NVARCHAR(MAX), + created_at DATETIME2 DEFAULT GETDATE() +); +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_backup_policy') + CREATE INDEX idx_backup_policy ON fs_backup_log(policy_id); +GO diff --git a/server/utils/jwt.go b/server/utils/jwt.go index c219af1..0391d8b 100644 --- a/server/utils/jwt.go +++ b/server/utils/jwt.go @@ -43,6 +43,16 @@ func ParseToken(tokenString, secret string) (*JWTClaims, error) { } if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid { + jsonBytes, err := json.MarshalIndent(claims, "", " ") // MarshalIndent 用于格式化输出,更易读 + if err != nil { + // 记录序列化错误,但不一定中断业务逻辑,视需求而定 + log.Printf("Failed to marshal claims to JSON: %v", err) + } else { + // 2. 在控制台输出 JSON 字符串 + fmt.Println("=== Decoded JWT Claims ===") + fmt.Println(string(jsonBytes)) + fmt.Println("==========================") + } return claims, nil }