feat:1.主题配置2.网站首页设置3.设置信息持久化

This commit is contained in:
1708-huayu 2025-08-25 18:49:01 +08:00
parent 5eaf84df48
commit 51329f09e8
24 changed files with 324 additions and 89 deletions

View File

@ -57,6 +57,14 @@ http {
add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type,Authorization,Origin,source-client' always;
# 缓存时间
add_header 'Access-Control-Max-Age' 1728000 always;
# 安全头部
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
# 确保不会重定向到带端口的URL
add_header X-Forwarded-Host $host;
add_header X-Forwarded-Port 443;
add_header X-Forwarded-Proto https;
# 预检请求的处理
if ($request_method = 'OPTIONS') {
return 204;
@ -83,7 +91,7 @@ http {
index index.html index.htm;
# 正确的文件查找逻辑:所有路由都返回 index.html
try_files $uri $uri/ /todo/index.html;
try_files $uri $uri.html $uri/ /todo/index.html;
# 安全头部
add_header X-Frame-Options "SAMEORIGIN" always;

BIN
public/static/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
public/static/pc-Web.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 868 KiB

View File

@ -40,8 +40,8 @@ export default function Layout({children}: { children: React.ReactNode }) {
data: {state: data.taskState,pid:pid,treeList:true,treeOrList:false,treeFilter:true},
sortList:[{property:"sort_no",direction:"ASC"}]
}
if (data.expectedStartTime.length>0){
const parse = JSON.parse(data.expectedStartTime);
if (data.expectedStartTime!.length>0){
const parse = JSON.parse(data.expectedStartTime!);
requestParam.data.expectedStartTimeStart=parse[0].value;
requestParam.data.expectedStartTimeEnd=parse[1].value;
}

View File

@ -30,10 +30,10 @@ export default function Layout({children}: { children: React.ReactNode }) {
{name:'ALL-CHILD',value:"true",operateType: "ALL-CHILD"},
);
}else {
if (data.taskState.length>0){
if (data.taskState && data.taskState.length>0){
leftUp.push({name:"state",value:data.taskState,operateType:"IN"});
}
if (data.expectedStartTime.length>0){
if (data.expectedStartTime && data.expectedStartTime.length>0){
const parse = JSON.parse(data.expectedStartTime);
leftUp.push(...parse);
}

View File

@ -6,55 +6,120 @@ import dayjs from "dayjs";
import 'dayjs/locale/zh-cn';
import {ConfigProvider} from "antd";
import locale from "antd/locale/zh_CN";
import {BackgroundProvider, useBackground} from "@/ui/BackgroundContext";
import Cookies from "js-cookie";
export default function Layout({children}: { children: React.ReactNode }) {
function BodyWithBackground({children}: { children: React.ReactNode }) {
dayjs.locale('zh-cn');
const [taskState, setTaskState] = React.useState<string>('8,9,10')
// 背景色 start
const {backgroundColor} = useBackground();
// 背景色 end
// 查询参数获取 start
const {
taskState: taskStateCookies, taskTypeList: taskTypeListCookies,
refreshDataFlag: refreshDataFlagCookies,
expectedStartTime: expectedStartTimeCookies
} = JSON.parse(Cookies.get('platform-setting') || "{}")
console.log(taskStateCookies || '8,9,10',{taskStateCookies})
const [taskState, setTaskState] =
React.useState<string>(taskStateCookies ?? '8,9,10')
let expectStartTimeList = [];
expectStartTimeList.push({'name': "expectedStartTime", 'value': dayjs().subtract(7, 'day'), 'operateType': ">="});
expectStartTimeList.push({'name': "expectedStartTime", 'value': dayjs().add(7, 'day'), 'operateType': "<"})
const [expectedStartTime, setExpectedStartTime] = React.useState<string>(JSON.stringify(expectStartTimeList))
const [taskTypeList,setTaskTypeList] = React.useState<string[]>(["0,1,2,3","4"])
const [refreshDataFlag, setRefreshDataFlag] = React.useState<boolean>(true)
const [expectedStartTime, setExpectedStartTime] = React.useState<string>(JSON.stringify(expectedStartTimeCookies ?? expectStartTimeList))
const [taskTypeList, setTaskTypeList] = React.useState<string[]>(taskTypeListCookies ?? ["0,1,2,3", "4"])
const [refreshDataFlag, setRefreshDataFlag] = React.useState<boolean>(refreshDataFlagCookies || true)
console.log('taskState,expectedStartTime,refreshDataFlag', taskState, expectedStartTime, refreshDataFlag)
// 查询参数获取 end
// 设置参数 start
const updateCookies = (date: {}) => {
try {
const platform = Cookies.get('platform-setting');
const currentSettings = platform ? JSON.parse(platform) : {};
const updatedSettings = {
...currentSettings,
...date
};
Cookies.set('platform-setting', JSON.stringify(updatedSettings), {
expires: 365, // 1年有效期
path: '/',
secure: process.env.NODE_ENV === 'production'
});
} catch (error) {
console.error('获取设置失败:', error);
}
}
// 设置参数 end
function refreshData() {
setRefreshDataFlag(!refreshDataFlag)
}
console.log('taskState,expectedStartTime,refreshDataFlag', taskState, expectedStartTime, refreshDataFlag)
return (
<ConfigProvider
locale={locale}
theme={{
components: {
Table: {
rowHoverBg: '#4096ff'
/* 这里是你的组件 token */
},
},
token: {
colorBgBase: backgroundColor,
colorPrimaryBg: backgroundColor,
controlItemBgHover: "#4096ff",
controlItemBgActiveHover: "#4096ff",
controlItemBgActive: "#4096ff"
}
}}
>
<LocalContext.Provider value={{
'taskState': taskState,
'expectedStartTime': expectedStartTime,
'refreshData': refreshDataFlag,
'taskTypeList': taskTypeList
}}
>
<TitleOperation
setTaskState={(taskState) => {
console.log({taskTypeList})
setTaskState(taskState);
updateCookies({taskState})
}}
setExpectedStartTime={(expectedStartTime) => {
console.log({taskTypeList})
setExpectedStartTime(expectedStartTime);
updateCookies({updateCookies});
}}
setTaskTypeList={(taskTypeList) => {
console.log({taskTypeList})
setTaskTypeList(taskTypeList);
updateCookies({taskTypeList});
}}
refreshData={refreshData}/>
<div style={{height: "calc(100vh - 42px)", overflow: "auto", background: backgroundColor}}>
{children}
</div>
</LocalContext.Provider>
</ConfigProvider>
);
}
export default function Layout({children}: { children: React.ReactNode }) {
return (
<Fragment>
<ConfigProvider
locale={locale}
theme={{
components: {
Table: {
rowHoverBg: '#4096ff'
/* 这里是你的组件 token */
},
},
token: {
controlItemBgHover:"#4096ff",
controlItemBgActiveHover:"#4096ff",
controlItemBgActive:"#4096ff"
}
}}
>
<LocalContext.Provider value={{
'taskState': taskState,
'expectedStartTime': expectedStartTime,
'refreshData': refreshDataFlag,
'taskTypeList':taskTypeList
}}
>
<TitleOperation setTaskState={setTaskState} setExpectedStartTime={setExpectedStartTime}
setTaskTypeList={setTaskTypeList}
refreshData={refreshData}/>
<div style={{height:"calc(100vh - 42px)",overflow:"auto"}}>
{children}
</div>
</LocalContext.Provider>
</ConfigProvider>
<BackgroundProvider>
<BodyWithBackground> {children}</BodyWithBackground>
</BackgroundProvider>
</Fragment>
);
}

View File

@ -2,9 +2,7 @@ import TreeTablePro from "@/ui/task/project/TreeTablePro";
const Page: React.FC = () => {
return (
<>
<TreeTablePro/>
</>
);
};

View File

@ -102,9 +102,9 @@ const ShareOption = (props: { taskId: string }) => {
{buttonIndex == 1 && <div className="displayFlexRow">
<div className="displayFlexColumn">
<div className="title"></div>
<Image width={300} src="/static/pc-Web.png"/>
<Image width={300} src="/static/pc-Web.jpg"/>
<Button
onClick={() => doDownload("/static/pc-Web.png", '微信小程序马上行计划管理.png')}></Button>
onClick={() => doDownload("/static/pc-Web.jpg", '微信小程序马上行计划管理.png')}></Button>
</div>
<div className="displayFlexColumn" id="myqrcode">
<div className="title">1</div>

View File

@ -12,6 +12,7 @@ import {
quitTeamAPI,
removeTeamAPI
} from "@/components/service/Share";
import Cookies from "js-cookie";
const TeamMember = (props: { taskId: string, closeOpen?: () => void, reloadData?: () => void }) => {
const [open, setOpen] = useState(false);
@ -54,7 +55,10 @@ const TeamMember = (props: { taskId: string, closeOpen?: () => void, reloadData?
// 处理管理员数据
if (adminRes.data?.status?.success) {
const message = localStorage.getItem('user-message');
let message = localStorage.getItem('user-message');
if (!message){
message = Cookies.get('user-message')||""
}
if (message) {
try {
const { username } = JSON.parse(message);

7
src/lib/PlatformSettingModel.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
export interface PlatformSettingModel {
colorBgBase?:string,
taskState?:string,
expectedStartTime?:string,
refreshData?:boolean,
taskTypeList?:string[]
}

View File

@ -0,0 +1,72 @@
// contexts/BackgroundContext.tsx
'use client';
import React, {createContext, useContext, useState, ReactNode} from 'react';
import Cookies from "js-cookie";
interface BackgroundContextType {
backgroundColor: string;
setBackgroundColor: (color: string) => void;
}
const BackgroundContext = createContext<BackgroundContextType | undefined>(undefined);
// 导出 hook
export const useBackground = () => {
const context = useContext(BackgroundContext);
if (context === undefined) {
throw new Error('useBackground must be used within a BackgroundProvider');
}
return context;
};
// 导出 Provider
interface BackgroundProviderProps {
children: ReactNode;
}
export const BackgroundProvider: React.FC<BackgroundProviderProps> = ({children}) => {
const [backgroundColor, setBackgroundColor] = useState<string>(() => {
try {
const platform = Cookies.get('platform-setting');
if (!platform) return '#fff';
const settings = JSON.parse(platform);
return settings?.colorBgBase || '#fff';
} catch (error) {
console.error('获取设置失败:', error);
return '#fff'; // 确保有默认值
}
});
const setBackgroundColorCookies = (color: string) => {
setBackgroundColor(color)
try {
const platform = Cookies.get('platform-setting');
const currentSettings = platform ? JSON.parse(platform) : {};
const updatedSettings = {
...currentSettings,
colorBgBase: color
};
Cookies.set('platform-setting', JSON.stringify(updatedSettings), {
expires: 365, // 1年有效期
path: '/',
secure: process.env.NODE_ENV === 'production'
});
} catch (error) {
console.error('获取设置失败:', error);
}
}
return (
<BackgroundContext.Provider value={{backgroundColor, setBackgroundColor: setBackgroundColorCookies}}>
{children}
</BackgroundContext.Provider>
);
};

View File

@ -1,6 +1,6 @@
import React from 'react';
import {PlatformSettingModel} from "@/lib/PlatformSettingModel";
const LocalContext = React.createContext({'taskState':'','expectedStartTime':'','refreshData':true,
'taskTypeList':[""]});
const LocalContext = React.createContext<PlatformSettingModel>({});
export default LocalContext;

View File

@ -10,6 +10,7 @@ import {LoginObject} from "@/lib/login/definitions";
import {useRouter} from 'next/navigation'
import {v4 as uuidv4} from 'uuid';
import {askLoginAPI, generateQrcodeAPI} from "@/lib/login/service";
import Cookies from "js-cookie";
// import Cookies from "js-cookie";
export default function XcxLoginPage() {
@ -81,6 +82,11 @@ export default function XcxLoginPage() {
localStorage.setItem('user-message', JSON.stringify(res.data.data[0],(key, value) => {
return key === 'password' ? undefined : value;
}))
Cookies.set('platform-security', res.data.data[0].token,{
expires: 365, // 1年有效期
path: '/',
secure: process.env.NODE_ENV === 'production'
})
// 删除名为 'platform-security' 的Cookie
// Cookies.remove('platform-security');
// 设置一个有效期为7天的Cookie
@ -148,7 +154,7 @@ export default function XcxLoginPage() {
{
qrCodeShow ?
<QRCode value={qrCodeValue} size={300} status={qrCodeStatus} onRefresh={generateQrcode}/> :
<Image width={300} src="/static/pc-Web.png"/>
<Image width={300} src="/static/pc-Web.jpg"/>
}
</div>
</LoginFormPage> : <Skeleton/>}

View File

@ -1,6 +1,17 @@
'use client'
import React, {Fragment, useContext, useEffect, useState} from "react";
import {Button, Checkbox, CheckboxOptionType, DatePicker, MenuProps, message, Popconfirm, Select, Space} from "antd";
import {
Button,
Checkbox,
CheckboxOptionType,
ColorPicker,
DatePicker,
MenuProps,
message,
Popconfirm,
Select,
Space
} from "antd";
import {usePathname, useRouter} from "next/navigation";
import {DetailModelForm} from "@/ui/task/project/DetailModelForm";
import {deleteTask, OPERATION_BUTTON_TYPE, taskStateList} from "@/lib/task/project/data";
@ -11,7 +22,12 @@ import dayjs, {Dayjs} from "dayjs";
import {useSearchParams} from "next/dist/client/components/navigation";
import Dropdown from "antd/es/dropdown/dropdown";
import {QuestionCircleOutlined} from "@ant-design/icons";
import { theme } from 'antd';
import type {Color} from "antd/es/color-picker/color";
import {useBackground} from "@/ui/BackgroundContext";
import Cookies from "js-cookie";
const { useToken } = theme;
interface TitleOperationProps {
setTaskState: (value: string) => void;
setTaskTypeList: (value: string[]) => void;
@ -28,16 +44,16 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
const {replace} = useRouter();
const searchParams = useSearchParams();
const pathname = usePathname();
const { token } = useToken();
const [pathParam, setPathParam] = useState<string | undefined>(searchParams.toString());
const [pathName, setPathName] = useState(pathname);
const { backgroundColor, setBackgroundColor } = useBackground();
console.log('usePathname()', pathname);
console.log('useSearchParams()', searchParams.toString(), searchParams.get('pName'), searchParams.get('pid'));
const data = useContext(LocalContext);
const {RangePicker} = DatePicker;
const expectStartTimeParseResult: RequestDateType[] = data.expectedStartTime.length > 0 ? JSON.parse(data.expectedStartTime) : [undefined, undefined]
const expectStartTimeParseResult: RequestDateType[] = data.expectedStartTime!.length > 0 ? JSON.parse(data.expectedStartTime!) : [undefined, undefined]
expectStartTimeParseResult.map(item => item && item.value ? dayjs(item.value.toString()) : undefined)
const defaultExpectStartTime: [start: Dayjs | null | undefined, end: Dayjs | null | undefined] = [
expectStartTimeParseResult[0] && expectStartTimeParseResult[0].value ? dayjs(expectStartTimeParseResult[0].value.toString()) : undefined,
@ -62,6 +78,9 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
useEffect(() => {
let userMessage = localStorage.getItem('user-message');
if (!userMessage){
userMessage = Cookies.get('user-message')||""
}
if (userMessage) {
let parse = JSON.parse(userMessage);
setNickName(parse.nickname)
@ -79,6 +98,16 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
}
};
const changeBackGroundColor = (value: Color, hex: string) =>{
console.log({value},{hex},value.toHexString())
// setBackgroundColor(typeof value === 'string' ? value : value!.toHexString())
setBackgroundColor(value.toHexString())
}
const clearBackGroundColor = ()=>{
setBackgroundColor("#fff")
}
const items: MenuProps['items'] = [
{
label: <Popconfirm
@ -94,6 +123,14 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
><a>退</a></Popconfirm>,
key: '1',
},
{
label: <ColorPicker trigger="hover" allowClear onClear={clearBackGroundColor}
value={backgroundColor}
onChange={changeBackGroundColor}>
<a></a>
</ColorPicker>,
key:3
},
];
const itemsPid: MenuProps['items'] = [
{
@ -110,14 +147,23 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
><a>退</a></Popconfirm>,
key: '1',
},
{
label: <ColorPicker trigger="hover"
allowClear onClear={clearBackGroundColor}
value={backgroundColor}
onChange={changeBackGroundColor}>
<a></a>
</ColorPicker>,
key:3
},
{
label: '从顶级任务查看',
key: '2',
},
];
return <div className={style.container}>
<Space style={{marginTop: 0, "height": "42px", "alignContent": "center"}}>
return <div className={style.container} style={{background: token.colorBgBase,}}>
<Space style={{marginTop: 0, height: "42px", alignContent: "center", }}>
<DetailModelForm haveButton={true} open={false} operationId={OPERATION_BUTTON_TYPE.ADD}
description='添加主线任务' reloadData={refreshData}/>
{
@ -163,7 +209,7 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
allowClear
style={{minWidth: '100px'}}
placeholder="任务状态"
defaultValue={data.taskState != '' && data.taskState.split(",").length > 0 ? data.taskState.split(",") : []}
defaultValue={data.taskState != '' && data.taskState!.split(",").length > 0 ? data.taskState!.split(",") : []}
onChange={(value) => {
console.log('onChange', {value})
if (value.length == 0) {

View File

@ -315,7 +315,7 @@ const CalShow: React.FC = () => {
if (existing !== undefined && filtered !== undefined) {
result = [...filtered, {...existing, state: "7"}];
}
let strings = state == "" ? [] : state.split(",");
let strings = !state||state == "" ? [] : state.split(",");
console.log('result', result, strings)
return result.filter((ev: TaskEvent) => !ev.state || strings.length == 0 || strings.indexOf(ev.state.toString()) >= 0);
})

View File

@ -2,7 +2,7 @@
import React, {CSSProperties} from "react";
import {Draggable, Droppable} from "react-beautiful-dnd";
import {ConfigProvider, Tooltip} from "antd";
import {ConfigProvider, theme, Tooltip} from "antd";
import {DataType} from "@/lib/definitions";
import './index.modules.css'
import dayjs from "dayjs";
@ -21,6 +21,8 @@ interface DroppableTableProps {
}
export const DroppableTable = React.memo((props: DroppableTableProps) => {
const { useToken } = theme;
const { token } = useToken();
const stateName = React.useMemo(() => {
switch (props.tableCode) {
case '0':
@ -38,7 +40,7 @@ export const DroppableTable = React.memo((props: DroppableTableProps) => {
const getItemStyle = React.useCallback((isDragging: boolean, draggableStyle: any): CSSProperties => ({
userSelect: "none",
background: isDragging ? "lightgreen" : "white",
background: isDragging ? "lightgreen" : token.colorBgBase,
position: 'relative',
zIndex: isDragging ? 2147483647 : 'auto',
...draggableStyle,
@ -47,13 +49,13 @@ export const DroppableTable = React.memo((props: DroppableTableProps) => {
verticalAlign: 'middle',
textAlign: 'center',
borderColor:taskPriorityList.find((item) => item.code === props.tableCode)?.color
}), []);
}), [token]);
const getListStyle = React.useCallback((isDraggingOver: boolean) => ({
background: isDraggingOver ? "lightblue" : "white",
background: isDraggingOver ? "lightblue" : token.colorBgBase,
height: 'calc((100vh - 42px)/2)',
width: '50vw'
}), []);
}), [token]);
const headerStyle = React.useMemo(() => ({
backgroundColor: taskPriorityList.find((item) => item.code === props.tableCode)?.color,

View File

@ -61,16 +61,16 @@ const TreeTable: React.FC<TableSearchType> = (props) => {
dataIndex: 'state',
width: '10%',
key: 'state',
filtered: checkLocal&&dataLocalContext.taskState.length > 0,
defaultFilteredValue: dataLocalContext.taskState.split(','),
filtered: checkLocal&&dataLocalContext.taskState!.length > 0,
defaultFilteredValue: dataLocalContext.taskState!.split(','),
onFilter: (text, record) => {
// console.log('&record.priority.toString()===props.priority',record.priority,text,props.priority)
// &record.priority.toString()===props.priority 不重要紧急 0 0
if (dataLocalContext.taskState.length === 0) {
if (dataLocalContext.taskState!.length === 0) {
return true;
}
var dataLocalContextTaskStateList = dataLocalContext.taskState.split(",");
console.log('dataLocalContextTaskStateList', dataLocalContext.taskState.length > 0, dataLocalContextTaskStateList);
var dataLocalContextTaskStateList = dataLocalContext.taskState!.split(",");
console.log('dataLocalContextTaskStateList', dataLocalContext.taskState!.length > 0, dataLocalContextTaskStateList);
return taskStateList.filter(taskState => dataLocalContextTaskStateList.includes(taskState.code))
.find(taskState => taskState.name === record.state) != undefined;
}
@ -100,14 +100,14 @@ const TreeTable: React.FC<TableSearchType> = (props) => {
dataIndex: 'expectedStartTime',
width: '10%',
key: 'expectedStartTime',
filtered: checkLocal&&dataLocalContext.expectedStartTime.length > 0,
filtered: checkLocal&&dataLocalContext.expectedStartTime!.length > 0,
// defaultFilteredValue: JSON.parse(dataLocalContext.expectedStartTime),
onFilter: (text, record) => {
console.log('dataLocalContext.expectedStartTime',dataLocalContext.expectedStartTime)
if (dataLocalContext.expectedStartTime.length === 0) {
if (dataLocalContext.expectedStartTime!.length === 0) {
return true;
}
const expectStartTimeParseResult:RequestDateType[] = JSON.parse(dataLocalContext.expectedStartTime);
const expectStartTimeParseResult:RequestDateType[] = JSON.parse(dataLocalContext.expectedStartTime!);
console.log('expectStartTimeParseResult',expectStartTimeParseResult)
if (expectStartTimeParseResult[0]!=undefined){
let le:boolean;
@ -155,10 +155,10 @@ const TreeTable: React.FC<TableSearchType> = (props) => {
resultDataType.action= <OperationButton itemId={resultDataType.id} itemName={resultDataType.name}
fId={resultDataType.fId} fName={resultDataType.fName}
pid={resultDataType.pid} pPid={resultDataType.pPid} refreshDate={props.refreshDate}/>
if (dataLocalContext.expectedStartTime.length === 0) {
if (dataLocalContext.expectedStartTime!.length === 0) {
return true;
}
const expectStartTimeParseResult:RequestDateType[] = JSON.parse(dataLocalContext.expectedStartTime);
const expectStartTimeParseResult:RequestDateType[] = JSON.parse(dataLocalContext.expectedStartTime!);
if (expectStartTimeParseResult[0]!=undefined){
let le:boolean;
if (expectStartTimeParseResult[0].operateType==='<='){

View File

@ -62,16 +62,16 @@ const TreeTable: React.FC<TableSearchType> = (props) => {
dataIndex: 'state',
width: '10%',
key: 'state',
filtered: checkLocal&&dataLocalContext.taskState.length > 0,
defaultFilteredValue: dataLocalContext.taskState.split(','),
filtered: checkLocal&&dataLocalContext.taskState!.length > 0,
defaultFilteredValue: dataLocalContext.taskState!.split(','),
onFilter: (text, record) => {
// console.log('&record.priority.toString()===props.priority',record.priority,text,props.priority)
// &record.priority.toString()===props.priority 不重要紧急 0 0
if (dataLocalContext.taskState.length === 0) {
if (dataLocalContext.taskState!.length === 0) {
return true;
}
var dataLocalContextTaskStateList = dataLocalContext.taskState.split(",");
console.log('dataLocalContextTaskStateList', dataLocalContext.taskState.length > 0, dataLocalContextTaskStateList);
var dataLocalContextTaskStateList = dataLocalContext.taskState!.split(",");
console.log('dataLocalContextTaskStateList', dataLocalContext.taskState!.length > 0, dataLocalContextTaskStateList);
return taskStateList.filter(taskState => dataLocalContextTaskStateList.includes(taskState.code))
.find(taskState => taskState.name === record.state) != undefined;
},
@ -101,14 +101,14 @@ const TreeTable: React.FC<TableSearchType> = (props) => {
dataIndex: 'expectedStartTime',
width: '13%',
key: 'expectedStartTime',
filtered: checkLocal&&dataLocalContext.expectedStartTime.length > 0,
filtered: checkLocal&&dataLocalContext.expectedStartTime!.length > 0,
// defaultFilteredValue: JSON.parse(dataLocalContext.expectedStartTime),
onFilter: (text, record) => {
console.log('dataLocalContext.expectedStartTime',dataLocalContext.expectedStartTime)
if (dataLocalContext.expectedStartTime.length === 0) {
if (dataLocalContext.expectedStartTime!.length === 0) {
return true;
}
const expectStartTimeParseResult:RequestDateType[] = JSON.parse(dataLocalContext.expectedStartTime);
const expectStartTimeParseResult:RequestDateType[] = JSON.parse(dataLocalContext.expectedStartTime!);
console.log('expectStartTimeParseResult',expectStartTimeParseResult)
if (expectStartTimeParseResult[0]!=undefined){
let le:boolean;
@ -169,10 +169,10 @@ const TreeTable: React.FC<TableSearchType> = (props) => {
resultDataType.action= <OperationButton itemId={resultDataType.id} itemName={resultDataType.name}
fId={resultDataType.fId} fName={resultDataType.fName}
priority={resultDataType.priority} pid={resultDataType.pid} pPid={resultDataType.pPid} refreshDate={props.refreshDate}/>
if (dataLocalContext.expectedStartTime.length === 0) {
if (dataLocalContext.expectedStartTime!.length === 0) {
return true;
}
const expectStartTimeParseResult:RequestDateType[] = JSON.parse(dataLocalContext.expectedStartTime);
const expectStartTimeParseResult:RequestDateType[] = JSON.parse(dataLocalContext.expectedStartTime!);
if (expectStartTimeParseResult[0]!=undefined){
let le:boolean;
if (expectStartTimeParseResult[0].operateType==='<='){

View File

@ -22,6 +22,7 @@ import {useSearchParams} from "next/navigation";
import {TaskWebSelectVO} from "@/lib/task/project/definitions";
import TaskNameAndIcon from "@/components/TaskNameAndIcon";
import {copyToClipboard} from "@/lib/copyToClipboard";
import LocalContext from "@/ui/LocalContent";
const TreeTablePro: React.FC = (props: { joinId?: string }) => {
// 刷新表格
@ -33,6 +34,7 @@ const TreeTablePro: React.FC = (props: { joinId?: string }) => {
// 页码信息
const [current, setCurrent] = React.useState(1);
const [pageSize, setPageSize] = React.useState(10);
const {taskState: state} = useContext(LocalContext);
// 获取路径参数pid
const pathPid = useSearchParams().get('pid');
const pid = pathPid ? pathPid : '0';
@ -111,9 +113,9 @@ const TreeTablePro: React.FC = (props: { joinId?: string }) => {
dataIndex: 'state',
valueType: 'select',
order: 3,
initialValue: ['8', '9'],
initialValue: state =="" ?undefined:state!.split(','),
fieldProps: {
defaultValue: ['8', '9'],
defaultValue: state =="" ?undefined:state!.split(','),
mode: "tags",
options: taskStateList.map(item => {
return {label: item.name, value: item.code}

View File

@ -1,6 +1,7 @@
import axios, {AxiosInterceptorOptions, CancelTokenSource} from "axios";
import {message} from "antd";
import {refreshTokenAPI} from "@/lib/login/service";
import Cookies from "js-cookie";
export const httpReq = axios.create({
@ -21,7 +22,10 @@ httpReq.defaults.headers.common['Accept'] = 'application/json';
httpReq.interceptors.request.use((config) => {
console.log("config.url", config.url)
// 从本地存储中获取 token
const token = localStorage.getItem('platform-security');
let token = localStorage.getItem('platform-security');
if (!token){
token=Cookies.get("platform-security")||""
}
if (token) {
config.headers.Authorization = `Bearer ${token}`;
if (config.url && config.url.indexOf("refreshToken") == -1 &&
@ -76,6 +80,11 @@ function reduceToken(token: string) {
refreshTokenAPI().then(res => {
if (res.data.status.success) {
localStorage.setItem('platform-security', res.data.data)
Cookies.set('platform-security', res.data.data,{
expires: 365, // 1年有效期
path: '/',
secure: process.env.NODE_ENV === 'production'
})
}
})
}

View File

@ -32,7 +32,8 @@
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
"docker/out/types/**/*.ts"
"docker/out/types/**/*.ts",
"docker/outd/types/**/*.ts"
],
"exclude": [
"node_modules"

View File

@ -1,6 +1,4 @@
# 可能用到的技术栈
## 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
## 富文本

View File

@ -0,0 +1,17 @@
## next
https://nextjs.org/docs/app/guides/static-exports
## ant定制主题
https://ant.design/docs/react/customize-theme-cn
https://ant.design/theme-editor-cn#Color
## react-big-calendar
演示
https://jquense.github.io/react-big-calendar/examples/index.html?path=/docs/about-big-calendar--page
github
https://github.com/jquense/react-big-calendar
## LunarCalendar
https://www.npmjs.com/package/lunar-calendar
https://github.com/zzyss86/LunarCalendar
## umi
https://umijs.org/docs/introduce/faq