commit c7a55d14da316509ae93fd57f770ccad926c17d9 Author: BJ-HPC3\13478 <13478707150@163.com> Date: Tue Jul 8 10:49:22 2025 +0800 initial commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5760be5 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..0a4b789 --- /dev/null +++ b/.env.development @@ -0,0 +1,2 @@ +# 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config +# TARO_APP_ID="开发环境下的小程序 AppID" diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..eb3c3a1 --- /dev/null +++ b/.env.production @@ -0,0 +1 @@ +# TARO_APP_ID="生产环境下的小程序 AppID" diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..194e829 --- /dev/null +++ b/.env.test @@ -0,0 +1 @@ +# TARO_APP_ID="测试环境下的小程序 AppID" diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..7809e66 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,7 @@ +{ + "extends": ["taro/react"], + "rules": { + "react/jsx-uses-react": "off", + "react/react-in-jsx-scope": "off" + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bc64557 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +dist/ +deploy_versions/ +.temp/ +.rn_temp/ +node_modules/ +.DS_Store +.swc +*.local diff --git a/README.md b/README.md new file mode 100644 index 0000000..0425aed --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +# jf_202506 + +#### 介绍 +202506小程序交付 + +#### 软件架构 +taro react + +### 依赖工具 ++ **开发框架**:[tarojs@4.1.2](https://docs.taro.zone/docs/) ++ **基础架构**:[react@18.0](https://reactjs.org/) ++ **ui框架**:[antd-mobile@5.39](https://mobile.ant.design/zh) + +### 项目启动 +1. node > ver.18 +2. 安装yarn@1.22.19,执行`yarn install` +3. 执行`npm run dev:h5`,本地启动 +4. 执行`npm run build:h5`,打包编译 + +### 项目部署 + +1. 本地构建 + + ```bash + // 1. git 操作拉取项目,此处省略... + // 2. 进入到项目根目录 + yarn install + // 3. 编译构建 + npm run build:h5 + ``` + +2. 登录宝塔平台 + +3. 网站/HTML项目 下 添加HTML项目 + + ![image-20250708103317051](.\docs\image-20250708103317051.png) + +4. 修改nginx配置文件 + + ![image-20250708103453330](.\docs\image-20250708103453330.png) + + ```nginx + location ^~/api { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header REMOTE-HOST $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_http_version 1.1; + proxy_set_header Connection ''; + + proxy_buffering off; + proxy_cache off; + + proxy_read_timeout 86400s; + send_timeout 86400s; + + client_max_body_size 50m; + + # 这里改成 [对应的域名 + /api] + proxy_pass https://he.lehuonianhua.com/api; + } + ``` + + + +5. 上传生产包 + + ![image-20250708104053513](.\docs\image-20250708104053513.png) + +6. 重启nginx + + ![image-20250708104244826](.\docs\image-20250708104244826.png) + + + + +## 讨论 +联系人:jinech 13478707150@163.com diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..07abcca --- /dev/null +++ b/babel.config.js @@ -0,0 +1,12 @@ +// babel-preset-taro 更多选项和默认值: +// https://docs.taro.zone/docs/next/babel-config +module.exports = { + presets: [ + ['taro', { + framework: 'react', + ts: false, + compiler: 'vite', + useBuiltIns: process.env.TARO_ENV === 'h5' ? 'usage' : false + }] + ] +} diff --git a/config/dev.js b/config/dev.js new file mode 100644 index 0000000..66084a9 --- /dev/null +++ b/config/dev.js @@ -0,0 +1,16 @@ + + +export default { + + mini: {}, + h5: { + devServer: { + proxy: { + '/api/Open': { + target: 'https://he.lehuonianhua.com', + changeOrigin: true, + }, + } + } + } +} diff --git a/config/index.js b/config/index.js new file mode 100644 index 0000000..490f349 --- /dev/null +++ b/config/index.js @@ -0,0 +1,89 @@ +import { defineConfig } from '@tarojs/cli' + +import devConfig from './dev' +import prodConfig from './prod' + +// https://taro-docs.jd.com/docs/next/config#defineconfig-辅助函数 +export default defineConfig(async (merge, { command, mode }) => { + const baseConfig = { + projectName: 'jf_20250608', + date: '2025-6-8', + designWidth: 750, + deviceRatio: { + 640: 2.34 / 2, + 750: 1, + 375: 2, + 828: 1.81 / 2 + }, + sourceRoot: 'src', + outputRoot: 'dist', + plugins: [], + defineConstants: { + }, + copy: { + patterns: [ + ], + options: { + } + }, + framework: 'react', + compiler: 'vite', + mini: { + postcss: { + pxtransform: { + enable: true, + config: { + + } + }, + cssModules: { + enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true + config: { + namingPattern: 'module', // 转换模式,取值为 global/module + generateScopedName: '[name]__[local]___[hash:base64:5]' + } + } + }, + }, + h5: { + publicPath: '/', + staticDirectory: 'static', + + miniCssExtractPluginOption: { + ignoreOrder: true, + filename: 'css/[name].[hash].css', + chunkFilename: 'css/[name].[chunkhash].css' + }, + postcss: { + autoprefixer: { + enable: true, + config: {} + }, + cssModules: { + enable: true, // 默认为 false,如需使用 css modules 功能,则设为 true + config: { + namingPattern: 'module', // 转换模式,取值为 global/module + generateScopedName: '[name]__[local]___[hash:base64:5]' + } + } + } + }, + rn: { + appName: 'taroDemo', + postcss: { + cssModules: { + enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true + } + } + } + } + + process.env.BROWSERSLIST_ENV = process.env.NODE_ENV + + if (process.env.NODE_ENV === 'development') { + // 本地开发构建配置(不混淆压缩) + return merge({}, baseConfig, devConfig) + } + // 生产构建配置(默认开启压缩混淆等) + return merge({}, baseConfig, prodConfig) +}) diff --git a/config/prod.js b/config/prod.js new file mode 100644 index 0000000..e7e470f --- /dev/null +++ b/config/prod.js @@ -0,0 +1,37 @@ + + +export default { + mini: {}, + h5: { + // publicPath: '/ryc/', + // staticDirectory: './ryc/static' + // 确保产物为 es5 + // legacy: true, + /** + * WebpackChain 插件配置 + * @docs https://github.com/neutrinojs/webpack-chain + */ + // webpackChain (chain) { + // /** + // * 如果 h5 端编译后体积过大,可以使用 webpack-bundle-analyzer 插件对打包体积进行分析。 + // * @docs https://github.com/webpack-contrib/webpack-bundle-analyzer + // */ + // chain.plugin('analyzer') + // .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, []) + // /** + // * 如果 h5 端首屏加载时间过长,可以使用 prerender-spa-plugin 插件预加载首页。 + // * @docs https://github.com/chrisvfritz/prerender-spa-plugin + // */ + // const path = require('path') + // const Prerender = require('prerender-spa-plugin') + // const staticDir = path.join(__dirname, '..', 'dist') + // chain + // .plugin('prerender') + // .use(new Prerender({ + // staticDir, + // routes: [ '/pages/index/index' ], + // postProcess: (context) => ({ ...context, outputPath: path.join(staticDir, 'index.html') }) + // })) + // } + } +} diff --git a/docs/image-20250708103317051.png b/docs/image-20250708103317051.png new file mode 100644 index 0000000..f43ad96 Binary files /dev/null and b/docs/image-20250708103317051.png differ diff --git a/docs/image-20250708103453330.png b/docs/image-20250708103453330.png new file mode 100644 index 0000000..31e2ce8 Binary files /dev/null and b/docs/image-20250708103453330.png differ diff --git a/docs/image-20250708104053513.png b/docs/image-20250708104053513.png new file mode 100644 index 0000000..fbae0ca Binary files /dev/null and b/docs/image-20250708104053513.png differ diff --git a/docs/image-20250708104244826.png b/docs/image-20250708104244826.png new file mode 100644 index 0000000..74f9580 Binary files /dev/null and b/docs/image-20250708104244826.png differ diff --git a/package.json b/package.json new file mode 100644 index 0000000..f854d0b --- /dev/null +++ b/package.json @@ -0,0 +1,93 @@ +{ + "name": "jf_20250608", + "version": "1.0.0", + "private": true, + "description": "", + "templateInfo": { + "name": "default", + "typescript": false, + "css": "Less", + "framework": "React" + }, + "scripts": { + "build:weapp": "taro build --type weapp", + "build:swan": "taro build --type swan", + "build:alipay": "taro build --type alipay", + "build:tt": "taro build --type tt", + "build:h5": "taro build --type h5", + "build:rn": "taro build --type rn", + "build:qq": "taro build --type qq", + "build:jd": "taro build --type jd", + "build:harmony-hybrid": "taro build --type harmony-hybrid", + "dev:weapp": "npm run build:weapp -- --watch", + "dev:swan": "npm run build:swan -- --watch", + "dev:alipay": "npm run build:alipay -- --watch", + "dev:tt": "npm run build:tt -- --watch", + "dev:h5": "npm run build:h5 -- --watch", + "dev:rn": "npm run build:rn -- --watch", + "dev:qq": "npm run build:qq -- --watch", + "dev:jd": "npm run build:jd -- --watch", + "dev:harmony-hybrid": "npm run build:harmony-hybrid -- --watch" + }, + "browserslist": { + "development": [ + "defaults and fully supports es6-module", + "maintained node versions" + ], + "production": [ + "last 3 versions", + "Android >= 4.1", + "ios >= 8" + ] + }, + "author": "", + "dependencies": { + "@babel/runtime": "^7.24.4", + "@tarojs/components": "4.1.2", + "@tarojs/helper": "4.1.2", + "@tarojs/plugin-framework-react": "4.1.2", + "@tarojs/plugin-platform-alipay": "4.1.2", + "@tarojs/plugin-platform-h5": "4.1.2", + "@tarojs/plugin-platform-harmony-hybrid": "4.1.2", + "@tarojs/plugin-platform-jd": "4.1.2", + "@tarojs/plugin-platform-qq": "4.1.2", + "@tarojs/plugin-platform-swan": "4.1.2", + "@tarojs/plugin-platform-tt": "4.1.2", + "@tarojs/plugin-platform-weapp": "4.1.2", + "@tarojs/react": "4.1.2", + "@tarojs/runtime": "4.1.2", + "@tarojs/shared": "4.1.2", + "@tarojs/taro": "4.1.2", + "ahooks": "^3.8.5", + "antd-mobile": "^5.39.0", + "axios": "^1.10.0", + "classnames": "^2.5.1", + "lodash": "^4.17.21", + "md5": "^2.3.0", + "qrcode.react": "^4.2.0", + "react": "^18.0.0", + "react-copy-to-clipboard": "^5.1.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@babel/core": "^7.24.4", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/plugin-transform-class-properties": "7.25.9", + "@babel/preset-react": "^7.24.1", + "@tarojs/cli": "4.1.2", + "@tarojs/vite-runner": "4.1.2", + "@types/react": "^18.0.0", + "@vitejs/plugin-react": "^4.3.0", + "babel-preset-taro": "4.1.2", + "eslint": "^8.57.0", + "eslint-config-taro": "4.1.2", + "eslint-plugin-react": "^7.34.1", + "eslint-plugin-react-hooks": "^4.4.0", + "less": "^4.2.0", + "postcss": "^8.4.38", + "react-refresh": "^0.14.0", + "stylelint": "^16.4.0", + "terser": "^5.30.4", + "vite": "^4.2.0" + } +} diff --git a/project.config.json b/project.config.json new file mode 100644 index 0000000..a4e2df1 --- /dev/null +++ b/project.config.json @@ -0,0 +1,15 @@ +{ + "miniprogramRoot": "./dist", + "projectname": "jf_20250608", + "description": "", + "appid": "touristappid", + "setting": { + "urlCheck": true, + "es6": false, + "enhance": false, + "compileHotReLoad": false, + "postcss": false, + "minified": false + }, + "compileType": "miniprogram" +} diff --git a/src/app.config.js b/src/app.config.js new file mode 100644 index 0000000..83f182e --- /dev/null +++ b/src/app.config.js @@ -0,0 +1,56 @@ +export default defineAppConfig({ + pages: [ + 'pages/index/index', + 'pages/dataset/index', + 'pages/mine/index', + 'pages/login/index', + 'pages/forget/index', + 'pages/payforget/index', + 'pages/register/index', + 'pages/shopinfo/index', + 'pages/team/index', + 'pages/invite/index', + 'pages/paymentmethod/index', + 'pages/funds/index', + 'pages/safe/index', + 'pages/feedback/index', + 'pages/myfeedback/index', + 'pages/notice/index', + 'pages/notice-detail/index', + 'pages/viplevelup/index', + 'pages/sitemessage/index', + 'pages/payconfirm/index', + 'pages/feeconfirm/index', + ], + window: { + backgroundTextStyle: 'light', + navigationBarBackgroundColor: '#fff', + navigationBarTitleText: 'WeChat', + navigationBarTextStyle: 'black' + }, + tabBar: { + color: '#7A7E83', + selectedColor: '#007AFF', + backgroundColor: '#FAFAFA', + list: [ + { + pagePath: 'pages/index/index', + text: '首页', + iconPath: 'assets/icons/home.png', + selectedIconPath: 'assets/icons/home-active.png' + }, + { + pagePath: 'pages/dataset/index', + text: '数据优化', + iconPath: 'assets/icons/dataset.png', + selectedIconPath: 'assets/icons/dataset-active.png' + }, + { + pagePath: 'pages/mine/index', + text: '我的', + iconPath: 'assets/icons/mine.png', + selectedIconPath: 'assets/icons/mine-active.png' + } + ] + } +}) diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..98d40b3 --- /dev/null +++ b/src/app.js @@ -0,0 +1,15 @@ + +import { useLaunch } from '@tarojs/taro'; + +import './app.less'; + +function App({ children }) { + useLaunch(() => { + console.log('App launched.') + }); + + // children 是将要会渲染的页面 + return children; +} + +export default App; diff --git a/src/app.less b/src/app.less new file mode 100644 index 0000000..398ef7a --- /dev/null +++ b/src/app.less @@ -0,0 +1,3 @@ +:root { + --color-primary: #007AFF; +} diff --git a/src/assets/icons/ali.svg b/src/assets/icons/ali.svg new file mode 100644 index 0000000..6792bf8 --- /dev/null +++ b/src/assets/icons/ali.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/bank.svg b/src/assets/icons/bank.svg new file mode 100644 index 0000000..6e2cb05 --- /dev/null +++ b/src/assets/icons/bank.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/dataset-active.png b/src/assets/icons/dataset-active.png new file mode 100644 index 0000000..dda5155 Binary files /dev/null and b/src/assets/icons/dataset-active.png differ diff --git a/src/assets/icons/dataset.png b/src/assets/icons/dataset.png new file mode 100644 index 0000000..1bc7d6c Binary files /dev/null and b/src/assets/icons/dataset.png differ diff --git a/src/assets/icons/home-active.png b/src/assets/icons/home-active.png new file mode 100644 index 0000000..a8b785d Binary files /dev/null and b/src/assets/icons/home-active.png differ diff --git a/src/assets/icons/home.png b/src/assets/icons/home.png new file mode 100644 index 0000000..3457612 Binary files /dev/null and b/src/assets/icons/home.png differ diff --git a/src/assets/icons/kefu.svg b/src/assets/icons/kefu.svg new file mode 100644 index 0000000..cce19bd --- /dev/null +++ b/src/assets/icons/kefu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/logo.png b/src/assets/icons/logo.png new file mode 100644 index 0000000..3813f5b Binary files /dev/null and b/src/assets/icons/logo.png differ diff --git a/src/assets/icons/mine-active.png b/src/assets/icons/mine-active.png new file mode 100644 index 0000000..a68ee8b Binary files /dev/null and b/src/assets/icons/mine-active.png differ diff --git a/src/assets/icons/mine.png b/src/assets/icons/mine.png new file mode 100644 index 0000000..c4d6762 Binary files /dev/null and b/src/assets/icons/mine.png differ diff --git a/src/assets/icons/setting.svg b/src/assets/icons/setting.svg new file mode 100644 index 0000000..7447d34 --- /dev/null +++ b/src/assets/icons/setting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/wx.svg b/src/assets/icons/wx.svg new file mode 100644 index 0000000..e831ab5 --- /dev/null +++ b/src/assets/icons/wx.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/banner.png b/src/assets/images/banner.png new file mode 100644 index 0000000..9c30098 Binary files /dev/null and b/src/assets/images/banner.png differ diff --git a/src/components/FormImage/index.jsx b/src/components/FormImage/index.jsx new file mode 100644 index 0000000..516aa75 --- /dev/null +++ b/src/components/FormImage/index.jsx @@ -0,0 +1,71 @@ + +import cls from 'classnames'; +import styles from './index.module.less'; +import { Image, ImageViewer } from 'antd-mobile'; +import { CameraOutline } from 'antd-mobile-icons'; +import { View } from '@tarojs/components'; +import { uploadImage64Action } from '../../request/actions'; +import Taro from '@tarojs/taro'; +import React, { useState } from 'react'; + +const FormImage = ({ value, className, onChange, readonly, ...props }) => { + const prefix = cls(styles.img, className); + const [visible, updateVisible] = useState(false); + + const handleClick = () => { + // TODO + if (readonly || value) { + updateVisible(true); + return; + } + const input = document.createElement('input'); + input.type = 'file'; + input.accept = 'image/*'; + input.onchange = (event) => { + const file = event.target.files[0]; + if (file) { + const reader = new FileReader(); + reader.onload = async () => { + const imageBase64 = reader.result; + const res = await uploadImage64Action({ imageBase64 }); + onChange(res?.logo); + }; + reader.readAsDataURL(file); // 将文件读取为 Base64 + } + }; + input.click(); + }; + + + if (!value) { + if (readonly) { + return ( + + ); + } + return ( + + + + ); + } + + return ( + + + { + updateVisible(false) + }} + /> + + ); +}; + +export default FormImage; diff --git a/src/components/FormImage/index.module.less b/src/components/FormImage/index.module.less new file mode 100644 index 0000000..abb2e64 --- /dev/null +++ b/src/components/FormImage/index.module.less @@ -0,0 +1,15 @@ + +.img { + width: 72px; + height: 72px; +} + +.empty { + width: 72px; + height: 72px; + border-radius: 6px; + background-color: #f4f5f7; + display: flex; + justify-content: center; + align-items: center; +} diff --git a/src/components/FormLabel/index.jsx b/src/components/FormLabel/index.jsx new file mode 100644 index 0000000..6a74c5f --- /dev/null +++ b/src/components/FormLabel/index.jsx @@ -0,0 +1,7 @@ + +const FormLabel = ({ value, render, ...props }) => { + + return {render ? render(value) : value}; +}; + +export default FormLabel; diff --git a/src/hooks/useRequestList/index.ts b/src/hooks/useRequestList/index.ts new file mode 100644 index 0000000..bdadd3c --- /dev/null +++ b/src/hooks/useRequestList/index.ts @@ -0,0 +1,96 @@ +import { useEffect, useRef, useState } from 'react'; + +import { AxiosRequestConfig } from 'axios'; +import { Toast } from 'antd-mobile'; + +type Request = (params: T, options?: any) => Promise; + +interface UseRequestListProps { + action: Request; + immediate?: boolean; + onOk?: () => void | boolean; + initFilterParams?: Partial

; + showMsg?: boolean; + options?: AxiosRequestConfig; + loop?: boolean; + interval?: number; + onLoop?: (data: any) => boolean; +}; + + +function useRequestList({ + action, + immediate = true, + onOk, + initFilterParams, + showMsg = false, + options = {}, + loop = false, + interval = 2000, + onLoop +}: UseRequestListProps) { + const [loading, updateLoading] = useState(false); + const filterParamsRef = useRef(initFilterParams); + const [data, updateData] = useState(); + + const timer = useRef(null); + + const abortLoop = () => { + if (timer.current) { + clearInterval(timer.current); + timer.current = null; + } + }; + + const getDataTask = async (params: P, loading = true) => { + try { + loading && updateLoading(true); + const filterParams = filterParamsRef.current; + const queryParams = { ...filterParams, ...params }; + const res = await action(queryParams, options); + filterParamsRef.current = queryParams; + updateData(res); + if (loop && onLoop?.(res)) { + timer.current = setTimeout(() => { + getDataTask(queryParams, loading); + }, interval); + } + else { + loading && updateLoading(false); + onOk?.(); + return res; + } + } + catch (err) { + abortLoop(); + showMsg && Toast.show({ + icon: 'error', + content: `${err}` + }); + } + finally { + loading && !loop && updateLoading(false); + } + }; + + useEffect(() => { + return abortLoop; + }, []); + + useEffect(() => { + if (!immediate) { + return; + } + getDataTask({} as P); + }, []); + + return { + getDataTask, + loading, + data, + filterParams: filterParamsRef.current, + abortLoop + }; +} + +export default useRequestList; diff --git a/src/hooks/useRequestSubmit/index.ts b/src/hooks/useRequestSubmit/index.ts new file mode 100644 index 0000000..6c7adac --- /dev/null +++ b/src/hooks/useRequestSubmit/index.ts @@ -0,0 +1,50 @@ +/* + * @Author: WIN-J7OL7MK489U\EDY 13478707150@163.com + * @Date: 2023-06-28 16:45:43 + * @LastEditors: BJ-HPC3\13478 13478707150@163.com + * @LastEditTime: 2025-02-21 17:15:40 + * @FilePath: \jsure_zdbg_web_react\src\hooks\useRequest\index.ts + * @Description: 通用请求 + */ + +import { useState } from 'react'; + +import type { Request } from '@/request/utils'; + +interface UseRequestListProps { + action?: Request; + onOk?: () => void; +}; + +function useRequestSubmit({ + action, + onOk, +}: UseRequestListProps) { + const [loading, updateLoading] = useState(false); + const [data, updateData] = useState(null); + + const actionTask = async (params: P, loading = true) => { + try { + loading && updateLoading(true); + const res = await action(params); + updateData(res); + onOk?.(); + return res; + } + catch (err) { + console.log('[request submit err]: ', err); + return Promise.reject(err); + } + finally { + loading && updateLoading(false); + } + }; + + return { + actionTask, + loading, + data + }; +} + +export default useRequestSubmit; \ No newline at end of file diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..5d49b24 --- /dev/null +++ b/src/index.html @@ -0,0 +1,17 @@ + + + + + + + + + + + jf_20250608 + + + +

+ + diff --git a/src/pages/dataset/components/DataList/index.jsx b/src/pages/dataset/components/DataList/index.jsx new file mode 100644 index 0000000..ed59316 --- /dev/null +++ b/src/pages/dataset/components/DataList/index.jsx @@ -0,0 +1,111 @@ +import React, { useEffect, useState } from 'react'; +import { PullToRefresh, List, Empty, Button, Modal, Toast } from 'antd-mobile'; +import { View, Text, ScrollView } from '@tarojs/components'; +import { getOrderListLoopAction, orderConfirmAction } from '../../../../request/actions'; +import { OrderStatusEnum } from '../../constants'; +import Taro, { useDidShow } from '@tarojs/taro'; + +import styles from './index.module.less'; + +const fetchDataRecursively = async (times, params, datasource) => { + if (times <= 0 || (datasource && datasource?.length < 10)) { + return []; + } + const lastOrderId = datasource?.[datasource?.length - 1]?.orderId; + const result = await getOrderListLoopAction({ ...params, lastOrderId }); + const nextResults = await fetchDataRecursively(times - 1, params, result?.dataList); + return [...result?.dataList, ...nextResults]; +}; + +const DataList = ({ orderStatus }) => { + const [data, setData] = useState([]); + + const initData = async () => { + const dataSource = await fetchDataRecursively(1, { orderStatus }); + setData(dataSource); + }; + + + const handleScrollToLower = async () => { + const lastLogId = data?.[data?.length - 1]?.orderId; + const result = await getOrderListLoopAction({ lastLogId }); + const newDataSource = result?.dataList; + setData([...data, ...newDataSource]); + }; + + const handleJump = item => { + // 去支付 + if (orderStatus === OrderStatusEnum.waittingForPay.value) { + Taro.navigateTo({ + url: `/pages/payconfirm/index?orderId=${item.orderId}` + }); + } + // 确认订单 + if (orderStatus === OrderStatusEnum.waittingForConfirm.value) { + // Modal.confirm({ + // title: '是否确认收款?', + // onConfirm: async () => { + // try { + // const orderId = item.orderId; + // await orderConfirmAction({ orderId }); + // initData(); + // Toast.show({ + // icon: 'success', + // content: '已成功确认收款信息' + // }); + // } + // catch (err) { + // console.log('err: ', err); + // } + // } + // }) + Taro.navigateTo({ + url: `/pages/feeconfirm/index?orderId=${item.orderId}` + }); + } + }; + + useDidShow(initData); + + useEffect(() => { + initData(); + }, [orderStatus]); + + return ( + + {data.length > 0 ? ( + + + {data.map((item, index) => ( + handleJump(item)} arrowIcon={false}> + + 订单编号: {item.orderId} + 订单日期: {item.orderDate || '-'} + + + 订单金额: {item.orderPrice} + + {orderStatus !== OrderStatusEnum.done.value && ( + + )} + + ))} + + + ) : ( + + )} + + ) +}; + +export default DataList; diff --git a/src/pages/dataset/components/DataList/index.module.less b/src/pages/dataset/components/DataList/index.module.less new file mode 100644 index 0000000..14f71c0 --- /dev/null +++ b/src/pages/dataset/components/DataList/index.module.less @@ -0,0 +1,12 @@ +.row { + display: flex; + justify-content: space-between; + font-size: 28px; + line-height: 2; +} +.btn { + width: 100%; +} +.list { + height: calc(100vh - 92px - 120px); +} diff --git a/src/pages/dataset/constants.js b/src/pages/dataset/constants.js new file mode 100644 index 0000000..a1fbd3b --- /dev/null +++ b/src/pages/dataset/constants.js @@ -0,0 +1,15 @@ + +export const OrderStatusEnum = { + waittingForPay: { + label: '待付款', + value: '0' + }, + waittingForConfirm: { + label: '待确认', + value: '1' + }, + done: { + label: '已完成', + value: '9' + } +}; diff --git a/src/pages/dataset/index.config.js b/src/pages/dataset/index.config.js new file mode 100644 index 0000000..fd10fbe --- /dev/null +++ b/src/pages/dataset/index.config.js @@ -0,0 +1,4 @@ +export default definePageConfig({ + navigationBarTitleText: '数据优化', + usingComponents: {}, +}) diff --git a/src/pages/dataset/index.jsx b/src/pages/dataset/index.jsx new file mode 100644 index 0000000..4399d7f --- /dev/null +++ b/src/pages/dataset/index.jsx @@ -0,0 +1,25 @@ +import { View } from '@tarojs/components'; +import { Tabs } from 'antd-mobile'; + +import DataList from './components/DataList'; +import { OrderStatusEnum } from './constants'; + +import styles from './index.module.less'; + +export default function Dataset() { + return ( + + + + + + + + + + + + + + ) +} diff --git a/src/pages/dataset/index.module.less b/src/pages/dataset/index.module.less new file mode 100644 index 0000000..797ad4d --- /dev/null +++ b/src/pages/dataset/index.module.less @@ -0,0 +1,16 @@ +.container { + position: relative; + + .tabs { + height: 82px; + position: sticky; + top: 0; + z-index: 9; + background-color: #fff; + } + :global { + .adm-list-body { + border-top: unset; + } + } +} diff --git a/src/pages/feeconfirm/components/Alipay/index.jsx b/src/pages/feeconfirm/components/Alipay/index.jsx new file mode 100644 index 0000000..1fc9aa1 --- /dev/null +++ b/src/pages/feeconfirm/components/Alipay/index.jsx @@ -0,0 +1,42 @@ +import { View } from '@tarojs/components'; +import { Form } from 'antd-mobile'; +import FormLabel from '/components/FormLabel'; +import FormImage from '/components/FormImage'; + +import styles from './index.module.less'; + +export default function Alipay({ namePrefix }) { + + return ( + + + + + + + + {/* + + */} + {/* + + */} + + ) +} diff --git a/src/pages/feeconfirm/components/Alipay/index.module.less b/src/pages/feeconfirm/components/Alipay/index.module.less new file mode 100644 index 0000000..11be4b3 --- /dev/null +++ b/src/pages/feeconfirm/components/Alipay/index.module.less @@ -0,0 +1,3 @@ +.container { + +} diff --git a/src/pages/feeconfirm/components/BankPay/index.jsx b/src/pages/feeconfirm/components/BankPay/index.jsx new file mode 100644 index 0000000..2941289 --- /dev/null +++ b/src/pages/feeconfirm/components/BankPay/index.jsx @@ -0,0 +1,41 @@ +import { View } from '@tarojs/components'; +import { Form } from 'antd-mobile'; +import FormLabel from '/components/FormLabel'; + +import styles from './index.module.less'; + +export default function BankPay({ namePrefix }) { + + return ( + + + + + + + + + + + {/* + + */} + + ) +} diff --git a/src/pages/feeconfirm/components/BankPay/index.module.less b/src/pages/feeconfirm/components/BankPay/index.module.less new file mode 100644 index 0000000..4851408 --- /dev/null +++ b/src/pages/feeconfirm/components/BankPay/index.module.less @@ -0,0 +1,2 @@ +.container { +} diff --git a/src/pages/feeconfirm/components/FormBar/index.jsx b/src/pages/feeconfirm/components/FormBar/index.jsx new file mode 100644 index 0000000..d8a9251 --- /dev/null +++ b/src/pages/feeconfirm/components/FormBar/index.jsx @@ -0,0 +1,179 @@ +import { View } from '@tarojs/components'; +import { Button, CapsuleTabs, Form, Modal, Toast } from 'antd-mobile'; + +import FormImage from '/components/FormImage'; +import FormLabel from '/components/FormLabel'; +import React, { useEffect, useMemo, useState } from 'react'; +import { getOrderInfoAction } from '/request/actions'; +import { getUrlParam } from '/utils'; +import Taro from '@tarojs/taro'; + +// import Alipay from '../Alipay'; +// import Wxpay from '../Wxpay'; +// import BankPay from '../BankPay'; + +// import aliSrc from '/assets/icons/ali.svg'; +// import wxSrc from '/assets/icons/wx.svg'; +// import bankSrc from '/assets/icons/bank.svg'; +import { orderConfirmAction } from '../../../../request/actions'; + +import styles from './index.module.less'; + +// const TabItem = ({ src, text }) => ( +// +// +// {text} +// +// ); + +export default function FormBar() { + const [form] = Form.useForm(); + // const [showFee, updateShowFee] = useState(false); + + useEffect(() => { + getOrderInfoAction({ + orderId: getUrlParam('orderId') + }).then(res => { + const orderShopInfo = res.orderShopInfo || {}; + const feeShopInfo = res.feeShopInfo || {}; + const _orderShopInfo = Object.keys(orderShopInfo).reduce((res, key) => { + return { + ...res, + [`pay-${key}`]: orderShopInfo[key] + } + }, {}); + const _feeShopInfo = Object.keys(orderShopInfo).reduce((res, key) => { + return { + ...res, + [`fee-${key}`]: feeShopInfo[key] + } + }, {}); + form.setFieldsValue({ + ...res, + ..._orderShopInfo, + ..._feeShopInfo + }); + + // updateShowFee(res.feePrice || res.feeImage || res.feeShopInfo) + }); + }, []); + + const handleSubmit = () => { + Modal.confirm({ + title: '是否确认收款?', + onConfirm: async () => { + try { + const orderId = getUrlParam('orderId'); + await orderConfirmAction({ orderId }); + Toast.show({ + icon: 'success', + content: '已成功确认收款信息' + }); + Taro.navigateTo({ + url: '/pages/dataset/index' + }); + } + catch (err) { + console.log('err: ', err); + } + } + }) + }; + + // const way = Form.useWatch('way', form); + // const feeway = Form.useWatch('feeway', form); + + // const detailRenderer = useMemo(() => { + // return { + // alipay: , + // wx: , + // bank: + // }[way]; + // }, [way]); + + // const feeDetailRenderer = useMemo(() => { + // return { + // alipay: , + // wx: , + // bank: + // }[feeway]; + // }, [feeway]); + + const payImage = Form.useWatch('payImage', form); + const feeImage = Form.useWatch('feeImage', form); + + return ( + +
+ + 收款信息 + + + + + + + + + `¥${val || 0}`} /> + + + `¥${val || 0}`} /> + + + + + + + + + + + {/* + + } key='alipay' /> + } key='wx' /> + } key='bank' /> + + + {detailRenderer} + {showFee && ( + + + 服务费收款信息 + + + `¥${val || 0}`} /> + + + + + + + } key='alipay' /> + } key='wx' /> + } key='bank' /> + + + {feeDetailRenderer} + + )} */} +
+ +
+ ) +} diff --git a/src/pages/feeconfirm/components/FormBar/index.module.less b/src/pages/feeconfirm/components/FormBar/index.module.less new file mode 100644 index 0000000..6348817 --- /dev/null +++ b/src/pages/feeconfirm/components/FormBar/index.module.less @@ -0,0 +1,71 @@ +.container { + background-color: #fff; + border-radius: 18px; + padding: 32px 32px 48px 32px; + + .tabitem { + font-size: 24px; + display: flex; + align-items: center; + + img { + width: 28px; + margin-right: 8px; + } + } + + .btn { + width: 100%; + margin-top: 24px; + } + + .title { + font-size: 28px; + font-weight: 600; + margin: 24px 0; + } + + .margin { + margin-top: 32px; + } + + .submit { + width: 100%; + margin-top: 72px; + } + + :global { + .adm-capsule-tabs-header { + padding: 0; + } + + .adm-list-item-content-prefix { + width: 168px; + } + + .adm-capsule-tabs-tab { + padding: 8px; + border-radius: 6px; + border: 1px solid transparent; + transition: all .2s ease-in-out; + } + + .adm-capsule-tabs-tab-active { + color: var(--color-primary); + background-color: #f0f9ff; + border-color: var(--color-primary); + } + + .adm-list-body { + border-top: unset; + } + + .adm-list-item { + padding-left: 0; + } + + .adm-list-item-content { + border-top: unset; + } + } +} diff --git a/src/pages/feeconfirm/components/Wxpay/index.jsx b/src/pages/feeconfirm/components/Wxpay/index.jsx new file mode 100644 index 0000000..5edc347 --- /dev/null +++ b/src/pages/feeconfirm/components/Wxpay/index.jsx @@ -0,0 +1,42 @@ +import { View } from '@tarojs/components'; +import { Form } from 'antd-mobile'; +import FormLabel from '/components/FormLabel'; +import FormImage from '/components/FormImage'; + +import styles from './index.module.less'; + +export default function Wxpay({ namePrefix }) { + + return ( + + + + + + + + {/* + + */} + {/* + + */} + + ) +} diff --git a/src/pages/feeconfirm/components/Wxpay/index.module.less b/src/pages/feeconfirm/components/Wxpay/index.module.less new file mode 100644 index 0000000..4851408 --- /dev/null +++ b/src/pages/feeconfirm/components/Wxpay/index.module.less @@ -0,0 +1,2 @@ +.container { +} diff --git a/src/pages/feeconfirm/index.config.js b/src/pages/feeconfirm/index.config.js new file mode 100644 index 0000000..c71227b --- /dev/null +++ b/src/pages/feeconfirm/index.config.js @@ -0,0 +1,4 @@ +export default definePageConfig({ + navigationBarTitleText: '确认收款', + usingComponents: {}, +}) diff --git a/src/pages/feeconfirm/index.jsx b/src/pages/feeconfirm/index.jsx new file mode 100644 index 0000000..39976bd --- /dev/null +++ b/src/pages/feeconfirm/index.jsx @@ -0,0 +1,25 @@ +import { View } from '@tarojs/components'; +import Taro from '@tarojs/taro'; + +import FormBar from './components/FormBar'; +import { NavBar } from 'antd-mobile'; + +import styles from './index.module.less'; + +export default function ShopInfo() { + + const handleBack = () => { + Taro.navigateTo({ + url: '/pages/dataset/index' + }); + }; + + return ( + + 确认收款 + + + + + ) +} diff --git a/src/pages/feeconfirm/index.module.less b/src/pages/feeconfirm/index.module.less new file mode 100644 index 0000000..e32d392 --- /dev/null +++ b/src/pages/feeconfirm/index.module.less @@ -0,0 +1,10 @@ +.container { + background: linear-gradient(180deg, #d7ebfa, #f5f5f5 30vh); + height: 100%; + overflow-y: auto; + + .wrapper { + box-sizing: border-box; + padding: 42px; + } +} diff --git a/src/pages/feedback/index.config.js b/src/pages/feedback/index.config.js new file mode 100644 index 0000000..7e2e45e --- /dev/null +++ b/src/pages/feedback/index.config.js @@ -0,0 +1,4 @@ +export default definePageConfig({ + navigationBarTitleText: '反馈', + usingComponents: {}, +}) diff --git a/src/pages/feedback/index.jsx b/src/pages/feedback/index.jsx new file mode 100644 index 0000000..e4cc23c --- /dev/null +++ b/src/pages/feedback/index.jsx @@ -0,0 +1,45 @@ +import { View } from '@tarojs/components'; +import Taro from '@tarojs/taro'; + +import { Button, Form, NavBar, TextArea } from 'antd-mobile'; +import { feedbackAction } from '../../request/actions'; + +import styles from './index.module.less'; + +export default function Feedback() { + const [form] = Form.useForm(); + + const handleBack = () => { + Taro.navigateTo({ + url: '/pages/mine/index' + }); + }; + + const handleVery = async () => { + try { + const values = await form.validateFields(); + console.log('values: ', values); + await feedbackAction(values); + handleBack(); + } + catch (err) { + console.log('err: ', err); + } + }; + + return ( + + + 反馈 + +
+ +