feat:backup

This commit is contained in:
1708-huayu 2025-05-30 18:53:42 +08:00
parent d2e9e4c4ae
commit ec3bb0cdef
11 changed files with 165 additions and 12 deletions

View File

@ -19,3 +19,15 @@ docker run -d -p 3001:80 -p 3002:443 --network task-manager --restart unless-sto
# 进入容器 # 进入容器
docker exec -it a3ca9658cc6ce331cc0e4f84996088940a386b39b3e2edd56549d335a52ab581 /bin/sh docker exec -it a3ca9658cc6ce331cc0e4f84996088940a386b39b3e2edd56549d335a52ab581 /bin/sh
``` ```
日更
```shell
docker build -t task-manager-nginx:20250526 .
docker stop task-manager-nginx
docker run -d -p 3001:80 -p 3002:443 --network task-manager --restart unless-stopped -v ./out:/usr/share/nginx/html --name task-manager-nginx task-manager-nginx:20250528
# 复制证书到云服务器
scp -r cert/ root@121.36.71.28:/usr/local/software/nginx-1.28.0/
```

120
docker/nginx-yun.conf Normal file
View File

@ -0,0 +1,120 @@
# 全局配置
user root;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
# 事件处理
events {
worker_connections 1024;
}
# HTTP 服务器
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# HTTPS 服务器监听端口
# 443
# HTTP 服务器监听端口
server {
listen 80;
# start 启用https
listen 443 ssl;
# 服务器名称
server_name www.huaruyu.com;
# 将所有HTTP请求通过rewrite指令重定向到HTTPS。
# rewrite ^(.*)$ https://$host$1;
# 填写证书文件绝对路径
ssl_certificate /usr/local/software/nginx-1.28.0/cert/www.huaruyu.com.pem;
# 填写证书私钥文件绝对路径
ssl_certificate_key /usr/local/software/nginx-1.28.0/cert/www.huaruyu.com.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
# 自定义设置使用的TLS协议的类型以及加密套件以下为配置示例请您自行评估是否需要配置
# TLS协议版本越高HTTPS通信的安全性越高但是相较于低版本TLS协议高版本TLS协议对浏览器的兼容性较差。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
# 表示优先使用服务端加密套件。默认开启
ssl_prefer_server_ciphers on;
# end 启用https
# 启用 ETag 头Nginx 会为每个资源生成一个唯一的 ETag 值当资源更新时ETag 值会改变。
etag on;
# 设置允许跨域的域,* 表示允许任何域,也可以设置特定的域,has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.
add_header 'Access-Control-Allow-Origin' '*';
# 允许的方法
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
# 允许的头信息字段
add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type,Authorization,Origin' always;
# 缓存时间
add_header 'Access-Control-Max-Age' 1728000 always;
# 预检请求的处理
if ($request_method = 'OPTIONS') {
return 204;
}
# 访问日志路径
access_log /var/log/nginx/access.log;
# 站点根目录
root /usr/share/nginx/html;
# 代理配置
location / {
# 默认页面
index index.html index.htm;
try_files $uri $uri.html $uri/ =404;
# try_files $uri $uri/ =404;
}
# 第二个页面的配置
location ^~ /mobile/ {
# index index.html index.htm;
# try_files $uri $uri.html $uri/ =404;
alias /usr/share/nginx/html/mobile/;
index index.html index.htm;
try_files $uri $uri/ /mobile/index.html;
}
location ^~ /todo-server/ {
# 预检请求的处理
if ($request_method = 'OPTIONS') {
return 204;
}
# rewrite ^/todo-server/(.*)$ /$1 break;
proxy_pass http://localhost:8092/;
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;
client_body_buffer_size 16k;
client_max_body_size 100M;
}
location ^~ /security-server/ {
# 预检请求的处理
if ($request_method = 'OPTIONS') {
return 204;
}
# rewrite ^/security-server/(.*)$ /$1 break;
proxy_pass http://localhost:8091/;
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;
client_body_buffer_size 16k;
client_max_body_size 100M;
}
location /task/ {
# 预检请求的处理
if ($request_method = 'OPTIONS') {
return 204;
}
rewrite ^/task/(.*)$ /task/$1.html break;
}
# 静态文件缓存配置
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 7d;
access_log off;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 KiB

View File

@ -46,7 +46,7 @@ export default function Layout({children}: { children: React.ReactNode }) {
if (result.status.success) { if (result.status.success) {
// recursionActionChild(result.data.content); // recursionActionChild(result.data.content);
result.data.content.forEach(dataType=>{ result.data.content.forEach(dataType=>{
dataType.state=taskStateList.find(taskState=>taskState.code===dataType.state+'')?.name dataType.state=taskStateList.find(taskState=>taskState.code===dataType.state+'')!.name
}) })
setResultDataTypeList(result.data.content) setResultDataTypeList(result.data.content)
console.log("setResultDataTypeList(result.data.content)",result.data.content) console.log("setResultDataTypeList(result.data.content)",result.data.content)

View File

@ -37,7 +37,6 @@ export type TaskMessage ={
export type DataType = TaskMessage&{ export type DataType = TaskMessage&{
key: React.ReactNode; key: React.ReactNode;
type:number; type:number;
action?:React.ReactNode; action?:React.ReactNode;
expectedStartTime?:string; expectedStartTime?:string;

View File

@ -43,8 +43,8 @@ export const DetailForm: React.FC<DetailFormProps> = (props) => {
console.log('getTask(props.itemId)', props.itemId, task); console.log('getTask(props.itemId)', props.itemId, task);
if (task.status.success) { if (task.status.success) {
// setTaskMessage(task.data) // setTaskMessage(task.data)
task.data.state = taskStateList.find(taskState => taskState.code === task.data.state?.toString())?.name; task.data.state = taskStateList.find(taskState => taskState.code === task.data.state?.toString())!.name;
task.data.priority = taskPriorityList.find(taskPriority => taskPriority.code === task.data.priority?.toString())?.name; task.data.priority = taskPriorityList.find(taskPriority => taskPriority.code === task.data.priority?.toString())!.name;
defaultPriority = task.data.priority defaultPriority = task.data.priority
task.data.actualTimeRange = [task.data.actualStartTime ? dayjs(task.data.actualStartTime) : '', task.data.actualTimeRange = [task.data.actualStartTime ? dayjs(task.data.actualStartTime) : '',
task.data.actualEndTime ? dayjs(task.data.actualEndTime) : '']; task.data.actualEndTime ? dayjs(task.data.actualEndTime) : ''];
@ -95,6 +95,7 @@ export const DetailForm: React.FC<DetailFormProps> = (props) => {
id: values.id, id: values.id,
pPid: props.operationId === OPERATION_BUTTON_TYPE.ADD_CHILD ? props.pPid : values.pPid, pPid: props.operationId === OPERATION_BUTTON_TYPE.ADD_CHILD ? props.pPid : values.pPid,
pid: props.operationId === OPERATION_BUTTON_TYPE.ADD_CHILD ? props.itemId : props.operationId === OPERATION_BUTTON_TYPE.UPDATE ? values.pid : 0, pid: props.operationId === OPERATION_BUTTON_TYPE.ADD_CHILD ? props.itemId : props.operationId === OPERATION_BUTTON_TYPE.UPDATE ? values.pid : 0,
pName: values.pName,
code: values.code, code: values.code,
name: values.name, name: values.name,
description: values.description, description: values.description,

View File

@ -25,7 +25,7 @@ export const DroppableTable: React.FC<DroppableTableProps> = (props) => {
}else if (props.tableCode=='4'){ }else if (props.tableCode=='4'){
setStateName('紧急重要'); setStateName('紧急重要');
} }
}, []); }, [props]);
const getItemStyle = (isDragging:any, draggableStyle:any):CSSProperties => { const getItemStyle = (isDragging:any, draggableStyle:any):CSSProperties => {
console.log({draggableStyle}) console.log({draggableStyle})
return { return {

View File

@ -43,8 +43,8 @@ export const DetailForm: React.FC<DetailFormProps> = (props) => {
console.log('getTask(props.itemId)', props.itemId, task); console.log('getTask(props.itemId)', props.itemId, task);
if (task.status.success) { if (task.status.success) {
// setTaskMessage(task.data) // setTaskMessage(task.data)
task.data.state = taskStateList.find(taskState => taskState.code === task.data.state?.toString())?.name; task.data.state = taskStateList.find(taskState => taskState.code === task.data.state?.toString())!.name;
task.data.priority = taskPriorityList.find(taskPriority => taskPriority.code === task.data.priority?.toString())?.name; task.data.priority = taskPriorityList.find(taskPriority => taskPriority.code === task.data.priority?.toString())!.name;
defaultPriority = task.data.priority defaultPriority = task.data.priority
task.data.actualTimeRange = [task.data.actualStartTime ? dayjs(task.data.actualStartTime) : '', task.data.actualTimeRange = [task.data.actualStartTime ? dayjs(task.data.actualStartTime) : '',
task.data.actualEndTime ? dayjs(task.data.actualEndTime) : '']; task.data.actualEndTime ? dayjs(task.data.actualEndTime) : ''];
@ -95,6 +95,7 @@ export const DetailForm: React.FC<DetailFormProps> = (props) => {
id: values.id, id: values.id,
pPid: props.operationId === OPERATION_BUTTON_TYPE.ADD_CHILD ? props.pPid : values.pPid, pPid: props.operationId === OPERATION_BUTTON_TYPE.ADD_CHILD ? props.pPid : values.pPid,
pid: props.operationId === OPERATION_BUTTON_TYPE.ADD_CHILD ? props.itemId : props.operationId === OPERATION_BUTTON_TYPE.UPDATE ? values.pid : 0, pid: props.operationId === OPERATION_BUTTON_TYPE.ADD_CHILD ? props.itemId : props.operationId === OPERATION_BUTTON_TYPE.UPDATE ? values.pid : 0,
pName:values.pName,
code: values.code, code: values.code,
name: values.name, name: values.name,
description: values.description, description: values.description,

View File

@ -46,7 +46,7 @@ const TreeTable: React.FC<TableSearchType> = (props) => {
width: '10%', width: '10%',
}, },
{ {
title: '任务名称', title: props.priority=='0'?"不重要不紧急":props.priority=='1'?"不重要紧急":props.priority=='2'?"重要不紧急":props.priority=='3'?"重要紧急":"任务名称",
dataIndex: 'name', dataIndex: 'name',
key: 'name', key: 'name',
width: '20%', width: '20%',

View File

@ -51,8 +51,8 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
console.log('DetailModelForm:getTask(props.itemId)', props.itemId, task); console.log('DetailModelForm:getTask(props.itemId)', props.itemId, task);
if (task.status.success) { if (task.status.success) {
// setTaskMessage(task.data) // setTaskMessage(task.data)
task.data.state = taskStateList.find(taskState => taskState.code === task.data.state?.toString())?.name; task.data.state = taskStateList.find(taskState => taskState.code === task.data.state?.toString())!.name;
task.data.priority = taskPriorityList.find(taskPriority => taskPriority.code === task.data.priority?.toString())?.name; task.data.priority = taskPriorityList.find(taskPriority => taskPriority.code === task.data.priority?.toString())!.name;
task.data.actualTimeRange = [task.data.actualStartTime ? dayjs(task.data.actualStartTime) : undefined, task.data.actualTimeRange = [task.data.actualStartTime ? dayjs(task.data.actualStartTime) : undefined,
task.data.actualEndTime ? dayjs(task.data.actualEndTime) : undefined]; task.data.actualEndTime ? dayjs(task.data.actualEndTime) : undefined];
task.data.expectedTimeRange = [task.data.expectedStartTime ? dayjs(task.data.expectedStartTime) : undefined, task.data.expectedTimeRange = [task.data.expectedStartTime ? dayjs(task.data.expectedStartTime) : undefined,
@ -145,10 +145,10 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
values.pid='0' values.pid='0'
} }
if (values.expectedTimeRange?.[0]!=undefined) { if (values.expectedTimeRange?.[0]!=undefined) {
values.expectedStartTime=dayjs(values.expectedTimeRange[0]).toDate() values.expectedStartTime=dayjs(values.expectedTimeRange[0]).format()
} }
if (values.expectedTimeRange?.[1]!=undefined) { if (values.expectedTimeRange?.[1]!=undefined) {
values.expectedEndTime=dayjs(values.expectedTimeRange[1]).toDate() values.expectedEndTime=dayjs(values.expectedTimeRange[1]).format()
} }
if (values.actualTimeRange?.[0]!=undefined) { if (values.actualTimeRange?.[0]!=undefined) {
values.actualStartTime=dayjs(values.actualTimeRange[0]).toDate() values.actualStartTime=dayjs(values.actualTimeRange[0]).toDate()

View File

@ -0,0 +1,20 @@
# 可能用到的技术栈
## Next
https://nextjs.org/docs/app/api-reference/cli/next#next-build-options
## 面向开发者的 Web 技术
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/scrollX
## 富文本
https://playground.lexical.dev/
https://lexical.dev/docs/getting-started/creating-plugin
## 界面布局
https://github.com/react-grid-layout/react-grid-layout
## 拖拉
https://github.com/atlassian/react-beautiful-dnd
## 3D
https://github.com/mrdoob/three.js/
https://threejs.org/examples/#webgl_animation_keyframes
## 状态管理
zustand
## 动画
https://motion.dev/docs/react-quick-start