Compare commits

..

No commits in common. "f6e4b6400aa4090dafb6f89d7a11035469b2b164" and "cf8fdda4b67262da8b0aa2c219e084441b8d3b38" have entirely different histories.

14 changed files with 54 additions and 5855 deletions

View File

@ -2,8 +2,5 @@
# NEXT_PUBLIC_TODO_REQUEST_URL=http://localhost:8092
# NEXT_PUBLIC_SECURITY_REQUEST_URL=http://localhost:8091
# NEXT_PUBLIC_TODO_REQUEST_URL=http://localhost:80/todo-server
# NEXT_PUBLIC_SECURITY_REQUEST_URL=http://localhost:80/security-server
NEXT_PUBLIC_TODO_REQUEST_URL=http://www.huaruyu.com/todo-server
NEXT_PUBLIC_SECURITY_REQUEST_URL=http://www.huaruyu.com/security-server
NEXT_PUBLIC_TODO_REQUEST_URL=http://localhost:80/todo-server
NEXT_PUBLIC_SECURITY_REQUEST_URL=http://localhost:80/security-server

View File

@ -1,15 +0,0 @@
```shell
scp -r out/ shixiaohua@10.104.11.99:/home/shixiaohua/docker/todo-web
```
docker操作
```shell
docker stop task-manager-nginx
docker rm task-manager-nginx
docker rmi task-manager-nginx
docker build -t task-manager-nginx .
# docker run -d -p 3001:3001 --network task-manager --restart unless-stopped -v ./out:/usr/share/nginx/html --name task-manager-nginx task-manager-nginx
docker run -d -p 3001:80 --network task-manager --restart unless-stopped -v ./out:/usr/share/nginx/html --name task-manager-nginx task-manager-nginx
```

View File

@ -15,14 +15,12 @@ http {
default_type application/octet-stream;
# HTTP 服务器监听端口
server {
listen 80;
# 启用 ETag Nginx 会为每个资源生成一个唯一的 ETag 当资源更新时ETag 值会改变。
etag on;
listen 3001;
# 设置允许跨域的域,* 表示允许任何域,也可以设置特定的域,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-Methods' 'GET, POST, OPTIONS' always;
# 允许的头信息字段
add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type,Authorization,Origin' always;
# 缓存时间
@ -44,16 +42,6 @@ http {
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') {

5744
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -14,13 +14,11 @@
"@tailwindcss/forms": "^0.5.7",
"antd": "^5.16.1",
"axios": "^1.6.8",
"dayjs": "^1.11.13",
"js-cookie": "^3.0.5",
"next": "14.1.3",
"postcss": "8.4.31",
"react": "^18",
"react-big-calendar": "^1.12.2",
"react-device-detect": "^2.2.3",
"react-dom": "^18",
"sass": "^1.77.3",
"tailwindcss": "3.3.3"
@ -36,7 +34,6 @@
"eslint-config-next": "14.1.3",
"prettier": "3.0.3",
"prettier-plugin-tailwindcss": "0.5.4",
"typescript": "^5",
"react-beautiful-dnd": "^13.1.8"
"typescript": "^5"
}
}

View File

@ -1,5 +1,6 @@
import type {Metadata} from "next";
import "@/ui/globals.css";
import Script from "next/script";
export const metadata: Metadata = {
title: "任务管理",
@ -17,6 +18,8 @@ export default function RootLayout({
}>) {
return (
<html>
<Script src="https://cdn.jsdelivr.net/npm/dayjs@1/dayjs.min.js"/>
<Script src="https://cdn.jsdelivr.net/npm/dayjs@1/locale/zh-cn.js"/>
<head>
<title></title>
<link rel="icon" href="/favicon.ico"/>

View File

@ -2,20 +2,11 @@
import { useRouter} from "next/navigation";
import dayjs from "dayjs";
import {useEffect} from "react";
import { isMobile } from 'react-device-detect';
export default function Home() {
const {replace} = useRouter();
useEffect(()=>{
if(localStorage.getItem('platform-security')){
if (isMobile){
replace('/mobile/')
}else {
replace("/task/project")
}
}else {
replace("/login")
}
replace("/login")
},[])
dayjs.locale('zh-cn')
return (

View File

@ -13,31 +13,8 @@ import {DataType, ResponseVO, ResultPage} from "@/lib/definitions";
export default function Layout({children}: { children: React.ReactNode }) {
const [resultDataTypeList, setResultDataTypeList] = useState<DataType[]>([]);
const [loadingState,setLoadingState] =useState(true)
const data = useContext(LocalContext);
console.log('data',data);
// 如果有pid,在前端过滤(防止中间数据不满足条件,导致子数据丢失),
// 无pid在后端过滤防止数据量过大
var pid = useSearchParams().get('pid');
console.log('pid!=null',pid!=null);
const refreshDate = (): void => {
const leftUp:{name:string,operateType:string,value:string|number|boolean}[] = []
setLoadingState(true)
if (pid!=null) {
leftUp.push({name:"pid",value:pid,operateType:"="},
{name:'TREE-FILTER',value:"true",operateType: "TREE-FILTER"},
{name:'ALL-CHILD',value:"true",operateType: "ALL-CHILD"},
);
}else {
if (data.taskState.length>0){
leftUp.push({name:"state",value:data.taskState,operateType:"IN"});
}
if (data.expectedStartTime.length>0){
const parse = JSON.parse(data.expectedStartTime);
leftUp.push(...parse);
}
}
getTaskTreeResult(JSON.stringify({
pageSize:1000,
pageNumber:1,
@ -67,6 +44,28 @@ export default function Layout({children}: { children: React.ReactNode }) {
document.getElementById('tenLeft').style.fontSize = divHeight/6*4 + 'px';
refreshDate()
}, [useContext(LocalContext)]);
const data = useContext(LocalContext);
const leftUp:{name:string,operateType:string,value:string|number|boolean}[] = []
var pid = useSearchParams().get('pid');
// 如果有pid,在前端过滤(防止中间数据不满足条件,导致子数据丢失),
// 无pid在后端过滤防止数据量过大
console.log('data',data);
console.log('pid!=null',pid!=null);
if (pid!=null) {
leftUp.push({name:"pid",value:pid,operateType:"="},
{name:'TREE-FILTER',value:"true",operateType: "TREE-FILTER"},
{name:'ALL-CHILD',value:"true",operateType: "ALL-CHILD"},
);
}else {
if (data.taskState.length>0){
leftUp.push({name:"state",value:data.taskState,operateType:"IN"});
}
if (data.expectedStartTime.length>0){
const parse = JSON.parse(data.expectedStartTime);
leftUp.push(...parse);
}
}
return (
<div>
<div className='firstRow' style={{display: 'flex'}}>

View File

@ -140,7 +140,7 @@ export const taskStateList: DictType[] = [
// {
// id: 6,
// code: '6',
// name: '关闭',
// name: '排期中',
// order: 6,
// color: 'red'
// },
@ -173,7 +173,6 @@ export enum OPERATION_BUTTON_TYPE {
UPDATE,
DELETE,
COMPLETE,
SHOW_TREE,
SHOW_FOUR,
SHOW_CALENDAR,
ADD,

View File

@ -1,10 +1,16 @@
'use client'
import {
AlipayOutlined,
LockOutlined, MailOutlined,
MobileOutlined,
TaobaoOutlined,
UserOutlined,
WeiboOutlined,
} from '@ant-design/icons';
import {
LoginForm,
LoginFormPage,
ProConfigProvider,
ProFormCaptcha,
ProFormCheckbox,
ProFormText,
@ -16,8 +22,8 @@ import {useState} from 'react';
import {CaptchaLoginSuccess, LoginObject} from "@/lib/login/definitions";
import {httpReq} from "@/utils/axiosReq";
import {useRouter} from 'next/navigation'
import { isMobile } from 'react-device-detect';
import Cookies from "js-cookie";
import {use} from 'react';
import Loading from "@/app/loading";
type LoginType = 'email' | 'account';
@ -31,11 +37,6 @@ const iconStyles: CSSProperties = {
export default function Page() {
const [loaded, setLoaded] = useState(false);
useLayoutEffect(() => {
if (isMobile){
console.log("手机端")
}else {
console.log("PC端")
}
console.log('页面所有资源加载完毕');
setLoaded(true);
})
@ -52,11 +53,7 @@ export default function Page() {
content: "使用帐号" + captchaLoginSuccess.username + "登录成功"
})
localStorage.setItem('platform-security', captchaLoginSuccess.token)
if (isMobile){
window.location.href = '/mobile/'
}else {
router.push('/task/project')
}
router.push('/task/project')
setOpen(false)
setLoading(false)
}
@ -113,13 +110,9 @@ export default function Page() {
// 删除名为 'platform-security' 的Cookie
// Cookies.remove('platform-security');
// 设置一个有效期为7天的Cookie
Cookies.set('platform-security', response.data.data, { expires: 7 });
// Cookies.set('platform-security', response.data.data, { expires: 7 });
// 登录成功,跳转到首页或者回调
if (isMobile){
window.location.href = '/mobile/'
}else {
router.push('/task/project')
}
router.push('/task/project')
} else {
messageApi.open({
type: 'error',
@ -140,17 +133,13 @@ export default function Page() {
setCaptchaLoginSuccessList(response.data.data)
setOpen(true)
} else {
localStorage.setItem('platform-security', response.data.data[0].token)
localStorage.setItem('platform-security', response.data.data)
// 删除名为 'platform-security' 的Cookie
// Cookies.remove('platform-security');
// 设置一个有效期为7天的Cookie
Cookies.set('platform-security', response.data.data[0].token, { expires: 7 });
// Cookies.set('platform-security', response.data.data, { expires: 7 });
// 登录成功,跳转到首页或者回调
if (isMobile){
window.location.href = '/mobile/'
}else {
router.push('/task/project')
}
router.push('/task/project')
}
} else {
messageApi.open({

View File

@ -110,10 +110,6 @@ class OperationButton extends React.Component<OperationButtonProps, OperationMod
}}
><a></a></Popconfirm>,
},
{
key: OPERATION_BUTTON_TYPE.SHOW_TREE,
label: <Link href={"/task/project?pid=" + this.props.itemId}></Link>,
},
{
key: OPERATION_BUTTON_TYPE.SHOW_FOUR,
label: <Link href={"/task/four?pid=" + this.props.itemId}></Link>,

View File

@ -7,7 +7,6 @@ import '@/ui/task/TitleOperation.modules.css'
import LocalContext from "@/ui/LocalContent";
import {RequestDateType} from "@/ui/task/RequestDateType";
import dayjs, {Dayjs} from "dayjs";
import {useSearchParams} from "next/dist/client/components/navigation";
interface TitleOperationProps {
setTaskState: (value: string) => void;
@ -22,7 +21,6 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
}: TitleOperationProps) => {
const {replace} = useRouter();
console.log('usePathname()', usePathname());
console.log('useSearchParams()', useSearchParams().get('pid'));
const data = useContext(LocalContext);
const {RangePicker} = DatePicker;
const expectStartTimeParseResult: RequestDateType[] = data.expectedStartTime.length > 0 ? JSON.parse(data.expectedStartTime) : [undefined, undefined]

View File

@ -1,6 +1,7 @@
'use client'
import React, {useCallback, useContext, useEffect, useMemo, useRef, useState} from "react";
import {Calendar, dayjsLocalizer, Event, SlotInfo, View} from 'react-big-calendar'
// https://day.js.org/docs/zh-CN/get-set/get-set
import dayjs, {Dayjs} from 'dayjs'
import 'react-big-calendar/lib/css/react-big-calendar.css'
import 'react-big-calendar/lib/sass/styles.scss'
@ -39,7 +40,7 @@ const CalShow: React.FC = () => {
start: dayjs(date).startOf('week').toDate(),
end: dayjs(date).endOf('week').toDate()
});
const state=useContext(LocalContext).taskState;
const [state, setState] = useState<string>(useContext(LocalContext).taskState);
const handleViewChange = (newView: View) => {
setView(newView);

View File

@ -18,8 +18,6 @@ import {DetailModelForm} from "@/ui/task/project/DetailModelForm";
import OperationButton from "@/ui/task/OperationButton";
import dayjs from "dayjs";
import '@/ui/task/project/TreeTablePro.modules.css'
import {useSearchParams} from "next/navigation";
const TreeTablePro: React.FC = () => {
const actionRef = useRef<ActionType>();
@ -28,10 +26,7 @@ const TreeTablePro: React.FC = () => {
const [filterChecked, setFilterChecked] = React.useState(true);
const [current,setCurrent] = React.useState(1);
const [pageSize,setPageSize] = React.useState(10);
const pathPid = useSearchParams().get('pid');
const pid = pathPid?pathPid:'0';
const { RangePicker } = DatePicker;
console.log("TreeTablePro",useSearchParams().get('pid'))
const columns: ProColumns<DataType>[] = [
{
key:'code',
@ -150,10 +145,6 @@ const TreeTablePro: React.FC = () => {
actionRef.current?.reload( false);
}} /></>)
}
useEffect(()=>{
actionRef.current?.reload( false)
},[useSearchParams()])
return (
<ProTable<DataType>
columns={columns}
@ -163,9 +154,8 @@ const TreeTablePro: React.FC = () => {
console.log('request',params,params.keyword,sort, filter);
const searchList=[]
if (switchChecked) {
searchList.push({name:'tree',value:'TRUE',operateType:"TREE"})
searchList.push({name:'pid',value:'0',operateType:"="},{name:'tree',value:'TRUE',operateType:"TREE"})
}
searchList.push({name:"pid",value:pid,operateType:"="})
if (filterChecked) {
searchList.push({name:'tree',value:'TRUE',operateType:"TREE-FILTER"})
}