12300922
This commit is contained in:
parent
c8dfb4db25
commit
124e263f78
|
@ -6,3 +6,4 @@ dist
|
||||||
test
|
test
|
||||||
.md
|
.md
|
||||||
volumes
|
volumes
|
||||||
|
*.tar
|
|
@ -1,235 +1,69 @@
|
||||||
# Node.js
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
node_modules/
|
backup
|
||||||
|
# dependencies
|
||||||
|
**/node_modules/
|
||||||
|
volumes
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
*.tar
|
||||||
|
# testing
|
||||||
|
**/coverage/
|
||||||
|
.env
|
||||||
|
docker-compose.yml
|
||||||
|
packages/common/prisma/migrations
|
||||||
|
packages/common/src/generated
|
||||||
|
# production
|
||||||
|
**/build/
|
||||||
|
**/dist/
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
pnpm-debug.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
# Logs
|
# 快速刷新错误记录
|
||||||
logs/
|
.expo/web/cache/development/
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
# Expo
|
||||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
**/.expo/
|
||||||
|
**/.expo-shared/
|
||||||
|
|
||||||
# Runtime data
|
# Android
|
||||||
pids/
|
*.apk
|
||||||
*.pid
|
*.aar
|
||||||
*.seed
|
*.jks
|
||||||
*.pid.lock
|
!apps/mobile/android/app/release.jks
|
||||||
|
**/android/.gradle/
|
||||||
|
**/android/app/build/
|
||||||
|
**/android/app/release/
|
||||||
|
**/android/react-native-jsc/build/
|
||||||
|
**/android/react/build/
|
||||||
|
**/android/*/google-services.json
|
||||||
|
**/android/app/src/debug/res/xml/react_native_debug.xml
|
||||||
|
**/android/app/src/dev19/res/xml/react_native_debug.xml
|
||||||
|
**/android/app/src/dev20/res/xml/react_native_debug.xml
|
||||||
|
**/android/app/src/main/assets/shell-app.bundle
|
||||||
|
**/android/app/src/main/res/raw/shell_app_bundle
|
||||||
|
**/android/app/src/release/res/xml/react_native_debug.xml
|
||||||
|
|
||||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
# iOS
|
||||||
lib-cov/
|
**/ios/Pods/
|
||||||
|
/ios/*.xcworkspace
|
||||||
|
**/ios/DerivedData/
|
||||||
|
**/ios/build/
|
||||||
|
**/ios/Podfile.lock
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
# Yarn Plug'n'Play
|
||||||
coverage/
|
.pnp.*
|
||||||
*.lcov
|
.yarn/cache/
|
||||||
|
.yarn/unplugged/
|
||||||
# nyc test coverage
|
|
||||||
.nyc_output/
|
|
||||||
|
|
||||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
||||||
.grunt/
|
|
||||||
|
|
||||||
# Bower dependency directory (https://bower.io/)
|
|
||||||
bower_components/
|
|
||||||
|
|
||||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
||||||
build/Release/
|
|
||||||
|
|
||||||
# Dependency directories
|
|
||||||
jspm_packages/
|
|
||||||
|
|
||||||
# TypeScript v1 declaration files
|
|
||||||
typings/
|
|
||||||
|
|
||||||
# Optional npm cache directory
|
|
||||||
.npm/
|
|
||||||
|
|
||||||
# Optional eslint cache
|
|
||||||
.eslintcache
|
|
||||||
|
|
||||||
# Optional stylelint cache
|
|
||||||
.stylelintcache
|
|
||||||
|
|
||||||
# Microbundle cache
|
|
||||||
.rpt2_cache/
|
|
||||||
.rts2_cache_cjs/
|
|
||||||
.rts2_cache_es/
|
|
||||||
.rts2_cache_umd/
|
|
||||||
|
|
||||||
# Optional REPL history
|
|
||||||
.node_repl_history
|
|
||||||
|
|
||||||
# Output of 'npm pack'
|
|
||||||
*.tgz
|
|
||||||
|
|
||||||
# Yarn Integrity file
|
|
||||||
.yarn-integrity
|
|
||||||
|
|
||||||
# dotenv environment variables file
|
|
||||||
.env
|
|
||||||
.env.*
|
|
||||||
!.env.example
|
|
||||||
|
|
||||||
# Parcel-bundler cache (https://parceljs.org/)
|
|
||||||
.cache
|
|
||||||
.parcel-cache
|
|
||||||
|
|
||||||
# Next.js build output
|
|
||||||
.next/
|
|
||||||
out/
|
|
||||||
|
|
||||||
# Nuxt.js build / generate output
|
|
||||||
.nuxt
|
|
||||||
dist
|
|
||||||
|
|
||||||
# Gatsby files
|
|
||||||
.cache/
|
|
||||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
|
||||||
# public
|
|
||||||
|
|
||||||
# vuepress build output
|
|
||||||
.vuepress/dist
|
|
||||||
|
|
||||||
# vuepress v2.x temp and cache directory
|
|
||||||
.temp
|
|
||||||
|
|
||||||
# Docusaurus cache and generated files
|
|
||||||
.docusaurus
|
|
||||||
.build
|
|
||||||
|
|
||||||
# Serverless directories
|
|
||||||
.serverless/
|
|
||||||
|
|
||||||
# FuseBox cache
|
|
||||||
.fusebox/
|
|
||||||
|
|
||||||
# DynamoDB Local files
|
|
||||||
.dynamodb/
|
|
||||||
|
|
||||||
# TernJS port file
|
|
||||||
.tern-port
|
|
||||||
|
|
||||||
# Stores VSCode versions used for testing VSCode extensions
|
|
||||||
.vscode-test
|
|
||||||
|
|
||||||
# Yarn v2
|
|
||||||
.yarn/cache
|
|
||||||
.yarn/unplugged
|
|
||||||
.yarn/build-state.yml
|
.yarn/build-state.yml
|
||||||
.yarn/install-state.gz
|
.yarn/install-state.gz
|
||||||
.pnp.*
|
|
||||||
|
|
||||||
# Vite local server cache
|
# Ignore .idea files in the Expo monorepo
|
||||||
.vite
|
**/.idea/
|
||||||
|
|
||||||
# Vitest cache
|
|
||||||
.vitest
|
|
||||||
|
|
||||||
# Storybook build outputs
|
|
||||||
.out/
|
|
||||||
.storybook-out/
|
|
||||||
|
|
||||||
# Monorepo-specific
|
|
||||||
apps/*/node_modules/
|
|
||||||
apps/*/dist/
|
|
||||||
apps/*/build/
|
|
||||||
apps/*/.turbo/
|
|
||||||
apps/*/.next/
|
|
||||||
apps/*/.nuxt/
|
|
||||||
apps/*/.cache/
|
|
||||||
apps/*/.parcel-cache/
|
|
||||||
apps/*/.vuepress/dist
|
|
||||||
apps/*/.docusaurus
|
|
||||||
apps/*/.build
|
|
||||||
apps/*/.serverless
|
|
||||||
apps/*/.fusebox
|
|
||||||
apps/*/.dynamodb
|
|
||||||
apps/*/.tern-port
|
|
||||||
apps/*/.vscode-test
|
|
||||||
apps/*/.yarn
|
|
||||||
apps/*/.vite
|
|
||||||
apps/*/.vitest
|
|
||||||
apps/*/.out
|
|
||||||
apps/*/.storybook-out
|
|
||||||
|
|
||||||
packages/*/node_modules/
|
|
||||||
packages/*/dist/
|
|
||||||
packages/*/build/
|
|
||||||
packages/*/.turbo/
|
|
||||||
packages/*/.next/
|
|
||||||
packages/*/.nuxt/
|
|
||||||
packages/*/.cache/
|
|
||||||
packages/*/.parcel-cache/
|
|
||||||
packages/*/.vuepress/dist
|
|
||||||
packages/*/.docusaurus
|
|
||||||
packages/*/.build
|
|
||||||
packages/*/.serverless
|
|
||||||
packages/*/.fusebox
|
|
||||||
packages/*/.dynamodb
|
|
||||||
packages/*/.tern-port
|
|
||||||
packages/*/.vscode-test
|
|
||||||
packages/*/.yarn
|
|
||||||
packages/*/.vite
|
|
||||||
packages/*/.vitest
|
|
||||||
packages/*/.out
|
|
||||||
packages/*/.storybook-out
|
|
||||||
|
|
||||||
libs/*/node_modules/
|
|
||||||
libs/*/dist/
|
|
||||||
libs/*/build/
|
|
||||||
libs/*/.turbo/
|
|
||||||
libs/*/.next/
|
|
||||||
libs/*/.nuxt/
|
|
||||||
libs/*/.cache/
|
|
||||||
libs/*/.parcel-cache/
|
|
||||||
libs/*/.vuepress/dist
|
|
||||||
libs/*/.docusaurus
|
|
||||||
libs/*/.build
|
|
||||||
libs/*/.serverless
|
|
||||||
libs/*/.fusebox
|
|
||||||
libs/*/.dynamodb
|
|
||||||
libs/*/.tern-port
|
|
||||||
libs/*/.vscode-test
|
|
||||||
libs/*/.yarn
|
|
||||||
libs/*/.vite
|
|
||||||
libs/*/.vitest
|
|
||||||
libs/*/.out
|
|
||||||
libs/*/.storybook-out
|
|
||||||
|
|
||||||
# Ignore lockfiles
|
|
||||||
**/package-lock.json
|
|
||||||
**/yarn.lock
|
|
||||||
**/pnpm-lock.yaml
|
|
||||||
|
|
||||||
# IDEs and editors
|
|
||||||
.vscode/
|
|
||||||
.idea/
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
||||||
|
|
||||||
# MacOS
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# Windows
|
|
||||||
Thumbs.db
|
|
||||||
ehthumbs.db
|
|
||||||
Desktop.ini
|
|
||||||
$RECYCLE.BIN/
|
|
||||||
|
|
||||||
# Linux
|
|
||||||
*~
|
|
||||||
|
|
||||||
docker-compose.yml
|
|
||||||
.env
|
|
||||||
packages/common/prisma/migrations
|
|
||||||
volumes
|
|
||||||
|
|
67
Dockerfile
67
Dockerfile
|
@ -1,12 +1,10 @@
|
||||||
# 基础镜像
|
# 基础镜像
|
||||||
FROM node:20-alpine as base
|
FROM node:20-alpine as base
|
||||||
|
# 更改 apk 镜像源为阿里云
|
||||||
# 设置 npm 镜像源
|
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
|
||||||
RUN yarn config set registry https://registry.npmmirror.com
|
yarn config set registry https://registry.npmmirror.com && \
|
||||||
|
yarn global add pnpm && \
|
||||||
# 全局安装 pnpm 并设置其镜像源
|
pnpm config set registry https://registry.npmmirror.com
|
||||||
RUN yarn global add pnpm && pnpm config set registry https://registry.npmmirror.com
|
|
||||||
|
|
||||||
# 设置工作目录
|
# 设置工作目录
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
@ -16,64 +14,71 @@ COPY pnpm-workspace.yaml ./
|
||||||
# 首先复制 package.json, package-lock.json 和 pnpm-lock.yaml 文件
|
# 首先复制 package.json, package-lock.json 和 pnpm-lock.yaml 文件
|
||||||
COPY package*.json pnpm-lock.yaml* ./
|
COPY package*.json pnpm-lock.yaml* ./
|
||||||
|
|
||||||
COPY tsconfig.json .
|
COPY tsconfig.base.json .
|
||||||
# 利用 Docker 缓存机制,如果依赖没有改变则不会重新执行 pnpm install
|
|
||||||
|
|
||||||
|
|
||||||
FROM base As server-build
|
FROM base As server-build
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY packages/common /app/packages/common
|
COPY packages/common /app/packages/common
|
||||||
COPY apps/back-worker /app/apps/back-worker
|
COPY apps/server /app/apps/server
|
||||||
RUN pnpm install --filter back-worker
|
RUN pnpm install --filter common && \
|
||||||
RUN pnpm install --filter common
|
pnpm install --filter server && \
|
||||||
RUN pnpm --filter common build
|
pnpm --filter common generate && \
|
||||||
RUN pnpm run build:server
|
pnpm --filter common build:cjs && \
|
||||||
|
pnpm --filter server build
|
||||||
|
|
||||||
FROM base As server-prod-dep
|
FROM base As server-prod-dep
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY packages/common /app/packages/common
|
COPY packages/common /app/packages/common
|
||||||
COPY apps/back-worker /app/apps/back-worker
|
COPY apps/server /app/apps/server
|
||||||
RUN pnpm install --filter back-worker --prod
|
RUN pnpm install --filter common --prod && \
|
||||||
RUN pnpm install --filter common --prod
|
pnpm install --filter server --prod && \
|
||||||
|
# 清理包管理器缓存
|
||||||
|
pnpm store prune && rm -rf /root/.npm && rm -rf /root/.cache
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FROM server-prod-dep as server
|
FROM server-prod-dep as server
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV NODE_ENV production
|
ENV NODE_ENV production
|
||||||
COPY --from=server-build /app/packages/common/dist ./packages/common/dist
|
COPY --from=server-build /app/packages/common/dist ./packages/common/dist
|
||||||
COPY --from=server-build /app/apps/back-worker/dist ./apps/back-worker/dist
|
COPY --from=server-build /app/apps/server/dist ./apps/server/dist
|
||||||
COPY apps/back-worker/entrypoint.sh ./apps/back-worker/entrypoint.sh
|
COPY apps/server/entrypoint.sh ./apps/server/entrypoint.sh
|
||||||
|
RUN chmod +x ./apps/server/entrypoint.sh
|
||||||
|
# RUN apk add --no-cache postgresql-client
|
||||||
|
|
||||||
RUN chmod +x ./apps/back-worker/entrypoint.sh
|
|
||||||
RUN apk add postgresql-client
|
|
||||||
|
|
||||||
EXPOSE 3010
|
EXPOSE 3000
|
||||||
|
|
||||||
ENTRYPOINT [ "/app/apps/back-worker/entrypoint.sh" ]
|
ENTRYPOINT [ "/app/apps/server/entrypoint.sh" ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FROM base AS front-app-build
|
FROM base AS web-build
|
||||||
# 复制其余文件到工作目录
|
# 复制其余文件到工作目录
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN pnpm install
|
RUN pnpm install && pnpm --filter web build
|
||||||
RUN pnpm run build:web
|
|
||||||
# 第二阶段,使用 nginx 提供服务
|
# 第二阶段,使用 nginx 提供服务
|
||||||
FROM nginx:stable-alpine as front-app
|
FROM nginx:stable-alpine as web
|
||||||
|
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||||||
# 设置工作目录
|
# 设置工作目录
|
||||||
WORKDIR /usr/share/nginx/html
|
WORKDIR /usr/share/nginx/html
|
||||||
# 设置环境变量
|
# 设置环境变量
|
||||||
ENV NODE_ENV production
|
ENV NODE_ENV production
|
||||||
# 将构建的文件从上一阶段复制到当前镜像中
|
# 将构建的文件从上一阶段复制到当前镜像中
|
||||||
COPY --from=front-app-build /app/apps/front-app/build .
|
COPY --from=web-build /app/apps/web/dist .
|
||||||
# 删除默认的nginx配置文件并添加自定义配置
|
# 删除默认的nginx配置文件并添加自定义配置
|
||||||
RUN rm /etc/nginx/conf.d/default.conf
|
RUN rm /etc/nginx/conf.d/default.conf
|
||||||
COPY apps/front-app/nginx.conf /etc/nginx/conf.d
|
COPY apps/web/nginx.conf /etc/nginx/conf.d
|
||||||
# 添加 entrypoint 脚本,并确保其可执行
|
# 添加 entrypoint 脚本,并确保其可执行
|
||||||
COPY apps/front-app/entrypoint.sh /usr/bin/
|
COPY apps/web/entrypoint.sh /usr/bin/
|
||||||
RUN chmod +x /usr/bin/entrypoint.sh
|
RUN chmod +x /usr/bin/entrypoint.sh
|
||||||
# 安装 envsubst 以支持环境变量替换
|
# 安装 envsubst 以支持环境变量替换
|
||||||
RUN apk add envsubst
|
# RUN apk add --no-cache envsubst
|
||||||
|
# RUN echo "http://mirrors.aliyun.com/alpine/v3.12/main/" > /etc/apk/repositories && \
|
||||||
|
# echo "http://mirrors.aliyun.com/alpine/v3.12/community/" >> /etc/apk/repositories && \
|
||||||
|
# apk update && \
|
||||||
|
RUN apk add --no-cache gettext
|
||||||
# 暴露 80 端口
|
# 暴露 80 端口
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
DATABASE_URL="postgresql://root:Letusdoit000@localhost:5432/defender_app?schema=public"
|
DATABASE_URL="postgresql://root:Letusdoit000@localhost:5432/defender_app?schema=public"
|
||||||
REDIS_HOST=localhost
|
REDIS_HOST=localhost
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
|
REDIS_PASSWORD=Letusdoit000
|
||||||
TUS_URL=http://localhost:8080
|
TUS_URL=http://localhost:8080
|
||||||
JWT_SECRET=/yT9MnLm/r6NY7ee2Fby6ihCHZl+nFx4OQFKupivrhA=
|
JWT_SECRET=/yT9MnLm/r6NY7ee2Fby6ihCHZl+nFx4OQFKupivrhA=
|
||||||
APP_URL=http://localhost:5173
|
PUSH_URL=http://dns:9092
|
||||||
|
PUSH_APPID=123
|
||||||
|
PUSH_APPSECRET=123
|
||||||
|
DEADLINE_CRON="0 0 8 * * *"
|
||||||
|
SERVER_PORT=3000
|
||||||
|
ADMIN_PHONE_NUMBER=13258117304
|
||||||
|
NODE_ENV=development
|
||||||
|
|
|
@ -29,33 +29,33 @@
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ pnpm install
|
$ yarn install
|
||||||
```
|
```
|
||||||
|
|
||||||
## Running the app
|
## Running the app
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# development
|
# development
|
||||||
$ pnpm run start
|
$ yarn run start
|
||||||
|
|
||||||
# watch mode
|
# watch mode
|
||||||
$ pnpm run start:dev
|
$ yarn run start:dev
|
||||||
|
|
||||||
# production mode
|
# production mode
|
||||||
$ pnpm run start:prod
|
$ yarn run start:prod
|
||||||
```
|
```
|
||||||
|
|
||||||
## Test
|
## Test
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# unit tests
|
# unit tests
|
||||||
$ pnpm run test
|
$ yarn run test
|
||||||
|
|
||||||
# e2e tests
|
# e2e tests
|
||||||
$ pnpm run test:e2e
|
$ yarn run test:e2e
|
||||||
|
|
||||||
# test coverage
|
# test coverage
|
||||||
$ pnpm run test:cov
|
$ yarn run test:cov
|
||||||
```
|
```
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
|
@ -1,24 +1,41 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
# # 从 DATABASE_URL 环境变量中提取主机名、端口和用户名
|
||||||
|
# DB_HOST=$(echo $DATABASE_URL | cut -d '@' -f 2 | cut -d ':' -f 1)
|
||||||
|
# DB_PORT=$(echo $DATABASE_URL | cut -d ':' -f 4 | cut -d '/' -f 1)
|
||||||
|
# DB_USER=$(echo $DATABASE_URL | cut -d '/' -f 3 | cut -d ':' -f 1)
|
||||||
|
|
||||||
|
# # 检查数据库是否就绪
|
||||||
|
# until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do
|
||||||
|
# echo "Database is unavailable - sleeping"
|
||||||
|
# sleep 1
|
||||||
|
# done
|
||||||
|
|
||||||
|
# echo "Database is up"
|
||||||
|
|
||||||
|
# # 检查标记文件是否存在,如果不存在,则执行 prisma deploy 并创建标记文件
|
||||||
|
# # if [ ! -f "/app/prisma-deployed" ]; then
|
||||||
|
# # pnpm prisma generate
|
||||||
|
# # pnpm prisma migrate deploy
|
||||||
|
# # touch /app/prisma-deployed
|
||||||
|
# # fi
|
||||||
|
|
||||||
|
# # 启动主应用
|
||||||
|
# exec node apps/server/dist/main
|
||||||
|
|
||||||
|
|
||||||
# 从 DATABASE_URL 环境变量中提取主机名、端口和用户名
|
# 从 DATABASE_URL 环境变量中提取主机名、端口和用户名
|
||||||
DB_HOST=$(echo $DATABASE_URL | cut -d '@' -f 2 | cut -d ':' -f 1)
|
DB_HOST=$(echo $DATABASE_URL | cut -d '@' -f 2 | cut -d ':' -f 1)
|
||||||
DB_PORT=$(echo $DATABASE_URL | cut -d ':' -f 4 | cut -d '/' -f 1)
|
DB_PORT=$(echo $DATABASE_URL | cut -d ':' -f 4 | cut -d '/' -f 1)
|
||||||
DB_USER=$(echo $DATABASE_URL | cut -d '/' -f 3 | cut -d ':' -f 1)
|
DB_USER=$(echo $DATABASE_URL | cut -d '/' -f 3 | cut -d ':' -f 1)
|
||||||
|
|
||||||
# 检查数据库是否就绪
|
# 检查数据库是否就绪
|
||||||
until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do
|
until nc -z $DB_HOST $DB_PORT; do
|
||||||
echo "Database is unavailable - sleeping"
|
echo "Database is unavailable - sleeping"
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "Database is up"
|
echo "Database is up"
|
||||||
|
|
||||||
# 检查标记文件是否存在,如果不存在,则执行 prisma deploy 并创建标记文件
|
|
||||||
# if [ ! -f "/app/prisma-deployed" ]; then
|
|
||||||
# pnpm prisma generate
|
|
||||||
# pnpm prisma migrate deploy
|
|
||||||
# touch /app/prisma-deployed
|
|
||||||
# fi
|
|
||||||
|
|
||||||
# 启动主应用
|
# 启动主应用
|
||||||
exec node apps/back-worker/dist/main
|
exec node apps/server/dist/main
|
|
@ -1,6 +1,6 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { TrpcService } from '@server/trpc/trpc.service';
|
import { TrpcService } from '@server/trpc/trpc.service';
|
||||||
import { ChangedRows, ObjectType, Prisma } from '@nicestack/common';
|
import { Prisma } from '@nicestack/common';
|
||||||
import { PostService } from './post.service';
|
import { PostService } from './post.service';
|
||||||
import { z, ZodType } from 'zod';
|
import { z, ZodType } from 'zod';
|
||||||
const PostCreateArgsSchema: ZodType<Prisma.PostCreateArgs> = z.any();
|
const PostCreateArgsSchema: ZodType<Prisma.PostCreateArgs> = z.any();
|
||||||
|
@ -15,7 +15,7 @@ export class PostRouter {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly trpc: TrpcService,
|
private readonly trpc: TrpcService,
|
||||||
private readonly postService: PostService,
|
private readonly postService: PostService,
|
||||||
) {}
|
) { }
|
||||||
router = this.trpc.router({
|
router = this.trpc.router({
|
||||||
create: this.trpc.protectProcedure
|
create: this.trpc.protectProcedure
|
||||||
.input(PostCreateArgsSchema)
|
.input(PostCreateArgsSchema)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { db, Post, PostType, UserProfile, VisitType } from "@nicestack/common";
|
import { db, Post, PostType, UserProfile, VisitType } from "@nicestack/common";
|
||||||
import { getTroubleWithRelation } from "../trouble/utils";
|
|
||||||
export async function setPostRelation(params: { data: Post, staff?: UserProfile }) {
|
export async function setPostRelation(params: { data: Post, staff?: UserProfile }) {
|
||||||
const { data, staff } = params
|
const { data, staff } = params
|
||||||
const limitedComments = await db.post.findMany({
|
const limitedComments = await db.post.findMany({
|
||||||
|
@ -32,13 +32,13 @@ export async function setPostRelation(params: { data: Post, staff?: UserProfile
|
||||||
visitType: VisitType.READED,
|
visitType: VisitType.READED,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const trouble = await getTroubleWithRelation(data.referenceId, staff)
|
// const trouble = await getTroubleWithRelation(data.referenceId, staff)
|
||||||
Object.assign(data, {
|
Object.assign(data, {
|
||||||
readed,
|
readed,
|
||||||
readedCount,
|
readedCount,
|
||||||
limitedComments,
|
limitedComments,
|
||||||
commentsCount,
|
commentsCount,
|
||||||
trouble
|
// trouble
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,7 +2,6 @@ import { Injectable } from '@nestjs/common';
|
||||||
import { TransformService } from './transform.service';
|
import { TransformService } from './transform.service';
|
||||||
import { TransformMethodSchema} from '@nicestack/common';
|
import { TransformMethodSchema} from '@nicestack/common';
|
||||||
import { TrpcService } from '@server/trpc/trpc.service';
|
import { TrpcService } from '@server/trpc/trpc.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TransformRouter {
|
export class TransformRouter {
|
||||||
constructor(
|
constructor(
|
||||||
|
|
|
@ -7,10 +7,13 @@ import {
|
||||||
db,
|
db,
|
||||||
Prisma,
|
Prisma,
|
||||||
Staff,
|
Staff,
|
||||||
|
GetTroubleLevel,
|
||||||
|
UserProfile,
|
||||||
|
TroubleDto,
|
||||||
|
ObjectType,
|
||||||
|
RiskState,
|
||||||
} from '@nicestack/common';
|
} from '@nicestack/common';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
import * as argon2 from 'argon2';
|
import * as argon2 from 'argon2';
|
||||||
import { TaxonomyService } from '@server/models/taxonomy/taxonomy.service';
|
import { TaxonomyService } from '@server/models/taxonomy/taxonomy.service';
|
||||||
import { uploadFile } from '@server/utils/tool';
|
import { uploadFile } from '@server/utils/tool';
|
||||||
|
|
|
@ -14,5 +14,6 @@ export default async function (job: Job<any, any, CustomJobType>) {
|
||||||
logger.log(`push message ${job.data.id}`)
|
logger.log(`push message ${job.data.id}`)
|
||||||
pushService.messagePush(job.data.registerToken, job.data.messageContent)
|
pushService.messagePush(job.data.registerToken, job.data.messageContent)
|
||||||
break
|
break
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ import { Injectable, OnModuleInit } from "@nestjs/common";
|
||||||
import { WebSocketType } from "../types";
|
import { WebSocketType } from "../types";
|
||||||
import { BaseWebSocketServer } from "../base/base-websocket-server";
|
import { BaseWebSocketServer } from "../base/base-websocket-server";
|
||||||
import EventBus, { CrudOperation } from "@server/utils/event-bus";
|
import EventBus, { CrudOperation } from "@server/utils/event-bus";
|
||||||
import { ObjectType, SocketMsgType, TroubleDto, MessageDto, PostDto, PostType } from "@nicestack/common";
|
import { ObjectType, SocketMsgType, MessageDto, PostDto, PostType } from "@nicestack/common";
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RealtimeServer extends BaseWebSocketServer implements OnModuleInit {
|
export class RealtimeServer extends BaseWebSocketServer implements OnModuleInit {
|
||||||
onModuleInit() {
|
onModuleInit() {
|
||||||
|
@ -11,11 +11,7 @@ export class RealtimeServer extends BaseWebSocketServer implements OnModuleInit
|
||||||
const receiverIds = (data as Partial<MessageDto>).receivers.map(receiver => receiver.id)
|
const receiverIds = (data as Partial<MessageDto>).receivers.map(receiver => receiver.id)
|
||||||
this.sendToUsers(receiverIds, { type: SocketMsgType.NOTIFY, payload: { objectType: ObjectType.MESSAGE } })
|
this.sendToUsers(receiverIds, { type: SocketMsgType.NOTIFY, payload: { objectType: ObjectType.MESSAGE } })
|
||||||
}
|
}
|
||||||
if (type === ObjectType.TROUBLE) {
|
|
||||||
const trouble = data as Partial<TroubleDto>
|
|
||||||
this.sendToRoom('troubles', { type: SocketMsgType.NOTIFY, payload: { objectType: ObjectType.TROUBLE } })
|
|
||||||
this.sendToRoom(trouble.id, { type: SocketMsgType.NOTIFY, payload: { objectType: ObjectType.TROUBLE } })
|
|
||||||
}
|
|
||||||
if (type === ObjectType.POST) {
|
if (type === ObjectType.POST) {
|
||||||
const post = data as Partial<PostDto>
|
const post = data as Partial<PostDto>
|
||||||
if (post.type === PostType.TROUBLE_INSTRUCTION || post.type === PostType.TROUBLE_PROGRESS) {
|
if (post.type === PostType.TROUBLE_INSTRUCTION || post.type === PostType.TROUBLE_PROGRESS) {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import {
|
||||||
getCounts,
|
getCounts,
|
||||||
getRandomImageLinks
|
getRandomImageLinks
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
|
||||||
import { StaffService } from '@server/models/staff/staff.service';
|
import { StaffService } from '@server/models/staff/staff.service';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GenDevService {
|
export class GenDevService {
|
||||||
|
@ -40,6 +41,7 @@ export class GenDevService {
|
||||||
deptGeneratedCount = 0;
|
deptGeneratedCount = 0;
|
||||||
constructor(
|
constructor(
|
||||||
private readonly appConfigService: AppConfigService,
|
private readonly appConfigService: AppConfigService,
|
||||||
|
|
||||||
private readonly departmentService: DepartmentService,
|
private readonly departmentService: DepartmentService,
|
||||||
private readonly staffService: StaffService,
|
private readonly staffService: StaffService,
|
||||||
private readonly termService: TermService,
|
private readonly termService: TermService,
|
||||||
|
@ -183,7 +185,6 @@ export class GenDevService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async createDepartment(
|
private async createDepartment(
|
||||||
name: string,
|
name: string,
|
||||||
parentId?: string,
|
parentId?: string,
|
||||||
|
|
|
@ -2,12 +2,14 @@ import { db, getRandomElement, getRandomIntInRange, getRandomTimeInterval, Objec
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
export interface DevDataCounts {
|
export interface DevDataCounts {
|
||||||
deptCount: number;
|
deptCount: number;
|
||||||
|
|
||||||
staffCount: number
|
staffCount: number
|
||||||
termCount: number
|
termCount: number
|
||||||
}
|
}
|
||||||
export async function getCounts(): Promise<DevDataCounts> {
|
export async function getCounts(): Promise<DevDataCounts> {
|
||||||
const counts = {
|
const counts = {
|
||||||
deptCount: await db.department.count(),
|
deptCount: await db.department.count(),
|
||||||
|
|
||||||
staffCount: await db.staff.count(),
|
staffCount: await db.staff.count(),
|
||||||
termCount: await db.term.count(),
|
termCount: await db.term.count(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { ReminderService } from './reminder.service';
|
||||||
import { MessageModule } from '@server/models/message/message.module';
|
import { MessageModule } from '@server/models/message/message.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [MessageModule],
|
imports: [ MessageModule],
|
||||||
providers: [ReminderService],
|
providers: [ReminderService],
|
||||||
exports: [ReminderService]
|
exports: [ReminderService]
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,9 +7,8 @@
|
||||||
|
|
||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { db, getUniqueItems, MessageMethodSchema, TroubleType, truncateString } from '@nicestack/common';
|
|
||||||
import { MessageService } from '@server/models/message/message.service';
|
import { MessageService } from '@server/models/message/message.service';
|
||||||
import { extractUniqueStaffIds } from '@server/models/department/utils';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提醒服务类
|
* 提醒服务类
|
||||||
|
@ -75,6 +74,8 @@ export class ReminderService {
|
||||||
* 发送截止日期提醒
|
* 发送截止日期提醒
|
||||||
*/
|
*/
|
||||||
async remindDeadline() {
|
async remindDeadline() {
|
||||||
|
this.logger.log('开始检查截止日期以发送提醒。');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ export class TrpcRouter {
|
||||||
private readonly taxonomy: TaxonomyRouter,
|
private readonly taxonomy: TaxonomyRouter,
|
||||||
private readonly role: RoleRouter,
|
private readonly role: RoleRouter,
|
||||||
private readonly rolemap: RoleMapRouter,
|
private readonly rolemap: RoleMapRouter,
|
||||||
|
|
||||||
private readonly transform: TransformRouter,
|
private readonly transform: TransformRouter,
|
||||||
private readonly auth: AuthRouter,
|
private readonly auth: AuthRouter,
|
||||||
private readonly app_config: AppConfigRouter,
|
private readonly app_config: AppConfigRouter,
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 进入指定目录
|
||||||
|
cd /opt/projects/two-defender-app || exit
|
||||||
|
|
||||||
|
# 停止 server 容器
|
||||||
|
echo "停止 server 容器..."
|
||||||
|
sudo docker-compose stop server
|
||||||
|
|
||||||
|
# 移除 server 容器,自动确认
|
||||||
|
echo "移除 server 容器..."
|
||||||
|
yes | sudo docker-compose rm server
|
||||||
|
|
||||||
|
# 停止 web 容器
|
||||||
|
echo "停止 web 容器..."
|
||||||
|
sudo docker-compose stop web
|
||||||
|
|
||||||
|
# 移除 web 容器,自动确认
|
||||||
|
echo "移除 web 容器..."
|
||||||
|
yes | sudo docker-compose rm web
|
||||||
|
|
||||||
|
# 删除镜像
|
||||||
|
echo "删除 Docker 镜像..."
|
||||||
|
sudo docker image rm td-server:latest
|
||||||
|
sudo docker image rm td-web:latest
|
||||||
|
|
||||||
|
# 加载镜像
|
||||||
|
echo "加载 Docker 镜像..."
|
||||||
|
sudo docker load -i td-server.tar
|
||||||
|
sudo docker load -i td-web.tar
|
||||||
|
|
||||||
|
# 删除已加载的 tar 文件
|
||||||
|
sudo rm td-server.tar
|
||||||
|
sudo rm td-web.tar
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
echo "启动服务..."
|
||||||
|
sudo docker-compose up -d
|
||||||
|
|
||||||
|
# 查看 server 容器的日志
|
||||||
|
echo "查看 server 容器的日志..."
|
||||||
|
sudo docker-compose logs server
|
||||||
|
|
||||||
|
echo "脚本执行完成。"
|
|
@ -0,0 +1,109 @@
|
||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: postgres:latest
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
environment:
|
||||||
|
- POSTGRES_DB=defender_app
|
||||||
|
- POSTGRES_USER=root
|
||||||
|
- POSTGRES_PASSWORD=Letusdoit000
|
||||||
|
volumes:
|
||||||
|
- ./volumes/postgres:/var/lib/postgresql/data
|
||||||
|
minio:
|
||||||
|
image: minio/minio
|
||||||
|
ports:
|
||||||
|
- "9000:9000"
|
||||||
|
- "9001:9001"
|
||||||
|
volumes:
|
||||||
|
- ./volumes/minio:/minio_data
|
||||||
|
environment:
|
||||||
|
- MINIO_ACCESS_KEY=minioadmin
|
||||||
|
- MINIO_SECRET_KEY=minioadmin
|
||||||
|
command: minio server /minio_data --console-address ":9001" -address ":9000"
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD",
|
||||||
|
"curl",
|
||||||
|
"-f",
|
||||||
|
"http://192.168.2.1:9001/minio/health/live"
|
||||||
|
]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 3
|
||||||
|
pgadmin:
|
||||||
|
image: dpage/pgadmin4
|
||||||
|
ports:
|
||||||
|
- "8082:80"
|
||||||
|
environment:
|
||||||
|
- PGADMIN_DEFAULT_EMAIL=insiinc@outlook.com
|
||||||
|
- PGADMIN_DEFAULT_PASSWORD=Letusdoit000
|
||||||
|
tusd:
|
||||||
|
image: tusproject/tusd
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
environment:
|
||||||
|
- AWS_REGION=cn-north-1
|
||||||
|
- AWS_ACCESS_KEY_ID=minioadmin
|
||||||
|
- AWS_SECRET_ACCESS_KEY=minioadmin
|
||||||
|
command: -verbose -s3-bucket app -s3-endpoint http://minio:9000
|
||||||
|
volumes:
|
||||||
|
- ./volumes/tusd:/data
|
||||||
|
depends_on:
|
||||||
|
- minio
|
||||||
|
redis:
|
||||||
|
image: redis:latest
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
volumes:
|
||||||
|
- ./config/redis.conf:/usr/local/etc/redis/redis.conf
|
||||||
|
- ./volumes/redis:/data
|
||||||
|
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
|
||||||
|
# restic:
|
||||||
|
# image: restic/restic:latest
|
||||||
|
# environment:
|
||||||
|
# - RESTIC_REPOSITORY=/backup
|
||||||
|
# - RESTIC_PASSWORD=Letusdoit000
|
||||||
|
# volumes:
|
||||||
|
# - ./volumes/postgres:/data
|
||||||
|
# - ./volumes/restic-cache:/root/.cache/restic
|
||||||
|
# - ./backup:/backup # 本地目录挂载到容器内的 /backup
|
||||||
|
# - ./config/backup.sh:/usr/local/bin/backup.sh # Mount your script inside the container
|
||||||
|
# entrypoint: /usr/local/bin/backup.sh
|
||||||
|
# depends_on:
|
||||||
|
# - db
|
||||||
|
# web:
|
||||||
|
# image: td-web:latest
|
||||||
|
# ports:
|
||||||
|
# - "80:80"
|
||||||
|
# environment:
|
||||||
|
# - VITE_APP_SERVER_IP=192.168.79.77
|
||||||
|
# - VITE_APP_VERSION=0.3.0
|
||||||
|
# - VITE_APP_APP_NAME=两道防线管理后台
|
||||||
|
# server:
|
||||||
|
# image: td-server:latest
|
||||||
|
# ports:
|
||||||
|
# - "3000:3000"
|
||||||
|
# - "3001:3001"
|
||||||
|
# environment:
|
||||||
|
# - DATABASE_URL=postgresql://root:Letusdoit000@db:5432/defender_app?schema=public
|
||||||
|
# - REDIS_HOST=redis
|
||||||
|
# - REDIS_PORT=6379
|
||||||
|
# - REDIS_PASSWORD=Letusdoit000
|
||||||
|
# - TUS_URL=http://192.168.2.1:8080
|
||||||
|
# - JWT_SECRET=/yT9MnLm/r6NY7ee2Fby6ihCHZl+nFx4OQFKupivrhA=
|
||||||
|
# - PUSH_URL=http://dns:9092
|
||||||
|
# - PUSH_APPID=123
|
||||||
|
# - PUSH_APPSECRET=123
|
||||||
|
# - MINIO_HOST=minio
|
||||||
|
# - ADMIN_PHONE_NUMBER=13258117304
|
||||||
|
# - DEADLINE_CRON=0 0 8 * * *
|
||||||
|
# depends_on:
|
||||||
|
# - db
|
||||||
|
# - redis
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
name: defender-app
|
|
@ -1,60 +0,0 @@
|
||||||
version: "3.8"
|
|
||||||
|
|
||||||
services:
|
|
||||||
db:
|
|
||||||
image: postgres:latest
|
|
||||||
ports:
|
|
||||||
- "5432:5432"
|
|
||||||
environment:
|
|
||||||
- POSTGRES_DB=app
|
|
||||||
- POSTGRES_USER=root
|
|
||||||
- POSTGRES_PASSWORD=Letusdoit000
|
|
||||||
volumes:
|
|
||||||
- ./volumes/postgres:/var/lib/postgresql/data
|
|
||||||
minio:
|
|
||||||
image: minio/minio
|
|
||||||
ports:
|
|
||||||
- "9000:9000"
|
|
||||||
- "9001:9001"
|
|
||||||
volumes:
|
|
||||||
- ./volumes/minio:/data
|
|
||||||
environment:
|
|
||||||
- MINIO_ACCESS_KEY=minioadmin
|
|
||||||
- MINIO_SECRET_KEY=minioadmin
|
|
||||||
command: server /data --console-address ":9001" -address ":9000"
|
|
||||||
healthcheck:
|
|
||||||
test:
|
|
||||||
[
|
|
||||||
"CMD",
|
|
||||||
"curl",
|
|
||||||
"-f",
|
|
||||||
"http://localhost:9001/minio/health/live"
|
|
||||||
]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 20s
|
|
||||||
retries: 3
|
|
||||||
pgadmin:
|
|
||||||
image: dpage/pgadmin4
|
|
||||||
ports:
|
|
||||||
- "8081:80"
|
|
||||||
environment:
|
|
||||||
- PGADMIN_DEFAULT_EMAIL=insiinc@outlook.com
|
|
||||||
- PGADMIN_DEFAULT_PASSWORD=Letusdoit000
|
|
||||||
tusd:
|
|
||||||
image: tusproject/tusd
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
environment:
|
|
||||||
- AWS_REGION=cn-north-1
|
|
||||||
- AWS_ACCESS_KEY_ID=minioadmin
|
|
||||||
- AWS_SECRET_ACCESS_KEY=minioadmin
|
|
||||||
|
|
||||||
command: -verbose -s3-bucket app -s3-endpoint http://minio:9000
|
|
||||||
volumes:
|
|
||||||
- ./volumes/tusd:/data
|
|
||||||
redis:
|
|
||||||
image: redis:latest
|
|
||||||
ports:
|
|
||||||
- "6379:6379"
|
|
||||||
volumes:
|
|
||||||
- ./volumes/redis:/data
|
|
|
@ -19,6 +19,7 @@
|
||||||
"tinycolor2": "^1.6.0"
|
"tinycolor2": "^1.6.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
"dayjs": "^1.11.12",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"@nicestack/common": "workspace:^",
|
"@nicestack/common": "workspace:^",
|
||||||
"@tanstack/query-async-storage-persister": "^5.51.9",
|
"@tanstack/query-async-storage-persister": "^5.51.9",
|
||||||
|
|
|
@ -5,7 +5,6 @@ export * from "./useTerm"
|
||||||
export * from "./useRole"
|
export * from "./useRole"
|
||||||
export * from "./useRoleMap"
|
export * from "./useRoleMap"
|
||||||
export * from "./useTransform"
|
export * from "./useTransform"
|
||||||
export * from "./useTrouble"
|
|
||||||
export * from "./useTaxonomy"
|
export * from "./useTaxonomy"
|
||||||
export * from "./useVisitor"
|
export * from "./useVisitor"
|
||||||
export * from "./useMessage"
|
export * from "./useMessage"
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { getQueryKey } from "@trpc/react-query";
|
||||||
|
import { api } from "../trpc"; // Adjust path as necessary
|
||||||
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
|
export function useTransform() {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const queryKey = getQueryKey(api.transform);
|
||||||
|
const termQueryKey = getQueryKey(api.term);
|
||||||
|
const deptQueryKey = getQueryKey(api.department);
|
||||||
|
|
||||||
|
const importTerms = api.transform.importTerms.useMutation({
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey });
|
||||||
|
queryClient.invalidateQueries({ queryKey: termQueryKey });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const importDepts = api.transform.importDepts.useMutation({
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey });
|
||||||
|
queryClient.invalidateQueries({ queryKey: deptQueryKey });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const importStaffs = api.transform.importStaffs.useMutation({
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
importTerms,
|
||||||
|
importDepts,
|
||||||
|
importStaffs,
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ export function useVisitor() {
|
||||||
const create = api.visitor.create.useMutation({
|
const create = api.visitor.create.useMutation({
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
utils.visitor.invalidate();
|
utils.visitor.invalidate();
|
||||||
utils.trouble.invalidate();
|
// utils.trouble.invalidate();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
/**
|
/**
|
||||||
|
@ -20,67 +20,67 @@ export function useVisitor() {
|
||||||
updateFn: (item: any, variables: any) => any
|
updateFn: (item: any, variables: any) => any
|
||||||
) => ({
|
) => ({
|
||||||
// 在请求发送前执行本地数据预更新
|
// 在请求发送前执行本地数据预更新
|
||||||
onMutate: async (variables: any) => {
|
// onMutate: async (variables: any) => {
|
||||||
const previousDataList: any[] = [];
|
// const previousDataList: any[] = [];
|
||||||
// 动态生成参数列表,包括星标和其他参数
|
// // 动态生成参数列表,包括星标和其他参数
|
||||||
|
|
||||||
const paramsList = troubleParams.getItems();
|
// const paramsList = troubleParams.getItems();
|
||||||
console.log(paramsList.length);
|
// console.log(paramsList.length);
|
||||||
// 遍历所有参数列表,执行乐观更新
|
// // 遍历所有参数列表,执行乐观更新
|
||||||
for (const params of paramsList) {
|
// for (const params of paramsList) {
|
||||||
// 取消可能的并发请求
|
// // 取消可能的并发请求
|
||||||
await utils.trouble.findManyWithCursor.cancel();
|
// await utils.trouble.findManyWithCursor.cancel();
|
||||||
// 获取并保存当前数据
|
// // 获取并保存当前数据
|
||||||
const previousData =
|
// const previousData =
|
||||||
utils.trouble.findManyWithCursor.getInfiniteData({
|
// utils.trouble.findManyWithCursor.getInfiniteData({
|
||||||
...params,
|
// ...params,
|
||||||
});
|
// });
|
||||||
previousDataList.push(previousData);
|
// previousDataList.push(previousData);
|
||||||
// 执行乐观更新
|
// // 执行乐观更新
|
||||||
utils.trouble.findManyWithCursor.setInfiniteData(
|
// utils.trouble.findManyWithCursor.setInfiniteData(
|
||||||
{
|
// {
|
||||||
...params,
|
// ...params,
|
||||||
},
|
// },
|
||||||
(oldData) => {
|
// (oldData) => {
|
||||||
if (!oldData) return oldData;
|
// if (!oldData) return oldData;
|
||||||
return {
|
// return {
|
||||||
...oldData,
|
// ...oldData,
|
||||||
pages: oldData.pages.map((page) => ({
|
// pages: oldData.pages.map((page) => ({
|
||||||
...page,
|
// ...page,
|
||||||
items: page.items.map((item) =>
|
// items: page.items.map((item) =>
|
||||||
item.id === variables?.troubleId
|
// item.id === variables?.troubleId
|
||||||
? updateFn(item, variables)
|
// ? updateFn(item, variables)
|
||||||
: item
|
// : item
|
||||||
),
|
// ),
|
||||||
})),
|
// })),
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
return { previousDataList };
|
// return { previousDataList };
|
||||||
},
|
// },
|
||||||
// 错误处理:数据回滚
|
// // 错误处理:数据回滚
|
||||||
onError: (_err: any, _variables: any, context: any) => {
|
// onError: (_err: any, _variables: any, context: any) => {
|
||||||
const paramsList = troubleParams.getItems();
|
// const paramsList = troubleParams.getItems();
|
||||||
paramsList.forEach((params, index) => {
|
// paramsList.forEach((params, index) => {
|
||||||
if (context?.previousDataList?.[index]) {
|
// if (context?.previousDataList?.[index]) {
|
||||||
utils.trouble.findManyWithCursor.setInfiniteData(
|
// utils.trouble.findManyWithCursor.setInfiniteData(
|
||||||
{ ...params },
|
// { ...params },
|
||||||
context.previousDataList[index]
|
// context.previousDataList[index]
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
},
|
// },
|
||||||
// 成功后的缓存失效
|
// // 成功后的缓存失效
|
||||||
onSuccess: (_: any, variables: any) => {
|
// onSuccess: (_: any, variables: any) => {
|
||||||
utils.visitor.invalidate();
|
// utils.visitor.invalidate();
|
||||||
utils.trouble.findFirst.invalidate({
|
// utils.trouble.findFirst.invalidate({
|
||||||
where: {
|
// where: {
|
||||||
id: (variables as any)?.troubleId,
|
// id: (variables as any)?.troubleId,
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
},
|
// },
|
||||||
});
|
});
|
||||||
// 定义具体的mutation
|
// 定义具体的mutation
|
||||||
const read = api.visitor.create.useMutation(
|
const read = api.visitor.create.useMutation(
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import mitt from 'mitt';
|
import mitt from 'mitt';
|
||||||
import { DepartmentDto, ObjectType, RoleMapDto, StaffDto, TermDto, TroubleDto } from '@nicestack/common';
|
import { DepartmentDto, ObjectType, RoleMapDto, StaffDto, TermDto, } from '@nicestack/common';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 枚举类型,表示可以对数据执行的CRUD操作。
|
* 枚举类型,表示可以对数据执行的CRUD操作。
|
||||||
|
@ -38,7 +38,6 @@ type EmitChangeFunction<T> = (data: Partial<T>, operation: CrudOperation) => voi
|
||||||
*/
|
*/
|
||||||
interface EmitChangeHandlers {
|
interface EmitChangeHandlers {
|
||||||
[ObjectType.STAFF]: EmitChangeFunction<StaffDto>; // 员工数据变更处理器
|
[ObjectType.STAFF]: EmitChangeFunction<StaffDto>; // 员工数据变更处理器
|
||||||
[ObjectType.TROUBLE]: EmitChangeFunction<TroubleDto>; // 问题数据变更处理器
|
|
||||||
[ObjectType.ROLE_MAP]: EmitChangeFunction<RoleMapDto>; // 角色映射数据变更处理器
|
[ObjectType.ROLE_MAP]: EmitChangeFunction<RoleMapDto>; // 角色映射数据变更处理器
|
||||||
[ObjectType.DEPARTMENT]: EmitChangeFunction<DepartmentDto>; // 部门数据变更处理器
|
[ObjectType.DEPARTMENT]: EmitChangeFunction<DepartmentDto>; // 部门数据变更处理器
|
||||||
[ObjectType.TERM]: EmitChangeFunction<TermDto> // 术语数据变更处理器
|
[ObjectType.TERM]: EmitChangeFunction<TermDto> // 术语数据变更处理器
|
||||||
|
@ -66,21 +65,6 @@ const emitChangeHandlers: EmitChangeHandlers = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
[ObjectType.TROUBLE]: (data, operation) => {
|
|
||||||
// 转换问题数据,包含额外字段
|
|
||||||
const rowData = {
|
|
||||||
...data,
|
|
||||||
dept_name: data.department?.name,
|
|
||||||
possible_result: data.possibleResult,
|
|
||||||
};
|
|
||||||
// 发出问题数据变更事件
|
|
||||||
EventBus.emit("dataChanged", {
|
|
||||||
type: ObjectType.TROUBLE,
|
|
||||||
operation,
|
|
||||||
data: [rowData]
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
[ObjectType.ROLE_MAP]: (data, operation) => {
|
[ObjectType.ROLE_MAP]: (data, operation) => {
|
||||||
// 转换角色映射数据,包含额外字段
|
// 转换角色映射数据,包含额外字段
|
||||||
const rowData = {
|
const rowData = {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import {
|
||||||
TroubleType,
|
TroubleType,
|
||||||
VisitType,
|
VisitType,
|
||||||
} from "./enum";
|
} from "./enum";
|
||||||
import { troubleUnDetailSelect } from "./select";
|
|
||||||
|
|
||||||
export const InitRoles: {
|
export const InitRoles: {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { troubleUnDetailSelect } from "./select";
|
|
||||||
|
|
||||||
export enum SocketMsgType {
|
export enum SocketMsgType {
|
||||||
NOTIFY,
|
NOTIFY,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import type {
|
||||||
Term,
|
Term,
|
||||||
Message,
|
Message,
|
||||||
Post,
|
Post,
|
||||||
Trouble,
|
|
||||||
RoleMap,
|
RoleMap,
|
||||||
} from "@prisma/client";
|
} from "@prisma/client";
|
||||||
import { SocketMsgType, RolePerms } from "./enum";
|
import { SocketMsgType, RolePerms } from "./enum";
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
"target": "es2022",
|
"target": "es2022",
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"lib": [
|
"lib": [
|
||||||
|
"DOM",
|
||||||
"es2022"
|
"es2022"
|
||||||
],
|
],
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,6 +2,5 @@ packages:
|
||||||
# all packages in direct subdirs of packages/
|
# all packages in direct subdirs of packages/
|
||||||
- 'packages/*'
|
- 'packages/*'
|
||||||
- 'apps/*'
|
- 'apps/*'
|
||||||
- 'libs/*'
|
|
||||||
# exclude packages that are inside test directories
|
# exclude packages that are inside test directories
|
||||||
# - '!**/test/**'
|
# - '!**/test/**'
|
|
@ -3,9 +3,8 @@
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"incremental": true,
|
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": false,
|
||||||
"strictBindCallApply": true,
|
"strictBindCallApply": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
@ -17,10 +16,10 @@
|
||||||
"strictPropertyInitialization": false,
|
"strictPropertyInitialization": false,
|
||||||
"paths": {
|
"paths": {
|
||||||
"@server/*": [
|
"@server/*": [
|
||||||
"./apps/server/src/*"
|
"./apps/server/src/*",
|
||||||
],
|
],
|
||||||
"@web/*": [
|
"@web/*": [
|
||||||
"apps/web/*"
|
"./apps/web/*",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue