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 - - - - {/* - - */} - - - - - - - - - - 登录即表示你同意我们的 - - 用户协议 - - 和 - - 隐私政策 - - - - - - ); -} 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 + + + + + + + + + + + + + + 登录即表示你同意我们的 + + 用户协议 + + 和 + + 隐私政策 + + + + + + ); +} 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'])