feat(部署): 新增 deployment/ 内外网两套按侧部署包
按 demo/ 的写法把交付包改成「角色由目录决定」:iw/ 拷内网机、ow/ 拷外网机, 各自含镜像 tar、SQL、配置与 install.sh,install.sh 不再收 iw/ow 参数。 前端不再打进镜像,改为静态包放在 <侧>/web/ 只读挂进 nginx:1.27-alpine, 现场临时改页面直接替换文件 + restart web 即可。数据仍全部挂宿主机, 子目录命名与 deploy/offline 一致(pgdata/redis/mq/upload/logs/gate), 默认根改为包内 ./volumes,放数据盘只改 .env 的 SFILE_DATA_ROOT。 后端镜像 sfile-app:1.0.1 含传输优化那一批(实测组包 11.4×、解包 9.9×)。 出包脚本 deployment/scripts/build-package.sh 负责 jar→镜像→前端双包→sql→tar→VERSION。
This commit is contained in:
71
deployment/iw/.env
Normal file
71
deployment/iw/.env
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# s-file 部署配置 —— 内网机(iw)
|
||||||
|
#
|
||||||
|
# 装机后必须立刻改的两处:admin 登录口令(首次登录后在页面上改)、
|
||||||
|
# 新用户初始密码 USER_DEFAULT_PASSWORD
|
||||||
|
# 下面的库/MQ 口令是出厂默认值,交付单要抄一份并建议现场轮换。
|
||||||
|
# 现场改过的 .env 属于该台机器的实际配置,不要提交回仓库。
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# ---------- 本机角色(内网机固定 iw,别改) ----------
|
||||||
|
SFILE_ROLE=iw
|
||||||
|
# 传输方向:内网机 1 / 外网机 2,写反了摆渡方向就反了
|
||||||
|
SFILE_TRANSFER_LOCATION=1
|
||||||
|
|
||||||
|
# ---------- 镜像(images/ 里的 tar docker load 后就是这些 tag) ----------
|
||||||
|
APP_IMAGE=sfile-app:1.1.0
|
||||||
|
NGINX_IMAGE=nginx:1.27-alpine
|
||||||
|
PG_IMAGE=postgres:18
|
||||||
|
REDIS_IMAGE=redis:8
|
||||||
|
MQ_IMAGE=rabbitmq:3.13-management-alpine
|
||||||
|
# postgres 18+ 数据目录挂载点是 /var/lib/postgresql,15- 要改成 /var/lib/postgresql/data
|
||||||
|
PG_DATA_DIR=/var/lib/postgresql
|
||||||
|
|
||||||
|
# ---------- 对外访问:只暴露前端 ----------
|
||||||
|
WEB_HOST=0.0.0.0
|
||||||
|
WEB_PORT=80
|
||||||
|
|
||||||
|
# ---------- 口令与密钥 ----------
|
||||||
|
POSTGRES_DB=s_file
|
||||||
|
POSTGRES_USER=sfile
|
||||||
|
POSTGRES_PASSWORD=Sfile-iw-Pg-N1tOz1MxgdaS
|
||||||
|
MQ_USER=sfile
|
||||||
|
MQ_PASSWORD=Sfile-iw-Mq-UTqVSnCDZ0LB
|
||||||
|
JWT_SECRET=86a6b015f3292eb3fdab298d3eced941da4276d47e24e924b82ab8adee397d70
|
||||||
|
USER_DEFAULT_PASSWORD=Sfile-iw-Usr-FBLS-0fA
|
||||||
|
|
||||||
|
# ---------- 发号器与容器网段(与外网机各用一段,同机并跑时才需要错开) ----------
|
||||||
|
APP_SUBNET=172.30.18.0/24
|
||||||
|
APP_GATEWAY=172.30.18.1
|
||||||
|
APP_NODE_IP=172.30.18.10
|
||||||
|
APP_WORK_ID=1
|
||||||
|
|
||||||
|
# ---------- 宿主机数据目录 ----------
|
||||||
|
# 默认落在本目录 volumes/ 下(相对 docker-compose.yml)。
|
||||||
|
# 要放到独立数据盘就改成绝对路径,例如 /data/sfile,改完 install.sh 会自动建目录
|
||||||
|
SFILE_DATA_ROOT=./volumes
|
||||||
|
# 光闸摆渡目录:out = 本机发出,in = 本机收到。
|
||||||
|
# 光闸设备要能访问到这两个路径,现场通常改成绝对路径并告知光闸厂商
|
||||||
|
GATE_SEND_DIR=./volumes/gate/out
|
||||||
|
GATE_RECV_DIR=./volumes/gate/in
|
||||||
|
|
||||||
|
# ---------- MeshSafe 文件安全检测 ----------
|
||||||
|
# 该侧没有部署 MeshSafe 就把 MESHSAFE_ENABLED 改成 false,下面几项可以不管
|
||||||
|
# 启用时凭证必须与 MeshSafe 侧 MESHSAFE_API_CLIENTS 白名单里的 client_id:secret 逐字一致
|
||||||
|
MESHSAFE_ENABLED=true
|
||||||
|
MESHSAFE_BASE_URL=http://host.docker.internal:44380
|
||||||
|
MESHSAFE_CLIENT_ID=sfile-iw
|
||||||
|
MESHSAFE_SECRET=CHANGE_ME_meshsafe_secret
|
||||||
|
MESHSAFE_CHANNEL=sfile-iw
|
||||||
|
# 等保从严建议 false:检测服务不可用时阻断而不是放行
|
||||||
|
MESHSAFE_FAIL_OPEN=true
|
||||||
|
MESHSAFE_TIMEOUT_SECONDS=120
|
||||||
|
MESHSAFE_POLL_TIMEOUT_MINUTES=60
|
||||||
|
MESHSAFE_POLL_CRON=0/10 * * * * ?
|
||||||
|
|
||||||
|
# ---------- 资源与运行时 ----------
|
||||||
|
TZ=Asia/Shanghai
|
||||||
|
APP_JAVA_OPTS=-Xms1g -Xmx3g -Dfile.encoding=UTF-8
|
||||||
|
REDIS_MAXMEMORY=512mb
|
||||||
|
# 摆渡目录监听周期。改这个要同步改 config/application.yml 的 round-budget-seconds(留 1 秒余量)
|
||||||
|
FILE_TRANSFER_MONITOR_CRON=0/5 * * * * ?
|
||||||
8
deployment/iw/.gitignore
vendored
Normal file
8
deployment/iw/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# 镜像 tar 是出包产物(约 640MB),不进 git
|
||||||
|
images/*.tar
|
||||||
|
images/SHA256SUMS.txt
|
||||||
|
dist/
|
||||||
|
|
||||||
|
# volumes/ 是运行时数据(pgdata / redis / mq / upload / logs / gate),不进 git
|
||||||
|
# 前端静态包在 web/,属于交付物,要进 git
|
||||||
|
volumes/
|
||||||
111
deployment/iw/README.md
Normal file
111
deployment/iw/README.md
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# s-file 内网机部署包(iw)
|
||||||
|
|
||||||
|
本目录**就是**一台内网服务器的完整部署包:镜像 tar、前端静态包、SQL、配置、安装脚本都在里面,
|
||||||
|
整目录拷到内网机即可装机,不需要联网、不需要回仓库取任何东西。
|
||||||
|
|
||||||
|
外网机用同级的 `../ow/`,两份除了 `.env` 与 `web/`(前端内/外网包)之外完全一样。
|
||||||
|
完整拓扑、两侧差异表、已知坑见仓库里的 [`../部署说明.md`](../部署说明.md)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 装机(三步)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1) 整目录拷到内网机,例如 /opt/sfile-iw
|
||||||
|
cd /opt/sfile-iw
|
||||||
|
|
||||||
|
# 2) 改配置:至少确认 MeshSafe(没接检测就把 MESHSAFE_ENABLED 改成 false)
|
||||||
|
vi .env
|
||||||
|
|
||||||
|
# 3) 一键装:自检 -> 校验并载入镜像 -> 建数据目录 -> 起栈 -> 等健康
|
||||||
|
./scripts/install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
装完会打印访问地址 `http://<本机IP>:<WEB_PORT>`。**首次登录后立刻改掉 admin 的初始口令。**
|
||||||
|
|
||||||
|
重复执行 `install.sh` 是安全的:只重建有差异的容器,不动已初始化好的数据库。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 目录说明
|
||||||
|
|
||||||
|
```
|
||||||
|
├── docker-compose.yml 5 个服务(web/app/pg/redis/mq),现场不改
|
||||||
|
├── .env 本机全部可变项:角色/端口/口令/目录/MeshSafe ← 只改这个
|
||||||
|
├── config/application.yml 后端静态默认配置,不放任何口令(口令走 .env 注入)
|
||||||
|
├── nginx/web.conf 前端站点 + /api 反代,改端口/上传上限时看这里
|
||||||
|
├── web/ 前端静态包(内网包),挂进 nginx 当站点根
|
||||||
|
├── sql/01-init-table.sql 全量建表 02-init-data.sql 初始数据(admin、机构、平台编码)
|
||||||
|
├── sql/upgrade/ 已上线老库的增量脚本,新装不用跑(见 sql/README.md)
|
||||||
|
├── images/*.tar 5 个镜像 + SHA256SUMS.txt
|
||||||
|
├── scripts/install.sh 一键安装
|
||||||
|
└── volumes/ 运行时数据,install.sh 自动创建
|
||||||
|
├── pgdata/ redis/ mq/ 三个中间件的数据
|
||||||
|
├── upload/ 用户上传的文件本体
|
||||||
|
├── logs/ 后端日志(logs/nginx 是前端访问日志)
|
||||||
|
└── gate/out/ gate/in/ 光闸摆渡:本机发出 / 本机收到
|
||||||
|
```
|
||||||
|
|
||||||
|
数据全在宿主机 `volumes/` 下,容器删了数据还在。要放到独立数据盘就改 `.env` 的
|
||||||
|
`SFILE_DATA_ROOT`(以及 `GATE_SEND_DIR`/`GATE_RECV_DIR`)为绝对路径,重跑 `install.sh`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 现场要确认的 6 件事(都在 `.env`)
|
||||||
|
|
||||||
|
| 项 | 变量 | 内网机出厂值 / 建议 |
|
||||||
|
|---|---|---|
|
||||||
|
| 前端对外端口 | `WEB_PORT` | `80`;被占用就改 8080/9080,同步改访问地址 |
|
||||||
|
| 数据盘根目录 | `SFILE_DATA_ROOT` | `./volumes`;正式环境建议改绝对路径指到独立数据盘(≥200G) |
|
||||||
|
| 光闸摆渡目录 | `GATE_SEND_DIR` / `GATE_RECV_DIR` | `./volumes/gate/out` / `in`;**与光闸厂商确认挂载点**,发出与收到必须是两个不同目录 |
|
||||||
|
| 传输方向 | `SFILE_TRANSFER_LOCATION` | 内网机固定 `1`(外网机是 `2`)。**写反了摆渡方向就反了** |
|
||||||
|
| MeshSafe | `MESHSAFE_ENABLED` / `_BASE_URL` / `_CLIENT_ID` / `_SECRET` | 没接检测 → `MESHSAFE_ENABLED=false`;接了 → secret 必须与 MeshSafe 侧 `MESHSAFE_API_CLIENTS` 白名单里的 `client_id:secret` 逐字一致 |
|
||||||
|
| 口令 | `POSTGRES_PASSWORD` / `MQ_PASSWORD` / `JWT_SECRET` / `USER_DEFAULT_PASSWORD` | 出厂已给随机值可直接跑;`USER_DEFAULT_PASSWORD` 是新建用户的初始密码,**必须改并告知业务员** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 改前端页面(不用重建镜像)
|
||||||
|
|
||||||
|
前端是解压好的静态包,`web/` 就是站点根:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 替换整个前端包
|
||||||
|
rm -rf web && cp -r /path/to/new/dist web
|
||||||
|
docker compose restart web
|
||||||
|
|
||||||
|
# 只改单个文件(例如临时改个文案)
|
||||||
|
vi web/assets/xxx.js # 或替换 index.html
|
||||||
|
docker compose restart web # 浏览器再强刷一次(Ctrl+F5)
|
||||||
|
```
|
||||||
|
|
||||||
|
`web/` 是只读挂载,容器不会写它;改坏了从仓库 `frontend/` 重新构建一份覆盖即可。
|
||||||
|
构建产物的文件名自带 hash,`index.html` 不做缓存,所以换包后用户浏览器会自动取到新文件。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 运维
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose ps # 状态(5 个都该是 healthy)
|
||||||
|
docker logs -f sfile-iw-app # 后端日志(含送检/摆渡全过程)
|
||||||
|
docker compose restart app # 改完 .env / config 后重启后端
|
||||||
|
docker compose restart web # 替换 web/ 里的前端文件后刷新站点
|
||||||
|
docker compose down # 停止(不动数据)
|
||||||
|
```
|
||||||
|
|
||||||
|
**备份只需三样**:`volumes/pgdata`(库)、`volumes/upload`(文件本体)、`.env`(口令)。
|
||||||
|
恢复:换机器后按原路径放回 + `docker load` + `./scripts/install.sh`。
|
||||||
|
|
||||||
|
改了 `.env` 里的口令/网段这类**建容器时固化**的值,光 `restart` 不生效,要
|
||||||
|
`docker compose up -d`(重建容器)。数据库口令属于建库时写入,改它要连 `volumes/pgdata` 一起处理。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 装不上时先看这三条
|
||||||
|
|
||||||
|
1. `images/` 少 tar 或 sha256 不对 → 交付盘拷坏了,重拷(`install.sh` 会明确报哪一条)。
|
||||||
|
2. 架构不符(信创 ARM 机装了 amd64 包)→ `install.sh` 会拦;回构建机用 `TARGET_PLATFORM=linux/arm64` 重新出包。
|
||||||
|
3. 端口/网段与机器上已有容器冲突 → 改 `.env` 的 `WEB_PORT`,或整段换 `APP_SUBNET`/`APP_GATEWAY`/`APP_NODE_IP`(三个值必须同网段)。
|
||||||
|
|
||||||
|
其余坑(发号器 workerId、nginx 透传 Host、PostgreSQL 18 数据目录挂载点、监听周期与传输快慢)
|
||||||
|
见 [`../部署说明.md`](../部署说明.md) 最后一节。
|
||||||
19
deployment/iw/VERSION.txt
Normal file
19
deployment/iw/VERSION.txt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
s-file 部署包 1.1.0(内网机 iw)
|
||||||
|
构建平台: linux/amd64
|
||||||
|
导出时间: 2026-11-04 21:34:45
|
||||||
|
后端 jar: fa77c56(+ 未提交改动则与本仓库当前源码一致)
|
||||||
|
|
||||||
|
镜像清单(sha256 见 images/SHA256SUMS.txt):
|
||||||
|
nginx.tar 21M "RepoTags":["nginx:1.27-alpine"]
|
||||||
|
postgres.tar 161M "RepoTags":["postgres:18"]
|
||||||
|
rabbitmq.tar 84M "RepoTags":["rabbitmq:3.13-management-alpine"]
|
||||||
|
redis.tar 53M "RepoTags":["redis:8"]
|
||||||
|
sfile-app.tar 313M "RepoTags":["sfile-app:1.1.0"]
|
||||||
|
|
||||||
|
前端静态包: web/(内网包/外网包已分别就位,改页面直接替换文件)
|
||||||
|
SQL: sql/01-init-table.sql sql/02-init-data.sql 老库增量: sql/upgrade/
|
||||||
|
|
||||||
|
现场步骤(本机执行):
|
||||||
|
1) 整目录拷到服务器,例如 /opt/sfile-iw && cd /opt/sfile-iw
|
||||||
|
2) vi .env # 至少确认 MESHSAFE_ENABLED/SECRET、WEB_PORT、SFILE_DATA_ROOT、GATE_*
|
||||||
|
3) ./scripts/install.sh
|
||||||
110
deployment/iw/config/application.yml
Normal file
110
deployment/iw/config/application.yml
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# s-file 客户侧静态默认配置(两台机器共用同一份,现场一般不用改)
|
||||||
|
#
|
||||||
|
# 随角色/环境变化的取值一律由 docker-compose 的环境变量注入,本文件不放:
|
||||||
|
# 数据库/Redis/MQ 地址与口令、JWT 密钥、用户初始密码、传输方向与摆渡目录、
|
||||||
|
# MeshSafe 开关与凭证、MQ 交换机命名 —— 全部在 .env 里填
|
||||||
|
# 这样交付物里不存在任何写死的口令或密钥
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: s-file
|
||||||
|
datasource:
|
||||||
|
driver-class-name: org.postgresql.Driver
|
||||||
|
type: com.alibaba.druid.pool.DruidDataSource
|
||||||
|
druid:
|
||||||
|
initial-size: 5
|
||||||
|
min-idle: 5
|
||||||
|
max-active: 50
|
||||||
|
validation-query: SELECT 1
|
||||||
|
test-while-idle: true
|
||||||
|
# 摆渡解包/送检会在多任务里并发取连接,压太低会出现等待
|
||||||
|
max-wait: 10000
|
||||||
|
redis:
|
||||||
|
timeout: 5000
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
max-active: 16
|
||||||
|
max-idle: 8
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
max-file-size: 500MB
|
||||||
|
max-request-size: 500MB
|
||||||
|
main:
|
||||||
|
allow-bean-definition-overriding: true
|
||||||
|
|
||||||
|
mybatis-plus:
|
||||||
|
mapper-locations: classpath*:com/senmesh/**/mapper/*.xml
|
||||||
|
|
||||||
|
# 平台编码,需与 sql/02-init-data.sql 里 uc_platform.platform_code 一致
|
||||||
|
system:
|
||||||
|
code: 1
|
||||||
|
|
||||||
|
security:
|
||||||
|
jwt:
|
||||||
|
enable: true
|
||||||
|
# secret 由环境变量 SECURITY_JWT_SECRET 注入,勿在此填写
|
||||||
|
expiration: 86400000
|
||||||
|
header: Authorization
|
||||||
|
ignoring: /error,/favicon.ico
|
||||||
|
login-page: /login
|
||||||
|
superior-only: false
|
||||||
|
# 单机自闭环部署:权限走本地库,不接外部用户中心
|
||||||
|
use-local: true
|
||||||
|
allow-if-all-abstain-decisions: true
|
||||||
|
oauth2:
|
||||||
|
enable: false
|
||||||
|
not-logs: ""
|
||||||
|
anonymous: ""
|
||||||
|
|
||||||
|
# 新用户初始密码由环境变量 USER_DEFAULT_PASSWORD 注入
|
||||||
|
user:
|
||||||
|
default:
|
||||||
|
password: ${USER_DEFAULT_PASSWORD:}
|
||||||
|
|
||||||
|
file:
|
||||||
|
upload-dir: /data/upload
|
||||||
|
storage:
|
||||||
|
type: local
|
||||||
|
transfer:
|
||||||
|
# location / send-dir / receive-dir / monitor.cron 均由环境变量注入
|
||||||
|
# 解包时是否再做一次内容风险识别(依赖下面的 dify,未部署 dify 时保持 false)
|
||||||
|
unpack-risk-check: false
|
||||||
|
monitor:
|
||||||
|
# 单轮处理时间预算(秒)。超预算即结束本轮,剩余留给下一轮。
|
||||||
|
# 与监听周期配套:周期 5 秒则预算留 4 秒,保证两轮不互相挤压。
|
||||||
|
# 目录持续积压(日志「目录剩余待处理」超过 50)时调大此值
|
||||||
|
round-budget-seconds: 4
|
||||||
|
# 单轮兜底个数上限,防止极端场景单轮过长
|
||||||
|
round-max-files: 500
|
||||||
|
# 包内单个文件大小上限(MB)。解包时整个文件读进堆,峰值约 2-3 倍文件大小,
|
||||||
|
# 超限直接标 .error 而不是解包到 OOM。按 APP_JAVA_OPTS 的 -Xmx 调整:-Xmx3g 对应 512
|
||||||
|
max-unpack-size-mb: 512
|
||||||
|
# 校验不通过或解包异常,且文件静止超过该秒数即判定为坏包,标 .error 停止重试。
|
||||||
|
# 用于区分「光闸还在搬」与「搬完了但是坏包」,必须大于光闸搬运单个包的最长时间
|
||||||
|
stale-after-seconds: 300
|
||||||
|
|
||||||
|
# 内容风险识别(Dify)。未部署 Dify 时留空并保持 file.transfer.unpack-risk-check=false
|
||||||
|
dify:
|
||||||
|
risk:
|
||||||
|
rule:
|
||||||
|
api-key: ""
|
||||||
|
scan:
|
||||||
|
api-key: ""
|
||||||
|
|
||||||
|
# MeshSafe 全段由环境变量注入(MESHSAFE_*),未部署时 MESHSAFE_ENABLED=false 即可,
|
||||||
|
# 前端会自动隐藏「安全检测」列,跨网摆渡不受影响
|
||||||
|
meshsafe:
|
||||||
|
review-sync-to-meshsafe: true
|
||||||
|
|
||||||
|
# 接口文档在生产关闭
|
||||||
|
swagger:
|
||||||
|
enable: false
|
||||||
|
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
com.senmesh: info
|
||||||
192
deployment/iw/docker-compose.yml
Normal file
192
deployment/iw/docker-compose.yml
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# s-file 信创文件安全传输系统 —— 单台服务器一套(内网机 iw / 外网机 ow 通用同一份)
|
||||||
|
#
|
||||||
|
# 两台机器之间只靠光闸摆渡目录互通,彼此不开任何网络端口。
|
||||||
|
# 随角色变化的取值全在同目录 .env 里,本文件现场不用改。
|
||||||
|
#
|
||||||
|
# ./scripts/install.sh 自检 -> 校验并载入 images/*.tar -> 建目录 -> 起栈 -> 等健康
|
||||||
|
#
|
||||||
|
# 数据一律落在宿主机,不建 docker 卷(默认在本目录 volumes/ 下,见 .env 的 SFILE_DATA_ROOT):
|
||||||
|
# volumes/pgdata PostgreSQL 数据 volumes/redis Redis AOF
|
||||||
|
# volumes/mq RabbitMQ 数据 volumes/upload 用户上传的文件本体
|
||||||
|
# volumes/logs 后端日志(+logs/nginx) volumes/gate/out|in 光闸发出/收到的传输包
|
||||||
|
#
|
||||||
|
# 前端是已构建好的静态包,直接放在 web/ 目录挂进 nginx:
|
||||||
|
# 改页面 = 替换 web/ 下的文件,docker compose restart web 即可,不用重新构建镜像。
|
||||||
|
#
|
||||||
|
# 只发布前端端口;后端 / PostgreSQL / Redis / RabbitMQ 仅在容器网络内可达。
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
name: sfile-${SFILE_ROLE:?缺少 SFILE_ROLE(内网机 iw / 外网机 ow)}
|
||||||
|
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
image: ${NGINX_IMAGE:?缺少 NGINX_IMAGE}
|
||||||
|
container_name: sfile-${SFILE_ROLE}-web
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "${WEB_HOST:-0.0.0.0}:${WEB_PORT:-80}:80"
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ:-Asia/Shanghai}
|
||||||
|
volumes:
|
||||||
|
- ./nginx/web.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
|
# 前端静态包:宿主机 web/ 目录即站点根,替换文件即换页面
|
||||||
|
- ./web:/usr/share/nginx/html:ro
|
||||||
|
- ${SFILE_DATA_ROOT:?缺少 SFILE_DATA_ROOT}/logs/nginx:/var/log/nginx
|
||||||
|
depends_on:
|
||||||
|
app:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -sf -o /dev/null http://127.0.0.1:80/ || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
start_period: 20s
|
||||||
|
networks: [sfile]
|
||||||
|
|
||||||
|
app:
|
||||||
|
image: ${APP_IMAGE:?缺少 APP_IMAGE}
|
||||||
|
container_name: sfile-${SFILE_ROLE}-app
|
||||||
|
restart: unless-stopped
|
||||||
|
stop_grace_period: 30s
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ:-Asia/Shanghai}
|
||||||
|
# 发号器 workerId 按「容器 IP」取键,取不到会回退 99 而 99 > 31 直接启动失败,
|
||||||
|
# 因此这里锁死 app 的容器 IP,并把同一个键写进 JVM 参数,两处永远一致
|
||||||
|
JAVA_OPTS: "${APP_JAVA_OPTS:--Xms1g -Xmx3g -Dfile.encoding=UTF-8} -Dcode.snowflake.workid.${APP_NODE_IP:?缺少 APP_NODE_IP}=${APP_WORK_ID:?缺少 APP_WORK_ID}"
|
||||||
|
SPRING_CONFIG_ADDITIONAL_LOCATION: file:/config/application.yml
|
||||||
|
|
||||||
|
SPRING_DATASOURCE_URL: jdbc:postgresql://pg:5432/${POSTGRES_DB:?缺少 POSTGRES_DB}
|
||||||
|
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:?缺少 POSTGRES_USER}
|
||||||
|
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:?缺少 POSTGRES_PASSWORD}
|
||||||
|
|
||||||
|
SPRING_REDIS_HOST: redis
|
||||||
|
SPRING_REDIS_PORT: 6379
|
||||||
|
|
||||||
|
SPRING_RABBITMQ_HOST: mq
|
||||||
|
SPRING_RABBITMQ_PORT: 5672
|
||||||
|
SPRING_RABBITMQ_USERNAME: ${MQ_USER:?缺少 MQ_USER}
|
||||||
|
SPRING_RABBITMQ_PASSWORD: ${MQ_PASSWORD:?缺少 MQ_PASSWORD}
|
||||||
|
# 两侧交换机/广播 ID 必须不同,防止有人把两套栈并到一台机器时串消息
|
||||||
|
RABBITMQ_CUSTOM_TOPIC_EXCHANGE_NAME: s-file-${SFILE_ROLE}-topic
|
||||||
|
RABBITMQ_CUSTOM_DELAYED_EXCHANGE_NAME: s-file-${SFILE_ROLE}-delayed
|
||||||
|
RABBITMQ_CUSTOM_BROADCAST_ID: s-file-${SFILE_ROLE}-broadcast
|
||||||
|
|
||||||
|
SECURITY_JWT_SECRET: ${JWT_SECRET:?缺少 JWT_SECRET}
|
||||||
|
USER_DEFAULT_PASSWORD: ${USER_DEFAULT_PASSWORD:?缺少 USER_DEFAULT_PASSWORD}
|
||||||
|
|
||||||
|
# 内网机 1 / 外网机 2,写反了摆渡方向就反了
|
||||||
|
FILE_TRANSFER_LOCATION: "${SFILE_TRANSFER_LOCATION:?缺少 SFILE_TRANSFER_LOCATION}"
|
||||||
|
FILE_TRANSFER_SEND_DIR: /data/transfer/send
|
||||||
|
FILE_TRANSFER_RECEIVE_DIR: /data/transfer/receive
|
||||||
|
FILE_TRANSFER_MONITOR_CRON: "${FILE_TRANSFER_MONITOR_CRON:-0/5 * * * * ?}"
|
||||||
|
|
||||||
|
MESHSAFE_ENABLED: ${MESHSAFE_ENABLED:-true}
|
||||||
|
MESHSAFE_BASE_URL: ${MESHSAFE_BASE_URL:-}
|
||||||
|
MESHSAFE_CLIENT_ID: ${MESHSAFE_CLIENT_ID:-}
|
||||||
|
MESHSAFE_SECRET: ${MESHSAFE_SECRET:-}
|
||||||
|
MESHSAFE_CHANNEL: ${MESHSAFE_CHANNEL:-sfile-${SFILE_ROLE}}
|
||||||
|
MESHSAFE_FAIL_OPEN: ${MESHSAFE_FAIL_OPEN:-true}
|
||||||
|
MESHSAFE_TIMEOUT_SECONDS: ${MESHSAFE_TIMEOUT_SECONDS:-120}
|
||||||
|
MESHSAFE_POLL_TIMEOUT_MINUTES: ${MESHSAFE_POLL_TIMEOUT_MINUTES:-60}
|
||||||
|
MESHSAFE_POLL_CRON: ${MESHSAFE_POLL_CRON:-0/10 * * * * ?}
|
||||||
|
volumes:
|
||||||
|
- ./config/application.yml:/config/application.yml:ro
|
||||||
|
- ${SFILE_DATA_ROOT}/upload:/data/upload
|
||||||
|
- ${SFILE_DATA_ROOT}/logs:/app/logs
|
||||||
|
# 摆渡目录:容器内固定路径,宿主机侧由光闸设备负责单向搬运
|
||||||
|
- ${GATE_SEND_DIR:?缺少 GATE_SEND_DIR}:/data/transfer/send
|
||||||
|
- ${GATE_RECV_DIR:?缺少 GATE_RECV_DIR}:/data/transfer/receive
|
||||||
|
# MeshSafe 与应用同机部署时靠它从容器内访问宿主机端口;
|
||||||
|
# Docker < 20.10 不支持 host-gateway,或 MeshSafe 在独立服务器时,删掉这两行即可
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
depends_on:
|
||||||
|
pg:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
mq:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -s --max-time 5 -o /dev/null http://127.0.0.1:8080/ || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 8s
|
||||||
|
retries: 5
|
||||||
|
# 首次建库要跑全量 DDL,冷启动给足时间
|
||||||
|
start_period: 180s
|
||||||
|
networks:
|
||||||
|
sfile:
|
||||||
|
ipv4_address: ${APP_NODE_IP}
|
||||||
|
|
||||||
|
pg:
|
||||||
|
image: ${PG_IMAGE:?缺少 PG_IMAGE}
|
||||||
|
container_name: sfile-${SFILE_ROLE}-pg
|
||||||
|
restart: unless-stopped
|
||||||
|
stop_grace_period: 60s
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ:-Asia/Shanghai}
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB:?缺少 POSTGRES_DB}
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:?缺少 POSTGRES_USER}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?缺少 POSTGRES_PASSWORD}
|
||||||
|
# 空库首次启动才执行 initdb.d,已有数据卷时会被忽略
|
||||||
|
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=C --lc-ctype=C"
|
||||||
|
volumes:
|
||||||
|
# postgres 18+ 数据目录挂载点是 /var/lib/postgresql,15- 是 .../data,见 .env 的 PG_DATA_DIR
|
||||||
|
- ${SFILE_DATA_ROOT}/pgdata:${PG_DATA_DIR:-/var/lib/postgresql}
|
||||||
|
- ./sql/01-init-table.sql:/docker-entrypoint-initdb.d/01-init-table.sql:ro
|
||||||
|
- ./sql/02-init-data.sql:/docker-entrypoint-initdb.d/02-init-data.sql:ro
|
||||||
|
healthcheck:
|
||||||
|
# 必须强制走 TCP(-h 127.0.0.1):首次 initdb 期间镜像会临时起一个只听 unix socket
|
||||||
|
# 的实例,此时用默认 socket 探测也会返回成功,导致 app 抢跑连库失败
|
||||||
|
test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
start_period: 60s
|
||||||
|
networks: [sfile]
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: ${REDIS_IMAGE:?缺少 REDIS_IMAGE}
|
||||||
|
container_name: sfile-${SFILE_ROLE}-redis
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ["redis-server", "--appendonly", "yes", "--maxmemory", "${REDIS_MAXMEMORY:-512mb}", "--maxmemory-policy", "allkeys-lru"]
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ:-Asia/Shanghai}
|
||||||
|
volumes:
|
||||||
|
- ${SFILE_DATA_ROOT}/redis:/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
networks: [sfile]
|
||||||
|
|
||||||
|
mq:
|
||||||
|
image: ${MQ_IMAGE:?缺少 MQ_IMAGE}
|
||||||
|
container_name: sfile-${SFILE_ROLE}-mq
|
||||||
|
restart: unless-stopped
|
||||||
|
stop_grace_period: 30s
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ:-Asia/Shanghai}
|
||||||
|
RABBITMQ_DEFAULT_USER: ${MQ_USER:?缺少 MQ_USER}
|
||||||
|
RABBITMQ_DEFAULT_PASS: ${MQ_PASSWORD:?缺少 MQ_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- ${SFILE_DATA_ROOT}/mq:/var/lib/rabbitmq
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "rabbitmq-diagnostics -q ping"]
|
||||||
|
interval: 20s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 10
|
||||||
|
start_period: 60s
|
||||||
|
networks: [sfile]
|
||||||
|
|
||||||
|
networks:
|
||||||
|
sfile:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
# 锁 app 容器 IP 是为了发号器 workerId 取键;subnet/网关/app IP 三个值必须同网段。
|
||||||
|
# 若与客户机器上已有 docker 网段冲突,整段换掉(如 172.31.88.0/24)即可
|
||||||
|
- subnet: ${APP_SUBNET:?缺少 APP_SUBNET}
|
||||||
|
gateway: ${APP_GATEWAY:?缺少 APP_GATEWAY}
|
||||||
44
deployment/iw/nginx/web.conf
Normal file
44
deployment/iw/nginx/web.conf
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
charset utf-8;
|
||||||
|
|
||||||
|
# 站点根 = 宿主机 web/ 目录(compose 里 ./web:/usr/share/nginx/html:ro)
|
||||||
|
# 临时改页面:替换 web/ 下的文件后 docker compose restart web,不用重建镜像
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# 与后端 multipart 上限(500MB)保持一致,改这里要同步改 config/application.yml
|
||||||
|
client_max_body_size 500m;
|
||||||
|
client_body_timeout 300s;
|
||||||
|
|
||||||
|
# /api/xxx -> 后端 /xxx(去掉 /api 前缀,与前端构建时的 VITE_API_URL=/api 对应)
|
||||||
|
# app 是 compose 里的服务名,改了服务名这里要跟着改
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://app:8080/;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
# 必须保留端口($http_host):后端 getRootDomain 对「无端口的 IP/localhost」会抛
|
||||||
|
# IllegalStateException,导致登录成功回调 500。改成 $host 就会复现这个坑
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_read_timeout 600s;
|
||||||
|
proxy_send_timeout 600s;
|
||||||
|
# 大文件上传不在 nginx 侧缓冲,直接流给后端
|
||||||
|
proxy_request_buffering off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# SPA:hash 路由,静态资源找不到时回落 index.html
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 构建产物的文件名自带 hash,可以放心缓存;index.html 不在其中,换包后浏览器直接拿到新的
|
||||||
|
location ~* \.(js|mjs|css|woff2?|ttf|png|jpe?g|gif|svg|ico)$ {
|
||||||
|
expires 7d;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
}
|
||||||
198
deployment/iw/scripts/install.sh
Executable file
198
deployment/iw/scripts/install.sh
Executable file
@@ -0,0 +1,198 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# =============================================================================
|
||||||
|
# s-file 一键安装(在本机执行;内网机用 iw/ 那份,外网机用 ow/ 那份)
|
||||||
|
#
|
||||||
|
# cd /opt/sfile-iw && ./scripts/install.sh
|
||||||
|
#
|
||||||
|
# 做六件事:环境自检 -> 校验交付物 -> 校验并载入镜像 tar -> 建数据目录 -> 起栈 -> 等健康
|
||||||
|
# 幂等:重复执行只重建有差异的容器,不动已初始化好的数据库
|
||||||
|
# 本目录就是配置:角色/口令/端口/目录全在同级 .env 里,改完重跑本脚本即可
|
||||||
|
# =============================================================================
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
HERE="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
|
cd "$HERE"
|
||||||
|
|
||||||
|
envget() { grep -E "^[[:space:]]*$1=" .env | tail -1 | cut -d= -f2- | tr -d '"' | sed 's/[[:space:]]*$//'; }
|
||||||
|
|
||||||
|
step() { printf '\n\033[1;36m==> %s\033[0m\n' "$1"; }
|
||||||
|
die() { printf '\033[1;31m!!! %s\033[0m\n' "$1" >&2; exit 1; }
|
||||||
|
|
||||||
|
[ -f .env ] || die "缺少 .env(交付包不完整,本目录下应有一份出厂 .env)"
|
||||||
|
ROLE="$(envget SFILE_ROLE)"
|
||||||
|
case "$ROLE" in
|
||||||
|
iw|ow) ;;
|
||||||
|
*) die ".env 里 SFILE_ROLE=「$ROLE」不合法,只能是 iw(内网机)或 ow(外网机)" ;;
|
||||||
|
esac
|
||||||
|
echo "本机角色:$ROLE(传输方向 location=$(envget SFILE_TRANSFER_LOCATION))"
|
||||||
|
|
||||||
|
# ---------- 1. 前置自检 ----------
|
||||||
|
step "检查 docker 与 compose"
|
||||||
|
command -v docker >/dev/null 2>&1 || die "未安装 docker,请先装 Docker Engine(信创系统用厂商源,版本号 >= 20.10)"
|
||||||
|
docker info >/dev/null 2>&1 || die "docker 守护进程不可用,检查服务是否启动、当前用户是否在 docker 组"
|
||||||
|
if docker compose version >/dev/null 2>&1; then
|
||||||
|
DC="docker compose"
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then
|
||||||
|
DC="docker-compose"
|
||||||
|
else
|
||||||
|
die "缺少 compose:安装 docker compose v2 插件,或用 docker-compose 命令"
|
||||||
|
fi
|
||||||
|
echo " 使用:$DC"
|
||||||
|
echo " docker server:$(docker version --format '{{.Server.Version}}')"
|
||||||
|
|
||||||
|
if grep -q "CHANGE_ME" .env; then
|
||||||
|
# MeshSafe 的 secret 只有真的启用检测时才必须填,否则现场没接 MeshSafe 就装不了机
|
||||||
|
if [ "$(envget MESHSAFE_ENABLED)" = "true" ] && grep -qE "^MESHSAFE_SECRET=.*CHANGE_ME" .env; then
|
||||||
|
die "启用了 MeshSafe 但 MESHSAFE_SECRET 还是占位值:按 MeshSafe 交付单改成白名单里的 secret,或把 MESHSAFE_ENABLED 改成 false"
|
||||||
|
fi
|
||||||
|
rest="$(grep -n CHANGE_ME .env | grep -v '^.*MESHSAFE_SECRET=' | cut -d: -f2 | tr '\n' ' ')"
|
||||||
|
[ -z "$rest" ] || die ".env 里还有 CHANGE_ME 未替换:$rest"
|
||||||
|
fi
|
||||||
|
|
||||||
|
step "检查交付物"
|
||||||
|
[ -d images ] || die "缺少 images/ 目录(镜像 tar 应在本目录的 images/ 下)"
|
||||||
|
tar_count=$(find images -maxdepth 1 -name '*.tar' | wc -l)
|
||||||
|
[ "$tar_count" -eq 5 ] || die "images/ 下应有 5 个 .tar(app/nginx/postgres/redis/rabbitmq),实际 $tar_count 个:$(ls images)"
|
||||||
|
for f in sql/01-init-table.sql sql/02-init-data.sql config/application.yml nginx/web.conf; do
|
||||||
|
[ -s "$f" ] || die "缺少 $f(交付包不完整)"
|
||||||
|
done
|
||||||
|
# 前端是静态包,缺了 nginx 起来只有默认页,看着像装好了其实没有界面
|
||||||
|
[ -s web/index.html ] || die "缺少 web/index.html —— 前端静态包没随包带过来"
|
||||||
|
[ -n "$(ls -A web/assets 2>/dev/null)" ] || die "web/assets 是空的 —— 前端静态包不完整"
|
||||||
|
echo " 镜像 tar:5 个,SQL / 后端配置 / nginx 配置 / 前端包就位"
|
||||||
|
|
||||||
|
# 端口占用先探一次:装到一半发现 80 被占,回滚比改 .env 麻烦
|
||||||
|
WEB_PORT="$(envget WEB_PORT)"
|
||||||
|
if command -v ss >/dev/null 2>&1 && ss -ltn 2>/dev/null | awk '{print $4}' | grep -qE "[:.]${WEB_PORT:-80}$"; then
|
||||||
|
printf ' \033[1;33m提示:宿主机 %s 端口已被占用,改 .env 的 WEB_PORT 后重跑\033[0m\n' "${WEB_PORT:-80}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------- 2. 校验交付盘 + 镜像架构 ----------
|
||||||
|
# 650M 的 tar 经 U 盘/内网 scp 拷坏是最常见的现场故障,坏包 load 到一半才报错更难查
|
||||||
|
if [ -f images/SHA256SUMS.txt ] && [ "${SKIP_CHECKSUM:-0}" != "1" ]; then
|
||||||
|
step "校验镜像 tar 完整性(sha256,约半分钟)"
|
||||||
|
( cd images && sha256sum -c SHA256SUMS.txt ) \
|
||||||
|
|| die "有 tar 与 SHA256SUMS.txt 不一致:交付盘拷坏了,重新拷一份;确认无碍可 SKIP_CHECKSUM=1 跳过"
|
||||||
|
fi
|
||||||
|
|
||||||
|
step "核对镜像架构"
|
||||||
|
HOST_ARCH="$(uname -m)"
|
||||||
|
case "$HOST_ARCH" in
|
||||||
|
x86_64) EXPECT="amd64" ;;
|
||||||
|
aarch64|arm64) EXPECT="arm64" ;;
|
||||||
|
*) EXPECT="unknown" ;;
|
||||||
|
esac
|
||||||
|
echo " 本机:$HOST_ARCH (期望镜像架构 ${EXPECT})"
|
||||||
|
|
||||||
|
# 架构在镜像的 config blob 里,不在 manifest.json —— manifest.json 只给 Config 的路径
|
||||||
|
tar_arch() {
|
||||||
|
local t="$1" cfg
|
||||||
|
cfg="$(tar -xOf "$t" manifest.json 2>/dev/null | tr -d '\n' \
|
||||||
|
| { grep -oE '"Config":"[^"]+"' || true; } | awk -F'"' 'NR==1{print $4}')"
|
||||||
|
[ -n "$cfg" ] || { echo ""; return 0; }
|
||||||
|
tar -xOf "$t" "$cfg" 2>/dev/null | tr -d '\n' \
|
||||||
|
| { grep -oE '"architecture":"[a-z0-9-]+"' || true; } | awk -F'"' 'NR==1{print $4}'
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$EXPECT" != "unknown" ]; then
|
||||||
|
# app 和 pg 各查一个:一个是自己构建的,一个是基础镜像,架构错了必是出盘时选错平台
|
||||||
|
for t in images/sfile-app.tar images/postgres.tar; do
|
||||||
|
[ -f "$t" ] || continue
|
||||||
|
# 不能用 `| head -1`:pipefail 下 head 提前关管道会让上游 grep 收到 SIGPIPE(141),脚本静默中断
|
||||||
|
IMG_ARCH="$(tar_arch "$t")"
|
||||||
|
if [ -n "${IMG_ARCH:-}" ] && [ "$IMG_ARCH" != "$EXPECT" ]; then
|
||||||
|
die "$(basename "$t") 是 $IMG_ARCH,本机是 $EXPECT —— 别硬装,回来重出对应架构的包"
|
||||||
|
fi
|
||||||
|
printf ' %-18s %s\n' "$(basename "$t")" "${IMG_ARCH:-未识别,继续}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------- 3. 载入镜像 ----------
|
||||||
|
step "docker load 载入离线镜像"
|
||||||
|
for t in images/*.tar; do
|
||||||
|
echo " <- $t"
|
||||||
|
docker load -i "$t"
|
||||||
|
done
|
||||||
|
|
||||||
|
# compose 用的是 .env 里的 tag,缺一个就会去联网拉,离线机上直接卡死
|
||||||
|
for img in "$(envget APP_IMAGE)" "$(envget NGINX_IMAGE)" "$(envget PG_IMAGE)" \
|
||||||
|
"$(envget REDIS_IMAGE)" "$(envget MQ_IMAGE)"; do
|
||||||
|
docker image inspect "$img" >/dev/null 2>&1 \
|
||||||
|
|| die "载入后仍看不到镜像 $img —— tar 与 .env 的 tag 不一致,别继续,回来看 images/ 和 .env"
|
||||||
|
echo " ✓ $img"
|
||||||
|
done
|
||||||
|
|
||||||
|
# ---------- 4. 目录 ----------
|
||||||
|
step "创建数据与摆渡目录"
|
||||||
|
DATA_ROOT="$(envget SFILE_DATA_ROOT)"
|
||||||
|
GATE_SEND="$(envget GATE_SEND_DIR)"
|
||||||
|
GATE_RECV="$(envget GATE_RECV_DIR)"
|
||||||
|
[ -n "$DATA_ROOT" ] || die ".env 里 SFILE_DATA_ROOT 为空"
|
||||||
|
|
||||||
|
mkdir -p "$DATA_ROOT"/{upload,logs/nginx,pgdata,redis,mq}
|
||||||
|
mkdir -p "$GATE_SEND" "$GATE_RECV"
|
||||||
|
|
||||||
|
# 数据盘挂载点没起来时直接建目录会落到根分区,先确认一下
|
||||||
|
case "$DATA_ROOT" in
|
||||||
|
/*) mountpoint -q "$DATA_ROOT" 2>/dev/null \
|
||||||
|
|| printf ' \033[1;33m提示:%s 不是独立挂载点,确认容量够(上传+库+日志)\033[0m\n' "$DATA_ROOT" ;;
|
||||||
|
*) echo " 数据目录用本目录下的相对路径:$(cd "$DATA_ROOT" && pwd)" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# pgdata 提前给到容器内 postgres 的 uid=999,避免镜像入口脚本 chown 失败;
|
||||||
|
# redis/mq 的官方入口脚本自己会改属主,这里只保证目录存在且可写
|
||||||
|
chown -R 999:999 "$DATA_ROOT/pgdata" 2>/dev/null || true
|
||||||
|
chmod -R 750 "$DATA_ROOT" 2>/dev/null || true
|
||||||
|
|
||||||
|
# SELinux(麒麟/统信多为 enforcing):无 :z 标记的绑定挂载需要放开标签,否则库起不来、
|
||||||
|
# nginx 读不到前端包(表现为 403)。这里把 compose 里所有 bind 挂载点都标一遍
|
||||||
|
if command -v chcon >/dev/null 2>&1; then
|
||||||
|
chcon -Rt svirt_sandbox_file_t \
|
||||||
|
"$HERE/config" "$HERE/nginx" "$HERE/web" "$HERE/sql" \
|
||||||
|
"$DATA_ROOT" "$GATE_SEND" "$GATE_RECV" 2>/dev/null \
|
||||||
|
|| echo " chcon 失败(未启用 SELinux 可忽略)"
|
||||||
|
fi
|
||||||
|
echo " $DATA_ROOT / $GATE_SEND / $GATE_RECV 就位"
|
||||||
|
|
||||||
|
# ---------- 5. 起栈 ----------
|
||||||
|
step "启动服务(首次建库约 1-3 分钟)"
|
||||||
|
$DC up -d
|
||||||
|
|
||||||
|
step "等待健康检查"
|
||||||
|
for svc in pg redis mq app web; do
|
||||||
|
name="sfile-${ROLE}-${svc}"
|
||||||
|
printf ' %-24s ' "$name"
|
||||||
|
st=""
|
||||||
|
for _ in $(seq 1 60); do
|
||||||
|
st="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "$name" 2>/dev/null || echo missing)"
|
||||||
|
case "$st" in
|
||||||
|
healthy|running) printf '\033[32m%s\033[0m\n' "$st"; break ;;
|
||||||
|
missing) sleep 2 ;;
|
||||||
|
*) sleep 5 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
if [ "$st" != "healthy" ] && [ "$st" != "running" ]; then
|
||||||
|
printf '\033[31m超时(最后状态:%s)\033[0m\n' "${st:-unknown}"
|
||||||
|
$DC ps
|
||||||
|
echo " 看日志:docker logs --tail 200 ${name}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# ---------- 6. 出口信息 ----------
|
||||||
|
IP="$(hostname -I 2>/dev/null | tr ' ' '\n' | { grep -E '^[0-9]+\.' || true; } | awk 'NR==1{print}')"
|
||||||
|
step "完成"
|
||||||
|
cat <<EOF
|
||||||
|
访问地址: http://${IP:-<本机IP>}:${WEB_PORT:-80}
|
||||||
|
角色: ${ROLE}(传输方向 location=$(envget SFILE_TRANSFER_LOCATION))
|
||||||
|
数据目录: $(cd "$DATA_ROOT" && pwd)
|
||||||
|
摆渡: 发出 $GATE_SEND / 收到 $GATE_RECV
|
||||||
|
MeshSafe: $(envget MESHSAFE_ENABLED) -> $(envget MESHSAFE_BASE_URL)
|
||||||
|
|
||||||
|
常用命令:
|
||||||
|
$DC ps 看状态
|
||||||
|
docker logs -f sfile-${ROLE}-app 看后端日志
|
||||||
|
$DC restart app 改完 .env / config 后重启后端
|
||||||
|
$DC restart web 替换 web/ 里的前端文件后刷新站点
|
||||||
|
EOF
|
||||||
|
echo " 首次登录后立刻改掉 admin 的默认口令。"
|
||||||
2083
deployment/iw/sql/01-init-table.sql
Normal file
2083
deployment/iw/sql/01-init-table.sql
Normal file
File diff suppressed because it is too large
Load Diff
46
deployment/iw/sql/02-init-data.sql
Normal file
46
deployment/iw/sql/02-init-data.sql
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
-- 系统uc_platform
|
||||||
|
INSERT INTO uc_platform
|
||||||
|
(platform_code, name, full_name, short_name, business, deleted, create_time)
|
||||||
|
VALUES(1, '文档系统', 's-file', 'file', true, FALSE, now());
|
||||||
|
|
||||||
|
-- 平台机构/平台机构管理员
|
||||||
|
INSERT INTO xs_org
|
||||||
|
(org_name, org_code, type, address_code, address_name, description, quality, enable, activated, parent_id, credit_code, trade, deleted, create_by, create_time, update_by, update_time, proxy_by, activation_code, phone, query_children, org_logo, registered_address, company_size, business_license, recruit_position_type)
|
||||||
|
VALUES('senmesh', 'O001', '1', '440232', NULL, NULL, false, TRUE, TRUE, NULL, '', NULL, FALSE, 0, now(), 1, now(), null, NULL, null, NULL, null, '1234', '6', null, '1');
|
||||||
|
|
||||||
|
INSERT INTO uc_user
|
||||||
|
(username, password, type, supeiror, security_code, nickname, avatar, phone, phone_binding, real_name, card_no, authenticated, status, email, address, education, init_user_id, enabled, account_non_expired, account_non_locked, credentials_non_expired, deleted, create_by, create_time, update_by, update_time, proxy_by, gender, birthday)
|
||||||
|
VALUES('admin', '$2a$10$0N3iaxx2sYv0hXvYzS4.6.yriL.DfjRTjED7Y4vkqxzbxi2dNpBou', 1, TRUE, '$2a$10$mGA1jdBzq8micEr02KiJ9OiYQz1fc/PSVG0hN0EYUuxhZp8EI1M2q', '平台管理员', '', '13888888888', TRUE, '平台管理员', NULL, FALSE, 2, null, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE, FALSE, 0, now(), 1, NULL, NULL, NULL, NULL);
|
||||||
|
INSERT INTO uc_org_user
|
||||||
|
(user_id, org_id, administrator, deleted, create_by, create_time, update_by, update_time, proxy_by)
|
||||||
|
VALUES(1, 1, TRUE, FALSE, 0, now(), NULL, NULL, NULL);
|
||||||
|
-- 平台uc_org_relation
|
||||||
|
INSERT INTO uc_org_relation
|
||||||
|
(org_id, org_type, parent_id, path, platform_code, platform_name, deleted, create_by, create_time, update_by, update_time, proxy_by)
|
||||||
|
VALUES(1, 1, 0, '1', 1, NULL, FALSE, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of x_file_category
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO x_file_category (file_category, file_suffix, deleted, create_by, create_time) VALUES
|
||||||
|
('video', 'mp4', FALSE, 0, NOW()),
|
||||||
|
('video', 'mkv', FALSE, 0, NOW()),
|
||||||
|
('video', 'avi', FALSE, 0, NOW()),
|
||||||
|
('video', 'mov', FALSE, 0, NOW()),
|
||||||
|
('video', 'wmv', FALSE, 0, NOW()),
|
||||||
|
('video', 'flv', FALSE, 0, NOW()),
|
||||||
|
('audio', 'mp3', FALSE, 0, NOW()),
|
||||||
|
('audio', 'wav', FALSE, 0, NOW()),
|
||||||
|
('audio', 'flac', FALSE, 0, NOW()),
|
||||||
|
('audio', 'aac', FALSE, 0, NOW()),
|
||||||
|
('document', 'txt', FALSE, 0, NOW()),
|
||||||
|
('document', 'docx', FALSE, 0, NOW()),
|
||||||
|
('document', 'pdf', FALSE, 0, NOW()),
|
||||||
|
('document', 'epub', FALSE, 0, NOW()),
|
||||||
|
('other', 'zip', FALSE, 0, NOW()),
|
||||||
|
('other', 'rar', FALSE, 0, NOW()),
|
||||||
|
('other', '7z', FALSE, 0, NOW()),
|
||||||
|
('other', 'jpg', FALSE, 0, NOW()),
|
||||||
|
('other', 'png', FALSE, 0, NOW()),
|
||||||
|
('other', 'gif', FALSE, 0, NOW()),
|
||||||
|
('other', 'tiff', FALSE, 0, NOW());
|
||||||
42
deployment/iw/sql/README.md
Normal file
42
deployment/iw/sql/README.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
建表与初始数据脚本已随包放好,文件名前缀决定执行顺序(先建表后灌数据):
|
||||||
|
|
||||||
|
| 文件 | 来源 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `01-init-table.sql` | `backend/db/init-table-postgres-full.sql` | 全量 DDL,含 `x_file_security` 安全检测表与 `idx_file_record_md5_code` 索引 |
|
||||||
|
| `02-init-data.sql` | `backend/db/init-data.sql` | admin 账号、机构、平台编码(`system.code=1` 要与此一致) |
|
||||||
|
|
||||||
|
出包时用 `deployment/scripts/build-package.sh` 从仓库重新覆盖这两份,别手改副本。
|
||||||
|
|
||||||
|
只有 `POSTGRES_*` 指向的库为空时,PostgreSQL 官方镜像才会执行 `docker-entrypoint-initdb.d`;
|
||||||
|
数据目录已有数据时会跳过 —— 想重建就把 `volumes/pgdata` 一起清掉再 `up`。
|
||||||
|
|
||||||
|
## upgrade/ —— 已上线老库的增量脚本(新装不用跑)
|
||||||
|
|
||||||
|
| 文件 | 作用 |
|
||||||
|
|---|---|
|
||||||
|
| `upgrade-20260914-upload-config.sql` | 新增 `x_upload_config`(机构上传后缀白名单/大小上限/开关) |
|
||||||
|
| `upgrade-20260915-release.sql` | 与上一份同一件事(上线汇总版),**两者跑其一即可** |
|
||||||
|
| `upgrade-20261101-meshsafe-file-security.sql` | 新增 `x_file_security` 文件安全检测表与字段 |
|
||||||
|
| `upgrade-20261103-transfer-perf.sql` | 给 `xs_file_record.md5_code` 补索引(解包时按 MD5 去重查询,缺索引就是每文件一次全表扫描) |
|
||||||
|
|
||||||
|
客户如果从 2026-09 之前的老库升上来,本包(PostgreSQL)真正缺的只有三个对象:
|
||||||
|
`x_upload_config`、`x_file_security`、`idx_file_record_md5_code`。
|
||||||
|
这三项在 `01-init-table.sql` 里都已是 PostgreSQL 写法,老库升级建议直接照它补,别整份管道进 psql:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 先看缺不缺
|
||||||
|
docker exec -i sfile-iw-pg psql -U sfile -d s_file -c \
|
||||||
|
"\dt x_upload_config" -c "\dt x_file_security" -c "\di idx_file_record_md5_code"
|
||||||
|
|
||||||
|
# 只补 md5 索引(这份脚本带「-- 2. PostgreSQL」分节标题,可以截出来跑)
|
||||||
|
awk '/^-- 2\. PostgreSQL/{f=1} f' sql/upgrade/upgrade-20261103-transfer-perf.sql \
|
||||||
|
| docker exec -i sfile-iw-pg psql -U sfile -d s_file
|
||||||
|
```
|
||||||
|
|
||||||
|
> 注意:这 4 份历史增量脚本是**达梦/MySQL 优先**写的,`upgrade-20260915-release.sql` 的 PostgreSQL 段整段是注释掉的,
|
||||||
|
> 只有 `upgrade-20261101`、`upgrade-20261103` 两份带可执行的「第 2 节 PostgreSQL」。别照着 MySQL 段硬跑。
|
||||||
|
|
||||||
|
这两份带可执行第 2 节的脚本都是「第 1 节 MySQL/达梦、第 2 节 PostgreSQL」双库混排,**只能跑第 2 节**,
|
||||||
|
整份管道进去会先执行 MySQL 那节。它们不会自动执行,要人工触发(容器名内网机 `sfile-iw-pg` / 外网机 `sfile-ow-pg`)。
|
||||||
|
|
||||||
|
数据量大时建索引会锁写,放到业务低峰执行;不能停写就用脚本里注明的 `CONCURRENTLY` 写法。
|
||||||
62
deployment/iw/sql/upgrade/upgrade-20260914-upload-config.sql
Normal file
62
deployment/iw/sql/upgrade/upgrade-20260914-upload-config.sql
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
-- =============================================================
|
||||||
|
-- 升级脚本:机构上传配置(文件上传类型/大小限制)
|
||||||
|
-- 日期:2026-09-14
|
||||||
|
-- 说明:新增 x_upload_config 表(一行对应一个机构)。
|
||||||
|
-- 机构管理员可配置本机构允许上传的文件后缀白名单、
|
||||||
|
-- 单文件大小上限、上传总开关;未配置的机构默认允许全部。
|
||||||
|
-- 拦截点:网盘上传落库(normal_user_file/create)。
|
||||||
|
-- 执行方式:MySQL/达梦(DM8 MySQL兼容模式)执行第 1 节;
|
||||||
|
-- PostgreSQL 执行第 2 节。
|
||||||
|
-- =============================================================
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 1. MySQL / 达梦 DM8
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
CREATE TABLE `x_upload_config` (
|
||||||
|
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
|
`org_id` bigint(20) DEFAULT NULL COMMENT '机构id',
|
||||||
|
`upload_enabled` bit(1) DEFAULT b'1' COMMENT '是否允许上传',
|
||||||
|
`allow_all_type` bit(1) DEFAULT b'1' COMMENT '是否允许全部类型(false时按allowed_suffixes白名单校验)',
|
||||||
|
`allowed_suffixes` varchar(1024) DEFAULT NULL COMMENT '允许的文件后缀(逗号分隔,小写),allow_all_type=false时生效',
|
||||||
|
`max_file_size` bigint(20) DEFAULT NULL COMMENT '单文件大小上限(MB),空或0不限制',
|
||||||
|
`deleted` bit(1) DEFAULT b'0' COMMENT '是否删除',
|
||||||
|
`create_by` bigint(20) DEFAULT NULL COMMENT '创建人',
|
||||||
|
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_by` bigint(20) DEFAULT NULL COMMENT '修改人',
|
||||||
|
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||||
|
`proxy_by` bigint(20) DEFAULT NULL COMMENT '代理人',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE KEY `uk_org_id` (`org_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='机构上传配置';
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 2. PostgreSQL
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
CREATE TABLE x_upload_config (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
org_id BIGINT DEFAULT NULL,
|
||||||
|
upload_enabled BOOLEAN DEFAULT TRUE,
|
||||||
|
allow_all_type BOOLEAN DEFAULT TRUE,
|
||||||
|
allowed_suffixes VARCHAR(1024) DEFAULT NULL,
|
||||||
|
max_file_size BIGINT DEFAULT NULL,
|
||||||
|
deleted BOOLEAN DEFAULT FALSE,
|
||||||
|
create_by BIGINT DEFAULT NULL,
|
||||||
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
update_by BIGINT DEFAULT NULL,
|
||||||
|
update_time TIMESTAMP DEFAULT NULL,
|
||||||
|
proxy_by BIGINT DEFAULT NULL,
|
||||||
|
CONSTRAINT uk_upload_config_org_id UNIQUE (org_id)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE x_upload_config IS '机构上传配置';
|
||||||
|
COMMENT ON COLUMN x_upload_config.id IS '主键ID';
|
||||||
|
COMMENT ON COLUMN x_upload_config.org_id IS '机构id';
|
||||||
|
COMMENT ON COLUMN x_upload_config.upload_enabled IS '是否允许上传';
|
||||||
|
COMMENT ON COLUMN x_upload_config.allow_all_type IS '是否允许全部类型(false时按allowed_suffixes白名单校验)';
|
||||||
|
COMMENT ON COLUMN x_upload_config.allowed_suffixes IS '允许的文件后缀(逗号分隔,小写),allow_all_type=false时生效';
|
||||||
|
COMMENT ON COLUMN x_upload_config.max_file_size IS '单文件大小上限(MB),空或0不限制';
|
||||||
|
COMMENT ON COLUMN x_upload_config.deleted IS '是否删除';
|
||||||
|
COMMENT ON COLUMN x_upload_config.create_by IS '创建人';
|
||||||
|
COMMENT ON COLUMN x_upload_config.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN x_upload_config.update_by IS '修改人';
|
||||||
|
COMMENT ON COLUMN x_upload_config.update_time IS '修改时间';
|
||||||
|
COMMENT ON COLUMN x_upload_config.proxy_by IS '代理人';
|
||||||
90
deployment/iw/sql/upgrade/upgrade-20260915-release.sql
Normal file
90
deployment/iw/sql/upgrade/upgrade-20260915-release.sql
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
-- =====================================================================
|
||||||
|
-- s-file 上线数据库脚本(2026-09-15 版本)
|
||||||
|
-- 适用场景:已有生产库升级(老版本 → 当前版本)
|
||||||
|
--
|
||||||
|
-- 本次版本(用户启停/注销、机构账号查询、手机号查记录、机构上传配置)
|
||||||
|
-- 相对老版本的数据库变更只有一项:
|
||||||
|
-- 新增表 x_upload_config(机构上传配置)
|
||||||
|
-- 其余功能(启停/注销/查询)全部复用已有表字段,无需任何变更。
|
||||||
|
--
|
||||||
|
-- 【执行说明】
|
||||||
|
-- * 生产主力库为达梦 DM8(MySQL 兼容模式)→ 只执行【第一部分】
|
||||||
|
-- * 若目标库是 PostgreSQL → 只执行【第二部分】
|
||||||
|
-- * 执行前建议备份;执行后核对【第三部分】的验证 SQL
|
||||||
|
-- * 可重复执行(幂等):表已存在时再执行会报"已存在"错误,属正常,
|
||||||
|
-- 说明该脚本已执行过,无需处理
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
|
||||||
|
-- =====================================================================
|
||||||
|
-- 第一部分:达梦 DM8 / MySQL
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
CREATE TABLE x_upload_config (
|
||||||
|
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
|
org_id BIGINT DEFAULT NULL COMMENT '机构id',
|
||||||
|
upload_enabled BIT(1) DEFAULT b'1' COMMENT '是否允许上传',
|
||||||
|
allow_all_type BIT(1) DEFAULT b'1' COMMENT '是否允许全部类型(false时按allowed_suffixes白名单校验)',
|
||||||
|
allowed_suffixes VARCHAR(1024) DEFAULT NULL COMMENT '允许的文件后缀(逗号分隔,小写),allow_all_type=false时生效',
|
||||||
|
max_file_size BIGINT DEFAULT NULL COMMENT '单文件大小上限(MB),空或0不限制',
|
||||||
|
deleted BIT(1) DEFAULT b'0' COMMENT '是否删除',
|
||||||
|
create_by BIGINT DEFAULT NULL COMMENT '创建人',
|
||||||
|
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
update_by BIGINT DEFAULT NULL COMMENT '修改人',
|
||||||
|
update_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||||
|
proxy_by BIGINT DEFAULT NULL COMMENT '代理人',
|
||||||
|
PRIMARY KEY (id) USING BTREE,
|
||||||
|
UNIQUE KEY uk_org_id (org_id)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='机构上传配置';
|
||||||
|
|
||||||
|
-- 说明:不需要初始化数据。
|
||||||
|
-- 未配置的机构 = 默认策略(允许上传全部类型、不限大小),
|
||||||
|
-- 由各机构管理员在管理后台"上传配置"页面自行配置后落库。
|
||||||
|
|
||||||
|
|
||||||
|
-- =====================================================================
|
||||||
|
-- 第二部分:PostgreSQL
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
-- CREATE TABLE x_upload_config (
|
||||||
|
-- id BIGSERIAL PRIMARY KEY,
|
||||||
|
-- org_id BIGINT DEFAULT NULL,
|
||||||
|
-- upload_enabled BOOLEAN DEFAULT TRUE,
|
||||||
|
-- allow_all_type BOOLEAN DEFAULT TRUE,
|
||||||
|
-- allowed_suffixes VARCHAR(1024) DEFAULT NULL,
|
||||||
|
-- max_file_size BIGINT DEFAULT NULL,
|
||||||
|
-- deleted BOOLEAN DEFAULT FALSE,
|
||||||
|
-- create_by BIGINT DEFAULT NULL,
|
||||||
|
-- create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
-- update_by BIGINT DEFAULT NULL,
|
||||||
|
-- update_time TIMESTAMP DEFAULT NULL,
|
||||||
|
-- proxy_by BIGINT DEFAULT NULL,
|
||||||
|
-- CONSTRAINT uk_upload_config_org_id UNIQUE (org_id)
|
||||||
|
-- );
|
||||||
|
-- COMMENT ON TABLE x_upload_config IS '机构上传配置';
|
||||||
|
-- COMMENT ON COLUMN x_upload_config.id IS '主键ID';
|
||||||
|
-- COMMENT ON COLUMN x_upload_config.org_id IS '机构id';
|
||||||
|
-- COMMENT ON COLUMN x_upload_config.upload_enabled IS '是否允许上传';
|
||||||
|
-- COMMENT ON COLUMN x_upload_config.allow_all_type IS '是否允许全部类型(false时按allowed_suffixes白名单校验)';
|
||||||
|
-- COMMENT ON COLUMN x_upload_config.allowed_suffixes IS '允许的文件后缀(逗号分隔,小写),allow_all_type=false时生效';
|
||||||
|
-- COMMENT ON COLUMN x_upload_config.max_file_size IS '单文件大小上限(MB),空或0不限制';
|
||||||
|
-- COMMENT ON COLUMN x_upload_config.deleted IS '是否删除';
|
||||||
|
-- COMMENT ON COLUMN x_upload_config.create_by IS '创建人';
|
||||||
|
-- COMMENT ON COLUMN x_upload_config.create_time IS '创建时间';
|
||||||
|
-- COMMENT ON COLUMN x_upload_config.update_by IS '修改人';
|
||||||
|
-- COMMENT ON COLUMN x_upload_config.update_time IS '修改时间';
|
||||||
|
-- COMMENT ON COLUMN x_upload_config.proxy_by IS '代理人';
|
||||||
|
|
||||||
|
|
||||||
|
-- =====================================================================
|
||||||
|
-- 第三部分:执行后验证(达梦/MySQL 语法)
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
-- 1) 表存在且为空(0 行正常)
|
||||||
|
-- SELECT COUNT(*) FROM x_upload_config;
|
||||||
|
|
||||||
|
-- 2) 唯一约束存在(应返回 uk_org_id)
|
||||||
|
-- SELECT INDEX_NAME FROM USER_INDEXES WHERE TABLE_NAME = 'X_UPLOAD_CONFIG';
|
||||||
|
|
||||||
|
-- 3) (可选)回滚脚本 —— 如需回滚上线:
|
||||||
|
-- DROP TABLE x_upload_config;
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
-- =============================================================
|
||||||
|
-- 升级脚本:MeshSafe 文件安全检测对接
|
||||||
|
-- 日期:2026-11-01
|
||||||
|
-- 说明:新增 x_file_security 表(按文件编码维度记录安全检测结果)。
|
||||||
|
-- 文件上传/传输接收解包后自动提交 MeshSafe 检测,
|
||||||
|
-- 检测结论(通过/不通过)回写本表;同一文件允许多条检测
|
||||||
|
-- 记录(人工复核、重新检测均新增记录),业务取最新一条生效。
|
||||||
|
-- 检测不通过的文件禁止分享与跨网传输(下载预览不受限)。
|
||||||
|
-- 执行方式:MySQL/达梦(DM8 MySQL兼容模式)执行第 1 节;
|
||||||
|
-- PostgreSQL 执行第 2 节。
|
||||||
|
-- =============================================================
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 1. MySQL / 达梦 DM8
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
CREATE TABLE `x_file_security` (
|
||||||
|
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
|
`file_code` varchar(32) DEFAULT NULL COMMENT '文件编码',
|
||||||
|
`task_id` varchar(64) DEFAULT NULL COMMENT 'MeshSafe检测任务ID',
|
||||||
|
`scan_status` varchar(2) DEFAULT NULL COMMENT '检测状态:1检测中/2通过/3不通过/4检测失败',
|
||||||
|
`action` varchar(32) DEFAULT NULL COMMENT 'MeshSafe处置动作:pass/manual_review/reject',
|
||||||
|
`reason` varchar(1024) DEFAULT NULL COMMENT '检测结论说明',
|
||||||
|
`result_json` text DEFAULT NULL COMMENT '检测完整结果JSON',
|
||||||
|
`review_comment` varchar(512) DEFAULT NULL COMMENT '人工复核说明(人工改判时有值)',
|
||||||
|
`deleted` bit(1) DEFAULT b'0' COMMENT '是否删除',
|
||||||
|
`create_by` bigint(20) DEFAULT NULL COMMENT '创建人',
|
||||||
|
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_by` bigint(20) DEFAULT NULL COMMENT '修改人',
|
||||||
|
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||||
|
`proxy_by` bigint(20) DEFAULT NULL COMMENT '代理人',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
KEY `idx_file_security_file_code` (`file_code`) USING BTREE,
|
||||||
|
KEY `idx_file_security_scan_status` (`scan_status`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件安全检测记录';
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 2. PostgreSQL
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
CREATE TABLE x_file_security (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
file_code VARCHAR(32) DEFAULT NULL,
|
||||||
|
task_id VARCHAR(64) DEFAULT NULL,
|
||||||
|
scan_status VARCHAR(2) DEFAULT NULL,
|
||||||
|
action VARCHAR(32) DEFAULT NULL,
|
||||||
|
reason VARCHAR(1024) DEFAULT NULL,
|
||||||
|
result_json TEXT DEFAULT NULL,
|
||||||
|
review_comment VARCHAR(512) DEFAULT NULL,
|
||||||
|
deleted BOOLEAN DEFAULT FALSE,
|
||||||
|
create_by BIGINT DEFAULT NULL,
|
||||||
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
update_by BIGINT DEFAULT NULL,
|
||||||
|
update_time TIMESTAMP DEFAULT NULL,
|
||||||
|
proxy_by BIGINT DEFAULT NULL
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_file_security_file_code ON x_file_security(file_code);
|
||||||
|
CREATE INDEX idx_file_security_scan_status ON x_file_security(scan_status);
|
||||||
|
COMMENT ON TABLE x_file_security IS '文件安全检测记录';
|
||||||
|
COMMENT ON COLUMN x_file_security.id IS '主键ID';
|
||||||
|
COMMENT ON COLUMN x_file_security.file_code IS '文件编码';
|
||||||
|
COMMENT ON COLUMN x_file_security.task_id IS 'MeshSafe检测任务ID';
|
||||||
|
COMMENT ON COLUMN x_file_security.scan_status IS '检测状态:1检测中/2通过/3不通过/4检测失败';
|
||||||
|
COMMENT ON COLUMN x_file_security.action IS 'MeshSafe处置动作:pass/manual_review/reject';
|
||||||
|
COMMENT ON COLUMN x_file_security.reason IS '检测结论说明';
|
||||||
|
COMMENT ON COLUMN x_file_security.result_json IS '检测完整结果JSON';
|
||||||
|
COMMENT ON COLUMN x_file_security.review_comment IS '人工复核说明(人工改判时有值)';
|
||||||
|
COMMENT ON COLUMN x_file_security.deleted IS '是否删除';
|
||||||
|
COMMENT ON COLUMN x_file_security.create_by IS '创建人';
|
||||||
|
COMMENT ON COLUMN x_file_security.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN x_file_security.update_by IS '修改人';
|
||||||
|
COMMENT ON COLUMN x_file_security.update_time IS '修改时间';
|
||||||
|
COMMENT ON COLUMN x_file_security.proxy_by IS '代理人';
|
||||||
26
deployment/iw/sql/upgrade/upgrade-20261103-transfer-perf.sql
Normal file
26
deployment/iw/sql/upgrade/upgrade-20261103-transfer-perf.sql
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
-- =============================================================
|
||||||
|
-- 升级脚本:跨网传输链路性能优化(第一批)
|
||||||
|
-- 日期:2026-11-03
|
||||||
|
-- 说明:给 xs_file_record.md5_code 补索引。
|
||||||
|
-- 文件入库时会用 MD5 做内容去重查询
|
||||||
|
-- (FileServiceImpl 上传 → find(md5Code)),此前该列无索引,
|
||||||
|
-- 每个文件入库都是一次全表扫描。解包一个含 N 个文件的传输包
|
||||||
|
-- 就是 N 次全表扫描,数据量上来后是多文件解包的主要数据库开销。
|
||||||
|
-- 新环境由 init 脚本建表时已包含该索引,本脚本仅供已上线环境增量执行。
|
||||||
|
-- 执行方式:MySQL/达梦(DM8 MySQL兼容模式)执行第 1 节;
|
||||||
|
-- PostgreSQL 执行第 2 节。
|
||||||
|
-- 注意:表数据量大时建索引会锁写,建议业务低峰执行。
|
||||||
|
-- 重复执行会报「索引已存在」,忽略即可。
|
||||||
|
-- =============================================================
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 1. MySQL / 达梦 DM8
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
CREATE INDEX idx_file_record_md5_code ON xs_file_record(md5_code);
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 2. PostgreSQL
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 表已有数据且不能停写时,改用下面这句(不可在事务块内执行):
|
||||||
|
-- CREATE INDEX CONCURRENTLY idx_file_record_md5_code ON xs_file_record(md5_code);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_file_record_md5_code ON xs_file_record(md5_code);
|
||||||
75
deployment/iw/web/assets/(user)-ByN4Axee.js
Normal file
75
deployment/iw/web/assets/(user)-ByN4Axee.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/admin-V-3Z0PVJ.js
Normal file
1
deployment/iw/web/assets/admin-V-3Z0PVJ.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{qn as e,zn as t}from"./index-BaTxSAlR.js";var n=e(t());function r(){return(0,n.jsx)(`div`,{className:`p-4 min-h-full`,children:(0,n.jsx)(`div`,{className:`p-8 rounded-lg`,children:(0,n.jsx)(`div`,{className:`flex items-center justify-center py-10`,children:(0,n.jsx)(`div`,{className:`text-base text-black/50`,children:`欢迎使用管理后台`})})})})}export{r as component};
|
||||||
1
deployment/iw/web/assets/app-layout-D4ftBqmM.js
Normal file
1
deployment/iw/web/assets/app-layout-D4ftBqmM.js
Normal file
File diff suppressed because one or more lines are too long
BIN
deployment/iw/web/assets/bg-CBsBX9E3.png
Normal file
BIN
deployment/iw/web/assets/bg-CBsBX9E3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 285 KiB |
1
deployment/iw/web/assets/chevron-left-r2x2HO6r.js
Normal file
1
deployment/iw/web/assets/chevron-left-r2x2HO6r.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{fn as e}from"./index-BaTxSAlR.js";var t=e(`chevron-left`,[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]);export{t};
|
||||||
1
deployment/iw/web/assets/chevron-right-_MvSGoRx.js
Normal file
1
deployment/iw/web/assets/chevron-right-_MvSGoRx.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{fn as e}from"./index-BaTxSAlR.js";var t=e(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]);export{t};
|
||||||
2
deployment/iw/web/assets/console-nn2bY2CJ.js
Normal file
2
deployment/iw/web/assets/console-nn2bY2CJ.js
Normal file
File diff suppressed because one or more lines are too long
4
deployment/iw/web/assets/data-table-CEq6a930.js
Normal file
4
deployment/iw/web/assets/data-table-CEq6a930.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/date-range-picker-CAdUnH9W.js
Normal file
1
deployment/iw/web/assets/date-range-picker-CAdUnH9W.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/dialog-CnxDxMp1.js
Normal file
1
deployment/iw/web/assets/dialog-CnxDxMp1.js
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
import{t as e}from"./chevron-right-_MvSGoRx.js";import{Vn as t,en as n,in as r,qn as i,zn as a}from"./index-BaTxSAlR.js";t();var o=i(a(),1);function s({...e}){return(0,o.jsx)(`nav`,{"aria-label":`breadcrumb`,"data-slot":`breadcrumb`,...e})}function c({className:e,...t}){return(0,o.jsx)(`ol`,{"data-slot":`breadcrumb-list`,className:n(`text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5`,e),...t})}function l({className:e,...t}){return(0,o.jsx)(`li`,{"data-slot":`breadcrumb-item`,className:n(`inline-flex items-center gap-1.5`,e),...t})}function u({asChild:e,className:t,...i}){return(0,o.jsx)(e?r:`a`,{"data-slot":`breadcrumb-link`,className:n(`hover:text-foreground transition-colors`,t),...i})}function d({className:e,...t}){return(0,o.jsx)(`span`,{"data-slot":`breadcrumb-page`,role:`link`,"aria-disabled":`true`,"aria-current":`page`,className:n(`text-foreground font-normal`,e),...t})}function f({children:t,className:r,...i}){return(0,o.jsx)(`li`,{"data-slot":`breadcrumb-separator`,role:`presentation`,"aria-hidden":`true`,className:n(`[&>svg]:size-3.5`,r),...i,children:t??(0,o.jsx)(e,{})})}function p({directorys:e,onChangeDirectorys:t,className:n}){return(0,o.jsx)(s,{className:n,children:(0,o.jsxs)(c,{children:[(0,o.jsx)(l,{children:(0,o.jsx)(u,{onClick:()=>t({id:0}),className:`cursor-pointer`,children:`根目录`})}),e.length>0&&(0,o.jsx)(f,{}),e.length>0&&e.map((n,r)=>(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(l,{children:r===e.length-1?(0,o.jsx)(d,{className:`cursor-default`,children:n.fileName}):(0,o.jsx)(u,{onClick:()=>t(n),className:`cursor-pointer`,children:n.fileName.length>6?n.fileName.slice(0,6)+`...`:n.fileName})},n.id),r!==e.length-1&&(0,o.jsx)(f,{},`separator`+n.id)]}))]})})}export{p as t};
|
||||||
1
deployment/iw/web/assets/dist-2m9EwrEG.js
Normal file
1
deployment/iw/web/assets/dist-2m9EwrEG.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{cn as e,ln as t}from"./index-BaTxSAlR.js";export{t as toast};
|
||||||
1
deployment/iw/web/assets/dist-7VFSSFOV.js
Normal file
1
deployment/iw/web/assets/dist-7VFSSFOV.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{Vn as e,Y as t,fn as n,qn as r,zn as i}from"./index-BaTxSAlR.js";var a=n(`chevron-down`,[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]),o=r(e(),1),s=r(i(),1),c=Object.defineProperty,l=(e,t)=>c(e,`name`,{value:t,configurable:!0}),u=Object.freeze({position:`absolute`,border:0,width:1,height:1,padding:0,margin:-1,overflow:`hidden`,clip:`rect(0, 0, 0, 0)`,whiteSpace:`nowrap`,wordWrap:`normal`}),d=o.forwardRef(l(function(e,n){return(0,s.jsx)(t.span,{...e,ref:n,style:{...u,...e.style}})},`VisuallyHidden`));export{d as n,a as r,u as t};
|
||||||
1
deployment/iw/web/assets/dist-AWHq1sQs.js
Normal file
1
deployment/iw/web/assets/dist-AWHq1sQs.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{A as e,O as t,Vn as n,Y as r,b as i,j as a,k as o,qn as s,sn as c,u as l,zn as u}from"./index-BaTxSAlR.js";import{n as d,t as f}from"./dist-CpxP8T7M.js";var p=s(n(),1),m=Object.defineProperty,h=(e,t)=>m(e,`name`,{value:t,configurable:!0}),g=!1;function _(){let[e,t]=p.useState(g);return p.useEffect(()=>{g||(g=!0,t(!0))},[]),e}h(_,`useIsHydrated`);var v=p.useSyncExternalStore;function y(){return()=>{}}h(y,`subscribe`);function b(){return v(y,()=>!0,()=>!1)}h(b,`useIsHydratedModern`);var x=typeof v==`function`?b:_,S=s(u(),1),C=Object.defineProperty,w=(e,t)=>C(e,`name`,{value:t,configurable:!0}),T=`rovingFocusGroup.onEntryFocus`,E={bubbles:!1,cancelable:!0},D=`RovingFocusGroup`,[O,k,A]=d(D),[j,M]=o(D,[A]),N={Vertical:`vertical`,Horizontal:`horizontal`},P={LTR:`ltr`,RTL:`rtl`},[F,I]=j(D),L=p.forwardRef(w(function(e,t){return(0,S.jsx)(O.Provider,{scope:e.__scopeRovingFocusGroup,children:(0,S.jsx)(O.Slot,{scope:e.__scopeRovingFocusGroup,children:(0,S.jsx)(R,{...e,ref:t})})})},`RovingFocusGroup`)),R=p.forwardRef(w(function(n,i){let{__scopeRovingFocusGroup:a,orientation:o,loop:s=!1,dir:u,currentTabStopId:d,defaultCurrentTabStopId:m,onCurrentTabStopIdChange:h,onEntryFocus:g,preventScrollOnEntryFocus:_=!1,...v}=n,y=p.useRef(null),b=c(i,y),x=f(u),[C,w]=l({prop:d,defaultProp:m??null,onChange:h,caller:D}),[O,A]=p.useState(!1),j=t(g),M=k(a),N=p.useRef(!1),[P,I]=p.useState(0);return p.useEffect(()=>{let e=y.current;if(e)return e.addEventListener(T,j),()=>e.removeEventListener(T,j)},[j]),(0,S.jsx)(F,{scope:a,orientation:o,dir:x,loop:s,currentTabStopId:C,onItemFocus:p.useCallback(e=>w(e),[w]),onItemShiftTab:p.useCallback(()=>A(!0),[]),onFocusableItemAdd:p.useCallback(()=>I(e=>e+1),[]),onFocusableItemRemove:p.useCallback(()=>I(e=>e-1),[]),children:(0,S.jsx)(r.div,{tabIndex:O||P===0?-1:0,"data-orientation":o,...v,ref:b,style:{outline:`none`,...n.style},onMouseDown:e(n.onMouseDown,()=>{N.current=!0}),onFocus:e(n.onFocus,e=>{let t=!N.current;if(e.target===e.currentTarget&&t&&!O){let t=new CustomEvent(T,E);if(e.currentTarget.dispatchEvent(t),!t.defaultPrevented){let e=M().filter(e=>e.focusable);W([e.find(e=>e.active),e.find(e=>e.id===C),...e].filter(Boolean).map(e=>e.ref.current),_)}}N.current=!1}),onBlur:e(n.onBlur,()=>A(!1))})})},`RovingFocusGroupImpl`)),z=`RovingFocusGroupItem`,B=p.forwardRef(w(function(t,n){let{__scopeRovingFocusGroup:o,focusable:s=!0,active:c=!1,tabStopId:l,children:u,...d}=t,f=i(),m=l||f,h=I(z,o),g=h.currentTabStopId===m,_=k(o),{onFocusableItemAdd:v,onFocusableItemRemove:y,currentTabStopId:b}=h,C=x();return a(()=>{if(!(!C||!s))return v(),()=>y()},[C,s,v,y]),p.useEffect(()=>{if(!(C||!s))return v(),()=>y()},[C,s,v,y]),(0,S.jsx)(O.ItemSlot,{scope:o,id:m,focusable:s,active:c,children:(0,S.jsx)(r.span,{tabIndex:g?0:-1,"data-orientation":h.orientation,...d,ref:n,onMouseDown:e(t.onMouseDown,e=>{s?h.onItemFocus(m):e.preventDefault()}),onFocus:e(t.onFocus,()=>h.onItemFocus(m)),onKeyDown:e(t.onKeyDown,e=>{if(e.key===`Tab`&&e.shiftKey){h.onItemShiftTab();return}if(e.target!==e.currentTarget)return;let t=U(e,h.orientation,h.dir);if(t!==void 0){if(e.metaKey||e.ctrlKey||e.altKey||e.shiftKey)return;e.preventDefault();let n=_().filter(e=>e.focusable).map(e=>e.ref.current);if(t===`last`)n.reverse();else if(t===`prev`||t===`next`){t===`prev`&&n.reverse();let r=n.indexOf(e.currentTarget);n=h.loop?G(n,r+1):n.slice(r+1)}setTimeout(()=>W(n))}}),children:typeof u==`function`?u({isCurrentTabStop:g,hasTabStop:b!=null}):u})})},`RovingFocusGroupItem`)),V={ArrowLeft:`prev`,ArrowUp:`prev`,ArrowRight:`next`,ArrowDown:`next`,PageUp:`first`,Home:`first`,PageDown:`last`,End:`last`};function H(e,t){return t===P.RTL?e===`ArrowLeft`?`ArrowRight`:e===`ArrowRight`?`ArrowLeft`:e:e}w(H,`getDirectionAwareKey`);function U(e,t,n){let r=H(e.key,n);if(!(t===N.Vertical&&[`ArrowLeft`,`ArrowRight`].includes(r))&&!(t===N.Horizontal&&[`ArrowUp`,`ArrowDown`].includes(r)))return V[r]}w(U,`getFocusIntent`);function W(e,t=!1){let n=document.activeElement;for(let r of e)if(r===n||(r.focus({preventScroll:t}),document.activeElement!==n))return}w(W,`focusFirst`);function G(e,t){return e.map((n,r)=>e[(t+r)%e.length])}w(G,`wrapArray`);export{B as n,M as r,L as t};
|
||||||
1
deployment/iw/web/assets/dist-CpxP8T7M.js
Normal file
1
deployment/iw/web/assets/dist-CpxP8T7M.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/edit-user-dialog-DTs4QrEM.js
Normal file
1
deployment/iw/web/assets/edit-user-dialog-DTs4QrEM.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{$ as e,Bt as t,G as n,H as r,It as i,Jt as a,K as o,Q as s,Qt as c,R as l,U as u,V as d,Vn as f,Vt as p,W as m,Zt as h,et as g,ln as _,q as v,qn as y,qt as b,tt as x,yn as S,z as C,zn as w,zt as T}from"./index-BaTxSAlR.js";import{a as E,n as D,o as O,r as k,s as A,t as j}from"./dialog-CnxDxMp1.js";const M=e=>{let{mutateAsync:n,isPending:r}=S({mutationFn:p,...e||{}}),{mutateAsync:a,isPending:o}=S({mutationFn:t,...e||{}}),{mutateAsync:s,isPending:c}=S({mutationFn:i,...e||{}}),l=e=>t=>{_.promise(e(t),{loading:`提交中...`,success:`操作成功`})};return{enable:l(n),disable:l(a),adminCancel:l(s),enableIsPending:r,disableIsPending:o,cancelIsPending:c}};var N=y(f(),1),P=y(w(),1),F=s({newPassword:e().nonempty({message:`新密码不能为空`}),confirmPassword:e().nonempty({message:`确认密码不能为空`})});function I({open:e,setOpen:t,data:i}){let{mutateAsync:s,isPending:l}=S({mutationFn:a,onSuccess(){t(!1)}}),f=x({resolver:g(F),defaultValues:{newPassword:``,confirmPassword:``}});(0,N.useEffect)(()=>{e&&f.reset()},[e]);let p=e=>{_.promise(s({...e,userId:i.userId??i.id}),{loading:`提交中...`,success:`修改成功`})};return(0,P.jsx)(j,{open:e,onOpenChange:t,children:(0,P.jsxs)(k,{className:`w-[400px]`,children:[(0,P.jsx)(O,{children:(0,P.jsx)(A,{children:`重置密码`})}),(0,P.jsx)(r,{...f,children:(0,P.jsxs)(`form`,{onSubmit:f.handleSubmit(p),className:`space-y-4`,children:[(0,P.jsx)(m,{control:f.control,name:`newPassword`,render:({field:e})=>(0,P.jsxs)(n,{children:[(0,P.jsx)(o,{children:`新密码`}),(0,P.jsx)(u,{children:(0,P.jsx)(d,{...e,type:`password`})}),(0,P.jsx)(v,{})]})}),(0,P.jsx)(m,{control:f.control,name:`confirmPassword`,render:({field:e})=>(0,P.jsxs)(n,{children:[(0,P.jsx)(o,{children:`确认密码`}),(0,P.jsx)(u,{children:(0,P.jsx)(d,{...e,type:`password`})}),(0,P.jsx)(v,{})]})}),(0,P.jsxs)(E,{children:[(0,P.jsx)(D,{asChild:!0,children:(0,P.jsx)(c,{variant:`outline`,children:`取消`})}),(0,P.jsxs)(c,{type:`submit`,disabled:l,children:[l&&(0,P.jsx)(h,{}),`确定`]})]})]})})]})})}const L=e=>{let{mutateAsync:t,isPending:n}=S({mutationFn:e=>e.id?b(e):T(e),...e||{}});return{save:e=>{_.promise(t(e),{loading:`提交中...`,success:`操作成功`})},saveIsPending:n}};var R=`Qaz123567!@#`,z=t=>s({phone:t?e().nonempty({message:`手机号不能为空`}):e().optional(),username:t?e().optional():e().nonempty({message:`用户名不能为空`}),realName:e().nonempty({message:`真实姓名不能为空`})});function B({open:e,setOpen:t,refetch:i,data:a}){let s=(a==null?void 0:a.userId)??(a==null?void 0:a.id),f=(0,N.useMemo)(()=>!s,[s]),p=x({resolver:g((0,N.useMemo)(()=>z(f),[f])),defaultValues:{phone:``,username:``,realName:``}}),_=p.watch(`phone`),{save:y,saveIsPending:b}=L({onSuccess(){t(!1),i==null||i()}});(0,N.useEffect)(()=>{e&&(p.reset(),a&&(p.setValue(`username`,(a==null?void 0:a.username)||``),p.setValue(`realName`,(a==null?void 0:a.realName)||``)))},[e,a,p]);let S=e=>{y({id:s,...e})};return(0,P.jsx)(j,{open:e,onOpenChange:t,children:(0,P.jsxs)(k,{className:`w-[400px]`,children:[(0,P.jsx)(O,{children:(0,P.jsx)(A,{children:f?`创建用户`:`修改用户`})}),(0,P.jsx)(r,{...p,children:(0,P.jsxs)(`form`,{onSubmit:p.handleSubmit(S),className:`space-y-4`,children:[(0,P.jsx)(m,{control:p.control,name:f?`phone`:`username`,render:({field:e})=>(0,P.jsxs)(n,{children:[(0,P.jsx)(o,{children:`手机号`}),(0,P.jsx)(u,{children:(0,P.jsx)(d,{...e})}),(0,P.jsx)(v,{})]})}),(0,P.jsx)(m,{control:p.control,name:`realName`,render:({field:e})=>(0,P.jsxs)(n,{children:[(0,P.jsx)(o,{children:`真实姓名`}),(0,P.jsx)(u,{children:(0,P.jsx)(d,{...e})}),(0,P.jsx)(v,{})]})}),f&&(0,P.jsx)(l,{children:(0,P.jsxs)(C,{children:[(0,P.jsxs)(`div`,{children:[`用户账号:`,_]}),(0,P.jsxs)(`div`,{children:[`初始密码:`,R]})]})}),(0,P.jsxs)(E,{children:[(0,P.jsx)(D,{asChild:!0,children:(0,P.jsx)(c,{variant:`outline`,children:`取消`})}),(0,P.jsxs)(c,{type:`submit`,disabled:b,children:[b&&(0,P.jsx)(h,{}),`确定`]})]})]})})]})})}export{I as n,M as r,B as t};
|
||||||
5
deployment/iw/web/assets/es-6YDPW35u.js
Normal file
5
deployment/iw/web/assets/es-6YDPW35u.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/extract-sa8PNFSm.js
Normal file
1
deployment/iw/web/assets/extract-sa8PNFSm.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{t as e}from"./useLocation-B-0SqFIj.js";import{$ as t,G as n,H as r,I as i,K as a,L as o,Q as s,Qt as c,U as l,V as u,W as d,Zt as f,_n as p,en as m,et as h,ln as g,mn as _,nn as v,q as y,qn as b,rt as x,tt as S,un as C,xt as w,yn as T,zn as E}from"./index-BaTxSAlR.js";var D=b(E(),1);function O({className:e,...t}){return(0,D.jsx)(`div`,{"data-slot":`empty`,className:m(`flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12`,e),...t})}function k({className:e,...t}){return(0,D.jsx)(`div`,{"data-slot":`empty-header`,className:m(`flex max-w-sm flex-col items-center gap-2 text-center`,e),...t})}var A=v(`flex shrink-0 items-center justify-center mb-2 [&_svg]:pointer-events-none [&_svg]:shrink-0`,{variants:{variant:{default:`bg-transparent`,icon:`bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6`}},defaultVariants:{variant:`default`}});function j({className:e,variant:t=`default`,...n}){return(0,D.jsx)(`div`,{"data-slot":`empty-icon`,"data-variant":t,className:m(A({variant:t,className:e})),...n})}function M({className:e,...t}){return(0,D.jsx)(`div`,{"data-slot":`empty-title`,className:m(`text-lg font-medium tracking-tight`,e),...t})}var N=s({accessCode:t().length(6,{message:`提取码只能是6位`}).nonempty({message:`提取码不能为空`})}),P=`森睿智传`;function F(){let t=p(),s=S({resolver:h(N),defaultValues:{accessCode:``}}),m=i.useSearch(),{mutateAsync:v,isPending:b}=T({mutationFn:e=>w(e),onSuccess(e,n){t.navigate({to:`/extract/list?accessCode=`+n.accessCode+`&shareId=`+n.shareId})}}),E=e=>{g.promise(v({...m,...e}),{loading:`校验中`,success:`校验通过`})},A=x(),F=e();return!A&&F.pathname===`/extract`?(0,D.jsx)(_,{to:`/login?redirect=`+encodeURIComponent(encodeURIComponent(F.href))}):(0,D.jsx)(`div`,{className:`flex items-center justify-center min-h-screen box-border`,children:(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{className:`flex justify-center items-center mb-4 gap-2`,children:[(0,D.jsx)(`img`,{src:o,alt:``,className:`size-12 object-contain rounded-full bg-white overflow-hidden`}),(0,D.jsx)(`div`,{className:`text-3xl`,children:P})]}),(0,D.jsxs)(`div`,{className:`w-[480px] p-10 bg-white rounded-xl`,children:[(0,D.jsx)(`div`,{className:`text-center text-2xl`,children:`文件提取`}),m.shareId?(0,D.jsx)(r,{...s,children:(0,D.jsxs)(`form`,{onSubmit:s.handleSubmit(E),className:`space-y-8 mt-12`,children:[(0,D.jsx)(d,{control:s.control,name:`accessCode`,render:({field:e})=>(0,D.jsxs)(n,{children:[(0,D.jsx)(a,{children:`提取码`}),(0,D.jsx)(l,{children:(0,D.jsx)(u,{placeholder:`请输入提取码`,...e})}),(0,D.jsx)(y,{})]})}),(0,D.jsxs)(c,{type:`submit`,className:`w-full`,disabled:b,children:[b&&(0,D.jsx)(f,{}),`提交`]})]})}):(0,D.jsx)(O,{children:(0,D.jsxs)(k,{children:[(0,D.jsx)(j,{variant:`default`,children:(0,D.jsx)(C,{size:24})}),(0,D.jsx)(M,{children:`无效的分享链接`})]})})]})]})})}export{F as component};
|
||||||
1
deployment/iw/web/assets/file-COj1kCUn.js
Normal file
1
deployment/iw/web/assets/file-COj1kCUn.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{fn as e}from"./index-BaTxSAlR.js";var t=e(`file`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}]]);export{t};
|
||||||
82
deployment/iw/web/assets/file-category-filter-BIAErrxo.js
Normal file
82
deployment/iw/web/assets/file-category-filter-BIAErrxo.js
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
pre code.hljs{padding:1em;display:block;overflow-x:auto}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}
|
||||||
1
deployment/iw/web/assets/file-record-xAA0hSRQ.js
Normal file
1
deployment/iw/web/assets/file-record-xAA0hSRQ.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/file-type-BBx4p_T6.js
Normal file
1
deployment/iw/web/assets/file-type-BBx4p_T6.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{fn as e}from"./index-BaTxSAlR.js";var t=e(`file-image`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`circle`,{cx:`10`,cy:`12`,r:`2`,key:`737tya`}],[`path`,{d:`m20 17-1.296-1.296a2.41 2.41 0 0 0-3.408 0L9 22`,key:`wt3hpn`}]]),n=e(`file-play`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M15.033 13.44a.647.647 0 0 1 0 1.12l-4.065 2.352a.645.645 0 0 1-.968-.56v-4.704a.645.645 0 0 1 .967-.56z`,key:`1tzo1f`}]]),r=e(`file-type`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M11 18h2`,key:`12mj7e`}],[`path`,{d:`M12 12v6`,key:`3ahymv`}],[`path`,{d:`M9 13v-.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 .5.5v.5`,key:`qbrxap`}]]);export{n,t as r,r as t};
|
||||||
1
deployment/iw/web/assets/folder-Dl7FxCLT.js
Normal file
1
deployment/iw/web/assets/folder-Dl7FxCLT.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{fn as e}from"./index-BaTxSAlR.js";var t=e(`folder`,[[`path`,{d:`M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z`,key:`1kt360`}]]);export{t};
|
||||||
1
deployment/iw/web/assets/folder-input--tEWrMtP.js
Normal file
1
deployment/iw/web/assets/folder-input--tEWrMtP.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{fn as e}from"./index-BaTxSAlR.js";var t=e(`folder-input`,[[`path`,{d:`M2 9V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-1`,key:`fm4g5t`}],[`path`,{d:`M2 13h10`,key:`pgb2dq`}],[`path`,{d:`m9 16 3-3-3-3`,key:`6m91ic`}]]);export{t};
|
||||||
118
deployment/iw/web/assets/index-BaTxSAlR.js
Normal file
118
deployment/iw/web/assets/index-BaTxSAlR.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/index-BbZGMJ6u.css
Normal file
1
deployment/iw/web/assets/index-BbZGMJ6u.css
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/inside-BDK478rm.js
Normal file
1
deployment/iw/web/assets/inside-BDK478rm.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{n as e,t}from"./file-category-filter-BIAErrxo.js";import{t as n}from"./file-COj1kCUn.js";import{t as r}from"./folder-input--tEWrMtP.js";import{t as i}from"./folder-Dl7FxCLT.js";import{n as a,t as o}from"./remove-file-dialog-cN0TGs4y.js";import{F as s,M as c,Qt as l,Vn as u,ct as d,lt as f,pt as p,qn as m,st as h,tn as g,zn as _}from"./index-BaTxSAlR.js";import{t as v}from"./directory-breadcrumb-u3uCxukv.js";import{t as y}from"./data-table-CEq6a930.js";import{t as b}from"./pagination-Bragnnjj.js";import{t as x}from"./use-fetch-files-rnWwNE4C.js";import"./dialog-CnxDxMp1.js";var S=m(u()),C=m(_());function w({handleChangeParentId:e,handleMove:t,handleRemove:a,handleFilePreview:o}){return[{accessorKey:`fileName`,header:`文件名`,cell:({row:t})=>{var a;return(0,C.jsxs)(`div`,{className:`flex items-center gap-1 break-all cursor-pointer hover:underline hover:text-primary group`,onClick:()=>{var n;(t==null||(n=t.original)==null?void 0:n.fileType)===d.DIRECTORY?e(t==null?void 0:t.original):o(t==null?void 0:t.original)},children:[(t==null||(a=t.original)==null?void 0:a.fileType)===d.FILE?(0,C.jsx)(C.Fragment,{children:(0,C.jsx)(n,{size:18,className:`text-primary`})}):(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(i,{size:18,className:`text-amber-500 group-hover:hidden`}),(0,C.jsx)(r,{size:18,className:`text-amber-500 group-hover:block hidden`})]}),(0,C.jsx)(`span`,{children:t.getValue(`fileName`)})]})}},{accessorKey:`createTime`,header:`创建日期`,cell:({row:e})=>(0,C.jsx)(`div`,{children:e.getValue(`createTime`)})},{accessorKey:`fileSize`,header:`文件大小`,cell:({row:e})=>(0,C.jsx)(`div`,{children:g(e.getValue(`fileSize`))})},{accessorKey:`fileCategory`,header:`文件种类`,cell:({row:e})=>(0,C.jsx)(`div`,{children:e.original.fileType===d.FILE?s(e.getValue(`fileCategory`)):`-`})},{accessorKey:`fileStatus`,header:()=>(0,C.jsx)(`div`,{className:`text-center`,children:`状态`}),cell:({row:e})=>(0,C.jsx)(`div`,{className:`text-center`,children:(0,C.jsx)(c,{status:e.original.fileStatus})})},{id:`actions`,enableHiding:!1,header:`操作`,cell:({row:e})=>{let n=e.original;return(0,C.jsxs)(`div`,{className:`space-x-2`,children:[(0,C.jsx)(l,{size:`sm`,variant:`destructive`,onClick:()=>a(e.original),children:`删除`}),(0,C.jsx)(l,{size:`sm`,variant:`outline`,onClick:()=>t(e.original),children:`移动`}),n.fileType===d.FILE&&(0,C.jsx)(l,{variant:`outline`,size:`sm`,onClick:()=>{p({code:n.fileCode})},children:`下载`})]})}}]}function T(){let[n,r]=(0,S.useState)(null),[i,s]=(0,S.useState)(!1),c=e=>{r(e),s(!0)},[l,u]=(0,S.useState)(!1),d=e=>{r(e),u(!0)},[p,m]=(0,S.useState)(!1),g=e=>{r(e),m(!0)},[_,T]=(0,S.useState)(`all`),E=(0,S.useMemo)(()=>({rootType:f.INSIDE,fileStatusIn:[h.VALID,h.PARSING,h.TRANSFERING,h.FAILED].join(`,`),fileCategory:_===`all`?void 0:_}),[_]),{openDirectorys:D,changeOpenDirectorys:O,table:k,query:A,reset:j}=x({useColumns:e=>w({handleChangeParentId:e,handleMove:c,handleRemove:d,handleFilePreview:g}),queryKey:[`insideFiles`],params:E});return(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(a,{open:i,setOpen:s,data:n,params:E,refetch:A.refetch}),(0,C.jsx)(o,{open:l,setOpen:u,data:n,refetch:A.refetch}),(0,C.jsx)(e,{open:p,setOpen:m,data:n}),(0,C.jsxs)(`div`,{className:`p-4 box-border min-h-full space-y-4`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-lg`,children:`我的发送`}),(0,C.jsx)(`div`,{className:`text-xs text-black/50`,children:`文件传输的状态`})]}),(0,C.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,C.jsx)(t,{fileCategory:_,setFileCategory:T,reset:j})}),(0,C.jsxs)(`div`,{className:`p-4 rounded-lg border bg-white space-y-2`,children:[(0,C.jsx)(v,{directorys:D,onChangeDirectorys:O}),(0,C.jsxs)(`div`,{className:`relative overflow-hidden`,children:[(0,C.jsx)(y,{table:k,query:A}),(0,C.jsx)(b,{table:k,className:`justify-end p-2 sticky bottom-0 left-0 right-0 z-10 bg-white`})]})]})]})]})}export{T as component,w as useColumns};
|
||||||
1
deployment/iw/web/assets/list-DFASxSFf.js
Normal file
1
deployment/iw/web/assets/list-DFASxSFf.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{t as e}from"./useQuery-dxbdhNvu.js";import{n as t,t as n}from"./file-category-filter-BIAErrxo.js";import{t as r}from"./file-COj1kCUn.js";import{t as i}from"./folder-input--tEWrMtP.js";import{t as a}from"./folder-Dl7FxCLT.js";import{F as o,P as s,Qt as c,Vn as l,ct as u,pt as d,qn as f,tn as p,xt as m,zn as h}from"./index-BaTxSAlR.js";import{t as g}from"./directory-breadcrumb-u3uCxukv.js";import{n as _,r as v,t as y}from"./data-table-CEq6a930.js";import"./dialog-CnxDxMp1.js";var b=f(l(),1);const x=(t,n,r)=>{let[i,a]=(0,b.useState)([]),[o,s]=(0,b.useState)(0),c=e({queryKey:[`shareFileList`,o],queryFn:()=>m({...n,...r,parentId:o}).then(e=>e.data)}),l=e=>{s(e.id),a(t=>[...t,e])},u=t(l);return{parentId:o,handleChangeParentId:l,openDirectorys:i,changeOpenDirectorys:e=>{s(e==null?void 0:e.id),a(t=>{let n=t.findIndex(t=>t.id===(e==null?void 0:e.id));return n>-1?[...t.slice(0,n+1)]:[]})},table:_({data:(c==null?void 0:c.data)||[],columns:u,getCoreRowModel:v()}),query:c,reset:()=>{a([]),s(0)}}};var S=f(h());function C(e,t){return[{accessorKey:`fileName`,header:`文件名`,cell:({row:n})=>{var o;return(0,S.jsxs)(`div`,{className:`flex items-center gap-1 break-all cursor-pointer hover:underline hover:text-primary group`,onClick:()=>{var r;(n==null||(r=n.original)==null?void 0:r.fileType)===u.DIRECTORY?e(n==null?void 0:n.original):t(n==null?void 0:n.original)},children:[(n==null||(o=n.original)==null?void 0:o.fileType)===u.FILE?(0,S.jsx)(S.Fragment,{children:(0,S.jsx)(r,{size:18,className:`text-primary`})}):(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(a,{size:18,className:`text-amber-500 group-hover:hidden`}),(0,S.jsx)(i,{size:18,className:`text-amber-500 group-hover:block hidden`})]}),(0,S.jsx)(`span`,{children:n.getValue(`fileName`)})]})}},{accessorKey:`createTime`,header:`创建日期`,cell:({row:e})=>(0,S.jsx)(`div`,{children:e.getValue(`createTime`)})},{accessorKey:`fileSize`,header:`文件大小`,cell:({row:e})=>(0,S.jsx)(`div`,{children:p(e.getValue(`fileSize`))})},{accessorKey:`fileCategory`,header:`文件种类`,cell:({row:e})=>(0,S.jsx)(`div`,{children:e.original.fileType===u.FILE?o(e.getValue(`fileCategory`)):`-`})},{id:`actions`,enableHiding:!1,header:`操作`,cell:({row:e})=>{let t=e.original;return(0,S.jsx)(`div`,{className:`space-x-2`,children:t.fileType===u.FILE&&(0,S.jsx)(c,{variant:`outline`,size:`sm`,onClick:()=>{d({code:t.fileCode})},children:`下载`})})}}]}function w(){let e=s.useSearch(),[r,i]=(0,b.useState)(null),[a,o]=(0,b.useState)(!1),c=e=>{i(e),o(!0)},[l,u]=(0,b.useState)(`all`),{table:d,query:f,openDirectorys:p,changeOpenDirectorys:m,reset:h}=x(e=>C(e,c),e,(0,b.useMemo)(()=>({fileCategory:l===`all`?void 0:l}),[l]));return(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(t,{open:a,setOpen:o,data:r}),(0,S.jsx)(`div`,{className:`p-4 min-h-screen`,children:(0,S.jsxs)(`div`,{className:`rounded-xl bg-white/50 backdrop-blur-lg min-h-full space-y-4 p-4`,children:[(0,S.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,S.jsx)(n,{fileCategory:l,setFileCategory:u,reset:h})}),(0,S.jsxs)(`div`,{className:`p-4 rounded-lg border bg-white space-y-2`,children:[(0,S.jsx)(g,{directorys:p,onChangeDirectorys:m}),(0,S.jsx)(`div`,{className:`relative overflow-hidden`,children:(0,S.jsx)(y,{table:d,query:f})})]})]})})]})}export{w as component,C as useColumns};
|
||||||
1
deployment/iw/web/assets/login-AXVtM6Py.js
Normal file
1
deployment/iw/web/assets/login-AXVtM6Py.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{n as e,t}from"./radio-group-dGI8aZOA.js";import{$ as n,G as r,H as i,J as a,K as o,L as s,N as c,Q as l,Qt as u,U as d,Ut as f,V as p,Vn as m,W as h,Wt as g,Zt as _,_n as v,et as y,ln as b,ot as x,q as S,qn as C,tt as w,yn as T,zn as E}from"./index-BaTxSAlR.js";var D=C(m()),O=C(E()),k=l({username:n().min(2,{message:`账号只能是4~16个字符`}),password:n().min(2,{message:`密码只能是4~32个字符`})}),A=`森睿智传`;function j(){let n=v(),[l,m]=(0,D.useState)(null),[C,E]=(0,D.useState)(``),j=w({resolver:y(k),defaultValues:{username:``,password:``}}),M=e=>{x.setState({token:e.data.token}),n.navigate({to:decodeURIComponent(decodeURIComponent(n.state.location.search.redirect||`/`)),replace:!0})},{mutateAsync:N,isPending:P}=T({mutationFn:async e=>{try{return await f(e)}catch(e){var t;if((e==null?void 0:e.code)===`600`&&!(e==null||(t=e.errorData)==null||(t=t.orgs)==null)&&t.length)return{needSelectOrg:!0,...e.errorData};throw e}},onSuccess(e){if(e!=null&&e.needSelectOrg){E(String(e.orgs[0].orgId)),m({tempToken:e.tempToken,orgs:e.orgs});return}M(e)}}),{mutateAsync:F,isPending:I}=T({mutationFn:e=>g(e.tempToken,e.orgId),onSuccess(e){M(e)}}),L=e=>{let t=N({...e,userType:1});b.promise(t,{loading:`登录中...`,success:e=>e!=null&&e.needSelectOrg?`请选择机构`:`登录成功`})};return(0,O.jsx)(`div`,{className:`flex items-center justify-center min-h-screen box-border`,children:(0,O.jsxs)(`div`,{children:[(0,O.jsxs)(`div`,{className:`flex justify-center items-center mb-4 gap-2`,children:[(0,O.jsx)(`img`,{src:s,alt:``,className:`size-12 object-contain rounded-full bg-white overflow-hidden`}),(0,O.jsx)(`div`,{className:`text-3xl`,children:A})]}),(0,O.jsx)(`div`,{className:`w-[480px] p-10 bg-white rounded-xl`,children:l?(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)(`div`,{className:`text-center text-2xl`,children:`选择机构`}),(0,O.jsx)(`div`,{className:`text-center text-sm text-black/50 mt-2`,children:`当前账号属于多个机构,请选择要登录的机构`}),(0,O.jsx)(t,{value:C,onValueChange:E,className:`space-y-1 mt-8`,children:l.orgs.map(t=>(0,O.jsxs)(`div`,{onClick:()=>E(String(t.orgId)),className:`flex items-center gap-3 rounded-lg border p-3 cursor-pointer transition-colors ${C===String(t.orgId)?`border-primary bg-primary/10`:`hover:bg-black/5`}`,children:[(0,O.jsx)(e,{value:String(t.orgId),id:`org-${t.orgId}`}),(0,O.jsxs)(a,{htmlFor:`org-${t.orgId}`,className:`flex items-center gap-2 flex-1 cursor-pointer`,children:[(0,O.jsx)(`span`,{children:t.orgName}),t.administrator&&(0,O.jsx)(c,{variant:`outline`,className:`text-primary border-primary`,children:`管理员`})]})]},t.orgId))}),(0,O.jsxs)(`div`,{className:`space-y-3 mt-8`,children:[(0,O.jsxs)(u,{className:`w-full`,disabled:I||!C,onClick:()=>{if(!C||!l)return;let e=F({tempToken:l.tempToken,orgId:C});b.promise(e,{loading:`登录中...`,success:`登录成功`})},children:[I&&(0,O.jsx)(_,{}),`进入系统`]}),(0,O.jsx)(u,{variant:`outline`,className:`w-full`,disabled:I,onClick:()=>m(null),children:`返回登录`})]})]}):(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)(`div`,{className:`text-center text-2xl`,children:`用户登录`}),(0,O.jsx)(i,{...j,children:(0,O.jsxs)(`form`,{onSubmit:j.handleSubmit(L),className:`space-y-8 mt-12`,children:[(0,O.jsx)(h,{control:j.control,name:`username`,render:({field:e})=>(0,O.jsxs)(r,{children:[(0,O.jsx)(o,{children:`用户名`}),(0,O.jsx)(d,{children:(0,O.jsx)(p,{placeholder:`用户名`,...e})}),(0,O.jsx)(S,{})]})}),(0,O.jsx)(h,{control:j.control,name:`password`,render:({field:e})=>(0,O.jsxs)(r,{children:[(0,O.jsx)(o,{children:`密码`}),(0,O.jsx)(d,{children:(0,O.jsx)(p,{type:`password`,placeholder:`密码`,...e})}),(0,O.jsx)(S,{})]})}),(0,O.jsxs)(u,{type:`submit`,className:`w-full`,disabled:P,children:[P&&(0,O.jsx)(_,{}),`提交`]})]})})]})})]})})}export{j as component};
|
||||||
BIN
deployment/iw/web/assets/logo-CE4fGrmK.png
Normal file
BIN
deployment/iw/web/assets/logo-CE4fGrmK.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 378 KiB |
3
deployment/iw/web/assets/my-C6gzFuIT.js
Normal file
3
deployment/iw/web/assets/my-C6gzFuIT.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/org-CX5LJyS0.js
Normal file
1
deployment/iw/web/assets/org-CX5LJyS0.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{Yt as e}from"./index-BaTxSAlR.js";const t=t=>e.get(`/user/page/platform_user`,{params:t}),n=t=>e.post(`/uc/org/create`,t),r=t=>e.put(`/uc/org/modify`,t),i=t=>e.get(`/uc/org/page`,{params:t});export{r as i,i as n,t as r,n as t};
|
||||||
1
deployment/iw/web/assets/org-account-BvqGo47r.js
Normal file
1
deployment/iw/web/assets/org-account-BvqGo47r.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/outside-DtRMqIkz.js
Normal file
1
deployment/iw/web/assets/outside-DtRMqIkz.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{n as e,t}from"./file-category-filter-BIAErrxo.js";import{t as n}from"./file-COj1kCUn.js";import{t as r}from"./folder-input--tEWrMtP.js";import{t as i}from"./folder-Dl7FxCLT.js";import{n as a,t as o}from"./remove-file-dialog-cN0TGs4y.js";import{F as s,M as c,Qt as l,Vn as u,ct as d,lt as f,pt as p,qn as m,st as h,tn as g,zn as _}from"./index-BaTxSAlR.js";import{t as v}from"./directory-breadcrumb-u3uCxukv.js";import{t as y}from"./data-table-CEq6a930.js";import{t as b}from"./pagination-Bragnnjj.js";import{t as x}from"./use-fetch-files-rnWwNE4C.js";import"./dialog-CnxDxMp1.js";var S=m(u()),C=m(_());function w({handleChangeParentId:e,handleMove:t,handleRemove:a,handleFilePreview:o}){return[{accessorKey:`fileName`,header:`文件名`,cell:({row:t})=>{var a;return(0,C.jsxs)(`div`,{className:`flex items-center gap-1 break-all cursor-pointer hover:underline hover:text-primary group`,onClick:()=>{var n;(t==null||(n=t.original)==null?void 0:n.fileType)===d.DIRECTORY?e(t==null?void 0:t.original):o(t==null?void 0:t.original)},children:[(t==null||(a=t.original)==null?void 0:a.fileType)===d.FILE?(0,C.jsx)(C.Fragment,{children:(0,C.jsx)(n,{size:18,className:`text-primary`})}):(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(i,{size:18,className:`text-amber-500 group-hover:hidden`}),(0,C.jsx)(r,{size:18,className:`text-amber-500 group-hover:block hidden`})]}),(0,C.jsx)(`span`,{children:t.getValue(`fileName`)})]})}},{accessorKey:`createTime`,header:`创建日期`,cell:({row:e})=>(0,C.jsx)(`div`,{children:e.getValue(`createTime`)})},{accessorKey:`fileSize`,header:`文件大小`,cell:({row:e})=>(0,C.jsx)(`div`,{children:g(e.getValue(`fileSize`))})},{accessorKey:`fileCategory`,header:`文件种类`,cell:({row:e})=>(0,C.jsx)(`div`,{children:e.original.fileType===d.FILE?s(e.getValue(`fileCategory`)):`-`})},{accessorKey:`fileStatus`,header:()=>(0,C.jsx)(`div`,{className:`text-center`,children:`状态`}),cell:({row:e})=>(0,C.jsx)(`div`,{className:`text-center`,children:(0,C.jsx)(c,{status:e.original.fileStatus})})},{id:`actions`,enableHiding:!1,header:`操作`,cell:({row:e})=>{let n=e.original;return(0,C.jsxs)(`div`,{className:`space-x-2`,children:[(0,C.jsx)(l,{size:`sm`,variant:`destructive`,onClick:()=>a(e.original),children:`删除`}),(0,C.jsx)(l,{size:`sm`,variant:`outline`,onClick:()=>t(e.original),children:`移动`}),n.fileType===d.FILE&&(0,C.jsx)(l,{variant:`outline`,size:`sm`,onClick:()=>{p({code:n.fileCode})},children:`下载`})]})}}]}function T(){let[n,r]=(0,S.useState)(null),[i,s]=(0,S.useState)(!1),c=e=>{r(e),s(!0)},[l,u]=(0,S.useState)(!1),d=e=>{r(e),u(!0)},[p,m]=(0,S.useState)(!1),g=e=>{r(e),m(!0)},[_,T]=(0,S.useState)(`all`),E=(0,S.useMemo)(()=>({rootType:f.OUTSIDE,fileStatusIn:[h.VALID,h.PARSING,h.TRANSFERING,h.FAILED].join(`,`),fileCategory:_===`all`?void 0:_}),[_]),{openDirectorys:D,changeOpenDirectorys:O,table:k,query:A,reset:j}=x({useColumns:e=>w({handleChangeParentId:e,handleMove:c,handleRemove:d,handleFilePreview:g}),queryKey:[`outsideFiles`],params:E});return(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(a,{open:i,setOpen:s,data:n,params:E,refetch:A.refetch}),(0,C.jsx)(o,{open:l,setOpen:u,data:n,refetch:A.refetch}),(0,C.jsx)(e,{open:p,setOpen:m,data:n}),(0,C.jsxs)(`div`,{className:`p-4 box-border min-h-full space-y-4`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-lg`,children:`我的接收`}),(0,C.jsx)(`div`,{className:`text-xs text-black/50`,children:`文件传输的状态`})]}),(0,C.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,C.jsx)(t,{fileCategory:_,setFileCategory:T,reset:j})}),(0,C.jsxs)(`div`,{className:`p-4 rounded-lg border bg-white space-y-2`,children:[(0,C.jsx)(v,{directorys:D,onChangeDirectorys:O}),(0,C.jsxs)(`div`,{className:`relative overflow-hidden`,children:[(0,C.jsx)(y,{table:k,query:A}),(0,C.jsx)(b,{table:k,className:`justify-end p-2 sticky bottom-0 left-0 right-0 z-10 bg-white`})]})]})]})]})}export{T as component,w as useColumns};
|
||||||
1
deployment/iw/web/assets/pagination-Bragnnjj.js
Normal file
1
deployment/iw/web/assets/pagination-Bragnnjj.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/plus-BHIlMeNy.js
Normal file
1
deployment/iw/web/assets/plus-BHIlMeNy.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{fn as e}from"./index-BaTxSAlR.js";var t=e(`plus`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`M12 5v14`,key:`s699le`}]]);export{t};
|
||||||
1
deployment/iw/web/assets/prop-types-BuNDdpC2.js
Normal file
1
deployment/iw/web/assets/prop-types-BuNDdpC2.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{Hn as e}from"./index-BaTxSAlR.js";var t=e(((e,t)=>{t.exports=`SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED`})),n=e(((e,n)=>{var r=t();function i(){}function a(){}a.resetWarningCache=i,n.exports=function(){function e(e,t,n,i,a,o){if(o!==r){var s=Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name=`Invariant Violation`,s}}e.isRequired=e;function t(){return e}var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:i};return n.PropTypes=n,n}})),r=e(((e,t)=>{t.exports=n()()}));export{r as t};
|
||||||
1
deployment/iw/web/assets/radio-group-dGI8aZOA.js
Normal file
1
deployment/iw/web/assets/radio-group-dGI8aZOA.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/recycle-CSeB7_Hw.js
Normal file
1
deployment/iw/web/assets/recycle-CSeB7_Hw.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/remove-file-dialog-cN0TGs4y.js
Normal file
1
deployment/iw/web/assets/remove-file-dialog-cN0TGs4y.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/route-C-dN6SG2.js
Normal file
1
deployment/iw/web/assets/route-C-dN6SG2.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{t as e}from"./app-layout-D4ftBqmM.js";import{t}from"./shield-alert-XSqo2W3w.js";import{at as n,fn as r,qn as i,zn as a}from"./index-BaTxSAlR.js";import"./dialog-CnxDxMp1.js";var o=r(`building-2`,[[`path`,{d:`M10 12h4`,key:`a56b0p`}],[`path`,{d:`M10 8h4`,key:`1sr2af`}],[`path`,{d:`M14 21v-3a2 2 0 0 0-4 0v3`,key:`1rgiei`}],[`path`,{d:`M6 10H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-2`,key:`secmi2`}],[`path`,{d:`M6 21V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v16`,key:`16ra0t`}]]),s=r(`cloud-upload`,[[`path`,{d:`M12 13v8`,key:`1l5pq0`}],[`path`,{d:`M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242`,key:`1pljnt`}],[`path`,{d:`m8 17 4-4 4 4`,key:`1quai1`}]]),c=r(`file-search`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`circle`,{cx:`11.5`,cy:`14.5`,r:`2.5`,key:`1bq0ko`}],[`path`,{d:`M13.3 16.3 15 18`,key:`2quom7`}]]),l=r(`user-round-pen`,[[`path`,{d:`M2 21a8 8 0 0 1 10.821-7.487`,key:`1c8h7z`}],[`path`,{d:`M21.378 16.626a1 1 0 0 0-3.004-3.004l-4.01 4.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z`,key:`1817ys`}],[`circle`,{cx:`10`,cy:`8`,r:`5`,key:`o932ke`}]]),u=r(`users`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`path`,{d:`M16 3.128a4 4 0 0 1 0 7.744`,key:`16gr8j`}],[`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`,key:`kshegd`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}]]),d=i(a()),f=[{title:`单位管理`,url:`/admin/tenant`,icon:(0,d.jsx)(o,{})},{title:`用户管理`,url:`/admin/user`,icon:(0,d.jsx)(l,{})},{title:`上传配置`,url:`/admin/upload-config`,icon:(0,d.jsx)(s,{})},{title:`机构账号`,url:`/admin/org-account`,icon:(0,d.jsx)(u,{})},{title:`记录查询`,url:`/admin/file-record`,icon:(0,d.jsx)(c,{})},{title:`审核`,url:`/admin/console`,icon:(0,d.jsx)(t,{})}],p=[`/admin/tenant`,`/admin/org-account`,`/admin/file-record`];function m(){let t=n();return(0,d.jsx)(e,{menus:f.filter(e=>t||!p.includes(e.url)),isAdmin:!0})}export{m as component};
|
||||||
1
deployment/iw/web/assets/route-yMj8live.js
Normal file
1
deployment/iw/web/assets/route-yMj8live.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{t as e}from"./folder-input--tEWrMtP.js";import{t}from"./folder-Dl7FxCLT.js";import{t as n}from"./app-layout-D4ftBqmM.js";import{fn as r,qn as i,zn as a}from"./index-BaTxSAlR.js";import"./dialog-CnxDxMp1.js";var o=r(`folder-output`,[[`path`,{d:`M2 7.5V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-1.5`,key:`1yk7aj`}],[`path`,{d:`M2 13h10`,key:`pgb2dq`}],[`path`,{d:`m5 10-3 3 3 3`,key:`1r8ie0`}]]),s=r(`house`,[[`path`,{d:`M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8`,key:`5wwlr5`}],[`path`,{d:`M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`,key:`r6nss1`}]]),c=r(`recycle`,[[`path`,{d:`M7 19H4.815a1.83 1.83 0 0 1-1.57-.881 1.785 1.785 0 0 1-.004-1.784L7.196 9.5`,key:`x6z5xu`}],[`path`,{d:`M11 19h8.203a1.83 1.83 0 0 0 1.556-.89 1.784 1.784 0 0 0 0-1.775l-1.226-2.12`,key:`1x4zh5`}],[`path`,{d:`m14 16-3 3 3 3`,key:`f6jyew`}],[`path`,{d:`M8.293 13.596 7.196 9.5 3.1 10.598`,key:`wf1obh`}],[`path`,{d:`m9.344 5.811 1.093-1.892A1.83 1.83 0 0 1 11.985 3a1.784 1.784 0 0 1 1.546.888l3.943 6.843`,key:`9tzpgr`}],[`path`,{d:`m13.378 9.633 4.096 1.098 1.097-4.096`,key:`1oe83g`}]]),l=r(`share-2`,[[`circle`,{cx:`18`,cy:`5`,r:`3`,key:`gq8acd`}],[`circle`,{cx:`6`,cy:`12`,r:`3`,key:`w7nqdw`}],[`circle`,{cx:`18`,cy:`19`,r:`3`,key:`1xt0gg`}],[`line`,{x1:`8.59`,x2:`15.42`,y1:`13.51`,y2:`17.49`,key:`47mynk`}],[`line`,{x1:`15.41`,x2:`8.59`,y1:`6.51`,y2:`10.49`,key:`1n3mei`}]]),u=i(a()),d=[{title:`首页`,url:`/`,icon:(0,u.jsx)(s,{})},{title:`我的文件`,url:`/my`,icon:(0,u.jsx)(t,{})},{title:`我的接收`,url:`/outside`,icon:(0,u.jsx)(e,{})},{title:`我的发送`,url:`/inside`,icon:(0,u.jsx)(o,{})},{title:`分享`,url:`/share`,icon:(0,u.jsx)(l,{})},{title:`回收站`,url:`/recycle`,icon:(0,u.jsx)(c,{})}];function f(){return(0,u.jsx)(n,{menus:d})}export{f as component};
|
||||||
1
deployment/iw/web/assets/search-BGsuWyQ1.js
Normal file
1
deployment/iw/web/assets/search-BGsuWyQ1.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{fn as e}from"./index-BaTxSAlR.js";var t=e(`rotate-ccw`,[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}]]),n=e(`search`,[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]);export{t as n,n as t};
|
||||||
1
deployment/iw/web/assets/select-stsOu5jD.js
Normal file
1
deployment/iw/web/assets/select-stsOu5jD.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/share-D-HlQYDW.js
Normal file
1
deployment/iw/web/assets/share-D-HlQYDW.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/shield-alert-XSqo2W3w.js
Normal file
1
deployment/iw/web/assets/shield-alert-XSqo2W3w.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{fn as e}from"./index-BaTxSAlR.js";var t=e(`shield-alert`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`M12 8v4`,key:`1got3b`}],[`path`,{d:`M12 16h.01`,key:`1drbdi`}]]);export{t};
|
||||||
1
deployment/iw/web/assets/tabs-DopbVsQe.js
Normal file
1
deployment/iw/web/assets/tabs-DopbVsQe.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{A as e,Vn as t,Y as n,b as r,en as i,f as a,k as o,qn as s,u as c,zn as l}from"./index-BaTxSAlR.js";import{t as u}from"./dist-CpxP8T7M.js";import{n as d,r as f,t as p}from"./dist-AWHq1sQs.js";var m=s(t(),1),h=s(l(),1),g=Object.defineProperty,_=(e,t)=>g(e,`name`,{value:t,configurable:!0}),v={Automatic:`automatic`,Manual:`manual`},y=`Tabs`,[b,x]=o(y,[f]),S=f(),[C,w]=b(y),T=m.forwardRef(_(function(e,t){let{__scopeTabs:i,value:a,onValueChange:o,defaultValue:s,orientation:l=`horizontal`,dir:d,activationMode:f=v.Automatic,...p}=e,m=u(d),[g,_]=c({prop:a,onChange:o,defaultProp:s??``,caller:y});return(0,h.jsx)(C,{scope:i,baseId:r(),value:g,onValueChange:_,orientation:l,dir:m,activationMode:f,children:(0,h.jsx)(n.div,{dir:m,"data-orientation":l,...p,ref:t})})},`Tabs`)),E=`TabsList`,D=m.forwardRef(_(function(e,t){let{__scopeTabs:r,loop:i=!0,...a}=e,o=w(E,r),s=S(r);return(0,h.jsx)(p,{asChild:!0,...s,orientation:o.orientation,dir:o.dir,loop:i,children:(0,h.jsx)(n.div,{role:`tablist`,"aria-orientation":o.orientation,...a,ref:t})})},`TabsList`)),O=`TabsTrigger`,k=m.forwardRef(_(function(t,r){let{__scopeTabs:i,value:a,disabled:o=!1,...s}=t,c=w(O,i),l=S(i),u=M(c.baseId,a),f=N(c.baseId,a),p=a===c.value;return(0,h.jsx)(d,{asChild:!0,...l,focusable:!o,active:p,children:(0,h.jsx)(n.button,{type:`button`,role:`tab`,"aria-selected":p,"aria-controls":f,"data-state":p?`active`:`inactive`,"data-disabled":o?``:void 0,disabled:o,id:u,...s,ref:r,onMouseDown:e(t.onMouseDown,e=>{!o&&e.button===0&&e.ctrlKey===!1?(e.currentTarget.focus(),c.onValueChange(a)):e.preventDefault()}),onKeyDown:e(t.onKeyDown,e=>{o||e.target!==e.currentTarget||[` `,`Enter`].includes(e.key)&&c.onValueChange(a)}),onFocus:e(t.onFocus,()=>{let e=c.activationMode!==v.Manual;!p&&!o&&e&&c.onValueChange(a)})})})},`TabsTrigger`)),A=`TabsContent`,j=m.forwardRef(_(function(e,t){let{__scopeTabs:r,value:i,forceMount:o,children:s,...c}=e,l=w(A,r),u=M(l.baseId,i),d=N(l.baseId,i),f=i===l.value,p=m.useRef(f);return m.useEffect(()=>{let e=requestAnimationFrame(()=>p.current=!1);return()=>cancelAnimationFrame(e)},[]),(0,h.jsx)(a,{present:o||f,children:({present:r})=>(0,h.jsx)(n.div,{"data-state":f?`active`:`inactive`,"data-orientation":l.orientation,role:`tabpanel`,"aria-labelledby":u,hidden:!r,id:d,tabIndex:0,...c,ref:t,style:{...e.style,animationDuration:p.current?`0s`:void 0},children:r&&s})})},`TabsContent`));function M(e,t){return`${e}-trigger-${t}`}_(M,`makeTriggerId`);function N(e,t){return`${e}-content-${t}`}_(N,`makeContentId`);function P({className:e,...t}){return(0,h.jsx)(T,{"data-slot":`tabs`,className:i(`flex flex-col gap-2`,e),...t})}function F({className:e,...t}){return(0,h.jsx)(D,{"data-slot":`tabs-list`,className:i(`bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]`,e),...t})}function I({className:e,...t}){return(0,h.jsx)(k,{"data-slot":`tabs-trigger`,className:i(`data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,e),...t})}function L({className:e,...t}){return(0,h.jsx)(j,{"data-slot":`tabs-content`,className:i(`flex-1 outline-none`,e),...t})}export{I as i,L as n,F as r,P as t};
|
||||||
1
deployment/iw/web/assets/tenant-DS3zyWsK.js
Normal file
1
deployment/iw/web/assets/tenant-DS3zyWsK.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{t as e}from"./useQuery-dxbdhNvu.js";import{t}from"./plus-BHIlMeNy.js";import{$ as n,G as r,H as i,K as a,Q as o,Qt as s,R as c,U as l,V as u,Vn as d,W as f,Zt as p,et as m,ln as h,q as g,qn as _,tt as v,yn as y,z as b,zn as x}from"./index-BaTxSAlR.js";import{n as S,r as C,t as w}from"./data-table-CEq6a930.js";import{t as T}from"./pagination-Bragnnjj.js";import{a as E,n as D,o as O,r as k,s as A,t as j}from"./dialog-CnxDxMp1.js";import{i as M,n as N,t as P}from"./org-CX5LJyS0.js";var F=_(d(),1);const I=t=>{var n,r,i;let[a,o]=(0,F.useState)({pageIndex:0,pageSize:10}),s=e({queryKey:[`orgList`,a],queryFn:()=>N({pageSize:a.pageSize,pageNo:a.pageIndex+1}).then(e=>e.data)}),c=t();return{pagination:a,table:S({data:(s==null||(n=s.data)==null?void 0:n.entityList)||[],columns:c,getCoreRowModel:C(),manualPagination:!1,rowCount:(s==null||(r=s.data)==null?void 0:r.totalCount)||0,pageCount:(s==null||(i=s.data)==null?void 0:i.pageCount)||0,onPaginationChange:o,autoResetPageIndex:!1,state:{pagination:a}}),query:s}},L=e=>{let{mutateAsync:t,isPending:n}=y({mutationFn:e=>e.id?M(e):P({...e,parentId:1}),...e||{}});return{save:e=>{h.promise(t(e),{loading:`提交中...`,success:`操作成功`})},saveIsPending:n}};var R=_(x(),1),z=`Qaz123567!@#`,B=o({orgName:n().nonempty({message:`单位名称不能为空`}),type:n().nonempty({message:`单位类型不能为空`}),phone:n().nonempty({message:`管理员手机号不能为空`}),realName:n().nonempty({message:`管理员姓名不能为空`})});function V({open:e,setOpen:t,data:n,refetch:o}){let d=v({resolver:m(B),defaultValues:{orgName:``,type:`3`,phone:``,realName:``}}),{save:h,saveIsPending:_}=L({onSuccess(){t(!1),o==null||o()}});(0,F.useEffect)(()=>{e&&(d.reset(),n&&(d.setValue(`orgName`,n.orgName),d.setValue(`type`,n.type),d.setValue(`phone`,n.phone),d.setValue(`realName`,n.realName)))},[e]);let y=d.watch(`phone`),x=(0,F.useMemo)(()=>!(n!=null&&n.id),[n]),S=e=>{h({...e,id:n==null?void 0:n.id})};return(0,R.jsx)(j,{open:e,onOpenChange:t,children:(0,R.jsxs)(k,{className:`w-[400px]`,children:[(0,R.jsx)(O,{children:(0,R.jsx)(A,{children:x?`创建单位`:`修改单位`})}),(0,R.jsx)(i,{...d,children:(0,R.jsxs)(`form`,{onSubmit:d.handleSubmit(S),className:`space-y-4`,children:[(0,R.jsx)(f,{control:d.control,name:`orgName`,render:({field:e})=>(0,R.jsxs)(r,{children:[(0,R.jsx)(a,{children:`单位名称`}),(0,R.jsx)(l,{children:(0,R.jsx)(u,{...e})}),(0,R.jsx)(g,{})]})}),(0,R.jsx)(f,{control:d.control,name:`realName`,render:({field:e})=>(0,R.jsxs)(r,{children:[(0,R.jsx)(a,{children:`管理员姓名`}),(0,R.jsx)(l,{children:(0,R.jsx)(u,{...e})}),(0,R.jsx)(g,{})]})}),(0,R.jsx)(f,{control:d.control,name:`phone`,render:({field:e})=>(0,R.jsxs)(r,{children:[(0,R.jsx)(a,{children:`管理员手机号`}),(0,R.jsx)(l,{children:(0,R.jsx)(u,{...e})}),(0,R.jsx)(g,{})]})}),x&&(0,R.jsx)(c,{children:(0,R.jsxs)(b,{children:[(0,R.jsxs)(`div`,{children:[`管理员账号:`,y]}),(0,R.jsxs)(`div`,{children:[`初始密码:`,z]})]})}),(0,R.jsxs)(E,{children:[(0,R.jsx)(D,{asChild:!0,children:(0,R.jsx)(s,{variant:`outline`,children:`取消`})}),(0,R.jsxs)(s,{type:`submit`,disabled:_,children:[_&&(0,R.jsx)(p,{}),`确定`]})]})]})})]})})}function H({handleEditOrg:e}){return[{accessorKey:`orgName`,header:`单位名称`,cell:({row:e})=>(0,R.jsx)(`div`,{children:e.getValue(`orgName`)})},{accessorKey:`realName`,header:`管理员姓名`,cell:({row:e})=>(0,R.jsx)(`div`,{children:e.getValue(`realName`)})},{accessorKey:`phone`,header:`管理员手机号`,cell:({row:e})=>(0,R.jsx)(`div`,{children:e.getValue(`phone`)})},{accessorKey:`createTime`,header:`创建日期`,cell:({row:e})=>(0,R.jsx)(`div`,{children:e.getValue(`createTime`)})}]}function U(){let[e,n]=(0,F.useState)(null),[r,i]=(0,F.useState)(!1),a=e=>{n(e),i(!0)},{table:o,query:c}=I(()=>H({handleEditOrg:a}));return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(V,{open:r,setOpen:i,data:e,refetch:c==null?void 0:c.refetch}),(0,R.jsxs)(`div`,{className:`p-4 box-border min-h-full space-y-4`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`div`,{className:`text-lg`,children:`单位管理`}),(0,R.jsx)(`div`,{className:`text-xs text-black/50`,children:`管理单位信息`})]}),(0,R.jsxs)(`div`,{className:`p-4 rounded-lg border bg-white space-y-2`,children:[(0,R.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,R.jsxs)(s,{onClick:()=>a(),children:[(0,R.jsx)(t,{}),`新增`]})}),(0,R.jsxs)(`div`,{className:`relative overflow-hidden`,children:[(0,R.jsx)(w,{table:o,query:c}),(0,R.jsx)(T,{table:o,className:`justify-end p-2 sticky bottom-0 left-0 right-0 z-10 bg-white`})]})]})]})]})}export{U as component,H as useColumns};
|
||||||
1
deployment/iw/web/assets/textarea-Dyx6I5ZN.js
Normal file
1
deployment/iw/web/assets/textarea-Dyx6I5ZN.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{Vn as e,en as t,qn as n,zn as r}from"./index-BaTxSAlR.js";e();var i=n(r(),1);function a({className:e,...n}){return(0,i.jsx)(`textarea`,{"data-slot":`textarea`,className:t(`border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm`,e),...n})}export{a as t};
|
||||||
1
deployment/iw/web/assets/upload-Cr-BixPb.js
Normal file
1
deployment/iw/web/assets/upload-Cr-BixPb.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{fn as e}from"./index-BaTxSAlR.js";var t=e(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]);export{t};
|
||||||
2
deployment/iw/web/assets/upload-config-D_24SNBe.js
Normal file
2
deployment/iw/web/assets/upload-config-D_24SNBe.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/use-fetch-files-rnWwNE4C.js
Normal file
1
deployment/iw/web/assets/use-fetch-files-rnWwNE4C.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{t as e}from"./useQuery-dxbdhNvu.js";import{Vn as t,ht as n,qn as r,ut as i}from"./index-BaTxSAlR.js";import{n as a,r as o}from"./data-table-CEq6a930.js";var s=r(t(),1);const c=({useColumns:t,queryKey:r,params:c})=>{var l,u,d;let[f,p]=(0,s.useState)([]),[m,h]=(0,s.useState)(0),[g,_]=(0,s.useState)({pageIndex:0,pageSize:10}),v=e({queryKey:[...r,g,m,c],queryFn:()=>n({parentId:m||0,pageSize:g.pageSize,pageNo:g.pageIndex+1,...c}).then(e=>e.data),refetchInterval:e=>{var t;return((e==null||(t=e.state)==null||(t=t.data)==null?void 0:t.entityList)||[]).some(e=>e.securityStatus===i.SCANNING)?2e3:!1}}),y=e=>{h(e.id),x.setPageIndex(0),p(t=>[...t,e])},b=t(y),x=a({data:(v==null||(l=v.data)==null?void 0:l.entityList)||[],columns:b,getCoreRowModel:o(),manualPagination:!1,rowCount:(v==null||(u=v.data)==null?void 0:u.totalCount)||0,pageCount:(v==null||(d=v.data)==null?void 0:d.pageCount)||0,onPaginationChange:_,autoResetPageIndex:!1,state:{pagination:g}});return{parentId:m,setParentId:h,handleChangeParentId:y,openDirectorys:f,changeOpenDirectorys:e=>{h(e==null?void 0:e.id),x.setPageIndex(0),p(t=>{let n=t.findIndex(t=>t.id===(e==null?void 0:e.id));return n>-1?[...t.slice(0,n+1)]:[]})},pagination:g,table:x,query:v,reset:()=>{h(0),x.setPageIndex(0),p([])}}};export{c as t};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import{t as e}from"./useQuery-dxbdhNvu.js";import{Yt as t}from"./index-BaTxSAlR.js";const n=()=>{let{data:n}=e({queryKey:[`securityEnabled`],queryFn:()=>t.get(`/file_security/enabled`).then(e=>e.data),staleTime:300*1e3});return{securityEnabled:!!n}};export{n as t};
|
||||||
1
deployment/iw/web/assets/use-upload-config-OxxQwpLm.js
Normal file
1
deployment/iw/web/assets/use-upload-config-OxxQwpLm.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{t as e}from"./useQuery-dxbdhNvu.js";import{Yt as t}from"./index-BaTxSAlR.js";const n=()=>t.get(`/upload_config/info`),r=e=>t.post(`/upload_config/modify`,e),i=e=>t.get(`/upload_config/check`,{params:e}),a=()=>e({queryKey:[`uploadConfig`],queryFn:()=>n().then(e=>e==null?void 0:e.data)}),o=e=>{var t;if(!(!e||e.allowAllType||!((t=e.allowedSuffixes)!=null&&t.length)))return e.allowedSuffixes.map(e=>`.${String(e).replace(/^\.+/,``).toLowerCase()}`).join(`,`)},s=e=>{if(e!=null&&e.maxFileSize&&e.maxFileSize>0)return e.maxFileSize*1024*1024};export{r as a,i,s as n,a as r,o as t};
|
||||||
1
deployment/iw/web/assets/useLocation-B-0SqFIj.js
Normal file
1
deployment/iw/web/assets/useLocation-B-0SqFIj.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{_n as e,gn as t,hn as n,vn as r}from"./index-BaTxSAlR.js";function i(r){let i=e();return t(i.stores.location,n(r,i))}export{i as t};
|
||||||
1
deployment/iw/web/assets/useQuery-dxbdhNvu.js
Normal file
1
deployment/iw/web/assets/useQuery-dxbdhNvu.js
Normal file
File diff suppressed because one or more lines are too long
4
deployment/iw/web/assets/user-CwyiWp7E.js
Normal file
4
deployment/iw/web/assets/user-CwyiWp7E.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/assets/x-CNIkD3YH.js
Normal file
1
deployment/iw/web/assets/x-CNIkD3YH.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{fn as e}from"./index-BaTxSAlR.js";var t=e(`x`,[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]);export{t};
|
||||||
104
deployment/iw/web/assets/xlsx-DLapqJRf.js
Normal file
104
deployment/iw/web/assets/xlsx-DLapqJRf.js
Normal file
File diff suppressed because one or more lines are too long
BIN
deployment/iw/web/favicon.png
Normal file
BIN
deployment/iw/web/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
44
deployment/iw/web/index.html
Normal file
44
deployment/iw/web/index.html
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="zh">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<!-- 避免IE兼容模式 -->
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="chrome=1,IE=edge" />
|
||||||
|
<!-- 极速模式渲染 -->
|
||||||
|
<meta name="renderer" content="webkit" />
|
||||||
|
<!-- 屏幕缩放大小 -->
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover"
|
||||||
|
/>
|
||||||
|
<!-- 拨打电话 -->
|
||||||
|
<meta name="format-detection" content="telephone=yes" />
|
||||||
|
<!-- 设置缓存 -->
|
||||||
|
<meta
|
||||||
|
http-equiv="Cache-Control"
|
||||||
|
content="no-cache, no-store, must-revalidate"
|
||||||
|
/>
|
||||||
|
<meta http-equiv="Pragma" content="no-cache" />
|
||||||
|
<meta http-equiv="Expires" content="0" />
|
||||||
|
<!-- SEO -->
|
||||||
|
<meta property="generator" content="react" />
|
||||||
|
<meta id="keywords" property="keywords" content="" />
|
||||||
|
<meta id="robots" property="robots" content="none" />
|
||||||
|
<meta name="description" content="" />
|
||||||
|
<meta property="og:title" content="" />
|
||||||
|
<meta property="og:description" content="" />
|
||||||
|
<meta property="og:locale" content="zh_CN" />
|
||||||
|
|
||||||
|
<!-- dns解析 -->
|
||||||
|
<link rel="dns-prefetch" href="" />
|
||||||
|
<!-- 图标 -->
|
||||||
|
<link id="favicon" rel="icon" href="/favicon.png" />
|
||||||
|
<!-- 标题 -->
|
||||||
|
<title>森睿智传</title>
|
||||||
|
<script type="module" crossorigin src="/assets/index-BaTxSAlR.js"></script>
|
||||||
|
<link rel="stylesheet" crossorigin href="/assets/index-BbZGMJ6u.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
177
deployment/iw/web/pdfjs/LICENSE
Normal file
177
deployment/iw/web/pdfjs/LICENSE
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
24450
deployment/iw/web/pdfjs/build/pdf.js
Normal file
24450
deployment/iw/web/pdfjs/build/pdf.js
Normal file
File diff suppressed because it is too large
Load Diff
1
deployment/iw/web/pdfjs/build/pdf.js.map
Normal file
1
deployment/iw/web/pdfjs/build/pdf.js.map
Normal file
File diff suppressed because one or more lines are too long
316
deployment/iw/web/pdfjs/build/pdf.sandbox.js
Normal file
316
deployment/iw/web/pdfjs/build/pdf.sandbox.js
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/pdfjs/build/pdf.sandbox.js.map
Normal file
1
deployment/iw/web/pdfjs/build/pdf.sandbox.js.map
Normal file
File diff suppressed because one or more lines are too long
79063
deployment/iw/web/pdfjs/build/pdf.worker.js
vendored
Normal file
79063
deployment/iw/web/pdfjs/build/pdf.worker.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
deployment/iw/web/pdfjs/build/pdf.worker.js.map
vendored
Normal file
1
deployment/iw/web/pdfjs/build/pdf.worker.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
deployment/iw/web/pdfjs/web/cmaps/78-EUC-H.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/78-EUC-H.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/78-EUC-V.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/78-EUC-V.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/78-H.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/78-H.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/78-RKSJ-H.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/78-RKSJ-H.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/78-RKSJ-V.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/78-RKSJ-V.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/78-V.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/78-V.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/78ms-RKSJ-H.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/78ms-RKSJ-H.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/78ms-RKSJ-V.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/78ms-RKSJ-V.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/83pv-RKSJ-H.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/83pv-RKSJ-H.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/90ms-RKSJ-H.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/90ms-RKSJ-H.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/90ms-RKSJ-V.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/90ms-RKSJ-V.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/90msp-RKSJ-H.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/90msp-RKSJ-H.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/90msp-RKSJ-V.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/90msp-RKSJ-V.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/90pv-RKSJ-H.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/90pv-RKSJ-H.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/90pv-RKSJ-V.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/90pv-RKSJ-V.bcmap
Normal file
Binary file not shown.
BIN
deployment/iw/web/pdfjs/web/cmaps/Add-H.bcmap
Normal file
BIN
deployment/iw/web/pdfjs/web/cmaps/Add-H.bcmap
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user