feat:backup

This commit is contained in:
1708-huayu 2024-12-27 19:06:20 +08:00
parent 9e7996c617
commit c46fbd2646
21 changed files with 915 additions and 126 deletions

2
.gitignore vendored
View File

@ -10,7 +10,7 @@
# production
/build
.idea
# misc
.DS_Store
.env.local

View File

@ -1,7 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="c22c6a78-950d-4bff-ac7a-ed800fcbb7de" name="Changes" comment="" />
<list default="true" id="c22c6a78-950d-4bff-ac7a-ed800fcbb7de" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/src/components/DataPickerItem/index.jsx" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/components/DetailForm/index.css" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/components/DetailForm/index.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/components/DetailNavBar/index.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/components/ParentTask/index.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/pages/ToDoList/index.css" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/pages/ToDoList/index.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/utils/requestUtil.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/package-lock.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/App.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/App.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/App.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/App.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/Bottom/index.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/Bottom/index.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/Bottom/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/Bottom/index.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/Home/index.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/Home/index.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/Home/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/Home/index.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/Map/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/Map/index.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/WidthUseNavigate/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/WidthUseNavigate/index.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/utils/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/index.js" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
@ -13,18 +38,59 @@
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 8
}</component>
<component name="ProjectId" id="2KWNUOdtRQIUIJvVRsdpzzM23Bg" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"last_opened_file_path": "D:/workspace/hkzf-mobile"
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;master&quot;,
&quot;last_opened_file_path&quot;: &quot;D:/electron/assistant-todo-mobile&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;npm.start.executor&quot;: &quot;Run&quot;,
&quot;ts.external.directory.path&quot;: &quot;C:\\Program Files\\JetBrains\\WebStorm 2024.1.5\\plugins\\javascript-plugin\\jsLanguageServicesImpl\\external&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}
}]]></component>
}</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="D:\electron\assistant-todo-mobile\src\components\DataPickerItem" />
</key>
</component>
<component name="RunManager">
<configuration name="start" type="js.build_tools.npm" temporary="true" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="start" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="npm.start" />
</list>
</recent_temporary>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-js-predefined-1d06a55b98c1-0b3e54e931b4-JavaScript-WS-241.18034.50" />
</set>
</attachedChunks>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
@ -33,9 +99,14 @@
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1674086393783</updated>
<workItem from="1735199009773" duration="4532000" />
<workItem from="1735203621890" duration="33395000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>

133
package-lock.json generated
View File

@ -1,11 +1,11 @@
{
"name": "hkzf-mobile",
"name": "assistant-todo-mobile",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "hkzf-mobile",
"name": "assistant-todo-mobile",
"version": "0.1.0",
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
@ -13,8 +13,10 @@
"@testing-library/user-event": "^13.5.0",
"antd-mobile": "^5.27.0",
"axios": "^1.2.2",
"dayjs": "^1.11.13",
"node-gyp": "^9.3.1",
"react": "^18.2.0",
"react-beautiful-dnd": "^13.1.1",
"react-dom": "^18.2.0",
"react-router-dom": "^6.6.2",
"react-scripts": "5.0.1",
@ -3705,6 +3707,15 @@
"@types/node": "*"
}
},
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.6",
"resolved": "https://registry.npmmirror.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz",
"integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==",
"dependencies": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"node_modules/@types/html-minifier-terser": {
"version": "6.1.0",
"resolved": "https://registry.npmmirror.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@ -4034,6 +4045,17 @@
"@types/react": "*"
}
},
"node_modules/@types/react-redux": {
"version": "7.1.34",
"resolved": "https://registry.npmmirror.com/@types/react-redux/-/react-redux-7.1.34.tgz",
"integrity": "sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ==",
"dependencies": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0",
"redux": "^4.0.0"
}
},
"node_modules/@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmmirror.com/@types/resolve/-/resolve-1.17.1.tgz",
@ -6031,6 +6053,14 @@
"postcss": "^8.4"
}
},
"node_modules/css-box-model": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/css-box-model/-/css-box-model-1.2.1.tgz",
"integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
"dependencies": {
"tiny-invariant": "^1.0.6"
}
},
"node_modules/css-declaration-sorter": {
"version": "6.3.1",
"resolved": "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz",
@ -6392,9 +6422,9 @@
}
},
"node_modules/dayjs": {
"version": "1.11.7",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.7.tgz",
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
"version": "1.11.13",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
},
"node_modules/debug": {
"version": "4.3.4",
@ -8585,6 +8615,19 @@
"he": "bin/he"
}
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmmirror.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"dependencies": {
"react-is": "^16.7.0"
}
},
"node_modules/hoist-non-react-statics/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/hoopy": {
"version": "0.1.4",
"resolved": "https://registry.npmmirror.com/hoopy/-/hoopy-0.1.4.tgz",
@ -11663,6 +11706,11 @@
"node": ">= 4.0.0"
}
},
"node_modules/memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-5.2.1.tgz",
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
},
"node_modules/merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@ -13852,6 +13900,11 @@
"performance-now": "^2.1.0"
}
},
"node_modules/raf-schd": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/raf-schd/-/raf-schd-4.0.3.tgz",
"integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ=="
},
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz",
@ -13963,6 +14016,25 @@
"node": ">=14"
}
},
"node_modules/react-beautiful-dnd": {
"version": "13.1.1",
"resolved": "https://registry.npmmirror.com/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz",
"integrity": "sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==",
"deprecated": "react-beautiful-dnd is now deprecated. Context and options: https://github.com/atlassian/react-beautiful-dnd/issues/2672",
"dependencies": {
"@babel/runtime": "^7.9.2",
"css-box-model": "^1.2.0",
"memoize-one": "^5.1.1",
"raf-schd": "^4.0.2",
"react-redux": "^7.2.0",
"redux": "^4.0.4",
"use-memo-one": "^1.1.1"
},
"peerDependencies": {
"react": "^16.8.5 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.5 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-dev-utils": {
"version": "12.0.1",
"resolved": "https://registry.npmmirror.com/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
@ -14098,6 +14170,30 @@
"resolved": "https://registry.npmmirror.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
"node_modules/react-redux": {
"version": "7.2.9",
"resolved": "https://registry.npmmirror.com/react-redux/-/react-redux-7.2.9.tgz",
"integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==",
"dependencies": {
"@babel/runtime": "^7.15.4",
"@types/react-redux": "^7.1.20",
"hoist-non-react-statics": "^3.3.2",
"loose-envify": "^1.4.0",
"prop-types": "^15.7.2",
"react-is": "^17.0.2"
},
"peerDependencies": {
"react": "^16.8.3 || ^17 || ^18"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmmirror.com/react-refresh/-/react-refresh-0.11.0.tgz",
@ -14280,6 +14376,14 @@
"node": ">=8"
}
},
"node_modules/redux": {
"version": "4.2.1",
"resolved": "https://registry.npmmirror.com/redux/-/redux-4.2.1.tgz",
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
"dependencies": {
"@babel/runtime": "^7.9.2"
}
},
"node_modules/regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmmirror.com/regenerate/-/regenerate-1.4.2.tgz",
@ -15690,6 +15794,11 @@
"resolved": "https://registry.npmmirror.com/thunky/-/thunky-1.1.0.tgz",
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
},
"node_modules/tiny-invariant": {
"version": "1.3.3",
"resolved": "https://registry.npmmirror.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
"integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="
},
"node_modules/tmpl": {
"version": "1.0.5",
"resolved": "https://registry.npmmirror.com/tmpl/-/tmpl-1.0.5.tgz",
@ -15872,9 +15981,9 @@
}
},
"node_modules/typescript": {
"version": "4.9.4",
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.4.tgz",
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
"version": "4.9.5",
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"peer": true,
"bin": {
"tsc": "bin/tsc",
@ -16026,6 +16135,14 @@
"requires-port": "^1.0.0"
}
},
"node_modules/use-memo-one": {
"version": "1.1.3",
"resolved": "https://registry.npmmirror.com/use-memo-one/-/use-memo-one-1.1.3.tgz",
"integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",

View File

@ -1,5 +1,5 @@
{
"name": "hkzf-mobile",
"name": "assistant-todo-mobile",
"version": "0.1.0",
"private": true,
"dependencies": {
@ -8,8 +8,10 @@
"@testing-library/user-event": "^13.5.0",
"antd-mobile": "^5.27.0",
"axios": "^1.2.2",
"dayjs": "^1.11.13",
"node-gyp": "^9.3.1",
"react": "^18.2.0",
"react-beautiful-dnd": "^13.1.1",
"react-dom": "^18.2.0",
"react-router-dom": "^6.6.2",
"react-scripts": "5.0.1",

View File

@ -1,5 +1,7 @@
.App {
text-align: center;
display: flex;
flex-direction: column;
}
.App-logo {

View File

@ -1,46 +1,54 @@
import { BrowserRouter as Router, Route, Navigate, Routes } from 'react-router-dom';
import {BrowserRouter as Router, Route, Navigate, Routes} from 'react-router-dom';
import Home from './pages/Home';
import Map from './pages/Map';
import Index from './pages/Index'
import './pages/Bottom/index.css'
import CityList from './pages/CityList';
import { Todo, Message, PersonalCenter } from './pages/Bottom'
import {Todo, Message, PersonalCenter} from './pages/Bottom'
import ToDoList from "./pages/ToDoList";
import DetailForm from "./components/DetailForm";
import {NavBar} from "antd-mobile";
import DetailNavBar from "./components/DetailNavBar";
function App() {
return (
<Router>
<div className='app'>
{/* <div className='top'>
return (
<Router>
<div className='app'>
{/* <div className='top'>
<NavBar >配合路由使用</NavBar>
</div> */}
{/* <div className='body'> */}
<Routes >
{/* <Route path='/' element={<Navigate to="/home" />}>
{/* <div className='body'> */}
<Routes>
{/* <Route path='/' element={<Navigate to="/home" />}>
</Route> */}
<Route path='/' element={<Home />}>
<Route index path='/home' element={<Index />} />
<Route path='/home/todo' element={<Todo />}></Route>
<Route path='/home/message' element={<Message />}></Route>
<Route path='/home/me' element={<PersonalCenter />}></Route>
</Route>
<Route path='/' element={<Home/>}>
<Route index path='/home' element={<Index/>}/>
<Route path='/home/todo' element={<ToDoList/>}></Route>
<Route path='/home/message' element={<Message/>}></Route>
<Route path='/home/me' element={<PersonalCenter/>}></Route>
</Route>
<Route path='/detail' element={<DetailNavBar/>}>
<Route path='addTask' element={<DetailForm/>}></Route>
</Route>
{/* <Route path='/home' element={<Home />}>
{/* <Route path='/home' element={<Home />}>
<Route path='/home/todo' element={<Todo />}></Route>
<Route path='/home/message' element={<Message />}></Route>
<Route path='/home/me' element={<PersonalCenter />}></Route>
</Route> */}
{/* <Route path='/todo' element={<Todo />}></Route>
{/* <Route path='/todo' element={<Todo />}></Route>
<Route path='/message' element={<Message />}></Route>
<Route path='/me' element={<PersonalCenter />}></Route> */}
<Route path='/citylist' element={<CityList />}></Route>
<Route path='/map' element={<Map />}></Route>
</Routes>
{/* </div> */}
{/* <div>
<Route path='/citylist' element={<CityList/>}></Route>
<Route path='/map' element={<Map/>}></Route>
</Routes>
{/* </div> */}
{/* <div>
<Bottom />
</div> */}
</div>
</Router>
);
</div>
</Router>
);
}
export default App;

View File

@ -0,0 +1,79 @@
import {useCallback, useState} from "react";
import {
Form,
DatePicker,
} from 'antd-mobile'
import dayjs from 'dayjs'
import {CloseCircleFill} from 'antd-mobile-icons'
const DatePickerItem = (props) => {
const [pickerVisible, setPickerVisible] = useState(false)
const {fieldName, labelName} = props
const labelRenderer = useCallback((type, data) => {
switch (type) {
case 'year':
return data + '年'
case 'month':
return data + '月'
case 'day':
return data + '日'
case 'hour':
return data + '时'
case 'minute':
return data + '分'
case 'second':
return data + '秒'
default:
return data
}
}, [])
return (
<Form.Item
noStyle
shouldUpdate={(prevValues, curValues) =>
prevValues.fieldName !== curValues.fieldName
}
>
{({getFieldValue, setFieldsValue}) => (
<Form.Item
name={fieldName}
label={labelName}
trigger='onConfirm'
arrow={
getFieldValue(fieldName) ? (
<CloseCircleFill
style={{
color: 'var(--adm-color-light)',
fontSize: 14,
}}
onClick={e => {
e.stopPropagation()
setFieldsValue({fieldName: null})
}}
/>
) : (
true
)
}
onClick={() => {
setPickerVisible(true)
}}
>
<DatePicker
precision='minute'
visible={pickerVisible}
renderLabel={labelRenderer}
onClose={() => {
setPickerVisible(false)
}}
>
{value =>
value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '请选择日期'
}
</DatePicker>
</Form.Item>
)}
</Form.Item>
)
}
export default DatePickerItem;

View File

@ -0,0 +1,3 @@
.adm-tag {
font-size: var(--adm-font-size-9);
}

View File

@ -0,0 +1,75 @@
import React from 'react'
import {
Form,
Input,
Button,
Dialog,
TextArea,
Space,
Checkbox, Selector, Tag, Radio
} from 'antd-mobile'
import ParentTask from "../ParentTask";
import DatePickerItem from "../DataPickerItem"
import "./index.css"
export default () => {
const now = new Date()
const onFinish = (values) => {
Dialog.alert({
content: <pre>{JSON.stringify(values, null, 2)}</pre>,
})
}
return (
<>
<Form
layout='horizontal'
onFinish={onFinish}
footer={
<Button block type='submit' color='primary' size='large'>
提交
</Button>
}
>
<ParentTask/>
<Form.Item
name='name'
label='任务名称'
rules={[{required: true, message: '任务名称不能为空'}]}
>
<Input onChange={console.log} placeholder='任务名称'/>
</Form.Item>
<Form.Item name='address' label='任务描述' help='详情地址'>
<TextArea
placeholder='请输入地址'
maxLength={100}
rows={2}
showCount
/>
</Form.Item>
<Form.Item name='state' label='任务状态' required>
<Radio.Group>
<Space direction='vertical'>
<Radio value='1'><Tag color='danger'>未开始</Tag></Radio>
<Radio value='2'><Tag color='warning'>进行中</Tag></Radio>
<Radio value='3'><Tag color='success'>已完成</Tag></Radio>
<Radio value='4'><Tag>已关闭</Tag></Radio>
</Space>
</Radio.Group>
</Form.Item>
<Form.Item name='priority' label='任务优先级'>
<Radio.Group>
<Space direction='vertical'>
<Radio value='1'><Tag color='danger'>紧急重要</Tag></Radio>
<Radio value='2'><Tag color='warning'>不紧急重要</Tag></Radio>
<Radio value='3'><Tag>紧急不重要</Tag></Radio>
<Radio value='4'><Tag color='success'>不紧急不重要</Tag></Radio>
</Space>
</Radio.Group>
</Form.Item>
<DatePickerItem fieldName={"expectedStartTime"} labelName={"预计开始时间"}/>
<DatePickerItem fieldName={"expectedEndTime"} labelName={"预计结束时间"}/>
<DatePickerItem fieldName={"actualStartTime"} labelName={"实际开始时间"}/>
<DatePickerItem fieldName={"actualEndTime"} labelName={"实际结束时间"}/>
</Form>
</>
)
}

View File

@ -0,0 +1,21 @@
import React from "react";
import {Outlet,useNavigate} from "react-router-dom";
import {NavBar} from "antd-mobile";
const DetailNavBar = () => {
const navigate = useNavigate();
const handleClick =()=> {
console.log("click",navigate.length);
navigate(-1)
}
return (
<div className='detail'>
<NavBar back='返回' onBack={handleClick}>标题</NavBar><Outlet/>
</div>
)
}
export default DetailNavBar;

View File

@ -0,0 +1,214 @@
import {Cascader,Input, Toast} from "antd-mobile";
import React, {useState} from "react";
import {
Form,
} from 'antd-mobile'
const options = [
{
label: '浙江',
value: '浙江',
children: [
{
label: '杭州',
value: '杭州',
children: [
{
label: '西湖区',
value: '西湖区',
},
{
label: '上城区',
value: '上城区',
},
{
label: '余杭区',
value: '余杭区',
disabled: true,
},
],
},
{
label: '温州',
value: '温州',
children: [
{
label: '鹿城区',
value: '鹿城区',
},
{
label: '龙湾区',
value: '龙湾区',
disabled: true,
},
{
label: '瓯海区',
value: '瓯海区',
},
],
},
{
label: '宁波',
value: '宁波',
children: [
{
label: '海曙区',
value: '海曙区',
},
{
label: '江北区',
value: '江北区',
},
{
label: '镇海区',
value: '镇海区',
},
],
},
],
},
{
label: '安徽',
value: '安徽',
children: [
{
label: '合肥',
value: '合肥',
children: [
{
label: '包河区',
value: '包河区',
},
{
label: '蜀山区',
value: '蜀山区',
},
{
label: '瑶海区',
value: '瑶海区',
},
],
},
{
label: '芜湖',
value: '芜湖',
children: [
{
label: '镜湖区',
value: '镜湖区',
},
{
label: '弋江区',
value: '弋江区',
},
{
label: '湾沚区',
value: '湾沚区',
},
],
},
],
},
{
label: '江苏',
value: '江苏',
children: [
{
label: '南京',
value: '南京',
children: [
{
label: '玄武区',
value: '玄武区',
},
{
label: '秦淮区',
value: '秦淮区',
},
{
label: '建邺区',
value: '建邺区',
},
],
},
{
label: '苏州',
value: '苏州',
children: [
{
label: '虎丘区',
value: '虎丘区',
},
{
label: '吴中区',
value: '吴中区',
},
{
label: '相城区',
value: '相城区',
},
],
},
],
},
]
const ParentTask = ()=>{
const [parentValue, setParentValue] = useState("")
const [visible, setVisible] = useState(false)
return <Form.Item
name='pid'
label='主线任务'
onClick={() => {
setVisible(true)
}}
>
<Cascader
options={options}
visible={visible}
onClose={() => {
setVisible(false)
}}
value={parentValue}
onConfirm={setParentValue}
onSelect={(val, extend) => {
console.log('onSelect', val, extend.items)
}}
>
{items => {
if (items.every(item => item === null)) {
return <span style={{color:"#cccccc"}}>主线任务选线</span>
} else {
return items.map(item => item?.label ??
<span style={{color: "#cccccc"}}>主线任务选线</span>).join('-')
}
}}
</Cascader>
</Form.Item>
// const [parentValue, setParentValue] = useState("")
// return <Form.Item
// name='name'
// label='主线任务'
// onClick={async () => {
// const value = await Cascader.prompt({
// options: options,
// placeholder: '请选择',
// })
// Toast.show(
// value ? `你选择了 ${value.join(' - ')}` : '你没有进行选择'
// )
// if (value){
// setParentValue(value.join(' - '))
// }
// }}
// >
// <Input
// defaultValue={parentValue}
// value={parentValue}
// readOnly={true}
// placeholder='主线任务名称选填'>
// {parentValue}
// </Input>
// </Form.Item>
}
export default ParentTask;

View File

@ -21,6 +21,7 @@
.adm-tab-bar {
flex: 0;
background: white;
border-top: solid 1px var(--adm-color-border);
width:100%;
position: fixed;

View File

@ -1,87 +1,108 @@
import React ,{FC} from "react";
import { TabBar } from 'antd-mobile'
import React, {FC, Fragment} from "react";
import {TabBar, FloatingBubble, Toast} from 'antd-mobile'
import WidthUseNavigate from './../WidthUseNavigate/index'
import {
AppOutline,
MessageOutline,
UnorderedListOutline,
UserOutline,
AppOutline,
MessageOutline,
UnorderedListOutline,
UserOutline,
AddOutline,
} from 'antd-mobile-icons'
const tabs = [
{
key: '/home',
title: '首页',
icon: <AppOutline />,
badge: '1',
},
{
key: '/home/todo',
title: '待办',
icon: <UnorderedListOutline />,
badge: '2',
},
{
key: '/home/message',
title: '消息',
icon: <MessageOutline />,
badge: '3',
},
{
key: '/home/me',
title: '我的',
icon: <UserOutline />,
badge: '4',
},
]
import "./index.css"
import DetailForm from "../../components/DetailForm";
class BottomInner extends React.Component{
const tabs = [
{
key: '/home',
title: '树状任务',
icon: <AppOutline/>,
badge: '1',
},
{
key: '/home/todo',
title: '列表任务',
icon: <UnorderedListOutline/>,
badge: '2',
},
{
key: '/home/message',
title: '日历任务',
icon: <MessageOutline/>,
badge: '3',
},
{
key: '/home/me',
title: '我的',
icon: <UserOutline/>,
badge: '4',
},
]
class BottomInner extends React.Component {
state = {
// 默认选中的TabBar菜单项
selectedTab: this.props.useLocation
// 默认选中的TabBar菜单项
selectedTab: this.props.useLocation
}
// 组件接收到新的props此处实际上是路由信息就会触发该钩子函数
componentDidUpdate(prevProps) {
// prevProps 上一次的props此处也就是上一次的路由信息
// this.props 当前最新的props此处也就是最新的路由信息
// 注意:在该钩子函数中更新状态时,一定要在 条件判断 中进行,否则会造成递归更新的问题
if (prevProps.useLocation !== this.props.useLocation) {
// 此时,就说明路由发生切换了
this.setState({
selectedTab: this.props.useLocation
})
}
}
setRouteActive = (value) => {
this.props.to(value)
this.setState({
selectedTab: value
})
// prevProps 上一次的props此处也就是上一次的路由信息
// this.props 当前最新的props此处也就是最新的路由信息
// 注意:在该钩子函数中更新状态时,一定要在 条件判断 中进行,否则会造成递归更新的问题
if (prevProps.useLocation !== this.props.useLocation) {
// 此时,就说明路由发生切换了
this.setState({
selectedTab: this.props.useLocation
})
}
}
setRouteActive = (value) => {
this.props.to(value)
this.setState({
selectedTab: value
})
}
onClick = () => {
// Toast.show('你点击了气泡')
this.props.to("/detail/addTask")
}
render() {
return <TabBar activeKey={this.state.selectedTab} onChange={value => this.setRouteActive(value)}>
{tabs.map(item => (
<TabBar.Item key={item.key} icon={item.icon} title={item.title} badge= {item.badge}/>
))}
</TabBar>
return <Fragment>
<FloatingBubble
axis='x'
magnetic='x'
style={{
'--initial-position-bottom': '80px',
'--initial-position-right': '24px',
'--edge-distance': '24px',
}}
onClick={this.onClick}
>
<AddOutline fontSize={32}/>
</FloatingBubble>
<TabBar activeKey={this.state.selectedTab} onChange={value => this.setRouteActive(value)}>
{tabs.map(item => (
<TabBar.Item key={item.key} icon={item.icon} title={item.title} badge={item.badge}/>
))}
</TabBar>
</Fragment>
}
}
}
export function Todo() {
export function Todo() {
return <div>待办</div>
}
}
export function Message() {
export function Message() {
return <div>消息</div>
}
}
export function PersonalCenter() {
return <div>我的</div>
}
export function PersonalCenter() {
return <div>pc端可访问:http://www.hauruyu.com</div>
}
// 使用高阶组件包裹当前类组件
const Bottom = WidthUseNavigate(BottomInner);

View File

@ -6,19 +6,22 @@
user-select: none;
align-items: top;
} */
.context-swapper{
.context-swapper {
height: 212px;
position: relative;
}
.search-box{
.search-box {
position: absolute;
top: 25px;
width: 100%;
padding: 0,10px;
padding: 0, 10px;
}
.adm-grid-item {
text-align: center;
}
.context h2 {
margin: 0;
}
@ -26,3 +29,9 @@
.context {
padding-bottom: 50px;
}
.adm-search-bar{
height: 40px;
}
.adm-search-bar-input-box {
height: 40px;
}

View File

@ -1,12 +1,22 @@
import React from 'react'
import Bottom from './../Bottom/index'
import Bottom from './../Bottom/index'
import './index.css'
import { Outlet } from 'react-router-dom'
import WidthUseNavigate from '../WidthUseNavigate'
import {Outlet} from 'react-router-dom'
import {SearchBar} from "antd-mobile";
export default class Home extends React.Component {
render() {
return (
<div className='body'><Outlet /><Bottom /></div>
<div className='body'>
<div style={{"position": "fixed","top":"0","left":"0","width":"100%","zIndex":100}}>
<SearchBar placeholder='请输入内容'/>
</div>
<div style={{marginTop:"40px",width:"100%"}}>
<Outlet/>
</div>
<Bottom/>
</div>
)
}
}

View File

@ -30,10 +30,10 @@ export default class Map extends React.Component {
label.id=value
label.addEventListener('click',()=>{
console.log(value)
// 放大地图
this.map.centerAndZoom(new window.BMapGL.Point(longitude,latitude),nextZoom)
// 清除当前覆盖物信息
this.map.clearOverlays()
// // 放大地图
// this.map.centerAndZoom(new window.BMapGL.Point(longitude,latitude),nextZoom)
// // 清除当前覆盖物信息
// this.map.clearOverlays()
})
}
createRect(element){

View File

@ -0,0 +1,3 @@
.adm-list-default{
width:100%;
}

140
src/pages/ToDoList/index.js Normal file
View File

@ -0,0 +1,140 @@
import {Dialog,Image, List, SwipeAction} from 'antd-mobile'
import React, {useEffect, useRef, useState} from 'react'
import {
DragDropContext,
Draggable,
Droppable,
// DropResult,
} from 'react-beautiful-dnd'
import {getTaskList} from "../../utils";
import "./index.css"
const reorder = (
list,
startIndex,
endIndex
) => {
const result = Array.from(list)
const [removed] = result.splice(startIndex, 1)
result.splice(endIndex, 0, removed)
return result
}
const ToDoList = () => {
const [taskList, setTaskList] = useState([])
useEffect(() => {
getTaskList().then(result => {
console.log("getTaskList()", result)
setTaskList(result.data.data.content)
})
}, [])
const onDragEnd = (result) => {
if (!result.destination) return
const newList = reorder(taskList, result.source.index, result.destination.index)
setTaskList([...newList])
}
const ref = useRef(null)
return (
<List
// header='任务清单'
>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId='droppable'>
{droppableProvided => (
<div ref={droppableProvided.innerRef}>
{taskList.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={{
...provided.draggableProps.style,
opacity: snapshot.isDragging ? 0.8 : 1,
}}
>
<SwipeAction
ref={ref}
closeOnAction={false}
closeOnTouchOutside={false}
rightActions={[
{
key: 'delete',
text: '删除',
color: 'danger',
onClick: async () => {
await Dialog.confirm({
content: '确定要关闭吗?',
})
ref.current?.close()
},
},
{
key: 'close',
text: '关闭',
color: 'warning',
onClick: async () => {
await Dialog.confirm({
content: '确定要关闭吗?',
})
ref.current?.close()
},
},
{
key: 'update',
text: '修改',
color: 'primary',
onClick: async () => {
await Dialog.confirm({
content: '确定要修改吗?',
})
ref.current?.close()
},
},
{
key: 'complete',
text: '完成',
color: 'success',
onClick: async () => {
await Dialog.confirm({
content: '确定要完成吗?',
})
ref.current?.close()
},
},
]}
>
<List.Item
key={item.id}
// prefix={
// <Image
// src={item.avatar}
// style={{ borderRadius: 20 }}
// fit='cover'
// width={40}
// height={40}
// />
// }
description={item.description}
onClick={
()=>{console.log("dianji")}
}
>
{item.name}
</List.Item>
</SwipeAction>
</div>
)}
</Draggable>
))}
{droppableProvided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
</List>
)
}
export default ToDoList;

View File

@ -2,19 +2,19 @@ import { useNavigate } from 'react-router-dom'
// 高阶组件包装useNavigate()功能
// 原因类组件中无法使用useNavigate(),会报错
// React Hook "useNavigate" cannot be called in a class component.
function WidthUseNavigate(WrapCompontent) {
function WidthUseNavigate(WrapComponent) {
// 设置别名
WrapCompontent.displayName = `widthUseNavigate${getDisplayName(WrapCompontent)}`
return function NavigateCompont() {
WrapComponent.displayName = `widthUseNavigate${getDisplayName(WrapComponent)}`
return function NavigateComponent() {
const navigate = useNavigate()
// 给传入的组件新增一个to方法传给原始组件的props在原始组件中通过this.props.to(参数)使用
return <WrapCompontent to={navigate}></WrapCompontent>
return <WrapComponent to={navigate}></WrapComponent>
}
}
// 别名
function getDisplayName(WrapCompontent) {
return WrapCompontent.displayname || WrapCompontent.name || 'Component'
function getDisplayName(WrapComponent) {
return WrapComponent.displayname || WrapComponent.name || 'Component'
}
export default WidthUseNavigate

View File

@ -1,4 +1,5 @@
import axios from "axios"
import {requestUtil} from "./requestUtil";
export const getCurrentCity=()=>{
const localCity = JSON.parse(localStorage.getItem('local_city'))
if(!localCity){
@ -22,3 +23,8 @@ export const getCurrentCity=()=>{
// })
return Promise.resolve(localCity)
}
export const getTaskList= () => {
return requestUtil.get('/todo-server/search/task_message_tree?search=%7B%22pageSize%22%3A20%2C%22pageNumber%22%3A1%2C%22data%22%3A%5B%7B%22name%22%3A%22tree%22%2C%22value%22%3A%22TRUE%22%2C%22operateType%22%3A%22TREE-FILTER%22%7D%2C%7B%22name%22%3A%22state%22%2C%22value%22%3A%228%2C9%22%2C%22operateType%22%3A%22IN%22%7D%5D%7D');
}

7
src/utils/requestUtil.js Normal file
View File

@ -0,0 +1,7 @@
import axios from "axios";
export const requestUtil = axios.create({
baseURL: 'http://www.huaruyu.com/',
timeout: 1000,
headers: {'Authorization': 'Bearer eyJraWQiOiIwNzdlYzBjMi1iZDQwLTRjODktOGE5OC05OTI1YmZkNzJlZjAiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJzaGl4aWFvaHVhIiwic3ViIjoie1wiaWRcIjpcIjM2OTg0Nzc3MTAxODAzNTIwXCIsXCJuaWNrbmFtZVwiOlwi5biI5pmT5Y2OXCIsXCJ1c2VybmFtZVwiOlwic2hpeGlhb2h1YVwifSJ9.WiNGZYbWlIdu3WL7ujtlKsGa42IblW93SG-Mf4jDOuECWrDHFNA0gJBKUQkWKQfpWWRaIzcBmUC78WkIM5yFIHiB2_wBXyywHyjVCWBYC3sTJghtWogLB9ceR69eNfCZanm_ZlrcIEWJ9rqCk-hmMEuWwIk9xJ-M4hFGHkoAr_ftYJiBkGqgKpXOeVE_Tish6SqYZtN-V6Dcnyny3k7T6lG1jzXGyhokEzg_0B5hYpRvvA-GJx14Q1RO6Sv3vgMFOX63bhKX3L7KCSwLO2NJ5GkFHXqcDCf_-pnbiHUtP1JrchzXGWpI_Blrlf_65CdrMWuyVSGtDJ6_Z-Ef4Uq_tQ'}
});