feat:backup
This commit is contained in:
parent
d2e9e4c4ae
commit
ec3bb0cdef
|
@ -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
|
||||
```
|
||||
|
||||
|
||||
日更
|
||||
```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/
|
||||
|
||||
```
|
|
@ -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 |
|
@ -46,7 +46,7 @@ export default function Layout({children}: { children: React.ReactNode }) {
|
|||
if (result.status.success) {
|
||||
// recursionActionChild(result.data.content);
|
||||
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)
|
||||
console.log("setResultDataTypeList(result.data.content)",result.data.content)
|
||||
|
|
|
@ -37,7 +37,6 @@ export type TaskMessage ={
|
|||
|
||||
export type DataType = TaskMessage&{
|
||||
key: React.ReactNode;
|
||||
|
||||
type:number;
|
||||
action?:React.ReactNode;
|
||||
expectedStartTime?:string;
|
||||
|
|
|
@ -43,8 +43,8 @@ export const DetailForm: React.FC<DetailFormProps> = (props) => {
|
|||
console.log('getTask(props.itemId)', props.itemId, task);
|
||||
if (task.status.success) {
|
||||
// setTaskMessage(task.data)
|
||||
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.state = taskStateList.find(taskState => taskState.code === task.data.state?.toString())!.name;
|
||||
task.data.priority = taskPriorityList.find(taskPriority => taskPriority.code === task.data.priority?.toString())!.name;
|
||||
defaultPriority = task.data.priority
|
||||
task.data.actualTimeRange = [task.data.actualStartTime ? dayjs(task.data.actualStartTime) : '',
|
||||
task.data.actualEndTime ? dayjs(task.data.actualEndTime) : ''];
|
||||
|
@ -95,6 +95,7 @@ export const DetailForm: React.FC<DetailFormProps> = (props) => {
|
|||
id: values.id,
|
||||
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,
|
||||
pName: values.pName,
|
||||
code: values.code,
|
||||
name: values.name,
|
||||
description: values.description,
|
||||
|
|
|
@ -25,7 +25,7 @@ export const DroppableTable: React.FC<DroppableTableProps> = (props) => {
|
|||
}else if (props.tableCode=='4'){
|
||||
setStateName('紧急重要');
|
||||
}
|
||||
}, []);
|
||||
}, [props]);
|
||||
const getItemStyle = (isDragging:any, draggableStyle:any):CSSProperties => {
|
||||
console.log({draggableStyle})
|
||||
return {
|
||||
|
|
|
@ -43,8 +43,8 @@ export const DetailForm: React.FC<DetailFormProps> = (props) => {
|
|||
console.log('getTask(props.itemId)', props.itemId, task);
|
||||
if (task.status.success) {
|
||||
// setTaskMessage(task.data)
|
||||
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.state = taskStateList.find(taskState => taskState.code === task.data.state?.toString())!.name;
|
||||
task.data.priority = taskPriorityList.find(taskPriority => taskPriority.code === task.data.priority?.toString())!.name;
|
||||
defaultPriority = task.data.priority
|
||||
task.data.actualTimeRange = [task.data.actualStartTime ? dayjs(task.data.actualStartTime) : '',
|
||||
task.data.actualEndTime ? dayjs(task.data.actualEndTime) : ''];
|
||||
|
@ -95,6 +95,7 @@ export const DetailForm: React.FC<DetailFormProps> = (props) => {
|
|||
id: values.id,
|
||||
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,
|
||||
pName:values.pName,
|
||||
code: values.code,
|
||||
name: values.name,
|
||||
description: values.description,
|
||||
|
|
|
@ -46,7 +46,7 @@ const TreeTable: React.FC<TableSearchType> = (props) => {
|
|||
width: '10%',
|
||||
},
|
||||
{
|
||||
title: '任务名称',
|
||||
title: props.priority=='0'?"不重要不紧急":props.priority=='1'?"不重要紧急":props.priority=='2'?"重要不紧急":props.priority=='3'?"重要紧急":"任务名称",
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
width: '20%',
|
||||
|
|
|
@ -51,8 +51,8 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
console.log('DetailModelForm:getTask(props.itemId)', props.itemId, task);
|
||||
if (task.status.success) {
|
||||
// setTaskMessage(task.data)
|
||||
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.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.actualTimeRange = [task.data.actualStartTime ? dayjs(task.data.actualStartTime) : undefined,
|
||||
task.data.actualEndTime ? dayjs(task.data.actualEndTime) : 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'
|
||||
}
|
||||
if (values.expectedTimeRange?.[0]!=undefined) {
|
||||
values.expectedStartTime=dayjs(values.expectedTimeRange[0]).toDate()
|
||||
values.expectedStartTime=dayjs(values.expectedTimeRange[0]).format()
|
||||
}
|
||||
if (values.expectedTimeRange?.[1]!=undefined) {
|
||||
values.expectedEndTime=dayjs(values.expectedTimeRange[1]).toDate()
|
||||
values.expectedEndTime=dayjs(values.expectedTimeRange[1]).format()
|
||||
}
|
||||
if (values.actualTimeRange?.[0]!=undefined) {
|
||||
values.actualStartTime=dayjs(values.actualTimeRange[0]).toDate()
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue