diff --git a/code/base-project/base-app/package.json b/code/base-project/base-app/package.json index 84b09590..a56f0ee8 100644 --- a/code/base-project/base-app/package.json +++ b/code/base-project/base-app/package.json @@ -19,6 +19,8 @@ "@react-native-segmented-control/segmented-control": "2.5.7", "alova": "^3.3.4", "axios": "^1.13.2", + "big.js": "^7.0.1", + "dayjs": "^1.11.19", "expo": "~54.0.20", "expo-blur": "~15.0.7", "expo-constants": "~18.0.10", @@ -32,16 +34,19 @@ "nativewind": "^4.2.1", "react": "19.1.0", "react-native": "0.81.5", + "react-native-calendars": "^1.1313.0", + "react-native-dates-picker": "^0.2.0", "react-native-gesture-handler": "~2.28.0", "react-native-reanimated": "~4.1.3", "react-native-safe-area-context": "~5.6.1", "react-native-screens": "~4.16.0", - "react-native-segmented-control-2": "^2.1.1", "react-native-svg": "15.12.0", + "react-native-ui-datepicker": "^3.1.2", "zustand": "^5.0.8" }, "devDependencies": { "@antfu/eslint-config": "^6.2.0", + "@types/big.js": "^6.2.2", "@types/react": "~19.1.0", "babel-plugin-module-resolver": "^5.0.2", "eslint": "^9.38.0", diff --git a/code/base-project/base-app/pnpm-lock.yaml b/code/base-project/base-app/pnpm-lock.yaml index c2266f2a..4a70f61d 100644 --- a/code/base-project/base-app/pnpm-lock.yaml +++ b/code/base-project/base-app/pnpm-lock.yaml @@ -35,6 +35,12 @@ importers: axios: specifier: ^1.13.2 version: 1.13.2 + big.js: + specifier: ^7.0.1 + version: 7.0.1 + dayjs: + specifier: ^1.11.19 + version: 1.11.19 expo: specifier: ~54.0.20 version: 54.0.21(@babel/core@7.28.5)(@expo/metro-runtime@6.1.2)(expo-router@6.0.14)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) @@ -74,6 +80,12 @@ importers: react-native: specifier: 0.81.5 version: 0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0) + react-native-calendars: + specifier: ^1.1313.0 + version: 1.1313.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + react-native-dates-picker: + specifier: ^0.2.0 + version: 0.2.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) react-native-gesture-handler: specifier: ~2.28.0 version: 2.28.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) @@ -86,12 +98,12 @@ importers: react-native-screens: specifier: ~4.16.0 version: 4.16.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) - react-native-segmented-control-2: - specifier: ^2.1.1 - version: 2.1.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) react-native-svg: specifier: 15.12.0 version: 15.12.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + react-native-ui-datepicker: + specifier: ^3.1.2 + version: 3.1.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) zustand: specifier: ^5.0.8 version: 5.0.8(@types/react@19.1.17)(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0)) @@ -99,6 +111,9 @@ importers: '@antfu/eslint-config': specifier: ^6.2.0 version: 6.2.0(@vue/compiler-sfc@3.5.22)(eslint@9.39.0(jiti@1.21.7))(typescript@5.9.3) + '@types/big.js': + specifier: ^6.2.2 + version: 6.2.2 '@types/react': specifier: ~19.1.0 version: 19.1.17 @@ -1997,6 +2012,9 @@ packages: '@types/babel__traverse@7.28.0': resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/big.js@6.2.2': + resolution: {integrity: sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==} + '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -2343,6 +2361,9 @@ packages: resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} engines: {node: '>=0.6'} + big.js@7.0.1: + resolution: {integrity: sha512-iFgV784tD8kq4ccF1xtNMZnXeZzVuXWWM+ERFzKQjv+A5G9HC8CY3DuV45vgzFFcW+u2tIvmF95+AzWgs6BjCg==} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -2605,6 +2626,9 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + dayjs@1.11.19: + resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -3543,6 +3567,9 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + 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} @@ -3719,48 +3746,56 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-gnu@1.30.2: resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.27.0: resolution: {integrity: sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-arm64-musl@1.30.2: resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.27.0: resolution: {integrity: sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-gnu@1.30.2: resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.27.0: resolution: {integrity: sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-linux-x64-musl@1.30.2: resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.27.0: resolution: {integrity: sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==} @@ -4191,6 +4226,9 @@ packages: mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -4523,6 +4561,9 @@ packages: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -4590,6 +4631,10 @@ packages: react-is@19.2.0: resolution: {integrity: sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==} + react-native-calendars@1.1313.0: + resolution: {integrity: sha512-YQ7Vg57rBRVymolamYDTxZ0lPOELTDHQbTukTWdxR47aRBYJwKI6ocRbwcY5gYgyDwNgJS4uLGu5AvmYS74LYQ==} + engines: {node: '>=18'} + react-native-css-interop@0.2.1: resolution: {integrity: sha512-B88f5rIymJXmy1sNC/MhTkb3xxBej1KkuAt7TiT9iM7oXz3RM8Bn+7GUrfR02TvSgKm4cg2XiSuLEKYfKwNsjA==} engines: {node: '>=18'} @@ -4606,6 +4651,13 @@ packages: react-native-svg: optional: true + react-native-dates-picker@0.2.0: + resolution: {integrity: sha512-dO7HGami3fhKa/WVtd5jj0xfekbNJZzka++4+0pBUW8br2/t9YzyJ7DYPcZ7vGdRy6bw/qkBG6EASRq8DJP/5Q==} + engines: {node: '>= 16.0.0'} + peerDependencies: + react: '>=17.0.0' + react-native: '*' + react-native-gesture-handler@2.28.0: resolution: {integrity: sha512-0msfJ1vRxXKVgTgvL+1ZOoYw3/0z1R+Ked0+udoJhyplC2jbVKIJ8Z1bzWdpQRCV3QcQ87Op0zJVE5DhKK2A0A==} peerDependencies: @@ -4634,6 +4686,12 @@ packages: react-native: '*' react-native-worklets: '>=0.5.0' + react-native-safe-area-context@4.5.0: + resolution: {integrity: sha512-0WORnk9SkREGUg2V7jHZbuN5x4vcxj/1B0QOcXJjdYWrzZHgLcUzYWWIUecUPJh747Mwjt/42RZDOaFn3L8kPQ==} + peerDependencies: + react: '*' + react-native: '*' + react-native-safe-area-context@5.6.1: resolution: {integrity: sha512-/wJE58HLEAkATzhhX1xSr+fostLsK8Q97EfpfMDKo8jlOc1QKESSX/FQrhk7HhQH/2uSaox4Y86sNaI02kteiA==} peerDependencies: @@ -4646,18 +4704,22 @@ packages: react: '*' react-native: '*' - react-native-segmented-control-2@2.1.1: - resolution: {integrity: sha512-qtDM4KhPMb/V3R6vVGWkhPVmUNLu+Vt+ypuYbsErFTCXLKMTmYfT+xH1rtvXn9cfzBM+lzjTiI5ij3hgs9/Tug==} - peerDependencies: - react: '>=17 || >=18' - react-native: '>=0.71' - react-native-svg@15.12.0: resolution: {integrity: sha512-iE25PxIJ6V0C6krReLquVw6R0QTsRTmEQc4K2Co3P6zsimU/jltcDBKYDy1h/5j9S/fqmMeXnpM+9LEWKJKI6A==} peerDependencies: react: '*' react-native: '*' + react-native-swipe-gestures@1.0.5: + resolution: {integrity: sha512-Ns7Bn9H/Tyw278+5SQx9oAblDZ7JixyzeOczcBK8dipQk2pD7Djkcfnf1nB/8RErAmMLL9iXgW0QHqiII8AhKw==} + + react-native-ui-datepicker@3.1.2: + resolution: {integrity: sha512-1yukCKMLUuVb5daYOgb4mLZqpynZ6GMQyNF2NPwpiDB5F2D/NGpeOmoYb7qFwDrTNwr+m4IemNUa0TlYIFktlg==} + engines: {node: '>= 18'} + peerDependencies: + react: '*' + react-native: '*' + react-native-web@0.21.2: resolution: {integrity: sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==} peerDependencies: @@ -4732,6 +4794,12 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + recyclerlistview@4.2.3: + resolution: {integrity: sha512-STR/wj/FyT8EMsBzzhZ1l2goYirMkIgfV3gYEPxI3Kf3lOnu6f7Dryhyw7/IkQrgX5xtTcDrZMqytvteH9rL3g==} + peerDependencies: + react: '>= 15.2.1' + react-native: '>= 0.30.0' + refa@0.12.1: resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -5061,6 +5129,9 @@ packages: tailwind-merge@1.14.0: resolution: {integrity: sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==} + tailwind-merge@3.4.0: + resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==} + tailwind-variants@0.1.20: resolution: {integrity: sha512-AMh7x313t/V+eTySKB0Dal08RHY7ggYK0MSn/ad8wKWOrDUIzyiWNayRUm2PIJ4VRkvRnfNuyRuKbLV3EN+ewQ==} engines: {node: '>=16.x', pnpm: '>=7.x'} @@ -5150,6 +5221,9 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-object-utils@0.0.5: + resolution: {integrity: sha512-iV0GvHqOmilbIKJsfyfJY9/dNHCs969z3so90dQWsO1eMMozvTpnB1MEaUbb3FYtZTGjv5sIy/xmslEz0Rg2TA==} + tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} @@ -5396,6 +5470,9 @@ packages: resolution: {integrity: sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==} engines: {node: '>=10.0.0'} + xdate@0.8.3: + resolution: {integrity: sha512-1NhJWPJwN+VjbkACT9XHbQK4o6exeSVtS2CxhMPwUE7xQakoEFTlwra9YcqV/uHQVyeEUYoYC46VGDJ+etnIiw==} + xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} @@ -8179,6 +8256,8 @@ snapshots: dependencies: '@babel/types': 7.28.5 + '@types/big.js@6.2.2': {} + '@types/debug@4.1.12': dependencies: '@types/ms': 2.1.0 @@ -8623,6 +8702,8 @@ snapshots: big-integer@1.6.52: {} + big.js@7.0.1: {} + binary-extensions@2.3.0: {} boolbase@1.0.0: {} @@ -8891,6 +8972,8 @@ snapshots: csstype@3.1.3: {} + dayjs@1.11.19: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -9885,6 +9968,8 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jalali-plugin-dayjs@1.1.4: {} + jest-environment-node@29.7.0: dependencies: '@jest/environment': 29.7.0 @@ -10913,6 +10998,9 @@ snapshots: pkg-types: 1.3.1 ufo: 1.6.1 + moment@2.30.1: + optional: true + ms@2.0.0: {} ms@2.1.3: {} @@ -11209,6 +11297,12 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + proxy-from-env@1.1.0: {} punycode@2.3.1: {} @@ -11313,6 +11407,22 @@ snapshots: react-is@19.2.0: {} + react-native-calendars@1.1313.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): + dependencies: + hoist-non-react-statics: 3.3.2 + lodash: 4.17.21 + memoize-one: 5.2.1 + prop-types: 15.8.1 + react-native-safe-area-context: 4.5.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + react-native-swipe-gestures: 1.0.5 + recyclerlistview: 4.2.3(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + xdate: 0.8.3 + optionalDependencies: + moment: 2.30.1 + transitivePeerDependencies: + - react + - react-native + react-native-css-interop@0.2.1(react-native-reanimated@4.1.3(@babel/core@7.28.5)(react-native-worklets@0.5.2(@babel/core@7.28.5)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-svg@15.12.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.18(yaml@2.8.1)): dependencies: '@babel/helper-module-imports': 7.27.1 @@ -11331,6 +11441,12 @@ snapshots: transitivePeerDependencies: - supports-color + react-native-dates-picker@0.2.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): + dependencies: + dayjs: 1.11.19 + react: 19.1.0 + react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0) + react-native-gesture-handler@2.28.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): dependencies: '@egjs/hammerjs': 2.0.17 @@ -11368,6 +11484,11 @@ snapshots: react-native-worklets: 0.5.2(@babel/core@7.28.5)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) semver: 7.7.2 + react-native-safe-area-context@4.5.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0) + react-native-safe-area-context@5.6.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): dependencies: react: 19.1.0 @@ -11381,11 +11502,6 @@ snapshots: react-native-is-edge-to-edge: 1.2.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) warn-once: 0.1.1 - react-native-segmented-control-2@2.1.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): - dependencies: - react: 19.1.0 - react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0) - react-native-svg@15.12.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): dependencies: css-select: 5.2.2 @@ -11394,6 +11510,18 @@ snapshots: react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0) warn-once: 0.1.1 + react-native-swipe-gestures@1.0.5: {} + + react-native-ui-datepicker@3.1.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): + dependencies: + clsx: 2.1.1 + dayjs: 1.11.19 + jalali-plugin-dayjs: 1.1.4 + lodash: 4.17.21 + react: 19.1.0 + react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0) + tailwind-merge: 3.4.0 + react-native-web@0.21.2(react-dom@19.2.0(react@19.1.0))(react@19.1.0): dependencies: '@babel/runtime': 7.28.4 @@ -11544,6 +11672,14 @@ snapshots: dependencies: picomatch: 2.3.1 + recyclerlistview@4.2.3(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): + dependencies: + lodash.debounce: 4.0.8 + prop-types: 15.8.1 + react: 19.1.0 + react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0) + ts-object-utils: 0.0.5 + refa@0.12.1: dependencies: '@eslint-community/regexpp': 4.12.2 @@ -11849,6 +11985,8 @@ snapshots: tailwind-merge@1.14.0: {} + tailwind-merge@3.4.0: {} + tailwind-variants@0.1.20(tailwindcss@3.4.18(yaml@2.8.1)): dependencies: tailwind-merge: 1.14.0 @@ -11959,6 +12097,8 @@ snapshots: ts-interface-checker@0.1.13: {} + ts-object-utils@0.0.5: {} + tslib@1.14.1: {} tslib@2.8.1: {} @@ -12154,6 +12294,8 @@ snapshots: simple-plist: 1.3.1 uuid: 7.0.3 + xdate@0.8.3: {} + xml-name-validator@4.0.0: {} xml2js@0.4.23: diff --git a/code/base-project/base-app/src/app/(tabs)/chat.tsx b/code/base-project/base-app/src/app/(tabs)/chat.tsx index 06f9c76d..c0d9520e 100644 --- a/code/base-project/base-app/src/app/(tabs)/chat.tsx +++ b/code/base-project/base-app/src/app/(tabs)/chat.tsx @@ -1,28 +1,19 @@ -import { ScrollView, Text } from 'react-native' -import { AButton } from '@/components/common/ao' -import { useUserStore } from '@/store/user' +import type { DateType } from 'react-native-ui-datepicker' +import { useState } from 'react' +import DateTimePicker, { useDefaultStyles } from 'react-native-ui-datepicker' -export default function Chat() { - const userStore = useUserStore() +export default function Calendar() { + const defaultStyles = useDefaultStyles() + const [selected, setSelected] = useState() return ( - - { - userStore.setUserInfo({ - ...(userStore.userInfo as any), - token: `test-token-${Date.now()}`, - }) - }} - > - 测试 - - - - 当前 token: - {' '} - {userStore.userInfo?.token ?? '(无)'} - - + setSelected(date)} + styles={defaultStyles} + className="mt-22" + /> ) } + \ No newline at end of file diff --git a/code/base-project/base-app/src/app/(tabs)/components/LocaleSelector.tsx b/code/base-project/base-app/src/app/(tabs)/components/LocaleSelector.tsx new file mode 100644 index 00000000..d3e51d1e --- /dev/null +++ b/code/base-project/base-app/src/app/(tabs)/components/LocaleSelector.tsx @@ -0,0 +1,68 @@ +import { Pressable, StyleSheet, Text, View } from 'react-native' + +const Locales = ['zh-cn', 'en', 'de', 'es'] + +interface Props { + locale: string + setLocale: (locale: string) => void + mainColor?: string + activeTextColor?: string +} + +export default function LocaleSelector({ + locale, + setLocale, + mainColor, + activeTextColor, +}: Props) { + return ( + + Locale: + {Locales.map((item, index) => ( + setLocale(item)} + accessibilityRole="button" + accessibilityLabel={item.toUpperCase()} + > + + {item.split('-')[0]?.toUpperCase()} + + + ))} + + ) +} + +const styles = StyleSheet.create({ + localeContainer: { + flexDirection: 'row', + alignItems: 'center', + marginBottom: 20, + }, + localeButton: { + alignItems: 'center', + justifyContent: 'center', + width: 36, + height: 36, + borderRadius: 36, + margin: 2, + }, + localeButtonText: { + fontSize: 15, + }, +}) diff --git a/code/base-project/base-app/src/app/(tabs)/components/ThemeSelector.tsx b/code/base-project/base-app/src/app/(tabs)/components/ThemeSelector.tsx new file mode 100644 index 00000000..30fe6c9a --- /dev/null +++ b/code/base-project/base-app/src/app/(tabs)/components/ThemeSelector.tsx @@ -0,0 +1,54 @@ +import { Pressable, StyleSheet, View } from 'react-native' + +export interface ITheme { + mainColor: string + activeTextColor: string +} + +interface Props { + themes: ITheme[] + setTheme: (theme: ITheme) => void +} + +export default function ThemeSelector({ themes = [], setTheme }: Props) { + return ( + + {themes.map((item, index) => ( + setTheme(item)} + accessibilityRole="button" + accessibilityLabel="Set Active Theme" + /> + ))} + + ) +} + +const styles = StyleSheet.create({ + themeContainer: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-around', + marginBottom: 10, + width: 330, + }, + themeButton: { + borderWidth: 4, + width: 32, + height: 32, + borderRadius: 32, + margin: 5, + shadowRadius: 20, + shadowColor: '#000', + shadowOpacity: 0.1, + shadowOffset: { width: 0, height: 0 }, + }, +}) diff --git a/code/base-project/base-app/src/app/(tabs)/money/components/AddDrawer.tsx b/code/base-project/base-app/src/app/(tabs)/money/components/AddDrawer.tsx index c21c1d2d..d8c1b69c 100644 --- a/code/base-project/base-app/src/app/(tabs)/money/components/AddDrawer.tsx +++ b/code/base-project/base-app/src/app/(tabs)/money/components/AddDrawer.tsx @@ -1,17 +1,17 @@ import type { MoneyCategoryResult } from '@/request/api/money' import type { MoneyCategory } from '@/types/money' -import { DeleteIcon } from 'lucide-react-native' +import Big from 'big.js' +import dayjs from 'dayjs' import { useEffect, useState } from 'react' -import { Pressable, Text, View } from 'react-native' +import { Pressable, StyleSheet, Text, View } from 'react-native' import { useSafeAreaInsets } from 'react-native-safe-area-context' -import { AInput } from '@/components/common/ao' +import { AInput, LucideIcon } from '@/components/common/ao' import SegmentedTabs from '@/components/common/ao/SegmentedTabs' import { Drawer, DrawerBackdrop, DrawerBody, DrawerContent, - DrawerFooter, DrawerHeader, } from '@/components/ui/drawer' import { Grid, GridItem } from '@/components/ui/grid' @@ -31,24 +31,24 @@ const keys: KeydownItem[] = [ { key: '1', content: 1 }, { key: '2', content: 2 }, { key: '3', content: 3 }, - { key: 'del', content: }, + { key: 'del', content: }, { key: '4', content: 4 }, { key: '5', content: 5 }, { key: '6', content: 6 }, - { key: '+', content: + }, + { key: '+', content: }, { key: '7', content: 7 }, { key: '8', content: 8 }, { key: '9', content: 9 }, - { key: '-', content: - }, - { key: 'clear', content: ( + { key: '-', content: }, + { key: 'repeat', content: ( - AC + 再记 ) }, { key: '0', content: 0 }, - { key: '.', content: . }, + { key: '.', content: }, { key: '/', content: ( - + 完成 ) }, @@ -62,6 +62,9 @@ export default function AddMoneyDrawer({ const [selectedIndex, setSelectedIndex] = useState(0) const [selectedCategoryId, setSelectedCategoryId] = useState(null) const [showKeydown, setShowKeydown] = useState(false) + const [keydownInput, setKeydownInput] = useState('') + const [result, setResult] = useState('0') + const [date, setDate] = useState(dayjs()) const [categories, setCategories] = useState({ income: [], @@ -79,7 +82,7 @@ export default function AddMoneyDrawer({ try { const res = await getMoneyCategoryApi() if (res.isSuccess) { - setCategories(res.data) + // setCategories(res.data) } } catch (err) { @@ -90,17 +93,161 @@ export default function AddMoneyDrawer({ } }, [isOpen]) - const handlePress = (key: string | number, idx: number) => { - console.log('点击了格子 key:', key, '索引:', idx) + function onMainDrawerClose() { + setShowKeydown(false) + onClose() } + const handlePress = (key: string | number) => { + setKeydownInput((prev) => { + let newInput = prev + + if (key === 'del') { + newInput = prev.slice(0, -1) + } + else if (key === '/') { + // 完成操作,可以在这里提交或关闭键盘 + return prev + } + else { + const keyStr = key.toString() + + // 检查是否要输入运算符(+ 或 -) + if (keyStr === '+' || keyStr === '-') { + // 获取最后一个字符 + const lastChar = prev.slice(-1) + + // 如果最后一个字符已经是运算符,则替换而不是追加 + if (lastChar === '+' || lastChar === '-') { + newInput = prev.slice(0, -1) + keyStr + } + else { + newInput = prev + keyStr + } + } + // 检查是否要输入小数点(.) + else if (keyStr === '.') { + // 检查当前数字是否已经包含小数点 + const parts = prev.split(/[+-]/) + const currentNumber = parts[parts.length - 1] + + // 如果当前数字中还没有小数点,可以添加 + if (!currentNumber.includes('.')) { + // 检查当前数字的小数位数(应该是0,因为还没有小数点) + if (currentNumber === '' || /[+-]/.test(prev.slice(-1))) { + newInput = `${prev}0.` + } + else { + newInput = `${prev}.` + } + } + else { + // 已经有小数点了,不重复添加 + newInput = prev + } + } + // 处理数字输入 + else if (/^\d$/.test(keyStr)) { + // 检查当前数字的小数位数 + const parts = prev.split(/[+-]/) + const currentNumber = parts[parts.length - 1] + + // 如果当前数字包含小数点,检查小数位数 + if (currentNumber.includes('.')) { + const decimalParts = currentNumber.split('.') + // 如果小数部分已经达到2位,不允许继续输入 + if (decimalParts.length > 1 && decimalParts[1].length >= 2) { + newInput = prev // 不改变输入 + } + else { + newInput = prev + keyStr + } + } + else { + // 没有小数点,正常输入数字 + newInput = prev + keyStr + } + } + else { + // 对于其他字符,正常追加 + newInput = prev + keyStr + } + } + + // 计算结果 + try { + const computed = calculateWithBig(newInput) + setResult(computed) + } + catch (e) { + setResult('0') + } + + return newInput + }) + } + + function calculateWithBig(expression: string): string { + if (!expression.trim()) + return '0' + + // 移除表达式末尾的运算符(+或-),避免不完整的表达式 + let cleanExpression = expression.trim() + const lastChar = cleanExpression.slice(-1) + if (lastChar === '+' || lastChar === '-') { + cleanExpression = cleanExpression.slice(0, -1) + } + + if (!cleanExpression) + return '0' + + try { + // 使用更智能的解析方式,支持基本的加减运算 + const numbers = cleanExpression.split(/[+-]/).filter(Boolean) + const operators = cleanExpression.split(/[^+-]/).filter(Boolean) + + if (numbers.length === 0) + return '0' + + let result = new Big(numbers[0]) + + for (let i = 0; i < operators.length; i++) { + const operator = operators[i] + const nextNumber = new Big(numbers[i + 1]) + + if (operator === '+') { + result = result.plus(nextNumber) + } + else if (operator === '-') { + result = result.minus(nextNumber) + } + } + + // 限制结果为最多两位小数 + return result.toFixed(2) + } + catch (error) { + // 如果解析失败,尝试只计算数字部分 + const tokens = expression.match(/[+-]?\d+(\.\d+)?/g) + if (!tokens || tokens.length === 0) + return '0' + + let total = new Big(0) + tokens.forEach((token) => { + total = total.plus(new Big(token)) + }) + + // 限制结果为最多两位小数 + return total.toFixed(2) + } + } return ( <> @@ -116,7 +263,7 @@ export default function AddMoneyDrawer({ style={{ width: 180 }} className="mx-auto" /> - + 取消 @@ -167,6 +314,7 @@ export default function AddMoneyDrawer({ isOpen={showKeydown} size="md" anchor="bottom" + onClose={() => setShowKeydown(false)} > - 0.00 + + + + 2024/11/05 + + + {result} + + + + {keydownInput} + + handlePress(item.key, idx)} + onPress={() => handlePress(item.key)} style={{ width: '25%', height: '25%', @@ -213,7 +375,22 @@ export default function AddMoneyDrawer({ borderColor: '#ddd', }} > - {item.content} + {({ pressed }) => { + const defaultBg = item.key === '/' ? '#e6d7b8' : '#fff' + const pressedBg = item.key === '/' ? '#f5e9d4' : '#f2f2f2' + + return ( + <> + + {item.content} + + ) + }} ) })} @@ -223,6 +400,7 @@ export default function AddMoneyDrawer({ + ) } diff --git a/code/base-project/base-app/src/components/common/ao/LucideIcon.tsx b/code/base-project/base-app/src/components/common/ao/LucideIcon.tsx index 509f85d4..dab815ea 100644 --- a/code/base-project/base-app/src/components/common/ao/LucideIcon.tsx +++ b/code/base-project/base-app/src/components/common/ao/LucideIcon.tsx @@ -10,6 +10,7 @@ interface LucideIconProps { strokeWidth?: number onPress?: (event: GestureResponderEvent) => void style?: ViewStyle + clickable?: boolean // 新增参数,是否可点击,默认 true } export default function LucideIcon({ @@ -19,12 +20,18 @@ export default function LucideIcon({ strokeWidth = 2, onPress, style, + clickable = true, }: LucideIconProps) { const IconComponent = icons[icon] if (!IconComponent) return null + if (!clickable) { + return + } + + // clickable 为 true,包 Pressable return ( diff --git a/code/base-project/base-app/src/request/api/money.ts b/code/base-project/base-app/src/request/api/money.ts index 35303f70..c785b0aa 100644 --- a/code/base-project/base-app/src/request/api/money.ts +++ b/code/base-project/base-app/src/request/api/money.ts @@ -11,3 +11,34 @@ export interface MoneyCategoryResult { export function getMoneyCategoryApi() { return alovaInstance.Get>(`${API_PREFIX}/category`) } + +interface InsertMoneyRecordParams { + category_id: number + amount: string + record_time: string + remark: string +} + +export function insertMoneyRecordApi(params: InsertMoneyRecordParams) { + return alovaInstance.Post>(`${API_PREFIX}/insert`, params) +} + +interface UpdateMoneyRecordParams { + id: number + category_id: number + amount: string + record_time: string + remark: string +} + +export function updateMoneyRecordApi(params: UpdateMoneyRecordParams) { + return alovaInstance.Post>(`${API_PREFIX}/update`, params) +} + +interface DeleteMoneyRecordParams { + id: number +} + +export function deleteMoneyRecordApi(params: DeleteMoneyRecordParams) { + return alovaInstance.Post>(`${API_PREFIX}/delete`, params) +} diff --git a/code/base-project/base-app/src/request/index.ts b/code/base-project/base-app/src/request/index.ts index 91ba317c..6c068bd8 100644 --- a/code/base-project/base-app/src/request/index.ts +++ b/code/base-project/base-app/src/request/index.ts @@ -30,11 +30,11 @@ function isWhiteListed(url: string) { } const alovaInstance = createAlova({ - baseURL: 'http://192.168.5.6:8085/app', - // baseURL: 'http://192.168.1.136:8085/app', + // baseURL: 'http://192.168.5.6:8085/app', + baseURL: 'http://192.168.1.136:8085/app', requestAdapter: axiosRequestAdapter(), timeout: 5000, - cacheLogger: false, + cacheFor: null, responded: { onSuccess: async (response, method: Method) => { const resData = response.data as ResponseData @@ -154,7 +154,6 @@ const alovaInstance = createAlova({ return Promise.reject(new Error('未登录')) } - method.config.cacheFor = 0 method.config.headers.token = useUserStore.getState().userInfo?.token ?? '' }, }) diff --git a/code/base-project/base-app/src/types/money.ts b/code/base-project/base-app/src/types/money.ts index 12654356..0d300300 100644 --- a/code/base-project/base-app/src/types/money.ts +++ b/code/base-project/base-app/src/types/money.ts @@ -6,3 +6,13 @@ export interface MoneyCategory { sort_number: number type: number } + +export interface MoneyRecord { + id: number + category_id: number + user_id: number + amount: string + remark: string + record_time: string + create_time: string +} diff --git a/code/base-project/base-go-v2/go.mod b/code/base-project/base-go-v2/go.mod index dcbbb701..b615497e 100644 --- a/code/base-project/base-go-v2/go.mod +++ b/code/base-project/base-go-v2/go.mod @@ -21,6 +21,7 @@ require ( github.com/klauspost/compress v1.18.1 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/sagikazarmark/locafero v0.12.0 // indirect + github.com/shopspring/decimal v1.4.0 // indirect github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect github.com/spf13/afero v1.15.0 // indirect github.com/spf13/cast v1.10.0 // indirect diff --git a/code/base-project/base-go-v2/go.sum b/code/base-project/base-go-v2/go.sum index 1577e5fb..9d3fbb25 100644 --- a/code/base-project/base-go-v2/go.sum +++ b/code/base-project/base-go-v2/go.sum @@ -27,6 +27,8 @@ github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDc github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4= github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= diff --git a/code/base-project/base-go-v2/internal/api/money/index.go b/code/base-project/base-go-v2/internal/api/money/index.go index 2ef0fdae..20abb1da 100644 --- a/code/base-project/base-go-v2/internal/api/money/index.go +++ b/code/base-project/base-go-v2/internal/api/money/index.go @@ -7,12 +7,15 @@ import ( "base-go-v2/internal/utils/idgen" "base-go-v2/internal/utils/mapx" "fmt" + "github.com/shopspring/decimal" ) func InitMoneyRouter(r *router.Router) { group := r.Group("money") group.GET("/category", getUserCategory) - //group := r.Group("auth") + group.POST("/insert", insertMoneyRecord) + group.POST("/update", updateMoneyRecord) + group.POST("/delete", deleteMoneyRecord) } // InitDefaultCategories 初始化系统默认分类到用户分类表 @@ -54,7 +57,6 @@ func InitDefaultCategories(userID int64) error { } func getUserCategory(c *router.Context) error { - fmt.Println("请求进入了====") userId := c.GetUserID() // 查询当前用户的分类 @@ -80,3 +82,110 @@ func getUserCategory(c *router.Context) error { return response.Success(c).Data(result).Send() } + +func insertMoneyRecord(c *router.Context) error { + bodyData, err := c.GetBodyWithRequired("category_id", "amount", "record_time") + if err != nil { + return c.AddError(err) + } + + categoryId := bodyData.GetInt64("category_id") + recordTime := bodyData.GetString("record_time") + amountStr := bodyData.GetString("amount") + remark := bodyData.GetString("remark") + + amountDecimal, err := decimal.NewFromString(amountStr) + if err != nil { + return c.AddError(err) + } + + newRecord := mapx.New().SetKV("id", idgen.NextId(), + "category_id", categoryId, + "user_id", c.GetUserID(), + "amount", amountDecimal, + "remark", remark, + "record_time", recordTime, + ) + + insertOne, err := db.InsertOne("money_record", newRecord) + if err != nil { + return response.Fail(c).Message("新增失败").Send() + } + if insertOne != 1 { + return response.Fail(c).Message("新增失败").Send() + } + + return response.Success(c).Data(newRecord).Message("新增成功").Send() +} + +func updateMoneyRecord(c *router.Context) error { + bodyData, err := c.GetBodyWithRequired("id") + if err != nil { + return c.AddError(err) + } + + recordId := bodyData.GetInt64("id") + + record, err := db.GetOne("money_record", "id", recordId) + if err != nil { + return c.AddError(err) + } + if record == nil { + return response.Fail(c).Message("该条账单不存在").Send() + } + + categoryId := bodyData.GetInt64("category_id") + recordTime := bodyData.GetString("record_time") + amountStr := bodyData.GetString("amount") + remark := bodyData.GetString("remark") + + updateRecord := mapx.New().SetKV("id", recordId) + + if record.GetInt64("category_id") != categoryId { + updateRecord.SetKV("category_id", categoryId) + } + + if record.GetString("record_time") != recordTime { + updateRecord.SetKV("record_time", recordTime) + } + + if record.GetString("amount") != amountStr { + amountDecimal, err := decimal.NewFromString(amountStr) + if err != nil { + return c.AddError(err) + } + updateRecord.SetKV("amount", amountDecimal) + } + + if record.GetString("remark") != remark { + updateRecord.SetKV("remark", remark) + } + + updateOne, err := db.UpdateOne("money_record", "id", recordId, updateRecord) + if err != nil { + return c.AddError(err) + } + if updateOne != 1 { + return response.Fail(c).Message("更新失败").Send() + } + + return response.Success(c).Message("更新成功").Send() +} + +func deleteMoneyRecord(c *router.Context) error { + bodyData, err := c.GetBodyWithRequired("id") + if err != nil { + return c.AddError(err) + } + recordId := bodyData.GetInt64("id") + + deleteOne, err := db.DeleteOne("money_record", "id", recordId) + if err != nil { + return c.AddError(err) + } + if deleteOne != 1 { + return response.Fail(c).Message("删除失败").Send() + } + + return response.Success(c).Message("删除成功").Send() +}