Refactor App component to use React Navigation; update dependencies for navigation and gesture handling

This commit is contained in:
xudan 2025-07-21 15:10:39 +08:00
parent efa0d27041
commit ea68167afb
18 changed files with 1045 additions and 30 deletions

View File

@ -0,0 +1,11 @@
{
"permissions": {
"allow": [
"Bash(npm install:*)",
"Bash(mkdir -p:*)",
"Bash(npm install:*)",
"Bash(*:*)"
],
"deny": []
}
}

33
App.tsx
View File

@ -1,28 +1,15 @@
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
*/
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import AppNavigator from './src/navigation/AppNavigator';
import { NewAppScreen } from '@react-native/new-app-screen';
import { StatusBar, StyleSheet, useColorScheme, View } from 'react-native';
function App() {
const isDarkMode = useColorScheme() === 'dark';
import { PaperProvider } from 'react-native-paper';
export default function App() {
return (
<View style={styles.container}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<NewAppScreen templateFileName="App.tsx" />
</View>
<PaperProvider>
<NavigationContainer>
<AppNavigator />
</NavigationContainer>
</PaperProvider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default App;

View File

@ -107,6 +107,8 @@ android {
}
}
apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")
dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")

View File

@ -1,3 +1,5 @@
import 'react-native-get-random-values';
import 'react-native-gesture-handler';
/**
* @format
*/

513
package-lock.json generated
View File

@ -9,8 +9,18 @@
"version": "0.0.1",
"dependencies": {
"@react-native/new-app-screen": "0.80.1",
"@react-navigation/bottom-tabs": "^7.4.2",
"@react-navigation/native": "^7.1.14",
"@react-navigation/stack": "^7.4.2",
"react": "19.1.0",
"react-native": "0.80.1"
"react-native": "0.80.1",
"react-native-gesture-handler": "^2.27.1",
"react-native-get-random-values": "^1.11.0",
"react-native-paper": "^5.14.5",
"react-native-safe-area-context": "^5.5.2",
"react-native-screens": "^4.13.1",
"react-native-vector-icons": "^10.2.0",
"uuid": "^11.1.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
@ -26,6 +36,7 @@
"@types/jest": "^29.5.13",
"@types/react": "^19.1.0",
"@types/react-test-renderer": "^19.1.0",
"@types/uuid": "^10.0.0",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
@ -1995,6 +2006,40 @@
"dev": true,
"license": "MIT"
},
"node_modules/@callstack/react-theme-provider": {
"version": "3.0.9",
"resolved": "https://registry.npmmirror.com/@callstack/react-theme-provider/-/react-theme-provider-3.0.9.tgz",
"integrity": "sha512-tTQ0uDSCL0ypeMa8T/E9wAZRGKWj8kXP7+6RYgPTfOPs9N07C9xM8P02GJ3feETap4Ux5S69D9nteq9mEj86NA==",
"license": "MIT",
"dependencies": {
"deepmerge": "^3.2.0",
"hoist-non-react-statics": "^3.3.0"
},
"peerDependencies": {
"react": ">=16.3.0"
}
},
"node_modules/@callstack/react-theme-provider/node_modules/deepmerge": {
"version": "3.3.0",
"resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-3.3.0.tgz",
"integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@egjs/hammerjs": {
"version": "2.0.17",
"resolved": "https://registry.npmmirror.com/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
"integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
"license": "MIT",
"dependencies": {
"@types/hammerjs": "^2.0.36"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.7.0",
"resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
@ -3297,6 +3342,114 @@
}
}
},
"node_modules/@react-navigation/bottom-tabs": {
"version": "7.4.2",
"resolved": "https://registry.npmmirror.com/@react-navigation/bottom-tabs/-/bottom-tabs-7.4.2.tgz",
"integrity": "sha512-jyBux5l3qqEucY5M/ZWxVvfA8TQu7DVl2gK+xB6iKqRUfLf7dSumyVxc7HemDwGFoz3Ug8dVZFvSMEs+mfrieQ==",
"license": "MIT",
"dependencies": {
"@react-navigation/elements": "^2.5.2",
"color": "^4.2.3"
},
"peerDependencies": {
"@react-navigation/native": "^7.1.14",
"react": ">= 18.2.0",
"react-native": "*",
"react-native-safe-area-context": ">= 4.0.0",
"react-native-screens": ">= 4.0.0"
}
},
"node_modules/@react-navigation/core": {
"version": "7.12.1",
"resolved": "https://registry.npmmirror.com/@react-navigation/core/-/core-7.12.1.tgz",
"integrity": "sha512-ir6s25CDkReufi0vQhSIAe+AAHHJN9zTgGlS6iDS1yqbwgl2MiBAZzpaOL1T5llYujie2jF/bODeLz2j4k80zw==",
"license": "MIT",
"dependencies": {
"@react-navigation/routers": "^7.4.1",
"escape-string-regexp": "^4.0.0",
"nanoid": "^3.3.11",
"query-string": "^7.1.3",
"react-is": "^19.1.0",
"use-latest-callback": "^0.2.4",
"use-sync-external-store": "^1.5.0"
},
"peerDependencies": {
"react": ">= 18.2.0"
}
},
"node_modules/@react-navigation/core/node_modules/react-is": {
"version": "19.1.0",
"resolved": "https://registry.npmmirror.com/react-is/-/react-is-19.1.0.tgz",
"integrity": "sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==",
"license": "MIT"
},
"node_modules/@react-navigation/elements": {
"version": "2.5.2",
"resolved": "https://registry.npmmirror.com/@react-navigation/elements/-/elements-2.5.2.tgz",
"integrity": "sha512-aGC3ukF5+lXuiF5bK7bJyRuWCE+Tk4MZ3GoQpAb7u7+m0KmsquliDhj4UCWEUU5kUoCeoRAUvv+1lKcYKf+WTQ==",
"license": "MIT",
"dependencies": {
"color": "^4.2.3",
"use-latest-callback": "^0.2.4",
"use-sync-external-store": "^1.5.0"
},
"peerDependencies": {
"@react-native-masked-view/masked-view": ">= 0.2.0",
"@react-navigation/native": "^7.1.14",
"react": ">= 18.2.0",
"react-native": "*",
"react-native-safe-area-context": ">= 4.0.0"
},
"peerDependenciesMeta": {
"@react-native-masked-view/masked-view": {
"optional": true
}
}
},
"node_modules/@react-navigation/native": {
"version": "7.1.14",
"resolved": "https://registry.npmmirror.com/@react-navigation/native/-/native-7.1.14.tgz",
"integrity": "sha512-X233/CNx41FpshlWe4uEAUN8CNem3ju4t5pnVKcdhDR0cTQT1rK6P0ZwjSylD9zXdnHvJttFjBhKTot6TcvSqA==",
"license": "MIT",
"dependencies": {
"@react-navigation/core": "^7.12.1",
"escape-string-regexp": "^4.0.0",
"fast-deep-equal": "^3.1.3",
"nanoid": "^3.3.11",
"use-latest-callback": "^0.2.4"
},
"peerDependencies": {
"react": ">= 18.2.0",
"react-native": "*"
}
},
"node_modules/@react-navigation/routers": {
"version": "7.4.1",
"resolved": "https://registry.npmmirror.com/@react-navigation/routers/-/routers-7.4.1.tgz",
"integrity": "sha512-42mZrMzQ0LfKxUb5OHIurYrPYyRsXFLolucILrvm21f0O40Sw0Ufh1bnn/jRqnxZZu7wvpUGIGYM8nS9zVE1Aw==",
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.11"
}
},
"node_modules/@react-navigation/stack": {
"version": "7.4.2",
"resolved": "https://registry.npmmirror.com/@react-navigation/stack/-/stack-7.4.2.tgz",
"integrity": "sha512-QlqBxKBfKVx/XRH04pRRGQ92tO1fV0RL7YEw5G4pew6CNY26102dVQl5A39ZztvlvEDQbCQkatyDS7i2xR1QiA==",
"license": "MIT",
"dependencies": {
"@react-navigation/elements": "^2.5.2",
"color": "^4.2.3"
},
"peerDependencies": {
"@react-navigation/native": "^7.1.14",
"react": ">= 18.2.0",
"react-native": "*",
"react-native-gesture-handler": ">= 2.0.0",
"react-native-safe-area-context": ">= 4.0.0",
"react-native-screens": ">= 4.0.0"
}
},
"node_modules/@sideway/address": {
"version": "4.1.5",
"resolved": "https://registry.npmmirror.com/@sideway/address/-/address-4.1.5.tgz",
@ -3395,6 +3548,12 @@
"@types/node": "*"
}
},
"node_modules/@types/hammerjs": {
"version": "2.0.46",
"resolved": "https://registry.npmmirror.com/@types/hammerjs/-/hammerjs-2.0.46.tgz",
"integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==",
"license": "MIT"
},
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.6",
"resolved": "https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
@ -3514,6 +3673,13 @@
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
"license": "MIT"
},
"node_modules/@types/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmmirror.com/@types/uuid/-/uuid-10.0.0.tgz",
"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/yargs": {
"version": "17.0.33",
"resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-17.0.33.tgz",
@ -4810,6 +4976,19 @@
"dev": true,
"license": "MIT"
},
"node_modules/color": {
"version": "4.2.3",
"resolved": "https://registry.npmmirror.com/color/-/color-4.2.3.tgz",
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1",
"color-string": "^1.9.0"
},
"engines": {
"node": ">=12.5.0"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
@ -4828,6 +5007,16 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/color-string": {
"version": "1.9.1",
"resolved": "https://registry.npmmirror.com/color-string/-/color-string-1.9.1.tgz",
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
"license": "MIT",
"dependencies": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
}
},
"node_modules/colorette": {
"version": "1.4.0",
"resolved": "https://registry.npmmirror.com/colorette/-/colorette-1.4.0.tgz",
@ -5126,6 +5315,15 @@
"node": ">=0.10.0"
}
},
"node_modules/decode-uri-component": {
"version": "0.2.2",
"resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
"integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
"license": "MIT",
"engines": {
"node": ">=0.10"
}
},
"node_modules/dedent": {
"version": "1.6.0",
"resolved": "https://registry.npmmirror.com/dedent/-/dedent-1.6.0.tgz",
@ -6234,11 +6432,16 @@
"integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==",
"license": "Apache-2.0"
},
"node_modules/fast-base64-decode": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz",
"integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==",
"license": "MIT"
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-glob": {
@ -6347,6 +6550,15 @@
"node": ">=8"
}
},
"node_modules/filter-obj": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/filter-obj/-/filter-obj-1.1.0.tgz",
"integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.1.2.tgz",
@ -6879,6 +7091,21 @@
"hermes-estree": "0.28.1"
}
},
"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==",
"license": "BSD-3-Clause",
"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==",
"license": "MIT"
},
"node_modules/html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz",
@ -9629,6 +9856,24 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz",
@ -9726,7 +9971,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@ -10279,7 +10523,6 @@
"version": "15.8.1",
"resolved": "https://registry.npmmirror.com/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.4.0",
@ -10291,7 +10534,6 @@
"version": "16.13.1",
"resolved": "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true,
"license": "MIT"
},
"node_modules/punycode": {
@ -10337,6 +10579,24 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/query-string": {
"version": "7.1.3",
"resolved": "https://registry.npmmirror.com/query-string/-/query-string-7.1.3.tgz",
"integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==",
"license": "MIT",
"dependencies": {
"decode-uri-component": "^0.2.2",
"filter-obj": "^1.1.0",
"split-on-first": "^1.0.0",
"strict-uri-encode": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/queue": {
"version": "6.0.2",
"resolved": "https://registry.npmmirror.com/queue/-/queue-6.0.2.tgz",
@ -10432,6 +10692,18 @@
}
}
},
"node_modules/react-freeze": {
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/react-freeze/-/react-freeze-1.0.4.tgz",
"integrity": "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"peerDependencies": {
"react": ">=17.0.0"
}
},
"node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmmirror.com/react-is/-/react-is-17.0.2.tgz",
@ -10497,6 +10769,167 @@
}
}
},
"node_modules/react-native-gesture-handler": {
"version": "2.27.1",
"resolved": "https://registry.npmmirror.com/react-native-gesture-handler/-/react-native-gesture-handler-2.27.1.tgz",
"integrity": "sha512-57TUWerhdz589OcDD21e/YlL923Ma4OIpyWsP0hy7gItBCPm5d7qIUW7Yo/cS2wo1qDdOhJaNlvlBD1lDou1fA==",
"license": "MIT",
"dependencies": {
"@egjs/hammerjs": "^2.0.17",
"hoist-non-react-statics": "^3.3.0",
"invariant": "^2.2.4"
},
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-get-random-values": {
"version": "1.11.0",
"resolved": "https://registry.npmmirror.com/react-native-get-random-values/-/react-native-get-random-values-1.11.0.tgz",
"integrity": "sha512-4BTbDbRmS7iPdhYLRcz3PGFIpFJBwNZg9g42iwa2P6FOv9vZj/xJc678RZXnLNZzd0qd7Q3CCF6Yd+CU2eoXKQ==",
"license": "MIT",
"dependencies": {
"fast-base64-decode": "^1.0.0"
},
"peerDependencies": {
"react-native": ">=0.56"
}
},
"node_modules/react-native-is-edge-to-edge": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz",
"integrity": "sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q==",
"license": "MIT",
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-paper": {
"version": "5.14.5",
"resolved": "https://registry.npmmirror.com/react-native-paper/-/react-native-paper-5.14.5.tgz",
"integrity": "sha512-eaIH5bUQjJ/mYm4AkI6caaiyc7BcHDwX6CqNDi6RIxfxfWxROsHpll1oBuwn/cFvknvA8uEAkqLk/vzVihI3AQ==",
"license": "MIT",
"workspaces": [
"example",
"docs"
],
"dependencies": {
"@callstack/react-theme-provider": "^3.0.9",
"color": "^3.1.2",
"use-latest-callback": "^0.2.3"
},
"peerDependencies": {
"react": "*",
"react-native": "*",
"react-native-safe-area-context": "*"
}
},
"node_modules/react-native-paper/node_modules/color": {
"version": "3.2.1",
"resolved": "https://registry.npmmirror.com/color/-/color-3.2.1.tgz",
"integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
"license": "MIT",
"dependencies": {
"color-convert": "^1.9.3",
"color-string": "^1.6.0"
}
},
"node_modules/react-native-paper/node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"license": "MIT",
"dependencies": {
"color-name": "1.1.3"
}
},
"node_modules/react-native-paper/node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"license": "MIT"
},
"node_modules/react-native-safe-area-context": {
"version": "5.5.2",
"resolved": "https://registry.npmmirror.com/react-native-safe-area-context/-/react-native-safe-area-context-5.5.2.tgz",
"integrity": "sha512-t4YVbHa9uAGf+pHMabGrb0uHrD5ogAusSu842oikJ3YKXcYp6iB4PTGl0EZNkUIR3pCnw/CXKn42OCfhsS0JIw==",
"license": "MIT",
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-screens": {
"version": "4.13.1",
"resolved": "https://registry.npmmirror.com/react-native-screens/-/react-native-screens-4.13.1.tgz",
"integrity": "sha512-EESsMAtyzYcL3gpAI2NKKiIo+Ew0fnX4P4b3Zy/+MTc6SJIo3foJbZwdIWd/SUBswOf7IYCvWBppg+D8tbwnsw==",
"license": "MIT",
"dependencies": {
"react-freeze": "^1.0.0",
"react-native-is-edge-to-edge": "^1.2.1",
"warn-once": "^0.1.0"
},
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-vector-icons": {
"version": "10.2.0",
"resolved": "https://registry.npmmirror.com/react-native-vector-icons/-/react-native-vector-icons-10.2.0.tgz",
"integrity": "sha512-n5HGcxUuVaTf9QJPs/W22xQpC2Z9u0nb0KgLPnVltP8vdUvOp6+R26gF55kilP/fV4eL4vsAHUqUjewppJMBOQ==",
"license": "MIT",
"dependencies": {
"prop-types": "^15.7.2",
"yargs": "^16.1.1"
},
"bin": {
"fa-upgrade.sh": "bin/fa-upgrade.sh",
"fa5-upgrade": "bin/fa5-upgrade.sh",
"fa6-upgrade": "bin/fa6-upgrade.sh",
"generate-icon": "bin/generate-icon.js"
}
},
"node_modules/react-native-vector-icons/node_modules/cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"license": "ISC",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^7.0.0"
}
},
"node_modules/react-native-vector-icons/node_modules/yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmmirror.com/yargs/-/yargs-16.2.0.tgz",
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"license": "MIT",
"dependencies": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.0",
"y18n": "^5.0.5",
"yargs-parser": "^20.2.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/react-native-vector-icons/node_modules/yargs-parser": {
"version": "20.2.9",
"resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz",
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
"license": "ISC",
"engines": {
"node": ">=10"
}
},
"node_modules/react-native/node_modules/ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz",
@ -11231,6 +11664,21 @@
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"license": "ISC"
},
"node_modules/simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmmirror.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
"license": "MIT",
"dependencies": {
"is-arrayish": "^0.3.1"
}
},
"node_modules/simple-swizzle/node_modules/is-arrayish": {
"version": "0.3.2",
"resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.3.2.tgz",
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
"license": "MIT"
},
"node_modules/sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmmirror.com/sisteransi/-/sisteransi-1.0.5.tgz",
@ -11312,6 +11760,15 @@
"source-map": "^0.6.0"
}
},
"node_modules/split-on-first": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/split-on-first/-/split-on-first-1.1.0.tgz",
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz",
@ -11389,6 +11846,15 @@
"node": ">= 0.4"
}
},
"node_modules/strict-uri-encode": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
"integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==",
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz",
@ -12039,6 +12505,24 @@
"punycode": "^2.1.0"
}
},
"node_modules/use-latest-callback": {
"version": "0.2.4",
"resolved": "https://registry.npmmirror.com/use-latest-callback/-/use-latest-callback-0.2.4.tgz",
"integrity": "sha512-LS2s2n1usUUnDq4oVh1ca6JFX9uSqUncTfAm44WMg0v6TxL7POUTk1B044NH8TeLkFbNajIsgDHcgNpNzZucdg==",
"license": "MIT",
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/use-sync-external-store": {
"version": "1.5.0",
"resolved": "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
"integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
"license": "MIT",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
@ -12055,6 +12539,19 @@
"node": ">= 0.4.0"
}
},
"node_modules/uuid": {
"version": "11.1.0",
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-11.1.0.tgz",
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist/esm/bin/uuid"
}
},
"node_modules/v8-to-istanbul": {
"version": "9.3.0",
"resolved": "https://registry.npmmirror.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
@ -12095,6 +12592,12 @@
"makeerror": "1.0.12"
}
},
"node_modules/warn-once": {
"version": "0.1.1",
"resolved": "https://registry.npmmirror.com/warn-once/-/warn-once-0.1.1.tgz",
"integrity": "sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==",
"license": "MIT"
},
"node_modules/wcwidth": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz",

View File

@ -10,9 +10,19 @@
"test": "jest"
},
"dependencies": {
"@react-native/new-app-screen": "0.80.1",
"@react-navigation/bottom-tabs": "^7.4.2",
"@react-navigation/native": "^7.1.14",
"@react-navigation/stack": "^7.4.2",
"react": "19.1.0",
"react-native": "0.80.1",
"@react-native/new-app-screen": "0.80.1"
"react-native-gesture-handler": "^2.27.1",
"react-native-get-random-values": "^1.11.0",
"react-native-paper": "^5.14.5",
"react-native-safe-area-context": "^5.5.2",
"react-native-screens": "^4.13.1",
"react-native-vector-icons": "^10.2.0",
"uuid": "^11.1.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
@ -28,6 +38,7 @@
"@types/jest": "^29.5.13",
"@types/react": "^19.1.0",
"@types/react-test-renderer": "^19.1.0",
"@types/uuid": "^10.0.0",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",

View File

@ -0,0 +1,43 @@
import React from 'react';
import { View, Button, StyleSheet } from 'react-native';
interface BottomActionBarProps {
onRun: () => void;
onSave: () => void;
onUndo: () => void;
onRestore: () => void;
onBack: () => void;
isSaveDisabled?: boolean;
}
const BottomActionBar: React.FC<BottomActionBarProps> = ({
onRun,
onSave,
onUndo,
onRestore,
onBack,
isSaveDisabled = true,
}) => {
return (
<View style={styles.container}>
<Button title="运行" onPress={onRun} />
<Button title="保存" onPress={onSave} disabled={isSaveDisabled} />
<Button title="撤销" onPress={onUndo} />
<Button title="恢复" onPress={onRestore} />
<Button title="返回" onPress={onBack} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'space-around',
padding: 16,
borderTopWidth: 1,
borderColor: '#ccc',
backgroundColor: '#f5f5f5',
},
});
export default BottomActionBar;

View File

@ -0,0 +1,43 @@
import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import { Task } from '../types/task';
interface TaskCardProps {
task: Task;
onPress: (id: string) => void;
}
const TaskCard: React.FC<TaskCardProps> = ({ task, onPress }) => {
return (
<TouchableOpacity style={styles.card} onPress={() => onPress(task.id)}>
<Text style={styles.title}>{task.name}</Text>
<Text style={styles.status}>: {task.status}</Text>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
card: {
backgroundColor: '#fff',
borderRadius: 8,
padding: 16,
margin: 8,
width: '45%',
elevation: 3,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 2,
},
title: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 8,
},
status: {
fontSize: 14,
color: '#666',
},
});
export default TaskCard;

105
src/components/TaskForm.tsx Normal file
View File

@ -0,0 +1,105 @@
import React from 'react';
import { View, Text, TextInput, StyleSheet, ScrollView } from 'react-native';
import { Task, RobotAction } from '../types/task';
interface TaskFormProps {
task: Task;
onTaskChange: (updatedTask: Task) => void;
}
const TaskForm: React.FC<TaskFormProps> = ({ task, onTaskChange }) => {
const handleParamChange = (field: string, value: string) => {
const updatedTask = {
...task,
parameters: {
...task.parameters,
[field]: value,
},
};
onTaskChange(updatedTask);
};
return (
<ScrollView style={styles.container}>
<View style={styles.fieldContainer}>
<Text style={styles.label}></Text>
<TextInput
style={styles.input}
value={task.name}
onChangeText={text => onTaskChange({ ...task, name: text })}
/>
</View>
<View style={styles.fieldContainer}>
<Text style={styles.label}></Text>
<TextInput
style={styles.input}
value={task.parameters.startLocation}
onChangeText={text => handleParamChange('startLocation', text)}
/>
</View>
<View style={styles.fieldContainer}>
<Text style={styles.label}></Text>
<TextInput
style={styles.input}
value={task.parameters.endLocation}
onChangeText={text => handleParamChange('endLocation', text)}
/>
</View>
<View style={styles.fieldContainer}>
<Text style={styles.label}></Text>
<TextInput
style={styles.input}
value={task.parameters.waypoint || ''}
onChangeText={text => handleParamChange('waypoint', text)}
placeholder="可选"
/>
</View>
<View style={styles.fieldContainer}>
<Text style={styles.label}></Text>
{/* 在实际应用中,这里最好是一个下拉选择器 */}
<TextInput
style={styles.input}
value={task.parameters.robotAction}
onChangeText={text => handleParamChange('robotAction', text as RobotAction)}
/>
</View>
<View style={styles.fieldContainer}>
<Text style={styles.label}></Text>
<TextInput
style={styles.input}
value={task.parameters.payload}
onChangeText={text => handleParamChange('payload', text)}
/>
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
},
fieldContainer: {
marginBottom: 16,
},
label: {
fontSize: 16,
marginBottom: 8,
fontWeight: 'bold',
},
input: {
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 4,
padding: 12,
fontSize: 16,
},
});
export default TaskForm;

53
src/data/mockData.ts Normal file
View File

@ -0,0 +1,53 @@
import { Task } from '../types/task';
import { v4 as uuidv4 } from 'uuid';
export const MOCK_TASKS: Task[] = [
{
id: uuidv4(),
name: '炉前缓存区到热处理上料交接区运输',
status: 'IDLE',
createdAt: new Date().toISOString(),
parameters: {
startLocation: '炉前缓存区',
endLocation: '热处理上料交接区',
robotAction: 'TRANSPORT',
payload: '满料架-A1',
},
},
{
id: uuidv4(),
name: '空料架到焊接空料架交接区运输',
status: 'RUNNING',
createdAt: new Date().toISOString(),
parameters: {
startLocation: '空料架缓存区',
endLocation: '焊接空料架交接区',
robotAction: 'TRANSPORT',
payload: '空料架-B2',
},
},
{
id: uuidv4(),
name: '热后空料架返回交接区',
status: 'COMPLETED',
createdAt: new Date().toISOString(),
parameters: {
startLocation: '热后区',
endLocation: '空料架缓存区',
robotAction: 'TRANSPORT',
payload: '空料架-C3',
},
},
{
id: uuidv4(),
name: 'ALD上料空车运输到空车区',
status: 'IDLE',
createdAt: new Date().toISOString(),
parameters: {
startLocation: 'ALD上料区',
endLocation: '空车区',
robotAction: 'TRANSPORT',
payload: '空车',
},
},
];

View File

@ -0,0 +1,31 @@
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import TaskListScreen from '../screens/TaskListScreen';
import TaskEditScreen from '../screens/TaskEditScreen';
import RunScreen from '../screens/RunScreen';
import EditScreen from '../screens/EditScreen';
import SettingsScreen from '../screens/SettingsScreen';
const HomeStack = createStackNavigator();
const Tab = createBottomTabNavigator();
function HomeStackNavigator() {
return (
<HomeStack.Navigator>
<HomeStack.Screen name="TaskList" component={TaskListScreen} options={{ title: '任务列表' }} />
<HomeStack.Screen name="TaskEdit" component={TaskEditScreen} options={{ title: '编辑任务' }} />
</HomeStack.Navigator>
);
}
export default function AppNavigator() {
return (
<Tab.Navigator>
<Tab.Screen name="主页" component={HomeStackNavigator} options={{ headerShown: false }} />
<Tab.Screen name="运行" component={RunScreen} />
<Tab.Screen name="编辑" component={EditScreen} />
<Tab.Screen name="设置" component={SettingsScreen} />
</Tab.Navigator>
);
}

View File

@ -0,0 +1,18 @@
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default function EditScreen() {
return (
<View style={styles.screenContainer}>
<Text>!</Text>
</View>
);
}
const styles = StyleSheet.create({
screenContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});

View File

@ -0,0 +1,32 @@
import React from 'react';
import { StyleSheet, Text, View, Button, SafeAreaView } from 'react-native';
export default function HomeScreen() {
return (
<SafeAreaView style={styles.container}>
<View style={styles.grid}>
{[...Array(8)].map((_, i) => (
<View key={i} style={styles.buttonContainer}>
<Button title={`测试 ${i + 1}`} onPress={() => {}} />
</View>
))}
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20,
},
grid: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'center',
},
buttonContainer: {
width: '40%',
margin: 10,
},
});

18
src/screens/RunScreen.tsx Normal file
View File

@ -0,0 +1,18 @@
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default function RunScreen() {
return (
<View style={styles.screenContainer}>
<Text>!</Text>
</View>
);
}
const styles = StyleSheet.create({
screenContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});

View File

@ -0,0 +1,18 @@
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default function SettingsScreen() {
return (
<View style={styles.screenContainer}>
<Text>!</Text>
</View>
);
}
const styles = StyleSheet.create({
screenContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});

View File

@ -0,0 +1,70 @@
import React, { useState, useEffect } from 'react';
import { View, StyleSheet, Alert } from 'react-native';
import { useRoute, useNavigation } from '@react-navigation/native';
import { RouteProp } from '@react-navigation/native';
import TaskForm from '../components/TaskForm';
import BottomActionBar from '../components/BottomActionBar';
import { Task } from '../types/task';
import { MOCK_TASKS } from '../data/mockData';
type RootStackParamList = {
TaskEdit: { taskId: string };
};
type TaskEditRouteProp = RouteProp<RootStackParamList, 'TaskEdit'>;
export default function TaskEditScreen() {
const route = useRoute<TaskEditRouteProp>();
const navigation = useNavigation();
const { taskId } = route.params;
const [task, setTask] = useState<Task | null>(null);
const [isModified, setIsModified] = useState(false);
useEffect(() => {
// 根据taskId从模拟数据中查找任务
const foundTask = MOCK_TASKS.find(t => t.id === taskId);
if (foundTask) {
setTask(foundTask);
}
}, [taskId]);
const handleTaskChange = (updatedTask: Task) => {
setTask(updatedTask);
if (!isModified) {
setIsModified(true);
}
};
const handleSave = () => {
// 在这里处理保存逻辑比如调用API
Alert.alert('已保存', `任务 "${task?.name}" 已被保存。`);
setIsModified(false);
};
if (!task) {
return null; // 或者显示一个加载指示器
}
return (
<View style={styles.container}>
<TaskForm task={task} onTaskChange={handleTaskChange} />
<BottomActionBar
onRun={() => Alert.alert('运行', '开始运行任务...')}
onSave={handleSave}
onUndo={() => Alert.alert('撤销', '撤销更改...')}
onRestore={() => Alert.alert('恢复', '恢复到初始状态...')}
onBack={() => navigation.goBack()}
isSaveDisabled={!isModified}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});

View File

@ -0,0 +1,45 @@
import React, { useState } from 'react';
import { View, FlatList, StyleSheet } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack';
import TaskCard from '../components/TaskCard';
import { Task } from '../types/task';
import { MOCK_TASKS } from '../data/mockData';
type RootStackParamList = {
TaskList: undefined;
TaskEdit: { taskId: string };
};
type TaskListNavigationProp = StackNavigationProp<RootStackParamList, 'TaskList'>;
export default function TaskListScreen() {
const [tasks] = useState<Task[]>(MOCK_TASKS);
const navigation = useNavigation<TaskListNavigationProp>();
const handlePressTask = (taskId: string) => {
navigation.navigate('TaskEdit', { taskId });
};
return (
<View style={styles.container}>
<FlatList
data={tasks}
renderItem={({ item }) => <TaskCard task={item} onPress={handlePressTask} />}
keyExtractor={item => item.id}
numColumns={2}
columnWrapperStyle={styles.row}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
},
row: {
justifyContent: 'center',
},
});

23
src/types/task.ts Normal file
View File

@ -0,0 +1,23 @@
// 机器人的具体动作,可以定义为枚举或联合类型
export type RobotAction = 'PICKUP' | 'DROPOFF' | 'TRANSPORT' | 'WAIT';
// 任务的状态
export type TaskStatus = 'IDLE' | 'RUNNING' | 'COMPLETED' | 'ERROR';
// 任务参数
export interface TaskParameters {
startLocation: string; // 起点
endLocation: string; // 终点
waypoint?: string; // 途经点 (可选)
robotAction: RobotAction; // 机器人动作
payload: string; // 载荷,比如 '空料架' 或具体的物料ID
}
// 核心任务对象
export interface Task {
id: string; // 唯一ID例如使用 uuid
name: string; // 任务名称, e.g., "炉前缓存区到热处理上料交接区运输"
status: TaskStatus; // 任务当前状态
parameters: TaskParameters; // 任务的具体执行参数
createdAt: string; // 创建时间
}