diff --git a/config/index.js b/config/index.js index 62c89fe..09a4522 100644 --- a/config/index.js +++ b/config/index.js @@ -1,9 +1,14 @@ const path = require('path') -const childProcess = require('child_process'); -const versions = childProcess.execSync('git rev-parse --abbrev-ref HEAD', { 'encoding': 'utf8' }) != "HEAD\n" ? childProcess.execSync('git rev-parse --abbrev-ref HEAD', { 'encoding': 'utf8' }) : childProcess.execSync('git describe --tags --abbrev=0', { 'encoding': 'utf8' }) -const CURRENT_GITHASH = childProcess.execSync('git rev-parse --short HEAD', { 'encoding': 'utf8' }) -const CURRENT_VERSION = `Version: ${JSON.stringify(process.env.CODE_BRANCH || versions)} ${CURRENT_GITHASH} ${new Date().toLocaleString()}`.replace(/\"|\\n/g, ''); - +const childProcess = require('child_process') +const versions = + childProcess.execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }) != 'HEAD\n' + ? childProcess.execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }) + : childProcess.execSync('git describe --tags --abbrev=0', { encoding: 'utf8' }) +const CURRENT_GITHASH = childProcess.execSync('git rev-parse --short HEAD', { encoding: 'utf8' }) +const CURRENT_VERSION = `Version: ${JSON.stringify(process.env.CODE_BRANCH || versions)} ${CURRENT_GITHASH} ${new Date().toLocaleString()}`.replace( + /\"|\\n/g, + '', +) const config = { projectName: 'EShop', @@ -12,7 +17,7 @@ const config = { deviceRatio: { 640: 2.34 / 2, 750: 1, - 828: 1.81 / 2 + 828: 1.81 / 2, }, sourceRoot: 'src', outputRoot: 'dist', @@ -20,37 +25,33 @@ const config = { defineConstants: { CURRENT_VERSION: JSON.stringify(CURRENT_VERSION), CURRENT_GITHASH: JSON.stringify(CURRENT_GITHASH), - CURRENT_ENV: JSON.stringify(process.env.NODE_ENV) + CURRENT_ENV: JSON.stringify(process.env.NODE_ENV), }, copy: { - patterns: [ - ], - options: { - } + patterns: [], + options: {}, }, framework: 'react', mini: { postcss: { pxtransform: { enable: true, - config: { - - } + config: {}, }, url: { enable: true, config: { - limit: 1024 // 设定转换尺寸上限 - } + limit: 1024, // 设定转换尺寸上限 + }, }, cssModules: { enable: true, // 默认为 false,如需使用 css modules 功能,则设为 true config: { namingPattern: 'module', // 转换模式,取值为 global/module - generateScopedName: '[name]__[local]___[hash:base64:5]' - } - } - } + generateScopedName: '[name]__[local]___[hash:base64:5]', + }, + }, + }, }, h5: { publicPath: '/', @@ -58,23 +59,25 @@ const config = { postcss: { autoprefixer: { enable: true, - config: { - } + config: {}, }, cssModules: { enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true config: { namingPattern: 'module', // 转换模式,取值为 global/module - generateScopedName: '[name]__[local]___[hash:base64:5]' - } - } - } - } + generateScopedName: '[name]__[local]___[hash:base64:5]', + }, + }, + }, + }, } module.exports = function (merge) { if (process.env.NODE_ENV === 'development') { return merge({}, config, require('./dev')) } + if (process.env.NODE_ENV === 'pre') { + return merge({}, config, require('./pre')) + } return merge({}, config, require('./prod')) } diff --git a/config/pre.js b/config/pre.js new file mode 100644 index 0000000..fe4664b --- /dev/null +++ b/config/pre.js @@ -0,0 +1,51 @@ +const path = require('path') +module.exports = { + env: { + NODE_ENV: '"pre"', + }, + outputRoot: 'pre_dis', + defineConstants: {}, + mini: { + optimizeMainPackage: { + enable: true, + }, + webpackChain: (chain, webpack) => { + chain.merge({ + plugin: { + install: { + plugin: require('terser-webpack-plugin'), + args: [ + { + terserOptions: { + // compress: true, // 默认使用terser压缩 + compress: { + drop_console: true, // 去掉打印 + }, // 默认使用terser压缩 + // mangle: false, + keep_classnames: true, // 不改变class名称 + keep_fnames: true, // 不改变函数名称 + }, + }, + ], + }, + }, + }) + }, + }, + h5: { + /** + * 如果h5端编译后体积过大,可以使用webpack-bundle-analyzer插件对打包体积进行分析。 + * 参考代码如下: + * webpackChain (chain) { + * chain.plugin('analyzer') + * .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, []) + * } + */ + }, + alias: { + '@': path.resolve(__dirname, '..', 'src'), + }, + sass: { + resource: path.resolve(__dirname, '..', 'src/styles/common.scss'), + }, +} diff --git a/config/prod.js b/config/prod.js index 8b30be6..6f57ab4 100644 --- a/config/prod.js +++ b/config/prod.js @@ -1,35 +1,35 @@ const path = require('path') module.exports = { env: { - NODE_ENV: '"production"' - }, - defineConstants: { + NODE_ENV: '"production"', }, + defineConstants: {}, mini: { optimizeMainPackage: { - enable: true + enable: true, }, webpackChain: (chain, webpack) => { chain.merge({ plugin: { install: { plugin: require('terser-webpack-plugin'), - args: [{ - terserOptions: { - // compress: true, // 默认使用terser压缩 - compress: { - drop_console: true, // 去掉打印 - }, // 默认使用terser压缩 - // mangle: false, - keep_classnames: true, // 不改变class名称 - keep_fnames: true // 不改变函数名称 - } - }] - } - } + args: [ + { + terserOptions: { + // compress: true, // 默认使用terser压缩 + compress: { + drop_console: true, // 去掉打印 + }, // 默认使用terser压缩 + // mangle: false, + keep_classnames: true, // 不改变class名称 + keep_fnames: true, // 不改变函数名称 + }, + }, + ], + }, + }, }) - } - + }, }, h5: { /** @@ -45,6 +45,6 @@ module.exports = { '@': path.resolve(__dirname, '..', 'src'), }, sass: { - resource: path.resolve(__dirname, '..', 'src/styles/common.scss') - } + resource: path.resolve(__dirname, '..', 'src/styles/common.scss'), + }, } diff --git a/src/api/addressManager.ts b/src/api/addressManager.ts index ffa3dcd..6d9310c 100644 --- a/src/api/addressManager.ts +++ b/src/api/addressManager.ts @@ -1,56 +1,56 @@ -import { useRequest } from "@/use/useHttp" +import { useRequest } from '@/use/useHttp' /** * 获取地址列表 - * @returns + * @returns */ - export const addressListApi = () => { - return useRequest({ - url: `/v1/mall/address/list`, - method: "get", - }) +export const addressListApi = () => { + return useRequest({ + url: `/v1/mall/address/list`, + method: 'get', + }) } /** * 添加地址 - * @returns + * @returns */ - export const addressAddApi = () => { +export const addressAddApi = () => { return useRequest({ - url: `/v1/mall/address`, - method: "post", + url: `/v1/mall/address`, + method: 'post', }) } /** * 地址详情 - * @returns + * @returns */ - export const addressDetailApi = () => { +export const addressDetailApi = () => { return useRequest({ - url: `/v1/mall/address`, - method: "get", + url: `/v1/mall/address`, + method: 'get', }) } /** * 地址编辑 - * @returns + * @returns */ - export const addressEditApi = () => { +export const addressEditApi = () => { return useRequest({ - url: `/v1/mall/address`, - method: "put", + url: `/v1/mall/address`, + method: 'put', }) } /** * 地址删除 - * @returns + * @returns */ - export const addressDeleteApi = () => { +export const addressDeleteApi = () => { return useRequest({ - url: `/v1/mall/address`, - method: "delete", + url: `/v1/mall/address`, + method: 'delete', }) } diff --git a/src/api/banner.ts b/src/api/banner.ts index dc8a8ff..d39c350 100644 --- a/src/api/banner.ts +++ b/src/api/banner.ts @@ -1,12 +1,12 @@ -import { useRequest } from "@/use/useHttp" +import { useRequest } from '@/use/useHttp' /** * 获取轮播图列表 - * @returns + * @returns */ - export const GetBannerList = () => { - return useRequest({ - url: `/v1/mall/carouselBanner/list`, - method: "get", - }) +export const GetBannerList = () => { + return useRequest({ + url: `/v1/mall/carouselBanner/list`, + method: 'get', + }) } diff --git a/src/api/cdn.ts b/src/api/cdn.ts index 8289c45..1c34ec8 100644 --- a/src/api/cdn.ts +++ b/src/api/cdn.ts @@ -1,13 +1,12 @@ -import { useRequest } from "@/use/useHttp" - +import { useRequest } from '@/use/useHttp' /** * 获取cdn 签名/密钥 - * @returns + * @returns */ - export const GetSignApi = () => { - return useRequest({ - url: `/v1/mall/cdn/token`, - method: "get" - }) +export const GetSignApi = () => { + return useRequest({ + url: `/v1/mall/cdn/token`, + method: 'get', + }) } diff --git a/src/api/company.ts b/src/api/company.ts index 799464b..500d626 100644 --- a/src/api/company.ts +++ b/src/api/company.ts @@ -1,23 +1,23 @@ -import { useRequest } from "@/use/useHttp" +import { useRequest } from '@/use/useHttp' /** * 公司获取 - * @returns + * @returns */ - export const companyDetailApi = () => { - return useRequest({ - url: `/v1/mall/company/info`, - method: "get", - }) +export const companyDetailApi = () => { + return useRequest({ + url: `/v1/mall/company/info`, + method: 'get', + }) } /** * 公司保存 - * @returns + * @returns */ - export const companyUpdateApi = () => { +export const companyUpdateApi = () => { return useRequest({ - url: `/v1/mall/company/info`, - method: "put", + url: `/v1/mall/company/info`, + method: 'put', }) } diff --git a/src/api/creditLine.ts b/src/api/creditLine.ts index 7c69511..2fd133b 100644 --- a/src/api/creditLine.ts +++ b/src/api/creditLine.ts @@ -1,23 +1,23 @@ -import { useRequest } from "@/use/useHttp" +import { useRequest } from '@/use/useHttp' /** * 额度获取 - * @returns + * @returns */ - export const creditInfoApi = () => { - return useRequest({ - url: `/v1/mall/credit`, - method: "get", - }) +export const creditInfoApi = () => { + return useRequest({ + url: `/v1/mall/credit`, + method: 'get', + }) } /** * 额度已用获取 - * @returns + * @returns */ - export const creditListApi = () => { +export const creditListApi = () => { return useRequest({ - url: `/v1/mall/credit/list`, - method: "get", + url: `/v1/mall/credit/list`, + method: 'get', }) } diff --git a/src/api/deposit.ts b/src/api/deposit.ts index 23b47ee..4a24d8e 100644 --- a/src/api/deposit.ts +++ b/src/api/deposit.ts @@ -1,34 +1,34 @@ -import { useRequest } from "@/use/useHttp" +import { useRequest } from '@/use/useHttp' /** * 预存款信息获取 - * @returns + * @returns */ - export const depositInfoApi = () => { - return useRequest({ - url: `/v1/mall/rechargeApplication`, - method: "get", - }) +export const depositInfoApi = () => { + return useRequest({ + url: `/v1/mall/rechargeApplication`, + method: 'get', + }) } /** * 预存款收支明细 - * @returns + * @returns */ - export const depositListApi = () => { +export const depositListApi = () => { return useRequest({ - url: `/v1/mall/rechargeApplication/list`, - method: "get", + url: `/v1/mall/rechargeApplication/list`, + method: 'get', }) } /** * 预存款收支明细详情 - * @returns + * @returns */ - export const depositDetailApi = () => { +export const depositDetailApi = () => { return useRequest({ - url: `/v1/mall/rechargeApplication/order`, - method: "get", + url: `/v1/mall/rechargeApplication/order`, + method: 'get', }) } diff --git a/src/api/favorite.ts b/src/api/favorite.ts index 334cf3a..09eaa77 100644 --- a/src/api/favorite.ts +++ b/src/api/favorite.ts @@ -1,91 +1,89 @@ -import { useRequest } from "@/use/useHttp" +import { useRequest } from '@/use/useHttp' /** * 获取收藏夹列表 - * @returns -*/ + * @returns + */ export const FavoriteListApi = () => { - return useRequest({ - url: `/v1/mall/favorite/list`, - method: "get", - }) + return useRequest({ + url: `/v1/mall/favorite/list`, + method: 'get', + }) } - /** * 创建收藏夹列表 - * @returns -*/ + * @returns + */ export const CreateFavoriteApi = () => { - return useRequest({ - url: `/v1/mall/favorite`, - method: "post", - }) + return useRequest({ + url: `/v1/mall/favorite`, + method: 'post', + }) } - /** * 删除收藏夹列表 - * @returns -*/ + * @returns + */ export const DelFavoriteApi = () => { - return useRequest({ - url: `/v1/mall/favorite`, - method: "delete", - }) + return useRequest({ + url: `/v1/mall/favorite`, + method: 'delete', + }) } /** * 更新收藏夹 - * @returns -*/ + * @returns + */ export const UpdateFavoriteApi = () => { - return useRequest({ - url: `/v1/mall/favorite`, - method: "put", - }) + return useRequest({ + url: `/v1/mall/favorite`, + method: 'put', + }) } /** * 加入收藏夹 - * @returns -*/ + * @returns + */ export const AddFavoriteApi = () => { - return useRequest({ - url: `/v1/mall/favorite/product`, - method: "post", - }) + return useRequest({ + url: `/v1/mall/favorite/product`, + method: 'post', + }) } /** * 删除收藏夹商品 - * @returns -*/ + * @returns + */ export const DelFavoriteProductApi = () => { - return useRequest({ - url: `/v1/mall/favorite/product`, - method: "delete", - }) + return useRequest({ + url: `/v1/mall/favorite/product`, + method: 'delete', + }) } /** * 获取收藏夹商品详情 - * @returns -*/ + * @returns + */ export const DetailFavoriteProductApi = () => { - return useRequest({ - url: `/v1/mall/favorite`, - method: "get", - }) + return useRequest({ + url: `/v1/mall/favorite`, + method: 'get', + }) } /** * 移动收藏夹商品 - * @returns -*/ + * @returns + */ export const MoveFavoriteProductApi = () => { - return useRequest({ - url: `/v1/mall/favorite/product`, - method: "put", - }) -} \ No newline at end of file + return useRequest({ + url: `/v1/mall/favorite/product`, + method: 'put', + }) +} diff --git a/src/api/login.ts b/src/api/login.ts index a7cb935..d1e830c 100644 --- a/src/api/login.ts +++ b/src/api/login.ts @@ -1,12 +1,12 @@ -import { useRequest } from "@/use/useHttp" +import { useRequest } from '@/use/useHttp' /** * 登录 - * @returns -*/ + * @returns + */ export const LoginApi = () => { - return useRequest({ - url: `/v1/mall/login`, - method: "post", - }) + return useRequest({ + url: `/v1/mall/login`, + method: 'post', + }) } diff --git a/src/api/order.ts b/src/api/order.ts index 952811e..bc1f632 100644 --- a/src/api/order.ts +++ b/src/api/order.ts @@ -1,112 +1,111 @@ -import { useRequest } from "@/use/useHttp" +import { useRequest } from '@/use/useHttp' /** * 下单现货销售单 */ export const SaleOrderApi = () => { - return useRequest({ - url: `/v1/mall/saleOrder`, - method: "post", - }) + return useRequest({ + url: `/v1/mall/saleOrder`, + method: 'post', + }) } /** * 预览销售单 */ - export const SaleOrderPreViewApi = () => { - return useRequest({ - url: `/v1/mall/saleOrder/preView`, - method: "put", - }) +export const SaleOrderPreViewApi = () => { + return useRequest({ + url: `/v1/mall/saleOrder/preView`, + method: 'put', + }) } /** * 获取商城订单详情 */ - export const GetSaleOrderDetailApi = () => { - return useRequest({ - url: `/v1/mall/saleOrder/detail`, - method: "get", - }) +export const GetSaleOrderDetailApi = () => { + return useRequest({ + url: `/v1/mall/saleOrder/detail`, + method: 'get', + }) } - /** * 修改销售单备注 */ - export const EditSaleOrderRemarkApi = () => { - return useRequest({ - url: `/v1/mall/saleOrder/remark`, - method: "put", - }) +export const EditSaleOrderRemarkApi = () => { + return useRequest({ + url: `/v1/mall/saleOrder/remark`, + method: 'put', + }) } /** * 修改销售单地址 */ - export const EditSaleOrderAddressApi = () => { - return useRequest({ - url: `/v1/mall/saleOrder/address`, - method: "put", - }) +export const EditSaleOrderAddressApi = () => { + return useRequest({ + url: `/v1/mall/saleOrder/address`, + method: 'put', + }) } /** * 修改销售单收货方法 */ - export const EditSaleOrderShipmentModeApi = () => { - return useRequest({ - url: `/v1/mall/saleOrder/shipmentMode`, - method: "put", - }) +export const EditSaleOrderShipmentModeApi = () => { + return useRequest({ + url: `/v1/mall/saleOrder/shipmentMode`, + method: 'put', + }) } /** * 获取订单状态枚举 */ - export const GetOrderStatusListApi = () => { - return useRequest({ - url: `/v1/mall/enum/sale/order/status`, - method: "get", - }) +export const GetOrderStatusListApi = () => { + return useRequest({ + url: `/v1/mall/enum/sale/order/status`, + method: 'get', + }) } /** * 获取订单列表 */ - export const GetOrderListApi = () => { - return useRequest({ - url: `/v1/mall/saleOrder/list`, - method: "get", - }) +export const GetOrderListApi = () => { + return useRequest({ + url: `/v1/mall/saleOrder/list`, + method: 'get', + }) } /** * 作废销售单 */ export const CancelOrderApi = () => { - return useRequest({ - url: `/v1/mall/saleOrder/cancel`, - method: "put", - }) + return useRequest({ + url: `/v1/mall/saleOrder/cancel`, + method: 'put', + }) } /** * 确认收货 */ export const ReceiveOrderApi = () => { - return useRequest({ - url: `/v1/mall/saleOrder/receive`, - method: "put", - }) + return useRequest({ + url: `/v1/mall/saleOrder/receive`, + method: 'put', + }) } /** * 订单状态列表 */ - export const OrderStatusListApi = () => { - return useRequest({ - url: `/v1/mall/enum/filterSaleOrderStatus`, - method: "get", - }) -} \ No newline at end of file +export const OrderStatusListApi = () => { + return useRequest({ + url: `/v1/mall/enum/filterSaleOrderStatus`, + method: 'get', + }) +} diff --git a/src/api/orderPay.ts b/src/api/orderPay.ts index 2b49a18..eb34c41 100644 --- a/src/api/orderPay.ts +++ b/src/api/orderPay.ts @@ -1,41 +1,41 @@ -import { useRequest } from "@/use/useHttp" +import { useRequest } from '@/use/useHttp' /** * 获取应收单订单支付方式信息 */ - export const GetOrderPayApi = () => { - return useRequest({ - url: `/v1/mall/orderPayment/orderPaymentMethodInfo`, - method: "get", - }) +export const GetOrderPayApi = () => { + return useRequest({ + url: `/v1/mall/orderPayment/orderPaymentMethodInfo`, + method: 'get', + }) } /** * 应收单订单支付提交 */ - export const SubmitOrderPayApi = () => { - return useRequest({ - url: `/v1/mall/orderPayment/orderPaymentSubmission`, - method: "put", - }) +export const SubmitOrderPayApi = () => { + return useRequest({ + url: `/v1/mall/orderPayment/orderPaymentSubmission`, + method: 'put', + }) } /** * 获取预付单支付方式信息 */ - export const GetPrepayOrderPayApi = () => { - return useRequest({ - url: `/v1/mall/orderPayment/preCollectOrder/orderPaymentMethodInfo`, - method: "get", - }) +export const GetPrepayOrderPayApi = () => { + return useRequest({ + url: `/v1/mall/orderPayment/preCollectOrder/orderPaymentMethodInfo`, + method: 'get', + }) } /** * 预付单订单支付提交 */ - export const SubmitPrepayOrderPayApi = () => { - return useRequest({ - url: `/v1/mall/orderPayment/preCollectOrder/orderPaymentSubmission`, - method: "put", - }) -} \ No newline at end of file +export const SubmitPrepayOrderPayApi = () => { + return useRequest({ + url: `/v1/mall/orderPayment/preCollectOrder/orderPaymentSubmission`, + method: 'put', + }) +} diff --git a/src/api/shopCart.ts b/src/api/shopCart.ts index 291ab60..6a101ca 100644 --- a/src/api/shopCart.ts +++ b/src/api/shopCart.ts @@ -1,45 +1,45 @@ -import { useRequest } from "@/use/useHttp" +import { useRequest } from '@/use/useHttp' /** * 获取购物车列表 - * @returns -*/ + * @returns + */ export const GetShoppingCartApi = () => { - return useRequest({ - url: `/v1/mall/shoppingCart/productColor`, - method: "get", - }) + return useRequest({ + url: `/v1/mall/shoppingCart/productColor`, + method: 'get', + }) } /** * 批量添加面料颜色到物车列表 - * @returns -*/ + * @returns + */ export const AddShoppingCartApi = () => { - return useRequest({ - url: `/v1/mall/shoppingCart/productColor/list`, - method: "post", - }) + return useRequest({ + url: `/v1/mall/shoppingCart/productColor/list`, + method: 'post', + }) } /** * 批量删除购物车面料颜色 - * @returns -*/ + * @returns + */ export const DelShoppingCartApi = () => { - return useRequest({ - url: `/v1/mall/shoppingCart/productColor`, - method: "delete", - }) + return useRequest({ + url: `/v1/mall/shoppingCart/productColor`, + method: 'delete', + }) } /** * 修改购物车数量 - * @returns -*/ + * @returns + */ export const UpdateShoppingCartApi = () => { - return useRequest({ - url: `/v1/mall/shoppingCart/productColor`, - method: "put", - }) -} \ No newline at end of file + return useRequest({ + url: `/v1/mall/shoppingCart/productColor`, + method: 'put', + }) +} diff --git a/src/common/constant.js b/src/common/constant.js index 49183c2..6f29d7c 100644 --- a/src/common/constant.js +++ b/src/common/constant.js @@ -21,15 +21,11 @@ export const UPLOAD_CDN_URL = `https://v0.api.upyun.com/` // cdn // export const IMG_CND_Prefix = CURRENT_ENV.includes('development')? "https://test.cdn.zzfzyc.com":"https://cdn.zzfzyc.com" -export const IMG_CND_Prefix = CURRENT_ENV.includes('development') - ? 'https://test.cdn.zzfzyc.com' - : 'https://test.cdn.zzfzyc.com' +export const IMG_CND_Prefix = CURRENT_ENV.includes('development') ? 'https://test.cdn.zzfzyc.com' : 'https://test.cdn.zzfzyc.com' //在线支付图片baseUrl // export const CAP_HTML_TO_IMAGE_BASE_URL = CURRENT_ENV.includes('development')? "https://test.zzfzyc.com":"https://www.zzfzyc.com" -export const CAP_HTML_TO_IMAGE_BASE_URL = CURRENT_ENV.includes('development') - ? 'https://test.zzfzyc.com' - : 'https://test.zzfzyc.com' +export const CAP_HTML_TO_IMAGE_BASE_URL = CURRENT_ENV.includes('development') ? 'https://test.zzfzyc.com' : 'https://test.zzfzyc.com' // 上传图片视频 export const CDN_UPLOAD_IMG = `${UPLOAD_CDN_URL || ''}` diff --git a/src/components/LabAndImg/index.module.scss b/src/components/LabAndImg/index.module.scss index a2c303f..e6f5a09 100644 --- a/src/components/LabAndImg/index.module.scss +++ b/src/components/LabAndImg/index.module.scss @@ -1,18 +1,16 @@ - -.labAndImg_main{ +.labAndImg_main { + width: 100%; + height: 100%; + .boxColor { width: 100%; height: 100%; - .boxColor{ - width: 100%; - height: 100%; - border-radius: 20px; - border:1PX solid #818181; - box-sizing: border-box; - } - image{ - width: 100%; - height: 100%; - border-radius: 20px; - } - + border-radius: 20px; + border: 1px solid #818181; + box-sizing: border-box; + } + .labAndImg_image { + width: 100%; + height: 100%; + border-radius: 20px !important; + } } diff --git a/src/components/LabAndImg/index.tsx b/src/components/LabAndImg/index.tsx index ddb93a7..7927786 100644 --- a/src/components/LabAndImg/index.tsx +++ b/src/components/LabAndImg/index.tsx @@ -1,62 +1,61 @@ -import { formatImgUrl, formatRemoveHashTag } from "@/common/fotmat"; -import Preview from "@/pages/details/components/preview"; -import { Image, View } from "@tarojs/components"; -import { memo, useCallback, useEffect, useMemo, useState } from "react"; +import { formatImgUrl, formatRemoveHashTag } from '@/common/fotmat' +import Preview from '@/pages/details/components/preview' +import { Image, View } from '@tarojs/components' +import { memo, useCallback, useEffect, useMemo, useState } from 'react' import styles from './index.module.scss' -import Taro from "@tarojs/taro"; -import LabAndImgShow from "../LabAndImgShow"; +import Taro from '@tarojs/taro' +import LabAndImgShow from '../LabAndImgShow' //该组件宽高为100%需调整外层元素宽高 type Param = { - value?: { - texture_url?: string, //纹理图路径 - lab?: {l:number, a:number, b:number}, //lab - rgb?: {r:number, g:number, b:number} //rgb - title?: string - }, - showStatus?: true|false, - onClick?: (val: Param['value']) => void + value?: { + texture_url?: string //纹理图路径 + lab?: { l: number; a: number; b: number } //lab + rgb?: { r: number; g: number; b: number } //rgb + title?: string + } + showStatus?: true | false + onClick?: (val: Param['value']) => void } -export default memo(({value, onClick, showStatus = false}:Param) => { - const [imgs, setImgs] = useState([]) +export default memo(({ value, onClick, showStatus = false }: Param) => { + const [imgs, setImgs] = useState([]) - //lab是否都是0 - const rgbStyle = useMemo(() => { - if(value?.lab&&(value.lab.l||value.lab.a||value.lab.b)) { - return {'backgroundColor':`rgb(${value.rgb?.r} ${value.rgb?.g} ${value.rgb?.b})`} - } else { - return null - } - }, [value]) - - useEffect(() => { - if(value?.texture_url) { - let res = value.texture_url.split(',').map(item => { - return formatImgUrl(item) - }) - setImgs(() => res) - } - }, [value]) - - const [labAndImgShow, setLabAndImgShow] = useState(false) - const closeLabAndImgShow = useCallback(() => { - setLabAndImgShow(false) - }, []) - const onShowLabAndImg = () => { - onClick?.(value) - if(!showStatus) return false - setLabAndImgShow(true) - + //lab是否都是0 + const rgbStyle = useMemo(() => { + if (value?.lab && (value.lab.l || value.lab.a || value.lab.b)) { + return { backgroundColor: `rgb(${value.rgb?.r} ${value.rgb?.g} ${value.rgb?.b})` } + } else { + return null } + }, [value]) - return ( - <> - onShowLabAndImg()}> - {imgs?.length > 0&&} - {(!imgs?.length&&rgbStyle)&&} - {(!imgs?.length&&!rgbStyle)&&} - - - - ) -}) \ No newline at end of file + useEffect(() => { + if (value?.texture_url) { + let res = value.texture_url.split(',').map((item) => { + return formatImgUrl(item) + }) + setImgs(() => res) + } + }, [value]) + + const [labAndImgShow, setLabAndImgShow] = useState(false) + const closeLabAndImgShow = useCallback(() => { + setLabAndImgShow(false) + }, []) + const onShowLabAndImg = () => { + onClick?.(value) + if (!showStatus) return false + setLabAndImgShow(true) + } + + return ( + <> + onShowLabAndImg()}> + {imgs?.length > 0 && } + {!imgs?.length && rgbStyle && } + {!imgs?.length && !rgbStyle && } + + + + ) +}) diff --git a/src/pages/order/components/addressInfoDetail/index.tsx b/src/pages/order/components/addressInfoDetail/index.tsx index 8173ab8..4a880ce 100644 --- a/src/pages/order/components/addressInfoDetail/index.tsx +++ b/src/pages/order/components/addressInfoDetail/index.tsx @@ -1,220 +1,219 @@ -import { GetAddressListApi } from "@/api/addressList"; -import { addressListApi } from "@/api/addressManager"; -import { EditSaleOrderAddressApi, EditSaleOrderShipmentModeApi } from "@/api/order"; -import { alert, goLink } from "@/common/common"; -import { ORDER_STATUS } from "@/common/enum"; -import { debounce, throttle } from "@/common/util"; -import AddressList from "@/components/AddressList"; -import Popup from "@/components/popup"; -import { Text, View } from "@tarojs/components" -import classnames from "classnames"; -import { forwardRef, memo, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react"; -import Taro from "@tarojs/taro"; -import styles from './index.module.scss' +import { GetAddressListApi } from '@/api/addressList' +import { addressListApi } from '@/api/addressManager' +import { EditSaleOrderAddressApi, EditSaleOrderShipmentModeApi } from '@/api/order' +import { alert, goLink } from '@/common/common' +import { ORDER_STATUS } from '@/common/enum' +import { debounce, throttle } from '@/common/util' +import AddressList from '@/components/AddressList' +import Popup from '@/components/popup' +import { Text, View } from '@tarojs/components' +import classnames from 'classnames' +import { forwardRef, memo, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react' +import Taro from '@tarojs/taro' +import styles from './index.module.scss' - -type Param = { - onSelect?: (val:any) => void, //选择地址 - disabled?: false|true, //true禁用后只用于展示 - onChangeShipmentMode?: (val: number) => void, //返回收货方式 - onLogistics?: () => void, //查看物流 - status?: 1|2, //1确认订单时使用, 2订单流程 - orderInfo?: { - id?: number //订单id - shipment_mode?: 1|2, //1自提 2物流 - status?: number //订单状态 - province_name: string, - city_name: string, - district_name: string, - address_detail: string, - take_goods_address: string, - take_goods_phone: string, - target_user_name: string, - target_user_phone: string - } +type Param = { + onSelect?: (val: any) => void //选择地址 + disabled?: false | true //true禁用后只用于展示 + onChangeShipmentMode?: (val: number) => void //返回收货方式 + onLogistics?: () => void //查看物流 + status?: 1 | 2 //1确认订单时使用, 2订单流程 + orderInfo?: { + id?: number //订单id + shipment_mode?: 1 | 2 //1自提 2物流 + status?: number //订单状态 + province_name: string + city_name: string + district_name: string + address_detail: string + take_goods_address: string + take_goods_phone: string + target_user_name: string + target_user_phone: string + } } -//订单状态 +//订单状态 const { - SaleorderstatusWaitingPrePayment, - SaleOrderStatusBooking, - SaleOrderStatusArranging, - SaleOrderStatusArranged, - SaleOrderStatusWaitingPayment, - SaleOrderStatusWaitingReceipt, - SaleOrderStatusAlreadyReceipt, - SaleOrderStatusComplete, - SaleOrderStatusRefund, - SaleOrderStatusCancel, + SaleorderstatusWaitingPrePayment, + SaleOrderStatusBooking, + SaleOrderStatusArranging, + SaleOrderStatusArranged, + SaleOrderStatusWaitingPayment, + SaleOrderStatusWaitingReceipt, + SaleOrderStatusAlreadyReceipt, + SaleOrderStatusComplete, + SaleOrderStatusRefund, + SaleOrderStatusCancel, } = ORDER_STATUS -export default memo(forwardRef(({onSelect, onChangeShipmentMode, orderInfo, status = 2, disabled = false, onLogistics}: Param, ref) => { - +export default memo( + forwardRef(({ onSelect, onChangeShipmentMode, orderInfo, status = 2, disabled = false, onLogistics }: Param, ref) => { const [addressInfo, setAddressInfo] = useState() useEffect(() => { - if(orderInfo) { - setReceivingStatus(() => orderInfo.shipment_mode||2) - setAddressInfo(() => orderInfo) - } + if (orderInfo) { + setReceivingStatus(() => orderInfo.shipment_mode || 2) + setAddressInfo(() => orderInfo) + } }, [orderInfo]) //打开地址列表 const [showAddressList, setShowAddressList] = useState(false) const changeShow = () => { - if(receivingStatus == 2 && !logisticsShow && limitEdit()) - setShowAddressList(() => true) + if (receivingStatus == 2 && !logisticsShow && limitEdit()) setShowAddressList(() => true) } //把内部方法提供给外部 useImperativeHandle(ref, () => ({ - changeShow + changeShow, })) //收货方法,1:自提,2物流 const [receivingStatus, setReceivingStatus] = useState(2) - const {fetchData: shipmentModeFetchData} = EditSaleOrderShipmentModeApi() + const { fetchData: shipmentModeFetchData } = EditSaleOrderShipmentModeApi() const onReceivingStatus = async (value, e) => { - e.stopPropagation() - if(limitEdit()) changeReceivingStatus(value) - + e.stopPropagation() + if (limitEdit()) changeReceivingStatus(value) } //当没有地址时获取地址列表中的第一个数据 - const {fetchData: addressListFetchData} = addressListApi() + const { fetchData: addressListFetchData } = addressListApi() const getAddressListOne = async () => { - if(orderInfo?.address_detail) return true - let res = await addressListFetchData() - if( res.data.list && res.data.list?.length > 0 ) { - let info = res.data.list[0] - await addressFetchData({id: orderInfo?.id, address_id: info.id}) - setAddressInfo((e) => ({...e, ...info, target_user_name: info.name, target_user_phone: info.phone})) - return true - } else { - Taro.showModal({ - content: '您还没有地址,请前去新增地址', - success: function (res) { - if (res.confirm) { - goLink('/pages/addressManager/index') - } else if (res.cancel) { - console.log('用户点击取消') - } - } - }) - return false - } - - + if (orderInfo?.address_detail) return true + let res = await addressListFetchData() + if (res.data.list && res.data.list?.length > 0) { + let info = res.data.list[0] + await addressFetchData({ id: orderInfo?.id, address_id: info.id }) + setAddressInfo((e) => ({ ...e, ...info, target_user_name: info.name, target_user_phone: info.phone })) + return true + } else { + Taro.showModal({ + content: '您还没有地址,请前去新增地址', + success: function (res) { + if (res.confirm) { + goLink('/pages/addressManager/index') + } else if (res.cancel) { + console.log('用户点击取消') + } + }, + }) + return false + } } - + const changeReceivingStatus = debounce(async (value) => { - if(!orderInfo || value == receivingStatus) return false - if(status == 1) { - onChangeShipmentMode?.(value) - setReceivingStatus(value) - return false - } - if(value == 2) { - let res = await getAddressListOne() - if(!res) return false - } - alert.loading('正在修改') - const res = await shipmentModeFetchData({id: orderInfo.id, shipment_mode:value}) - if(res.success) { - alert.success('收货方式修改成功') - onChangeShipmentMode?.(value) - setReceivingStatus(() => value) - } else { - alert.none(res.msg) - } + if (!orderInfo || value == receivingStatus) return false + if (status == 1) { + onChangeShipmentMode?.(value) + setReceivingStatus(value) + return false + } + if (value == 2) { + let res = await getAddressListOne() + if (!res) return false + } + alert.loading('正在修改') + const res = await shipmentModeFetchData({ id: orderInfo.id, shipment_mode: value }) + if (res.success) { + alert.success('收货方式修改成功') + onChangeShipmentMode?.(value) + setReceivingStatus(() => value) + } else { + alert.none(res.msg) + } }, 300) //修改地址 const [addressId, setAddressId] = useState(0) - const {fetchData: addressFetchData} = EditSaleOrderAddressApi() + const { fetchData: addressFetchData } = EditSaleOrderAddressApi() const getAddress = async (value) => { - if(!orderInfo) return false - if(status == 1) { - setShowAddressList(() => false) - setAddressId(value.id) - setAddressInfo((e) => ({...e, ...value, target_user_name: value.name, target_user_phone: value.phone})) - onSelect?.(value) - return false - } - alert.loading('正在修改') - const res = await addressFetchData({id: orderInfo.id, address_id: value.id}) - if(res.success) { - alert.success('地址修改成功') - onSelect?.(value) - setShowAddressList(() => false) - setAddressId(value.id) - setAddressInfo((e) => ({...e, ...value, target_user_name: value.name, target_user_phone: value.phone})) - } else { - alert.none(res.msg) - } + if (!orderInfo) return false + if (status == 1) { + setShowAddressList(() => false) + setAddressId(value.id) + setAddressInfo((e) => ({ ...e, ...value, target_user_name: value.name, target_user_phone: value.phone })) + onSelect?.(value) + return false + } + alert.loading('正在修改') + const res = await addressFetchData({ id: orderInfo.id, address_id: value.id }) + if (res.success) { + alert.success('地址修改成功') + onSelect?.(value) + setShowAddressList(() => false) + setAddressId(value.id) + setAddressInfo((e) => ({ ...e, ...value, target_user_name: value.name, target_user_phone: value.phone })) + } else { + alert.none(res.msg) + } } //根据订单状态判断是否可修改 const limitEdit = () => { - let res = [ - SaleorderstatusWaitingPrePayment.value, - SaleOrderStatusBooking.value, - SaleOrderStatusArranging.value, - SaleOrderStatusArranged.value, - SaleOrderStatusWaitingPayment.value, - ].includes(orderInfo?.status as number) - if(!res && status != 1) alert.none('该订单状态不能修改地址!') - return status == 1? true : res + let res = [SaleorderstatusWaitingPrePayment.value, SaleOrderStatusBooking.value, SaleOrderStatusArranging.value, SaleOrderStatusArranged.value, SaleOrderStatusWaitingPayment.value].includes( + orderInfo?.status as number, + ) + if (!res && status != 1) alert.none('该订单状态不能修改地址!') + return status == 1 ? true : res } - //根据订单状态判断是否显示物流 const logisticsShowList = [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value] const logisticsShow = useMemo(() => { - return logisticsShowList.includes(orderInfo?.status as number) + return logisticsShowList.includes(orderInfo?.status as number) }, [orderInfo]) //地址格式 const formatAddress = useMemo(() => { - if(receivingStatus == 2) { - return addressInfo?.address_detail?addressInfo.province_name + addressInfo.city_name + addressInfo.district_name + addressInfo.address_detail:'' - } else { - return addressInfo?.take_goods_address - } + if (receivingStatus == 2) { + return addressInfo?.address_detail ? addressInfo.province_name + addressInfo.city_name + addressInfo.district_name + addressInfo.address_detail : '' + } else { + return addressInfo?.take_goods_address + } }, [receivingStatus, addressInfo]) return ( - - changeShow()}> - - - - {formatAddress||'请选择收货地址及信息'} - {(receivingStatus == 2 && !logisticsShow)&&} - - - {receivingStatus == 1?'管理员':addressInfo?.target_user_name} - {receivingStatus == 1?addressInfo?.take_goods_phone: addressInfo?.target_user_phone} - - - {!logisticsShow&& - - onReceivingStatus(1,e)}>自提 - onReceivingStatus(2,e)}>物流 - - - || - (orderInfo?.status != SaleOrderStatusRefund.value)&& - 查看物流 - } + + changeShow()}> + + + + {formatAddress || '请选择收货地址及信息'} + {receivingStatus == 2 && !logisticsShow && } - setShowAddressList(false)}> - - 请选择收货地址 - - - + + {receivingStatus == 1 ? '谭先生' : addressInfo?.target_user_name} + {receivingStatus == 1 ? addressInfo?.take_goods_phone : addressInfo?.target_user_phone} + + + {(!logisticsShow && ( + + + onReceivingStatus(1, e)}> + 自提 - + onReceivingStatus(2, e)}> + 物流 + + + + + )) || + (orderInfo?.status != SaleOrderStatusRefund.value && ( + + 查看物流 + + ))} + setShowAddressList(false)}> + + 请选择收货地址 + + + + + + ) -})) \ No newline at end of file + }), +) diff --git a/src/pages/order/components/applyRefund/index.module.scss b/src/pages/order/components/applyRefund/index.module.scss index ec17129..dc7e177 100644 --- a/src/pages/order/components/applyRefund/index.module.scss +++ b/src/pages/order/components/applyRefund/index.module.scss @@ -1,66 +1,67 @@ - -.apply_after_sales_con{ - padding: 20px; - .returnSaleInput_item{ - display: flex; - align-items: center; - padding-bottom: 50px; - flex-wrap: wrap; - .title{ - font-size: $font_size; - font-weight: 700; - width: 119px; - } - .select{ - flex:1; - height: 60px; - border: 2px solid #e6e6e6; - border-radius: 10px; - margin-left: 20px; - display: flex; - align-items: center; - justify-content: space-between; - padding: 0 20px; - font-size: 26px; - color: $color_font_two; - .miconfont{ - font-size: 30px; - } - } - .upload_image{ - flex:1; - } +.apply_after_sales_con { + padding: 20px; + .returnSaleInput_item { + display: flex; + align-items: center; + padding-bottom: 50px; + flex-wrap: wrap; + .title { + font-size: $font_size; + font-weight: 700; + width: 119px; } - .btns_con{ - width: 100%; - bottom:0; - box-sizing: border-box; - margin-top: 50px; - .btns_two{ - display: flex; - height: 82px; - // border: 1PX solid #007aff; - font-size: $font_size_big; - border-radius: 40px; - margin-bottom: 20px; - .rest_btn{ - flex:1; - border: 1PX solid #007aff; - border-radius: 40px 0 0 40px; - text-align: center; - line-height: 82px; - color: $color_main; - background-color: #fff; - - } - .verify_btn{ - flex:1; - border-radius: 0 40px 40px 0; - background: #007aff; - text-align: center; - line-height: 82px; - color: #fff; - } - } + .select { + flex: 1; + height: 60px; + border: 2px solid #e6e6e6; + border-radius: 10px; + margin-left: 20px; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 20px; + font-size: 26px; + color: $color_font_two; + .miconfont { + font-size: 30px; + } + .selected { + color: #000; + } } -} \ No newline at end of file + .upload_image { + flex: 1; + } + } + .btns_con { + width: 100%; + bottom: 0; + box-sizing: border-box; + margin-top: 50px; + .btns_two { + display: flex; + height: 82px; + // border: 1PX solid #007aff; + font-size: $font_size_big; + border-radius: 40px; + margin-bottom: 20px; + .rest_btn { + flex: 1; + border: 1px solid #007aff; + border-radius: 40px 0 0 40px; + text-align: center; + line-height: 82px; + color: $color_main; + background-color: #fff; + } + .verify_btn { + flex: 1; + border-radius: 0 40px 40px 0; + background: #007aff; + text-align: center; + line-height: 82px; + color: #fff; + } + } + } +} diff --git a/src/pages/order/components/applyRefund/index.tsx b/src/pages/order/components/applyRefund/index.tsx index f467eb3..5dc3ed3 100644 --- a/src/pages/order/components/applyRefund/index.tsx +++ b/src/pages/order/components/applyRefund/index.tsx @@ -1,111 +1,112 @@ -import Popup from "@/components/popup"; -import TextareaEnhance from "@/components/textareaEnhance"; -import { ScrollView, Text, View } from "@tarojs/components"; -import { memo, useCallback, useEffect, useRef, useState } from "react"; -import ReasonPopup from "../reasonPopup"; -import styles from './index.module.scss' -import classnames from "classnames"; -import { ApplyRefundApi, RefundExplainApi } from "@/api/salesAfterOrder"; -import { alert } from "@/common/common"; +import Popup from '@/components/popup' +import TextareaEnhance from '@/components/textareaEnhance' +import { ScrollView, Text, View } from '@tarojs/components' +import { memo, useCallback, useEffect, useRef, useState } from 'react' +import ReasonPopup from '../reasonPopup' +import styles from './index.module.scss' +import classnames from 'classnames' +import { ApplyRefundApi, RefundExplainApi } from '@/api/salesAfterOrder' +import { alert } from '@/common/common' type Param = { - show?: true|false, - onClose?: () => void, - orderId?: number + show?: true | false + onClose?: () => void + orderId?: number + onSuccess?: () => void } -export default memo(({show, onClose, orderId}:Param) => { +export default memo(({ show, onClose, orderId, onSuccess }: Param) => { + //提交的数据 + const submitData = useRef({ + return_explain: 0, + sale_order_id: 0, + reason_describe: '', + }) - //提交的数据 - const submitData = useRef({ + useEffect(() => { + if (show && orderId) { + submitData.current.sale_order_id = orderId + refundExplain() + } + }, [orderId, show]) + + //申请退款 + const { fetchData } = ApplyRefundApi() + const getApplyRefund = async () => { + if (!submitData.current.return_explain) return alert.error('请选择说明原因') + let res = await fetchData(submitData.current) + if (res.success) { + alert.success('申请成功') + onSuccess?.() + } else { + alert.error('申请失败') + } + onClose?.() + } + + //获取说明数据 + const [list, setList] = useState([]) + const { fetchData: refundExplainFetchdata } = RefundExplainApi() + const refundExplain = async () => { + let res = await refundExplainFetchdata() + setList(() => res.data.list) + } + const [reason, setReason] = useState({ id: 0, name: '' }) + const reasonSelect = useCallback((e) => { + setReason({ ...reason, name: e.name, id: e.id }) + submitData.current.return_explain = e.id + closeReason() + }, []) + + //备注 + const getOtherReason = useCallback((val) => { + submitData.current.reason_describe = val + }, []) + + //显示说明 + const [showReason, setShowReason] = useState(false) + const closeReason = useCallback(() => { + setShowReason(false) + }, []) + + //提交 + const onSubmit = (val) => { + if (val == 2) { + getApplyRefund() + } else { + onClose?.() + submitData.current = { return_explain: 0, sale_order_id: 0, - reason_describe: '' - }) - - useEffect(() => { - console.log('show&&orderId::', show) - if(show&&orderId) { - submitData.current.sale_order_id = orderId - refundExplain() - } - }, [orderId, show]) - - //申请退款 - const {fetchData} = ApplyRefundApi() - const getApplyRefund = async () => { - if(!submitData.current.return_explain) return alert.error('请选择说明原因') - let res = await fetchData(submitData.current) - if(res.success) { - alert.error('申请成功') - } else { - alert.error('申请失败') - } - onClose?.() + reason_describe: '', + } } + } - //获取说明数据 - const [list, setList] = useState([]) - const {fetchData: refundExplainFetchdata} = RefundExplainApi() - const refundExplain = async () => { - let res = await refundExplainFetchdata() - setList(() => res.data.list) - } - const [reason, setReason] = useState({id:0, name:''}) - const reasonSelect = useCallback((e) => { - setReason({...reason, name:e.name, id:e.id}) - submitData.current.return_explain = e.id - closeReason() - }, []) - - - //备注 - const getOtherReason = useCallback((val) => { - submitData.current.reason_describe = val - }, []) - - - //显示说明 - const [showReason, setShowReason] = useState(false) - const closeReason = useCallback(() => { - setShowReason(false) - }, []) - - - //提交 - const onSubmit = (val) => { - if(val == 2) { - getApplyRefund() - } else { - onClose?.() - submitData.current = { - return_explain: 0, - sale_order_id: 0, - reason_describe: '' - } - } - } - - return ( - <> - - - - 退款说明 - setShowReason(true)}> - {reason.name||'请选择'} - - - - - - - onSubmit(1)}>取消 - onSubmit(2)}>确认 - - - - - - - ) -}) \ No newline at end of file + return ( + <> + + + + 退款说明 + setShowReason(true)}> + {reason.name || '请选择'} + + + + + + + onSubmit(1)}> + 取消 + + onSubmit(2)}> + 确认 + + + + + + + + ) +}) diff --git a/src/pages/order/index.tsx b/src/pages/order/index.tsx index 3be5a80..f858de6 100644 --- a/src/pages/order/index.tsx +++ b/src/pages/order/index.tsx @@ -221,6 +221,9 @@ export default () => { const applyRefundClose = useCallback(() => { setRefundShow(false) }, []) + const applyRefundSuccess = useCallback(() => { + getSaleOrderPreView() + }, []) //查看物流 const getLogistics = useCallback(() => { @@ -281,17 +284,9 @@ export default () => { return ( - {(orderDetail?.status != SaleorderstatusWaitingPrePayment.value && ) || ( - - )} + {(orderDetail?.status != SaleorderstatusWaitingPrePayment.value && ) || } - + @@ -315,9 +310,7 @@ export default () => { 订单备注 - {(orderRemark && {orderDetail?.remark}) || ( - 填写备注 - )} + {(orderRemark && {orderDetail?.remark}) || 填写备注} {orderDetail?.status != SaleOrderStatusCancel.value && ( @@ -331,7 +324,7 @@ export default () => { setShowScanPayCheck(false)} orderInfo={orderDetail} /> - + setShowCart(false)} /> diff --git a/src/pages/order/orderList/components/order/index.tsx b/src/pages/order/orderList/components/order/index.tsx index 27561d0..b52f925 100644 --- a/src/pages/order/orderList/components/order/index.tsx +++ b/src/pages/order/orderList/components/order/index.tsx @@ -1,146 +1,163 @@ -import { goLink } from "@/common/common"; -import { ORDER_STATUS } from "@/common/enum"; -import { formatHashTag, formatImgUrl, formatPriceDiv } from "@/common/fotmat"; -import LabAndImg from "@/components/LabAndImg"; -import OrderBtns from "@/components/orderBtns"; -import Payment from "@/pages/order/components/payment"; -import { useSelector } from "@/reducers/hooks"; -import { Image, Text, View } from "@tarojs/components" -import { useRouter } from "@tarojs/taro"; -import classnames from "classnames"; -import { memo, useCallback, useMemo, useRef, useState } from "react"; -import styles from './index.module.scss' +import { goLink } from '@/common/common' +import { ORDER_STATUS } from '@/common/enum' +import { formatHashTag, formatImgUrl, formatPriceDiv } from '@/common/fotmat' +import LabAndImg from '@/components/LabAndImg' +import OrderBtns from '@/components/orderBtns' +import Payment from '@/pages/order/components/payment' +import { useSelector } from '@/reducers/hooks' +import { Image, Text, View } from '@tarojs/components' +import { useRouter } from '@tarojs/taro' +import classnames from 'classnames' +import { memo, useCallback, useMemo, useRef, useState } from 'react' +import styles from './index.module.scss' type Param = { - value: { - order_no: string, - sale_mode: number, - sale_mode_name: string, - status_name: string, - shipment_mode: number, - shipment_mode_name: string, - product_list: any[], - total_fabrics: number, - total_colors: number, - total_number: number, - status: 0, - id: number, - lab: any, - rgb: any, - texture_url: string, - payment_method: number, //支付方式 - actual_amount: number, //实付金额 - wait_pay_amount: number, //待付金额 - should_collect_order_id: number, //应付单id - av_return_roll: number, - total_sale_price: number, - estimate_amount: number, - is_return: true|false - }, - onClickBtn?: (val:{status:number, orderInfo:Param['value']}) => void + value: { + order_no: string + sale_mode: number + sale_mode_name: string + status_name: string + shipment_mode: number + shipment_mode_name: string + product_list: any[] + total_fabrics: number + total_colors: number + total_number: number + status: 0 + id: number + lab: any + rgb: any + texture_url: string + payment_method: number //支付方式 + actual_amount: number //实付金额 + wait_pay_amount: number //待付金额 + should_collect_order_id: number //应付单id + av_return_roll: number + total_sale_price: number + estimate_amount: number + is_return: true | false + } + onClickBtn?: (val: { status: number; orderInfo: Param['value'] }) => void } -export default memo(({value, onClickBtn}: Param) => { +export default memo(({ value, onClickBtn }: Param) => { + const userInfo = useSelector((state) => state.userInfo) + //对应数量 + const formatCount = useCallback( + (item, sale_mode) => { + return sale_mode == 0 ? item.roll : Number(item.length / 100) + }, + [value], + ) + //对应单价 + const standardPrice = useCallback( + (price, sale_mode) => { + return '¥' + formatPriceDiv(price).toLocaleString() + '/' + (sale_mode == 1 ? 'm' : 'kg') + }, + [value], + ) - const userInfo = useSelector(state => state.userInfo) - //对应数量 - const formatCount = useCallback((item, sale_mode) => { - return sale_mode == 0? item.roll : Number(item.length / 100) - }, [value]) - //对应单价 - const standardPrice = useCallback((price, sale_mode) => { - return '¥' + formatPriceDiv(price).toLocaleString() + '/' + (sale_mode == 1?'m':'kg') - }, [value]) + //点击订单按钮 + const orderBtnsClick = useCallback( + (status) => { + onClickBtn?.({ status, orderInfo: value }) + }, + [value], + ) - //点击订单按钮 - const orderBtnsClick = useCallback((status) => { - onClickBtn?.({status, orderInfo:value}) - }, [value]) + let { SaleOrderStatusTaking, SaleOrderStatusWaitingReceipt } = ORDER_STATUS - let {SaleOrderStatusTaking, SaleOrderStatusWaitingReceipt} = ORDER_STATUS + //订单状态 + // const orderStatus = useCallback((item) => { + // return item.status == SaleOrderStatusTaking.value?'装车中':item.status_name + // }, [value]) - //订单状态 - // const orderStatus = useCallback((item) => { - // return item.status == SaleOrderStatusTaking.value?'装车中':item.status_name - // }, [value]) + //按钮所需数据 + const orderInfo = useMemo(() => { + return { + orderId: value?.id, + ...value, + } + }, [value]) - //按钮所需数据 - const orderInfo = useMemo(() => { - return { - orderId: value?.id, - ...value - } - }, [value]) + //总条数 + const numText = useMemo(() => { + let total_number_new = value?.sale_mode == 0 ? value?.total_number : value?.total_number / 100 + return `${value?.total_fabrics} 种面料,${value?.total_colors} 种颜色,共 ${total_number_new}${value?.sale_mode == 0 ? ' 条' : ' 米'}` + }, [value]) - //总条数 - const numText = useMemo(() => { - let total_number_new = value?.sale_mode == 0? value?.total_number:(value?.total_number/100) - return `${value?.total_fabrics} 种面料,${value?.total_colors} 种颜色,共 ${total_number_new}${value?.sale_mode == 0? ' 条':' 米'}` - }, [value]) + //订单状态 + const orderStatus = useMemo(() => { + if (value.status == SaleOrderStatusWaitingReceipt.value && value.shipment_mode == 1) { + return '待提货' + } else { + return value?.status_name + } + }, [value]) - //订单状态 - const orderStatus = useMemo(() => { - if(value.status == SaleOrderStatusWaitingReceipt.value && value.shipment_mode == 1) { - return '待提货' - } else { - return value?.status_name - } - }, [value]) - - return ( - - goLink('/pages/order/index', {id: value?.id})}> - - - - - {userInfo?.adminUserInfo?.user_name} - - - 订单号:{value?.order_no} - - - {orderStatus} - - - - - - goLink('/pages/order/index', {id: value?.id})}> - - {value?.sale_mode_name} - {formatHashTag(value?.product_list?.[0].code, value?.product_list?.[0].name)} - {value?.shipment_mode_name} - - - - - {value?.product_list?.[0].product_colors?.[0].code} - - - {value?.product_list?.[0].product_colors.map((itemColor, index) => { - return ( - (index <= 1)&& - {formatHashTag(itemColor.code, itemColor.name)} - {standardPrice(itemColor.sale_price, value.sale_mode)} - ×{formatCount(itemColor, value.sale_mode) + (value.sale_mode == 0?' 条':' 米')} - - ) - }) - } - {value?.product_list?.[0].length > 2 && - …… - …… - …… - } - - - - {numText} - ¥{value.total_sale_price?formatPriceDiv(value.total_sale_price, 100, true):formatPriceDiv(value.estimate_amount, 100, true)} - - - + return ( + + goLink('/pages/order/index', { id: value?.id })}> + + - ) + + {userInfo?.adminUserInfo?.user_name} + + + 订单号:{value?.order_no} + + + {orderStatus} + + + + goLink('/pages/order/index', { id: value?.id })}> + + {value?.sale_mode_name} + {formatHashTag(value?.product_list?.[0].code, value?.product_list?.[0].name)} + {value?.shipment_mode_name} + + + + + {value?.product_list?.[0].product_colors?.[0].code} + + + {value?.product_list?.[0].product_colors.map((itemColor, index) => { + return ( + index <= 1 && ( + + {formatHashTag(itemColor.code, itemColor.name)} + {standardPrice(itemColor.sale_price, value.sale_mode)} + ×{formatCount(itemColor, value.sale_mode) + (value.sale_mode == 0 ? ' 条' : ' 米')} + + ) + ) + })} + {value?.product_list?.[0].length > 2 && ( + + …… + …… + …… + + )} + + + + {numText} + + ¥ + {value.total_sale_price ? formatPriceDiv(value.total_sale_price, 100, true) : formatPriceDiv(value.estimate_amount, 100, true)} + + + + + + ) }) - diff --git a/src/pages/order/orderList/index.tsx b/src/pages/order/orderList/index.tsx index d50bd1e..c9f3c02 100644 --- a/src/pages/order/orderList/index.tsx +++ b/src/pages/order/orderList/index.tsx @@ -181,6 +181,9 @@ export default () => { const applyRefundClose = useCallback(() => { setRefundShow(false) }, []) + const applyRefundSuccess = useCallback(() => { + getOrderList() + }, []) //显示售后记录 const [returnRecordShow, setReturnRecordShow] = useState(false) @@ -210,14 +213,13 @@ export default () => { {orderData?.list?.map((item) => { return ( - {' '} ) })} - + setShowCart(false)} default_sale_mode={callBackOrderInfo?.sale_mode} /> diff --git a/src/pages/salesAfter/components/addressInfoDetail/index.tsx b/src/pages/salesAfter/components/addressInfoDetail/index.tsx index e8336f5..fb99242 100644 --- a/src/pages/salesAfter/components/addressInfoDetail/index.tsx +++ b/src/pages/salesAfter/components/addressInfoDetail/index.tsx @@ -1,84 +1,81 @@ -import { AFTER_ORDER_STATUS, REFUND_STATUS_ORDER } from "@/common/enum"; -import { Text, View } from "@tarojs/components" -import classnames from "classnames"; -import {memo, useMemo} from "react"; -import styles from './index.module.scss' +import { AFTER_ORDER_STATUS, REFUND_STATUS_ORDER } from '@/common/enum' +import { Text, View } from '@tarojs/components' +import classnames from 'classnames' +import { memo, useMemo } from 'react' +import styles from './index.module.scss' type Param = { - onLogistics?: (val: 1|2) => void, //1 上传物流 2 查看物流 - orderInfo: { - return_user_name?:string, - return_user_phone?: string, - stage?: number, - sale_mode?: 0|1|2, //0 大货 1剪板 2散剪 - type?: number, //申请单退款状态 - } - + onLogistics?: (val: 1 | 2) => void //1 上传物流 2 查看物流 + orderInfo: { + return_user_name?: string + return_user_phone?: string + stage?: number + sale_mode?: 0 | 1 | 2 //0 大货 1剪板 2散剪 + type?: number //申请单退款状态 + return_address?: string + } } -export default memo(({orderInfo, onLogistics}:Param) => { - const { - ReturnStageApplying, - ReturnStageWaitCheck, - ReturnStageChecked, - ReturnStageReturned, - ReturnStageCancel, - ReturnStageQualityCheckPendingRefund, - ReturnStageServiceOrderPendingRefund, - ReturnStageRejected - } = AFTER_ORDER_STATUS +export default memo(({ orderInfo, onLogistics }: Param) => { + const { + ReturnStageApplying, + ReturnStageWaitCheck, + ReturnStageChecked, + ReturnStageReturned, + ReturnStageCancel, + ReturnStageQualityCheckPendingRefund, + ReturnStageServiceOrderPendingRefund, + ReturnStageRejected, + } = AFTER_ORDER_STATUS - const { - ReturnApplyOrderTypeAdvanceReceiptRefund, // 预收退款 - ReturnApplyOrderTypeReturnForRefund, // 退货退款 - ReturnApplyOrderTypeSalesRefund, // 销售退款 - } = REFUND_STATUS_ORDER + const { + ReturnApplyOrderTypeAdvanceReceiptRefund, // 预收退款 + ReturnApplyOrderTypeReturnForRefund, // 退货退款 + ReturnApplyOrderTypeSalesRefund, // 销售退款 + } = REFUND_STATUS_ORDER - //是否显示地址 - const showAddress = useMemo(() => { - let after_list = [ - ReturnStageApplying.value, - ReturnStageCancel.value, - ReturnStageRejected.value - ] - let refurn_list = [ - ReturnApplyOrderTypeSalesRefund.value, - ReturnApplyOrderTypeAdvanceReceiptRefund.value - ] - return (!after_list.includes(orderInfo?.stage!)) && (orderInfo?.sale_mode != 1) && (!refurn_list.includes(orderInfo?.type!)) - }, [orderInfo]) + //是否显示地址 + const showAddress = useMemo(() => { + let after_list = [ReturnStageApplying.value, ReturnStageCancel.value, ReturnStageRejected.value] + let refurn_list = [ReturnApplyOrderTypeSalesRefund.value, ReturnApplyOrderTypeAdvanceReceiptRefund.value] + return !after_list.includes(orderInfo?.stage!) && orderInfo?.sale_mode != 1 && !refurn_list.includes(orderInfo?.type!) + }, [orderInfo]) - //上传物流 - const upLogistics = useMemo(() => { - return orderInfo?.stage == ReturnStageWaitCheck.value - }, [orderInfo]) + //上传物流 + const upLogistics = useMemo(() => { + return orderInfo?.stage == ReturnStageWaitCheck.value + }, [orderInfo]) - - return ( - <> - {showAddress&& - - - 请按以下退货地址寄回货物并提供退货物流信息 - - - - - - {orderInfo?.return_user_name} - - - 管理员 - {orderInfo?.return_user_phone} - {upLogistics&& onLogistics?.(1)}> - 上传物流 - - || onLogistics?.(2)}> - 查看物流 - } - - - - } - - ) -}) \ No newline at end of file + return ( + <> + {showAddress && ( + + + + 请按以下退货地址寄回货物并提供退货物流信息 + + + + + + {orderInfo?.return_address} + + + 谭先生 + {orderInfo?.return_user_phone} + {(upLogistics && ( + onLogistics?.(1)}> + 上传物流 + + )) || ( + onLogistics?.(2)}> + 查看物流 + + )} + + + + + )} + + ) +}) diff --git a/src/pages/salesAfter/components/applyRecord/index.tsx b/src/pages/salesAfter/components/applyRecord/index.tsx index 056aab9..d704020 100644 --- a/src/pages/salesAfter/components/applyRecord/index.tsx +++ b/src/pages/salesAfter/components/applyRecord/index.tsx @@ -1,136 +1,148 @@ -import { SaleOrderOrderDetailApi } from "@/api/salesAfterOrder"; -import { formatHashTag, formatPriceDiv, formatWeightDiv } from "@/common/fotmat"; -import LabAndImg from "@/components/LabAndImg"; -import Popup from "@/components/popup"; -import { ScrollView, Text, View } from "@tarojs/components"; -import { memo, useCallback, useEffect, useMemo, useState } from "react"; -import Taro from "@tarojs/taro"; -import styles from './index.module.scss' +import { SaleOrderOrderDetailApi } from '@/api/salesAfterOrder' +import { formatHashTag, formatPriceDiv, formatWeightDiv } from '@/common/fotmat' +import LabAndImg from '@/components/LabAndImg' +import Popup from '@/components/popup' +import { ScrollView, Text, View } from '@tarojs/components' +import { memo, useCallback, useEffect, useMemo, useState } from 'react' +import Taro from '@tarojs/taro' +import styles from './index.module.scss' type Param = { - show?: true|false, - onClose?: () => void, - onSubmit?: () => void, - id?: number + show?: true | false + onClose?: () => void + onSubmit?: () => void + id?: number } -export default memo(({show, onClose, onSubmit, id}:Param) => { - useEffect(() => { - if(show && id) getSaleOrderPreView() - if(!show) setFormatDetailOrder(() => null) - }, [show, id]) +export default memo(({ show, onClose, onSubmit, id }: Param) => { + useEffect(() => { + if (show && id) getSaleOrderPreView() + if (!show) setFormatDetailOrder(() => null) + }, [show, id]) - - //获取订单详情 - const [orderDetail, setOrderDetail] = useState(null) //获取到的原始数据 - const {fetchData: saleOrderOrderDetailData} = SaleOrderOrderDetailApi() - const getSaleOrderPreView = async () => { - if(id) { - let res = await saleOrderOrderDetailData({id: id}) - setOrderDetail(res.data) - } - Taro.stopPullDownRefresh() + //获取订单详情 + const [orderDetail, setOrderDetail] = useState(null) //获取到的原始数据 + const { fetchData: saleOrderOrderDetailData } = SaleOrderOrderDetailApi() + const getSaleOrderPreView = async () => { + if (id) { + let res = await saleOrderOrderDetailData({ id: id }) + setOrderDetail(res.data) } - //格式化数据格式 - const [formatDetailOrder, setFormatDetailOrder] = useState() //格式化后的数据 - const formatData = () => { - setFormatDetailOrder({ - estimate_amount: orderDetail.estimate_amount, //预估金额 - sale_mode: orderDetail.sale_mode, - sale_mode_name: orderDetail.sale_mode_name, - total_colors: orderDetail.total_colors, //总颜色数量 - total_number: orderDetail.total_number, //总数量 - total_fabrics: orderDetail.total_fabrics, //面料数量 - unit: orderDetail.sale_mode == 0?'条':'m', //单位 - list: orderDetail.product_list, - stage: orderDetail.stage, //订单状态 - type: orderDetail.type, //退货or退款 - total_sale_price: orderDetail.total_sale_price, //销售金额 - total_should_collect_money: orderDetail.total_should_collect_money, //应收金额 - total_weight_error_discount: orderDetail.total_weight_error_discount, //空差优惠 - actual_amount: orderDetail.actual_amount, //实付金额 - the_previous_status: orderDetail.the_previous_status, //取消订单时的订单状态 - }) + Taro.stopPullDownRefresh() + } + //格式化数据格式 + const [formatDetailOrder, setFormatDetailOrder] = useState() //格式化后的数据 + const formatData = () => { + setFormatDetailOrder({ + estimate_amount: orderDetail.estimate_amount, //预估金额 + sale_mode: orderDetail.sale_mode, + sale_mode_name: orderDetail.sale_mode_name, + total_colors: orderDetail.total_colors, //总颜色数量 + total_number: orderDetail.total_number, //总数量 + total_fabrics: orderDetail.total_fabrics, //面料数量 + unit: orderDetail.sale_mode == 0 ? '条' : 'm', //单位 + list: orderDetail.product_list, + stage: orderDetail.stage, //订单状态 + type: orderDetail.type, //退货or退款 + total_sale_price: orderDetail.total_sale_price, //销售金额 + total_should_collect_money: orderDetail.total_should_collect_money, //应收金额 + total_weight_error_discount: orderDetail.total_weight_error_discount, //空差优惠 + actual_amount: orderDetail.actual_amount, //实付金额 + the_previous_status: orderDetail.the_previous_status, //取消订单时的订单状态 + }) + } + + //监听获取到的数据 + useEffect(() => { + if (orderDetail) formatData() + }, [orderDetail]) + + //对应数量 + const formatCount = useCallback( + (item) => { + return formatDetailOrder?.sale_mode == 0 ? item.roll : Number(item.length / 100) + }, + [formatDetailOrder], + ) + + //对应单价 + const standardPrice = useCallback( + (price) => { + return formatPriceDiv(price).toLocaleString() + '/' + (formatDetailOrder?.sale_mode == 1 ? 'm' : 'kg') + }, + [formatDetailOrder], + ) + + //数量格式 + const numText = useMemo(() => { + if (formatDetailOrder) { + let tatal_number = formatDetailOrder?.sale_mode == 0 ? formatDetailOrder?.total_number : formatDetailOrder?.total_number / 100 + return `${formatDetailOrder?.total_fabrics} 种面料,${formatDetailOrder?.total_colors} 种颜色,共 ${tatal_number} ${formatDetailOrder?.unit}` } + }, [formatDetailOrder]) - //监听获取到的数据 - useEffect(() => { - if(orderDetail) - formatData() - }, [orderDetail]) + //整理颜色 + const labAndRgbAndUrl = useCallback((item) => { + return { lab: { ...item?.lab }, rgb: { ...item?.rgb }, texturl_url: item?.texturl_url } + }, []) - //对应数量 - const formatCount = useCallback((item) => { - return formatDetailOrder?.sale_mode == 0? item.roll : Number(item.length / 100) - }, [formatDetailOrder]) - - //对应单价 - const standardPrice = useCallback(price => { - return formatPriceDiv(price).toLocaleString() + '/' + (formatDetailOrder?.sale_mode == 1?'m':'kg') - }, [formatDetailOrder]) - - //数量格式 - const numText = useMemo(() => { - if(formatDetailOrder) { - let tatal_number = formatDetailOrder?.sale_mode == 0?formatDetailOrder?.total_number:formatDetailOrder?.total_number/100 - return `${formatDetailOrder?.total_fabrics} 种面料,${formatDetailOrder?.total_colors} 种颜色,共 ${tatal_number}${formatDetailOrder?.unit}` - } - }, [formatDetailOrder]) - - //整理颜色 - const labAndRgbAndUrl = useCallback((item) => { - return {lab:{...item?.lab}, rgb:{...item?.rgb}, texturl_url: item?.texturl_url} - }, []) - - return ( - <> - - - {formatDetailOrder&&<> - {numText} - - - { - formatDetailOrder?.list?.map(item => { - return - - {formatDetailOrder.sale_mode_name} - {formatHashTag(item.code, item.name)} - 共{item?.product_colors.length}种 - - - {item?.product_colors?.map(colorItem => { - return - - - - - - {colorItem.code + ' ' + colorItem.name} - - ¥{standardPrice(colorItem.sale_price)} - 总重{formatWeightDiv(colorItem.estimate_weight)}kg - - - - ×{formatCount(colorItem)}{formatDetailOrder.unit} - ¥{formatPriceDiv(colorItem.estimate_amount, 100, true)} - - - - })} - - - }) - } - {/* - 申请数量 - ×{orderDetail?.total_number} - */} - - - } + return ( + <> + + + {formatDetailOrder && ( + <> + + {numText} + + + + {formatDetailOrder?.list?.map((item) => { + return ( + + + {formatDetailOrder.sale_mode_name} + {formatHashTag(item.code, item.name)} + 共{item?.product_colors.length}种 + + + {item?.product_colors?.map((colorItem) => { + return ( + + + + + + + {colorItem.code + ' ' + colorItem.name} + + ¥{standardPrice(colorItem.sale_price)} + 总重{formatWeightDiv(colorItem.estimate_weight)}kg + + + + + ×{formatCount(colorItem)} + {formatDetailOrder.unit} + + + ¥ + {formatPriceDiv(colorItem.estimate_amount, 100, true)} + + + + + ) + })} + + + ) + })} - - - ) -}) \ No newline at end of file + + + )} + + + + ) +}) diff --git a/src/pages/salesAfter/components/returnLogistics/index.tsx b/src/pages/salesAfter/components/returnLogistics/index.tsx index 61b034b..c51c38e 100644 --- a/src/pages/salesAfter/components/returnLogistics/index.tsx +++ b/src/pages/salesAfter/components/returnLogistics/index.tsx @@ -1,74 +1,78 @@ -import Popup from "@/components/popup"; -import { Text, View } from "@tarojs/components"; -import { memo, useCallback, useEffect, useRef, useState } from "react"; -import UploadImage from "@/components/uploadImage" -import styles from './index.module.scss' -import TextareaEnhance from "@/components/textareaEnhance"; -import { ReturnApplyLogisticsApi } from "@/api/salesAfterOrder"; -import { alert } from "@/common/common"; +import Popup from '@/components/popup' +import { Text, View } from '@tarojs/components' +import { memo, useCallback, useEffect, useRef, useState } from 'react' +import UploadImage from '@/components/uploadImage' +import styles from './index.module.scss' +import TextareaEnhance from '@/components/textareaEnhance' +import { ReturnApplyLogisticsApi } from '@/api/salesAfterOrder' +import { alert } from '@/common/common' type Param = { - show?: true|false, - onClose?: () => void, - onSubmit?: () => void, - id?: number, //订单id - images: string[], //图片列表 - descValue?: string, //描述 - onlyRead?: false|true //true 只读 + show?: true | false + onClose?: () => void + onSubmit?: () => void + id?: number //订单id + images: string[] //图片列表 + descValue?: string //描述 + onlyRead?: false | true //true 只读 } -export default memo(({show = false, onClose, onSubmit, id = 0, images = [], descValue = '', onlyRead = false}: Param) => { - //需要提交的数据 - const submitData = useRef({ - accessory_url: [], - remark: '', - id: 0 - }) - useEffect(() => { - if(id) submitData.current.id = id - }, [id]) +export default memo(({ show = false, onClose, onSubmit, id = 0, images = [], descValue = '', onlyRead = false }: Param) => { + //需要提交的数据 + const submitData = useRef({ + accessory_url: [], + remark: '', + id: 0, + }) + useEffect(() => { + if (id) submitData.current.id = id + }, [id]) - //获取图片列表 - const getImageList = useCallback((list) => { - submitData.current.accessory_url = list - }, []) + //获取图片列表 + const getImageList = useCallback((list) => { + submitData.current.accessory_url = list + }, []) - //备注 - const getOtherReason = useCallback((val) => { - submitData.current.remark = val - }, []) + //备注 + const getOtherReason = useCallback((val) => { + submitData.current.remark = val + }, []) - //确定 - const {fetchData} = ReturnApplyLogisticsApi() - const onSubmitEven = async () => { - if(!id) return alert.error('参数有误') - if(submitData.current.accessory_url.length <= 0) return alert.error('请上传附件') - let res = await fetchData(submitData.current) - if(res.success) { - alert.success('上传成功') - } else { - alert.error('上传失败') - } - onSubmit?.() + //确定 + const { fetchData } = ReturnApplyLogisticsApi() + const onSubmitEven = async () => { + if (!id) return alert.error('参数有误') + if (submitData.current.accessory_url.length <= 0) return alert.error('请上传附件') + let res = await fetchData(submitData.current) + if (res.success) { + alert.success('上传成功') + } else { + alert.error('上传失败') } + onSubmit?.() + } - return ( - <> - - - - 上传附件: - - - - - - - - {!onlyRead&& - onSubmitEven()}>保存 - } - - - - ) -}) \ No newline at end of file + return ( + <> + + + + 上传附件: + + + + + + + + {!onlyRead && ( + + onSubmitEven()}> + 保存 + + + )} + + + + ) +}) diff --git a/src/pages/salesAfter/index.tsx b/src/pages/salesAfter/index.tsx index 7f5c0b3..a4f75bc 100644 --- a/src/pages/salesAfter/index.tsx +++ b/src/pages/salesAfter/index.tsx @@ -1,193 +1,204 @@ +import { SaleOrderOrderDetailApi } from '@/api/salesAfterOrder' +import { AFTER_ORDER_STATUS, ORDER_STATUS } from '@/common/enum' +import { formatDateTime, formatImgUrl, formatPriceDiv } from '@/common/fotmat' +import AfterOrderBtns from '@/components/afterOrderBtns' +import SearchInput from '@/components/searchInput' +import useLogin from '@/use/useLogin' +import { Image, Text, Textarea, View } from '@tarojs/components' +import Taro, { useDidShow, usePullDownRefresh, useRouter } from '@tarojs/taro' +import classnames from 'classnames' +import { useCallback, useEffect, useMemo, useRef, useState, memo } from 'react' +import AddressInfoDetail from './components/addressInfoDetail' +import ApplyRecord from './components/applyRecord' +import ContentBox from './components/contentBox' +import KindList from './components/kindList' +import OrderState from './components/orderState' +import ReturnLogistics from './components/returnLogistics' +import styles from './index.module.scss' -import { SaleOrderOrderDetailApi } from "@/api/salesAfterOrder"; -import { AFTER_ORDER_STATUS, ORDER_STATUS } from "@/common/enum"; -import { formatDateTime, formatImgUrl, formatPriceDiv } from "@/common/fotmat"; -import AfterOrderBtns from "@/components/afterOrderBtns"; -import SearchInput from "@/components/searchInput"; -import useLogin from "@/use/useLogin"; -import { Image, Text, Textarea, View } from "@tarojs/components" -import Taro, {useDidShow, usePullDownRefresh, useRouter } from "@tarojs/taro"; -import classnames from "classnames"; -import { useCallback, useEffect, useMemo, useRef, useState, memo } from "react"; -import AddressInfoDetail from "./components/addressInfoDetail"; -import ApplyRecord from "./components/applyRecord"; -import ContentBox from "./components/contentBox"; -import KindList from "./components/kindList"; -import OrderState from "./components/orderState"; -import ReturnLogistics from "./components/returnLogistics"; -import styles from './index.module.scss' - - export default () => { - useLogin() - const router = useRouter() - const orderId = useRef(Number(router.params.id)) - useDidShow(() => { - getSaleOrderPreView() +export default () => { + useLogin() + const router = useRouter() + const orderId = useRef(Number(router.params.id)) + useDidShow(() => { + getSaleOrderPreView() + }) + + //获取订单详情 + const [orderDetail, setOrderDetail] = useState() //获取到的原始数据 + const { fetchData: saleOrderOrderDetailData } = SaleOrderOrderDetailApi() + const getSaleOrderPreView = async () => { + if (orderId.current) { + let res = await saleOrderOrderDetailData({ id: orderId.current }) + setOrderDetail(res.data) + } + Taro.stopPullDownRefresh() + } + + //监听获取到的数据 + useEffect(() => { + if (orderDetail) formatData() + }, [orderDetail]) + + //格式化数据格式 + const [formatDetailOrder, setFormatDetailOrder] = useState() //格式化后的数据 + const formatData = () => { + setFormatDetailOrder({ + ...orderDetail, + unit: orderDetail.sale_mode == 0 ? '条' : 'm', //单位 }) + } + const formatPreViewOrderMemo = useMemo(() => { + return formatDetailOrder + }, [formatDetailOrder]) - //获取订单详情 - const [orderDetail, setOrderDetail] = useState() //获取到的原始数据 - const {fetchData: saleOrderOrderDetailData} = SaleOrderOrderDetailApi() - const getSaleOrderPreView = async () => { - if(orderId.current) { - let res = await saleOrderOrderDetailData({id: orderId.current}) - setOrderDetail(res.data) - } - Taro.stopPullDownRefresh() - } - - //监听获取到的数据 - useEffect(() => { - if(orderDetail) - formatData() - }, [orderDetail]) - - //格式化数据格式 - const [formatDetailOrder, setFormatDetailOrder] = useState() //格式化后的数据 - const formatData = () => { - setFormatDetailOrder({ - ...orderDetail, - unit: orderDetail.sale_mode == 0?'条':'m', //单位 - }) - } - const formatPreViewOrderMemo = useMemo(() => { - return formatDetailOrder - }, [formatDetailOrder]) - - - //获取底部按钮点击, 获取按钮状态 - const orderStateClick = useCallback((val) => { - if(val == 1 || val == 6) { - getSaleOrderPreView() - } else if(val == 8) { - //申请记录 - setApplyRecord(true) - } else if (val == 5) { - onShowLogistics(1) - } - }, [orderDetail]) - - //页面下拉刷新 - usePullDownRefresh(() => { + //获取底部按钮点击, 获取按钮状态 + const orderStateClick = useCallback( + (val) => { + if (val == 1 || val == 6) { getSaleOrderPreView() + } else if (val == 8) { + //申请记录 + setApplyRecord(true) + } else if (val == 5) { + onShowLogistics(1) + } + }, + [orderDetail], + ) + + //页面下拉刷新 + usePullDownRefresh(() => { + getSaleOrderPreView() + }) + + //按钮所需数据 + const orderInfo = useMemo(() => { + return { + ...orderDetail, + } + }, [orderDetail]) + + //售后订单状态枚举 + const {} = AFTER_ORDER_STATUS + + //物流显示 + const [logisticsShow, setLogisticsShow] = useState(false) + const [logistics, setLogistics] = useState(false) + const onShowLogistics = useCallback((val) => { + setLogisticsShow(true) + if (val != 1) setLogistics(true) + }, []) + const onCloseLogistics = useCallback(() => { + setLogisticsShow(false) + }, []) + //物流成功上传 + const logisticsSuccess = useCallback(() => { + setLogisticsShow(false) + getSaleOrderPreView() + }, []) + + //显示记录 + const [applyRecord, setApplyRecord] = useState(false) + + return ( + + + + + + + + + setApplyRecord(false)} /> + + + ) +} + +const OrderDes = memo(({ orderInfo }: { orderInfo?: any }) => { + //复制功能 + const clipboardData = (val) => { + Taro.setClipboardData({ + data: val, + success: function (res) { + Taro.showToast({ + icon: 'none', + title: '复制成功', + }) + }, }) - - //按钮所需数据 - const orderInfo = useMemo(() => { - return { - ...orderDetail - } - }, [orderDetail]) - - //售后订单状态枚举 - const { - - } = AFTER_ORDER_STATUS - - //物流显示 - const [logisticsShow, setLogisticsShow] = useState(false) - const [logistics, setLogistics] = useState(false) - const onShowLogistics = useCallback((val) => { - setLogisticsShow(true) - if(val != 1) setLogistics(true) - }, []) - const onCloseLogistics = useCallback(() => { - setLogisticsShow(false) - }, []) - //物流成功上传 - const logisticsSuccess = useCallback(() => { - setLogisticsShow(false) - getSaleOrderPreView() - }, []) - - //显示记录 - const [applyRecord, setApplyRecord] = useState(false) - - return ( - - - - - - - - - setApplyRecord(false)}/> - + } + return ( + + 订单信息 + + + {orderInfo?.return_order_no} + clipboardData(orderInfo?.return_order_no)}> + 复制 + - ) - } - - const OrderDes = memo(({orderInfo}:{orderInfo?:any}) => { - //复制功能 - const clipboardData = (val) => { - Taro.setClipboardData({ - data: val, - success: function (res) { - Taro.showToast({ - icon: 'none', - title: '复制成功' - }) - } - }) - } - return ( - - 订单信息 - - - {orderInfo?.return_order_no} - clipboardData(orderInfo?.return_order_no)}>复制 - - - - - {orderInfo?.order_no} - clipboardData(orderInfo?.order_no)}>复制 - - - - {orderInfo?.return_reason_name} - - - {orderInfo?.return_explain_name} - - - {orderInfo?.goods_status_name} - - - {formatDateTime(orderInfo?.apply_time)} - - - {orderInfo?.reason_describe} - + + + + {orderInfo?.order_no} + clipboardData(orderInfo?.order_no)}> + 复制 + - ) - }) + + + {orderInfo?.return_reason_name} + + + {orderInfo?.return_explain_name} + + + {orderInfo?.goods_status_name} + + + {formatDateTime(orderInfo?.apply_time)} + + + {orderInfo?.reason_describe} + + + ) +}) - const AfterSalePricture = memo(({urls = []}:{urls: string[]}) => { +const AfterSalePricture = memo(({ urls = [] }: { urls: string[] }) => { + const showList = useMemo(() => { + let res = urls.map((item) => { + return formatImgUrl(item, '!w800') + }) + return res + }, [urls]) - const showList = useMemo(() => { - let res = urls.map(item => { - return formatImgUrl(item, "!w800") - }) - return res - }, [urls]) - - //预览图片 - const showImage = () => { - Taro.previewImage({ - current: showList[0], // 当前显示 - urls: showList // 需要预览的图片http链接列表 - }) - } - return ( - - - {urls?.map(item=> - - )} - - - ) - }) + //预览图片 + const showImage = () => { + Taro.previewImage({ + current: showList[0], // 当前显示 + urls: showList, // 需要预览的图片http链接列表 + }) + } + return ( + + + {urls?.map((item) => ( + + + + ))} + + + ) +}) diff --git a/src/pages/salesAfter/salesAfterList/index.tsx b/src/pages/salesAfter/salesAfterList/index.tsx index 8053ae3..5797e62 100644 --- a/src/pages/salesAfter/salesAfterList/index.tsx +++ b/src/pages/salesAfter/salesAfterList/index.tsx @@ -1,110 +1,111 @@ -import Search from "@/components/search" -import useLogin from "@/use/useLogin" -import {View } from "@tarojs/components" -import Taro, { useDidShow} from "@tarojs/taro" -import { useCallback, useEffect, useMemo, useRef, useState } from "react" -import styles from './index.module.scss' -import classnames from "classnames"; -import Order from "./components/order" -import InfiniteScroll from "@/components/infiniteScroll" -import { dataLoadingStatus, getFilterData } from "@/common/util" -import OrderStatusList from "./components/orderStatusList" -import { GetSaleOrderListApi, RefundOrderSatausApi } from "@/api/salesAfterOrder" -import ApplyRecord from "../components/applyRecord" -import ReturnLogistics from "../components/returnLogistics" +import Search from '@/components/search' +import useLogin from '@/use/useLogin' +import { View } from '@tarojs/components' +import Taro, { useDidShow } from '@tarojs/taro' +import { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import styles from './index.module.scss' +import classnames from 'classnames' +import Order from './components/order' +import InfiniteScroll from '@/components/infiniteScroll' +import { dataLoadingStatus, getFilterData } from '@/common/util' +import OrderStatusList from './components/orderStatusList' +import { GetSaleOrderListApi, RefundOrderSatausApi } from '@/api/salesAfterOrder' +import ApplyRecord from '../components/applyRecord' +import ReturnLogistics from '../components/returnLogistics' export default () => { useLogin() //搜索参数 - const [searchField, setSearchField] = useState<{status: number|null, page: number, size: number, name: string}>({ + const [searchField, setSearchField] = useState<{ status: number | null; page: number; size: number; name: string }>({ status: null, - page : 1, - size : 10, - name:'' + page: 1, + size: 10, + name: '', }) //获取订单状态 - const [statusList, setStatusList] = useState([{id: -1, name: '全部'}]) - const {fetchData: fetchDataStatus} = RefundOrderSatausApi() - const getOrderStatusList = async () => { + const [statusList, setStatusList] = useState([{ id: -1, name: '全部' }]) + const { fetchData: fetchDataStatus } = RefundOrderSatausApi() + const getOrderStatusList = async () => { let res = await fetchDataStatus() setStatusList((e) => [...e, ...res.data.list]) } useEffect(() => { getOrderStatusList() - setSearchField((e) => ({...e, status:-1})) + setSearchField((e) => ({ ...e, status: -1 })) }, []) //获取订单列表 - const {fetchData: listFetchData, state:orderState} = GetSaleOrderListApi() - const [orderData, setOrderData] = useState<{list:any[], total:number}>({list:[], total:0}) + const { fetchData: listFetchData, state: orderState } = GetSaleOrderListApi() + const [orderData, setOrderData] = useState<{ list: any[]; total: number }>({ list: [], total: 0 }) const getOrderList = async () => { let res = await listFetchData(getFilterData(searchField)) - setOrderData({list: res.data.list, total: res.data.total}) + setOrderData({ list: res.data.list, total: res.data.total }) setRefresherTriggeredStatus(() => false) } useDidShow(() => { - if(searchField.status != null) getOrderList() + if (searchField.status != null) getOrderList() }) //监听筛选条件变化 useEffect(() => { - if(searchField.status != null) getOrderList() + if (searchField.status != null) getOrderList() }, [searchField]) //上拉加载数据 - const pageNum = useRef({size: searchField.size, page: searchField.page}) + const pageNum = useRef({ size: searchField.size, page: searchField.page }) const getScrolltolower = useCallback(() => { - if(orderData.list.length < orderData.total) { - pageNum.current.page++ - const size = pageNum.current.size * pageNum.current.page - setSearchField((e) => ({...e, size })) - } + if (orderData.list.length < orderData.total) { + pageNum.current.page++ + const size = pageNum.current.size * pageNum.current.page + setSearchField((e) => ({ ...e, size })) + } }, [orderData]) //状态改变 const changeStatus = useCallback((e) => { pageNum.current.page = 1 - setSearchField((value) => ({...value, status:e, size:10})) - setOrderData(() => ({list:[], total:0})) + setSearchField((value) => ({ ...value, status: e, size: 10 })) + setOrderData(() => ({ list: [], total: 0 })) }, []) - //数据加载状态 const statusMore = useMemo(() => { - return dataLoadingStatus({list:orderData.list, total: orderData.total, status: orderState.loading}) + return dataLoadingStatus({ list: orderData.list, total: orderData.total, status: orderState.loading }) }, [orderData, orderState]) //输入了搜索关键字 const getSearchData = useCallback((e) => { pageNum.current.page = 1 - setOrderData(() => ({list:[], total:0})) - setSearchField((val) => ({...val, name:e, size:10})) + setOrderData(() => ({ list: [], total: 0 })) + setSearchField((val) => ({ ...val, name: e, size: 10 })) }, []) - //列表下拉刷新 const [refresherTriggeredStatus, setRefresherTriggeredStatus] = useState(false) const getRefresherRefresh = async () => { pageNum.current.size = 1 setRefresherTriggeredStatus(true) - setSearchField((val) => ({...val, size:10})) + setSearchField((val) => ({ ...val, size: 10 })) } //监听点击的按钮 const [callBackOrderInfo, setCallBackPayOrderInfo] = useState() - const clickOrderBtn = useCallback(({status, orderInfo}) => { - if(status == 1 || status == 6) { - getOrderList() - } else if (status == 8) { - setApplyRecord(true) - } else if (status == 5) { - onShowLogistics(() => true) - } - setCallBackPayOrderInfo(orderInfo) - }, [orderData]) + const clickOrderBtn = useCallback( + ({ status, orderInfo }) => { + if (status == 1 || status == 6) { + getOrderList() + } else if (status == 8) { + setApplyRecord(true) + } else if (status == 5) { + onShowLogistics(() => true) + } + setCallBackPayOrderInfo(orderInfo) + }, + [orderData], + ) //显示记录 const [applyRecord, setApplyRecord] = useState(false) @@ -112,32 +113,48 @@ export default () => { //物流显示 const [logisticsShow, setLogisticsShow] = useState(false) const onShowLogistics = useCallback((val) => { - setLogisticsShow(true) + setLogisticsShow(true) }, []) const onCloseLogistics = useCallback(() => { - setLogisticsShow(false) + setLogisticsShow(false) }, []) //物流成功上传 const logisticsSuccess = useCallback(() => { - setLogisticsShow(false) - getOrderList() + setLogisticsShow(false) + getOrderList() }, [orderData]) return ( - - - - - - {orderData?.list.map(item => { - return - })} - + + - setApplyRecord(false)}/> - + + + {orderData?.list.map((item) => { + return ( + + + + ) + })} + + + setApplyRecord(false)} /> + ) } diff --git a/src/pages/searchList/hightSearchList.module.scss b/src/pages/searchList/hightSearchList.module.scss index 665ece2..da2d667 100644 --- a/src/pages/searchList/hightSearchList.module.scss +++ b/src/pages/searchList/hightSearchList.module.scss @@ -1,214 +1,214 @@ -.main{ - display: flex; - flex-direction: column; - height: 100vh; - background-color: $color_bg_one; - .search{ - padding: 20px; - .SearchInput{ - background-color: #fff; - padding: 10px 20px; - box-sizing: border-box; - border-radius: 10px; - } - - .bluetooth_color{ - .color_bock{ - width: 100px; - height: 46px; - } - .color_bock_no{ - font-size: $font_size_medium; - color: $color_font_three; - } - } +.main { + display: flex; + flex-direction: column; + height: 100vh; + background-color: $color_bg_one; + .search { + padding: 20px; + .SearchInput { + background-color: #fff; + padding: 10px 20px; + box-sizing: border-box; + border-radius: 10px; } - .filter{ - .filter_all { - display: flex; - justify-content: space-between; - align-items: center; - padding: 20px 130px; + + .bluetooth_color { + .color_bock { + width: 100px; + height: 46px; + } + .color_bock_no { + font-size: $font_size_medium; + color: $color_font_three; + } + } + } + .filter { + .filter_all { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px 130px; + font-size: $font_size_medium; + color: $color_font_three; + .text_zh, + .text_sc { + color: $color_main; + display: flex; + align-items: center; + .sortIcon { + display: flex; + flex-direction: column; + position: relative; + .icon_one { font-size: $font_size_medium; - color: $color_font_three; - .text_zh, .text_sc{ - color: $color_main; - display: flex; - align-items: center; - .sortIcon{ - display: flex; - flex-direction: column; - position: relative; - .icon_one{ - font-size: $font_size_medium; - position: absolute; - margin:auto; - top:0; - } - } - } - .text_ss{ - position: relative; - .miconfont{ - font-size: 20px; - margin-left: 5px; - } - &::before{ - content: ''; - width: 2px; - height: 32px; - background-color: #C2C2C2; - position: absolute; - top: 0; - left: -30px; - } - } + position: absolute; + margin: auto; + top: 0; + } } - .filter_btn_con{ - display: flex; - justify-content: space-between; - align-items: center; - height: 86px; - + } + .text_ss { + position: relative; + .miconfont { + font-size: 20px; + margin-left: 5px; } - .filter_scroll{ - flex:1; - width: 0; - padding-left: 20px; - ::-webkit-scrollbar { - display:none; - width:0; - height:0; - color:transparent; - } + &::before { + content: ''; + width: 2px; + height: 32px; + background-color: #c2c2c2; + position: absolute; + top: 0; + left: -30px; } - .filter_btn{ - display: flex; - justify-content: space-between; - padding: 20px; - margin-right: 20px; - flex:1; - view{ - font-size: $font_size_medium; - background-color: #F0F0F0; - border-radius: 24px; - min-width: 126px; - height: 46.93px; - text-align: center; - line-height: 46.93px; - color: $color_font_three; - &:nth-last-child(n+2) { - margin-right: 10px; - } - &:nth-last-child(1) { - margin-right: 30px; - } - } - .selected{ - background-color: #ecf5ff; - border: 2px solid #cde5ff; - color: $color_main; - width: 122px; - height: 42.93px; - } + } + } + .filter_btn_con { + display: flex; + justify-content: space-between; + align-items: center; + height: 86px; + } + .filter_scroll { + flex: 1; + width: 0; + padding-left: 20px; + ::-webkit-scrollbar { + display: none; + width: 0; + height: 0; + color: transparent; + } + } + .filter_btn { + display: flex; + justify-content: space-between; + padding: 20px; + margin-right: 20px; + flex: 1; + view { + font-size: $font_size_medium; + background-color: #f0f0f0; + border-radius: 24px; + min-width: 126px; + height: 46.93px; + text-align: center; + line-height: 46.93px; + color: $color_font_three; + &:nth-last-child(n + 2) { + margin-right: 10px; } - .filter_more{ - font-size: $font_size_medium; - color: $color_font_three; - padding: 0 30px 0 20px; - position: relative; + &:nth-last-child(1) { + margin-right: 30px; + } + } + .selected { + background-color: #ecf5ff; + border: 2px solid #cde5ff; + color: $color_main; + width: 122px; + height: 42.93px; + } + } + .filter_more { + font-size: $font_size_medium; + color: $color_font_three; + padding: 0 30px 0 20px; + position: relative; + height: 100%; + line-height: 86px; + &::before { + content: ''; + opacity: 1; + width: 30px; + height: 100%; + position: absolute; + left: -15px; + background-image: linear-gradient(to right, rgba(248, 248, 248, 0.3), rgba(248, 248, 248, 1) 60%); + // z-index: 99; + } + .miconfont { + font-size: 27px; + } + } + } + .list { + height: calc(100vh - 440px); + .list_num { + font-size: $font_size_min; + color: $color_font_two; + padding: 10px 38px; + border-bottom: 1px solid rgb(233, 233, 233); + } + + .scroll { + height: 100%; + padding-top: 3px; + } + .product_list { + padding: 38px; + display: grid; + grid-template-columns: 321px 321px; + justify-content: space-between; + .product_item { + width: 321px; + background-color: #fff; + border-radius: 20px; + margin-bottom: 20px; + box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1); + .product_img { + width: 100%; + height: 224px; + border-radius: 20px 20px 0px 0px; + position: relative; + image { + width: 100%; height: 100%; - line-height: 86px; - &::before{ - content: ''; - opacity: 1; - width: 30px; - height: 100%; - position: absolute; - left: -15px; - background-image: linear-gradient(to right, rgba(248, 248, 248, 0.3), rgba(248, 248, 248, 1) 60% ); - // z-index: 99; - } - .miconfont{ - font-size: 27px; - } - } - } - .list{ - height: calc(100vh - 440px); - .list_num { + border-radius: 20px 20px 0px 0px; + } + .color_num { + background: rgba(0, 0, 0, 0.5); + border-radius: 0px 50px 0px 30px; font-size: $font_size_min; - color:$color_font_two; - padding: 10px 38px; - border-bottom: 1PX solid rgb(233, 233, 233); + color: #fff; + position: absolute; + left: 0; + bottom: 0; + padding: 5px 20px; + box-sizing: border-box; + } } - - .scroll{ - height: 100%; - padding-top: 3px; + } + .product_info { + padding: 20px; + .title { + font-size: $font_size; + color: $color_font_three; + @include common_ellipsis(); } - .product_list{ - padding: 38px; - display: grid; - grid-template-columns: 321px 321px; - justify-content: space-between; - .product_item{ - width: 321px; - background-color: #fff; - border-radius: 20px; - margin-bottom: 20px; - box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.1) ; - .product_img{ - width: 100%; - height: 224px; - border-radius: 20px 20px 0px 0px; - position: relative; - image{ - width: 100%; - height: 100%; - border-radius: 20px 20px 0px 0px; - } - .color_num { - background: rgba(0,0,0, 0.5); - border-radius: 0px 50px 0px 30px; - font-size: $font_size_min; - color: #fff; - position: absolute; - left:0; - bottom:0; - padding: 5px 20px; - box-sizing: border-box; - } - } - } - .product_info{ - padding: 20px; - .title{ - font-size: $font_size; - color: $color_font_three; - @include common_ellipsis() - } - .tag_list{ - display: flex; - margin-top: 16px; - .tag{ - padding: 3px 10px; - background-color: #CDE5FF; - font-size: $font_size_min; - border-radius: 5px; - color: $color_main; - &:nth-child(2) { - margin-left: 10px; - } - } - } - .introduce{ - font-size: $font_size_medium; - color: $color_font_two; - margin-top: 16px; - @include common_ellipsis() - } + .tag_list { + display: flex; + margin-top: 16px; + .tag { + padding: 3px 10px; + background-color: #cde5ff; + font-size: $font_size_min; + border-radius: 5px; + color: $color_main; + &:nth-child(2) { + margin-left: 10px; } + } } + .introduce { + font-size: $font_size_medium; + color: $color_font_two; + margin-top: 16px; + @include common_ellipsis(); + } + } } -} \ No newline at end of file + } +} diff --git a/src/pages/searchList/searchList.module.scss b/src/pages/searchList/searchList.module.scss index c0b0c4c..1a82944 100644 --- a/src/pages/searchList/searchList.module.scss +++ b/src/pages/searchList/searchList.module.scss @@ -1,198 +1,198 @@ -.main{ - display: flex; - flex-direction: column; - height: 100vh; - background-color: #F8F8F8; - .search{ - padding: 20px; +.main { + display: flex; + flex-direction: column; + height: 100vh; + background-color: #f8f8f8; + .search { + padding: 20px; + } + .filter { + .filter_all { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px 50px; + font-size: $font_size_medium; + color: $color_font_three; + .text_zh, + .text_sc { + color: $color_main; + display: flex; + align-items: center; + .sortIcon { + display: flex; + flex-direction: column; + position: relative; + .icon_one { + font-size: $font_size_medium; + position: absolute; + margin: auto; + top: 0; + } + } + } + .text_ss { + position: relative; + .miconfont { + font-size: 30px; + margin-left: 5px; + } + &::before { + content: ''; + width: 2px; + height: 32px; + background-color: #c2c2c2; + position: absolute; + top: 0; + left: -30px; + } + } } - .filter{ - .filter_all { - display: flex; - justify-content: space-between; - align-items: center; - padding: 20px 50px; - font-size: $font_size_medium; - color: $color_font_three; - .text_zh, .text_sc{ - color: $color_main; - display: flex; - align-items: center; - .sortIcon{ - display: flex; - flex-direction: column; - position: relative; - .icon_one{ - font-size: $font_size_medium; - position: absolute; - margin:auto; - top:0; - } - } - } - .text_ss{ - position: relative; - .miconfont{ - font-size: 30px; - margin-left: 5px; - } - &::before{ - content: ''; - width: 2px; - height: 32px; - background-color: #C2C2C2; - position: absolute; - top: 0; - left: -30px; - } - } + .filter_btn_con { + display: flex; + justify-content: space-between; + align-items: center; + height: 86px; + } + .filter_scroll { + flex: 1; + width: 0; + padding-left: 20px; + ::-webkit-scrollbar { + display: none; + width: 0; + height: 0; + color: transparent; + } + } + .filter_btn { + display: flex; + justify-content: space-between; + padding: 20px; + margin-right: 20px; + flex: 1; + view { + font-size: $font_size_medium; + background-color: #f0f0f0; + border-radius: 24px; + min-width: 126px; + height: 46.93px; + text-align: center; + line-height: 46.93px; + color: $color_font_three; + &:nth-last-child(n + 2) { + margin-right: 10px; } - .filter_btn_con{ - display: flex; - justify-content: space-between; - align-items: center; - height: 86px; - + &:nth-last-child(1) { + margin-right: 30px; } - .filter_scroll{ - flex:1; - width: 0; - padding-left: 20px; - ::-webkit-scrollbar { - display:none; - width:0; - height:0; - color:transparent; - } - } - .filter_btn{ - display: flex; - justify-content: space-between; - padding: 20px; - margin-right: 20px; - flex:1; - view{ - font-size: $font_size_medium; - background-color: #F0F0F0; - border-radius: 24px; - min-width: 126px; - height: 46.93px; - text-align: center; - line-height: 46.93px; - color: $color_font_three; - &:nth-last-child(n+2) { - margin-right: 10px; - } - &:nth-last-child(1) { - margin-right: 30px; - } - } - .selected{ - background-color: #ecf5ff; - border: 2px solid #cde5ff; - color: $color_main; - width: 122px; - height: 42.93px; - } - } - .filter_more{ - font-size: $font_size_medium; - color: $color_font_three; - padding: 0 30px 0 20px; - position: relative; + } + .selected { + background-color: #ecf5ff; + border: 2px solid #cde5ff; + color: $color_main; + width: 122px; + height: 42.93px; + } + } + .filter_more { + font-size: $font_size_medium; + color: $color_font_three; + padding: 0 30px 0 20px; + position: relative; + height: 100%; + line-height: 86px; + &::before { + content: ''; + opacity: 1; + width: 30px; + height: 100%; + position: absolute; + left: -15px; + background-image: linear-gradient(to right, rgba(248, 248, 248, 0.3), rgba(248, 248, 248, 1) 60%); + // z-index: 99; + } + .miconfont { + font-size: 27px; + } + } + } + .list { + height: calc(100vh - 330px); + .list_num { + font-size: $font_size_min; + color: $color_font_two; + padding: 10px 38px; + border-bottom: 1px solid #e9e9e9; + } + + .scroll { + height: 100%; + padding-top: 3px; + } + .product_list { + padding: 38px; + display: grid; + grid-template-columns: 321px 321px; + justify-content: space-between; + .product_item { + width: 321px; + background-color: #fff; + border-radius: 20px; + margin-bottom: 20px; + box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1); + .product_img { + width: 100%; + height: 224px; + border-radius: 20px 20px 0px 0px; + position: relative; + image { + width: 100%; height: 100%; - line-height: 86px; - &::before{ - content: ''; - opacity: 1; - width: 30px; - height: 100%; - position: absolute; - left: -15px; - background-image: linear-gradient(to right, rgba(248, 248, 248, 0.3), rgba(248, 248, 248, 1) 60% ); - // z-index: 99; - } - .miconfont{ - font-size: 27px; - } - } - } - .list{ - height: calc(100vh - 330px); - .list_num { + border-radius: 20px; + } + .color_num { + background: rgba(0, 0, 0, 0.5); + border-radius: 50px 0px 0px 0px; font-size: $font_size_min; - color:$color_font_two; - padding: 10px 38px; - border-bottom: 1PX solid #e9e9e9; + color: #fff; + position: absolute; + right: 0; + bottom: 0; + padding: 5px 20px; + box-sizing: border-box; + } } - - .scroll{ - height: 100%; - padding-top: 3px; + } + .product_info { + padding: 20px; + .title { + font-size: $font_size; + color: $color_font_three; + @include common_ellipsis(); } - .product_list{ - padding: 38px; - display: grid; - grid-template-columns: 321px 321px; - justify-content: space-between; - .product_item{ - width: 321px; - background-color: #fff; - border-radius: 20px; - margin-bottom: 20px; - box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.1) ; - .product_img{ - width: 100%; - height: 224px; - border-radius: 20px 20px 0px 0px; - position: relative; - image{ - width: 100%; - height: 100%; - border-radius: 20px 20px 0px 0px; - } - .color_num { - background: rgba(0,0,0, 0.5); - border-radius: 50px 0px 0px 0px; - font-size: $font_size_min; - color: #fff; - position: absolute; - right:0; - bottom:0; - padding: 5px 20px; - box-sizing: border-box; - } - } - } - .product_info{ - padding: 20px; - .title{ - font-size: $font_size; - color: $color_font_three; - @include common_ellipsis(); - } - .tag_list{ - display: flex; - margin-top: 16px; - .tag{ - padding: 3px 10px; - background-color: #CDE5FF; - font-size: $font_size_min; - border-radius: 5px; - color: $color_main; - @include common_ellipsis(); - &:nth-child(2) { - margin-left: 10px; - } - } - } - .introduce{ - font-size: $font_size_medium; - color: $color_font_two; - margin-top: 16px; - @include common_ellipsis(); - } + .tag_list { + display: flex; + margin-top: 16px; + .tag { + padding: 3px 10px; + background-color: #cde5ff; + font-size: $font_size_min; + border-radius: 5px; + color: $color_main; + @include common_ellipsis(); + &:nth-child(2) { + margin-left: 10px; } + } } + .introduce { + font-size: $font_size_medium; + color: $color_font_two; + margin-top: 16px; + @include common_ellipsis(); + } + } } -} \ No newline at end of file + } +} diff --git a/src/use/BlueToothCopy.tsx b/src/use/BlueToothCopy.tsx index 0d07766..2619492 100644 --- a/src/use/BlueToothCopy.tsx +++ b/src/use/BlueToothCopy.tsx @@ -1,477 +1,477 @@ -import React, {useRef, useState } from "react" -import Taro from "@tarojs/taro"; -import { Command } from "@/common/bluetooth/command"; -import { uint8ArrayToFloat32, uint8ArrayToHex, waitFor } from "@/common/bluetooth/utils"; - +import React, { useRef, useState } from 'react' +import Taro from '@tarojs/taro' +import { Command } from '@/common/bluetooth/command' +import { uint8ArrayToFloat32, uint8ArrayToHex, waitFor } from '@/common/bluetooth/utils' interface params { - init: () => void - state: Object, - startScan: () => void, - measureAndGetLab: () => any, - getAdapterState: () => void, - connect: (any) => void, - disconnect: () => void + init: () => void + state: Object + startScan: () => void + measureAndGetLab: () => any + getAdapterState: () => void + connect: (any) => void + disconnect: () => void } -const Context = React.createContext(null) +const Context = React.createContext(null) interface stateStype { - listeners: any, - discovering: boolean, - available: boolean, - connected: any, - connecting: any, - serviceRule: any, - serviceId: any, - characteristicRule: any, - characteristicId: any, + listeners: any + discovering: boolean + available: boolean + connected: any + connecting: any + serviceRule: any + serviceId: any + characteristicRule: any + characteristicId: any - /** 正在执行的命令 */ - command: any, - responseResolve: any, - responseReject: any, - responseTimer: any, + /** 正在执行的命令 */ + command: any + responseResolve: any + responseReject: any + responseTimer: any - /** 是否显示蓝牙调试信息 */ - debug: any, - //搜索到的设备 - devices: any, - //取色仪主动返回的数据 - deviceLab: any + /** 是否显示蓝牙调试信息 */ + debug: any + //搜索到的设备 + devices: any + //取色仪主动返回的数据 + deviceLab: any } let stateObj: stateStype = { - /** 事件监听器 */ - listeners: new Set(), - /** 正在扫描设备 */ - discovering: false, - /** 蓝牙是否可用 */ - available: true, - /** 当前连接的设备 */ - connected: null, - /** 正在连接的设备 */ - connecting: null, + /** 事件监听器 */ + listeners: new Set(), + /** 正在扫描设备 */ + discovering: false, + /** 蓝牙是否可用 */ + available: true, + /** 当前连接的设备 */ + connected: null, + /** 正在连接的设备 */ + connecting: null, - serviceRule: /^0000FFE0/, - serviceId: null, - characteristicRule: /^0000FFE1/, - characteristicId: null, + serviceRule: /^0000FFE0/, + serviceId: null, + characteristicRule: /^0000FFE1/, + characteristicId: null, - /** 正在执行的命令 */ - command: null, - responseResolve: null, - responseReject: null, - responseTimer: null, + /** 正在执行的命令 */ + command: null, + responseResolve: null, + responseReject: null, + responseTimer: null, - /** 是否显示蓝牙调试信息 */ - debug: true, - //搜索到的设备 - devices: [], - //取色仪主动返回的数据 - deviceLab: null + /** 是否显示蓝牙调试信息 */ + debug: true, + //搜索到的设备 + devices: [], + //取色仪主动返回的数据 + deviceLab: null, } export default (props) => { - let refStatus = useRef(stateObj) - let [state, setState] = useState(refStatus.current) + let refStatus = useRef(stateObj) + let [state, setState] = useState(refStatus.current) - const changeStatus = (obj:Object): void => { - refStatus.current = {...refStatus.current, ...obj} - setState({...refStatus.current}) + const changeStatus = (obj: Object): void => { + refStatus.current = { ...refStatus.current, ...obj } + setState({ ...refStatus.current }) + } + + const init = async () => { + try { + await openAdapter() + } catch (e) { + changeStatus({ available: false }) } - const init = async () => { - try{ - await openAdapter(); - }catch(e) { - changeStatus({available:false}) - } - - // 绑定事件通知 - Taro.onBluetoothAdapterStateChange(res => { - emit({ type: 'stateUpdate', detail: res }); - }); - Taro.onBLEConnectionStateChange(res => { - emit({ type: res.connected ? 'connected' : 'disconnect', detail: res }); - }); - Taro.onBLECharacteristicValueChange(({ value }) => notifySubscriber(value)); - subscribe(async ev => { - if (ev.type === 'stateUpdate') { - // 蓝牙状态发生的变化 - changeStatus({discovering:ev.detail.discovering, available:ev.detail.available}) - } else if (ev.type === 'disconnect' && refStatus.current.connected && refStatus.current.connected.deviceId === ev.detail.deviceId) { - // 断开连接 - changeStatus({ - connected:null, - serviceId:null, - characteristicId:null, - deviceLab:null, - devices:[] - }) - Taro.showToast({ icon: 'none', title: '蓝牙连接已断开' }); - } else if (ev.type === 'connected' && refStatus.current.connecting) { - // 连接成功 - changeStatus({connected: refStatus.current.connecting, connecting: null}) - Taro.showToast({ title: '蓝牙已连接' }); - } else if (ev.type === 'measure') { - //监听取色仪主动推送lab - await measureAndGetLab() - } - - }); - } - - /** 打开蓝牙适配器 */ - const openAdapter = () => { - return new Promise((resolve, reject) => { - Taro.openBluetoothAdapter({ - success: resolve, - fail: reject - }); - }); - } - - /** - * 推送事件 - * @param {{type: string; data: any}} event - */ - const emit = (event) => { - refStatus.current.listeners.forEach(cb => { - cb && cb(event); - }); - } - - const subscribe = (cb) => { - if (cb) { - changeStatus({ - listeners: refStatus.current.listeners.add(cb) - }) - } - } - - /** - * 获取蓝牙适配器状态 - * @returns {Promise<{discovering: boolean; available: boolean}>} - */ - const getAdapterState = () => { - return new Promise((resolve, reject) => { - Taro.getBluetoothAdapterState({ - success: resolve, - fail: reject - }) - }) - } - - /** - * 启动设备扫描 - * @param {(res: { devices: { name: string, deviceId: string, RSSI: number }[] }) => void} cb - * @param {number} duration - */ - const startScan = (duration = 30000) => { - console.log('开始寻找') - changeStatus({devices:[]}) - Taro.onBluetoothDeviceFound(getDevices); - return new Promise((resolve, reject) => { - Taro.startBluetoothDevicesDiscovery({ - allowDuplicatesKey: true, - success: resolve, - fail: reject - }); - - if (duration > 0) { - setTimeout(() => { - Taro.offBluetoothDeviceFound(getDevices); - Taro.stopBluetoothDevicesDiscovery(); - console.log("停止搜索") - }, duration); - } - }); - } - - //获取搜索到的设备 - const getDevices = (res) => { - res.devices.forEach(device => { - // 排除掉已搜索到的设备和名称不合法的设备, 将新发现的设备添加到列表中 - if (/^CM/.test(device.name) && !refStatus.current.devices.find(i => i.deviceId === device.deviceId)) { - changeStatus({devices: [ ...refStatus.current.devices, device ]}) - } - }); - } - - /** - * 连接设备 - * @param {{ name: string, deviceId: string, RSSI: number }} device - */ - const connect = async (device) => { - try { - changeStatus({connecting: device}) - console.log('connecting::', device) - await createConnection(device.deviceId); - await discoverService(device.deviceId); - await discoverCharacteristic(device.deviceId); - await notifyCharacteristicValueChange(device.deviceId); - } catch (e) { - changeStatus({connecting: null}) - Taro.showToast({ icon: 'none', title: '蓝牙连接失败' }); - throw e; - } - } - - /** 断开当前连接的设备 */ - const disconnect = async () => { - if (!refStatus.current.connected && !refStatus.current.connecting) return; - if (refStatus.current.connected) { - await closeConnection(refStatus.current.connected.deviceId); - resetCommand(); - changeStatus({ - connected: null, - serviceId: null, - characteristicId: null, - devices: [], - deviceLab: null - }) - } - - if (refStatus.current.connecting) { - await closeConnection(refStatus.current.connecting.deviceId); - changeStatus({connecting:null}) - } - } - - /** 创建 BLE 连接 */ - function createConnection(deviceId) { - return new Promise((resolve, reject) => { - Taro.createBLEConnection({ - deviceId, - timeout: 2000, - success: resolve, - fail: reject - }); - }); - } - - /** 关闭 BLE 连接 */ - function closeConnection(deviceId) { - return new Promise((resolve, reject) => { - Taro.closeBLEConnection({ - deviceId, - success: resolve, - fail: reject - }); - }); - } - - /** 搜索服务 */ - function discoverService(deviceId) { - return new Promise((resolve, reject) => { - Taro.getBLEDeviceServices({ - deviceId, - success: ({ services }) => { - const service = services.find(i => refStatus.current.serviceRule.test(i.uuid)); - if (!service) { - reject(new Error('服务不可用')); - } else { - changeStatus({serviceId: service.uuid}) - resolve(service); - } - }, - fail: reject - }); - }); - } - - /** 搜索特征 */ - function discoverCharacteristic(deviceId) { - return new Promise((resolve, reject) => { - Taro.getBLEDeviceCharacteristics({ - deviceId, - serviceId: refStatus.current.serviceId, - success: ({ characteristics }) => { - const characteristic = characteristics.find(i => refStatus.current.characteristicRule.test(i.uuid)); - if (!characteristic) { - reject(new Error('特征不可用')); - } else { - changeStatus({characteristicId: characteristic.uuid}) - resolve(characteristic); - } - }, - fail: reject - }) - }); - } - - /** 启动特征通知 */ - function notifyCharacteristicValueChange(deviceId, stateParm = true) { - return new Promise((resolve, reject) => { - Taro.notifyBLECharacteristicValueChange({ - deviceId, - serviceId: refStatus.current.serviceId, - characteristicId: refStatus.current.characteristicId, - state:stateParm, - success: resolve, - fail: reject - }); - }); - } - - /** - * 通知订阅器 - * @param {ArrayBuffer} buffer - */ - function notifySubscriber(buffer) { - if (refStatus.current.command) { - if (refStatus.current.debug) { - console.log(`[BLE RESP] ${uint8ArrayToHex(new Uint8Array(buffer))}`); - } - refStatus.current.command.fillResponse(buffer); - if (refStatus.current.command.isComplete) { - if (refStatus.current.command.isValid && refStatus.current.responseResolve) { - refStatus.current.responseResolve(refStatus.current.command.response); - } else if (!refStatus.current.command.isValid) { - refStatus.current.responseReject(new Error('无效数据')); - } - resetCommand(); - } - } else { - const uint8Array = new Uint8Array(buffer); - if (uint8Array[0] === 0xbb && uint8Array[1] === 1 && uint8Array[3] === 0) { - const ev = { type: 'measure', detail: { mode: uint8Array[2] } }; - emit(ev); - } - } - } - - /** - * 发送命令 - * @param {Command}} command - * @returns {Promise} - */ - function exec(command) { - return new Promise(async (resolve, reject) => { - if (refStatus.current.command) { - reject(new Error('正在执行其他命令')); - } else { - try { - refStatus.current.command = command; - const data = command.data; - for (let i = 0; i < data.length; i++) { - await sendData(data[i]); - } - - if (command.responseSize <= 0) { - resolve(true); - resetCommand(); - } else { - refStatus.current.responseReject = reject; - refStatus.current.responseResolve = resolve; - refStatus.current.responseTimer = setTimeout(() => { - reject(new Error('命令响应超时')); - resetCommand(); - }, command.timeout); - } - } catch (e) { - reject(e); - } - } - - }); - } - - /** - * 发送命令 - * @param {ArrayBuffer} buffer - */ - function sendData(buffer) { - if (refStatus.current.debug) { - console.log(`[BLE SEND] ${uint8ArrayToHex(new Uint8Array(buffer))}`); - } - return new Promise((resolve, reject) => { - console.log('current:::',refStatus.current) - Taro.writeBLECharacteristicValue({ - deviceId: refStatus.current.connected.deviceId, - serviceId: refStatus.current.serviceId, - characteristicId: refStatus.current.characteristicId, - value: buffer, - success: resolve, - fail: reject - }) - }); - } - - function resetCommand() { - if (refStatus.current.responseTimer) { - clearTimeout(refStatus.current.responseTimer); - } + // 绑定事件通知 + Taro.onBluetoothAdapterStateChange((res) => { + emit({ type: 'stateUpdate', detail: res }) + }) + Taro.onBLEConnectionStateChange((res) => { + emit({ type: res.connected ? 'connected' : 'disconnect', detail: res }) + }) + Taro.onBLECharacteristicValueChange(({ value }) => notifySubscriber(value)) + subscribe(async (ev) => { + if (ev.type === 'stateUpdate') { + // 蓝牙状态发生的变化 + changeStatus({ discovering: ev.detail.discovering, available: ev.detail.available }) + } else if (ev.type === 'disconnect' && refStatus.current.connected && refStatus.current.connected.deviceId === ev.detail.deviceId) { + // 断开连接 changeStatus({ - command: null, - responseResolve: null, - responseReject: null, - responseTimer: null + connected: null, + serviceId: null, + characteristicId: null, + deviceLab: null, + devices: [], }) + Taro.showToast({ icon: 'none', title: '蓝牙连接已断开' }) + } else if (ev.type === 'connected' && refStatus.current.connecting) { + // 连接成功 + changeStatus({ connected: refStatus.current.connecting, connecting: null }) + Taro.showToast({ title: '蓝牙已连接' }) + } else if (ev.type === 'measure') { + //监听取色仪主动推送lab + await measureAndGetLab() + } + }) + } + + /** 打开蓝牙适配器 */ + const openAdapter = () => { + return new Promise((resolve, reject) => { + Taro.openBluetoothAdapter({ + success: resolve, + fail: reject, + }) + }) + } + + /** + * 推送事件 + * @param {{type: string; data: any}} event + */ + const emit = (event) => { + refStatus.current.listeners.forEach((cb) => { + cb && cb(event) + }) + } + + const subscribe = (cb) => { + if (cb) { + changeStatus({ + listeners: refStatus.current.listeners.add(cb), + }) + } + } + + /** + * 获取蓝牙适配器状态 + * @returns {Promise<{discovering: boolean; available: boolean}>} + */ + const getAdapterState = () => { + return new Promise((resolve, reject) => { + Taro.getBluetoothAdapterState({ + success: resolve, + fail: reject, + }) + }) + } + + /** + * 启动设备扫描 + * @param {(res: { devices: { name: string, deviceId: string, RSSI: number }[] }) => void} cb + * @param {number} duration + */ + const startScan = (duration = 30000) => { + console.log('开始寻找') + changeStatus({ devices: [] }) + Taro.onBluetoothDeviceFound(getDevices) + return new Promise((resolve, reject) => { + Taro.startBluetoothDevicesDiscovery({ + allowDuplicatesKey: true, + success: resolve, + fail: reject, + }) + + if (duration > 0) { + setTimeout(() => { + Taro.offBluetoothDeviceFound(getDevices) + Taro.stopBluetoothDevicesDiscovery() + console.log('停止搜索') + }, duration) + } + }) + } + + //获取搜索到的设备 + const getDevices = (res) => { + res.devices.forEach((device) => { + // 排除掉已搜索到的设备和名称不合法的设备, 将新发现的设备添加到列表中 + if (/^CM/.test(device.name) && !refStatus.current.devices.find((i) => i.deviceId === device.deviceId)) { + changeStatus({ devices: [...refStatus.current.devices, device] }) + } + }) + } + + /** + * 连接设备 + * @param {{ name: string, deviceId: string, RSSI: number }} device + */ + const connect = async (device) => { + try { + changeStatus({ connecting: device }) + console.log('connecting::', device) + await createConnection(device.deviceId) + await discoverService(device.deviceId) + await discoverCharacteristic(device.deviceId) + await notifyCharacteristicValueChange(device.deviceId) + } catch (e) { + changeStatus({ connecting: null }) + Taro.showToast({ icon: 'none', title: '蓝牙连接失败' }) + throw e + } + } + + /** 断开当前连接的设备 */ + const disconnect = async () => { + if (!refStatus.current.connected && !refStatus.current.connecting) return + if (refStatus.current.connected) { + await closeConnection(refStatus.current.connected.deviceId) + resetCommand() + changeStatus({ + connected: null, + serviceId: null, + characteristicId: null, + devices: [], + deviceLab: null, + }) } - /** - * 测量 - * @param {number} mode - * @returns {Promise} - */ - async function measure (mode = 0) { - console.log('current1:::',Command.WakeUp) - await exec(Command.WakeUp); - console.log('current2:::',Command.WakeUp) - await waitFor(50); - console.log('current3:::',Command.WakeUp) - return await exec(Command.measure(mode)); + if (refStatus.current.connecting) { + await closeConnection(refStatus.current.connecting.deviceId) + changeStatus({ connecting: null }) } + } - /** - * 获取测量的 lab 值 - * @param {number} mode - * @returns {Promise<{ L: number, a: number, b: number }>} - */ - async function getLab(mode = 0) { - await exec(Command.WakeUp); - await waitFor(50); - const data: any = await exec(Command.getLab(mode)); - return { - L: uint8ArrayToFloat32(data.slice(5, 9)), - a: uint8ArrayToFloat32(data.slice(9, 13)), - b: uint8ArrayToFloat32(data.slice(13, 17)), - }; + /** 创建 BLE 连接 */ + function createConnection(deviceId) { + return new Promise((resolve, reject) => { + Taro.createBLEConnection({ + deviceId, + timeout: 2000, + success: resolve, + fail: reject, + }) + }) + } + + /** 关闭 BLE 连接 */ + function closeConnection(deviceId) { + return new Promise((resolve, reject) => { + Taro.closeBLEConnection({ + deviceId, + success: resolve, + fail: reject, + }) + }) + } + + /** 搜索服务 */ + function discoverService(deviceId) { + return new Promise((resolve, reject) => { + Taro.getBLEDeviceServices({ + deviceId, + success: ({ services }) => { + const service = services.find((i) => refStatus.current.serviceRule.test(i.uuid)) + if (!service) { + reject(new Error('服务不可用')) + } else { + changeStatus({ serviceId: service.uuid }) + resolve(service) + } + }, + fail: reject, + }) + }) + } + + /** 搜索特征 */ + function discoverCharacteristic(deviceId) { + return new Promise((resolve, reject) => { + Taro.getBLEDeviceCharacteristics({ + deviceId, + serviceId: refStatus.current.serviceId, + success: ({ characteristics }) => { + const characteristic = characteristics.find((i) => refStatus.current.characteristicRule.test(i.uuid)) + if (!characteristic) { + reject(new Error('特征不可用')) + } else { + changeStatus({ characteristicId: characteristic.uuid }) + resolve(characteristic) + } + }, + fail: reject, + }) + }) + } + + /** 启动特征通知 */ + function notifyCharacteristicValueChange(deviceId, stateParm = true) { + return new Promise((resolve, reject) => { + Taro.notifyBLECharacteristicValueChange({ + deviceId, + serviceId: refStatus.current.serviceId, + characteristicId: refStatus.current.characteristicId, + state: stateParm, + success: resolve, + fail: reject, + }) + }) + } + + /** + * 通知订阅器 + * @param {ArrayBuffer} buffer + */ + function notifySubscriber(buffer) { + if (refStatus.current.command) { + if (refStatus.current.debug) { + console.log(`[BLE RESP] ${uint8ArrayToHex(new Uint8Array(buffer))}`) + } + refStatus.current.command.fillResponse(buffer) + if (refStatus.current.command.isComplete) { + if (refStatus.current.command.isValid && refStatus.current.responseResolve) { + refStatus.current.responseResolve(refStatus.current.command.response) + } else if (!refStatus.current.command.isValid) { + refStatus.current.responseReject(new Error('无效数据')) + } + resetCommand() + } + } else { + const uint8Array = new Uint8Array(buffer) + if (uint8Array[0] === 0xbb && uint8Array[1] === 1 && uint8Array[3] === 0) { + const ev = { type: 'measure', detail: { mode: uint8Array[2] } } + emit(ev) + } } + } - /** - * 测量并获取 lab 值 - * @param {number} mode - * @returns {Promise<{L: number, a: number, b: number}>} - */ - async function measureAndGetLab(mode = 0) { - await measure(mode); - await waitFor(50); - const lab = await getLab(mode); - console.log('lab2::',lab) - changeStatus({deviceLab:lab}) - return lab + /** + * 发送命令 + * @param {Command}} command + * @returns {Promise} + */ + function exec(command) { + return new Promise(async (resolve, reject) => { + if (refStatus.current.command) { + reject(new Error('正在执行其他命令')) + } else { + try { + refStatus.current.command = command + const data = command.data + for (let i = 0; i < data.length; i++) { + await sendData(data[i]) + } + + if (command.responseSize <= 0) { + resolve(true) + resetCommand() + } else { + refStatus.current.responseReject = reject + refStatus.current.responseResolve = resolve + refStatus.current.responseTimer = setTimeout(() => { + reject(new Error('命令响应超时')) + resetCommand() + }, command.timeout) + } + } catch (e) { + reject(e) + } + } + }) + } + + /** + * 发送命令 + * @param {ArrayBuffer} buffer + */ + function sendData(buffer) { + if (refStatus.current.debug) { + console.log(`[BLE SEND] ${uint8ArrayToHex(new Uint8Array(buffer))}`) } + return new Promise((resolve, reject) => { + console.log('current:::', refStatus.current) + Taro.writeBLECharacteristicValue({ + deviceId: refStatus.current.connected.deviceId, + serviceId: refStatus.current.serviceId, + characteristicId: refStatus.current.characteristicId, + value: buffer, + success: resolve, + fail: reject, + }) + }) + } - return } + */ + async function getLab(mode = 0) { + await exec(Command.WakeUp) + await waitFor(50) + const data: any = await exec(Command.getLab(mode)) + return { + L: uint8ArrayToFloat32(data.slice(5, 9)), + a: uint8ArrayToFloat32(data.slice(9, 13)), + b: uint8ArrayToFloat32(data.slice(13, 17)), + } + } + + /** + * 测量并获取 lab 值 + * @param {number} mode + * @returns {Promise<{L: number, a: number, b: number}>} + */ + async function measureAndGetLab(mode = 0) { + await measure(mode) + await waitFor(50) + const lab = await getLab(mode) + console.log('lab2::', lab) + changeStatus({ deviceLab: lab }) + return lab + } + + return ( + + disconnect, + }} + /> + ) } - export const useBluetoothTwo = () => { - const res = React.useContext(Context) - if(res) { - return {...res} - } else { - return {} - } - -} \ No newline at end of file + const res = React.useContext(Context) + if (res) { + return { ...res } + } else { + return {} + } +} diff --git a/src/use/contextBlueTooth.tsx b/src/use/contextBlueTooth.tsx index 518c5cc..7fb43ce 100644 --- a/src/use/contextBlueTooth.tsx +++ b/src/use/contextBlueTooth.tsx @@ -1,477 +1,477 @@ -import React, {useRef, useState } from "react" -import Taro from "@tarojs/taro"; -import { Command } from "@/common/bluetooth/command"; -import { uint8ArrayToFloat32, uint8ArrayToHex, waitFor } from "@/common/bluetooth/utils"; - +import React, { useRef, useState } from 'react' +import Taro from '@tarojs/taro' +import { Command } from '@/common/bluetooth/command' +import { uint8ArrayToFloat32, uint8ArrayToHex, waitFor } from '@/common/bluetooth/utils' interface params { - init: () => void - state: Object, - startScan: () => void, - measureAndGetLab: () => any, - getAdapterState: () => void, - connect: (any) => void, - disconnect: () => void + init: () => void + state: Object + startScan: () => void + measureAndGetLab: () => any + getAdapterState: () => void + connect: (any) => void + disconnect: () => void } -const Context = React.createContext(null) +const Context = React.createContext(null) interface stateStype { - listeners: any, - discovering: boolean, - available: boolean, - connected: any, - connecting: any, - serviceRule: any, - serviceId: any, - characteristicRule: any, - characteristicId: any, + listeners: any + discovering: boolean + available: boolean + connected: any + connecting: any + serviceRule: any + serviceId: any + characteristicRule: any + characteristicId: any - /** 正在执行的命令 */ - command: any, - responseResolve: any, - responseReject: any, - responseTimer: any, + /** 正在执行的命令 */ + command: any + responseResolve: any + responseReject: any + responseTimer: any - /** 是否显示蓝牙调试信息 */ - debug: any, - //搜索到的设备 - devices: any, - //取色仪主动返回的数据 - deviceLab: any + /** 是否显示蓝牙调试信息 */ + debug: any + //搜索到的设备 + devices: any + //取色仪主动返回的数据 + deviceLab: any } let stateObj: stateStype = { - /** 事件监听器 */ - listeners: new Set(), - /** 正在扫描设备 */ - discovering: false, - /** 蓝牙是否可用 */ - available: true, - /** 当前连接的设备 */ - connected: null, - /** 正在连接的设备 */ - connecting: null, + /** 事件监听器 */ + listeners: new Set(), + /** 正在扫描设备 */ + discovering: false, + /** 蓝牙是否可用 */ + available: true, + /** 当前连接的设备 */ + connected: null, + /** 正在连接的设备 */ + connecting: null, - serviceRule: /^0000FFE0/, - serviceId: null, - characteristicRule: /^0000FFE1/, - characteristicId: null, + serviceRule: /^0000FFE0/, + serviceId: null, + characteristicRule: /^0000FFE1/, + characteristicId: null, - /** 正在执行的命令 */ - command: null, - responseResolve: null, - responseReject: null, - responseTimer: null, + /** 正在执行的命令 */ + command: null, + responseResolve: null, + responseReject: null, + responseTimer: null, - /** 是否显示蓝牙调试信息 */ - debug: true, - //搜索到的设备 - devices: [], - //取色仪主动返回的数据 - deviceLab: null + /** 是否显示蓝牙调试信息 */ + debug: true, + //搜索到的设备 + devices: [], + //取色仪主动返回的数据 + deviceLab: null, } export default (props) => { - let refStatus = useRef(stateObj) - let [state, setState] = useState(refStatus.current) + let refStatus = useRef(stateObj) + let [state, setState] = useState(refStatus.current) - const changeStatus = (obj:Object): void => { - refStatus.current = {...refStatus.current, ...obj} - setState({...refStatus.current}) + const changeStatus = (obj: Object): void => { + refStatus.current = { ...refStatus.current, ...obj } + setState({ ...refStatus.current }) + } + + const init = async () => { + try { + await openAdapter() + } catch (e) { + changeStatus({ available: false }) } - const init = async () => { - try{ - await openAdapter(); - }catch(e) { - changeStatus({available:false}) - } - - // 绑定事件通知 - Taro.onBluetoothAdapterStateChange(res => { - emit({ type: 'stateUpdate', detail: res }); - }); - Taro.onBLEConnectionStateChange(res => { - emit({ type: res.connected ? 'connected' : 'disconnect', detail: res }); - }); - Taro.onBLECharacteristicValueChange(({ value }) => notifySubscriber(value)); - subscribe(async ev => { - if (ev.type === 'stateUpdate') { - // 蓝牙状态发生的变化 - changeStatus({discovering:ev.detail.discovering, available:ev.detail.available}) - } else if (ev.type === 'disconnect' && refStatus.current.connected && refStatus.current.connected.deviceId === ev.detail.deviceId) { - // 断开连接 - changeStatus({ - connected:null, - serviceId:null, - characteristicId:null, - deviceLab:null, - devices:[] - }) - Taro.showToast({ icon: 'none', title: '蓝牙连接已断开' }); - } else if (ev.type === 'connected' && refStatus.current.connecting) { - // 连接成功 - changeStatus({connected: refStatus.current.connecting, connecting: null}) - Taro.showToast({ title: '蓝牙已连接' }); - } else if (ev.type === 'measure') { - //监听取色仪主动推送lab - await measureAndGetLab() - } - - }); - } - - /** 打开蓝牙适配器 */ - const openAdapter = () => { - return new Promise((resolve, reject) => { - Taro.openBluetoothAdapter({ - success: resolve, - fail: reject - }); - }); - } - - /** - * 推送事件 - * @param {{type: string; data: any}} event - */ - const emit = (event) => { - refStatus.current.listeners.forEach(cb => { - cb && cb(event); - }); - } - - const subscribe = (cb) => { - if (cb) { - changeStatus({ - listeners: refStatus.current.listeners.add(cb) - }) - } - } - - /** - * 获取蓝牙适配器状态 - * @returns {Promise<{discovering: boolean; available: boolean}>} - */ - const getAdapterState = () => { - return new Promise((resolve, reject) => { - Taro.getBluetoothAdapterState({ - success: resolve, - fail: reject - }) - }) - } - - /** - * 启动设备扫描 - * @param {(res: { devices: { name: string, deviceId: string, RSSI: number }[] }) => void} cb - * @param {number} duration - */ - const startScan = (duration = 30000) => { - console.log('开始寻找') - changeStatus({devices:[]}) - Taro.onBluetoothDeviceFound(getDevices); - return new Promise((resolve, reject) => { - Taro.startBluetoothDevicesDiscovery({ - allowDuplicatesKey: true, - success: resolve, - fail: reject - }); - - if (duration > 0) { - setTimeout(() => { - Taro.offBluetoothDeviceFound(getDevices); - Taro.stopBluetoothDevicesDiscovery(); - console.log("停止搜索") - }, duration); - } - }); - } - - //获取搜索到的设备 - const getDevices = (res) => { - res.devices.forEach(device => { - // 排除掉已搜索到的设备和名称不合法的设备, 将新发现的设备添加到列表中 - if (/^CM/.test(device.name) && !refStatus.current.devices.find(i => i.deviceId === device.deviceId)) { - changeStatus({devices: [ ...refStatus.current.devices, device ]}) - } - }); - } - - /** - * 连接设备 - * @param {{ name: string, deviceId: string, RSSI: number }} device - */ - const connect = async (device) => { - try { - changeStatus({connecting: device}) - console.log('connecting::', device) - await createConnection(device.deviceId); - await discoverService(device.deviceId); - await discoverCharacteristic(device.deviceId); - await notifyCharacteristicValueChange(device.deviceId); - } catch (e) { - changeStatus({connecting: null}) - Taro.showToast({ icon: 'none', title: '蓝牙连接失败' }); - throw e; - } - } - - /** 断开当前连接的设备 */ - const disconnect = async () => { - if (!refStatus.current.connected && !refStatus.current.connecting) return; - if (refStatus.current.connected) { - await closeConnection(refStatus.current.connected.deviceId); - resetCommand(); - changeStatus({ - connected: null, - serviceId: null, - characteristicId: null, - devices: [], - deviceLab: null - }) - } - - if (refStatus.current.connecting) { - await closeConnection(refStatus.current.connecting.deviceId); - changeStatus({connecting:null}) - } - } - - /** 创建 BLE 连接 */ - function createConnection(deviceId) { - return new Promise((resolve, reject) => { - Taro.createBLEConnection({ - deviceId, - timeout: 2000, - success: resolve, - fail: reject - }); - }); - } - - /** 关闭 BLE 连接 */ - function closeConnection(deviceId) { - return new Promise((resolve, reject) => { - Taro.closeBLEConnection({ - deviceId, - success: resolve, - fail: reject - }); - }); - } - - /** 搜索服务 */ - function discoverService(deviceId) { - return new Promise((resolve, reject) => { - Taro.getBLEDeviceServices({ - deviceId, - success: ({ services }) => { - const service = services.find(i => refStatus.current.serviceRule.test(i.uuid)); - if (!service) { - reject(new Error('服务不可用')); - } else { - changeStatus({serviceId: service.uuid}) - resolve(service); - } - }, - fail: reject - }); - }); - } - - /** 搜索特征 */ - function discoverCharacteristic(deviceId) { - return new Promise((resolve, reject) => { - Taro.getBLEDeviceCharacteristics({ - deviceId, - serviceId: refStatus.current.serviceId, - success: ({ characteristics }) => { - const characteristic = characteristics.find(i => refStatus.current.characteristicRule.test(i.uuid)); - if (!characteristic) { - reject(new Error('特征不可用')); - } else { - changeStatus({characteristicId: characteristic.uuid}) - resolve(characteristic); - } - }, - fail: reject - }) - }); - } - - /** 启动特征通知 */ - function notifyCharacteristicValueChange(deviceId, stateParm = true) { - return new Promise((resolve, reject) => { - Taro.notifyBLECharacteristicValueChange({ - deviceId, - serviceId: refStatus.current.serviceId, - characteristicId: refStatus.current.characteristicId, - state:stateParm, - success: resolve, - fail: reject - }); - }); - } - - /** - * 通知订阅器 - * @param {ArrayBuffer} buffer - */ - function notifySubscriber(buffer) { - if (refStatus.current.command) { - if (refStatus.current.debug) { - console.log(`[BLE RESP] ${uint8ArrayToHex(new Uint8Array(buffer))}`); - } - refStatus.current.command.fillResponse(buffer); - if (refStatus.current.command.isComplete) { - if (refStatus.current.command.isValid && refStatus.current.responseResolve) { - refStatus.current.responseResolve(refStatus.current.command.response); - } else if (!refStatus.current.command.isValid) { - refStatus.current.responseReject(new Error('无效数据')); - } - resetCommand(); - } - } else { - const uint8Array = new Uint8Array(buffer); - if (uint8Array[0] === 0xbb && uint8Array[1] === 1 && uint8Array[3] === 0) { - const ev = { type: 'measure', detail: { mode: uint8Array[2] } }; - emit(ev); - } - } - } - - /** - * 发送命令 - * @param {Command}} command - * @returns {Promise} - */ - function exec(command) { - return new Promise(async (resolve, reject) => { - if (refStatus.current.command) { - reject(new Error('正在执行其他命令')); - } else { - try { - refStatus.current.command = command; - const data = command.data; - for (let i = 0; i < data.length; i++) { - await sendData(data[i]); - } - - if (command.responseSize <= 0) { - resolve(true); - resetCommand(); - } else { - refStatus.current.responseReject = reject; - refStatus.current.responseResolve = resolve; - refStatus.current.responseTimer = setTimeout(() => { - reject(new Error('命令响应超时')); - resetCommand(); - }, command.timeout); - } - } catch (e) { - reject(e); - } - } - - }); - } - - /** - * 发送命令 - * @param {ArrayBuffer} buffer - */ - function sendData(buffer) { - if (refStatus.current.debug) { - console.log(`[BLE SEND] ${uint8ArrayToHex(new Uint8Array(buffer))}`); - } - return new Promise((resolve, reject) => { - console.log('current:::',refStatus.current) - Taro.writeBLECharacteristicValue({ - deviceId: refStatus.current.connected.deviceId, - serviceId: refStatus.current.serviceId, - characteristicId: refStatus.current.characteristicId, - value: buffer, - success: resolve, - fail: reject - }) - }); - } - - function resetCommand() { - if (refStatus.current.responseTimer) { - clearTimeout(refStatus.current.responseTimer); - } + // 绑定事件通知 + Taro.onBluetoothAdapterStateChange((res) => { + emit({ type: 'stateUpdate', detail: res }) + }) + Taro.onBLEConnectionStateChange((res) => { + emit({ type: res.connected ? 'connected' : 'disconnect', detail: res }) + }) + Taro.onBLECharacteristicValueChange(({ value }) => notifySubscriber(value)) + subscribe(async (ev) => { + if (ev.type === 'stateUpdate') { + // 蓝牙状态发生的变化 + changeStatus({ discovering: ev.detail.discovering, available: ev.detail.available }) + } else if (ev.type === 'disconnect' && refStatus.current.connected && refStatus.current.connected.deviceId === ev.detail.deviceId) { + // 断开连接 changeStatus({ - command: null, - responseResolve: null, - responseReject: null, - responseTimer: null + connected: null, + serviceId: null, + characteristicId: null, + deviceLab: null, + devices: [], }) + Taro.showToast({ icon: 'none', title: '蓝牙连接已断开' }) + } else if (ev.type === 'connected' && refStatus.current.connecting) { + // 连接成功 + changeStatus({ connected: refStatus.current.connecting, connecting: null }) + Taro.showToast({ title: '蓝牙已连接' }) + } else if (ev.type === 'measure') { + //监听取色仪主动推送lab + await measureAndGetLab() + } + }) + } + + /** 打开蓝牙适配器 */ + const openAdapter = () => { + return new Promise((resolve, reject) => { + Taro.openBluetoothAdapter({ + success: resolve, + fail: reject, + }) + }) + } + + /** + * 推送事件 + * @param {{type: string; data: any}} event + */ + const emit = (event) => { + refStatus.current.listeners.forEach((cb) => { + cb && cb(event) + }) + } + + const subscribe = (cb) => { + if (cb) { + changeStatus({ + listeners: refStatus.current.listeners.add(cb), + }) + } + } + + /** + * 获取蓝牙适配器状态 + * @returns {Promise<{discovering: boolean; available: boolean}>} + */ + const getAdapterState = () => { + return new Promise((resolve, reject) => { + Taro.getBluetoothAdapterState({ + success: resolve, + fail: reject, + }) + }) + } + + /** + * 启动设备扫描 + * @param {(res: { devices: { name: string, deviceId: string, RSSI: number }[] }) => void} cb + * @param {number} duration + */ + const startScan = (duration = 30000) => { + console.log('开始寻找') + changeStatus({ devices: [] }) + Taro.onBluetoothDeviceFound(getDevices) + return new Promise((resolve, reject) => { + Taro.startBluetoothDevicesDiscovery({ + allowDuplicatesKey: true, + success: resolve, + fail: reject, + }) + + if (duration > 0) { + setTimeout(() => { + Taro.offBluetoothDeviceFound(getDevices) + Taro.stopBluetoothDevicesDiscovery() + console.log('停止搜索') + }, duration) + } + }) + } + + //获取搜索到的设备 + const getDevices = (res) => { + res.devices.forEach((device) => { + // 排除掉已搜索到的设备和名称不合法的设备, 将新发现的设备添加到列表中 + if (/^CM/.test(device.name) && !refStatus.current.devices.find((i) => i.deviceId === device.deviceId)) { + changeStatus({ devices: [...refStatus.current.devices, device] }) + } + }) + } + + /** + * 连接设备 + * @param {{ name: string, deviceId: string, RSSI: number }} device + */ + const connect = async (device) => { + try { + changeStatus({ connecting: device }) + console.log('connecting::', device) + await createConnection(device.deviceId) + await discoverService(device.deviceId) + await discoverCharacteristic(device.deviceId) + await notifyCharacteristicValueChange(device.deviceId) + } catch (e) { + changeStatus({ connecting: null }) + Taro.showToast({ icon: 'none', title: '蓝牙连接失败' }) + throw e + } + } + + /** 断开当前连接的设备 */ + const disconnect = async () => { + if (!refStatus.current.connected && !refStatus.current.connecting) return + if (refStatus.current.connected) { + await closeConnection(refStatus.current.connected.deviceId) + resetCommand() + changeStatus({ + connected: null, + serviceId: null, + characteristicId: null, + devices: [], + deviceLab: null, + }) } - /** - * 测量 - * @param {number} mode - * @returns {Promise} - */ - async function measure (mode = 0) { - console.log('current1:::',Command.WakeUp) - await exec(Command.WakeUp); - console.log('current2:::',Command.WakeUp) - await waitFor(50); - console.log('current3:::',Command.WakeUp) - return await exec(Command.measure(mode)); + if (refStatus.current.connecting) { + await closeConnection(refStatus.current.connecting.deviceId) + changeStatus({ connecting: null }) } + } - /** - * 获取测量的 lab 值 - * @param {number} mode - * @returns {Promise<{ L: number, a: number, b: number }>} - */ - async function getLab(mode = 0) { - await exec(Command.WakeUp); - await waitFor(50); - const data: any = await exec(Command.getLab(mode)); - return { - L: uint8ArrayToFloat32(data.slice(5, 9)), - a: uint8ArrayToFloat32(data.slice(9, 13)), - b: uint8ArrayToFloat32(data.slice(13, 17)), - }; + /** 创建 BLE 连接 */ + function createConnection(deviceId) { + return new Promise((resolve, reject) => { + Taro.createBLEConnection({ + deviceId, + timeout: 2000, + success: resolve, + fail: reject, + }) + }) + } + + /** 关闭 BLE 连接 */ + function closeConnection(deviceId) { + return new Promise((resolve, reject) => { + Taro.closeBLEConnection({ + deviceId, + success: resolve, + fail: reject, + }) + }) + } + + /** 搜索服务 */ + function discoverService(deviceId) { + return new Promise((resolve, reject) => { + Taro.getBLEDeviceServices({ + deviceId, + success: ({ services }) => { + const service = services.find((i) => refStatus.current.serviceRule.test(i.uuid)) + if (!service) { + reject(new Error('服务不可用')) + } else { + changeStatus({ serviceId: service.uuid }) + resolve(service) + } + }, + fail: reject, + }) + }) + } + + /** 搜索特征 */ + function discoverCharacteristic(deviceId) { + return new Promise((resolve, reject) => { + Taro.getBLEDeviceCharacteristics({ + deviceId, + serviceId: refStatus.current.serviceId, + success: ({ characteristics }) => { + const characteristic = characteristics.find((i) => refStatus.current.characteristicRule.test(i.uuid)) + if (!characteristic) { + reject(new Error('特征不可用')) + } else { + changeStatus({ characteristicId: characteristic.uuid }) + resolve(characteristic) + } + }, + fail: reject, + }) + }) + } + + /** 启动特征通知 */ + function notifyCharacteristicValueChange(deviceId, stateParm = true) { + return new Promise((resolve, reject) => { + Taro.notifyBLECharacteristicValueChange({ + deviceId, + serviceId: refStatus.current.serviceId, + characteristicId: refStatus.current.characteristicId, + state: stateParm, + success: resolve, + fail: reject, + }) + }) + } + + /** + * 通知订阅器 + * @param {ArrayBuffer} buffer + */ + function notifySubscriber(buffer) { + if (refStatus.current.command) { + if (refStatus.current.debug) { + console.log(`[BLE RESP] ${uint8ArrayToHex(new Uint8Array(buffer))}`) + } + refStatus.current.command.fillResponse(buffer) + if (refStatus.current.command.isComplete) { + if (refStatus.current.command.isValid && refStatus.current.responseResolve) { + refStatus.current.responseResolve(refStatus.current.command.response) + } else if (!refStatus.current.command.isValid) { + refStatus.current.responseReject(new Error('无效数据')) + } + resetCommand() + } + } else { + const uint8Array = new Uint8Array(buffer) + if (uint8Array[0] === 0xbb && uint8Array[1] === 1 && uint8Array[3] === 0) { + const ev = { type: 'measure', detail: { mode: uint8Array[2] } } + emit(ev) + } } + } - /** - * 测量并获取 lab 值 - * @param {number} mode - * @returns {Promise<{L: number, a: number, b: number}>} - */ - async function measureAndGetLab(mode = 0) { - await measure(mode); - await waitFor(50); - const lab = await getLab(mode); - console.log('lab2::',lab) - changeStatus({deviceLab:lab}) - return lab + /** + * 发送命令 + * @param {Command}} command + * @returns {Promise} + */ + function exec(command) { + return new Promise(async (resolve, reject) => { + if (refStatus.current.command) { + reject(new Error('正在执行其他命令')) + } else { + try { + refStatus.current.command = command + const data = command.data + for (let i = 0; i < data.length; i++) { + await sendData(data[i]) + } + + if (command.responseSize <= 0) { + resolve(true) + resetCommand() + } else { + refStatus.current.responseReject = reject + refStatus.current.responseResolve = resolve + refStatus.current.responseTimer = setTimeout(() => { + reject(new Error('命令响应超时')) + resetCommand() + }, command.timeout) + } + } catch (e) { + reject(e) + } + } + }) + } + + /** + * 发送命令 + * @param {ArrayBuffer} buffer + */ + function sendData(buffer) { + if (refStatus.current.debug) { + console.log(`[BLE SEND] ${uint8ArrayToHex(new Uint8Array(buffer))}`) } + return new Promise((resolve, reject) => { + console.log('current:::', refStatus.current) + Taro.writeBLECharacteristicValue({ + deviceId: refStatus.current.connected.deviceId, + serviceId: refStatus.current.serviceId, + characteristicId: refStatus.current.characteristicId, + value: buffer, + success: resolve, + fail: reject, + }) + }) + } - return } + */ + async function getLab(mode = 0) { + await exec(Command.WakeUp) + await waitFor(50) + const data: any = await exec(Command.getLab(mode)) + return { + L: uint8ArrayToFloat32(data.slice(5, 9)), + a: uint8ArrayToFloat32(data.slice(9, 13)), + b: uint8ArrayToFloat32(data.slice(13, 17)), + } + } + + /** + * 测量并获取 lab 值 + * @param {number} mode + * @returns {Promise<{L: number, a: number, b: number}>} + */ + async function measureAndGetLab(mode = 0) { + await measure(mode) + await waitFor(50) + const lab = await getLab(mode) + console.log('lab2::', lab) + changeStatus({ deviceLab: lab }) + return lab + } + + return ( + + disconnect, + }} + /> + ) } - export const useBluetooth = () => { - const res = React.useContext(Context) - if(res) { - return {...res} - } else { - return {} - } - -} \ No newline at end of file + const res = React.useContext(Context) + if (res) { + return { ...res } + } else { + return {} + } +} diff --git a/src/use/useCheckAuthorize.tsx b/src/use/useCheckAuthorize.tsx index d0ece73..abad977 100644 --- a/src/use/useCheckAuthorize.tsx +++ b/src/use/useCheckAuthorize.tsx @@ -1,51 +1,62 @@ -import { alert } from "@/common/common"; -import Taro from "@tarojs/taro"; -import { memo, useCallback, useState } from "react"; +import { alert } from '@/common/common' +import Taro from '@tarojs/taro' +import { memo, useCallback, useState } from 'react' -type Scope = 'scope.userLocation'|'scope.userLocation'|'scope.record'|'scope.camera'|'scope.bluetooth'|'scope.writePhotosAlbum'|'scope.addPhoneContact'|'scope.addPhoneCalendar'|'scope.werun'|'scope.address'|'scope.invoiceTitle'|'scope.invoice'|'scope.userInfo' +type Scope = + | 'scope.userLocation' + | 'scope.userLocation' + | 'scope.record' + | 'scope.camera' + | 'scope.bluetooth' + | 'scope.writePhotosAlbum' + | 'scope.addPhoneContact' + | 'scope.addPhoneCalendar' + | 'scope.werun' + | 'scope.address' + | 'scope.invoiceTitle' + | 'scope.invoice' + | 'scope.userInfo' type Param = { - scope: Scope, - msg: string //检查不通过时警告 + scope: Scope + msg: string //检查不通过时警告 } -export default ({scope, msg}: Param) => { - //这个hook微信授权检查授权 - const check = useCallback(() => { - return new Promise((reslove, reject) => { - Taro.getSetting({ - success: (res) => { - if(res.authSetting[scope]) { - reslove(true) - } else if (res.authSetting[scope] === undefined) { - Taro.authorize({ - scope: scope, - success() { - reslove(true) - }, - fail() { - alert.none(msg) - reject(false) - } - }) - } else { - Taro.openSetting({ - success(res) { - if(res.authSetting[scope]) { - reslove(true) - } else { - alert.none(msg) - reject(false) - } - } - }) - } - } +export default ({ scope, msg }: Param) => { + //这个hook微信授权检查授权 + const check = useCallback(() => { + return new Promise((reslove, reject) => { + Taro.getSetting({ + success: (res) => { + if (res.authSetting[scope]) { + reslove(true) + } else if (res.authSetting[scope] === undefined) { + Taro.authorize({ + scope: scope, + success() { + reslove(true) + }, + fail() { + alert.none(msg) + reject(false) + }, }) - }) - - }, [scope]) + } else { + Taro.openSetting({ + success(res) { + if (res.authSetting[scope]) { + reslove(true) + } else { + alert.none(msg) + reject(false) + } + }, + }) + } + }, + }) + }) + }, [scope]) - return { - check, - } - -} \ No newline at end of file + return { + check, + } +} diff --git a/src/use/useCommon.ts b/src/use/useCommon.ts index 0b6c366..f09525d 100644 --- a/src/use/useCommon.ts +++ b/src/use/useCommon.ts @@ -1,92 +1,90 @@ -import { SubscriptionMessageApi } from "@/api/user" -import Taro from "@tarojs/taro" -import dayjs from "dayjs" -import { useEffect, useRef, useState } from "react" +import { SubscriptionMessageApi } from '@/api/user' +import Taro from '@tarojs/taro' +import dayjs from 'dayjs' +import { useEffect, useRef, useState } from 'react' //倒计时hook export const useTimeCountDown = () => { - const [showTime, setShowTime] = useState({ - DD: '', - HH: '', - MM: '', - SS: '' - }) - const [timeStatus, setTimeStatus] = useState<0|1|2>(0) //倒计时状体 0:倒计时未开始 1:倒计时中, 2:倒计时已结束 - const timeObj:any = useRef() - const endTime = useRef('') - const onStart = (val = '') => { - console.log('time:::', val) - endTime.current = val - if(endTime.current) { - clearInterval(timeObj.current) - timeObj.current = setInterval(() => { - count_down() - }, 1000) - } + const [showTime, setShowTime] = useState({ + DD: '', + HH: '', + MM: '', + SS: '', + }) + const [timeStatus, setTimeStatus] = useState<0 | 1 | 2>(0) //倒计时状体 0:倒计时未开始 1:倒计时中, 2:倒计时已结束 + const timeObj: any = useRef() + const endTime = useRef('') + const onStart = (val = '') => { + console.log('time:::', val) + endTime.current = val + if (endTime.current) { + clearInterval(timeObj.current) + timeObj.current = setInterval(() => { + count_down() + }, 1000) } - useEffect(() => { - return () => { - clearInterval(timeObj.current) - } - }, []) - const count_down = () => { - var startData = dayjs(); - var endDate = dayjs(endTime.current); - setTimeStatus(() => 1) - if(startData >= endDate) { - clearInterval(timeObj.current) - setShowTime((e) => ({...e, DD:'00', HH:'00', MM:'00', SS:'00'})) - setTimeStatus(() => 2) - return false - } - var _dd = endDate.diff(startData,'day'); - var _hh = endDate.diff(startData,'hour'); - var _mm = endDate.diff(startData,'minute'); - var _ss = endDate.diff(startData,'second'); - // 转换 - var hh = _hh - (_dd*24); - var mm = _mm - (_hh*60); - var ss = _ss - (_mm*60); - // 格式化 - var DD = ('00'+_dd).slice(-2); - var HH = ('00'+hh).slice(-2); - var MM = ('00'+mm).slice(-2); - var SS = ('00'+ss).slice(-2); - console.log('endTime::', `${DD}-${HH}-${MM}-${SS}`) - setShowTime((e) => ({...e, DD, HH, MM, SS})) + } + useEffect(() => { + return () => { + clearInterval(timeObj.current) } - return { - showTime, - onStart, - timeStatus + }, []) + const count_down = () => { + var startData = dayjs() + var endDate = dayjs(endTime.current) + setTimeStatus(() => 1) + if (startData >= endDate) { + clearInterval(timeObj.current) + setShowTime((e) => ({ ...e, DD: '00', HH: '00', MM: '00', SS: '00' })) + setTimeStatus(() => 2) + return false } + var _dd = endDate.diff(startData, 'day') + var _hh = endDate.diff(startData, 'hour') + var _mm = endDate.diff(startData, 'minute') + var _ss = endDate.diff(startData, 'second') + // 转换 + var hh = _hh - _dd * 24 + var mm = _mm - _hh * 60 + var ss = _ss - _mm * 60 + // 格式化 + var DD = ('00' + _dd).slice(-2) + var HH = ('00' + hh).slice(-2) + var MM = ('00' + mm).slice(-2) + var SS = ('00' + ss).slice(-2) + console.log('endTime::', `${DD}-${HH}-${MM}-${SS}`) + setShowTime((e) => ({ ...e, DD, HH, MM, SS })) + } + return { + showTime, + onStart, + timeStatus, + } } - //订阅消息hook export const UseSubscriptionMessage = () => { - const {fetchData: fetchDataMessage} = SubscriptionMessageApi() - const openSubscriptionMessage = ({orderId = 0, scenes = 0}:{orderId?: number, scenes: number}) => { - return new Promise(async (resolve) => { - let params:{sale_order_id?: number, scenes?: number} = {} - orderId&&(params.sale_order_id = orderId) - params.scenes = scenes - let res = await fetchDataMessage(params) - if(res.success&&res.data.TemplateID&&res.data.TemplateID.length > 0) { - Taro.requestSubscribeMessage({ - tmplIds: res.data.TemplateID, - complete: function (res) { - resolve(res) - } - }) - } else { - resolve(true) - } + const { fetchData: fetchDataMessage } = SubscriptionMessageApi() + const openSubscriptionMessage = ({ orderId = 0, scenes = 0 }: { orderId?: number; scenes: number }) => { + return new Promise(async (resolve) => { + let params: { sale_order_id?: number; scenes?: number } = {} + orderId && (params.sale_order_id = orderId) + params.scenes = scenes + let res = await fetchDataMessage(params) + if (res.success && res.data.TemplateID && res.data.TemplateID.length > 0) { + Taro.requestSubscribeMessage({ + tmplIds: res.data.TemplateID, + complete: function (res) { + resolve(res) + }, }) - } + } else { + resolve(true) + } + }) + } - return { - openSubscriptionMessage - } - + return { + openSubscriptionMessage, + } } diff --git a/src/use/useCommonData.ts b/src/use/useCommonData.ts index a2b00d2..8af7ef9 100644 --- a/src/use/useCommonData.ts +++ b/src/use/useCommonData.ts @@ -1,33 +1,33 @@ import { useDispatch } from 'react-redux' -import {SET_SHOPCOUNT, CLEAR_SHOPCOUNT} from '@/constants/common' -import {DataParam} from '@/reducers/commonData' +import { SET_SHOPCOUNT, CLEAR_SHOPCOUNT } from '@/constants/common' +import { DataParam } from '@/reducers/commonData' import { useCallback, useState } from 'react' import { GetShoppingCartApi } from '@/api/shopCart' import { useSelector } from '@/reducers/hooks' export default () => { - const commonData = useSelector(state => state.commonData) - const dispatch = useDispatch() - - const setShopCount = (shopCount: number) => { - dispatch({type:SET_SHOPCOUNT, data:{shopCount}}) - } + const commonData = useSelector((state) => state.commonData) + const dispatch = useDispatch() - const removeShopCount = () => { - dispatch({type:CLEAR_SHOPCOUNT}) - } + const setShopCount = (shopCount: number) => { + dispatch({ type: SET_SHOPCOUNT, data: { shopCount } }) + } - const {fetchData: fetchDataShopCount} = GetShoppingCartApi() - const getShopCount = async () => { - //获取购物车数据数量 - const {data} = await fetchDataShopCount() - let color_list = data.color_list||[] - setShopCount(color_list.length) - } - - return { - setShopCount, - removeShopCount, - getShopCount, - commonData - } -} \ No newline at end of file + const removeShopCount = () => { + dispatch({ type: CLEAR_SHOPCOUNT }) + } + + const { fetchData: fetchDataShopCount } = GetShoppingCartApi() + const getShopCount = async () => { + //获取购物车数据数量 + const { data } = await fetchDataShopCount() + let color_list = data.color_list || [] + setShopCount(color_list.length) + } + + return { + setShopCount, + removeShopCount, + getShopCount, + commonData, + } +} diff --git a/src/use/useHttp.ts b/src/use/useHttp.ts index 314c0b6..89ca698 100644 --- a/src/use/useHttp.ts +++ b/src/use/useHttp.ts @@ -1,100 +1,98 @@ - - import Taro, { useRouter } from '@tarojs/taro' import { useEffect, useRef, useState } from 'react' -import {BASE_URL, WX_APPID} from '@/common/constant' -import useUserInfo from "./useUserInfo" -import qs from 'qs'; -import useLogin from './useLogin'; -import useLoginRequest from './useLoginRequest'; - +import { BASE_URL, WX_APPID } from '@/common/constant' +import useUserInfo from './useUserInfo' +import qs from 'qs' +import useLogin from './useLogin' +import useLoginRequest from './useLoginRequest' type Params = { - code: string|null - success: true|false - data: any, - msg: string, - loading: true|false, - error: any, - query: any, - filter: any, - sort: any, - total: number, - multiple: true|false, // 请求多次 - count: number, // 第几次请求 - token: string, // token - page?: number, - pageSize?: number + code: string | null + success: true | false + data: any + msg: string + loading: true | false + error: any + query: any + filter: any + sort: any + total: number + multiple: true | false // 请求多次 + count: number // 第几次请求 + token: string // token + page?: number + pageSize?: number } type option = { - url?: string, - method?: 'get'|'post'|'put'|'delete', - type?: string, - data?: any, - page?: number, - pageSize?: number, - pagination?: true|false, - base_url?: string, - apiMsgStatus?: true|false + url?: string + method?: 'get' | 'post' | 'put' | 'delete' + type?: string + data?: any + page?: number + pageSize?: number + pagination?: true | false + base_url?: string + apiMsgStatus?: true | false } /** * 返回状态信息,根据 http 状态错 - * @param {Number} status - * @returns + * @param {Number} status + * @returns */ const showStatus = (status) => { - let message = '' - switch (status) { + let message = '' + switch (status) { case 400: - message = '请求错误(400)' - break + message = '请求错误(400)' + break case 401: - message = '未授权,请重新登录(401)' - break + message = '未授权,请重新登录(401)' + break case 403: - message = '拒绝访问(403)' - break + message = '拒绝访问(403)' + break case 404: - message = '请求出错(404)' - break + message = '请求出错(404)' + break case 408: - message = '请求超时(408)' - break + message = '请求超时(408)' + break case 500: - message = '服务器错误(500)' - break + message = '服务器错误(500)' + break case 501: - message = '服务未实现(501)' - break + message = '服务未实现(501)' + break case 502: - message = '网络错误(502)' - break + message = '网络错误(502)' + break case 503: - message = '服务不可用(503)' - break + message = '服务不可用(503)' + break case 504: - message = '网络超时(504)' - break + message = '网络超时(504)' + break case 505: - message = 'HTTP版本不受支持(505)' - break + message = 'HTTP版本不受支持(505)' + break default: - message = `连接出错(${status})!` - } - return `${message},请检查网络或联系管理员!` + message = `连接出错(${status})!` + } + return `${message},请检查网络或联系管理员!` } -/** - * axios 请求状态封装,返回响应式数据 fetch(), loading, error, code, msg 等常用方法/状态 - * @param {Object} options 对象 - * @param {String} options.url 请求的URL - * @param {String} options.method 请求的方法 - * @param {Object} options.data 请求的参数 - * @returns {Object} 返回fetch(), loading, error, code, msg +/** + * axios 请求状态封装,返回响应式数据 fetch(), loading, error, code, msg 等常用方法/状态 + * @param {Object} options 对象 + * @param {String} options.url 请求的URL + * @param {String} options.method 请求的方法 + * @param {Object} options.data 请求的参数 + * @returns {Object} 返回fetch(), loading, error, code, msg */ -export const useRequest = (options:option = { +export const useRequest = ( + options: option = { url: '/', method: 'get', type: 'json', @@ -103,112 +101,107 @@ export const useRequest = (options:option = { pageSize: 24, pagination: false, // 是否分页 base_url: '', - apiMsgStatus: true //是否直接弹出后端错误 -}) => { - - options.url = `${options.base_url||BASE_URL}${options.url}` - let params:Params = { - code: null, // 业务码 - success: false, // 请求是否成功 - data: {}, - msg: '', - loading: false, - error: null, - query: {}, - filter: null, - sort: '', - total: 0, - multiple: true, // 请求多次 - count: 0, // 第几次请求 - token: '', // token - } + apiMsgStatus: true, //是否直接弹出后端错误 + }, +) => { + options.url = `${options.base_url || BASE_URL}${options.url}` + let params: Params = { + code: null, // 业务码 + success: false, // 请求是否成功 + data: {}, + msg: '', + loading: false, + error: null, + query: {}, + filter: null, + sort: '', + total: 0, + multiple: true, // 请求多次 + count: 0, // 第几次请求 + token: '', // token + } - const stateRef = useRef({...params}) - const [state, setState] = useState({...stateRef.current}) - const {removeToken, removeSessionKey, removeUserInfo} = useUserInfo() - const {login} = useLoginRequest() - - // 请求函数 - const fetchData = async (sub_options?:any) => { - stateRef.current.loading = true - setState((e) => ({...e, loading:true})) - stateRef.current.query = { - ...sub_options, - ...options.pagination && { - page: stateRef.current.page, - size: stateRef.current.pageSize, - }, - ...stateRef.current.filter, - ...stateRef.current.sort - } - try { - let token = Taro.getStorageSync('token') - const q = { - ...options, - ...{ - header: { - "Platform": 6, - "Appid": WX_APPID, - "Authorization": token || stateRef.current.token, - } - }, - ...options.method?.toUpperCase() == 'GET' ? { - data: stateRef.current.query - } : { - data: options.type?.toUpperCase() == 'FORMDATA' ? qs.stringify(stateRef.current.query) : stateRef.current.query - } + const stateRef = useRef({ ...params }) + const [state, setState] = useState({ ...stateRef.current }) + const { removeToken, removeSessionKey, removeUserInfo } = useUserInfo() + const { login } = useLoginRequest() + + // 请求函数 + const fetchData = async (sub_options?: any) => { + stateRef.current.loading = true + setState((e) => ({ ...e, loading: true })) + stateRef.current.query = { + ...sub_options, + ...(options.pagination && { + page: stateRef.current.page, + size: stateRef.current.pageSize, + }), + ...stateRef.current.filter, + ...stateRef.current.sort, + } + try { + let token = Taro.getStorageSync('token') + const q = { + ...options, + ...{ + header: { + Platform: 6, + Appid: WX_APPID, + Authorization: token || stateRef.current.token, + }, + }, + ...(options.method?.toUpperCase() == 'GET' + ? { + data: stateRef.current.query, } - const result = await Taro.request(q as any) - const { statusCode } = result - const { - code, - msg, - data - } = result.data - if (statusCode === 200) { - stateRef.current.success = (code === 0 ? true : false) - stateRef.current.code = code - stateRef.current.msg = msg - stateRef.current.data = data - stateRef.current.total = data?.list ? data?.total : 0 - if(code !== 0) { - options.apiMsgStatus !== false &&Taro.showToast({ - title: `${msg}`, - icon: 'none' - }) - console.log('错误::',msg) - } - }else{ - - if (statusCode === 401) { - removeToken() - removeSessionKey() - removeUserInfo() - login() - } else { - Taro.showToast({ - title: `错误:${showStatus(statusCode)}`, - icon: 'none' - }) - } - } - - } catch (e) { - stateRef.current.success = false - stateRef.current.error = true - stateRef.current.msg = e.errMsg - console.log('后台错误信息::',e.errMsg) - + : { + data: options.type?.toUpperCase() == 'FORMDATA' ? qs.stringify(stateRef.current.query) : stateRef.current.query, + }), + } + const result = await Taro.request(q as any) + const { statusCode } = result + const { code, msg, data } = result.data + if (statusCode === 200) { + stateRef.current.success = code === 0 ? true : false + stateRef.current.code = code + stateRef.current.msg = msg + stateRef.current.data = data + stateRef.current.total = data?.list ? data?.total : 0 + if (code !== 0) { + options.apiMsgStatus !== false && + Taro.showToast({ + title: `${msg}`, + icon: 'none', + }) + console.log('错误::', msg) } - stateRef.current.error = false - stateRef.current.loading = false - setState(() => ({...stateRef.current})) - return stateRef.current + } else { + if (statusCode === 401) { + removeToken() + removeSessionKey() + removeUserInfo() + login() + } else { + Taro.showToast({ + title: `错误:${showStatus(statusCode)}`, + icon: 'none', + }) + } + } + } catch (e) { + stateRef.current.success = false + stateRef.current.error = true + stateRef.current.msg = e.errMsg + console.log('后台错误信息::', e.errMsg) } + stateRef.current.error = false + stateRef.current.loading = false + setState(() => ({ ...stateRef.current })) + return stateRef.current + } - return { - fetchData, - state, - } - -} \ No newline at end of file + return { + fetchData, + state, + } +} diff --git a/src/use/useLogin.ts b/src/use/useLogin.ts index 7839e7a..c839260 100644 --- a/src/use/useLogin.ts +++ b/src/use/useLogin.ts @@ -1,137 +1,134 @@ -import useUserInfo from "./useUserInfo" -import Taro, { useDidShow, useRouter } from "@tarojs/taro" -import { GetWxUserInfoApi, GetAdminUserInfoApi, GetPhoneNumberApi, BindingCompanyApi } from "@/api/user" -import useLoginRequest from "./useLoginRequest" -import { SHARE_SCENE } from "@/common/enum" -import { GetShortCodeApi } from "@/api/share" -import { alert } from "@/common/common" -import { LoginApi } from "@/api/login" -import { IMG_CND_Prefix } from "@/common/constant" +import useUserInfo from './useUserInfo' +import Taro, { useDidShow, useRouter } from '@tarojs/taro' +import { GetWxUserInfoApi, GetAdminUserInfoApi, GetPhoneNumberApi, BindingCompanyApi } from '@/api/user' +import useLoginRequest from './useLoginRequest' +import { SHARE_SCENE } from '@/common/enum' +import { GetShortCodeApi } from '@/api/share' +import { alert } from '@/common/common' +import { LoginApi } from '@/api/login' +import { IMG_CND_Prefix } from '@/common/constant' export default () => { - const {setUserInfo, setAdminUserInfo, setSortCode, userInfo} = useUserInfo() + const { setUserInfo, setAdminUserInfo, setSortCode, userInfo } = useUserInfo() - useDidShow(() => { - checkLogin() + useDidShow(() => { + checkLogin() + }) + + //登录请求 + const { login } = useLoginRequest() + // const {fetchData:login} = LoginApi() + const wxLogin = async () => { + try { + await login() + getAdminUserInfo() + } catch (e) { + console.log('登录失败::', e) + } + } + + //获取用户信息 + const { fetchData: useFetchData } = GetAdminUserInfoApi() + const getAdminUserInfo = async () => { + let res = await useFetchData() + setAdminUserInfo({ ...res.data }) + getShortCode(res.data.user_id) + } + + //登录加checkLogin检查 + const checkLogin = () => { + return new Promise(async (reslove) => { + if (!userInfo.token) { + await wxLogin() + reslove(true) + } else { + //这个东西不要打开,checkSession有调用频率问题 + // Taro.checkSession({ + // success: async () => { + // reslove(true) + // if(!userInfo.adminUserInfo) getAdminUserInfo() + // }, + // fail: async () => { + // await wxLogin() + // reslove(true) + // } + // }) + } }) + } - //登录请求 - const {login} = useLoginRequest() - // const {fetchData:login} = LoginApi() - const wxLogin = async () => { - try { - await login() + //获取用户头像等信息数据 + const { fetchData: fetchDataUserInfo } = GetWxUserInfoApi() + const getSelfUserInfo = async () => { + return new Promise((reslove, reject) => { + if (userInfo.adminUserInfo?.is_authorize_name) { + reslove(true) + return true + } + Taro.getUserProfile({ + desc: '用于完善会员资料', + success: async (res) => { + if (!userInfo.session_key) { + await wxLogin() + } + const user_res = await fetchDataUserInfo({ + session_key: userInfo.session_key, + raw_data: res.rawData, + signature: res.signature, + encrypted_data: res.encryptedData, + iv: res.iv, + }) + if (user_res.success) { + setUserInfo({ ...user_res.data }) getAdminUserInfo() - } catch(e) { - console.log('登录失败::',e) - } - } + reslove(true) + } else { + reject(user_res.msg) + } + }, + fail: (e) => { + console.log('授权失败::', e) + reject(e.errMsg) + }, + }) + }) + } - //获取用户信息 - const {fetchData: useFetchData} = GetAdminUserInfoApi() - const getAdminUserInfo = async () => { - let res = await useFetchData() - setAdminUserInfo({...res.data}) - getShortCode(res.data.user_id) - } - - //登录加checkLogin检查 - const checkLogin = () => { - return new Promise( async (reslove) => { - if(!userInfo.token) { - await wxLogin() - reslove(true) - } else { - //这个东西不要打开,checkSession有调用频率问题 - // Taro.checkSession({ - // success: async () => { - // reslove(true) - // if(!userInfo.adminUserInfo) getAdminUserInfo() - // }, - // fail: async () => { - // await wxLogin() - // reslove(true) - // } - // }) - } - }) - } + //获取手机号码 + const { fetchData: fetchDataUserPhone } = GetPhoneNumberApi() + const { fetchData: fetchBindingCompany } = BindingCompanyApi() + const getPhoneNumber = (code) => { + return new Promise(async (reslove, reject) => { + if (userInfo.adminUserInfo?.is_authorize_phone) { + reslove(true) + return true + } + const res = await fetchDataUserPhone({ code }) + if (res.success) { + setUserInfo({ ...userInfo.userInfo, phone: res.data.phone_number }) + await fetchBindingCompany() + getAdminUserInfo() + reslove(res.data) + } else { + reject(res.msg) + } + }) + } - //获取用户头像等信息数据 - const {fetchData: fetchDataUserInfo} = GetWxUserInfoApi() - const getSelfUserInfo = async () => { - return new Promise((reslove, reject) => { - if(userInfo.adminUserInfo?.is_authorize_name) { - reslove(true) - return true - } - Taro.getUserProfile({ - desc: '用于完善会员资料', - success: async (res) => { - if(!userInfo.session_key) { - await wxLogin() - } - const user_res = await fetchDataUserInfo({ - session_key: userInfo.session_key, - raw_data: res.rawData, - signature: res.signature, - encrypted_data: res.encryptedData, - iv: res.iv - }) - if(user_res.success) { - setUserInfo({...user_res.data}) - getAdminUserInfo() - reslove(true) - } else { - reject(user_res.msg) - } - }, - fail:(e) => { - console.log('授权失败::',e) - reject(e.errMsg) - } - }) - }) - - - } + //获取分享码(右上角分享码) + const { SharePage } = SHARE_SCENE + const { fetchData: fetchDataShortCode } = GetShortCodeApi() + const getShortCode = async (user_id) => { + const { data: resPage } = await fetchDataShortCode({ share_user_id: user_id, type: SharePage.value }) + setSortCode({ ...userInfo.sort_code, shareShortPage: { title: '打造面料爆品 专注客户服务', code: resPage.md5_key, img: IMG_CND_Prefix + '/mall/share_img_01.png' } }) + } - //获取手机号码 - const {fetchData: fetchDataUserPhone} = GetPhoneNumberApi() - const {fetchData: fetchBindingCompany} = BindingCompanyApi() - const getPhoneNumber = (code) => { - return new Promise( async (reslove, reject) => { - if(userInfo.adminUserInfo?.is_authorize_phone) { - reslove(true) - return true - } - const res = await fetchDataUserPhone({code}) - if(res.success) { - setUserInfo({...userInfo.userInfo, phone:res.data.phone_number}) - await fetchBindingCompany() - getAdminUserInfo() - reslove(res.data) - } else { - reject(res.msg) - } - - }) - } - - //获取分享码(右上角分享码) - const {SharePage} = SHARE_SCENE - const {fetchData: fetchDataShortCode} = GetShortCodeApi() - const getShortCode = async (user_id) => { - const {data: resPage} = await fetchDataShortCode({"share_user_id": user_id, type:SharePage.value}) - setSortCode({...userInfo.sort_code, shareShortPage: {title: '打造面料爆品 专注客户服务', code: resPage.md5_key, img:IMG_CND_Prefix + '/mall/share_img_01.png'}}) - } - - return { - checkLogin, - wxLogin, - getSelfUserInfo, - getPhoneNumber, - userInfo, - getAdminUserInfo - } + return { + checkLogin, + wxLogin, + getSelfUserInfo, + getPhoneNumber, + userInfo, + getAdminUserInfo, + } } diff --git a/src/use/useUploadImage.ts b/src/use/useUploadImage.ts index 5c05e3c..07599ce 100644 --- a/src/use/useUploadImage.ts +++ b/src/use/useUploadImage.ts @@ -1,165 +1,155 @@ -import Taro from '@tarojs/taro'; -import {UPLOAD_CDN_URL } from '@/common/constant' +import Taro from '@tarojs/taro' +import { UPLOAD_CDN_URL } from '@/common/constant' import { GetSignApi } from '@/api/cdn' - - export default () => { + const { fetchData: GetSign, state } = GetSignApi() - const { fetchData: GetSign, state} = GetSignApi() - - // 上传图片 获取auth,Policy - /* + // 上传图片 获取auth,Policy + /* scene 场景值,区分上传文件的根路径 type 类型值,区分上传业务bucket */ - const getSecret = (scene, type) => { - return new Promise(async (resolve, reject) => { + const getSecret = (scene, type) => { + return new Promise(async (resolve, reject) => { + const SAVE_PATH = `/${scene}/{filemd5}{day}{hour}{min}{sec}{.suffix}` - const SAVE_PATH = `/${scene}/{filemd5}{day}{hour}{min}{sec}{.suffix}`; + let params = { + method: 'post', + save_key: SAVE_PATH, + } + // 获取签名 + let res = await GetSign(params) + if (res.success) { + resolve(res.data) + } else { + reject({ + code: res.code || '9999', + msg: res.msg, + }) + } + }) + } + const getFileType = (name) => { + if (!name) return false + var imgType = ['gif', 'jpeg', 'jpg', 'bmp', 'png'] + var videoType = ['avi', 'wmv', 'mkv', 'mp4', 'mov', 'rm', '3gp', 'flv', 'mpg', 'rmvb', 'quicktime'] - let params = { - 'method': 'post', - 'save_key': SAVE_PATH - } - // 获取签名 - let res = await GetSign(params) - if (res.success) { - resolve(res.data) + if (RegExp('.?(' + imgType.join('|') + ')$', 'i').test(name.toLowerCase())) { + return 'image' + } else if (RegExp('.(' + videoType.join('|') + ')$', 'i').test(name.toLowerCase())) { + return 'video' + } else { + return false + } + } + + /** + * + * @param {*} file 传入文件 + * @param {String} secene 传入 'product' + * @param {String} type 传入 'product' + * @returns + */ + const uploadCDNImg = (file, secene, type) => { + let filetype = file.path + console.log('filetype::', filetype) + if (!getFileType(filetype)) { + Taro.showToast({ + title: '上传文件类型错误', + icon: 'none', + duration: 3800, + }) + return false + } + + return new Promise((resolve, reject) => { + getSecret(secene, type) + .then((result) => { + let res: any = result + console.log('bucket', res.bucket) + var formdata = { + authorization: res.authorization, + policy: res.policy, + } + + const uploadTask = Taro.uploadFile({ + url: `${UPLOAD_CDN_URL}${res.bucket}`, + formData: formdata, + filePath: file.path, + name: 'file', + success: (res) => { + resolve(JSON.parse(`${res.data}`)) + }, + fail: (err) => { + console.log(err) + reject(err) + }, + }) + + uploadTask.progress((res) => { + console.log('上传进度', res.progress) + if (res.progress < 100) { + Taro.showLoading({ + title: '上传中...', + }) } else { - reject({ - code: res.code || '9999', - msg: res.msg - }); + Taro.hideLoading() } - + }) }) - } - const getFileType = (name) => { - if (!name) return false; - var imgType = ["gif", "jpeg", "jpg", "bmp", "png"]; - var videoType = ["avi", "wmv", "mkv", "mp4", "mov", "rm", "3gp", "flv", "mpg", "rmvb", "quicktime"]; - - if (RegExp("\.?(" + imgType.join("|") + ")$", "i").test(name.toLowerCase())) { - return 'image'; - } else if (RegExp("\.(" + videoType.join("|") + ")$", "i").test(name.toLowerCase())) { - return 'video'; - } else { - return false; - } - } - - /** - * - * @param {*} file 传入文件 - * @param {String} secene 传入 'product' - * @param {String} type 传入 'product' - * @returns - */ - const uploadCDNImg = (file, secene, type) => { - let filetype = file.path - console.log('filetype::',filetype) - if (!getFileType(filetype)) { - Taro.showToast({ - title: "上传文件类型错误", - icon: "none", - duration: 3800 - }) - return false - } - - return new Promise((resolve, reject) => { - getSecret(secene, type) - .then(result => { - let res:any = result - console.log('bucket', res.bucket); - var formdata = { - 'authorization': res.authorization, - 'policy': res.policy, - } - - const uploadTask = Taro.uploadFile({ - url: `${UPLOAD_CDN_URL}${res.bucket}`, - formData: formdata, - filePath: file.path, - name: 'file', - success: res => { - resolve(JSON.parse(`${res.data}`)) - }, - fail: err => { - console.log(err) - reject(err) - } - }) - - uploadTask.progress(res => { - console.log('上传进度', res.progress); - if (res.progress < 100) { - Taro.showLoading({ - title: '上传中...' - }) - } else { - Taro.hideLoading() - } - }) - }) - .catch(result => { - reject(result) - Taro.showToast({ - title: "获取密钥失败!", - icon: "none", - duration: 3800 - }) - }) + .catch((result) => { + reject(result) + Taro.showToast({ + title: '获取密钥失败!', + icon: 'none', + duration: 3800, + }) }) - } + }) + } - - // product 产品相关,图片、纹理图等 全平台 - // after-sale 售后(申请退货、退款)相关的、图片、视频 全平台 - // mall 电子商城相关的 全平台 - // logistics 物流(发货、提货)相关的、图片、视频 全平台 - type cdn_upload_type_Param = 'product'|'after-sale'|'mall'|'logistics' - /** - * 上传手机图片 - * @param cdn_upload_type 场景值 - * @param count // 1时返回一张图片信息, 大于1时返回图片数组 - * @returns - */ - const getWxPhoto = (cdn_upload_type: cdn_upload_type_Param, count: number = 1) => { - return new Promise((resolve, reject) => { - let list:any[] = [] - Taro.chooseImage({ - count: count, - sizeType: ['original', 'compressed'], - sourceType: ['album', 'camera'], - success: async function (res) { - try { - if(count > 1) { - for(let i = 0; i < res.tempFiles.length; i++) { - let data = await uploadCDNImg(res.tempFiles[i], cdn_upload_type, cdn_upload_type) - list.push(data) - } - resolve(list) - } else { - //兼容以前上传一张的情况 - let data = await uploadCDNImg(res.tempFiles[0], cdn_upload_type, cdn_upload_type) - resolve(data) - } - - } catch(res) { - reject(res) - } - - } - }) - }) - - } - - return { - uploadCDNImg, - getWxPhoto - } + // product 产品相关,图片、纹理图等 全平台 + // after-sale 售后(申请退货、退款)相关的、图片、视频 全平台 + // mall 电子商城相关的 全平台 + // logistics 物流(发货、提货)相关的、图片、视频 全平台 + type cdn_upload_type_Param = 'product' | 'after-sale' | 'mall' | 'logistics' + /** + * 上传手机图片 + * @param cdn_upload_type 场景值 + * @param count // 1时返回一张图片信息, 大于1时返回图片数组 + * @returns + */ + const getWxPhoto = (cdn_upload_type: cdn_upload_type_Param, count: number = 1) => { + return new Promise((resolve, reject) => { + let list: any[] = [] + Taro.chooseImage({ + count: count, + sizeType: ['original', 'compressed'], + sourceType: ['album', 'camera'], + success: async function (res) { + try { + if (count > 1) { + for (let i = 0; i < res.tempFiles.length; i++) { + let data = await uploadCDNImg(res.tempFiles[i], cdn_upload_type, cdn_upload_type) + list.push(data) + } + resolve(list) + } else { + //兼容以前上传一张的情况 + let data = await uploadCDNImg(res.tempFiles[0], cdn_upload_type, cdn_upload_type) + resolve(data) + } + } catch (res) { + reject(res) + } + }, + }) + }) + } + return { + uploadCDNImg, + getWxPhoto, + } } diff --git a/src/use/useUserInfo.ts b/src/use/useUserInfo.ts index 025bef6..e081bf2 100644 --- a/src/use/useUserInfo.ts +++ b/src/use/useUserInfo.ts @@ -1,51 +1,51 @@ import { useDispatch, useSelector } from 'react-redux' -import { CLEAR_SESSIONKEY, SET_USERINFO, SET_TOKEN, SET_SESSIONKEY, CLEAR_USERINFO, CLEAR_TOKEN, SET_ADMINUSERINFO, SET_SORTCODE} from '@/constants/userInfo' -import {DataParam, UserParam, UserAdminParam, SortCodeParam} from '@/reducers/userInfo' +import { CLEAR_SESSIONKEY, SET_USERINFO, SET_TOKEN, SET_SESSIONKEY, CLEAR_USERINFO, CLEAR_TOKEN, SET_ADMINUSERINFO, SET_SORTCODE } from '@/constants/userInfo' +import { DataParam, UserParam, UserAdminParam, SortCodeParam } from '@/reducers/userInfo' export default () => { - const userInfo = useSelector((state:DataParam) => state.userInfo) as DataParam - const dispatch = useDispatch() - - const setToken = (token: string) => { - dispatch({type:SET_TOKEN, data:{token}}) - } + const userInfo = useSelector((state: DataParam) => state.userInfo) as DataParam + const dispatch = useDispatch() - const setSessionKey = (sessionkey: string) => { - dispatch({type:SET_SESSIONKEY, data:{session_key: sessionkey}}) - } + const setToken = (token: string) => { + dispatch({ type: SET_TOKEN, data: { token } }) + } - const setUserInfo = (userInfo: UserParam) => { - dispatch({type:SET_USERINFO, data:{userInfo}}) - } + const setSessionKey = (sessionkey: string) => { + dispatch({ type: SET_SESSIONKEY, data: { session_key: sessionkey } }) + } - const setAdminUserInfo = (adminUserInfo: UserAdminParam) => { - dispatch({type:SET_ADMINUSERINFO, data:{adminUserInfo}}) - } + const setUserInfo = (userInfo: UserParam) => { + dispatch({ type: SET_USERINFO, data: { userInfo } }) + } - const setSortCode = (sortCode:SortCodeParam) => { - dispatch({type:SET_SORTCODE, data:{sort_code:sortCode}}) - } + const setAdminUserInfo = (adminUserInfo: UserAdminParam) => { + dispatch({ type: SET_ADMINUSERINFO, data: { adminUserInfo } }) + } - const removeUserInfo = () => { - dispatch({type:CLEAR_USERINFO}) - } + const setSortCode = (sortCode: SortCodeParam) => { + dispatch({ type: SET_SORTCODE, data: { sort_code: sortCode } }) + } - const removeToken = () => { - dispatch({type:CLEAR_TOKEN}) - } + const removeUserInfo = () => { + dispatch({ type: CLEAR_USERINFO }) + } - const removeSessionKey = () => { - dispatch({type:CLEAR_SESSIONKEY}) - } + const removeToken = () => { + dispatch({ type: CLEAR_TOKEN }) + } - return { - setToken, - setUserInfo, - setAdminUserInfo, - setSessionKey, - removeUserInfo, - removeToken, - removeSessionKey, - setSortCode, - userInfo, //响应式数据返回 - } -} \ No newline at end of file + const removeSessionKey = () => { + dispatch({ type: CLEAR_SESSIONKEY }) + } + + return { + setToken, + setUserInfo, + setAdminUserInfo, + setSessionKey, + removeUserInfo, + removeToken, + removeSessionKey, + setSortCode, + userInfo, //响应式数据返回 + } +}