diff --git a/code/app/app-rn4/app.json b/code/app/app-rn4/app.json
index 3b18eeaf..114954e1 100644
--- a/code/app/app-rn4/app.json
+++ b/code/app/app-rn4/app.json
@@ -6,7 +6,11 @@
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"userInterfaceStyle": "automatic",
- "scheme": ["oneao", "tencent102826474", "wxdab3e21a1f7e392f"],
+ "scheme": [
+ "oneao",
+ "tencent102826474",
+ "wxdab3e21a1f7e392f"
+ ],
"extra": {
"linkingScheme": "oneao"
},
diff --git a/code/app/app-rn4/package.json b/code/app/app-rn4/package.json
index d702e58d..13c8556b 100644
--- a/code/app/app-rn4/package.json
+++ b/code/app/app-rn4/package.json
@@ -4,7 +4,7 @@
"private": true,
"main": "expo-router/entry",
"scripts": {
- "start": "expo start --port=8082",
+ "start": "expo start --port=8083",
"reset-project": "node ./scripts/reset-project.js",
"android": "expo run:android",
"ios": "expo run:ios",
@@ -20,7 +20,6 @@
"@react-navigation/bottom-tabs": "^7.15.5",
"@react-navigation/elements": "^2.9.10",
"@react-navigation/native": "^7.1.33",
- "@yz1311/react-native-wheel-picker": "^0.4.5",
"alova": "^3.5.1",
"axios": "^1.15.0",
"dayjs": "^1.11.20",
@@ -47,19 +46,18 @@
"expo-wechat": "^0.2.6",
"heroui-native": "^1.0.1",
"lucide-react-native": "^1.8.0",
- "moment": "^2.30.1",
"react": "19.2.0",
"react-dom": "19.2.0",
"react-native": "0.83.4",
"react-native-gesture-handler": "~2.30.0",
"react-native-keyboard-controller": "1.20.7",
- "react-native-modal": "14.0.0-rc.1",
"react-native-reanimated": "4.2.1",
"react-native-safe-area-context": "~5.6.2",
"react-native-screens": "~4.23.0",
"react-native-shadow-2": "^7.1.2",
"react-native-sortables": "^1.9.4",
"react-native-svg": "15.15.3",
+ "react-native-ui-datepicker": "^3.1.3",
"react-native-web": "~0.21.0",
"react-native-worklets": "0.7.2",
"sonner-native": "^0.24.0",
@@ -71,6 +69,7 @@
},
"devDependencies": {
"@types/react": "~19.2.2",
+ "@yz1311/react-native-wheel-picker": "^0.4.5",
"babel-preset-expo": "^55.0.16",
"oxfmt": "^0.44.0",
"oxlint": "^1.59.0",
diff --git a/code/app/app-rn4/pnpm-lock.yaml b/code/app/app-rn4/pnpm-lock.yaml
index d60c4b9a..23a925f1 100644
--- a/code/app/app-rn4/pnpm-lock.yaml
+++ b/code/app/app-rn4/pnpm-lock.yaml
@@ -29,9 +29,6 @@ importers:
'@react-navigation/native':
specifier: ^7.1.33
version: 7.2.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)
- '@yz1311/react-native-wheel-picker':
- specifier: ^0.4.5
- version: 0.4.5(deprecated-react-native-prop-types@5.0.0)(moment@2.30.1)(react-native-modal@14.0.0-rc.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))
alova:
specifier: ^3.5.1
version: 3.5.1
@@ -110,9 +107,6 @@ importers:
lucide-react-native:
specifier: ^1.8.0
version: 1.8.0(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)
- moment:
- specifier: ^2.30.1
- version: 2.30.1
react:
specifier: 19.2.0
version: 19.2.0
@@ -128,9 +122,6 @@ importers:
react-native-keyboard-controller:
specifier: 1.20.7
version: 1.20.7(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)
- react-native-modal:
- specifier: 14.0.0-rc.1
- version: 14.0.0-rc.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)
react-native-reanimated:
specifier: 4.2.1
version: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)
@@ -149,6 +140,9 @@ importers:
react-native-svg:
specifier: 15.15.3
version: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)
+ react-native-ui-datepicker:
+ specifier: ^3.1.3
+ version: 3.1.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)
react-native-web:
specifier: ~0.21.0
version: 0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
@@ -177,6 +171,9 @@ importers:
'@types/react':
specifier: ~19.2.2
version: 19.2.14
+ '@yz1311/react-native-wheel-picker':
+ specifier: ^0.4.5
+ version: 0.4.5(deprecated-react-native-prop-types@5.0.0)(moment@2.30.1)(react-native-modal@14.0.0-rc.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))
babel-preset-expo:
specifier: ^55.0.16
version: 55.0.17(@babel/core@7.29.0)(@babel/runtime@7.29.2)(expo@55.0.15)(react-refresh@0.14.2)
@@ -1031,48 +1028,56 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@oxfmt/binding-linux-arm64-musl@0.44.0':
resolution: {integrity: sha512-AlObQIXyVRZ96LbtVljtFq0JqH5B92NU+BQeDFrXWBUWlCKAM0wF5GLfIhCLT5kQ3Sl+U0YjRJ7Alqj5hGQaCg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@oxfmt/binding-linux-ppc64-gnu@0.44.0':
resolution: {integrity: sha512-YcFE8/q/BbrCiIiM5piwbkA6GwJc5QqhMQp2yDrqQ2fuVkZ7CInb1aIijZ/k8EXc72qXMSwKpVlBv1w/MsGO/A==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@oxfmt/binding-linux-riscv64-gnu@0.44.0':
resolution: {integrity: sha512-eOdzs6RqkRzuqNHUX5C8ISN5xfGh4xDww8OEd9YAmc3OWN8oAe5bmlIqQ+rrHLpv58/0BuU48bxkhnIGjA/ATQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@oxfmt/binding-linux-riscv64-musl@0.44.0':
resolution: {integrity: sha512-YBgNTxntD/QvlFUfgvh8bEdwOhXiquX8gaofZJAwYa/Xp1S1DQrFVZEeck7GFktr24DztsSp8N8WtWCBwxs0Hw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
+ libc: [musl]
'@oxfmt/binding-linux-s390x-gnu@0.44.0':
resolution: {integrity: sha512-GLIh1R6WHWshl/i4QQDNgj0WtT25aRO4HNUWEoitxiywyRdhTFmFEYT2rXlcl9U6/26vhmOqG5cRlMLG3ocaIA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@oxfmt/binding-linux-x64-gnu@0.44.0':
resolution: {integrity: sha512-gZOpgTlOsLcLfAF9qgpTr7FIIFSKnQN3hDf/0JvQ4CIwMY7h+eilNjxq/CorqvYcEOu+LRt1W4ZS7KccEHLOdA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@oxfmt/binding-linux-x64-musl@0.44.0':
resolution: {integrity: sha512-1CyS9JTB+pCUFYFI6pkQGGZaT/AY5gnhHVrQQLhFba6idP9AzVYm1xbdWfywoldTYvjxQJV6x4SuduCIfP3W+A==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@oxfmt/binding-openharmony-arm64@0.44.0':
resolution: {integrity: sha512-bmEv70Ak6jLr1xotCbF5TxIKjsmQaiX+jFRtnGtfA03tJPf6VG3cKh96S21boAt3JZc+Vjx8PYcDuLj39vM2Pw==}
@@ -1145,48 +1150,56 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@oxlint/binding-linux-arm64-musl@1.60.0':
resolution: {integrity: sha512-eDYDXZGhQAXyn6GwtwiX/qcLS0HlOLPJ/+iiIY8RYr+3P8oKBmgKxADLlniL6FtWfE7pPk7IGN9/xvDEvDvFeg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@oxlint/binding-linux-ppc64-gnu@1.60.0':
resolution: {integrity: sha512-nxehly5XYBHUWI9VJX1bqCf9j/B43DaK/aS/T1fcxCpX3PA4Rm9BB54nPD1CKayT8xg6REN1ao+01hSRNgy8OA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@oxlint/binding-linux-riscv64-gnu@1.60.0':
resolution: {integrity: sha512-j1qf/NaUfOWQutjeoooNG1Q0zsK0XGmSu1uDLq3cctquRF3j7t9Hxqf/76ehCc5GEUAanth2W4Fa+XT1RFg/nw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@oxlint/binding-linux-riscv64-musl@1.60.0':
resolution: {integrity: sha512-YELKPRefQ/q/h3RUmeRfPCUhh2wBvgV1RyZ/F9M9u8cDyXsQW2ojv1DeWQTt466yczDITjZnIOg/s05pk7Ve2A==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
+ libc: [musl]
'@oxlint/binding-linux-s390x-gnu@1.60.0':
resolution: {integrity: sha512-JkO3C6Gki7Y6h/MiIkFKvHFOz98/YWvQ4WYbK9DLXACMP2rjULzkeGyAzorJE5S1dzLQGFgeqvN779kSFwoV1g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@oxlint/binding-linux-x64-gnu@1.60.0':
resolution: {integrity: sha512-XjKHdFVCpZZZSWBCKyyqCq65s2AKXykMXkjLoKYODrD+f5toLhlwsMESscu8FbgnJQ4Y/dpR/zdazsahmgBJIA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@oxlint/binding-linux-x64-musl@1.60.0':
resolution: {integrity: sha512-js29ZWIuPhNWzY8NC7KoffEMEeWG105vbmm+8EOJsC+T/jHBiKIJEUF78+F/IrgEWMMP9N0kRND4Pp75+xAhKg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@oxlint/binding-openharmony-arm64@1.60.0':
resolution: {integrity: sha512-H+PUITKHk04stFpWj3x3Kg08Afp/bcXSBi0EhasR5a0Vw7StXHTzdl655PUI0fB4qdh2Wsu6Dsi+3ACxPoyQnA==}
@@ -1608,24 +1621,28 @@ packages:
engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@tailwindcss/oxide-linux-arm64-musl@4.2.1':
resolution: {integrity: sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@tailwindcss/oxide-linux-x64-gnu@4.2.1':
resolution: {integrity: sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==}
engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@tailwindcss/oxide-linux-x64-musl@4.2.1':
resolution: {integrity: sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==}
engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@tailwindcss/oxide-wasm32-wasi@4.2.1':
resolution: {integrity: sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==}
@@ -1984,6 +2001,10 @@ packages:
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
engines: {node: '>=0.8'}
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
@@ -2580,7 +2601,7 @@ packages:
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
- deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
+ deprecated: Glob versions prior to v9 are no longer supported
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
@@ -2742,6 +2763,9 @@ packages:
resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==}
engines: {node: '>=8'}
+ jalali-plugin-dayjs@1.1.4:
+ resolution: {integrity: sha512-d62QGMTufGQ1TSov4a85gBU58PA8aL6wVQs9BnC3+d/VA+v4Sq0OqM3o6RoY+/VZjliYJroGIPwlSVf7uLnZ3w==}
+
jest-environment-node@29.7.0:
resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -2913,72 +2937,84 @@ packages:
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
lightningcss-linux-arm64-gnu@1.31.1:
resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
lightningcss-linux-arm64-gnu@1.32.0:
resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
lightningcss-linux-arm64-musl@1.30.1:
resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
lightningcss-linux-arm64-musl@1.31.1:
resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
lightningcss-linux-arm64-musl@1.32.0:
resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
lightningcss-linux-x64-gnu@1.30.1:
resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
lightningcss-linux-x64-gnu@1.31.1:
resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
lightningcss-linux-x64-gnu@1.32.0:
resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
lightningcss-linux-x64-musl@1.30.1:
resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
+ libc: [musl]
lightningcss-linux-x64-musl@1.31.1:
resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
+ libc: [musl]
lightningcss-linux-x64-musl@1.32.0:
resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
+ libc: [musl]
lightningcss-win32-arm64-msvc@1.30.1:
resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==}
@@ -3611,6 +3647,13 @@ packages:
react: '*'
react-native: '*'
+ react-native-ui-datepicker@3.1.3:
+ resolution: {integrity: sha512-IFafoW1UwCH2kbUJDgHGZtzVJMg82uyKLMXSmEbbXhyQ6+h1IZSJW/3eC/+X9fUVfArXnDzwsJG80r8dHSM3Ow==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ react: '*'
+ react-native: '*'
+
react-native-web@0.21.2:
resolution: {integrity: sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==}
peerDependencies:
@@ -6294,6 +6337,8 @@ snapshots:
clone@1.0.4: {}
+ clsx@2.1.1: {}
+
color-convert@1.9.3:
dependencies:
color-name: 1.1.3
@@ -7059,6 +7104,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ jalali-plugin-dayjs@1.1.4: {}
+
jest-environment-node@29.7.0:
dependencies:
'@jest/environment': 29.7.0
@@ -8111,6 +8158,16 @@ snapshots:
react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)
warn-once: 0.1.1
+ react-native-ui-datepicker@3.1.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0):
+ dependencies:
+ clsx: 2.1.1
+ dayjs: 1.11.20
+ jalali-plugin-dayjs: 1.1.4
+ lodash: 4.18.1
+ react: 19.2.0
+ react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)
+ tailwind-merge: 3.5.0
+
react-native-web@0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
dependencies:
'@babel/runtime': 7.29.2
diff --git a/code/app/app-rn4/src/app/(tabs)/chat/index.tsx b/code/app/app-rn4/src/app/(tabs)/chat/index.tsx
index 5dea6cd5..18fa97ba 100644
--- a/code/app/app-rn4/src/app/(tabs)/chat/index.tsx
+++ b/code/app/app-rn4/src/app/(tabs)/chat/index.tsx
@@ -1,79 +1,13 @@
-import React, { useState } from "react";
-import { View, Text } from "react-native";
-import { Button } from "heroui-native";
-import DateRangePicker from "@/components/DateRangePicker";
-import dayjs from "dayjs";
-
-export default function RangeDemo() {
- const [start, setStart] = useState("");
- const [end, setEnd] = useState("");
- const [show, setShow] = useState(false);
-
- // 快捷选择
- const setToday = () => {
- const today = dayjs().format("YYYY-MM-DD");
- setStart(today);
- setEnd(today);
- };
-
- const setLast7Days = () => {
- const end = dayjs();
- const start = end.subtract(6, "day");
- setStart(start.format("YYYY-MM-DD"));
- setEnd(end.format("YYYY-MM-DD"));
- };
-
- const setThisMonth = () => {
- const start = dayjs().startOf("month");
- const end = dayjs().endOf("month");
- setStart(start.format("YYYY-MM-DD"));
- setEnd(end.format("YYYY-MM-DD"));
- };
+import React from "react";
+import LayoutView from "@/components/layout/view";
+import { Text } from "react-native";
+export default function Chat() {
return (
-
- 日期区间选择 Demo
-
- {/* 当前选择展示 */}
- 开始:{start || "--"}
- 结束:{end || "--"}
-
- {/* 打开选择器 */}
-
-
- {/* 快捷选择 */}
-
-
-
-
-
-
- {/* RangePicker */}
- setShow(false)}
- onConfirm={(s, e) => {
- // 简单校验(开始不能大于结束)
- if (dayjs(s).isAfter(dayjs(e))) {
- console.warn("开始时间不能大于结束时间");
- return;
- }
-
- setStart(s);
- setEnd(e);
- setShow(false);
- }}
- />
-
+
+
+ Hello
+
+
);
-}
+}
\ No newline at end of file
diff --git a/code/app/app-rn4/src/app/(tabs)/star/index.tsx b/code/app/app-rn4/src/app/(tabs)/star/index.tsx
index 470646fd..e3ecf607 100644
--- a/code/app/app-rn4/src/app/(tabs)/star/index.tsx
+++ b/code/app/app-rn4/src/app/(tabs)/star/index.tsx
@@ -1,24 +1,13 @@
import React from "react";
-import { View, Text } from "react-native";
-import DatePicker from "@/components/DatePicker";
-import { useState } from "react";
-import { Button } from "heroui-native";
-
-export default function Star() {
- const [date, setDate] = useState("");
- const [showDate, setShowDate] = useState(false);
+import LayoutView from "@/components/layout/view";
+import { Text } from "react-native";
+export default function Start() {
return (
-
- Star
-
-
-
+
+
+ Hello
+
+
);
}
diff --git a/code/app/app-rn4/src/app/auth/login.tsx b/code/app/app-rn4/src/app/auth/login.tsx
index d69ebe6b..e811d96d 100644
--- a/code/app/app-rn4/src/app/auth/login.tsx
+++ b/code/app/app-rn4/src/app/auth/login.tsx
@@ -1,17 +1,11 @@
-import { useEffect } from "react";
import { Stack } from "expo-router";
import { Image, Text, View } from "react-native";
import { Button, LinkButton, ControlField, Checkbox, Spinner } from "heroui-native";
-import { IconQq, IconWeixin } from "@/components/iconfont";
+import { IconQq } from "@/components/iconfont";
import { useState } from "react";
import { FadeIn } from "react-native-reanimated";
import { useUserStore, useFamilyStore } from "@/store";
import { useRouter } from "expo-router";
-import ExpoQQ from "expo-qq";
-import ExpoWeChat from "expo-wechat";
-import { useEvent } from "expo";
-import { toast } from "sonner-native";
-import { loginQqApi, loginWxApi } from "@/request/api";
export default function Login() {
const router = useRouter();
@@ -20,189 +14,47 @@ export default function Login() {
const [loading, setLoading] = useState(false);
const [isAgreed, setIsAgreed] = useState(true);
- const [form, setForm] = useState({
- type: 0,
- openid: "",
- code: "",
- });
- // 登录
- const onLoginFinished = useEvent(ExpoQQ, "onLoginFinished");
- const onGetUserInfo = useEvent(ExpoQQ, "onGetUserInfo");
- const authResult = useEvent(ExpoWeChat, "onAuthResult");
+ /**
+ * {"code": 1000, "data": {"avatar": "http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100", "family_id": 797225979793477, "nickname": "Zhang", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJfaWQiOjc5NjU0MTkwMTM4OTg5M30sImlhdCI6MTc3Njc3MTcyOX0.JldxjA-0u2hza3qNx20xgUyVBVVV6hQuVuTW1GcJyr8", "userId": 796541901389893}, "isSuccess": true, "message": "success", "track_id": "hI5gEsPHu1LGwkQaJ6lf1dDQby0rzxGVJj0KcNC3Nxw"}
+ */
- useEffect(() => {
- ExpoQQ.init("102826474", "");
- ExpoWeChat.registerApp("wxdab3e21a1f7e392f", "");
- }, []);
-
- // 微信登录
- async function handleLoginWechat() {
- if (loading) {
- return;
- }
- setLoading(true);
-
- // 检查微信是否安装
- const isInstalled = await ExpoWeChat.isWXAppInstalled();
- if (!isInstalled) {
- toast.warning(onLoginFinished?.errorMessage || "请先安装微信");
- setLoading(false);
- return;
- }
-
- setForm((val) => ({
- ...val,
- type: 0,
- }));
-
- ExpoWeChat.sendAuthRequest("snsapi_userinfo", "state123");
- }
-
- // QQ 登录
- async function handleLoginQQ() {
+ function handleTest() {
if (loading) {
return;
}
setLoading(true);
- setForm((val) => ({
- ...val,
- type: 1,
- }));
- await ExpoQQ.login(["get_user_info"]);
- }
+ setTimeout(() => {
+ requestAnimationFrame(() => {
+ userStore.setUserInfo({
+ id: 796541901389893,
+ token:
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJfaWQiOjc5NjU0MTkwMTM4OTg5M30sImlhdCI6MTc3Njc3MTcyOX0.JldxjA-0u2hza3qNx20xgUyVBVVV6hQuVuTW1GcJyr8",
+ nickname: "Zhang",
+ avatar:
+ "http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100",
+ });
+ userStore.setAuthExpired(false);
+ console.log(familyStore.inFamily());
- useEffect(() => {
- if (!onLoginFinished) {
- return;
- }
+ // if (familyStore.inFamily()) {
+ // router.replace("/(tabs)/home");
+ // } else {
+ // router.replace("/family/entry");
+ // return;
+ // }
- if (!onLoginFinished.success) {
- toast.warning(onLoginFinished?.errorMessage || "授权失败,请检查手机是否安装 QQ 或确认授权");
- setLoading(false);
- return;
- }
-
- const fetchUserInfo = async () => {
- try {
- const tokenInfo = await ExpoQQ.getLoginTokenInfo();
- if (!tokenInfo.openId) {
- toast.warning(tokenInfo?.errorMessage || "授权失败,请检查手机是否安装 QQ 或确认授权");
- setLoading(false);
- return;
- }
-
- setForm((val) => ({
- ...val,
- openid: String(tokenInfo.openId),
- }));
-
- await ExpoQQ.sendGetUserInfoReq();
- } catch (e) {
- console.log(e);
-
- setLoading(false);
- }
- };
-
- fetchUserInfo();
- }, [onLoginFinished]);
-
- // QQ登录
- useEffect(() => {
- const handleLogin = async () => {
- if (!onGetUserInfo) {
- setLoading(false);
- return;
- }
-
- try {
- const loginRes = await loginQqApi({
- openid: form.openid,
- nickname: onGetUserInfo.nickname || "",
- avatar: onGetUserInfo.figureurlQq_2 || onGetUserInfo.figureurl_2,
+ familyStore.setCurrentFamily({
+ family_id: 797225979793477,
});
- if (loginRes.isSuccess) {
- requestAnimationFrame(() => {
- userStore.setUserInfo({
- token: loginRes.data.token,
- id: loginRes.data.userId,
- nickname: loginRes.data.nickname,
- avatar: loginRes.data.avatar,
- });
-
- userStore.setAuthExpired(false);
-
- if (loginRes.data.family_id === 0) {
- router.replace("/family/entry");
- } else {
- familyStore.setCurrentFamily({
- family_id: loginRes.data.family_id,
- });
-
- router.replace("/(tabs)/home");
- }
- });
- }
- } catch (err) {
- console.error("登录接口出错", err);
- } finally {
- setLoading(false);
- }
- };
-
- handleLogin();
- }, [onGetUserInfo]);
-
- // 微信登录
- useEffect(() => {
- if (!authResult) return;
-
- const handleLogin = async () => {
- if (authResult.errorCode === 0) {
- try {
- const loginRes = await loginWxApi({
- code: authResult.code,
- });
-
- if (loginRes.isSuccess) {
- requestAnimationFrame(() => {
- userStore.setUserInfo({
- token: loginRes.data.token,
- id: loginRes.data.userId,
- nickname: loginRes.data.nickname,
- avatar: loginRes.data.avatar,
- });
-
- userStore.setAuthExpired(false);
-
- if (loginRes.data.family_id === 0) {
- router.replace("/family/entry");
- } else {
- familyStore.setCurrentFamily({
- family_id: loginRes.data.family_id,
- });
-
- router.replace("/(tabs)/home");
- }
- });
- }
- } catch (err) {
- console.error("登录接口出错", err);
- } finally {
- setLoading(false);
- }
- } else {
- console.log("授权失败:", authResult.errorMessage);
- setLoading(false);
- }
- };
-
- handleLogin();
- }, [authResult]);
+ router.replace("/(tabs)/home");
+ });
+ setLoading(false);
+ }, 500);
+ }
return (
<>
@@ -222,7 +74,7 @@ export default function Login() {
-
diff --git a/code/app/app-rn4/src/app/auth/login.txt b/code/app/app-rn4/src/app/auth/login.txt
deleted file mode 100644
index e811d96d..00000000
--- a/code/app/app-rn4/src/app/auth/login.txt
+++ /dev/null
@@ -1,119 +0,0 @@
-import { Stack } from "expo-router";
-import { Image, Text, View } from "react-native";
-import { Button, LinkButton, ControlField, Checkbox, Spinner } from "heroui-native";
-import { IconQq } from "@/components/iconfont";
-import { useState } from "react";
-import { FadeIn } from "react-native-reanimated";
-import { useUserStore, useFamilyStore } from "@/store";
-import { useRouter } from "expo-router";
-
-export default function Login() {
- const router = useRouter();
- const userStore = useUserStore();
- const familyStore = useFamilyStore();
-
- const [loading, setLoading] = useState(false);
- const [isAgreed, setIsAgreed] = useState(true);
-
- /**
- * {"code": 1000, "data": {"avatar": "http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100", "family_id": 797225979793477, "nickname": "Zhang", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJfaWQiOjc5NjU0MTkwMTM4OTg5M30sImlhdCI6MTc3Njc3MTcyOX0.JldxjA-0u2hza3qNx20xgUyVBVVV6hQuVuTW1GcJyr8", "userId": 796541901389893}, "isSuccess": true, "message": "success", "track_id": "hI5gEsPHu1LGwkQaJ6lf1dDQby0rzxGVJj0KcNC3Nxw"}
- */
-
- function handleTest() {
- if (loading) {
- return;
- }
-
- setLoading(true);
-
- setTimeout(() => {
- requestAnimationFrame(() => {
- userStore.setUserInfo({
- id: 796541901389893,
- token:
- "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJfaWQiOjc5NjU0MTkwMTM4OTg5M30sImlhdCI6MTc3Njc3MTcyOX0.JldxjA-0u2hza3qNx20xgUyVBVVV6hQuVuTW1GcJyr8",
- nickname: "Zhang",
- avatar:
- "http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100",
- });
- userStore.setAuthExpired(false);
- console.log(familyStore.inFamily());
-
- // if (familyStore.inFamily()) {
- // router.replace("/(tabs)/home");
- // } else {
- // router.replace("/family/entry");
- // return;
- // }
-
- familyStore.setCurrentFamily({
- family_id: 797225979793477,
- });
-
- router.replace("/(tabs)/home");
- });
- setLoading(false);
- }, 500);
- }
-
- return (
- <>
-
-
-
-
- Welcome to Allapp
-
-
-
- {/*
- {loading ? (
-
- ) : (
-
- )}
- WeChat
-
-
-
- {loading ? : }
- QQ
- */}
-
-
- {loading ? : }
- Test
-
-
-
-
-
-
-
-
- 登录即表示你同意我们的
-
- 用户协议
-
- 和
-
- 隐私政策
-
-
-
-
- >
- );
-}
diff --git a/code/app/app-rn4/src/app/auth/login.txt2 b/code/app/app-rn4/src/app/auth/login.txt2
new file mode 100644
index 00000000..d69ebe6b
--- /dev/null
+++ b/code/app/app-rn4/src/app/auth/login.txt2
@@ -0,0 +1,262 @@
+import { useEffect } from "react";
+import { Stack } from "expo-router";
+import { Image, Text, View } from "react-native";
+import { Button, LinkButton, ControlField, Checkbox, Spinner } from "heroui-native";
+import { IconQq, IconWeixin } from "@/components/iconfont";
+import { useState } from "react";
+import { FadeIn } from "react-native-reanimated";
+import { useUserStore, useFamilyStore } from "@/store";
+import { useRouter } from "expo-router";
+import ExpoQQ from "expo-qq";
+import ExpoWeChat from "expo-wechat";
+import { useEvent } from "expo";
+import { toast } from "sonner-native";
+import { loginQqApi, loginWxApi } from "@/request/api";
+
+export default function Login() {
+ const router = useRouter();
+ const userStore = useUserStore();
+ const familyStore = useFamilyStore();
+
+ const [loading, setLoading] = useState(false);
+ const [isAgreed, setIsAgreed] = useState(true);
+ const [form, setForm] = useState({
+ type: 0,
+ openid: "",
+ code: "",
+ });
+
+ // 登录
+ const onLoginFinished = useEvent(ExpoQQ, "onLoginFinished");
+ const onGetUserInfo = useEvent(ExpoQQ, "onGetUserInfo");
+ const authResult = useEvent(ExpoWeChat, "onAuthResult");
+
+ useEffect(() => {
+ ExpoQQ.init("102826474", "");
+ ExpoWeChat.registerApp("wxdab3e21a1f7e392f", "");
+ }, []);
+
+ // 微信登录
+ async function handleLoginWechat() {
+ if (loading) {
+ return;
+ }
+ setLoading(true);
+
+ // 检查微信是否安装
+ const isInstalled = await ExpoWeChat.isWXAppInstalled();
+ if (!isInstalled) {
+ toast.warning(onLoginFinished?.errorMessage || "请先安装微信");
+ setLoading(false);
+ return;
+ }
+
+ setForm((val) => ({
+ ...val,
+ type: 0,
+ }));
+
+ ExpoWeChat.sendAuthRequest("snsapi_userinfo", "state123");
+ }
+
+ // QQ 登录
+ async function handleLoginQQ() {
+ if (loading) {
+ return;
+ }
+
+ setLoading(true);
+
+ setForm((val) => ({
+ ...val,
+ type: 1,
+ }));
+ await ExpoQQ.login(["get_user_info"]);
+ }
+
+ useEffect(() => {
+ if (!onLoginFinished) {
+ return;
+ }
+
+ if (!onLoginFinished.success) {
+ toast.warning(onLoginFinished?.errorMessage || "授权失败,请检查手机是否安装 QQ 或确认授权");
+ setLoading(false);
+ return;
+ }
+
+ const fetchUserInfo = async () => {
+ try {
+ const tokenInfo = await ExpoQQ.getLoginTokenInfo();
+ if (!tokenInfo.openId) {
+ toast.warning(tokenInfo?.errorMessage || "授权失败,请检查手机是否安装 QQ 或确认授权");
+ setLoading(false);
+ return;
+ }
+
+ setForm((val) => ({
+ ...val,
+ openid: String(tokenInfo.openId),
+ }));
+
+ await ExpoQQ.sendGetUserInfoReq();
+ } catch (e) {
+ console.log(e);
+
+ setLoading(false);
+ }
+ };
+
+ fetchUserInfo();
+ }, [onLoginFinished]);
+
+ // QQ登录
+ useEffect(() => {
+ const handleLogin = async () => {
+ if (!onGetUserInfo) {
+ setLoading(false);
+ return;
+ }
+
+ try {
+ const loginRes = await loginQqApi({
+ openid: form.openid,
+ nickname: onGetUserInfo.nickname || "",
+ avatar: onGetUserInfo.figureurlQq_2 || onGetUserInfo.figureurl_2,
+ });
+
+ if (loginRes.isSuccess) {
+ requestAnimationFrame(() => {
+ userStore.setUserInfo({
+ token: loginRes.data.token,
+ id: loginRes.data.userId,
+ nickname: loginRes.data.nickname,
+ avatar: loginRes.data.avatar,
+ });
+
+ userStore.setAuthExpired(false);
+
+ if (loginRes.data.family_id === 0) {
+ router.replace("/family/entry");
+ } else {
+ familyStore.setCurrentFamily({
+ family_id: loginRes.data.family_id,
+ });
+
+ router.replace("/(tabs)/home");
+ }
+ });
+ }
+ } catch (err) {
+ console.error("登录接口出错", err);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ handleLogin();
+ }, [onGetUserInfo]);
+
+ // 微信登录
+ useEffect(() => {
+ if (!authResult) return;
+
+ const handleLogin = async () => {
+ if (authResult.errorCode === 0) {
+ try {
+ const loginRes = await loginWxApi({
+ code: authResult.code,
+ });
+
+ if (loginRes.isSuccess) {
+ requestAnimationFrame(() => {
+ userStore.setUserInfo({
+ token: loginRes.data.token,
+ id: loginRes.data.userId,
+ nickname: loginRes.data.nickname,
+ avatar: loginRes.data.avatar,
+ });
+
+ userStore.setAuthExpired(false);
+
+ if (loginRes.data.family_id === 0) {
+ router.replace("/family/entry");
+ } else {
+ familyStore.setCurrentFamily({
+ family_id: loginRes.data.family_id,
+ });
+
+ router.replace("/(tabs)/home");
+ }
+ });
+ }
+ } catch (err) {
+ console.error("登录接口出错", err);
+ } finally {
+ setLoading(false);
+ }
+ } else {
+ console.log("授权失败:", authResult.errorMessage);
+ setLoading(false);
+ }
+ };
+
+ handleLogin();
+ }, [authResult]);
+
+ return (
+ <>
+
+
+
+
+ Welcome to Allapp
+
+
+
+
+ {loading ? (
+
+ ) : (
+
+ )}
+ WeChat
+
+
+
+ {loading ? : }
+ QQ
+
+
+
+
+
+
+
+
+ 登录即表示你同意我们的
+
+ 用户协议
+
+ 和
+
+ 隐私政策
+
+
+
+
+ >
+ );
+}
diff --git a/code/app/app-rn4/src/app/family/user.tsx b/code/app/app-rn4/src/app/family/user.tsx
index fdebe302..f0aa3188 100644
--- a/code/app/app-rn4/src/app/family/user.tsx
+++ b/code/app/app-rn4/src/app/family/user.tsx
@@ -1,13 +1,89 @@
import LayoutView from "@/components/layout/view";
-import { Text } from "react-native";
+import { View, Text, Pressable } from "react-native";
import PageLayout from "@/layouts/PageLayout";
+import { Avatar, PressableFeedback } from "heroui-native";
+import { loadDataApi } from "@/request/api";
+import { useUserStore } from "@/store";
+import { useEffect, useState } from "react";
+import { CameraIcon } from "lucide-react-native";
+import * as ImagePicker from "expo-image-picker";
export default function UserSetting() {
+ const userStore = useUserStore();
+
+ const [userInfo, setUserInfo] = useState({});
+
+ async function loadUserInfo() {
+ try {
+ const res = await loadDataApi({
+ view_name: "b_user",
+ search_columns: [],
+ search_condition: `id = ?`,
+ order_by: "",
+ args: [userStore.userInfo.id],
+ });
+
+ if (res.isSuccess && res.data.length > 0) {
+ setUserInfo(res.data[0]);
+ }
+ } catch (e) {
+ console.log(e);
+ }
+ }
+
+ useEffect(() => {
+ loadUserInfo();
+ }, []);
+
+ const pickImage = async () => {
+ const res = await ImagePicker.launchImageLibraryAsync({
+ mediaTypes: ["images"],
+ allowsEditing: true,
+ quality: 0.7,
+ });
+
+ if (!res.canceled) {
+ console.log(res.assets[0].uri);
+ }
+ };
+
return (
- UserSetting
+
+ 头像
+
+
+
+ {/* Avatar */}
+ {
+ pickImage();
+ }}
+ className="w-full h-full rounded-full overflow-hidden"
+ >
+
+
+ JD
+
+
+
+
+
+
+
+
+
+
+ {
+ pickImage();
+ }}
+ >
+ 基础信息
+
+
diff --git a/code/app/app-rn4/src/components/DateRangePicker.tsx b/code/app/app-rn4/src/components/DateRange.tsx
similarity index 100%
rename from code/app/app-rn4/src/components/DateRangePicker.tsx
rename to code/app/app-rn4/src/components/DateRange.tsx
diff --git a/code/app/app-rn4/src/components/DatePicker.tsx b/code/app/app-rn4/src/components/DateTime.tsx
similarity index 100%
rename from code/app/app-rn4/src/components/DatePicker.tsx
rename to code/app/app-rn4/src/components/DateTime.tsx
diff --git a/code/container-ocr/ocr-springboot/src/main/java/cn/g3soft/controller/FileController.java b/code/container-ocr/ocr-springboot/src/main/java/cn/g3soft/controller/FileController.java
index f2909ac6..b24ed5d8 100644
--- a/code/container-ocr/ocr-springboot/src/main/java/cn/g3soft/controller/FileController.java
+++ b/code/container-ocr/ocr-springboot/src/main/java/cn/g3soft/controller/FileController.java
@@ -41,7 +41,6 @@ public class FileController {
// 3. 物理路径
String basePath = fileConfig.getTempPath(); // D:/data/file/temp/
- System.out.println(basePath);
// 4. 保存
FileUtils.saveFile(file, basePath, uuidName);
@@ -99,7 +98,7 @@ public class FileController {
// 8. 返回
Map result = new HashMap<>();
- result.put("fileName", uuidName);
+ result.put("fileName", fileName);
result.put("url", url);
result.put("path", relativePath);
@@ -237,7 +236,7 @@ public class FileController {
result.put("url", url);
result.put("path", relativePath);
result.put("uid", nextId);
- result.put("fileName", newFileName);
+ result.put("fileName", fileName);
result.put("bucket", bucket);
return Result.ok(result);
diff --git a/code/container-ocr/ocr-springboot/src/main/resources/dbconfigs/g3hd.properties b/code/container-ocr/ocr-springboot/src/main/resources/dbconfigs/g3hd.properties
index 8d6733ef..05bead7b 100644
--- a/code/container-ocr/ocr-springboot/src/main/resources/dbconfigs/g3hd.properties
+++ b/code/container-ocr/ocr-springboot/src/main/resources/dbconfigs/g3hd.properties
@@ -1,10 +1,10 @@
-url=jdbc:sqlserver://118.89.70.199:1433;databaseName=G3BoxOCR
-username=sa
-password=zhang520..
-driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
-
-#url=jdbc:sqlserver://127.0.0.1:1433;databaseName=G3ContainerOCR
+#url=jdbc:sqlserver://118.89.70.199:1433;databaseName=G3BoxOCR
#username=sa
-#password=123456@aaa
+#password=zhang520..
#driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
+url=jdbc:sqlserver://127.0.0.1:1433;databaseName=G3ContainerOCR
+username=sa
+password=123456@aaa
+driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
+
diff --git a/code/container-ocr/ocr-uniapp/src/pages-sub/upload/edit.vue b/code/container-ocr/ocr-uniapp/src/pages-sub/upload/edit.vue
index 00e18ab6..13ccad83 100644
--- a/code/container-ocr/ocr-uniapp/src/pages-sub/upload/edit.vue
+++ b/code/container-ocr/ocr-uniapp/src/pages-sub/upload/edit.vue
@@ -14,7 +14,8 @@ const form = ref({
b_container_img: '',
})
-const subFileList = ref([])
+const subFileList = ref([]) // 装货照片
+const subFileList2 = ref([]) // 发货单、签收单、过磅单
onLoad((options) => {
const id = options.id
@@ -34,7 +35,7 @@ async function loadMainData() {
try {
const orgUrl = await getOrgBaseUrl(userStore.userInfo.orgid)
- // 并发请求(提升性能)
+ // ================= 并发请求 =================
const [res, fileRes] = await Promise.all([
loadDataApi({
viewName: 'v_container',
@@ -42,7 +43,7 @@ async function loadMainData() {
}),
loadDataApi({
viewName: 'bf_file',
- searchCondition: `father = '${form.value.b_id}' AND mx_cate_id = '1'`,
+ searchCondition: `father = '${form.value.b_id}'`,
}),
])
@@ -60,19 +61,46 @@ async function loadMainData() {
form.value = mainData
}
else {
- console.warn('未获取到主数据')
+ uni.showToast({
+ title: '当前数据无效',
+ icon: 'none',
+ duration: 1500,
+ })
+
+ setTimeout(() => {
+ const pages = getCurrentPages()
+
+ if (pages.length > 1) {
+ uni.navigateBack()
+ }
+ else {
+ uni.reLaunch({
+ url: '/',
+ })
+ }
+ }, 1500)
+ return
}
- // ================= 子表 =================
+ // ================= 子表统一处理 =================
if (fileRes.success) {
- const files = (fileRes.data || []).map(file => ({
+ const allFiles = fileRes.data || []
+
+ const formatFile = file => ({
...file,
mx_mapfilename: buildPubicUrl(orgUrl, file.mx_mapfilename),
name: file.mx_filename,
url: buildPubicUrl(orgUrl, file.mx_mapfilename),
- }))
+ })
- subFileList.value = files
+ // 按分类拆分
+ subFileList.value = allFiles
+ .filter(f => f.mx_cate_id === '1')
+ .map(formatFile)
+
+ subFileList2.value = allFiles
+ .filter(f => f.mx_cate_id === '2')
+ .map(formatFile)
}
}
catch (err) {
@@ -150,48 +178,68 @@ async function handleConfirm() {
})
const fileInserts = []
+ const fileUpdates = []
- // 子表
- for (let index = 0; index < subFileList.value.length; index++) {
- const fileItem = subFileList.value[index]
+ const allFiles = [
+ ...subFileList.value.map(item => ({ ...item, cate: '1' })),
+ ...subFileList2.value.map(item => ({ ...item, cate: '2' })),
+ ]
- if (fileItem.subid) {
- // 已上传的文件,无需重复上传
- continue
- }
+ const grouped = allFiles.reduce((acc, item) => {
+ if (!acc[item.cate])
+ acc[item.cate] = []
+ acc[item.cate].push(item)
+ return acc
+ }, {})
- const res = await uploadContainerFileApi(fileItem.file.path, {
- jobId: form.value.b_id,
- containerNo: form.value.b_container_no,
- fileName: fileItem.name,
- })
+ for (const cate in grouped) {
+ let index = 1
- const maxIndexNumber = Math.max(
- 0,
- ...subFileList.value.map(item => item.mx_xh || 0),
- )
+ for (const fileItem of grouped[cate]) {
+ const mx_xh = index++
- if (res.success) {
- const indexNumber = maxIndexNumber + 1
+ // 已存在 → update
+ if (fileItem.subid) {
+ fileUpdates.push({
+ subid: fileItem.subid,
+ mx_xh,
+ mx_cate_id: cate,
+ })
+ continue
+ }
+
+ // 新增 → upload
+ const res = await uploadContainerFileApi(fileItem.file.path, {
+ jobId: form.value.b_id,
+ containerNo: form.value.b_container_no,
+ fileName: fileItem.name,
+ })
+
+ if (!res.success)
+ continue
fileInserts.push({
subid: res.data.uid,
father: form.value.b_id,
- mx_xh: indexNumber,
+ mx_xh,
mx_filename: res.data.fileName,
mx_filesize: fileItem.file.size,
mx_fileext: getFileExtension(fileItem.file.name),
mx_mapfilename: res.data.path,
mx_moduleid: 'b_container',
- mx_cate_id: '1',
+ mx_cate_id: cate,
})
fileItem.subid = res.data.uid
}
}
- if (fileInserts.length === 0) {
+ if (fileInserts.length === 0 && fileUpdates.length === 0) {
toast.success('保存成功')
+
+ setTimeout(() => {
+ loadMainData()
+ }, 1000)
return
}
@@ -200,7 +248,7 @@ async function handleConfirm() {
tableName: 'bf_file',
keyField: 'subid',
inserts: fileInserts,
- updates: [],
+ updates: fileUpdates,
deletes: [],
},
]
@@ -208,6 +256,10 @@ async function handleConfirm() {
saveObjectApi(reqData).then((res) => {
if (res.success) {
toast.success('保存成功')
+
+ setTimeout(() => {
+ loadMainData()
+ }, 1000)
}
})
}
@@ -225,6 +277,7 @@ function validateContainerNo(containerNo) {
return false
}
}
+const templateCollapse = ref(['template1'])
@@ -272,12 +325,62 @@ function validateContainerNo(containerNo) {
+
+
+
+
+
+
+
+
+ 1、提空箱拍照模版
+
+
+
+
+
+
+
+ 2、装箱拍照模版
+
+
+
+
+
+
+
+
- 其他图片
+ 装货照片
@@ -292,6 +395,27 @@ function validateContainerNo(containerNo) {
/>
+
+
+
+
+
+
+ 发货单、签收单、过磅单
+
+
+
+
+
+
+
+
+
+
+
+
+ 发货单、签收单、过磅单
+
+
+
+
+
+
+