🌈 style(eslint): 新增eslint规则

This commit is contained in:
xuan 2022-12-02 18:59:29 +08:00
parent c3cb46a5a7
commit d49314aa5b
217 changed files with 19491 additions and 19187 deletions

View File

@ -1,12 +0,0 @@
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

7
.eslintignore Normal file
View File

@ -0,0 +1,7 @@
/node_modules
/build
/key
/dist
project.*.json
*.lock
*.log

View File

@ -1,8 +1,13 @@
{ {
"extends": ["taro/react"], "extends": ["taro/react","@aaronghx/eslint-config-react"],
"rules": { "rules": {
"react/jsx-uses-react": "off", "no-console": "off",
"react/react-in-jsx-scope": "off" "@typescript-eslint/no-shadow": "off",
}, "@typescript-eslint/no-unused-vars": "off",
"plugins": [""] "eqeqeq": "off",
"no-prototype-builtins": "off",
"import/first": "off",
"react/no-children-prop": "off",
"import/no-commonjs": "off"
}
} }

View File

@ -1,10 +0,0 @@
module.exports = {
printWidth: 160, // 每行代码最大长度
tabWidth: 2, //一个tab代表几个空格数默认为80
useTabs: false, //是否使用tab进行缩进默认为false表示用空格进行缩减
semi: false, // 声明后带分号
singleQuote: true, // 使用单引号
jsxSingleQuote: true, // 使用单引号
jsxBracketSameLine: true, // 启用jsx语法> 放在末尾
trailingComma: 'all',
}

View File

@ -4,7 +4,7 @@ module.exports = {
presets: [ presets: [
['taro', { ['taro', {
framework: 'react', framework: 'react',
ts: true ts: true,
}] }],
] ],
} }

View File

@ -1,4 +1,5 @@
const path = require('path') const path = require('path')
module.exports = { module.exports = {
env: { env: {
NODE_ENV: '"development"', NODE_ENV: '"development"',

View File

@ -1,15 +1,16 @@
const path = require('path') const path = require('path')
const childProcess = require('child_process') const childProcess = require('child_process')
const versions =
childProcess.execSync('git rev-parse --abbrev-ref HEAD', { const versions
= childProcess.execSync('git rev-parse --abbrev-ref HEAD', {
encoding: 'utf8', encoding: 'utf8',
}) != 'HEAD\n' }) != 'HEAD\n'
? childProcess.execSync('git rev-parse --abbrev-ref HEAD', { ? childProcess.execSync('git rev-parse --abbrev-ref HEAD', {
encoding: 'utf8', encoding: 'utf8',
}) })
: childProcess.execSync('git describe --tags --abbrev=0', { : childProcess.execSync('git describe --tags --abbrev=0', {
encoding: 'utf8', encoding: 'utf8',
}) })
const CURRENT_GITHASH = childProcess.execSync('git rev-parse --short HEAD', { const CURRENT_GITHASH = childProcess.execSync('git rev-parse --short HEAD', {
encoding: 'utf8', encoding: 'utf8',
}) })
@ -109,7 +110,7 @@ const config = {
// }, // },
} }
module.exports = function (merge) { module.exports = function(merge) {
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
return merge({}, config, require('./dev')) return merge({}, config, require('./dev'))
} }

View File

@ -1,4 +1,5 @@
const path = require('path') const path = require('path')
module.exports = { module.exports = {
env: { env: {
NODE_ENV: '"pre"', NODE_ENV: '"pre"',

View File

@ -1,4 +1,5 @@
const path = require('path') const path = require('path')
module.exports = { module.exports = {
env: { env: {
NODE_ENV: '"production"', NODE_ENV: '"production"',

4
global.d.ts vendored
View File

@ -1,4 +1,4 @@
/// <reference path="node_modules/@tarojs/plugin-platform-weapp/types/shims-weapp.d.ts" /> /// <reference types="@tarojs/taro" />
declare module '*.png' declare module '*.png'
declare module '*.gif' declare module '*.gif'
@ -19,4 +19,4 @@ declare namespace NodeJS {
declare const CURRENT_VERSION: string declare const CURRENT_VERSION: string
declare const CURRENT_GITHASH: string declare const CURRENT_GITHASH: string
declare const CURRENT_ENV: string declare const CURRENT_ENV: string

View File

@ -8,6 +8,7 @@
"typescript": true, "typescript": true,
"css": "sass" "css": "sass"
}, },
"author": "",
"scripts": { "scripts": {
"build:weapp": "taro build --type weapp", "build:weapp": "taro build --type weapp",
"build:swan": "taro build --type swan", "build:swan": "taro build --type swan",
@ -31,14 +32,15 @@
"dev:weapp:pre": "cross-env NODE_ENV=pre npm run build:weapp -- --watch", "dev:weapp:pre": "cross-env NODE_ENV=pre npm run build:weapp -- --watch",
"build:weapp:open": "taro build --type weapp --open", "build:weapp:open": "taro build --type weapp --open",
"build:weapp:upload": "taro build --type weapp --upload", "build:weapp:upload": "taro build --type weapp --upload",
"build:weapp:preview": "taro build --type weapp --preview" "build:weapp:preview": "taro build --type weapp --preview",
"lint": "eslint .",
"lint:fix": "eslint . --fix"
}, },
"browserslist": [ "browserslist": [
"last 3 versions", "last 3 versions",
"Android >= 4.1", "Android >= 4.1",
"ios >= 8" "ios >= 8"
], ],
"author": "",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.7.7", "@babel/runtime": "^7.7.7",
"@tarojs/components": "3.5.6", "@tarojs/components": "3.5.6",
@ -59,6 +61,7 @@
"tarojs": "^2.1.1" "tarojs": "^2.1.1"
}, },
"devDependencies": { "devDependencies": {
"@aaronghx/eslint-config-react": "^0.1.11",
"@babel/core": "^7.8.0", "@babel/core": "^7.8.0",
"@pmmmwh/react-refresh-webpack-plugin": "0.5.5", "@pmmmwh/react-refresh-webpack-plugin": "0.5.5",
"@tarojs/plugin-mini-ci": "3.5.6", "@tarojs/plugin-mini-ci": "3.5.6",
@ -67,15 +70,11 @@
"@types/qs": "^6.9.7", "@types/qs": "^6.9.7",
"@types/react": "^18.0.0", "@types/react": "^18.0.0",
"@types/webpack-env": "^1.13.6", "@types/webpack-env": "^1.13.6",
"@typescript-eslint/eslint-plugin": "^4.15.1",
"@typescript-eslint/parser": "^4.15.1",
"babel-preset-taro": "3.5.6", "babel-preset-taro": "3.5.6",
"classnames": "^2.3.2",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"eslint": "^6.8.0", "eslint": "^8.28.0",
"eslint-config-taro": "3.5.6", "eslint-config-taro": "3.5.6",
"eslint-plugin-import": "^2.12.0",
"eslint-plugin-react": "^7.8.2",
"eslint-plugin-react-hooks": "^4.2.0",
"react-refresh": "0.11.0", "react-refresh": "0.11.0",
"stylelint": "9.3.0", "stylelint": "9.3.0",
"typescript": "^4.1.0", "typescript": "^4.1.0",

View File

@ -1,12 +1,12 @@
import { useRequest } from "@/use/useHttp" import { useRequest } from '@/use/useHttp'
/** /**
* *
*/ */
export const GetAddressListApi = () => { export const GetAddressListApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/district/list`, url: '/v1/mall/district/list',
method: "get", method: 'get',
}) })
} }

View File

@ -6,7 +6,7 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const addressListApi = () => { export const addressListApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/address/list`, url: '/v1/mall/address/list',
method: 'get', method: 'get',
}) })
} }
@ -17,7 +17,7 @@ export const addressListApi = () => {
*/ */
export const addressAddApi = () => { export const addressAddApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/address`, url: '/v1/mall/address',
method: 'post', method: 'post',
}) })
} }
@ -28,7 +28,7 @@ export const addressAddApi = () => {
*/ */
export const addressDetailApi = () => { export const addressDetailApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/address`, url: '/v1/mall/address',
method: 'get', method: 'get',
}) })
} }
@ -39,7 +39,7 @@ export const addressDetailApi = () => {
*/ */
export const addressEditApi = () => { export const addressEditApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/address`, url: '/v1/mall/address',
method: 'put', method: 'put',
}) })
} }
@ -50,7 +50,7 @@ export const addressEditApi = () => {
*/ */
export const addressDeleteApi = () => { export const addressDeleteApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/address`, url: '/v1/mall/address',
method: 'delete', method: 'delete',
}) })
} }

View File

@ -6,7 +6,7 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const GetBannerList = () => { export const GetBannerList = () => {
return useRequest({ return useRequest({
url: `/v1/mall/carouselBanner/list`, url: '/v1/mall/carouselBanner/list',
method: 'get', method: 'get',
}) })
} }

View File

@ -6,7 +6,7 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const GetSignApi = () => { export const GetSignApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/cdn/token`, url: '/v1/mall/cdn/token',
method: 'get', method: 'get',
}) })
} }

View File

@ -1,34 +1,34 @@
import { useRequest } from "@/use/useHttp" import { useRequest } from '@/use/useHttp'
/** /**
* *
* @returns * @returns
*/ */
export const certificationDetailApi = () => { export const certificationDetailApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/company/authentication`, url: '/v1/mall/company/authentication',
method: "get", method: 'get',
}) })
} }
/** /**
* *
* @returns * @returns
*/ */
export const certificationSaveApi = () => { export const certificationSaveApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/company/authentication`, url: '/v1/mall/company/authentication',
method: "put", method: 'put',
}) })
} }
/** /**
* *
* @returns * @returns
*/ */
export const certificationTypeListApi = () => { export const certificationTypeListApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/enum/companyAuthenticationType`, url: '/v1/mall/enum/companyAuthenticationType',
method: "get", method: 'get',
}) })
} }

View File

@ -6,7 +6,7 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const companyDetailApi = () => { export const companyDetailApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/company/info`, url: '/v1/mall/company/info',
method: 'get', method: 'get',
}) })
} }
@ -17,7 +17,7 @@ export const companyDetailApi = () => {
*/ */
export const companyUpdateApi = () => { export const companyUpdateApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/company/info`, url: '/v1/mall/company/info',
method: 'put', method: 'put',
}) })
} }

View File

@ -6,7 +6,7 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const creditInfoApi = () => { export const creditInfoApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/credit`, url: '/v1/mall/credit',
method: 'get', method: 'get',
}) })
} }
@ -17,7 +17,7 @@ export const creditInfoApi = () => {
*/ */
export const creditListApi = () => { export const creditListApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/credit/list`, url: '/v1/mall/credit/list',
method: 'get', method: 'get',
}) })
} }

View File

@ -6,7 +6,7 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const depositInfoApi = () => { export const depositInfoApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/rechargeApplication`, url: '/v1/mall/rechargeApplication',
method: 'get', method: 'get',
}) })
} }
@ -17,7 +17,7 @@ export const depositInfoApi = () => {
*/ */
export const depositListApi = () => { export const depositListApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/rechargeApplication/list`, url: '/v1/mall/rechargeApplication/list',
method: 'get', method: 'get',
}) })
} }
@ -28,7 +28,7 @@ export const depositListApi = () => {
*/ */
export const depositDetailApi = () => { export const depositDetailApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/rechargeApplication/order`, url: '/v1/mall/rechargeApplication/order',
method: 'get', method: 'get',
}) })
} }

View File

@ -6,7 +6,7 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const FavoriteListApi = () => { export const FavoriteListApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/favorite/list`, url: '/v1/mall/favorite/list',
method: 'get', method: 'get',
}) })
} }
@ -17,7 +17,7 @@ export const FavoriteListApi = () => {
*/ */
export const CreateFavoriteApi = () => { export const CreateFavoriteApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/favorite`, url: '/v1/mall/favorite',
method: 'post', method: 'post',
}) })
} }
@ -28,7 +28,7 @@ export const CreateFavoriteApi = () => {
*/ */
export const DelFavoriteApi = () => { export const DelFavoriteApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/favorite`, url: '/v1/mall/favorite',
method: 'delete', method: 'delete',
}) })
} }
@ -39,7 +39,7 @@ export const DelFavoriteApi = () => {
*/ */
export const UpdateFavoriteApi = () => { export const UpdateFavoriteApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/favorite`, url: '/v1/mall/favorite',
method: 'put', method: 'put',
}) })
} }
@ -50,7 +50,7 @@ export const UpdateFavoriteApi = () => {
*/ */
export const AddFavoriteApi = () => { export const AddFavoriteApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/favorite/product`, url: '/v1/mall/favorite/product',
method: 'post', method: 'post',
}) })
} }
@ -61,7 +61,7 @@ export const AddFavoriteApi = () => {
*/ */
export const DelFavoriteProductApi = () => { export const DelFavoriteProductApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/favorite/product`, url: '/v1/mall/favorite/product',
method: 'delete', method: 'delete',
}) })
} }
@ -72,7 +72,7 @@ export const DelFavoriteProductApi = () => {
*/ */
export const DetailFavoriteProductApi = () => { export const DetailFavoriteProductApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/favorite`, url: '/v1/mall/favorite',
method: 'get', method: 'get',
}) })
} }
@ -83,7 +83,7 @@ export const DetailFavoriteProductApi = () => {
*/ */
export const MoveFavoriteProductApi = () => { export const MoveFavoriteProductApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/favorite/product`, url: '/v1/mall/favorite/product',
method: 'put', method: 'put',
}) })
} }

View File

@ -6,7 +6,7 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const LoginApi = () => { export const LoginApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/login`, url: '/v1/mall/login',
method: 'post', method: 'post',
}) })
} }

View File

@ -6,7 +6,7 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const GetCategoryList = () => { export const GetCategoryList = () => {
return useRequest({ return useRequest({
url: `/v1/mall/category/list`, url: '/v1/mall/category/list',
method: 'get', method: 'get',
}) })
} }
@ -17,7 +17,7 @@ export const GetCategoryList = () => {
*/ */
export const GetProductKindListApi = () => { export const GetProductKindListApi = () => {
return useRequest({ return useRequest({
url: `/v2/mall/product/kind/list`, url: '/v2/mall/product/kind/list',
method: 'get', method: 'get',
}) })
} }
@ -28,7 +28,7 @@ export const GetProductKindListApi = () => {
*/ */
export const GetProductListApi = () => { export const GetProductListApi = () => {
return useRequest({ return useRequest({
url: `/v2/mall/product/list`, url: '/v2/mall/product/list',
method: 'get', method: 'get',
}) })
} }
@ -38,7 +38,7 @@ export const GetProductListApi = () => {
*/ */
export const GetClassList = () => { export const GetClassList = () => {
return useRequest({ return useRequest({
url: `/v2/mall/product/kind/sub/list`, url: '/v2/mall/product/kind/sub/list',
method: 'get', method: 'get',
}) })
} }
@ -49,7 +49,7 @@ export const GetClassList = () => {
*/ */
export const GetProductDetailApi = () => { export const GetProductDetailApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/product`, url: '/v1/mall/product',
method: 'get', method: 'get',
}) })
} }
@ -60,7 +60,7 @@ export const GetProductDetailApi = () => {
*/ */
export const GetLabProductApi = () => { export const GetLabProductApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/product/color/absorb/match`, url: '/v1/mall/product/color/absorb/match',
method: 'get', method: 'get',
}) })
} }

View File

@ -1,12 +1,12 @@
import { useRequest } from "@/use/useHttp" import { useRequest } from '@/use/useHttp'
/** /**
* *
* @returns * @returns
*/ */
export const GetColorList = () => { export const GetColorList = () => {
return useRequest({ return useRequest({
url: `/v1/mall/product/color/list`, url: '/v1/mall/product/color/list',
method: "get", method: 'get',
}) })
} }

View File

@ -1,26 +1,26 @@
import { useRequest } from "@/use/useHttp" import { useRequest } from '@/use/useHttp'
/** /**
* *
* @returns * @returns
*/ */
export const userassets = () => { export const userassets = () => {
return useRequest({ return useRequest({
url: `/v1/mall/user/assets`, url: '/v1/mall/user/assets',
method: "get", method: 'get',
}) })
} }
//取色对比 // 取色对比
export const productabsorbcontrast = () => { export const productabsorbcontrast = () => {
return useRequest({ return useRequest({
url: `/v1/mall/product/color/absorb/contrast`, url: '/v1/mall/product/color/absorb/contrast',
method: "get", method: 'get',
}) })
} }
//订单统计 // 订单统计
export const userorderStatistics = () => { export const userorderStatistics = () => {
return useRequest({ return useRequest({
url: `/v1/mall/user/orderStatistics`, url: '/v1/mall/user/orderStatistics',
method: "get", method: 'get',
}) })
} }

View File

@ -6,13 +6,13 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const GetPayCode = () => { export const GetPayCode = () => {
return useRequest({ return useRequest({
url: `/xima-caphtml/caphtml`, url: '/xima-caphtml/caphtml',
base_url: CAP_HTML_TO_IMAGE_BASE_URL, base_url: CAP_HTML_TO_IMAGE_BASE_URL,
method: 'post', method: 'post',
}) })
} }
//本地获取二维码 // 本地获取二维码
// export const GetPayCode = () => { // export const GetPayCode = () => {
// return useRequest({ // return useRequest({
// url: `/caphtml`, // url: `/caphtml`,
@ -26,7 +26,7 @@ export const GetPayCode = () => {
*/ */
export const GetReturnPayCode = () => { export const GetReturnPayCode = () => {
return useRequest({ return useRequest({
url: `/xima-caphtml/caphtml-return`, url: '/xima-caphtml/caphtml-return',
base_url: CAP_HTML_TO_IMAGE_BASE_URL, base_url: CAP_HTML_TO_IMAGE_BASE_URL,
method: 'post', method: 'post',
}) })

View File

@ -5,7 +5,7 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const SaleOrderApi = () => { export const SaleOrderApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/saleOrder`, url: '/v1/mall/saleOrder',
method: 'post', method: 'post',
}) })
} }
@ -15,7 +15,7 @@ export const SaleOrderApi = () => {
*/ */
export const SaleOrderPreViewApi = () => { export const SaleOrderPreViewApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/saleOrder/preView`, url: '/v1/mall/saleOrder/preView',
method: 'put', method: 'put',
}) })
} }
@ -25,7 +25,7 @@ export const SaleOrderPreViewApi = () => {
*/ */
export const GetSaleOrderDetailApi = () => { export const GetSaleOrderDetailApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/saleOrder/detail`, url: '/v1/mall/saleOrder/detail',
method: 'get', method: 'get',
}) })
} }
@ -35,7 +35,7 @@ export const GetSaleOrderDetailApi = () => {
*/ */
export const EditSaleOrderRemarkApi = () => { export const EditSaleOrderRemarkApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/saleOrder/remark`, url: '/v1/mall/saleOrder/remark',
method: 'put', method: 'put',
}) })
} }
@ -45,7 +45,7 @@ export const EditSaleOrderRemarkApi = () => {
*/ */
export const EditSaleOrderAddressApi = () => { export const EditSaleOrderAddressApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/saleOrder/address`, url: '/v1/mall/saleOrder/address',
method: 'put', method: 'put',
}) })
} }
@ -55,7 +55,7 @@ export const EditSaleOrderAddressApi = () => {
*/ */
export const EditSaleOrderShipmentModeApi = () => { export const EditSaleOrderShipmentModeApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/saleOrder/shipmentMode`, url: '/v1/mall/saleOrder/shipmentMode',
method: 'put', method: 'put',
}) })
} }
@ -65,7 +65,7 @@ export const EditSaleOrderShipmentModeApi = () => {
*/ */
export const GetOrderStatusListApi = () => { export const GetOrderStatusListApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/enum/sale/order/status`, url: '/v1/mall/enum/sale/order/status',
method: 'get', method: 'get',
}) })
} }
@ -75,7 +75,7 @@ export const GetOrderStatusListApi = () => {
*/ */
export const GetOrderListApi = () => { export const GetOrderListApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/saleOrder/list`, url: '/v1/mall/saleOrder/list',
method: 'get', method: 'get',
}) })
} }
@ -85,7 +85,7 @@ export const GetOrderListApi = () => {
*/ */
export const CancelOrderApi = () => { export const CancelOrderApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/saleOrder/cancel`, url: '/v1/mall/saleOrder/cancel',
method: 'put', method: 'put',
}) })
} }
@ -95,7 +95,7 @@ export const CancelOrderApi = () => {
*/ */
export const ReceiveOrderApi = () => { export const ReceiveOrderApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/saleOrder/receive`, url: '/v1/mall/saleOrder/receive',
method: 'put', method: 'put',
}) })
} }
@ -105,7 +105,7 @@ export const ReceiveOrderApi = () => {
*/ */
export const OrderStatusListApi = () => { export const OrderStatusListApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/enum/filterSaleOrderStatus`, url: '/v1/mall/enum/filterSaleOrderStatus',
method: 'get', method: 'get',
}) })
} }

View File

@ -5,7 +5,7 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const GetOrderPayApi = () => { export const GetOrderPayApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/orderPayment/orderPaymentMethodInfo`, url: '/v1/mall/orderPayment/orderPaymentMethodInfo',
method: 'get', method: 'get',
}) })
} }
@ -15,7 +15,7 @@ export const GetOrderPayApi = () => {
*/ */
export const SubmitOrderPayApi = () => { export const SubmitOrderPayApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/orderPayment/orderPaymentSubmission`, url: '/v1/mall/orderPayment/orderPaymentSubmission',
method: 'put', method: 'put',
}) })
} }
@ -25,7 +25,7 @@ export const SubmitOrderPayApi = () => {
*/ */
export const GetPrepayOrderPayApi = () => { export const GetPrepayOrderPayApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/orderPayment/preCollectOrder/orderPaymentMethodInfo`, url: '/v1/mall/orderPayment/preCollectOrder/orderPaymentMethodInfo',
method: 'get', method: 'get',
}) })
} }
@ -35,7 +35,7 @@ export const GetPrepayOrderPayApi = () => {
*/ */
export const SubmitPrepayOrderPayApi = () => { export const SubmitPrepayOrderPayApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/orderPayment/preCollectOrder/orderPaymentSubmission`, url: '/v1/mall/orderPayment/preCollectOrder/orderPaymentSubmission',
method: 'put', method: 'put',
}) })
} }

View File

@ -1,122 +1,121 @@
import { useRequest } from "@/use/useHttp" import { useRequest } from '@/use/useHttp'
/** /**
* *
*/ */
export const GetSaleOrderListApi = () => { export const GetSaleOrderListApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/returnApplyOrder/list`, url: '/v1/mall/returnApplyOrder/list',
method: "get", method: 'get',
}) })
} }
/** /**
* *
*/ */
export const ReturnApplyOrderApi = () => { export const ReturnApplyOrderApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/returnApplyOrder`, url: '/v1/mall/returnApplyOrder',
method: "post", method: 'post',
}) })
} }
/** /**
* 退/退 * 退/退
*/ */
export const ReturnApplyOrderCancelApi = () => { export const ReturnApplyOrderCancelApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/returnApplyOrder/cancel`, url: '/v1/mall/returnApplyOrder/cancel',
method: "post", method: 'post',
}) })
} }
/** /**
* *
*/ */
export const SaleOrderOrderDetailApi = () => { export const SaleOrderOrderDetailApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/returnApplyOrder`, url: '/v1/mall/returnApplyOrder',
method: "get", method: 'get',
}) })
} }
/** /**
* *
*/ */
export const ReturnApplyLogisticsApi = () => { export const ReturnApplyLogisticsApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/returnApplyOrder/upload`, url: '/v1/mall/returnApplyOrder/upload',
method: "put", method: 'put',
}) })
} }
/** /**
* *
*/ */
export const ReturnGoodsStatusApi = () => { export const ReturnGoodsStatusApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/enum/return/goodsStatus`, url: '/v1/mall/enum/return/goodsStatus',
method: "get", method: 'get',
}) })
} }
/** /**
* 退 * 退
*/ */
export const ReturnReasonApi = () => { export const ReturnReasonApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/enum/returnOrder/returnReason`, url: '/v1/mall/enum/returnOrder/returnReason',
method: "get", method: 'get',
}) })
} }
/** /**
* 退 * 退
*/ */
export const ReturnExplainApi = () => { export const ReturnExplainApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/enum/returnExplain`, url: '/v1/mall/enum/returnExplain',
method: "get", method: 'get',
}) })
} }
/** /**
* 退 * 退
*/ */
export const ApplyRefundApi = () => { export const ApplyRefundApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/returnApplyOrder`, url: '/v1/mall/returnApplyOrder',
method: "post", method: 'post',
}) })
} }
/** /**
* *
*/ */
export const RefundOrderSatausApi = () => { export const RefundOrderSatausApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/enum/filterReturnStage`, url: '/v1/mall/enum/filterReturnStage',
method: "get", method: 'get',
}) })
} }
/** /**
* 退 * 退
*/ */
export const RefundExplainApi = () => { export const RefundExplainApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/enum/refundExplain`, url: '/v1/mall/enum/refundExplain',
method: "get", method: 'get',
}) })
} }
/** /**
* *
*/ */
export const ReturnRecordApi = () => { export const ReturnRecordApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/saleOrder/return`, url: '/v1/mall/saleOrder/return',
method: "get", method: 'get',
}) })
} }

View File

@ -1,33 +1,31 @@
import { useRequest } from "@/use/useHttp" import { useRequest } from '@/use/useHttp'
/** /**
* *
*/ */
export const GetHotSearchApi = () => { export const GetHotSearchApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/hotSearch/list`, url: '/v1/mall/hotSearch/list',
method: "get", method: 'get',
}) })
} }
/** /**
* *
*/ */
export const GetSearchHistoryApi = () => { export const GetSearchHistoryApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/searchHistory/list`, url: '/v1/mall/searchHistory/list',
method: "get", method: 'get',
}) })
} }
/** /**
* *
*/ */
export const AddSearchHistoryApi = () => { export const AddSearchHistoryApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/searchHistory`, url: '/v1/mall/searchHistory',
method: "post", method: 'post',
}) })
} }

View File

@ -1,31 +1,31 @@
import { useRequest } from "@/use/useHttp" import { useRequest } from '@/use/useHttp'
/** /**
* *
*/ */
export const GetShortCodeApi = () => { export const GetShortCodeApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/shortCode/add`, url: '/v1/mall/shortCode/add',
method: "post", method: 'post',
}) })
} }
/** /**
* *
*/ */
export const AnalysisShortCodeApi = () => { export const AnalysisShortCodeApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/shortCode`, url: '/v1/mall/shortCode',
method: "get", method: 'get',
}) })
} }
/** /**
* *
*/ */
export const BindShortCodeApi = () => { export const BindShortCodeApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/shortCode/bind`, url: '/v1/mall/shortCode/bind',
method: "post", method: 'post',
}) })
} }

View File

@ -6,7 +6,7 @@ import { useRequest } from '@/use/useHttp'
*/ */
export const GetShoppingCartApi = () => { export const GetShoppingCartApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/shoppingCart/productColor`, url: '/v1/mall/shoppingCart/productColor',
method: 'get', method: 'get',
}) })
} }
@ -17,7 +17,7 @@ export const GetShoppingCartApi = () => {
*/ */
export const AddShoppingCartApi = () => { export const AddShoppingCartApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/shoppingCart/productColor/list`, url: '/v1/mall/shoppingCart/productColor/list',
method: 'post', method: 'post',
}) })
} }
@ -28,7 +28,7 @@ export const AddShoppingCartApi = () => {
*/ */
export const DelShoppingCartApi = () => { export const DelShoppingCartApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/shoppingCart/productColor`, url: '/v1/mall/shoppingCart/productColor',
method: 'delete', method: 'delete',
}) })
} }
@ -39,7 +39,7 @@ export const DelShoppingCartApi = () => {
*/ */
export const UpdateShoppingCartApi = () => { export const UpdateShoppingCartApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/shoppingCart/productColor`, url: '/v1/mall/shoppingCart/productColor',
method: 'put', method: 'put',
}) })
} }

View File

@ -1,13 +1,12 @@
import { useRequest } from "@/use/useHttp" import { useRequest } from '@/use/useHttp'
/** /**
* *
* @returns * @returns
*/ */
export const GetSubjectList = () => { export const GetSubjectList = () => {
return useRequest({ return useRequest({
url: `/v1/mall/subject/list`, url: '/v1/mall/subject/list',
method: "get", method: 'get',
}) })
} }

View File

@ -1,110 +1,110 @@
import { useRequest } from "@/use/useHttp" import { useRequest } from '@/use/useHttp'
/** /**
* *
*/ */
export const GetWxUserInfoApi = () => { export const GetWxUserInfoApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/user/decrypt`, url: '/v1/mall/user/decrypt',
method: "post", method: 'post',
}) })
} }
/** /**
* *
*/ */
export const GetAdminUserInfoApi = () => { export const GetAdminUserInfoApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/user/info`, url: '/v1/mall/user/info',
method: "get", method: 'get',
}) })
} }
/** /**
* *
*/ */
export const GetPhoneNumberApi = () => { export const GetPhoneNumberApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/user/phoneNumber`, url: '/v1/mall/user/phoneNumber',
method: "post", method: 'post',
}) })
} }
/** /**
* *
*/ */
export const realNameUpdateApi = () => { export const realNameUpdateApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/user`, url: '/v1/mall/user',
method: "put", method: 'put',
}) })
} }
/** /**
* | * |
*/ */
export const companyTypeApi = () => { export const companyTypeApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/enum/purchaserType`, url: '/v1/mall/enum/purchaserType',
method: "get", method: 'get',
}) })
} }
/** /**
* *
*/ */
export const portraitUpdateApi = () => { export const portraitUpdateApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/user/avatar`, url: '/v1/mall/user/avatar',
method: "put", method: 'put',
}) })
} }
/** /**
* *
*/ */
export const BindingCompanyApi = () => { export const BindingCompanyApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/user/binding/company`, url: '/v1/mall/user/binding/company',
method: "put", method: 'put',
}) })
} }
/** /**
* *
*/ */
export const ApplyOrderAccessApi = () => { export const ApplyOrderAccessApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/orderAccess/apply`, url: '/v1/mall/orderAccess/apply',
method: "post", method: 'post',
}) })
} }
/** /**
* id * id
*/ */
export const SubscriptionMessageApi = () => { export const SubscriptionMessageApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/subscriptionMessage`, url: '/v1/mall/subscriptionMessage',
method: "get", method: 'get',
}) })
} }
/** /**
* *
*/ */
export const GetInvitationInfoApi = () => { export const GetInvitationInfoApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/user/invitationInfo`, url: '/v1/mall/user/invitationInfo',
method: "get", method: 'get',
}) })
} }
/** /**
* *
*/ */
export const BindInvitationInfoApi = () => { export const BindInvitationInfoApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/user/bindInvitationCode`, url: '/v1/mall/user/bindInvitationCode',
method: "post", method: 'post',
}) })
} }

View File

@ -1,56 +1,56 @@
import { useRequest } from "@/use/useHttp" import { useRequest } from '@/use/useHttp'
/** /**
* *
* @returns * @returns
*/ */
export const weightListApi = () => { export const weightListApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/title/list`, url: '/v1/mall/title/list',
method: "get", method: 'get',
}) })
} }
/** /**
* *
* @returns * @returns
*/ */
export const weightAddApi = () => { export const weightAddApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/title`, url: '/v1/mall/title',
method: "post", method: 'post',
}) })
} }
/** /**
* *
* @returns * @returns
*/ */
export const weightDetailApi = () => { export const weightDetailApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/title`, url: '/v1/mall/title',
method: "get", method: 'get',
}) })
} }
/** /**
* *
* @returns * @returns
*/ */
export const weightEditApi = () => { export const weightEditApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/title`, url: '/v1/mall/title',
method: "put", method: 'put',
}) })
} }
/** /**
* *
* @returns * @returns
*/ */
export const weightDeleteApi = () => { export const weightDeleteApi = () => {
return useRequest({ return useRequest({
url: `/v1/mall/title`, url: '/v1/mall/title',
method: "delete", method: 'delete',
}) })
} }

View File

@ -23,164 +23,164 @@ export default {
text: '我的', text: '我的',
iconPath: './styles/tabbar/my.png', iconPath: './styles/tabbar/my.png',
selectedIconPath: './styles/tabbar/my_selected.png', selectedIconPath: './styles/tabbar/my_selected.png',
} },
], ],
'color': '#707070', color: '#707070',
'selectedColor': '#2680EB', selectedColor: '#2680EB',
'backgroundColor': '#fff', backgroundColor: '#fff',
'borderStyle': 'white' borderStyle: 'white',
}, },
subPackages: [ subPackages: [
{ {
root: "pages/search", root: 'pages/search',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/classList", root: 'pages/classList',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/details", root: 'pages/details',
pages: [ pages: [
"index", 'index',
] ],
}, },
{ {
root: "pages/searchList", root: 'pages/searchList',
pages: [ pages: [
"searchList", 'searchList',
"hightSearchList", 'hightSearchList',
"search" 'search',
] ],
}, },
{ {
root: "pages/userEdit", root: 'pages/userEdit',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/addressManager", root: 'pages/addressManager',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/addressAdd", root: 'pages/addressAdd',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/company", root: 'pages/company',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/weightList", root: 'pages/weightList',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/weightListAdd", root: 'pages/weightListAdd',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/order", root: 'pages/order',
pages: [ pages: [
"index", 'index',
"comfirm", 'comfirm',
"orderList/index" 'orderList/index',
] ],
}, },
{ {
root: "pages/editOrder", root: 'pages/editOrder',
pages: [ pages: [
"index", 'index',
] ],
}, },
{ {
root: "pages/subjectList", root: 'pages/subjectList',
pages: [ pages: [
"index", 'index',
] ],
}, },
{ {
root: "pages/creditLine", root: 'pages/creditLine',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/creditUsed", root: 'pages/creditUsed',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/depositBeforehandDetail", root: 'pages/depositBeforehandDetail',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/depositBeforehand", root: 'pages/depositBeforehand',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/depositList", root: 'pages/depositList',
pages: [ pages: [
"index" 'index',
] ],
}, },
{ {
root: "pages/salesAfter", root: 'pages/salesAfter',
pages: [ pages: [
"index", 'index',
"salesAfterList/index" 'salesAfterList/index',
] ],
}, },
{ {
root: "pages/certification", root: 'pages/certification',
pages: [ pages: [
"index", 'index',
] ],
}, },
{ {
root: "pages/applyAfterSales", root: 'pages/applyAfterSales',
pages: [ pages: [
"index", 'index',
] ],
}, },
{ {
root: "pages/collection", root: 'pages/collection',
pages: [ pages: [
"index", 'index',
"collectionClass/index" 'collectionClass/index',
] ],
}, },
{ {
root: "pages/sampleComparison", root: 'pages/sampleComparison',
pages: [ pages: [
"index", 'index',
] ],
}, },
{ {
root: "pages/bindSalesman", root: 'pages/bindSalesman',
pages: [ pages: [
"index", 'index',
] ],
}, },
] ],
} }

View File

@ -1,7 +1,7 @@
import { FC } from 'react' import type { FC } from 'react'
import ContextBlueTooth from '@/use/contextBlueTooth'
import { Provider } from 'react-redux' import { Provider } from 'react-redux'
import configStore from './store' import configStore from './store'
import ContextBlueTooth from '@/use/contextBlueTooth'
import './app.scss' import './app.scss'
import Taro, { onAppShow, useDidShow } from '@tarojs/taro' import Taro, { onAppShow, useDidShow } from '@tarojs/taro'
import { shareShop } from './common/util' import { shareShop } from './common/util'
@ -12,21 +12,21 @@ const App: FC = (params) => {
withShareTicket: true, withShareTicket: true,
}) })
//分享 // 分享
shareShop() shareShop()
//检查版本更新 // 检查版本更新
onAppShow(() => { onAppShow(() => {
const updateManager = Taro.getUpdateManager() const updateManager = Taro.getUpdateManager()
updateManager.onCheckForUpdate(function (res) { updateManager.onCheckForUpdate((res) => {
// 请求完新版本信息的回调 // 请求完新版本信息的回调
console.log('版本信息:', res.hasUpdate) console.log('版本信息:', res.hasUpdate)
}) })
updateManager.onUpdateReady(function () { updateManager.onUpdateReady(() => {
Taro.showModal({ Taro.showModal({
title: '更新提示', title: '更新提示',
content: '新版本已经准备好,是否重启应用?', content: '新版本已经准备好,是否重启应用?',
success: function (res) { success(res) {
if (res.confirm) { if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启 // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate() updateManager.applyUpdate()
@ -34,7 +34,7 @@ const App: FC = (params) => {
}, },
}) })
}) })
updateManager.onUpdateFailed(function () { updateManager.onUpdateFailed(() => {
console.log('新版本更新失败') console.log('新版本更新失败')
}) })
}) })

View File

@ -1,86 +1,76 @@
module.exports = function(lab1, lab2){ module.exports = function(lab1, lab2) {
const rgb2labArray1 = lab1
var rgb2labArray1 = lab1; const rgb2labArray2 = lab2
var rgb2labArray2 = lab2;
var l1 = rgb2labArray1[0];
var a1 = rgb2labArray1[1];
var b1 = rgb2labArray1[2];
var l2 = rgb2labArray2[0];
var a2 = rgb2labArray2[1];
var b2 = rgb2labArray2[2];
var avg_lp = (l1 + l2) / 2;
var c1 = Math.sqrt(Math.pow(a1, 2) + Math.pow(b1, 2));
var c2 = Math.sqrt(Math.pow(a2, 2) + Math.pow(b2, 2));
var avg_c = (c1 + c2) / 2;
var g = (1- Math.sqrt(Math.pow(avg_c, 7) / (Math.pow(avg_c, 7) + Math.pow(25, 7)))) / 2;
var a1p = a1 * (1 + g);
var a2p = a2 * (1 + g);
var c1p = Math.sqrt(Math.pow(a1p, 2) + Math.pow(b1, 2));
var c2p = Math.sqrt(Math.pow(a2p, 2) + Math.pow(b2, 2));
var avg_cp = (c1p + c2p) / 2;
var h1p = rad2deg(Math.atan2(b1, a1p));
if(h1p < 0){
h1p = h1p + 360;
}
var h2p = rad2deg(Math.atan2(b2, a2p));
if(h2p < 0){
h2p = h2p + 360;
}
var avg_hp = Math.abs(h1p - h2p) > 180 ? (h1p + h2p + 360) / 2 : (h1p + h1p) / 2;
var t = 1 - 0.17 * Math.cos(deg2rad(avg_hp - 30)) + 0.24 * Math.cos(deg2rad(2 * avg_hp)) + 0.32 * Math.cos(deg2rad(3 * avg_hp + 6)) - 0.2 * Math.cos(deg2rad(4 * avg_hp - 63))
var delta_hp = h2p - h1p;
if(Math.abs(delta_hp) > 180){
if (h2p <= h1p) {
delta_hp += 360;
}
else {
delta_hp -= 360;
}
}
var delta_lp = l2 - l1;
var delta_cp = c2p - c1p;
delta_hp = 2 * Math.sqrt(c1p * c2p) * Math.sin(deg2rad(delta_hp) / 2);
var s_l = 1 + ((0.015 * Math.pow(avg_lp - 50, 2)) / Math.sqrt(20 + Math.pow(avg_lp - 50, 2)));
var s_c = 1 + 0.045 * avg_cp
var s_h = 1 + 0.015 * avg_cp * t;
var delta_ro = 30 * Math.exp( - (Math.pow((avg_hp - 275) / 25, 2)));
var r_c = 2 * Math.sqrt(Math.pow(avg_cp, 7) / (Math.pow(avg_cp, 7) + Math.pow(25, 7)));
var r_t = -r_c * Math.sin(2 * deg2rad(delta_ro));
var kl = 1, kc =1, kh = 1;
var delta_e = Math.sqrt(Math.pow(delta_lp / (kl * s_l), 2) + Math.pow(delta_cp / (kc * s_c), 2) + Math.pow(delta_hp / (kh * s_h), 2) + r_t * (delta_cp / (kc * s_c)) * (delta_hp / (kh * s_h))) const l1 = rgb2labArray1[0]
const a1 = rgb2labArray1[1]
const b1 = rgb2labArray1[2]
return delta_e const l2 = rgb2labArray2[0]
const a2 = rgb2labArray2[1]
const b2 = rgb2labArray2[2]
function rad2deg(rad){
const avg_lp = (l1 + l2) / 2
return 360 * rad / (2 * Math.PI); const c1 = Math.sqrt(Math.pow(a1, 2) + Math.pow(b1, 2))
} const c2 = Math.sqrt(Math.pow(a2, 2) + Math.pow(b2, 2))
function deg2rad(deg){ const avg_c = (c1 + c2) / 2
const g = (1 - Math.sqrt(Math.pow(avg_c, 7) / (Math.pow(avg_c, 7) + Math.pow(25, 7)))) / 2
return (2 * Math.PI * deg) / 360;
} const a1p = a1 * (1 + g)
const a2p = a2 * (1 + g)
const c1p = Math.sqrt(Math.pow(a1p, 2) + Math.pow(b1, 2))
const c2p = Math.sqrt(Math.pow(a2p, 2) + Math.pow(b2, 2))
const avg_cp = (c1p + c2p) / 2
let h1p = rad2deg(Math.atan2(b1, a1p))
if (h1p < 0) {
h1p = h1p + 360
}
let h2p = rad2deg(Math.atan2(b2, a2p))
if (h2p < 0) {
h2p = h2p + 360
}
const avg_hp = Math.abs(h1p - h2p) > 180 ? (h1p + h2p + 360) / 2 : (h1p + h1p) / 2
const t = 1 - 0.17 * Math.cos(deg2rad(avg_hp - 30)) + 0.24 * Math.cos(deg2rad(2 * avg_hp)) + 0.32 * Math.cos(deg2rad(3 * avg_hp + 6)) - 0.2 * Math.cos(deg2rad(4 * avg_hp - 63))
let delta_hp = h2p - h1p
if (Math.abs(delta_hp) > 180) {
if (h2p <= h1p) {
delta_hp += 360
}
else {
delta_hp -= 360
}
}
const delta_lp = l2 - l1
const delta_cp = c2p - c1p
delta_hp = 2 * Math.sqrt(c1p * c2p) * Math.sin(deg2rad(delta_hp) / 2)
const s_l = 1 + ((0.015 * Math.pow(avg_lp - 50, 2)) / Math.sqrt(20 + Math.pow(avg_lp - 50, 2)))
const s_c = 1 + 0.045 * avg_cp
const s_h = 1 + 0.015 * avg_cp * t
const delta_ro = 30 * Math.exp(-(Math.pow((avg_hp - 275) / 25, 2)))
const r_c = 2 * Math.sqrt(Math.pow(avg_cp, 7) / (Math.pow(avg_cp, 7) + Math.pow(25, 7)))
const r_t = -r_c * Math.sin(2 * deg2rad(delta_ro))
const kl = 1; const kc = 1; const kh = 1
const delta_e = Math.sqrt(Math.pow(delta_lp / (kl * s_l), 2) + Math.pow(delta_cp / (kc * s_c), 2) + Math.pow(delta_hp / (kh * s_h), 2) + r_t * (delta_cp / (kc * s_c)) * (delta_hp / (kh * s_h)))
return delta_e
function rad2deg(rad) {
return 360 * rad / (2 * Math.PI)
}
function deg2rad(deg) {
return (2 * Math.PI * deg) / 360
}
} }

View File

@ -4,10 +4,10 @@ import XyzCom from './xyz'
import ColorDiff from './colorDiff' import ColorDiff from './colorDiff'
export const toRgb = (lab) => { export const toRgb = (lab) => {
let xyz = LabCom.xyz(lab) const xyz = LabCom.xyz(lab)
return XyzCom.rgb(xyz) return XyzCom.rgb(xyz)
} }
export const Ediff = (lab1, lab2) => { export const Ediff = (lab1, lab2) => {
return ColorDiff(lab1, lab2) return ColorDiff(lab1, lab2)
} }

View File

@ -1,54 +1,54 @@
var xyz = require('./xyz'); const xyz = require('./xyz')
module.exports = { module.exports = {
name: 'lab', name: 'lab',
min: [0,-100,-100], min: [0, -100, -100],
max: [100,100,100], max: [100, 100, 100],
channel: ['lightness', 'a', 'b'], channel: ['lightness', 'a', 'b'],
alias: ['LAB', 'cielab'], alias: ['LAB', 'cielab'],
xyz: function(lab) { xyz(lab) {
var l = lab[0], const l = lab[0]
a = lab[1], const a = lab[1]
b = lab[2], const b = lab[2]
x, y, z, y2; let x; let y; let z; let y2
if (l <= 8) { if (l <= 8) {
y = (l * 100) / 903.3; y = (l * 100) / 903.3
y2 = (7.787 * (y / 100)) + (16 / 116); y2 = (7.787 * (y / 100)) + (16 / 116)
} else { }
y = 100 * Math.pow((l + 16) / 116, 3); else {
y2 = Math.pow(y / 100, 1/3); y = 100 * Math.pow((l + 16) / 116, 3)
} y2 = Math.pow(y / 100, 1 / 3)
}
x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3); x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3)
z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3); z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3)
return [x, y, z]; return [x, y, z]
} },
}; }
// extend xyz
xyz.lab = function(xyz) {
let x = xyz[0]
let y = xyz[1]
let z = xyz[2]
let l; let a; let b
//extend xyz x /= 95.047
xyz.lab = function(xyz){ y /= 100
var x = xyz[0], z /= 108.883
y = xyz[1],
z = xyz[2],
l, a, b;
x /= 95.047; x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116)
y /= 100; y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116)
z /= 108.883; z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116)
x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116); l = (116 * y) - 16
y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116); a = 500 * (x - y)
z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116); b = 200 * (y - z)
l = (116 * y) - 16; return [l, a, b]
a = 500 * (x - y); }
b = 200 * (y - z);
return [l, a, b];
};

View File

@ -1,9 +1,8 @@
module.exports = { module.exports = {
name: 'rgb', name: 'rgb',
min: [0,0,0], min: [0, 0, 0],
max: [255,255,255], max: [255, 255, 255],
channel: ['red', 'green', 'blue'], channel: ['red', 'green', 'blue'],
alias: ['RGB'] alias: ['RGB'],
}; }

View File

@ -1,13 +1,12 @@
var rgb = require('./rgb'); const rgb = require('./rgb')
var xyz = {
name: 'xyz',
min: [0,0,0],
channel: ['X','Y','Z'],
alias: ['XYZ', 'ciexyz', 'cie1931']
};
const xyz = {
name: 'xyz',
min: [0, 0, 0],
channel: ['X', 'Y', 'Z'],
alias: ['XYZ', 'ciexyz', 'cie1931'],
}
/** /**
* Whitepoint reference values with observer/illuminant * Whitepoint reference values with observer/illuminant
@ -15,57 +14,55 @@ var xyz = {
* http://en.wikipedia.org/wiki/Standard_illuminant * http://en.wikipedia.org/wiki/Standard_illuminant
*/ */
xyz.whitepoint = { xyz.whitepoint = {
//1931 2° // 1931 2°
2: { 2: {
//incadescent // incadescent
A:[109.85, 100, 35.585], A: [109.85, 100, 35.585],
// B:[], // B:[],
C: [98.074, 100, 118.232], C: [98.074, 100, 118.232],
D50: [96.422, 100, 82.521], D50: [96.422, 100, 82.521],
D55: [95.682, 100, 92.149], D55: [95.682, 100, 92.149],
//daylight // daylight
D65: [95.045592705167, 100, 108.9057750759878], D65: [95.045592705167, 100, 108.9057750759878],
D75: [94.972, 100, 122.638], D75: [94.972, 100, 122.638],
//flourescent // flourescent
// F1: [], // F1: [],
F2: [99.187, 100, 67.395], F2: [99.187, 100, 67.395],
// F3: [], // F3: [],
// F4: [], // F4: [],
// F5: [], // F5: [],
// F6:[], // F6:[],
F7: [95.044, 100, 108.755], F7: [95.044, 100, 108.755],
// F8: [], // F8: [],
// F9: [], // F9: [],
// F10: [], // F10: [],
F11: [100.966, 100, 64.370], F11: [100.966, 100, 64.370],
// F12: [], // F12: [],
E: [100,100,100] E: [100, 100, 100],
}, },
//1964 10°
10: {
//incadescent
A:[111.144, 100, 35.200],
C: [97.285, 100, 116.145],
D50: [96.720, 100, 81.427],
D55: [95.799, 100, 90.926],
//daylight
D65: [94.811, 100, 107.304],
D75: [94.416, 100, 120.641],
//flourescent
F2: [103.280, 100, 69.026],
F7: [95.792, 100, 107.687],
F11: [103.866, 100, 65.627],
E: [100,100,100]
}
};
// 1964 10°
10: {
// incadescent
A: [111.144, 100, 35.200],
C: [97.285, 100, 116.145],
D50: [96.720, 100, 81.427],
D55: [95.799, 100, 90.926],
// daylight
D65: [94.811, 100, 107.304],
D75: [94.416, 100, 120.641],
// flourescent
F2: [103.280, 100, 69.026],
F7: [95.792, 100, 107.687],
F11: [103.866, 100, 65.627],
E: [100, 100, 100],
},
}
/** /**
* Top values are the whitepoints top values, default are D65 * Top values are the whitepoints top values, default are D65
*/ */
xyz.max = xyz.whitepoint[2].D65; xyz.max = xyz.whitepoint[2].D65
/** /**
* Transform xyz to rgb * Transform xyz to rgb
@ -74,39 +71,40 @@ xyz.max = xyz.whitepoint[2].D65;
* *
* @return {Array} RGB values * @return {Array} RGB values
*/ */
xyz.rgb = function (_xyz, white) { xyz.rgb = function(_xyz, white) {
//FIXME: make sure we have to divide like this. Probably we have to replace matrix as well then // FIXME: make sure we have to divide like this. Probably we have to replace matrix as well then
white = white || xyz.whitepoint[2].E; white = white || xyz.whitepoint[2].E
var x = _xyz[0] / white[0], const x = _xyz[0] / white[0]
y = _xyz[1] / white[1], const y = _xyz[1] / white[1]
z = _xyz[2] / white[2], const z = _xyz[2] / white[2]
r, g, b; let r; let g; let b
// assume sRGB // assume sRGB
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
r = (x * 3.240969941904521) + (y * -1.537383177570093) + (z * -0.498610760293); r = (x * 3.240969941904521) + (y * -1.537383177570093) + (z * -0.498610760293)
g = (x * -0.96924363628087) + (y * 1.87596750150772) + (z * 0.041555057407175); g = (x * -0.96924363628087) + (y * 1.87596750150772) + (z * 0.041555057407175)
b = (x * 0.055630079696993) + (y * -0.20397695888897) + (z * 1.056971514242878); b = (x * 0.055630079696993) + (y * -0.20397695888897) + (z * 1.056971514242878)
r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) r = r > 0.0031308
: r = (r * 12.92); ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
: r = (r * 12.92)
g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) g = g > 0.0031308
: g = (g * 12.92); ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
: g = (g * 12.92)
b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) b = b > 0.0031308
: b = (b * 12.92); ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
: b = (b * 12.92)
r = Math.min(Math.max(0, r), 1); r = Math.min(Math.max(0, r), 1)
g = Math.min(Math.max(0, g), 1); g = Math.min(Math.max(0, g), 1)
b = Math.min(Math.max(0, b), 1); b = Math.min(Math.max(0, b), 1)
return [r * 255, g * 255, b * 255]; return [r * 255, g * 255, b * 255]
} }
/** /**
* RGB to XYZ * RGB to XYZ
* *
@ -115,24 +113,22 @@ xyz.rgb = function (_xyz, white) {
* @return {Array} XYZ channels * @return {Array} XYZ channels
*/ */
rgb.xyz = function(rgb, white) { rgb.xyz = function(rgb, white) {
var r = rgb[0] / 255, let r = rgb[0] / 255
g = rgb[1] / 255, let g = rgb[1] / 255
b = rgb[2] / 255; let b = rgb[2] / 255
// assume sRGB // assume sRGB
r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92)
g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92)
b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92)
var x = (r * 0.41239079926595) + (g * 0.35758433938387) + (b * 0.18048078840183); const x = (r * 0.41239079926595) + (g * 0.35758433938387) + (b * 0.18048078840183)
var y = (r * 0.21263900587151) + (g * 0.71516867876775) + (b * 0.072192315360733); const y = (r * 0.21263900587151) + (g * 0.71516867876775) + (b * 0.072192315360733)
var z = (r * 0.019330818715591) + (g * 0.11919477979462) + (b * 0.95053215224966); const z = (r * 0.019330818715591) + (g * 0.11919477979462) + (b * 0.95053215224966)
white = white || xyz.whitepoint[2].E; white = white || xyz.whitepoint[2].E
return [x * white[0], y * white[1], z * white[2]]; return [x * white[0], y * white[1], z * white[2]]
}; }
module.exports = xyz
module.exports = xyz;

View File

@ -1,146 +1,141 @@
import { uint32ToUint8Array, uint8ArrayToHex } from "./utils"; import { uint32ToUint8Array, uint8ArrayToHex } from './utils'
export class Command { export class Command {
// 测量序号 // 测量序号
static measureId = 1; static measureId = 1
// 命令完整响应的长度 // 命令完整响应的长度
responseSize = 0; responseSize = 0
// 命令发送的数据 // 命令发送的数据
content = new Uint8Array(0); content = new Uint8Array(0)
// 命令响应的数据 // 命令响应的数据
response = new Uint8Array(0); response = new Uint8Array(0)
// 等待响应的超时时间 // 等待响应的超时时间
timeout = 3000; timeout = 3000
// 发送的数据是否需要生成和校验值 // 发送的数据是否需要生成和校验值
needSign = true; needSign = true
/** /**
* @param {Uint8Array|ArrayBuffer|number[]} content * @param {Uint8Array|ArrayBuffer|number[]} content
* @param {number} responseSize * @param {number} responseSize
* @param {number} timeout * @param {number} timeout
* @param {boolean} needSign * @param {boolean} needSign
*/ */
constructor(content, responseSize, timeout = 3000, needSign = true) { constructor(content, responseSize, timeout = 3000, needSign = true) {
if (content instanceof Uint8Array) { if (content instanceof Uint8Array) {
this.content = content; this.content = content
} else { }
this.content = new Uint8Array(content); else {
} this.content = new Uint8Array(content)
this.responseSize = responseSize;
if (typeof timeout === 'number' && timeout >= 0) {
this.timeout = timeout;
}
this.needSign = needSign;
} }
this.responseSize = responseSize
/** if (typeof timeout === 'number' && timeout >= 0) {
this.timeout = timeout
}
this.needSign = needSign
}
/**
* 返回一个 ArrayBuffer 数组, 用于发送 * 返回一个 ArrayBuffer 数组, 用于发送
* @returns {ArrayBuffer[]} * @returns {ArrayBuffer[]}
*/ */
get data() { get data() {
if (this.content.length === 0) throw new Error('正文内容不能为空'); if (this.content.length === 0) { throw new Error('正文内容不能为空') }
const data = []; const data = []
const b = new Uint8Array(this.content.buffer); const b = new Uint8Array(this.content.buffer)
if (this.needSign) { if (this.needSign) {
b[b.length - 1] = Command.getSign(b); b[b.length - 1] = Command.getSign(b)
}
for (let i = 0; i < b.length; i += 20) {
data.push(b.slice(i, i + 20).buffer);
}
return data;
} }
for (let i = 0; i < b.length; i += 20) {
/** 是否接收完成 */ data.push(b.slice(i, i + 20).buffer)
get isComplete() {
return this.response.length >= this.responseSize;
} }
return data
}
/** 是否有效 */ /** 是否接收完成 */
get isValid() { get isComplete() {
return Command.getSign(this.response) === this.response[this.response.length - 1]; return this.response.length >= this.responseSize
} }
/** /** 是否有效 */
get isValid() {
return Command.getSign(this.response) === this.response[this.response.length - 1]
}
/**
* 填充响应数组 * 填充响应数组
* @param {ArrayBuffer} buffer * @param {ArrayBuffer} buffer
*/ */
fillResponse(buffer) { fillResponse(buffer) {
this.response = new Uint8Array([...this.response, ...(new Uint8Array(buffer))]); this.response = new Uint8Array([...this.response, ...(new Uint8Array(buffer))])
} }
/**
/**
* 获取和校验值 * 获取和校验值
* @param {ArrayBuffer|Uint8Array} buffer * @param {ArrayBuffer|Uint8Array} buffer
*/ */
static getSign(buffer) { static getSign(buffer) {
const _b = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer); const _b = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer)
let sum = 0; let sum = 0
_b.slice(0, _b.length - 1).forEach(i => sum += i); _b.slice(0, _b.length - 1).forEach(i => sum += i)
return new Uint8Array([sum])[0]; return new Uint8Array([sum])[0]
} }
// 唤醒命令 // 唤醒命令
static WakeUp = new Command([0xf0], 0, 0, false); static WakeUp = new Command([0xF0], 0, 0, false)
/** /**
* 获取测量命令 * 获取测量命令
* @param {number} mode * @param {number} mode
*/ */
static measure(mode = 0) { static measure(mode = 0) {
Command.measureId += 1; Command.measureId += 1
const measureId = uint32ToUint8Array(Command.measureId); const measureId = uint32ToUint8Array(Command.measureId)
return new Command([0xbb, 1, mode, ...measureId, 0, 0xff, 0], 10, 1500); return new Command([0xBB, 1, mode, ...measureId, 0, 0xFF, 0], 10, 1500)
} }
/** /**
* 获取测量数据 (Lab) * 获取测量数据 (Lab)
* @param {number} mode * @param {number} mode
*/ */
static getLab(mode = 0) { static getLab(mode = 0) {
return new Command([0xbb, 3, mode, 0, 0, 0, 0, 0, 0xff, 0], 20, 1500); return new Command([0xBB, 3, mode, 0, 0, 0, 0, 0, 0xFF, 0], 20, 1500)
} }
/** /**
* 获取测量数据 (RGB) * 获取测量数据 (RGB)
* @param {number} mode * @param {number} mode
*/ */
static getRGB(mode = 0) { static getRGB(mode = 0) {
return new Command([0xbb, 4, mode, 0, 0, 0, 0, 0, 0xff, 0], 20, 1500); return new Command([0xBB, 4, mode, 0, 0, 0, 0, 0, 0xFF, 0], 20, 1500)
} }
/** /**
* 获取测量的光谱数据 * 获取测量的光谱数据
* @param {number} mode * @param {number} mode
*/ */
static getSpectral(mode = 0) { static getSpectral(mode = 0) {
return new Command([0xbb, 2, 0x10 + mode, 0, 0, 0 ,0 ,0, 0xff, 0], 200, 5000); return new Command([0xBB, 2, 0x10 + mode, 0, 0, 0, 0, 0, 0xFF, 0], 200, 5000)
} }
/** /**
* 白校准 * 白校准
* @param {number} check 是否判断校准成功 1 判断 0 不判断 * @param {number} check 是否判断校准成功 1 判断 0 不判断
*/ */
static whiteCalibrate(check = 1) { static whiteCalibrate(check = 1) {
return new Command([0xbb, 0x11, check, 0, 0, 0, 0, 0, 0xff, 0], 10, 1500); return new Command([0xBB, 0x11, check, 0, 0, 0, 0, 0, 0xFF, 0], 10, 1500)
} }
/**
/**
* 黑校准 * 黑校准
* @param {number} check 是否判断校准成功 * @param {number} check 是否判断校准成功
*/ */
static blackCalibrate(check = 1) { static blackCalibrate(check = 1) {
return new Command([0xbb, 0x10, check, 0, 0, 0, 0, 0, 0xff, 0], 10, 1500); return new Command([0xBB, 0x10, check, 0, 0, 0, 0, 0, 0xFF, 0], 10, 1500)
} }
/** 获取校准状态 */
static GetCalibrationInf = new Command([0xBB, 0x1E, 0, 0, 0, 0, 0, 0, 0xFF, 0], 20, 1500)
/** 获取校准状态 */ static GetDeviceInf = new Command([0xBB, 0x12, 0x01, 0, 0, 0, 0, 0, 0xFF, 0], 200, 5000)
static GetCalibrationInf = new Command([0xbb, 0x1e, 0, 0, 0, 0, 0, 0, 0xff, 0], 20, 1500); }
static GetDeviceInf = new Command([0xbb, 0x12, 0x01, 0, 0, 0, 0, 0, 0xff, 0], 200, 5000);
}

View File

@ -1,70 +1,65 @@
/** /**
* Uint32 Uint8 数组 * Uint32 Uint8 数组
* @param {number} n * @param {number} n
*/ */
export function uint32ToUint8Array(n) { export function uint32ToUint8Array(n) {
return new Uint8Array(new Uint32Array([n]).buffer); return new Uint8Array(new Uint32Array([n]).buffer)
} }
/** /**
* Uint8 数组 Float32 * Uint8 数组 Float32
* @param {Uint8Array} raw * @param {Uint8Array} raw
*/ */
export function uint8ArrayToFloat32(raw) { export function uint8ArrayToFloat32(raw) {
return new Float32Array(raw.buffer)[0]; return new Float32Array(raw.buffer)[0]
} }
/** /**
* Uint8 数组 Uint16 * Uint8 数组 Uint16
* @param {Uint8Array} raw * @param {Uint8Array} raw
*/ */
export function uint8ArrayToUint16(raw) { export function uint8ArrayToUint16(raw) {
return new Uint16Array(raw.buffer)[0]; return new Uint16Array(raw.buffer)[0]
} }
/** /**
* Uint8 数组转 Uint32 * Uint8 数组转 Uint32
* @param {Uint8Array} raw * @param {Uint8Array} raw
* @returns * @returns
*/ */
export function uint8ArrayToUnit32(raw) { export function uint8ArrayToUnit32(raw) {
return new Uint32Array(raw.buffer)[0]; return new Uint32Array(raw.buffer)[0]
} }
/** /**
* 等待指定时长 * 等待指定时长
* @param {number} duration * @param {number} duration
*/ */
export function waitFor(duration) { export function waitFor(duration) {
return new Promise(resolve => { return new Promise((resolve) => {
setTimeout(resolve, duration); setTimeout(resolve, duration)
}); })
} }
/** /**
* uint8 数组转 hex 字符串 * uint8 数组转 hex 字符串
* @param {Uint8Array} raw * @param {Uint8Array} raw
*/ */
export function uint8ArrayToHex(raw) { export function uint8ArrayToHex(raw) {
const s = []; const s = []
raw.forEach(i => { raw.forEach((i) => {
const b = i.toString(16); const b = i.toString(16)
s.push(b.length > 1 ? b : `0${b}`); s.push(b.length > 1 ? b : `0${b}`)
}); })
return s.join(' '); return s.join(' ')
} }
// 二进制转字符串(ascii) // 二进制转字符串(ascii)
export function bufferToString(buffer) { export function bufferToString(buffer) {
let str = ""; let str = ''
for (let code of buffer) { for (const code of buffer) {
if (code === 0) break; if (code === 0) { break }
str += utf82string(code); str += utf82string(code)
} }
return str; return str
} }

View File

@ -8,7 +8,7 @@ import Qs from 'qs'
* @param type false true tabbar页面 * @param type false true tabbar页面
*/ */
type ParamLink = 'navigateTo' | 'switchTab' | 'reLaunch' | 'redirectTo' type ParamLink = 'navigateTo' | 'switchTab' | 'reLaunch' | 'redirectTo'
export const goLink = (path: string = '', params: object | null = null, way: ParamLink = 'navigateTo') => { export const goLink = (path = '', params: object | null = null, way: ParamLink = 'navigateTo') => {
if (path) { if (path) {
// let params_str = Qs_.stringify(params || {}, { encode: false }) // let params_str = Qs_.stringify(params || {}, { encode: false })
// path = params_str ? path + '?' + params_str : path // path = params_str ? path + '?' + params_str : path
@ -18,17 +18,18 @@ export const goLink = (path: string = '', params: object | null = null, way: Par
} }
const setUrlQuery = (options: { url: string; query: object | null }) => { const setUrlQuery = (options: { url: string; query: object | null }) => {
let { url, query } = options let { url, query } = options
if (!url) return '' if (!url) { return '' }
if (query) { if (query) {
let queryArr: any[] = [] const queryArr: any[] = []
for (const key in query) { for (const key in query) {
if (query.hasOwnProperty(key)) { if (query.hasOwnProperty(key)) {
queryArr.push(`${key}=${query[key]}`) queryArr.push(`${key}=${query[key]}`)
} }
} }
if (url.indexOf('?') !== -1) { if (url.includes('?')) {
url = `${url}&${queryArr.join('&')}` url = `${url}&${queryArr.join('&')}`
} else { }
else {
url = `${url}?${queryArr.join('&')}` url = `${url}?${queryArr.join('&')}`
} }
} }
@ -42,12 +43,15 @@ const setUrlQuery = (options: { url: string; query: object | null }) => {
export const isEmptyObject = (object: any) => { export const isEmptyObject = (object: any) => {
if (object == undefined || object == null || Number.isNaN(object)) { if (object == undefined || object == null || Number.isNaN(object)) {
return true return true
} else { }
else {
if (object.constructor == Object) { if (object.constructor == Object) {
return Reflect.ownKeys(object).length == 0 return Reflect.ownKeys(object).length == 0
} else if (object.constructor == Array) { }
else if (object.constructor == Array) {
return object.length == 0 return object.length == 0
} else if (object.constructor == String) { }
else if (object.constructor == String) {
return object == '' return object == ''
} }
} }
@ -56,7 +60,7 @@ export const isEmptyObject = (object: any) => {
/** /**
* *
* @param data * @param data
* @param rules = { * @param rules = {
account: [{ account: [{
message: "请输入正确的用户名", message: "请输入正确的用户名",
@ -70,25 +74,27 @@ export const isEmptyObject = (object: any) => {
// regex: /\d/ // regex: /\d/
}] }]
}; };
* @param message * @param message
* @returns * @returns
*/ */
export const retrieval = (data: any, rules?: Object, message: string = '请填写完信息') => { export const retrieval = (data: any, rules?: Object, message = '请填写完信息') => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (rules) { if (rules) {
const keys = Reflect.ownKeys(rules) const keys = Reflect.ownKeys(rules)
const result = keys.some((key: any) => { const result = keys.some((key: any) => {
for (let item of (rules as any)[key]) { for (const item of (rules as any)[key]) {
let _res = false let _res = false
if (item.validator) { if (item.validator) {
if (item.validator(data[key], item)) { if (item.validator(data[key], item)) {
_res = true _res = true
} }
} else if (item.regex) { }
else if (item.regex) {
if (!item.regex.test(data[key])) { if (!item.regex.test(data[key])) {
_res = true _res = true
} }
} else { }
else {
if (isEmptyObject(data[key])) { if (isEmptyObject(data[key])) {
_res = true _res = true
} }
@ -100,7 +106,8 @@ export const retrieval = (data: any, rules?: Object, message: string = '请填
if (result) { if (result) {
reject(message) reject(message)
} }
} else { }
else {
const keys = Reflect.ownKeys(data) const keys = Reflect.ownKeys(data)
if (keys.some((key: any) => isEmptyObject(data[key]))) { if (keys.some((key: any) => isEmptyObject(data[key]))) {
reject(message) reject(message)

View File

@ -18,27 +18,27 @@ export const BASE_URL = CURRENT_BASE_URL
// CDN // CDN
// 生成密钥 // 生成密钥
export const GET_UPLOAD_SIGN = `/upyun/getsign` // 请求签名 url export const GET_UPLOAD_SIGN = '/upyun/getsign' // 请求签名 url
export const UPLOAD_CDN_URL = `https://v0.api.upyun.com/` export const UPLOAD_CDN_URL = 'https://v0.api.upyun.com/'
// cdn // cdn
export const IMG_CND_Prefix = CURRENT_ENV.includes('production') ? 'https://cdn.zzfzyc.com' : 'https://test.cdn.zzfzyc.com' export const IMG_CND_Prefix = CURRENT_ENV.includes('production') ? 'https://cdn.zzfzyc.com' : 'https://test.cdn.zzfzyc.com'
// export const IMG_CND_Prefix = CURRENT_ENV.includes('production') ? 'https://cdn.zzfzyc.com' : 'https://cdn.zzfzyc.com' // export const IMG_CND_Prefix = CURRENT_ENV.includes('production') ? 'https://cdn.zzfzyc.com' : 'https://cdn.zzfzyc.com'
//在线支付图片baseUrl // 在线支付图片baseUrl
export const CAP_HTML_TO_IMAGE_BASE_URL = CURRENT_CAP_HTML_TO_IMAGE_BASE_URL export const CAP_HTML_TO_IMAGE_BASE_URL = CURRENT_CAP_HTML_TO_IMAGE_BASE_URL
// export const CAP_HTML_TO_IMAGE_BASE_URL = 'http://192.168.1.127:8081' // export const CAP_HTML_TO_IMAGE_BASE_URL = 'http://192.168.1.127:8081'
// 上传图片视频 // 上传图片视频
export const CDN_UPLOAD_IMG = `${UPLOAD_CDN_URL || ''}` export const CDN_UPLOAD_IMG = `${UPLOAD_CDN_URL || ''}`
//appid // appid
export const WX_APPID = 'wx68d92d7cbf0b6963' export const WX_APPID = 'wx68d92d7cbf0b6963'
//支付码单跳转链接 // 支付码单跳转链接
export const PAY_H5_CODE_URL = CURRENT_PAY_H5_CODE_URL export const PAY_H5_CODE_URL = CURRENT_PAY_H5_CODE_URL
//场景值 // 场景值
export const SCENE = { export const SCENE = {
SearchScene: 0, //商城面料搜索 SearchScene: 0, // 商城面料搜索
} }

View File

@ -1,11 +1,11 @@
//订单状态枚举 // 订单状态枚举
export const ORDER_STATUS = { export const ORDER_STATUS = {
SaleorderstatusWaitingPrePayment: { value: 10, label: '预付款' }, // 预付款 SaleorderstatusWaitingPrePayment: { value: 10, label: '预付款' }, // 预付款
SaleOrderStatusBooking: { value: 0, label: '待接单' }, // 待接单 SaleOrderStatusBooking: { value: 0, label: '待接单' }, // 待接单
SaleOrderStatusArranging: { value: 1, label: '配布中' }, // 配布中 SaleOrderStatusArranging: { value: 1, label: '配布中' }, // 配布中
SaleOrderStatusArranged: { value: 2, label: '已配布' }, // 已配布 SaleOrderStatusArranged: { value: 2, label: '已配布' }, // 已配布
SaleOrderStatusWaitingPayment: { value: 7, label: '待付款' }, // 待付款 SaleOrderStatusWaitingPayment: { value: 7, label: '待付款' }, // 待付款
SaleOrderStatusTaking: { value: 11, label: '提货中' }, //提货中 SaleOrderStatusTaking: { value: 11, label: '提货中' }, // 提货中
SaleOrderStatusWaitingDelivery: { value: 3, label: '待发货' }, // 待发货 SaleOrderStatusWaitingDelivery: { value: 3, label: '待发货' }, // 待发货
SaleOrderStatusWaitingReceipt: { value: 8, label: '待收货' }, // 待收货 SaleOrderStatusWaitingReceipt: { value: 8, label: '待收货' }, // 待收货
SaleOrderStatusAlreadyReceipt: { value: 9, label: '已收货' }, // 已收货 SaleOrderStatusAlreadyReceipt: { value: 9, label: '已收货' }, // 已收货
@ -14,7 +14,7 @@ export const ORDER_STATUS = {
SaleOrderStatusCancel: { value: 5, label: '已取消' }, // 已取消 SaleOrderStatusCancel: { value: 5, label: '已取消' }, // 已取消
} }
//售后单状态枚举 // 售后单状态枚举
export const AFTER_ORDER_STATUS = { export const AFTER_ORDER_STATUS = {
ReturnStageApplying: { value: 0, label: '申请中' }, // 申请中 ReturnStageApplying: { value: 0, label: '申请中' }, // 申请中
ReturnStageWaitCheck: { value: 1, label: '退货中' }, // 退货中 ReturnStageWaitCheck: { value: 1, label: '退货中' }, // 退货中
@ -26,7 +26,7 @@ export const AFTER_ORDER_STATUS = {
ReturnStageRejected: { value: 7, label: '已拒绝' }, // 已拒绝 ReturnStageRejected: { value: 7, label: '已拒绝' }, // 已拒绝
} }
//支付方式 // 支付方式
export const PAYMENT_METHOD = { export const PAYMENT_METHOD = {
PaymentMethodPreDeposit: { value: 2, label: '预存款' }, PaymentMethodPreDeposit: { value: 2, label: '预存款' },
PaymentMethodAccountPeriod: { value: 3, label: '账期' }, PaymentMethodAccountPeriod: { value: 3, label: '账期' },
@ -35,7 +35,7 @@ export const PAYMENT_METHOD = {
PaymentMethodCashOnDelivery: { value: 5, label: '货到付款' }, PaymentMethodCashOnDelivery: { value: 5, label: '货到付款' },
} }
//订单类型 // 订单类型
export const SALE_MODE = { export const SALE_MODE = {
SaLeModeBulk: { value: 0, label: '大货' }, SaLeModeBulk: { value: 0, label: '大货' },
SaleModeLengthCut: { value: 1, label: '剪版' }, SaleModeLengthCut: { value: 1, label: '剪版' },
@ -43,20 +43,20 @@ export const SALE_MODE = {
} }
export type saleModeType = 0 | 1 | 2 export type saleModeType = 0 | 1 | 2
//分享场景枚举 // 分享场景枚举
export const SHARE_SCENE = { export const SHARE_SCENE = {
ShareDetail: { value: 1, label: '详情分享' }, ShareDetail: { value: 1, label: '详情分享' },
SharePage: { value: 2, label: '页面分享' }, SharePage: { value: 2, label: '页面分享' },
} }
//订阅消息 // 订阅消息
export const SUBSCRIPTION_MESSAGE_SCENE = { export const SUBSCRIPTION_MESSAGE_SCENE = {
SubmitOrder: { value: 1, label: '确认下单' }, SubmitOrder: { value: 1, label: '确认下单' },
ToPay: { value: 2, label: '去付款' }, ToPay: { value: 2, label: '去付款' },
ApplyGoods: { value: 3, label: '申请退款' }, ApplyGoods: { value: 3, label: '申请退款' },
} }
//应收单退款状态枚举 // 应收单退款状态枚举
export const REFUND_STATUS = { export const REFUND_STATUS = {
ShouldCollectOrderRefundTypeUnknown: { value: 0, label: '未知退款' }, ShouldCollectOrderRefundTypeUnknown: { value: 0, label: '未知退款' },
ShouldCollectOrderRefundTypeAdvanceReceiptRefund: { value: 1, label: '预收退款' }, ShouldCollectOrderRefundTypeAdvanceReceiptRefund: { value: 1, label: '预收退款' },
@ -64,7 +64,7 @@ export const REFUND_STATUS = {
ShouldCollectOrderRefundTypeSalesRefund: { value: 3, label: '销售退款' }, ShouldCollectOrderRefundTypeSalesRefund: { value: 3, label: '销售退款' },
} }
//申请单退款状态枚举 // 申请单退款状态枚举
export const REFUND_STATUS_ORDER = { export const REFUND_STATUS_ORDER = {
ReturnApplyOrderTypeAdvanceReceiptRefund: { value: 2, label: '预收退款' }, // 预收退款 ReturnApplyOrderTypeAdvanceReceiptRefund: { value: 2, label: '预收退款' }, // 预收退款
ReturnApplyOrderTypeReturnForRefund: { value: 1, label: '退货退款' }, // 退货退款 ReturnApplyOrderTypeReturnForRefund: { value: 1, label: '退货退款' }, // 退货退款

View File

@ -20,7 +20,8 @@ export const formatRemoveHashTag = (val = '') => {
export const formatHashTag = (code = '', name = '', mode = 'both') => { export const formatHashTag = (code = '', name = '', mode = 'both') => {
if (mode == 'both') { if (mode == 'both') {
return `${formatRemoveHashTag(code)}# ${name}` return `${formatRemoveHashTag(code)}# ${name}`
} else if (mode == 'name') { }
else if (mode == 'name') {
return `${name}` return `${name}`
} }
} }
@ -40,7 +41,7 @@ export const weightDigit = 1000
* @returns * @returns
*/ */
export const formatPriceDiv = (val, digit = Digit, priceStatus = false) => { export const formatPriceDiv = (val, digit = Digit, priceStatus = false) => {
let res = strip(Number(val / digit)) || 0 const res = strip(Number(val / digit)) || 0
return priceStatus ? numberWithCommas({ number: res }) : res return priceStatus ? numberWithCommas({ number: res }) : res
} }
/** /**
@ -72,13 +73,13 @@ export const formatWeightDiv = (val, digit = weightDigit) => {
export const formatDateTime = (val, fmt = 'YYYY-MM-DD HH:mm:ss') => { export const formatDateTime = (val, fmt = 'YYYY-MM-DD HH:mm:ss') => {
if (val) { if (val) {
let time = new Date(val) const time = new Date(val)
let Y = time.getFullYear() const Y = time.getFullYear()
let M = time.getMonth() + 1 const M = time.getMonth() + 1
let d = time.getDate() const d = time.getDate()
let h = time.getHours() const h = time.getHours()
let m = time.getMinutes() const m = time.getMinutes()
let s = time.getSeconds() const s = time.getSeconds()
fmt = fmt fmt = fmt
.replace('YYYY', Y) .replace('YYYY', Y)
@ -89,7 +90,8 @@ export const formatDateTime = (val, fmt = 'YYYY-MM-DD HH:mm:ss') => {
.replace('ss', s.toString().padStart(2, '0')) .replace('ss', s.toString().padStart(2, '0'))
return fmt return fmt
} else { }
else {
return val return val
} }
} }
@ -120,17 +122,18 @@ export const formatMillionYuan = (num, digit = 10000) => {
* @returns * @returns
*/ */
export const toDecimal2 = (x) => { export const toDecimal2 = (x) => {
var f = parseFloat(x) let f = parseFloat(x)
if (isNaN(f)) { if (isNaN(f)) {
return 0 return 0
} }
f = f + '' f = `${f}`
let index = f.lastIndexOf('.') const index = f.lastIndexOf('.')
if (index >= 0) { if (index >= 0) {
let decimal = f.substring(index + 1) const decimal = f.substring(index + 1)
if (decimal.length == 1) { if (decimal.length == 1) {
f = f.substring(0, index + 1) + decimal + '0' f = `${f.substring(0, index + 1) + decimal}0`
} else { }
else {
f = f.substring(0, index + 1) + decimal.substring(0, 2) f = f.substring(0, index + 1) + decimal.substring(0, 2)
} }
} }
@ -146,8 +149,9 @@ export const toDecimal2 = (x) => {
export const formatImgUrl = (url, suffix = '!w200') => { export const formatImgUrl = (url, suffix = '!w200') => {
if (url) { if (url) {
return url.includes('http') ? url + suffix : IMG_CND_Prefix + url + suffix return url.includes('http') ? url + suffix : IMG_CND_Prefix + url + suffix
} else { }
return IMG_CND_Prefix + '/mall/no_img.png' else {
return `${IMG_CND_Prefix}/mall/no_img.png`
} }
} }
@ -160,11 +164,13 @@ export const formatImgUrl = (url, suffix = '!w200') => {
*/ */
export const isLabImage = (imgurl, rgb, suffix = '!w200') => { export const isLabImage = (imgurl, rgb, suffix = '!w200') => {
if (imgurl) { if (imgurl) {
return { status: 1, value: IMG_CND_Prefix + '/' + imgurl + suffix } return { status: 1, value: `${IMG_CND_Prefix}/${imgurl}${suffix}` }
} else if (rgb.r != 0 || rgb.g != 0 || rgb.b != 0) { }
else if (rgb.r != 0 || rgb.g != 0 || rgb.b != 0) {
return { status: 2, value: rgb } return { status: 2, value: rgb }
} else { }
return { status: 3, value: IMG_CND_Prefix + '/mall/no_img.png' } else {
return { status: 3, value: `${IMG_CND_Prefix}/mall/no_img.png` }
} }
} }
@ -177,7 +183,8 @@ export const numberWithCommas = ({ number = 0, digit = 2 }) => {
if (!isNaN(Number(number))) { if (!isNaN(Number(number))) {
// return parseFloat(number).toFixed(digit).replace(/^\B(?<!\.\d*)(?=(\d{3})+(?!\d))$/g, ","); // return parseFloat(number).toFixed(digit).replace(/^\B(?<!\.\d*)(?=(\d{3})+(?!\d))$/g, ",");
return parseFloat(number).toLocaleString('zh', { minimumFractionDigits: digit }) return parseFloat(number).toLocaleString('zh', { minimumFractionDigits: digit })
} else { }
else {
return 0.0 return 0.0
} }
} }

View File

@ -1,33 +1,33 @@
import Taro from "@tarojs/taro" import Taro from '@tarojs/taro'
import { BASE_URL } from "../constant" import { BASE_URL } from '../constant'
//解析短码(主要用于右上角按钮分享) // 解析短码(主要用于右上角按钮分享)
export const analysisShortCodeApi = (val) => { export const analysisShortCodeApi = (val) => {
//解析短码 // 解析短码
Taro.request({ Taro.request({
url:BASE_URL+'/v1/mall/shortCode', url: `${BASE_URL}/v1/mall/shortCode`,
method:"GET", method: 'GET',
data:{md5_key: val}, data: { md5_key: val },
success:(res) => { success: (res) => {
if(res.data.code == 0) { if (res.data.code == 0) {
//绑定上下级 // 绑定上下级
bindParent(res.data.data.share_user_id) bindParent(res.data.data.share_user_id)
} }
} },
}) })
} }
//绑定上下级 // 绑定上下级
const bindParent = (share_user_id) => { const bindParent = (share_user_id) => {
//绑定上下级 // 绑定上下级
Taro.request({ Taro.request({
url:BASE_URL+'/v1/mall/shortCode/bind', url: `${BASE_URL}/v1/mall/shortCode/bind`,
method:"POST", method: 'POST',
data:{share_user_id: share_user_id}, data: { share_user_id },
success:(res) => { success: (res) => {
if(res.data.code == 0) { if (res.data.code == 0) {
//绑定上下级 // 绑定上下级
}
} }
}) },
} })
}

View File

@ -1,9 +1,8 @@
import Taro from "@tarojs/taro"; import Taro from '@tarojs/taro'
/** /**
* *
* @param {Object} systemInfo * @param {Object} systemInfo
*/ */
export const setSystem = (systemInfo) => { export const setSystem = (systemInfo) => {
Taro.setStorageSync('system', JSON.stringify(systemInfo)) Taro.setStorageSync('system', JSON.stringify(systemInfo))
@ -19,7 +18,7 @@ export const getSystem = () => {
/** /**
* *
* @param {Object} systemInfo * @param {Object} systemInfo
*/ */
export const setAccountInfo = (systemInfo) => { export const setAccountInfo = (systemInfo) => {
Taro.setStorageSync('accountInfo', JSON.stringify(systemInfo)) Taro.setStorageSync('accountInfo', JSON.stringify(systemInfo))
@ -35,9 +34,9 @@ export const getAccountInfo = () => {
/** /**
* *
* @param {Object} info * @param {Object} info
*/ */
export const setParam = (info:Object) => { export const setParam = (info: Object) => {
Taro.setStorageSync('params', JSON.stringify(info)) Taro.setStorageSync('params', JSON.stringify(info))
} }
@ -46,5 +45,5 @@ export const setParam = (info:Object) => {
*/ */
export const getParam = () => { export const getParam = () => {
const res = Taro.getStorageSync('params') || null const res = Taro.getStorageSync('params') || null
return res?JSON.parse(res):null return res ? JSON.parse(res) : null
} }

View File

@ -1,6 +1,6 @@
import Taro from '@tarojs/taro'
import { formatImgUrl } from './fotmat' import { formatImgUrl } from './fotmat'
import { analysisShortCodeApi } from './shortCode' import { analysisShortCodeApi } from './shortCode'
import Taro from '@tarojs/taro'
/** /**
* *
@ -11,7 +11,7 @@ import Taro from '@tarojs/taro'
export const debounce = (fn, delay) => { export const debounce = (fn, delay) => {
let timer: any = null let timer: any = null
return (...param) => { return (...param) => {
if (timer) clearTimeout(timer) if (timer) { clearTimeout(timer) }
timer = setTimeout(() => { timer = setTimeout(() => {
fn(...param) fn(...param)
}, delay) }, delay)
@ -27,7 +27,7 @@ export const debounce = (fn, delay) => {
export const throttle = (fn, delay) => { export const throttle = (fn, delay) => {
let pre = 0 let pre = 0
return (...params) => { return (...params) => {
let now = new Date().getTime() const now = new Date().getTime()
if (now - pre > delay) { if (now - pre > delay) {
fn(...params) fn(...params)
pre = now pre = now
@ -42,14 +42,15 @@ export const throttle = (fn, delay) => {
* @returns * @returns
*/ */
export const getFilterData = (val = {}, arr: string[] = []) => { export const getFilterData = (val = {}, arr: string[] = []) => {
let res = {} const res = {}
for (let key in val) { for (const key in val) {
if (val[key] !== undefined && val[key] !== null && val[key] !== '' && !arr.includes(key)) { if (val[key] !== undefined && val[key] !== null && val[key] !== '' && !arr.includes(key)) {
if (typeof val[key] == 'number') { if (typeof val[key] == 'number') {
if (!isNaN(val[key])) { if (!isNaN(val[key])) {
res[key] = val[key] res[key] = val[key]
} }
} else { }
else {
res[key] = val[key] res[key] = val[key]
} }
} }
@ -63,24 +64,26 @@ export const getFilterData = (val = {}, arr: string[] = []) => {
*/ */
export const copyObject = (object) => { export const copyObject = (object) => {
if (object.constructor == Object) { if (object.constructor == Object) {
let keys = Object.keys(object) const keys = Object.keys(object)
let newObject = {} const newObject = {}
keys.map((key) => { keys.map((key) => {
newObject[key] = copyObject(object[key]) newObject[key] = copyObject(object[key])
}) })
return newObject return newObject
} else if (object.constructor == Array) { }
else if (object.constructor == Array) {
return object.map((item) => { return object.map((item) => {
return copyObject(item) return copyObject(item)
}) })
} else { }
else {
return object return object
} }
} }
/** /**
* *
* @param {*} suffix * @param {*} suffix
* !w80 * !w80
!w100 !w100
!w160 !w160
@ -94,23 +97,26 @@ export const screenshot = (url, suffix = '!w200') => {
return url + suffix return url + suffix
} }
//获取数据加载状态 //0:数据从无到有加载数据1没有任何数据 2下拉加载3下拉没有数据 // 获取数据加载状态 //0:数据从无到有加载数据1没有任何数据 2下拉加载3下拉没有数据
export const dataLoadingStatus = ({ list = [], total = 0, status = false }: { list: any[]; total: number; status: true | false }) => { export const dataLoadingStatus = ({ list = [], total = 0, status = false }: { list: any[]; total: number; status: true | false }) => {
if (list.length == 0 && status) { if (list.length == 0 && status) {
return 0 return 0
} else if (list.length == 0 && !status) { }
else if (list.length == 0 && !status) {
return 1 return 1
} else if (list.length < total) { }
else if (list.length < total) {
return 2 return 2
} else { }
else {
return 3 return 3
} }
} }
//全局分享监听 // 全局分享监听
export const shareShop = () => { export const shareShop = () => {
const page = Taro.getCurrentInstance().page const page = Taro.getCurrentInstance().page
//当有分享参数时,绑定上下级 // 当有分享参数时,绑定上下级
if (page && page.options?.share) { if (page && page.options?.share) {
analysisShortCodeApi(page.options.share) analysisShortCodeApi(page.options.share)
} }
@ -119,16 +125,17 @@ export const shareShop = () => {
let path = '' let path = ''
let title = '' let title = ''
let imageUrl = '' let imageUrl = ''
let sortCode = Taro.getStorageSync('sort_code') ? JSON.parse(Taro.getStorageSync('sort_code')) : '' const sortCode = Taro.getStorageSync('sort_code') ? JSON.parse(Taro.getStorageSync('sort_code')) : ''
let pageInfo: any = page const pageInfo: any = page
//商品详情分享 // 商品详情分享
if (pageInfo.route === 'pages/details/index') { if (pageInfo.route === 'pages/details/index') {
path = `/pages/details/index?share=${sortCode.shareShortDetail.code}` path = `/pages/details/index?share=${sortCode.shareShortDetail.code}`
title = sortCode.shareShortDetail.title title = sortCode.shareShortDetail.title
imageUrl = sortCode.shareShortDetail.img imageUrl = sortCode.shareShortDetail.img
} else { }
path = else {
pageInfo.route === 'pages/user/index' path
= pageInfo.route === 'pages/user/index'
? `/pages/user/index?share=${sortCode.shareShortPage.code}` ? `/pages/user/index?share=${sortCode.shareShortPage.code}`
: `/pages/index/index?share=${sortCode.shareShortPage.code}` : `/pages/index/index?share=${sortCode.shareShortPage.code}`
title = sortCode.shareShortPage.title title = sortCode.shareShortPage.title

View File

@ -1,80 +1,82 @@
import { Button, Navigator, ScrollView, Text, View } from "@tarojs/components" import { Button, Navigator, ScrollView, Text, View } from '@tarojs/components'
import { memo, useEffect, useState } from "react" import { memo, useEffect, useState } from 'react'
import "./index.scss" import './index.scss'
import {addressListApi,addressDeleteApi} from "@/api/addressManager" import { addressDeleteApi, addressListApi } from '@/api/addressManager'
import { alert } from "@/common/common" import { alert } from '@/common/common'
import Taro, { showModal } from "@tarojs/taro" import Taro, { showModal } from '@tarojs/taro'
interface Params{ interface Params{
refresherEnabled?: boolean,//是否开启刷新 refresherEnabled?: boolean// 是否开启刷新
onSelect?: (item:any,index:number)=>void,//列表选择 onSelect?: (item: any, index: number) => void// 列表选择
addButtonEnabled?: boolean, //是否显示添加按钮 addButtonEnabled?: boolean // 是否显示添加按钮
focusBorderEnabled?: boolean, //焦点显示蓝色边框 focusBorderEnabled?: boolean // 焦点显示蓝色边框
id?: number, //默认选择值 id?: number // 默认选择值
} }
// 地址列表 // 地址列表
const AddressList = memo((props:Params)=>{ const AddressList = memo((props: Params) => {
const {addButtonEnabled=true,focusBorderEnabled=false} = props; const { addButtonEnabled = true, focusBorderEnabled = false } = props
const {fetchData, state} = addressListApi() const { fetchData, state } = addressListApi()
// 获取数据 // 获取数据
const getData = async ()=>{ const getData = async() => {
const result = await fetchData(); const result = await fetchData()
if(props.id){ if (props.id) {
setFocusId(props.id as any); setFocusId(props.id as any)
}else{ }
result.data.list?.every(item=>{ else {
if(item.is_default){ result.data.list?.every((item) => {
setFocusId(item.id); if (item.is_default) {
return false; setFocusId(item.id)
return false
} }
return true; return true
}) })
} }
} }
useEffect(()=>{ useEffect(() => {
getData(); getData()
// 监听刷新 // 监听刷新
Taro.eventCenter.on("addressList:refresh", getData); Taro.eventCenter.on('addressList:refresh', getData)
return ()=>{ return () => {
Taro.eventCenter.off("addressList:refresh", getData); Taro.eventCenter.off('addressList:refresh', getData)
} }
},[]) }, [])
// 处理刷新 // 处理刷新
const [refreshState, setRefreshState] = useState(false); const [refreshState, setRefreshState] = useState(false)
const handleRefresh = async ()=>{ const handleRefresh = async() => {
setRefreshState(true); setRefreshState(true)
await getData(); await getData()
setRefreshState(false); setRefreshState(false)
} }
const data = Array.from({length:15}); const data = Array.from({ length: 15 })
// 焦点 // 焦点
const [focusId, setFocusId] = useState(); const [focusId, setFocusId] = useState()
// 列表选择 // 列表选择
const handleSelect = (item: any, index: number)=>{ const handleSelect = (item: any, index: number) => {
props.onSelect&&props.onSelect(item,index); props.onSelect && props.onSelect(item, index)
if(focusBorderEnabled){ if (focusBorderEnabled) {
setFocusId(item?.id); setFocusId(item?.id)
} }
} }
// 删除地址 // 删除地址
const {fetchData: deleteFetch} = addressDeleteApi() const { fetchData: deleteFetch } = addressDeleteApi()
const handleDelete = (item:any)=>{ const handleDelete = (item: any) => {
showModal(({ showModal(({
title: "提示", title: '提示',
content: "是否删除地址?", content: '是否删除地址?',
async success(ev){ async success(ev) {
if(ev.confirm){ if (ev.confirm) {
const result = await deleteFetch({id:item.id}); const result = await deleteFetch({ id: item.id })
if(result.success){ if (result.success) {
alert.success("删除成功"); alert.success('删除成功')
getData(); getData()
}else{ }
alert.success(result.msg); else {
alert.success(result.msg)
} }
} }
} },
})) }))
} }
@ -83,42 +85,43 @@ const AddressList = memo((props:Params)=>{
<ScrollView scrollY refresherEnabled={props.refresherEnabled} enhanced refresherTriggered={refreshState} onRefresherRefresh={handleRefresh}> <ScrollView scrollY refresherEnabled={props.refresherEnabled} enhanced refresherTriggered={refreshState} onRefresherRefresh={handleRefresh}>
<View className="address-scroll-view-content"> <View className="address-scroll-view-content">
{ {
state?.data?.list?.length>0? state?.data?.list?.length > 0
state?.data?.list?.map((item,index)=>{ ? state?.data?.list?.map((item, index) => {
// data.length>0? // data.length>0?
// data.map((item,index)=>{ // data.map((item,index)=>{
return( return (
<View onLongPress={()=>handleDelete(item)} onClick={()=>handleSelect(item,index)} className={`address-list ${focusId==item.id&&'address-active'}`}> <View onLongPress={() => handleDelete(item)} onClick={() => handleSelect(item, index)} className={`address-list ${focusId == item.id && 'address-active'}`}>
<View className="address-user"> <View className="address-user">
{item.name} {item.name}
{
item.is_default?<Text className="address-list-default"></Text>:
<Text className="address-list-phone">{item.phone.replace(item.phone.substring(3,7), "****")}</Text>
}
</View>
<View className="address-list-bottom">
<View className="address-list-info">
<View>{item.province_name+item.city_name+item.district_name}
{/* {item.address_detail} */}
</View>
{ {
item.is_default&&<Text className="address-list-phone">{item.phone.replace(item.phone.substring(3,7), "****")}</Text> item.is_default
? <Text className="address-list-default"></Text>
: <Text className="address-list-phone">{item.phone.replace(item.phone.substring(3, 7), '****')}</Text>
} }
</View> </View>
<Navigator onClick={e=>e.stopPropagation()} url={`/pages/addressAdd/index?type=edit&id=${item.id}`} hoverClass="none" className="address-edit"> <View className="address-list-bottom">
<Text className="iconfont icon-bianji"></Text> <View className="address-list-info">
</Navigator> <View>{item.province_name + item.city_name + item.district_name}
{/* {item.address_detail} */}
</View>
{
item.is_default && <Text className="address-list-phone">{item.phone.replace(item.phone.substring(3, 7), '****')}</Text>
}
</View>
<Navigator onClick={e => e.stopPropagation()} url={`/pages/addressAdd/index?type=edit&id=${item.id}`} hoverClass="none" className="address-edit">
<Text className="iconfont icon-bianji"></Text>
</Navigator>
</View>
</View> </View>
</View> )
); })
}): : <View className="address-no-data"></View>
<View className="address-no-data"></View>
} }
</View> </View>
</ScrollView> </ScrollView>
{addButtonEnabled&&<Navigator url="/pages/addressAdd/index?type=add" hoverClass="none" className="add-address"></Navigator>} {addButtonEnabled && <Navigator url="/pages/addressAdd/index?type=add" hoverClass="none" className="add-address"></Navigator>}
</View> </View>
) )
}) })
export default AddressList; export default AddressList

View File

@ -3,15 +3,15 @@ import { memo } from 'react'
import './index.scss' import './index.scss'
interface ListParams { interface ListParams {
label: string //左边label label: string // 左边label
onInput?: (ev: Object) => void // 输入框输入 onInput?: (ev: Object) => void // 输入框输入
onClick?: () => any //点击列表 onClick?: () => any // 点击列表
placeholder?: string // 提示文本 placeholder?: string // 提示文本
children?: any // 插槽 children?: any // 插槽
type?: string // 类型1.input,2.textarea,3.select, type?: string // 类型1.input,2.textarea,3.select,
primordialType?: 'text' | 'number' | 'idcard' | 'digit' primordialType?: 'text' | 'number' | 'idcard' | 'digit'
value?: any value?: any
style?: object //整行样式 style?: object // 整行样式
labelStyle?: object // label样式 labelStyle?: object // label样式
contentStyle?: object contentStyle?: object
required?: boolean required?: boolean
@ -22,40 +22,44 @@ const FromList = memo((props: ListParams) => {
const { type = 'input', value = '', style = {}, labelStyle = {}, contentStyle = {}, required = false } = props const { type = 'input', value = '', style = {}, labelStyle = {}, contentStyle = {}, required = false } = props
return ( return (
<View style={style} className='form-list'> <View style={style} className="form-list">
<View style={labelStyle} className={`form-list-label ${required && 'form-list-label-required'}`}> <View style={labelStyle} className={`form-list-label ${required && 'form-list-label-required'}`}>
{props.label} {props.label}
</View> </View>
<View onClick={props?.onClick} className='form-list-right'> <View onClick={props?.onClick} className="form-list-right">
{props.children ?? ( {props.children ?? (
<View style={contentStyle} onClick={props?.onClick} className='form-list-right-meet'> <View style={contentStyle} onClick={props?.onClick} className="form-list-right-meet">
{type == 'input' ? ( {type == 'input'
<View className='form-list-input'> ? (
<Input <View className="form-list-input">
alwaysEmbed={true} <Input
cursorSpacing={150} alwaysEmbed
value={value} cursorSpacing={150}
placeholder-class='phcolor' value={value}
type={props.primordialType || 'text'} placeholder-class="phcolor"
onInput={props?.onInput} type={props.primordialType || 'text'}
placeholder={props.placeholder} onInput={props?.onInput}
/> placeholder={props.placeholder}
{value && ( />
<View> {value && (
<Text onClick={() => props.onInput && props.onInput({ detail: { value: '' } })} className='iconfont icon-qingkong' /> <View>
</View> <Text onClick={() => props.onInput && props.onInput({ detail: { value: '' } })} className="iconfont icon-qingkong" />
)} </View>
</View> )}
) : type == 'textarea' ? (
<Textarea value={value} placeholder-class='phcolor' onInput={props?.onInput} placeholder={props.placeholder} />
) : (
<>
{props.value ? <View>{value}</View> : <View className='form-list-right-placeholder'>{props.placeholder}</View>}
<View className='form-list-right-enter'>
<Text className='iconfont icon-a-moreback'></Text>
</View> </View>
</> )
)} : type == 'textarea'
? (
<Textarea value={value} placeholder-class="phcolor" onInput={props?.onInput} placeholder={props.placeholder} />
)
: (
<>
{props.value ? <View>{value}</View> : <View className="form-list-right-placeholder">{props.placeholder}</View>}
<View className="form-list-right-enter">
<Text className="iconfont icon-a-moreback"></Text>
</View>
</>
)}
</View> </View>
)} )}
</View> </View>

View File

@ -3,14 +3,14 @@ import { memo } from 'react'
import './index.scss' import './index.scss'
interface ListParams { interface ListParams {
label: string //左边label label: string // 左边label
onInput?: (ev: Object) => void // 输入框输入 onInput?: (ev: Object) => void // 输入框输入
onClick?: () => any //点击列表 onClick?: () => any // 点击列表
placeholder?: string // 提示文本 placeholder?: string // 提示文本
children?: any // 插槽 children?: any // 插槽
type?: string // 类型1.input,2.textarea,3.select type?: string // 类型1.input,2.textarea,3.select
value?: any value?: any
style?: object //整行样式 style?: object // 整行样式
labelStyle?: object // label样式 labelStyle?: object // label样式
contentStyle?: object contentStyle?: object
required?: boolean required?: boolean
@ -22,37 +22,41 @@ const FromList = memo((props: ListParams) => {
const { type = 'input', value = '', style = {}, labelStyle = {}, contentStyle = {}, required = false, showIcon = true } = props const { type = 'input', value = '', style = {}, labelStyle = {}, contentStyle = {}, required = false, showIcon = true } = props
return ( return (
<View style={style} className='From-list-certification'> <View style={style} className="From-list-certification">
<View style={labelStyle} className={`From-list-certification-label ${required && 'From-list-certification-label-required'}`}> <View style={labelStyle} className={`From-list-certification-label ${required && 'From-list-certification-label-required'}`}>
{props.label} {props.label}
</View> </View>
<View onClick={props?.onClick} className='From-list-certification-right'> <View onClick={props?.onClick} className="From-list-certification-right">
{props.children ?? ( {props.children ?? (
<View style={contentStyle} onClick={props?.onClick} className='From-list-certification-right-meet'> <View style={contentStyle} onClick={props?.onClick} className="From-list-certification-right-meet">
{type == 'input' ? ( {type == 'input'
<View className='From-list-certification-input'> ? (
<Input <View className="From-list-certification-input">
alwaysEmbed={true} <Input
cursorSpacing={150} alwaysEmbed
value={value} cursorSpacing={150}
placeholder-class='phcolor' value={value}
onInput={props?.onInput} placeholder-class="phcolor"
placeholder={props.placeholder} onInput={props?.onInput}
/> placeholder={props.placeholder}
{value && ( />
<View> {value && (
<Text onClick={() => props.onInput && props.onInput({ detail: { value: '' } })} className='iconfont icon-qingkong' /> <View>
</View> <Text onClick={() => props.onInput && props.onInput({ detail: { value: '' } })} className="iconfont icon-qingkong" />
</View>
)}
</View>
)
: type == 'textarea'
? (
<Textarea value={value} placeholder-class="phcolor" onInput={props?.onInput} placeholder={props.placeholder} />
)
: (
<>
{props.value ? <View>{value}</View> : <View className="From-list-certification-right-placeholder">{props.placeholder}</View>}
<View className="From-list-certification-right-enter">{showIcon && <Text className="iconfont icon-a-moreback"></Text>}</View>
</>
)} )}
</View>
) : type == 'textarea' ? (
<Textarea value={value} placeholder-class='phcolor' onInput={props?.onInput} placeholder={props.placeholder} />
) : (
<>
{props.value ? <View>{value}</View> : <View className='From-list-certification-right-placeholder'>{props.placeholder}</View>}
<View className='From-list-certification-right-enter'>{showIcon && <Text className='iconfont icon-a-moreback'></Text>}</View>
</>
)}
</View> </View>
)} )}
</View> </View>

View File

@ -1,5 +1,6 @@
import type { ReactNode } from 'react'
import { useEffect, useMemo, useRef, useState } from 'react'
import InfiniteScroll from '@/components/infiniteScroll' import InfiniteScroll from '@/components/infiniteScroll'
import { ReactNode, useEffect, useMemo, useRef, useState } from 'react'
import { dataLoadingStatus, getFilterData } from '@/common/util' import { dataLoadingStatus, getFilterData } from '@/common/util'
import { alert, isEmptyObject } from '@/common/common' import { alert, isEmptyObject } from '@/common/common'
@ -23,7 +24,7 @@ export default (props: Params) => {
getData({ moreStatus: true }, { moreStatus: true }) getData({ moreStatus: true }, { moreStatus: true })
} }
}, [query]) }, [query])
const getData = async (startStatus, endStatus) => { const getData = async(startStatus, endStatus) => {
const tRefreshDataRef = refreshDataRef.current as any const tRefreshDataRef = refreshDataRef.current as any
setRefreshData({ setRefreshData({
...tRefreshDataRef, ...tRefreshDataRef,
@ -44,7 +45,8 @@ export default (props: Params) => {
...endStatus, ...endStatus,
loading: false, loading: false,
}) })
} else { }
else {
setData({ setData({
list: result.data.list, list: result.data.list,
// list: tRefreshDataRef.page>1?(dataRef.current as any).list.concat(result.data.list):result.data.list, // list: tRefreshDataRef.page>1?(dataRef.current as any).list.concat(result.data.list):result.data.list,
@ -57,7 +59,8 @@ export default (props: Params) => {
loading: false, loading: false,
}) })
} }
} else { }
else {
alert.none(result.msg) alert.none(result.msg)
setRefreshData({ setRefreshData({
...tRefreshDataRef, ...tRefreshDataRef,
@ -83,8 +86,8 @@ export default (props: Params) => {
}) })
const dataRef = useRef({}) const dataRef = useRef({})
// 下拉刷新 // 下拉刷新
const handleRefresh = async () => { const handleRefresh = async() => {
let tRefreshData = refreshDataRef.current as any const tRefreshData = refreshDataRef.current as any
setRefreshData({ setRefreshData({
...tRefreshData, ...tRefreshData,
page: 1, page: 1,
@ -93,9 +96,9 @@ export default (props: Params) => {
getData({ refreshStatus: true, moreStatus: false }, { refreshStatus: false, moreStatus: true }) getData({ refreshStatus: true, moreStatus: false }, { refreshStatus: false, moreStatus: true })
} }
// 加载更多 // 加载更多
const handleMoreLoad = async () => { const handleMoreLoad = async() => {
let t = dataRef.current as any const t = dataRef.current as any
let tRefreshData = refreshDataRef.current as any const tRefreshData = refreshDataRef.current as any
if (t.list.length < t.total) { if (t.list.length < t.total) {
setRefreshData({ setRefreshData({
...tRefreshData, ...tRefreshData,
@ -112,19 +115,20 @@ export default (props: Params) => {
) )
} }
} }
//数据加载状态 // 数据加载状态
const statusMore = useMemo(() => { const statusMore = useMemo(() => {
return dataLoadingStatus({ list: data.list, total: data.total, status: refreshData.loading }) return dataLoadingStatus({ list: data.list, total: data.total, status: refreshData.loading })
}, [refreshData.loading]) }, [refreshData.loading])
return ( return (
<InfiniteScroll <InfiniteScroll
refresherEnabled={true} refresherEnabled
refresherTriggered={refreshData.refreshStatus} refresherTriggered={refreshData.refreshStatus}
moreStatus={refreshData.moreStatus} moreStatus={refreshData.moreStatus}
selfOnRefresherRefresh={handleRefresh} selfOnRefresherRefresh={handleRefresh}
selfonScrollToLower={handleMoreLoad} selfonScrollToLower={handleMoreLoad}
statusMore={statusMore}> statusMore={statusMore}
>
{props.children} {props.children}
</InfiniteScroll> </InfiniteScroll>
) )

View File

@ -1,16 +1,16 @@
import { formatImgUrl, formatRemoveHashTag } from '@/common/fotmat'
import Preview from '@/pages/details/components/preview'
import { Image, View } from '@tarojs/components' import { Image, View } from '@tarojs/components'
import { memo, useCallback, useEffect, useMemo, useState } from 'react' import { memo, useCallback, useEffect, useMemo, useState } from 'react'
import styles from './index.module.scss'
import LabAndImgShow from '../LabAndImgShow' import LabAndImgShow from '../LabAndImgShow'
import styles from './index.module.scss'
import Preview from '@/pages/details/components/preview'
import { formatImgUrl, formatRemoveHashTag } from '@/common/fotmat'
//该组件宽高为100%需调整外层元素宽高 // 该组件宽高为100%需调整外层元素宽高
type Param = { interface Param {
value: { value: {
texture_url?: string //纹理图路径 texture_url?: string // 纹理图路径
lab?: { l: number; a: number; b: number } //lab lab?: { l: number; a: number; b: number } // lab
rgb?: { r: number; g: number; b: number } //rgb rgb?: { r: number; g: number; b: number } // rgb
title?: string title?: string
} }
showStatus?: true | false showStatus?: true | false
@ -21,18 +21,19 @@ type Param = {
export default memo(({ value, onClick, showStatus = false, round = false, name = '' }: Param) => { export default memo(({ value, onClick, showStatus = false, round = false, name = '' }: Param) => {
const [imgs, setImgs] = useState<string>('') const [imgs, setImgs] = useState<string>('')
//lab是否都是0 // lab是否都是0
const rgbStyle = useMemo(() => { const rgbStyle = useMemo(() => {
if (value?.lab && (value?.lab.l || value?.lab.a || value?.lab.b)) { if (value?.lab && (value?.lab.l || value?.lab.a || value?.lab.b)) {
return { backgroundColor: `rgb(${value.rgb?.r} ${value.rgb?.g} ${value.rgb?.b})` } return { backgroundColor: `rgb(${value.rgb?.r} ${value.rgb?.g} ${value.rgb?.b})` }
} else { }
else {
return null return null
} }
}, [value]) }, [value])
useEffect(() => { useEffect(() => {
if (value?.texture_url) { if (value?.texture_url) {
let imgs = value.texture_url.split(',').map((item) => { const imgs = value.texture_url.split(',').map((item) => {
return formatImgUrl(item) return formatImgUrl(item)
}) })
setImgs(() => imgs[0]) setImgs(() => imgs[0])
@ -46,7 +47,7 @@ export default memo(({ value, onClick, showStatus = false, round = false, name =
const onShowLabAndImg = (e) => { const onShowLabAndImg = (e) => {
onClick?.(value) onClick?.(value)
if (!showStatus) return false if (!showStatus) { return false }
setLabAndImgShow(true) setLabAndImgShow(true)
} }
@ -59,15 +60,16 @@ export default memo(({ value, onClick, showStatus = false, round = false, name =
<View className={styles.labAndImg_main} style={{ borderRadius: round ? '50%' : '' }} onClick={onShowLabAndImg}> <View className={styles.labAndImg_main} style={{ borderRadius: round ? '50%' : '' }} onClick={onShowLabAndImg}>
{value.texture_url && ( {value.texture_url && (
<Image <Image
mode='aspectFill' mode="aspectFill"
src={imgs} src={imgs}
onError={(e) => checkLoad(e)} onError={e => checkLoad(e)}
className={styles.labAndImg_image} className={styles.labAndImg_image}
style={{ borderRadius: round ? '50%' : '' }}></Image> style={{ borderRadius: round ? '50%' : '' }}
></Image>
)} )}
{!value.texture_url && rgbStyle && <View className={styles.boxColor} style={{ ...rgbStyle, borderRadius: round ? '50%' : '' }}></View>} {!value.texture_url && rgbStyle && <View className={styles.boxColor} style={{ ...rgbStyle, borderRadius: round ? '50%' : '' }}></View>}
{!value.texture_url && !rgbStyle && ( {!value.texture_url && !rgbStyle && (
<Image mode='aspectFill' src={formatImgUrl('')} className={styles.labAndImg_image} style={{ borderRadius: round ? '50%' : '' }}></Image> <Image mode="aspectFill" src={formatImgUrl('')} className={styles.labAndImg_image} style={{ borderRadius: round ? '50%' : '' }}></Image>
)} )}
{name && <View className={styles.labAndImg_name}>{name}</View>} {name && <View className={styles.labAndImg_name}>{name}</View>}
</View> </View>

View File

@ -1,39 +1,40 @@
import { formatImgUrl } from '@/common/fotmat'
import { View } from '@tarojs/components' import { View } from '@tarojs/components'
import Taro from '@tarojs/taro'
import { useEffect, useMemo, useState } from 'react' import { useEffect, useMemo, useState } from 'react'
import styles from './index.module.scss' import styles from './index.module.scss'
import Taro from '@tarojs/taro' import { formatImgUrl } from '@/common/fotmat'
export type colorParams = { export interface colorParams {
value?: { value?: {
texture_url?: string //纹理图路径 texture_url?: string // 纹理图路径
lab?: { l: number; a: number; b: number } //lab lab?: { l: number; a: number; b: number } // lab
rgb?: { r: number; g: number; b: number } //rgb rgb?: { r: number; g: number; b: number } // rgb
title?: string //标题 title?: string // 标题
} }
show?: false | true show?: false | true
onClose?: () => void onClose?: () => void
showNumber?: number //图片显示张数0不限制 showNumber?: number // 图片显示张数0不限制
} }
export default ({ value, show = false, onClose, showNumber = 1 }: colorParams) => { export default ({ value, show = false, onClose, showNumber = 1 }: colorParams) => {
useEffect(() => { useEffect(() => {
if (show && rgbStyle) setLabShow(() => true) if (show && rgbStyle) { setLabShow(() => true) }
if (show && value?.texture_url) onShowImage() if (show && value?.texture_url) { onShowImage() }
if (!show) setLabShow(() => false) if (!show) { setLabShow(() => false) }
}, [show]) }, [show])
//显示颜色 // 显示颜色
const [labShow, setLabShow] = useState(false) const [labShow, setLabShow] = useState(false)
//lab是否都是0 // lab是否都是0
const rgbStyle = useMemo(() => { const rgbStyle = useMemo(() => {
if (value?.lab && (value.lab.l || value.lab.a || value.lab.b)) { if (value?.lab && (value.lab.l || value.lab.a || value.lab.b)) {
return { backgroundColor: `rgb(${value.rgb?.r} ${value.rgb?.g} ${value.rgb?.b})` } return { backgroundColor: `rgb(${value.rgb?.r} ${value.rgb?.g} ${value.rgb?.b})` }
} else { }
else {
return null return null
} }
}, [value]) }, [value])
//显示图片 // 显示图片
const onShowImage = () => { const onShowImage = () => {
onClose?.() onClose?.()
let res: string[] = [] let res: string[] = []
@ -42,7 +43,7 @@ export default ({ value, show = false, onClose, showNumber = 1 }: colorParams) =
return formatImgUrl(item) return formatImgUrl(item)
}) })
} }
let n_res = showNumber == 0 ? res : res?.splice(0, showNumber) const n_res = showNumber == 0 ? res : res?.splice(0, showNumber)
Taro.previewImage({ Taro.previewImage({
current: n_res[0], current: n_res[0],
urls: n_res, urls: n_res,
@ -52,7 +53,7 @@ export default ({ value, show = false, onClose, showNumber = 1 }: colorParams) =
return ( return (
<> <>
{labShow && ( {labShow && (
<View className={styles.main} catch-move='true' onClick={() => onClose?.()}> <View className={styles.main} catch-move="true" onClick={() => onClose?.()}>
<View className={styles.con}> <View className={styles.con}>
<View className={styles.rgb} style={rgbStyle!}></View> <View className={styles.rgb} style={rgbStyle!}></View>
<View className={styles.name}>{value?.title}</View> <View className={styles.name}>{value?.title}</View>

View File

@ -1,14 +1,14 @@
import { Button, Navigator, ScrollView, Text, View } from "@tarojs/components" import { Button, Navigator, ScrollView, Text, View } from '@tarojs/components'
import { memo } from "react" import { memo } from 'react'
import "./index.scss" import './index.scss'
interface Params{ interface Params{
text: String,//提示信息 text: String// 提示信息
} }
// 消息提示 // 消息提示
const Message = memo((props:Params)=>{ const Message = memo((props: Params) => {
return ( return (
<View className="message-custom-tips"> <View className="message-custom-tips">
<Text className="iconfont icon-zhuyi"></Text> {props.text} <Text className="iconfont icon-zhuyi"></Text> {props.text}
@ -16,4 +16,4 @@ const Message = memo((props:Params)=>{
) )
}) })
export default Message; export default Message

View File

@ -1,29 +1,29 @@
import Popup from '@/components/popup'
import { Input, ScrollView, Text, View } from '@tarojs/components' import { Input, ScrollView, Text, View } from '@tarojs/components'
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react' import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import classnames from 'classnames' import classnames from 'classnames'
import styles from './index.module.scss' import styles from './index.module.scss'
import Popup from '@/components/popup'
import TextareaEnhance from '@/components/textareaEnhance' import TextareaEnhance from '@/components/textareaEnhance'
import { CreateFavoriteApi, FavoriteListApi } from '@/api/favorite' import { CreateFavoriteApi, FavoriteListApi } from '@/api/favorite'
import { alert, goLink } from '@/common/common' import { alert, goLink } from '@/common/common'
import { getFilterData } from '@/common/util' import { getFilterData } from '@/common/util'
//原因选择 // 原因选择
type ReasonInfoParam = { interface ReasonInfoParam {
show?: boolean //显示 show?: boolean // 显示
onClose?: () => void //关闭 onClose?: () => void // 关闭
onAdd?: (val: any) => void onAdd?: (val: any) => void
} }
export default memo(({ show = false, onClose, onAdd }: ReasonInfoParam) => { export default memo(({ show = false, onClose, onAdd }: ReasonInfoParam) => {
//获取列表 // 获取列表
const [list, setList] = useState([]) const [list, setList] = useState([])
const { fetchData: fetchDataList } = FavoriteListApi() const { fetchData: fetchDataList } = FavoriteListApi()
const getFavoriteList = async () => { const getFavoriteList = async() => {
let res = await fetchDataList(getFilterData()) const res = await fetchDataList(getFilterData())
setList(() => res.data.list) setList(() => res.data.list)
} }
useEffect(() => { useEffect(() => {
if (show) getFavoriteList() if (show) { getFavoriteList() }
}, [show]) }, [show])
const onCreate = () => { const onCreate = () => {

View File

@ -1,218 +1,218 @@
import { ScrollView, Text, View } from "@tarojs/components"; import { ScrollView, Text, View } from '@tarojs/components'
import { memo, ReactHTMLElement, useEffect, useRef, useState } from "react"; import Taro from '@tarojs/taro'
import Drawer from "@/components/popup"; import React, { ReactHTMLElement, memo, useEffect, useRef, useState } from 'react'
import styles from "./index.module.scss" import classnames from 'classnames'
import classnames from "classnames"; import styles from './index.module.scss'
import Taro from "@tarojs/taro"; import Drawer from '@/components/popup'
import { GetAddressListApi } from "@/api/addressList"; import { GetAddressListApi } from '@/api/addressList'
import { alert } from "@/common/common"; import { alert } from '@/common/common'
interface DefaultValueParm { name: string; id: string|number; level?: number|string }
type DefaultValueParm = {name: string, id:string|number, level?: number|string} interface Params {
addressOnSelect?: (val: DefaultValueParm[]) => void
type Params = { addressOnChange?: (val: DefaultValueParm[]) => void
addressOnSelect?: (val:DefaultValueParm[]) => void, addressOnClose?: () => void
addressOnChange?: (val:DefaultValueParm[]) => void, show?: true|false
addressOnClose?: () => void, defaultValue?: DefaultValueParm[]
show?: true|false, selectStatus?: false|true // false不需要选择完整地址true需要选择完整地址
defaultValue?:DefaultValueParm[]
selectStatus?: false|true, //false不需要选择完整地址true需要选择完整地址
} }
type AddresParam = { interface AddresParam {
ad_code?: string, ad_code?: string
id?: number, id?: number
level?: number, level?: number
level_name?: string, level_name?: string
name?: string, name?: string
parent_id?: number, parent_id?: number
}
}
export default memo(({ export default memo(({
addressOnSelect, addressOnSelect,
addressOnChange, addressOnChange,
addressOnClose, addressOnClose,
show = false, show = false,
defaultValue = [], defaultValue = [],
selectStatus = true selectStatus = true,
}: Params) => { }: Params) => {
//省 // 省
const provinceList = useRef<AddresParam[]>([]) const provinceList = useRef<AddresParam[]>([])
//市 // 市
const cityList = useRef<AddresParam[]>([]) const cityList = useRef<AddresParam[]>([])
//区 // 区
const areaList = useRef<AddresParam[]>([]) const areaList = useRef<AddresParam[]>([])
const [list, setList] = useState<AddresParam[]>([])
const [selectIndex, setSelectIndex] = useState(0) //0 省, 1 市2 区
const [selectId, setSelectId] = useState(1) //选中的id
const [selectArr, setSelectArr] = useState<DefaultValueParm[]>([]) //选中的省市区
const [cityStatus, setCityStatus] = useState(false) //城市是否存在
const [areaStatus, setAreaStatus] = useState(false) //区镇是否存在
const [confirmBtnStatus, setConfirmBtnStatus] = useState(false) //确认按钮是否可用
const [bottomStyle, setBottomStyle] = useState({width:'100rpx',left:'0rpx'}) //底部滚动条样式 const [list, setList] = useState<AddresParam[]>([])
const [selectIndex, setSelectIndex] = useState(0) // 0 省, 1 市2 区
const [selectId, setSelectId] = useState(1) // 选中的id
const [selectArr, setSelectArr] = useState<DefaultValueParm[]>([]) // 选中的省市区
const [cityStatus, setCityStatus] = useState(false) // 城市是否存在
const [areaStatus, setAreaStatus] = useState(false) // 区镇是否存在
const [confirmBtnStatus, setConfirmBtnStatus] = useState(false) // 确认按钮是否可用
useEffect(() => { const [bottomStyle, setBottomStyle] = useState<React.CSSProperties>({ width: '100rpx', left: '0rpx' }) // 底部滚动条样式
if(selectArr.length == 0) {
setSelectArr(defaultValue)
if(defaultValue.length > 1) setCityStatus(true)
if(defaultValue.length > 2) setAreaStatus(true)
if(defaultValue.length > 0) setConfirmBtnStatus(true)
}
}, [defaultValue])
useEffect(() => {
//获取地址 if (selectArr.length == 0) {
const {fetchData} = GetAddressListApi() setSelectArr(defaultValue)
useEffect(() => { if (defaultValue.length > 1) { setCityStatus(true) }
getProvince() if (defaultValue.length > 2) { setAreaStatus(true) }
}, []) if (defaultValue.length > 0) { setConfirmBtnStatus(true) }
//选中内容
const selectItem = (item) => {
setSelectId(item.id)
if(selectIndex == 0) {
setSelectArr([{name:item.name, id:item.id, level:item.level}])
getCity(item.id)
setAreaStatus(false)
setCityStatus(false)
} else if(selectIndex == 1){
setSelectArr([selectArr[0], {name:item.name, id:item.id, level:item.level}])
area(item.id)
} else {
setSelectArr([selectArr[0], selectArr[1], {name:item.name, id:item.id, level:item.level}])
getDomDes('#address_tab_2')
}
} }
}, [defaultValue])
//地址数据 // 获取地址
useEffect(() => { const { fetchData } = GetAddressListApi()
if(selectArr && selectArr.length > 0) useEffect(() => {
addressOnChange?.(selectArr) getProvince()
}, [selectArr]) }, [])
//选中标题 // 选中内容
const onSelectIndex = (index) => { const selectItem = (item) => {
setSelectIndex(index) setSelectId(item.id)
const selectid = selectArr[index]?selectArr[index].id:0 if (selectIndex == 0) {
setSelectId(selectid as number) setSelectArr([{ name: item.name, id: item.id, level: item.level }])
if(index == 0) { getCity(item.id)
getProvince() setAreaStatus(false)
} else if (index == 1) { setCityStatus(false)
const id = selectArr[0]?.id
getCity(id)
} else {
const id = selectArr[1]?.id
area(id)
}
} }
else if (selectIndex == 1) {
setSelectArr([selectArr[0], { name: item.name, id: item.id, level: item.level }])
//获取省 area(item.id)
const getProvince = async () => {
let res = await fetchData({parent_id: 1})
provinceList.current = res.data.list||[]
if(provinceList.current.length > 0) {
setSelectIndex(0)
setList(() => provinceList.current)
getDomDes('#address_tab_0')
}
} }
else {
//获取市 setSelectArr([selectArr[0], selectArr[1], { name: item.name, id: item.id, level: item.level }])
const getCity = async (id) => { getDomDes('#address_tab_2')
let res = await fetchData({parent_id: id})
cityList.current = res.data.list||[]
if(cityList.current.length > 0) {
setSelectIndex(1)
setList(() => cityList.current)
setCityStatus(true)
getDomDes('#address_tab_1')
setConfirmBtnStatus(false)
} else {
setConfirmBtnStatus(true)
setCityStatus(false)
}
} }
}
//获取区 // 地址数据
const area = async (id) => { useEffect(() => {
let res = await fetchData({parent_id: id}) if (selectArr && selectArr.length > 0) { addressOnChange?.(selectArr) }
areaList.current = res.data.list||[] }, [selectArr])
if(areaList.current.length > 0) {
setSelectIndex(2) // 选中标题
setList(() => areaList.current) const onSelectIndex = (index) => {
setAreaStatus(true) setSelectIndex(index)
getDomDes('#address_tab_2') const selectid = selectArr[index] ? selectArr[index].id : 0
setConfirmBtnStatus(false) setSelectId(selectid as number)
} else { if (index == 0) {
setConfirmBtnStatus(true) getProvince()
setAreaStatus(false)
}
} }
else if (index == 1) {
//确定按钮 const id = selectArr[0]?.id
const submitSelect = () => { getCity(id)
addressOnClose?.()
addressOnSelect?.(selectArr)
} }
else {
//获取省市区宽度 const id = selectArr[1]?.id
const getDomDes = (id) => { area(id)
setTimeout(() => {
let query = Taro.createSelectorQuery();
query.select(id).boundingClientRect(rect=>{
let left = rect.left;
let clientWidth = rect.width;
console.log(clientWidth)
setBottomStyle({
width: clientWidth + 'px',
left: left + 'px'
})
}).exec();
}, 100)
} }
}
//点击标题栏 // 获取省
const selectTab = (index) => { const getProvince = async() => {
onSelectIndex(index) const res = await fetchData({ parent_id: 1 })
getDomDes('#address_tab_'+index) provinceList.current = res.data.list || []
if (provinceList.current.length > 0) {
setSelectIndex(0)
setList(() => provinceList.current)
getDomDes('#address_tab_0')
} }
}
return ( // 获取市
<> const getCity = async(id) => {
<Drawer showTitle={false} show={show} onClose={submitSelect}> const res = await fetchData({ parent_id: id })
<View className={styles.address_main}> cityList.current = res.data.list || []
<View className={styles.address_title}> if (cityList.current.length > 0) {
<View onClick={() => addressOnClose?.()}></View> setSelectIndex(1)
<View onClick={() => submitSelect()}></View> setList(() => cityList.current)
setCityStatus(true)
getDomDes('#address_tab_1')
setConfirmBtnStatus(false)
}
else {
setConfirmBtnStatus(true)
setCityStatus(false)
}
}
// 获取区
const area = async(id) => {
const res = await fetchData({ parent_id: id })
areaList.current = res.data.list || []
if (areaList.current.length > 0) {
setSelectIndex(2)
setList(() => areaList.current)
setAreaStatus(true)
getDomDes('#address_tab_2')
setConfirmBtnStatus(false)
}
else {
setConfirmBtnStatus(true)
setAreaStatus(false)
}
}
// 确定按钮
const submitSelect = () => {
addressOnClose?.()
addressOnSelect?.(selectArr)
}
// 获取省市区宽度
const getDomDes = (id) => {
setTimeout(() => {
const query = Taro.createSelectorQuery()
query.select(id).boundingClientRect((rect) => {
const left = rect.left
const clientWidth = rect.width
console.log(clientWidth)
setBottomStyle({
width: `${clientWidth}px`,
left: `${left}px`,
})
}).exec()
}, 100)
}
// 点击标题栏
const selectTab = (index) => {
onSelectIndex(index)
getDomDes(`#address_tab_${index}`)
}
return (
<>
<Drawer showTitle={false} show={show} onClose={submitSelect}>
<View className={styles.address_main}>
<View className={styles.address_title}>
<View onClick={() => addressOnClose?.()}></View>
<View onClick={() => submitSelect()}></View>
</View>
<View className={styles.address_select}>
<View id="address_tab_0" onClick={() => selectTab(0)} className={classnames(styles.address_item, { [styles.addresst_select]: (selectIndex == 0) })}>{selectArr[0] ? selectArr[0].name : '请选择'}</View>
{cityStatus && <View id="address_tab_1" onClick={() => selectTab(1)} className={classnames(styles.address_item, { [styles.addresst_select]: (selectIndex == 1) })}>{selectArr[1] ? selectArr[1].name : '请选择'}</View>}
{areaStatus && <View id="address_tab_2" onClick={() => selectTab(2)} className={classnames(styles.address_item, { [styles.addresst_select]: (selectIndex == 2) })}>{selectArr[2] ? selectArr[2].name : '请选择'}</View>}
<View style={bottomStyle} className={styles.bottom_index}></View>
</View>
<View className={styles.address_list}>
<ScrollView scrollY className={styles.address_scroll}>
<View className={styles.address_scroll_list}>
{list.map((item) => {
return (
<View onClick={() => selectItem(item)} className={classnames(styles.address_list_item, { [styles.addresst_select]: (selectId == item.id) })}>
<View className={styles.address_list_item_name}>{item.name}</View>
{(selectArr[selectIndex]?.id == item.id) && <View className={`iconfont icon-tick ${styles.address_iconfont}`}></View>}
</View> </View>
<View className={styles.address_select}> )
<View id="address_tab_0" onClick={() => selectTab(0)} className={classnames(styles.address_item, {[styles.addresst_select]:(selectIndex == 0)})}>{selectArr[0]?selectArr[0].name:'请选择'}</View> })}
{cityStatus&&<View id="address_tab_1" onClick={() => selectTab(1)} className={classnames(styles.address_item, {[styles.addresst_select]:(selectIndex == 1)})}>{selectArr[1]?selectArr[1].name:'请选择'}</View>} </View>
{areaStatus&&<View id="address_tab_2" onClick={() => selectTab(2)} className={classnames(styles.address_item, {[styles.addresst_select]:(selectIndex == 2)})}>{selectArr[2]?selectArr[2].name:'请选择'}</View>} </ScrollView>
<View style={bottomStyle} className={styles.bottom_index}></View> </View>
</View> </View>
<View className={styles.address_list}> </Drawer>
<ScrollView scrollY className={styles.address_scroll}> </>
<View className={styles.address_scroll_list}> )
{list.map(item => { })
return (
<View onClick={() => selectItem(item)} className={classnames(styles.address_list_item, {[styles.addresst_select]:(selectId == item.id)})}>
<View className={styles.address_list_item_name}>{item.name}</View>
{(selectArr[selectIndex]?.id == item.id)&&<View className={`iconfont icon-tick ${styles.address_iconfont}` }></View>}
</View>
)
})}
</View>
</ScrollView>
</View>
</View>
</Drawer>
</>
)
})

View File

@ -1,202 +1,205 @@
import { CancelOrderApi, ReceiveOrderApi } from "@/api/order" import { ScrollView, Text, View } from '@tarojs/components'
import { alert } from "@/common/common" import Taro from '@tarojs/taro'
import { ORDER_STATUS, SALE_MODE } from "@/common/enum" import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { ScrollView, Text, View } from "@tarojs/components" import styles from './index.module.scss'
import Taro from "@tarojs/taro" import { ORDER_STATUS, SALE_MODE } from '@/common/enum'
import { useCallback, useRef, memo, useState, useEffect, useMemo } from "react" import { alert } from '@/common/common'
import styles from './index.module.scss' import { CancelOrderApi, ReceiveOrderApi } from '@/api/order'
type Param = { interface Param {
orderInfo: { orderInfo: {
status: number, //订单状态 status: number // 订单状态
orderId: number, //订单id orderId: number // 订单id
actual_amount: number, //实付金额 actual_amount: number // 实付金额
wait_pay_amount: number, //待付金额 wait_pay_amount: number // 待付金额
sale_mode: number //订单类型 sale_mode: number // 订单类型
}|null, }|null
onClick?: (val: number) => void //点击后触发的事件,返回订单状态 onClick?: (val: number) => void // 点击后触发的事件,返回订单状态
} }
export default memo(({orderInfo, onClick}:Param) => { export default memo(({ orderInfo, onClick }: Param) => {
//订单状态枚举 // 订单状态枚举
const { const {
SaleOrderStatusBooking, SaleOrderStatusBooking,
SaleOrderStatusArranging, SaleOrderStatusArranging,
SaleOrderStatusArranged, SaleOrderStatusArranged,
SaleOrderStatusWaitingDelivery, SaleOrderStatusWaitingDelivery,
SaleOrderStatusComplete, SaleOrderStatusComplete,
SaleOrderStatusRefund, SaleOrderStatusRefund,
SaleOrderStatusWaitingPayment, SaleOrderStatusWaitingPayment,
SaleOrderStatusWaitingReceipt, SaleOrderStatusWaitingReceipt,
SaleOrderStatusAlreadyReceipt, SaleOrderStatusAlreadyReceipt,
SaleorderstatusWaitingPrePayment SaleorderstatusWaitingPrePayment,
} = ORDER_STATUS } = ORDER_STATUS
//订单类型 // 订单类型
const { const {
SaLeModeBulk, SaLeModeBulk,
SaleModeLengthCut, SaleModeLengthCut,
SaLeModeWeightCut, SaLeModeWeightCut,
} = SALE_MODE } = SALE_MODE
//订单按钮按订单状态归类, value是该订单状态可能该按钮会出现
const orderBtnsList = useRef([
{
id: 1,
value: [SaleOrderStatusBooking.value,
SaleOrderStatusArranging.value,
SaleOrderStatusArranged.value,
SaleOrderStatusWaitingPayment.value,
SaleOrderStatusWaitingDelivery.value], //取消订单按钮对应: 待接单,配布中,已配布, 待付款, 待发货
label: '取消订单'
},
{
id: 2,
value: [SaleorderstatusWaitingPrePayment.value, SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value], //去付款按钮对应:待付款, 待发货, 待收货, 已收货, 已完成
label: '去付款'
},
{
id: 3,
value: [SaleOrderStatusWaitingDelivery.value], //申请退款按钮对应: 待发货
label: '申请退款'
},
{
id: 4,
value: [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value], //取消订单按钮对应: 待收货, 已收货, 已完成, 已退款
label: '查看物流'
},
{
id: 5,
value: [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusRefund.value], //申请退货按钮对应: 待收货, 已收货, 已退款
label: '申请退货'
},
{
id: 6,
value: [SaleOrderStatusWaitingReceipt.value], //确认收货按钮对应: 待收货
label: '确认收货'
},
{
id: 7,
value: [SaleOrderStatusWaitingReceipt.value,SaleOrderStatusAlreadyReceipt.value,SaleOrderStatusComplete.value,SaleOrderStatusRefund.value], //再次购买按钮对应: 待收货,已收货,已完成, 已退款
label: '再次购买'
},
{
id: 8,
value: [SaleOrderStatusBooking.value], //按钮对应: 待接单
label: '退款'
},
])
//判断是否显示该按钮 // 订单按钮按订单状态归类, value是该订单状态可能该按钮会出现
const orderBtnsShow = (item) => { const orderBtnsList = useRef([
if(orderInfo) { {
if(item.id == 1) { id: 1,
//取消订单按钮 value: [SaleOrderStatusBooking.value,
return( orderInfo.actual_amount == 0 && item.value.includes(orderInfo.status)) //在待发货之前没有付过款 SaleOrderStatusArranging.value,
} else if (item.id == 2) { SaleOrderStatusArranged.value,
//去付款按钮 SaleOrderStatusWaitingPayment.value,
return( orderInfo.wait_pay_amount != 0 && item.value.includes(orderInfo.status)) //只要没有付完款就显示 SaleOrderStatusWaitingDelivery.value], // 取消订单按钮对应: 待接单,配布中,已配布, 待付款, 待发货
} else if(item.id == 3 ) { label: '取消订单',
//申请退款, 只有大货才有 },
return (orderInfo.sale_mode == SaLeModeBulk.value && orderInfo.actual_amount != 0 && item.value.includes(orderInfo.status)) //大货在待发货付过款 {
} else if( item.id == 8) { id: 2,
//退款按钮(直接退款不用申请), 只有散剪和剪板有 value: [SaleorderstatusWaitingPrePayment.value, SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value], // 去付款按钮对应:待付款, 待发货, 待收货, 已收货, 已完成
return (orderInfo.sale_mode != SaLeModeBulk.value && orderInfo.actual_amount != 0 && item.value.includes(orderInfo.status)) //散剪和剪板在待接单时付过款 label: '去付款',
} },
else { {
//其他按钮 id: 3,
return item.value.includes(orderInfo.status) value: [SaleOrderStatusWaitingDelivery.value], // 申请退款按钮对应: 待发货
} label: '申请退款',
},
{
id: 4,
value: [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value], // 取消订单按钮对应: 待收货, 已收货, 已完成, 已退款
label: '查看物流',
},
{
id: 5,
value: [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusRefund.value], // 申请退货按钮对应: 待收货, 已收货, 已退款
label: '申请退货',
},
{
id: 6,
value: [SaleOrderStatusWaitingReceipt.value], // 确认收货按钮对应: 待收货
label: '确认收货',
},
{
id: 7,
value: [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value], // 再次购买按钮对应: 待收货,已收货,已完成, 已退款
label: '再次购买',
},
{
id: 8,
value: [SaleOrderStatusBooking.value], // 按钮对应: 待接单
label: '退款',
},
])
// 判断是否显示该按钮
const orderBtnsShow = (item) => {
if (orderInfo) {
if (item.id == 1) {
// 取消订单按钮
return (orderInfo.actual_amount == 0 && item.value.includes(orderInfo.status)) // 在待发货之前没有付过款
}
else if (item.id == 2) {
// 去付款按钮
return (orderInfo.wait_pay_amount != 0 && item.value.includes(orderInfo.status)) // 只要没有付完款就显示
}
else if (item.id == 3) {
// 申请退款, 只有大货才有
return (orderInfo.sale_mode == SaLeModeBulk.value && orderInfo.actual_amount != 0 && item.value.includes(orderInfo.status)) // 大货在待发货付过款
}
else if (item.id == 8) {
// 退款按钮(直接退款不用申请), 只有散剪和剪板有
return (orderInfo.sale_mode != SaLeModeBulk.value && orderInfo.actual_amount != 0 && item.value.includes(orderInfo.status)) // 散剪和剪板在待接单时付过款
}
else {
// 其他按钮
return item.value.includes(orderInfo.status)
}
}
}
// 显示的按钮数组
const orderBtnsShowList: { id: number; value: any; label: string }[] = useMemo(() => {
return orderBtnsList.current.filter((item) => {
return orderBtnsShow(item)
})
}, [orderInfo])
// 点击按钮操作
const submitBtns = (val, index) => {
(val == 1) && cancelOrder(); // 取消订单按钮
(val == 2) && onClick?.(2); // 去付款按钮
(val == 6) && receiveOrder() // 确认收货
}
// 取消订单
const { fetchData: cancelFetchData } = CancelOrderApi()
const cancelOrder = () => {
Taro.showModal({
title: '要取消该订单吗?',
async success(res) {
if (res.confirm) {
const res = await cancelFetchData({ id: orderInfo?.orderId })
if (res.success) {
alert.success('取消成功')
onClick?.(1)
}
else {
alert.none(res.msg)
}
}
else if (res.cancel) {
console.log('用户点击取消')
} }
} },
})
}
//显示的按钮数组 // 确认订单
const orderBtnsShowList: {id: number, value: any, label: string}[] = useMemo(() => { const { fetchData: receiveOrderFetchData } = ReceiveOrderApi()
return orderBtnsList.current.filter(item => { const receiveOrder = async() => {
return orderBtnsShow(item) console.log('123456')
}) Taro.showModal({
}, [orderInfo]) title: '确定收货?',
async success(res) {
if (res.confirm) {
const res = await receiveOrderFetchData({ sale_order_id: orderInfo?.orderId })
if (res.success) {
onClick?.(6)
alert.success('收货成功')
}
else {
alert.error('收货失败')
}
}
else if (res.cancel) {
console.log('用户点击取消')
}
},
})
}
// 显示更多按钮
const [showMore, setShowMore] = useState(false)
const styleTop = useMemo(() => {
return { top: `-${(orderBtnsShowList.length - 3) * 70 + 10}rpx`, left: `-${10}rpx` }
}, [orderBtnsShowList])
return (
<View className={styles.btns_list}>
{(orderBtnsShowList.length > 3) && <View className={styles.more}>
<Text onClick={() => setShowMore(true)}></Text>
{showMore && <View className={styles.more_con}>
<View className={styles.more_list} style={styleTop}>
{orderBtnsShowList.map((item, index) => {
return ((index >= 3) && <View className={styles.more_item} key={item.id} onClick={() => submitBtns(item.id, index)}>{item.label}</View>)
})}
</View>
<View className={styles.more_bg} catchMove onClick={() => setShowMore(false)}></View>
</View>}
</View>}
//点击按钮操作 <View className={styles.list_scroll}>
const submitBtns = (val, index) => { {orderBtnsShowList.map((item, index) =>
(val == 1)&&cancelOrder(); //取消订单按钮 (index < 3) && <View key={item.id} className={styles.btns_item} onClick={() => submitBtns(item.id, index)}>{item.label}</View>,
(val == 2)&&onClick?.(2); //去付款按钮 )}
(val == 6)&&receiveOrder(); //确认收货 </View>
}
//取消订单 </View>
const {fetchData: cancelFetchData} = CancelOrderApi() )
const cancelOrder = () => { })
Taro.showModal({
title: '要取消该订单吗?',
success: async function (res) {
if (res.confirm) {
let res = await cancelFetchData({id: orderInfo?.orderId})
if(res.success) {
alert.success('取消成功')
onClick?.(1)
} else {
alert.none(res.msg)
}
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
//确认订单
const {fetchData: receiveOrderFetchData} = ReceiveOrderApi()
const receiveOrder = async () => {
console.log('123456')
Taro.showModal({
title: '确定收货?',
success: async function (res) {
if (res.confirm) {
let res = await receiveOrderFetchData({sale_order_id: orderInfo?.orderId})
if(res.success){
onClick?.(6)
alert.success('收货成功')
} else {
alert.error('收货失败')
}
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
//显示更多按钮
const [showMore, setShowMore] = useState(false)
const styleTop = useMemo(() => {
return {top:`-${(orderBtnsShowList.length - 3)*70 + 10}rpx`, left: `-${10}rpx`}
}, [orderBtnsShowList])
return (
<View className={styles.btns_list}>
{(orderBtnsShowList.length > 3)&&<View className={styles.more}>
<Text onClick={() => setShowMore(true)}></Text>
{showMore&&<View className={styles.more_con}>
<View className={styles.more_list} style={styleTop}>
{orderBtnsShowList.map((item, index) => {
return ((index >= 3) &&<View className={styles.more_item} key={item.id} onClick={() => submitBtns(item.id, index)}>{item.label}</View>)
})}
</View>
<View className={styles.more_bg} catchMove onClick={() => setShowMore(false)}></View>
</View>}
</View>}
<View className={styles.list_scroll}>
{orderBtnsShowList.map((item, index) =>
(index < 3)&&<View key={item.id} className={styles.btns_item} onClick={() => submitBtns(item.id, index)}>{item.label}</View>
)}
</View>
</View>
)
})

View File

@ -1,29 +1,29 @@
import { alert } from '@/common/common'
import { AFTER_ORDER_STATUS, ORDER_STATUS, REFUND_STATUS_ORDER, SALE_MODE } from '@/common/enum'
import { Text, View } from '@tarojs/components' import { Text, View } from '@tarojs/components'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import { useRef, memo, useState, useMemo } from 'react' import { memo, useMemo, useRef, useState } from 'react'
import classnames from 'classnames' import classnames from 'classnames'
import styles from './index.module.scss' import styles from './index.module.scss'
import { AFTER_ORDER_STATUS, ORDER_STATUS, REFUND_STATUS_ORDER, SALE_MODE } from '@/common/enum'
import { alert } from '@/common/common'
import { ReturnApplyOrderCancelApi } from '@/api/salesAfterOrder' import { ReturnApplyOrderCancelApi } from '@/api/salesAfterOrder'
import { throttle } from '@/common/util' import { throttle } from '@/common/util'
type Param = { interface Param {
orderInfo: { orderInfo: {
stage: number //售后状态 stage: number // 售后状态
sale_mode: number //订单类型 sale_mode: number // 订单类型
type: number //1退货2退款 type: number // 1退货2退款
return_apply_order_id: number //售后申请单 return_apply_order_id: number // 售后申请单
is_quality_check: true | false //质检结果 is_quality_check: true | false // 质检结果
} }
onClick?: (val: number) => void //点击后触发的事件,返回订单状态 onClick?: (val: number) => void // 点击后触发的事件,返回订单状态
fixedBottom?: true | false //是否固定在底部 fixedBottom?: true | false // 是否固定在底部
} }
export default memo(({ orderInfo, onClick, fixedBottom = true }: Param) => { export default memo(({ orderInfo, onClick, fixedBottom = true }: Param) => {
//售后订单状态 // 售后订单状态
const { ReturnStageApplying, ReturnStageWaitCheck, ReturnStageReturned, ReturnStageQualityCheckPendingRefund, ReturnStageServiceOrderPendingRefund } = const { ReturnStageApplying, ReturnStageWaitCheck, ReturnStageReturned, ReturnStageQualityCheckPendingRefund, ReturnStageServiceOrderPendingRefund }
AFTER_ORDER_STATUS = AFTER_ORDER_STATUS
const { const {
ReturnApplyOrderTypeAdvanceReceiptRefund, // 预收退款 ReturnApplyOrderTypeAdvanceReceiptRefund, // 预收退款
@ -31,15 +31,14 @@ export default memo(({ orderInfo, onClick, fixedBottom = true }: Param) => {
ReturnApplyOrderTypeSalesRefund, // 销售退款 ReturnApplyOrderTypeSalesRefund, // 销售退款
} = REFUND_STATUS_ORDER } = REFUND_STATUS_ORDER
//注册按钮 // 注册按钮
type orderBtnsListParams = { id: number; label: string; validatarFunc: (val: typeof orderInfo) => any } interface orderBtnsListParams { id: number; label: string; validatarFunc: (val: typeof orderInfo) => any }
const orderBtnsList = useRef<orderBtnsListParams[]>([ const orderBtnsList = useRef<orderBtnsListParams[]>([
{ {
id: 8, id: 8,
label: '申请记录', label: '申请记录',
validatarFunc: (orderInfo) => { validatarFunc: (orderInfo) => {
if (orderInfo.sale_mode !== 1) if (orderInfo.sale_mode !== 1) { return [ReturnStageQualityCheckPendingRefund.value, ReturnStageServiceOrderPendingRefund.value, ReturnStageReturned.value].includes(orderInfo.stage) }
return [ReturnStageQualityCheckPendingRefund.value, ReturnStageServiceOrderPendingRefund.value, ReturnStageReturned.value].includes(orderInfo.stage)
return false return false
}, },
}, },
@ -47,8 +46,7 @@ export default memo(({ orderInfo, onClick, fixedBottom = true }: Param) => {
id: 1, id: 1,
label: '取消退货', label: '取消退货',
validatarFunc: (orderInfo) => { validatarFunc: (orderInfo) => {
if (orderInfo?.sale_mode != 1 && orderInfo.type == ReturnApplyOrderTypeReturnForRefund.value) if (orderInfo?.sale_mode != 1 && orderInfo.type == ReturnApplyOrderTypeReturnForRefund.value) { return [ReturnStageApplying.value, ReturnStageWaitCheck.value].includes(orderInfo.stage) }
return [ReturnStageApplying.value, ReturnStageWaitCheck.value].includes(orderInfo.stage)
return false return false
}, },
}, },
@ -70,9 +68,8 @@ export default memo(({ orderInfo, onClick, fixedBottom = true }: Param) => {
id: 6, id: 6,
label: '取消退款', label: '取消退款',
validatarFunc: (orderInfo) => { validatarFunc: (orderInfo) => {
if (orderInfo?.sale_mode != 1 && orderInfo.type != ReturnApplyOrderTypeReturnForRefund.value) if (orderInfo?.sale_mode != 1 && orderInfo.type != ReturnApplyOrderTypeReturnForRefund.value) { return [ReturnStageApplying.value, ReturnStageServiceOrderPendingRefund.value]?.includes(orderInfo.stage) }
return [ReturnStageApplying.value, ReturnStageServiceOrderPendingRefund.value]?.includes(orderInfo.stage) if (orderInfo?.sale_mode == 1) { return [ReturnStageApplying.value].includes(orderInfo.stage) }
if (orderInfo?.sale_mode == 1) return [ReturnStageApplying.value].includes(orderInfo.stage)
return false return false
}, },
}, },
@ -80,52 +77,56 @@ export default memo(({ orderInfo, onClick, fixedBottom = true }: Param) => {
id: 7, id: 7,
label: '退款码单', label: '退款码单',
validatarFunc: (orderInfo) => { validatarFunc: (orderInfo) => {
if (ReturnStageReturned.value == orderInfo.stage && orderInfo?.sale_mode === 0) return true if (ReturnStageReturned.value == orderInfo.stage && orderInfo?.sale_mode === 0) { return true }
return false return false
}, },
}, },
]) ])
//显示的按钮数组 // 显示的按钮数组
const orderBtnsShowList: any[] = useMemo(() => { const orderBtnsShowList: any[] = useMemo(() => {
return orderBtnsList.current.filter((item) => { return orderBtnsList.current.filter((item) => {
return item.validatarFunc(orderInfo) return item.validatarFunc(orderInfo)
}) })
}, [orderInfo]) }, [orderInfo])
//点击按钮操作 // 点击按钮操作
const submitBtns = throttle((val, index) => { const submitBtns = throttle((val, index) => {
if (val == 1) { if (val == 1) {
cancelOrder({ title: '要取消退货吗?', val }) cancelOrder({ title: '要取消退货吗?', val })
} else if (val == 6) { }
else if (val == 6) {
cancelOrder({ title: '要取消退款吗?', val }) cancelOrder({ title: '要取消退款吗?', val })
} else { }
else {
onClick?.(val) onClick?.(val)
} }
}, 600) }, 600)
//取消退货/退款 // 取消退货/退款
const { fetchData: returnApplyOrderCancelFetchData } = ReturnApplyOrderCancelApi() const { fetchData: returnApplyOrderCancelFetchData } = ReturnApplyOrderCancelApi()
const cancelOrder = ({ title = '', val }) => { const cancelOrder = ({ title = '', val }) => {
Taro.showModal({ Taro.showModal({
title, title,
success: async function (res) { async success(res) {
if (res.confirm) { if (res.confirm) {
let res = await returnApplyOrderCancelFetchData({ id: orderInfo?.return_apply_order_id }) const res = await returnApplyOrderCancelFetchData({ id: orderInfo?.return_apply_order_id })
if (res.success) { if (res.success) {
alert.success('取消成功') alert.success('取消成功')
onClick?.(val) onClick?.(val)
} else { }
else {
alert.none(res.msg) alert.none(res.msg)
} }
} else if (res.cancel) { }
else if (res.cancel) {
console.log('用户点击取消') console.log('用户点击取消')
} }
}, },
}) })
} }
//显示更多按钮 // 显示更多按钮
const [showMore, setShowMore] = useState(false) const [showMore, setShowMore] = useState(false)
const styleTop = useMemo(() => { const styleTop = useMemo(() => {
return { top: `-${(orderBtnsShowList.length - 3) * 70 + 10}rpx`, left: `-${10}rpx` } return { top: `-${(orderBtnsShowList.length - 3) * 70 + 10}rpx`, left: `-${10}rpx` }

View File

@ -1,29 +1,29 @@
import { Text, View } from "@tarojs/components"; import { Text, View } from '@tarojs/components'
import { memo, useCallback } from "react"; import { memo, useCallback } from 'react'
import styles from './index.module.scss' import classnames from 'classnames'
import classnames from "classnames"; import styles from './index.module.scss'
import { numberWithCommas } from "@/common/fotmat"; import { numberWithCommas } from '@/common/fotmat'
type Param = { interface Param {
number: number, //数字 number: number // 数字
status: 0|1|2 //0 小型1中型2大 status: 0|1|2 // 0 小型1中型2大
} }
export default memo(({number = 0, status = 1}:Param) => { export default memo(({ number = 0, status = 1 }: Param) => {
const priceDom = useCallback(() => { const priceDom = useCallback(() => {
let res = number.toFixed(2).split('.') const res = number.toFixed(2).split('.')
let int_num = parseInt(res[0]) + '' const int_num = `${parseInt(res[0])}`
let decimals_num = res[1] const decimals_num = res[1]
return (
<>
<Text className={styles.price_text}>¥</Text>
<Text className={styles.price_text}>{numberWithCommas({number:int_num, digit:0})}</Text>
<Text className={styles.price_text}>.{decimals_num}</Text>
</>
)
}, [number])
return ( return (
<View className={classnames(styles.order_price_num, status==1&&styles.emphasis_num, status==2&&styles.emphasis_num_big)} > <>
{priceDom()} <Text className={styles.price_text}>¥</Text>
</View> <Text className={styles.price_text}>{numberWithCommas({ number: int_num, digit: 0 })}</Text>
<Text className={styles.price_text}>.{decimals_num}</Text>
</>
) )
}) }, [number])
return (
<View className={classnames(styles.order_price_num, status == 1 && styles.emphasis_num, status == 2 && styles.emphasis_num_big)} >
{priceDom()}
</View>
)
})

View File

@ -1,19 +1,19 @@
import { Image, Swiper, SwiperItem, View } from '@tarojs/components' import { Image, Swiper, SwiperItem, View } from '@tarojs/components'
import { useEffect, useMemo, useState } from 'react'
import styles from './index.module.scss'
import { goLink } from '@/common/common' import { goLink } from '@/common/common'
import { GetBannerList } from '@/api/banner' import { GetBannerList } from '@/api/banner'
import styles from './index.module.scss'
import { useEffect, useMemo, useState } from 'react'
import { formatImgUrl } from '@/common/fotmat' import { formatImgUrl } from '@/common/fotmat'
type item = { title: string; img: string; url: string; id: number } interface item { title: string; img: string; url: string; id: number }
type params = { interface params {
list?: item[] list?: item[]
swiperOnClick?: (val: item) => void swiperOnClick?: (val: item) => void
style?: Object style?: Object
} }
export default (props: params) => { export default (props: params) => {
let { swiperOnClick, style = {} } = props const { swiperOnClick, style = {} } = props
const [list, setList] = useState<any[]>([]) const [list, setList] = useState<any[]>([])
const { fetchData, state } = GetBannerList() const { fetchData, state } = GetBannerList()
@ -22,15 +22,16 @@ export default (props: params) => {
getData() getData()
}, []) }, [])
const getData = async () => { const getData = async() => {
const res = await fetchData() const res = await fetchData()
setList(res.data?.list) setList(res.data?.list)
} }
const skipTo = (item) => { const skipTo = (item) => {
if (item.jump_type == 2 || item.jump_type == 0) { if (item.jump_type == 2 || item.jump_type == 0) {
goLink(item.link + '&title=' + item.title) goLink(`${item.link}&title=${item.title}`)
} else { }
else {
goLink(item.link) goLink(item.link)
} }
} }
@ -41,12 +42,12 @@ export default (props: params) => {
return ( return (
<View className={styles.swiper_con} style={style}> <View className={styles.swiper_con} style={style}>
<Swiper className={styles.xswiper} indicatorColor='#ccc' indicatorActiveColor='#fff' circular indicatorDots={showDot} autoplay> <Swiper className={styles.xswiper} indicatorColor="#ccc" indicatorActiveColor="#fff" circular indicatorDots={showDot} autoplay>
{list?.map((item) => { {list?.map((item) => {
return ( return (
<SwiperItem key={item.id}> <SwiperItem key={item.id}>
<View className={styles.image_item} onClick={() => skipTo(item)}> <View className={styles.image_item} onClick={() => skipTo(item)}>
<Image mode='aspectFill' src={formatImgUrl(item.prev_view_url, '!w800')}></Image> <Image mode="aspectFill" src={formatImgUrl(item.prev_view_url, '!w800')}></Image>
</View> </View>
</SwiperItem> </SwiperItem>
) )

View File

@ -1,51 +1,50 @@
import { Image, Swiper, SwiperItem, Text, View } from "@tarojs/components" import { Image, Swiper, SwiperItem, Text, View } from '@tarojs/components'
import styles from './index.module.scss' import Taro from '@tarojs/taro'
import { formatImgUrl } from "@/common/fotmat" import styles from './index.module.scss'
import Taro from "@tarojs/taro"; import { formatImgUrl } from '@/common/fotmat'
import { goLink } from "@/common/common"; import { goLink } from '@/common/common'
type params = { interface params {
show?: true|false, show?: true|false
onClose?: () => void onClose?: () => void
} }
export default ({show, onClose}:params) => { export default ({ show, onClose }: params) => {
const onCustomer = async () => { const onCustomer = async() => {
let res = await Taro.showModal({ const res = await Taro.showModal({
title: '是否拨打服务热线', title: '是否拨打服务热线',
confirmText: '拨打', confirmText: '拨打',
content: '(0757) 8270 6695', content: '(0757) 8270 6695',
cancelText: '取消', cancelText: '取消',
}) })
if(res.confirm) { if (res.confirm) {
Taro.makePhoneCall({ Taro.makePhoneCall({
phoneNumber: '(0757)82706695' phoneNumber: '(0757)82706695',
}) })
}
} }
}
const onConfirm = () => { const onConfirm = () => {
onClose?.() onClose?.()
goLink('/pages/bindSalesman/index') goLink('/pages/bindSalesman/index')
} }
return ( return (
<> <>
{show&&<View className={styles.bindSalesman_main}> {show && <View className={styles.bindSalesman_main}>
<View className={styles.bindSalesman_pop}> <View className={styles.bindSalesman_pop}>
<View className={styles.bindSalesman_header}> <View className={styles.bindSalesman_header}>
<Image src={formatImgUrl('/mall/invite_code_top.png', '!w400')} mode="aspectFill"/> <Image src={formatImgUrl('/mall/invite_code_top.png', '!w400')} mode="aspectFill" />
</View> </View>
<View className={styles.bindSalesman_message}> <View className={styles.bindSalesman_message}>
<Text></Text> <Text></Text>
<Text></Text> <Text></Text>
</View> </View>
<View className={styles.bindSalesman_operation}> <View className={styles.bindSalesman_operation}>
<View className={styles.btns} onClick={() => onConfirm()}></View> <View className={styles.btns} onClick={() => onConfirm()}></View>
<View className={styles.btns} onClick={() => onCustomer()}></View> <View className={styles.btns} onClick={() => onCustomer()}></View>
</View> </View>
</View> </View>
<View className={styles.bindSalesman_mask} onClick={onClose}></View> <View className={styles.bindSalesman_mask} onClick={onClose}></View>
</View>} </View>}
</> </>
) )
}
}

View File

@ -1,93 +1,93 @@
import { View } from "@tarojs/components"; import { View } from '@tarojs/components'
import { memo, useEffect, useMemo, useState } from "react"; import Taro, { useDidShow } from '@tarojs/taro'
import Taro, { useDidShow } from "@tarojs/taro"; import { memo, useEffect, useMemo, useState } from 'react'
import {useBluetooth} from "@/use/contextBlueTooth" import classnames from 'classnames'
import SearchInput from "@/components/searchInput"; import styles from './css/linkBlueTooth.module.scss'
import Popup from "@/components/bluetooth/Popup" import { useBluetooth } from '@/use/contextBlueTooth'
import classnames from "classnames"; import SearchInput from '@/components/searchInput'
import styles from "./css/linkBlueTooth.module.scss" import Popup from '@/components/bluetooth/Popup'
import useCheckAuthorize from "@/use/useCheckAuthorize"; import useCheckAuthorize from '@/use/useCheckAuthorize'
export default memo(() => { export default memo(() => {
const {state, init, startScan, connect, disconnect} = useBluetooth() const { state, init, startScan, connect, disconnect } = useBluetooth()
const {check} = useCheckAuthorize({scope:'scope.bluetooth', msg:'请开启小程序蓝牙权限'}) const { check } = useCheckAuthorize({ scope: 'scope.bluetooth', msg: '请开启小程序蓝牙权限' })
useEffect(() => { useEffect(() => {
init() init()
}, []) }, [])
const [linkStatus, setLinkStatus] = useState(1) const [linkStatus, setLinkStatus] = useState(1)
useEffect(() => { useEffect(() => {
if(!state.available) { if (!state.available) {
setLinkStatus(1) setLinkStatus(1)
} else if(state.available&&state.connected?.name) { }
setLinkStatus(3) else if (state.available && state.connected?.name) {
} else { setLinkStatus(3)
setLinkStatus(2) }
} else {
}, [state.available, state.connected]) setLinkStatus(2)
const linkName = useMemo(() => {
return state.connected?.localName||''
}, [state.connected])
//链接设备
const onLinkListen = (item) => {
if(!state.connected&&!state.connecting)
connect(item)
} }
}, [state.available, state.connected])
const [popupShow, setPopupShow] = useState(false) const linkName = useMemo(() => {
//显示设备列表 return state.connected?.localName || ''
const onFindDevice = () => { }, [state.connected])
check().then(res => {
if(linkStatus == 1) { // 链接设备
Taro.showToast({ const onLinkListen = (item) => {
title:'请打开手机蓝牙', if (!state.connected && !state.connecting) { connect(item) }
icon:'none' }
})
} else { const [popupShow, setPopupShow] = useState(false)
setPopupShow(true) // 显示设备列表
onFindEven() const onFindDevice = () => {
} check().then((res) => {
if (linkStatus == 1) {
Taro.showToast({
title: '请打开手机蓝牙',
icon: 'none',
}) })
} }
const onFindEven = () => { else {
if(!state.discovering&&!state.connected&&!state.connecting) setPopupShow(true)
startScan() onFindEven()
} }
})
}
const onFindEven = () => {
if (!state.discovering && !state.connected && !state.connecting) { startScan() }
}
//断开链接 // 断开链接
const onDisconnect = () => { const onDisconnect = () => {
disconnect() disconnect()
setPopupShow(false) setPopupShow(false)
} }
return ( return (
<> <>
<View className={styles.main}> <View className={styles.main}>
<SearchInput title="蓝牙设备" showIcon={true}> <SearchInput title="蓝牙设备" showIcon>
<View className={styles.bluetooth_link} onClick={onFindDevice}> <View className={styles.bluetooth_link} onClick={onFindDevice}>
<View className={classnames(styles.link_status, linkStatus == 3 &&styles.link_statused, linkStatus == 2&&styles.link_statused_no)}></View> <View className={classnames(styles.link_status, linkStatus == 3 && styles.link_statused, linkStatus == 2 && styles.link_statused_no)}></View>
{ {
linkStatus == 1&&<View className={classnames(styles.link_name, styles.link_name_no)}></View>|| linkStatus == 1 && <View className={classnames(styles.link_name, styles.link_name_no)}></View>
linkStatus == 2&&<View className={classnames(styles.link_name,styles.link_name_no_link) }></View>|| || linkStatus == 2 && <View className={classnames(styles.link_name, styles.link_name_no_link)}></View>
linkStatus == 3&&<View className={classnames(styles.link_name)}>{linkName}</View> || linkStatus == 3 && <View className={classnames(styles.link_name)}>{linkName}</View>
} }
</View> </View>
</SearchInput> </SearchInput>
<Popup <Popup
state={state} state={state}
show={popupShow} show={popupShow}
onClose={() => setPopupShow(false)} onClose={() => setPopupShow(false)}
onLink={item => onLinkListen(item)} onLink={item => onLinkListen(item)}
onOff={onDisconnect} onOff={onDisconnect}
onFind={onFindEven} onFind={onFindEven}
/> />
</View> </View>
</> </>
);
)
}) })

View File

@ -1,73 +1,73 @@
import { ScrollView, View } from "@tarojs/components" import { ScrollView, View } from '@tarojs/components'
import { memo, useEffect, useState } from "react" import { memo, useEffect, useState } from 'react'
import Loading from "@/components/loading" import style from './css/popup.module.scss'
import style from "./css/popup.module.scss" import Loading from '@/components/loading'
interface params { interface params {
state: any, state: any
show: Boolean, show: Boolean
onClose: (Boolean) => void, onClose: (Boolean) => void
onLink: (any) => void, onLink: (any) => void
children?: React.ReactNode children?: React.ReactNode
onOff: () => void, onOff: () => void
onFind: () => void, onFind: () => void
} }
export default memo(({state, show=false, onClose, onLink, onOff, onFind}:params) => { export default memo(({ state, show = false, onClose, onLink, onOff, onFind }: params) => {
const [popupShow, setPopupShow] = useState(show) const [popupShow, setPopupShow] = useState(show)
useEffect(() => { useEffect(() => {
setPopupShow(show) setPopupShow(show)
}, [show]) }, [show])
const onCloseListener = () => { const onCloseListener = () => {
onClose(false) onClose(false)
} }
return ( return (
<> <>
{ {
popupShow&&<View className={style.popup}> popupShow && <View className={style.popup}>
<View className={style.content}> <View className={style.content}>
<View className={style.title}></View> <View className={style.title}></View>
<View className={style.list}> <View className={style.list}>
<ScrollView scrollY className={style.scroll}> <ScrollView scrollY className={style.scroll}>
{ {
(state.devices&&state.devices.length > 0)&&state?.devices.map(item => { (state.devices && state.devices.length > 0) && state?.devices.map((item) => {
return ( return (
<View className={style.item} onClick={() => onLink(item)}> <View className={style.item} onClick={() => onLink(item)}>
<View>{item.name}</View> <View>{item.name}</View>
{
(!state.connecting&&!state.connected)&&<View ></View>||
(state.connecting&&item.deviceId == state.connecting.deviceId)&&<View className={style.link_ing}>...</View>||
(state.connected&&item.deviceId == state.connected.deviceId)&&<View className={style.link_success}></View>
}
</View>
)
})||
<View className={style.noDevice}>
{
(!state.discovering)&& <>
<View>,</View>
<View className={style.n_item}>1.</View>
<View className={style.n_item}>2.</View>
<View className={style.n_item}>3.</View>
</>||
<View></View>
}
</View>
}
</ScrollView>
</View>
{ {
state.connected&&<View className={`${style.footer} ${style.footer_off}`} onClick={onOff}></View>|| (!state.connecting && !state.connected) && <View ></View>
(!state.connected&&state.discovering)&&<View className={`${style.footer} ${style.finding}`}><Loading width={30} color='orange'/></View>|| || (state.connecting && item.deviceId == state.connecting.deviceId) && <View className={style.link_ing}>...</View>
<View className={style.footer} onClick={onFind}></View> || (state.connected && item.deviceId == state.connected.deviceId) && <View className={style.link_success}></View>
} }
</View> </View>
<View className={style.mask} onClick={onCloseListener}></View> )
</View> })
|| <View className={style.noDevice}>
{
(!state.discovering) && <>
<View>,</View>
<View className={style.n_item}>1.</View>
<View className={style.n_item}>2.</View>
<View className={style.n_item}>3.</View>
</>
|| <View></View>
}
</View>
}
</ScrollView>
</View>
{
state.connected && <View className={`${style.footer} ${style.footer_off}`} onClick={onOff}></View>
|| (!state.connected && state.discovering) && <View className={`${style.footer} ${style.finding}`}><Loading width={30} color="orange" /></View>
|| <View className={style.footer} onClick={onFind}></View>
} }
</> </View>
) <View className={style.mask} onClick={onCloseListener}></View>
}) </View>
}
</>
)
})

View File

@ -3,20 +3,21 @@ import classnames from 'classnames'
import { forwardRef, useEffect, useImperativeHandle, useState } from 'react' import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'
import styles from './index.module.scss' import styles from './index.module.scss'
type params = { interface params {
onSelect?: () => void //选择触发 onSelect?: () => void // 选择触发
onClose?: () => void //取消触发 onClose?: () => void // 取消触发
status?: false | true //是否选中 status?: false | true // 是否选中
disabled?: false | true //是否禁用 disabled?: false | true // 是否禁用
} }
export default forwardRef(({ onSelect, onClose, status = false, disabled = false }: params, ref) => { export default forwardRef(({ onSelect, onClose, status = false, disabled = false }: params, ref) => {
const [selected, SetSelected] = useState(false) const [selected, SetSelected] = useState(false)
const onSelectEven = () => { const onSelectEven = () => {
if (disabled) return false if (disabled) { return false }
let res = !selected const res = !selected
if (res) { if (res) {
onSelect?.() onSelect?.()
} else { }
else {
onClose?.() onClose?.()
} }
SetSelected(res) SetSelected(res)

View File

@ -1,20 +1,20 @@
import { View, Text } from "@tarojs/components" import { Text, View } from '@tarojs/components'
import { memo } from "react" import { memo } from 'react'
import style from "./index.module.scss" import style from './index.module.scss'
type Params = { interface Params {
onClose?: () => void, onClose?: () => void
styleObj?: Object styleObj?: Object
} }
export default memo(({onClose, styleObj = {}}:Params) => { export default memo(({ onClose, styleObj = {} }: Params) => {
return ( return (
<View <View
style={styleObj} style={styleObj}
className={style.icon_a_cuowuwrong_self} className={style.icon_a_cuowuwrong_self}
onClick={onClose} onClick={onClose}
> >
<Text className={`iconfont icon-qingkong ${style.icon_a_btn}`}></Text> <Text className={`iconfont icon-qingkong ${style.icon_a_btn}`}></Text>
</View> </View>
) )
}) })

View File

@ -1,18 +1,19 @@
import { Input, View } from '@tarojs/components' import { Input, View } from '@tarojs/components'
import { memo, useEffect, useMemo, useRef, useState } from 'react' import { memo, useEffect, useMemo, useRef, useState } from 'react'
import Big from 'big.js' import Big from 'big.js'
import styles from './index.module.scss' import styles from './index.module.scss'
type params = {
minNum?: number //最小值 interface params {
maxNum?: number //最大值 minNum?: number // 最小值
step?: number //步长 maxNum?: number // 最大值
defaultNum?: number //默认值 step?: number // 步长
digits?: number //多少位小数 defaultNum?: number // 默认值
digits?: number // 多少位小数
onChange?: (val: number) => void onChange?: (val: number) => void
onBlue?: (val: number) => void //失去焦点触发 onBlue?: (val: number) => void // 失去焦点触发
onClickBtn?: (val: number) => void onClickBtn?: (val: number) => void
unit?: string unit?: string
disable?: true | false //是否禁用 disable?: true | false // 是否禁用
} }
export default memo((props: params) => { export default memo((props: params) => {
return <Counter {...props}></Counter> return <Counter {...props}></Counter>
@ -20,24 +21,24 @@ export default memo((props: params) => {
function areEqual(prevProps: params, nextProps: params) { function areEqual(prevProps: params, nextProps: params) {
return ( return (
prevProps.defaultNum == nextProps.defaultNum && prevProps.defaultNum == nextProps.defaultNum
prevProps.unit == nextProps.unit && && prevProps.unit == nextProps.unit
prevProps.minNum == nextProps.minNum && && prevProps.minNum == nextProps.minNum
prevProps.maxNum == nextProps.maxNum && && prevProps.maxNum == nextProps.maxNum
prevProps.step == nextProps.step && && prevProps.step == nextProps.step
prevProps.digits == nextProps.digits && prevProps.digits == nextProps.digits
) )
} }
const Counter = memo((props: params) => { const Counter = memo((props: params) => {
let { minNum = 0, maxNum = 10000, step = 1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = '', disable = false } = props const { minNum = 0, maxNum = 10000, step = 1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = '', disable = false } = props
const [value, setValue] = useState<any>({ count: defaultNum }) const [value, setValue] = useState<any>({ count: defaultNum })
// useEffect(() => { // useEffect(() => {
// setValue({ count: defaultNum }) // setValue({ count: defaultNum })
// }, [defaultNum]) // }, [defaultNum])
console.log('1231231231231212') console.log('1231231231231212')
const onPlus = () => { const onPlus = () => {
if (disable) return false if (disable) { return false }
let { count } = value const { count } = value
let num_res = Big(count).add(step).toNumber() let num_res = Big(count).add(step).toNumber()
num_res = num_res >= maxNum ? maxNum : num_res num_res = num_res >= maxNum ? maxNum : num_res
num_res = formatDigits(num_res) num_res = formatDigits(num_res)
@ -46,8 +47,8 @@ const Counter = memo((props: params) => {
onClickBtn?.(parseFloat(num_res)) onClickBtn?.(parseFloat(num_res))
} }
const minus = () => { const minus = () => {
if (disable) return false if (disable) { return false }
let { count } = value const { count } = value
let num_res = Big(count).minus(step).toNumber() let num_res = Big(count).minus(step).toNumber()
num_res = num_res < minNum ? minNum : num_res num_res = num_res < minNum ? minNum : num_res
// setValue({ ...value, count: num_res }) // setValue({ ...value, count: num_res })
@ -55,23 +56,23 @@ const Counter = memo((props: params) => {
onClickBtn?.(parseFloat(num_res)) onClickBtn?.(parseFloat(num_res))
} }
//保留小数 // 保留小数
const formatDigits = (num) => { const formatDigits = (num) => {
num = num + '' num = `${num}`
if (num.includes('.') && digits > 0) { if (num.includes('.') && digits > 0) {
console.log('num::', num.includes('.')) console.log('num::', num.includes('.'))
let res = num.split('.') const res = num.split('.')
let last_num = res[1].substr(0, digits) const last_num = res[1].substr(0, digits)
return res[0] + '.' + last_num return `${res[0]}.${last_num}`
} }
return parseFloat(num) return parseFloat(num)
} }
//检查数据 // 检查数据
const checkData = (val) => { const checkData = (val) => {
let num = parseFloat(val) const num = parseFloat(val)
if (num > maxNum) return maxNum if (num > maxNum) { return maxNum }
if (num < minNum) return minNum if (num < minNum) { return minNum }
return val return val
} }
@ -100,13 +101,14 @@ const Counter = memo((props: params) => {
} }
const onBluerEven = (e) => { const onBluerEven = (e) => {
let num = parseFloat(e.detail.value) const num = parseFloat(e.detail.value)
if (!isNaN(num)) { if (!isNaN(num)) {
let count = formatDigits(num) let count = formatDigits(num)
count = checkData(count) count = checkData(count)
// setValue({ ...value, count }) // setValue({ ...value, count })
onBlue?.(count as number) onBlue?.(count as number)
} else { }
else {
// setValue({ ...value, count: defaultNum }) // setValue({ ...value, count: defaultNum })
onBlue?.(minNum) onBlue?.(minNum)
} }
@ -121,9 +123,9 @@ const Counter = memo((props: params) => {
value={String(props.defaultNum)} value={String(props.defaultNum)}
onInput={onInputEven} onInput={onInputEven}
onBlur={onBluerEven} onBlur={onBluerEven}
type='digit' type="digit"
disabled={disable} disabled={disable}
alwaysEmbed={true} alwaysEmbed
cursorSpacing={150} cursorSpacing={150}
/> />
<View className={styles.unit}>{unit}</View> <View className={styles.unit}>{unit}</View>

View File

@ -1,26 +1,27 @@
import { CustomWrapper, Input, View } from '@tarojs/components' import { CustomWrapper, Input, View } from '@tarojs/components'
import { memo, useEffect, useMemo, useRef, useState } from 'react' import { memo, useEffect, useMemo, useRef, useState } from 'react'
import Big from 'big.js' import Big from 'big.js'
import styles from './index.module.scss' import styles from './index.module.scss'
type params = {
minNum?: number //最小值 interface params {
maxNum?: number //最大值 minNum?: number // 最小值
step?: number //步长 maxNum?: number // 最大值
defaultNum?: number //默认值 step?: number // 步长
digits?: number //多少位小数 defaultNum?: number // 默认值
digits?: number // 多少位小数
onChange?: (val: number) => void onChange?: (val: number) => void
onBlue?: (val: number) => void //失去焦点触发 onBlue?: (val: number) => void // 失去焦点触发
onClickBtn?: (val: number) => void onClickBtn?: (val: number) => void
unit?: string unit?: string
disabled?: true | false //是否禁用 disabled?: true | false // 是否禁用
returnZero?: true | false //少于最小值时是否归0 returnZero?: true | false // 少于最小值时是否归0
} }
export default memo((props: params) => { export default memo((props: params) => {
return <Counter {...props}></Counter> return <Counter {...props}></Counter>
}) })
const Counter = memo((props: params) => { const Counter = memo((props: params) => {
let { const {
minNum = 0, minNum = 0,
maxNum = 10000, maxNum = 10000,
step = 1, step = 1,
@ -38,8 +39,8 @@ const Counter = memo((props: params) => {
setValue({ count: defaultNum }) setValue({ count: defaultNum })
}, [defaultNum]) }, [defaultNum])
const onPlus = () => { const onPlus = () => {
if (disabled) return false if (disabled) { return false }
let count = value.count const count = value.count
let num_res = Big(count).add(step).toNumber() let num_res = Big(count).add(step).toNumber()
num_res = num_res >= maxNum ? maxNum : num_res num_res = num_res >= maxNum ? maxNum : num_res
num_res = formatDigits(num_res) num_res = formatDigits(num_res)
@ -48,12 +49,13 @@ const Counter = memo((props: params) => {
onClickBtn?.(parseFloat(num_res)) onClickBtn?.(parseFloat(num_res))
} }
const minus = () => { const minus = () => {
if (disabled) return false if (disabled) { return false }
let count = value.count const count = value.count
let num_res = Big(count).minus(step).toNumber() let num_res = Big(count).minus(step).toNumber()
if (returnZero) { if (returnZero) {
num_res = num_res < minNum ? 0 : num_res num_res = num_res < minNum ? 0 : num_res
} else { }
else {
num_res = num_res < minNum ? minNum : num_res num_res = num_res < minNum ? minNum : num_res
} }
setValue({ ...value, count: num_res }) setValue({ ...value, count: num_res })
@ -61,15 +63,16 @@ const Counter = memo((props: params) => {
onClickBtn?.(parseFloat(num_res)) onClickBtn?.(parseFloat(num_res))
} }
//保留小数 // 保留小数
const formatDigits = (num) => { const formatDigits = (num) => {
num = num + '' num = `${num}`
if (num.includes('.')) { if (num.includes('.')) {
let res = num.split('.') const res = num.split('.')
if (digits > 0) { if (digits > 0) {
let last_num = res[1].substr(0, digits) const last_num = res[1].substr(0, digits)
return res[0] + '.' + last_num return `${res[0]}.${last_num}`
} else { }
else {
return res[0] return res[0]
} }
} }
@ -77,56 +80,61 @@ const Counter = memo((props: params) => {
return parseFloat(num) return parseFloat(num)
} }
//检查数据 // 检查数据
const checkData = (val) => { const checkData = (val) => {
let num = parseFloat(val) const num = parseFloat(val)
if (num > maxNum) return maxNum if (num > maxNum) { return maxNum }
if (num < minNum) return minNum if (num < minNum) { return minNum }
return val return val
} }
const onInputEven = (e) => { const onInputEven = (e) => {
let res = e.detail.value const res = e.detail.value
if (res === '') { if (res === '') {
onChange?.(minNum) onChange?.(minNum)
} else if (!isNaN(Number(res))) { }
else if (!isNaN(Number(res))) {
let count = formatDigits(res) let count = formatDigits(res)
count = checkData(count) count = checkData(count)
onChange?.(parseFloat(count as string)) onChange?.(parseFloat(count as string))
} else { }
let num = parseFloat(res) else {
const num = parseFloat(res)
if (!isNaN(num)) { if (!isNaN(num)) {
let count = formatDigits(num) let count = formatDigits(num)
count = checkData(count) count = checkData(count)
onChange?.(count as number) onChange?.(count as number)
} else { }
else {
onChange?.(defaultNum) onChange?.(defaultNum)
} }
} }
} }
const onBluerEven = (e) => { const onBluerEven = (e) => {
let num = parseFloat(e.detail.value) const num = parseFloat(e.detail.value)
if (e.detail.value == '') { if (e.detail.value == '') {
onBlue?.(minNum) onBlue?.(minNum)
setValue({ count: minNum }) setValue({ count: minNum })
} else if (!isNaN(num)) { }
else if (!isNaN(num)) {
let count = formatDigits(num) let count = formatDigits(num)
count = checkData(count) count = checkData(count)
setValue({ count }) setValue({ count })
onBlue?.(count as number) onBlue?.(count as number)
} else { }
else {
setValue({ count: minNum }) setValue({ count: minNum })
onBlue?.(minNum) onBlue?.(minNum)
} }
} }
return ( return (
<View className={styles.main} onClick={(e) => e.stopPropagation()}> <View className={styles.main} onClick={e => e.stopPropagation()}>
<View className={styles.reduce} onClick={() => minus()}> <View className={styles.reduce} onClick={() => minus()}>
- -
</View> </View>
<View className={styles.input}> <View className={styles.input}>
<Input type='digit' value={value.count} onInput={onInputEven} onBlur={onBluerEven} disabled={disabled} alwaysEmbed={true} cursorSpacing={150} /> <Input type="digit" value={value.count} onInput={onInputEven} onBlur={onBluerEven} disabled={disabled} alwaysEmbed cursorSpacing={150} />
<View className={styles.unit}>{unit}</View> <View className={styles.unit}>{unit}</View>
</View> </View>
<View className={styles.plus} onClick={() => onPlus()}> <View className={styles.plus} onClick={() => onPlus()}>

View File

@ -1,17 +1,17 @@
import { View } from "@tarojs/components"; import { View } from '@tarojs/components'
import { memo } from "react"; import { memo } from 'react'
import styles from './index.module.scss' import styles from './index.module.scss'
export default memo(() => { export default memo(() => {
return ( return (
<> <>
<View className={styles.load_box}> <View className={styles.load_box}>
<View className={styles.load_box_item}></View> <View className={styles.load_box_item}></View>
<View className={styles.load_box_item}></View> <View className={styles.load_box_item}></View>
<View className={styles.load_box_item}></View> <View className={styles.load_box_item}></View>
<View className={styles.load_box_item}></View> <View className={styles.load_box_item}></View>
<View className={styles.load_box_item}></View> <View className={styles.load_box_item}></View>
</View> </View>
</> </>
) )
}) })

View File

@ -1,64 +1,65 @@
import { Text, View } from "@tarojs/components" import { Text, View } from '@tarojs/components'
import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useState } from "react" import Taro from '@tarojs/taro'
import {formatKbPrice} from '@/common/common' import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useState } from 'react'
import classnames from "classnames"; import classnames from 'classnames'
import styles from './index.module.scss' import AmountShow from '../amountShow'
import Taro from "@tarojs/taro"; import styles from './index.module.scss'
import AmountShow from "../amountShow"; import { formatKbPrice } from '@/common/common'
type Param = { interface Param {
style?: Object, style?: Object
number?: number|string, number?: number|string
title?: string, title?: string
titleStatus?: true|false, //true 标题加大加深 titleStatus?: true|false // true 标题加大加深
numberStatus?: 0|1|2, //数字尺寸 numberStatus?: 0|1|2 // 数字尺寸
messageTitle?: string, messageTitle?: string
messageWidth?: number, messageWidth?: number
messageShow?: true|false, messageShow?: true|false
numberFormat?: 'number'|'text' //数字还是字符串 numberFormat?: 'number'|'text' // 数字还是字符串
} }
export default memo(({number = 0, titleStatus = true, title = '', messageTitle = '', numberStatus = 1, messageWidth = 430, messageShow = false, numberFormat = 'number'}:Param) => { export default memo(({ number = 0, titleStatus = true, title = '', messageTitle = '', numberStatus = 1, messageWidth = 430, messageShow = false, numberFormat = 'number' }: Param) => {
const [show, setShow] = useState(messageShow) const [show, setShow] = useState(messageShow)
const onClose = () => { const onClose = () => {
setShow(false) setShow(false)
} }
const openShow = () => [ const openShow = () => [
setShow(true) setShow(true),
] ]
const [style, setStyle] = useState<{top: string}>() const [style, setStyle] = useState<{ top: string }>()
useEffect(() => { useEffect(() => {
if(show) { if (show) {
getDomDes('#message') getDomDes('#message')
} else { }
setStyle(() => ({top: '0'})) else {
} setStyle(() => ({ top: '0' }))
}, [show])
//设置弹出层高度
const getDomDes = (id) => {
setTimeout(() => {
let query = Taro.createSelectorQuery();
query.select(id).boundingClientRect(rect=>{
let height = rect.height * 2 + 15;
setStyle((e) => ({...e, top: `-${height}rpx`, opacity: 1}))
}).exec();
}, 0)
} }
return ( }, [show])
<> // 设置弹出层高度
<View className={styles.order_price}> const getDomDes = (id) => {
<View className={classnames(styles.order_price_text, titleStatus&&styles.emphasis)} onClick={() => openShow()}> setTimeout(() => {
<Text>{title}</Text> const query = Taro.createSelectorQuery()
<View className={styles.iconfont_msg}> query.select(id).boundingClientRect((rect) => {
{show&&<View style={{...style, width: `${messageWidth}rpx`}} id='message' className={classnames(styles.message)}>{messageTitle}</View>} const height = rect.height * 2 + 15
<Text className={classnames(styles.miconfont, 'iconfont icon-zhushi')}></Text> setStyle(e => ({ ...e, top: `-${height}rpx`, opacity: 1 }))
</View> }).exec()
</View> }, 0)
{numberFormat == 'number' && <AmountShow status={numberStatus} number={(number as number / 100)}/>} }
{(numberFormat == 'text') && <View className={styles.refund_destination}>{number}</View>} return (
{show&&<View className={styles.close} catchMove onClick={onClose}></View>} <>
</View> <View className={styles.order_price}>
</> <View className={classnames(styles.order_price_text, titleStatus && styles.emphasis)} onClick={() => openShow()}>
) <Text>{title}</Text>
}) <View className={styles.iconfont_msg}>
{show && <View style={{ ...style, width: `${messageWidth}rpx` }} id="message" className={classnames(styles.message)}>{messageTitle}</View>}
<Text className={classnames(styles.miconfont, 'iconfont icon-zhushi')}></Text>
</View>
</View>
{numberFormat == 'number' && <AmountShow status={numberStatus} number={(number as number / 100)} />}
{(numberFormat == 'text') && <View className={styles.refund_destination}>{number}</View>}
{show && <View className={styles.close} catchMove onClick={onClose}></View>}
</View>
</>
)
})

View File

@ -1,17 +1,18 @@
import { GetProductKindListApi } from '@/api/material'
import Popup, { Params as PopuParams } from '@/components/popup'
import { Input, ScrollView, Text, Textarea, View } from '@tarojs/components' import { Input, ScrollView, Text, Textarea, View } from '@tarojs/components'
import { useDidShow } from '@tarojs/taro' import { useDidShow } from '@tarojs/taro'
import classnames from 'classnames' import classnames from 'classnames'
import { memo, useEffect, useRef, useState } from 'react' import { memo, useEffect, useRef, useState } from 'react'
import styles from './index.module.scss' import styles from './index.module.scss'
import Popup from '@/components/popup'
import type { Params as PopuParams } from '@/components/popup'
import { GetProductKindListApi } from '@/api/material'
type params = { type params = {
onFiltr?: (val: object) => void //确定搜索 onFiltr?: (val: object) => void // 确定搜索
onRest?: (val: Object) => void //重置 onRest?: (val: Object) => void // 重置
} & PopuParams } & PopuParams
export default memo(({ onClose, onFiltr, show = false, onRest }: params) => { export default memo(({ onClose, onFiltr, show = false, onRest }: params) => {
//搜索条件 // 搜索条件
const [filterObj, setFilterObj] = useState({ const [filterObj, setFilterObj] = useState({
seriesName: '', seriesName: '',
seriesId: '', seriesId: '',
@ -22,11 +23,11 @@ export default memo(({ onClose, onFiltr, show = false, onRest }: params) => {
const selectFieldValue = useRef({ width: '幅宽', weight: '克重', element: '成分', seriesName: '系列' }) const selectFieldValue = useRef({ width: '幅宽', weight: '克重', element: '成分', seriesName: '系列' })
//获取系列 // 获取系列
const { fetchData: kindFetchData } = GetProductKindListApi() const { fetchData: kindFetchData } = GetProductKindListApi()
const [kindList, setKindList] = useState<any[]>([]) const [kindList, setKindList] = useState<any[]>([])
const getCategoryList = async () => { const getCategoryList = async() => {
let { data } = await kindFetchData() const { data } = await kindFetchData()
setKindList(data.list) setKindList(data.list)
} }
@ -34,7 +35,7 @@ export default memo(({ onClose, onFiltr, show = false, onRest }: params) => {
show && getCategoryList() show && getCategoryList()
}, [show]) }, [show])
//切换系列 // 切换系列
const changeKind = (e) => { const changeKind = (e) => {
setFilterObj({ ...filterObj, seriesId: e.id, seriesName: e.name }) setFilterObj({ ...filterObj, seriesId: e.id, seriesName: e.name })
} }
@ -43,9 +44,9 @@ export default memo(({ onClose, onFiltr, show = false, onRest }: params) => {
onClose?.() onClose?.()
} }
//重置数据 // 重置数据
const onRestEven = () => { const onRestEven = () => {
let res = { const res = {
seriesName: '', seriesName: '',
seriesId: '', seriesId: '',
width: '', width: '',
@ -57,20 +58,20 @@ export default memo(({ onClose, onFiltr, show = false, onRest }: params) => {
onClose?.() onClose?.()
} }
//提交搜索 // 提交搜索
const onVerify = () => { const onVerify = () => {
onFiltr?.({ data: filterObj, field: selectFieldValue.current }) onFiltr?.({ data: filterObj, field: selectFieldValue.current })
onClose?.() onClose?.()
} }
//获取幅宽或克重输入值或成分 // 获取幅宽或克重输入值或成分
const setFieldData = (e, field) => { const setFieldData = (e, field) => {
filterObj[field] = e.detail.value filterObj[field] = e.detail.value
setFilterObj({ ...filterObj }) setFilterObj({ ...filterObj })
} }
return ( return (
<Popup position='right' show={show} showTitle={false} onClose={() => onCloseEven()} showIconButton={true}> <Popup position="right" show={show} showTitle={false} onClose={() => onCloseEven()} showIconButton>
<View className={styles.popup_main}> <View className={styles.popup_main}>
<View className={styles.popup_title}></View> <View className={styles.popup_title}></View>
<ScrollView scrollY className={styles.scroll}> <ScrollView scrollY className={styles.scroll}>
@ -78,11 +79,12 @@ export default memo(({ onClose, onFiltr, show = false, onRest }: params) => {
<View className={styles.popup_filter_item}> <View className={styles.popup_filter_item}>
<View className={styles.title}></View> <View className={styles.title}></View>
<View className={styles.btn_list}> <View className={styles.btn_list}>
{kindList.map((item) => ( {kindList.map(item => (
<View <View
key={item.id} key={item.id}
onClick={() => changeKind(item)} onClick={() => changeKind(item)}
className={classnames(styles.btn_item, filterObj.seriesId == item.id && styles.select_btn_item)}> className={classnames(styles.btn_item, filterObj.seriesId == item.id && styles.select_btn_item)}
>
{item.name} {item.name}
</View> </View>
))} ))}
@ -93,12 +95,12 @@ export default memo(({ onClose, onFiltr, show = false, onRest }: params) => {
<View className={styles.btn_list_input}> <View className={styles.btn_list_input}>
<View className={styles.btn_width}> <View className={styles.btn_width}>
<Input <Input
alwaysEmbed={true} alwaysEmbed
cursorSpacing={150} cursorSpacing={150}
value={filterObj.width} value={filterObj.width}
onBlur={(e) => setFieldData(e, 'width')} onBlur={e => setFieldData(e, 'width')}
placeholder='请输入幅宽' placeholder="请输入幅宽"
placeholderStyle='font-size: 26rpx' placeholderStyle="font-size: 26rpx"
/> />
</View> </View>
<View className={styles.unit}>cm</View> <View className={styles.unit}>cm</View>
@ -110,11 +112,11 @@ export default memo(({ onClose, onFiltr, show = false, onRest }: params) => {
<View className={styles.btn_width}> <View className={styles.btn_width}>
<Input <Input
value={filterObj.weight} value={filterObj.weight}
alwaysEmbed={true} alwaysEmbed
cursorSpacing={150} cursorSpacing={150}
onBlur={(e) => setFieldData(e, 'weight')} onBlur={e => setFieldData(e, 'weight')}
placeholder='请输入克重' placeholder="请输入克重"
placeholderStyle='font-size: 26rpx' placeholderStyle="font-size: 26rpx"
/> />
</View> </View>
<View className={styles.unit}>kg</View> <View className={styles.unit}>kg</View>
@ -123,11 +125,11 @@ export default memo(({ onClose, onFiltr, show = false, onRest }: params) => {
<View className={styles.popup_filter_item}> <View className={styles.popup_filter_item}>
<View className={styles.title}></View> <View className={styles.title}></View>
<View className={styles.btn_list_element}> <View className={styles.btn_list_element}>
<Textarea placeholder='请输入' cursorSpacing={60} value={filterObj.element} onInput={(e) => setFieldData(e, 'element')} /> <Textarea placeholder="请输入" cursorSpacing={60} value={filterObj.element} onInput={e => setFieldData(e, 'element')} />
</View> </View>
</View> </View>
<View className='common_safe_area_y'></View> <View className="common_safe_area_y"></View>
</View> </View>
</ScrollView> </ScrollView>
<View className={styles.btns_con}> <View className={styles.btns_con}>

View File

@ -1,16 +1,17 @@
import { GetProductKindListApi } from '@/api/material'
import Popup, { Params as PopuParams } from '@/components/popup'
import { Input, ScrollView, Text, Textarea, View } from '@tarojs/components' import { Input, ScrollView, Text, Textarea, View } from '@tarojs/components'
import { useDidShow } from '@tarojs/taro' import { useDidShow } from '@tarojs/taro'
import classnames from 'classnames' import classnames from 'classnames'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import styles from './index.module.scss' import styles from './index.module.scss'
import Popup from '@/components/popup'
import type { Params as PopuParams } from '@/components/popup'
import { GetProductKindListApi } from '@/api/material'
type params = { type params = {
onFiltr?: (val: object) => void onFiltr?: (val: object) => void
} & PopuParams } & PopuParams
export default ({ onClose, onFiltr, show = false }: params) => { export default ({ onClose, onFiltr, show = false }: params) => {
//搜索条件 // 搜索条件
const [filterObj, setFilterObj] = useState({ const [filterObj, setFilterObj] = useState({
seriesId: '', seriesId: '',
minWidth: '', minWidth: '',
@ -20,11 +21,11 @@ export default ({ onClose, onFiltr, show = false }: params) => {
element: '', element: '',
}) })
//获取系列 // 获取系列
const { fetchData: kindFetchData } = GetProductKindListApi() const { fetchData: kindFetchData } = GetProductKindListApi()
const [kindList, setKindList] = useState<any[]>([]) const [kindList, setKindList] = useState<any[]>([])
const getCategoryList = async () => { const getCategoryList = async() => {
let { data } = await kindFetchData() const { data } = await kindFetchData()
setKindList(data.list) setKindList(data.list)
} }
@ -32,7 +33,7 @@ export default ({ onClose, onFiltr, show = false }: params) => {
show && getCategoryList() show && getCategoryList()
}, [show]) }, [show])
//切换系列 // 切换系列
const changeKind = (e) => { const changeKind = (e) => {
setFilterObj({ ...filterObj, seriesId: e.id }) setFilterObj({ ...filterObj, seriesId: e.id })
} }
@ -62,21 +63,22 @@ export default ({ onClose, onFiltr, show = false }: params) => {
const setNumber = (e, field) => { const setNumber = (e, field) => {
console.log(e) console.log(e)
let num = parseFloat(e.detail.value) const num = parseFloat(e.detail.value)
if (isNaN(num)) { if (isNaN(num)) {
filterObj[field] = null filterObj[field] = null
} else { }
else {
filterObj[field] = parseFloat(num.toFixed(2)) filterObj[field] = parseFloat(num.toFixed(2))
} }
setFilterObj({ ...filterObj }) setFilterObj({ ...filterObj })
} }
const setElement = (e) => { const setElement = (e) => {
let res = e.detail.value const res = e.detail.value
setFilterObj({ ...filterObj, element: res }) setFilterObj({ ...filterObj, element: res })
} }
return ( return (
<Popup position='right' show={show} showTitle={false} onClose={() => onCloseEven()} showIconButton={true}> <Popup position="right" show={show} showTitle={false} onClose={() => onCloseEven()} showIconButton>
<View className={styles.popup_main}> <View className={styles.popup_main}>
<View className={styles.popup_title}></View> <View className={styles.popup_title}></View>
<ScrollView scrollY className={styles.scroll}> <ScrollView scrollY className={styles.scroll}>
@ -84,11 +86,12 @@ export default ({ onClose, onFiltr, show = false }: params) => {
<View className={styles.popup_filter_item}> <View className={styles.popup_filter_item}>
<View className={styles.title}></View> <View className={styles.title}></View>
<View className={styles.btn_list}> <View className={styles.btn_list}>
{kindList.map((item) => ( {kindList.map(item => (
<View <View
key={item.id} key={item.id}
onClick={() => changeKind(item)} onClick={() => changeKind(item)}
className={classnames(styles.btn_item, filterObj.seriesId == item.id && styles.select_btn_item)}> className={classnames(styles.btn_item, filterObj.seriesId == item.id && styles.select_btn_item)}
>
{item.name} {item.name}
</View> </View>
))} ))}
@ -99,13 +102,13 @@ export default ({ onClose, onFiltr, show = false }: params) => {
<View className={styles.btn_list_input}> <View className={styles.btn_list_input}>
<View className={styles.btn_width}> <View className={styles.btn_width}>
<Input <Input
alwaysEmbed={true} alwaysEmbed
cursorSpacing={150} cursorSpacing={150}
value={filterObj.minWidth} value={filterObj.minWidth}
type='digit' type="digit"
onBlur={(e) => setNumber(e, 'minWidth')} onBlur={e => setNumber(e, 'minWidth')}
placeholder='请输入幅宽' placeholder="请输入幅宽"
placeholderStyle='font-size: 26rpx' placeholderStyle="font-size: 26rpx"
/> />
</View> </View>
<View className={styles.unit}>cm</View> <View className={styles.unit}>cm</View>
@ -116,24 +119,24 @@ export default ({ onClose, onFiltr, show = false }: params) => {
<View className={styles.btn_list_input}> <View className={styles.btn_list_input}>
<View className={styles.btn_width}> <View className={styles.btn_width}>
<Input <Input
type='digit' type="digit"
value={filterObj.minWeight} value={filterObj.minWeight}
onBlur={(e) => setNumber(e, 'minWeight')} onBlur={e => setNumber(e, 'minWeight')}
placeholder='自定义最低值' placeholder="自定义最低值"
placeholderStyle='font-size: 26rpx' placeholderStyle="font-size: 26rpx"
alwaysEmbed={true} alwaysEmbed
cursorSpacing={150} cursorSpacing={150}
/> />
</View> </View>
<Text></Text> <Text></Text>
<View className={styles.btn_width}> <View className={styles.btn_width}>
<Input <Input
type='digit' type="digit"
value={filterObj.maxWeight} value={filterObj.maxWeight}
onBlur={(e) => setNumber(e, 'maxWeight')} onBlur={e => setNumber(e, 'maxWeight')}
placeholder='自定义最高值' placeholder="自定义最高值"
placeholderStyle='font-size: 26rpx' placeholderStyle="font-size: 26rpx"
alwaysEmbed={true} alwaysEmbed
cursorSpacing={150} cursorSpacing={150}
/> />
</View> </View>
@ -143,11 +146,11 @@ export default ({ onClose, onFiltr, show = false }: params) => {
<View className={styles.popup_filter_item}> <View className={styles.popup_filter_item}>
<View className={styles.title}></View> <View className={styles.title}></View>
<View className={styles.btn_list_element}> <View className={styles.btn_list_element}>
<Textarea placeholder='请输入' cursorSpacing={60} value={filterObj.element} onInput={(e) => setElement(e)} /> <Textarea placeholder="请输入" cursorSpacing={60} value={filterObj.element} onInput={e => setElement(e)} />
</View> </View>
</View> </View>
<View className='common_safe_area_y'></View> <View className="common_safe_area_y"></View>
</View> </View>
</ScrollView> </ScrollView>
<View className={styles.btns_con}> <View className={styles.btns_con}>

View File

@ -1,117 +1,118 @@
import { ScrollView, View } from "@tarojs/components" import { ScrollView, View } from '@tarojs/components'
import { memo, ReactNode, useMemo, useState } from "react" import type { ReactNode } from 'react'
import style from "./index.module.scss" import { memo, useMemo, useState } from 'react'
import DotLoading from "@/components/dotLoading" import LoadingCard from '../loadingCard'
import LoadingCard from "../loadingCard" import style from './index.module.scss'
import DotLoading from '@/components/dotLoading'
export type StatusParam = 0|1|2|3 export type StatusParam = 0|1|2|3
type Params = { interface Params {
styleObj?: Object, styleObj?: Object
selfonScrollToLower?: () => void, selfonScrollToLower?: () => void
hasMore?: false|true, hasMore?: false|true
moreStatus?: false|true, moreStatus?: false|true
statusMore?: StatusParam //0:数据从无到有加载数据1没有任何数据 2下拉加载3下拉没有数据 statusMore?: StatusParam // 0:数据从无到有加载数据1没有任何数据 2下拉加载3下拉没有数据
children?: ReactNode, children?: ReactNode
lowerThresholdNum?: number, lowerThresholdNum?: number
selfOnScrollToUpper?:() => void selfOnScrollToUpper?: () => void
selfOnScroll?:(val:any) => void selfOnScroll?: (val: any) => void
selfOnRefresherPulling?: () => void selfOnRefresherPulling?: () => void
selfOnRefresherRefresh?: () => void selfOnRefresherRefresh?: () => void
selfOnRefresherRestore?: () => void selfOnRefresherRestore?: () => void
selfOnRefresherAbort?: () => void selfOnRefresherAbort?: () => void
paddingBottom?: number, paddingBottom?: number
refresherTriggered?: true|false, refresherTriggered?: true|false
refresherEnabled?: true|false, refresherEnabled?: true|false
} }
export default memo(({ export default memo(({
styleObj, styleObj,
selfonScrollToLower, selfonScrollToLower,
selfOnScrollToUpper, selfOnScrollToUpper,
selfOnScroll, selfOnScroll,
selfOnRefresherPulling, selfOnRefresherPulling,
selfOnRefresherRefresh, selfOnRefresherRefresh,
selfOnRefresherRestore, selfOnRefresherRestore,
selfOnRefresherAbort, selfOnRefresherAbort,
hasMore=true, hasMore = true,
children, children,
lowerThresholdNum = 5, lowerThresholdNum = 5,
paddingBottom = 0, paddingBottom = 0,
refresherTriggered = false, refresherTriggered = false,
refresherEnabled = false, refresherEnabled = false,
moreStatus = true, moreStatus = true,
statusMore = 0 statusMore = 0,
}: Params) => { }: Params) => {
const scrollToLower = () => { const scrollToLower = () => {
selfonScrollToLower?.() selfonScrollToLower?.()
} }
const scrollToUpper = () => { const scrollToUpper = () => {
selfOnScrollToUpper?.() selfOnScrollToUpper?.()
} }
const scroll = (e) => { const scroll = (e) => {
selfOnScroll?.(e) selfOnScroll?.(e)
} }
const refresherPulling = () => { const refresherPulling = () => {
selfOnRefresherPulling?.() selfOnRefresherPulling?.()
} }
const refresherRefresh = () => { const refresherRefresh = () => {
selfOnRefresherRefresh?.() selfOnRefresherRefresh?.()
} }
const refresherRestore = () => { const refresherRestore = () => {
selfOnRefresherRestore?.() selfOnRefresherRestore?.()
} }
const refresherAbort = () => { const refresherAbort = () => {
selfOnRefresherAbort?.() selfOnRefresherAbort?.()
} }
//返回顶部 // 返回顶部
const scrollTop = useMemo(() => { const scrollTop = useMemo(() => {
if(statusMore == 0) { if (statusMore == 0) {
return 0.1 return 0.1
} }
},[statusMore]) }, [statusMore])
return ( return (
<> <>
<ScrollView <ScrollView
style={styleObj} style={styleObj}
className={style.scroll_main} className={style.scroll_main}
scrollY scrollY
onScrollToLower={() => scrollToLower()} onScrollToLower={() => scrollToLower()}
onScrollToUpper={() => scrollToUpper()} onScrollToUpper={() => scrollToUpper()}
onScroll={(e) => scroll(e)} onScroll={e => scroll(e)}
lowerThreshold={lowerThresholdNum} lowerThreshold={lowerThresholdNum}
refresherEnabled = {refresherEnabled} refresherEnabled={refresherEnabled}
refresherTriggered = {refresherTriggered} refresherTriggered={refresherTriggered}
onRefresherPulling = {() => refresherPulling()} onRefresherPulling={() => refresherPulling()}
onRefresherRefresh = {() => refresherRefresh()} onRefresherRefresh={() => refresherRefresh()}
onRefresherRestore = {() => refresherRestore()} onRefresherRestore={() => refresherRestore()}
onRefresherAbort = {() => refresherAbort()} onRefresherAbort={() => refresherAbort()}
refresherBackground ='#F8F8F8' refresherBackground="#F8F8F8"
scrollTop={scrollTop} scrollTop={scrollTop}
> >
{!moreStatus&&<> {!moreStatus && <>
<View style={{paddingBottom:paddingBottom + 'rpx'}} className={style.scrollViewCon}> <View style={{ paddingBottom: `${paddingBottom}rpx` }} className={style.scrollViewCon}>
{children} {children}
</View> </View>
</>||
<>
{(statusMore == 2 || statusMore == 3)&&<View style={{paddingBottom:paddingBottom + 'rpx'}} className={style.scrollViewCon}>
{children}
<View className={style.infinite_scroll}>
{
(statusMore == 2)&&<View className={style.loading_more}><DotLoading/></View>||
<View className={style.noMore}></View>
}
</View>
</View>
}
{(statusMore == 0)&&<LoadingCard/>}
{(statusMore == 1)&&<LoadingCard loadingIcon={false} title="暂无数据"/>}
</>}
<View className="common_safe_area_y"></View>
</ScrollView>
</> </>
) || <>
}) {(statusMore == 2 || statusMore == 3) && <View style={{ paddingBottom: `${paddingBottom}rpx` }} className={style.scrollViewCon}>
{children}
<View className={style.infinite_scroll}>
{
(statusMore == 2) && <View className={style.loading_more}><DotLoading /></View>
|| <View className={style.noMore}></View>
}
</View>
</View>
}
{(statusMore == 0) && <LoadingCard />}
{(statusMore == 1) && <LoadingCard loadingIcon={false} title="暂无数据" />}
</>}
<View className="common_safe_area_y"></View>
</ScrollView>
</>
)
})

View File

@ -1,25 +1,22 @@
import { View } from "@tarojs/components" import { View } from '@tarojs/components'
import { memo, useMemo } from "react" import { memo, useMemo } from 'react'
import style from './index.module.scss' import style from './index.module.scss'
export default memo(({width=60, color='#6190e8'}:{width?:number, color?:string}) => {
const styleObj = useMemo(() => { export default memo(({ width = 60, color = '#6190e8' }: { width?: number; color?: string }) => {
let obj = {} const styleObj = useMemo(() => {
if(width > 0) let obj = {}
obj = {width: width + 'rpx', height:width + 'rpx'} if (width > 0) { obj = { width: `${width}rpx`, height: `${width}rpx` } }
if(color) if (color) { obj = { ...obj, borderColor: `${color} transparent transparent` } }
obj = {...obj, borderColor: color+' transparent transparent'} return obj
return obj }, [width, color])
console.log('loading:::')
}, [width, color]) return (
console.log('loading:::') <View className={style.loading}
return ( style={styleObj}
<View className={style.loading} >
style={styleObj} <View style={styleObj} className={style.loading__ring}></View>
> <View style={styleObj} className={style.loading__ring}></View>
<View style={styleObj} className={style.loading__ring}></View> <View style={styleObj} className={style.loading__ring}></View>
<View style={styleObj} className={style.loading__ring}></View> </View>
<View style={styleObj} className={style.loading__ring}></View> )
</View> })
)
})

View File

@ -1,25 +1,25 @@
import { View } from "@tarojs/components" import { View } from '@tarojs/components'
import Loading from "@/components/loading" import { memo } from 'react'
import style from "./index.module.scss" import style from './index.module.scss'
import { memo } from "react"; import Loading from '@/components/loading'
type Params = { interface Params {
styleLoading?: Object, styleLoading?: Object
title?: string, title?: string
loadingIcon?: false|true loadingIcon?: false|true
} }
export default memo(({ export default memo(({
styleLoading = {}, styleLoading = {},
title = "加载中...", //显示的文字 title = '加载中...', // 显示的文字
loadingIcon = true //是否显示加载图标 loadingIcon = true, // 是否显示加载图标
}:Params) => { }: Params) => {
console.log('loadingCard:::') console.log('loadingCard:::')
return ( return (
<> <>
<View className={style.loadingCard_main}> <View className={style.loadingCard_main}>
{loadingIcon&&<Loading/>} {loadingIcon && <Loading />}
<View className={style.loading_text}>{title}</View> <View className={style.loading_text}>{title}</View>
</View> </View>
</> </>
) )
}) })

View File

@ -1,18 +1,19 @@
import { MovableArea, MovableView, View } from '@tarojs/components' import { MovableArea, MovableView, View } from '@tarojs/components'
import Taro, { useDidShow, useReady, useRouter } from '@tarojs/taro' import Taro, { useDidShow, useReady, useRouter } from '@tarojs/taro'
import { ReactElement, useEffect, useLayoutEffect, useRef, useState } from 'react' import type { ReactElement } from 'react'
import { useEffect, useLayoutEffect, useRef, useState } from 'react'
import classnames from 'classnames' import classnames from 'classnames'
import styles from './index.module.scss' import styles from './index.module.scss'
import { GetShoppingCartApi } from '@/api/shopCart' import { GetShoppingCartApi } from '@/api/shopCart'
import useCommonData from '@/use/useCommonData' import useCommonData from '@/use/useCommonData'
import { useSelector } from '@/reducers/hooks' import { useSelector } from '@/reducers/hooks'
type param = { interface param {
children?: ReactElement | null children?: ReactElement | null
onClick?: () => void onClick?: () => void
} }
export default ({ children = null, onClick }: param) => { export default ({ children = null, onClick }: param) => {
//获取购物车数据数量 // 获取购物车数据数量
const { getShopCount, commonData } = useCommonData() const { getShopCount, commonData } = useCommonData()
const [screenHeight, setScreenHeight] = useState(0) const [screenHeight, setScreenHeight] = useState(0)
@ -21,7 +22,7 @@ export default ({ children = null, onClick }: param) => {
useLayoutEffect(() => { useLayoutEffect(() => {
const res = Taro.getSystemInfoSync() const res = Taro.getSystemInfoSync()
if (res.screenHeight) { if (res.screenHeight) {
let ratio = 750 / res.screenWidth const ratio = 750 / res.screenWidth
setScreenHeight(res.screenHeight * ratio - 460) setScreenHeight(res.screenHeight * ratio - 460)
screenWidthRef.current = res.screenWidth / 2 screenWidthRef.current = res.screenWidth / 2
} }
@ -40,11 +41,12 @@ export default ({ children = null, onClick }: param) => {
<MovableView <MovableView
onClick={onClick} onClick={onClick}
className={styles.moveBtn} className={styles.moveBtn}
direction='all' direction="all"
inertia={true} inertia
x='630rpx' x="630rpx"
y={screenHeight + 'rpx'} y={`${screenHeight}rpx`}
onTouchEnd={(e) => dragEnd(e)}> onTouchEnd={e => dragEnd(e)}
>
<View className={classnames('iconfont', 'icon-gouwuche', styles.shop_icon)}></View> <View className={classnames('iconfont', 'icon-gouwuche', styles.shop_icon)}></View>
{commonData.shopCount > 0 && <View className={styles.product_num}>{commonData.shopCount > 99 ? '99+' : commonData.shopCount}</View>} {commonData.shopCount > 0 && <View className={styles.product_num}>{commonData.shopCount > 99 ? '99+' : commonData.shopCount}</View>}
</MovableView> </MovableView>

View File

@ -1,202 +1,205 @@
import { CancelOrderApi, ReceiveOrderApi } from "@/api/order" import { ScrollView, Text, View } from '@tarojs/components'
import { alert } from "@/common/common" import Taro from '@tarojs/taro'
import { ORDER_STATUS, SALE_MODE } from "@/common/enum" import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { ScrollView, Text, View } from "@tarojs/components" import styles from './index.module.scss'
import Taro from "@tarojs/taro" import { ORDER_STATUS, SALE_MODE } from '@/common/enum'
import { useCallback, useRef, memo, useState, useEffect, useMemo } from "react" import { alert } from '@/common/common'
import styles from './index.module.scss' import { CancelOrderApi, ReceiveOrderApi } from '@/api/order'
type Param = { interface Param {
orderInfo: { orderInfo: {
status: number, //订单状态 status: number // 订单状态
orderId: number, //订单id orderId: number // 订单id
actual_amount: number, //实付金额 actual_amount: number // 实付金额
wait_pay_amount: number, //待付金额 wait_pay_amount: number // 待付金额
sale_mode: number //订单类型 sale_mode: number // 订单类型
}|null, }|null
onClick?: (val: number) => void //点击后触发的事件,返回订单状态 onClick?: (val: number) => void // 点击后触发的事件,返回订单状态
} }
export default memo(({orderInfo, onClick}:Param) => { export default memo(({ orderInfo, onClick }: Param) => {
//订单状态枚举 // 订单状态枚举
const { const {
SaleOrderStatusBooking, SaleOrderStatusBooking,
SaleOrderStatusArranging, SaleOrderStatusArranging,
SaleOrderStatusArranged, SaleOrderStatusArranged,
SaleOrderStatusWaitingDelivery, SaleOrderStatusWaitingDelivery,
SaleOrderStatusComplete, SaleOrderStatusComplete,
SaleOrderStatusRefund, SaleOrderStatusRefund,
SaleOrderStatusWaitingPayment, SaleOrderStatusWaitingPayment,
SaleOrderStatusWaitingReceipt, SaleOrderStatusWaitingReceipt,
SaleOrderStatusAlreadyReceipt, SaleOrderStatusAlreadyReceipt,
SaleorderstatusWaitingPrePayment SaleorderstatusWaitingPrePayment,
} = ORDER_STATUS } = ORDER_STATUS
//订单类型 // 订单类型
const { const {
SaLeModeBulk, SaLeModeBulk,
SaleModeLengthCut, SaleModeLengthCut,
SaLeModeWeightCut, SaLeModeWeightCut,
} = SALE_MODE } = SALE_MODE
//订单按钮按订单状态归类, value是该订单状态可能该按钮会出现
const orderBtnsList = useRef([
{
id: 1,
value: [SaleOrderStatusBooking.value,
SaleOrderStatusArranging.value,
SaleOrderStatusArranged.value,
SaleOrderStatusWaitingPayment.value,
SaleOrderStatusWaitingDelivery.value], //取消订单按钮对应: 待接单,配布中,已配布, 待付款, 待发货
label: '取消订单'
},
{
id: 2,
value: [SaleorderstatusWaitingPrePayment.value, SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value], //去付款按钮对应:待付款, 待发货, 待收货, 已收货, 已完成
label: '去付款'
},
{
id: 3,
value: [SaleOrderStatusWaitingDelivery.value], //申请退款按钮对应: 待发货
label: '申请退款'
},
{
id: 4,
value: [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value], //取消订单按钮对应: 待收货, 已收货, 已完成, 已退款
label: '查看物流'
},
{
id: 5,
value: [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusRefund.value], //申请退货按钮对应: 待收货, 已收货, 已退款
label: '申请退货'
},
{
id: 6,
value: [SaleOrderStatusWaitingReceipt.value], //确认收货按钮对应: 待收货
label: '确认收货'
},
{
id: 7,
value: [SaleOrderStatusWaitingReceipt.value,SaleOrderStatusAlreadyReceipt.value,SaleOrderStatusComplete.value,SaleOrderStatusRefund.value], //再次购买按钮对应: 待收货,已收货,已完成, 已退款
label: '再次购买'
},
{
id: 8,
value: [SaleOrderStatusBooking.value], //按钮对应: 待接单
label: '退款'
},
])
//判断是否显示该按钮 // 订单按钮按订单状态归类, value是该订单状态可能该按钮会出现
const orderBtnsShow = (item) => { const orderBtnsList = useRef([
if(orderInfo) { {
if(item.id == 1) { id: 1,
//取消订单按钮 value: [SaleOrderStatusBooking.value,
return( orderInfo.actual_amount == 0 && item.value.includes(orderInfo.status)) //在待发货之前没有付过款 SaleOrderStatusArranging.value,
} else if (item.id == 2) { SaleOrderStatusArranged.value,
//去付款按钮 SaleOrderStatusWaitingPayment.value,
return( orderInfo.wait_pay_amount != 0 && item.value.includes(orderInfo.status)) //只要没有付完款就显示 SaleOrderStatusWaitingDelivery.value], // 取消订单按钮对应: 待接单,配布中,已配布, 待付款, 待发货
} else if(item.id == 3 ) { label: '取消订单',
//申请退款, 只有大货才有 },
return (orderInfo.sale_mode == SaLeModeBulk.value && orderInfo.actual_amount != 0 && item.value.includes(orderInfo.status)) //大货在待发货付过款 {
} else if( item.id == 8) { id: 2,
//退款按钮(直接退款不用申请), 只有散剪和剪板有 value: [SaleorderstatusWaitingPrePayment.value, SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value], // 去付款按钮对应:待付款, 待发货, 待收货, 已收货, 已完成
return (orderInfo.sale_mode != SaLeModeBulk.value && orderInfo.actual_amount != 0 && item.value.includes(orderInfo.status)) //散剪和剪板在待接单时付过款 label: '去付款',
} },
else { {
//其他按钮 id: 3,
return item.value.includes(orderInfo.status) value: [SaleOrderStatusWaitingDelivery.value], // 申请退款按钮对应: 待发货
} label: '申请退款',
},
{
id: 4,
value: [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value], // 取消订单按钮对应: 待收货, 已收货, 已完成, 已退款
label: '查看物流',
},
{
id: 5,
value: [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusRefund.value], // 申请退货按钮对应: 待收货, 已收货, 已退款
label: '申请退货',
},
{
id: 6,
value: [SaleOrderStatusWaitingReceipt.value], // 确认收货按钮对应: 待收货
label: '确认收货',
},
{
id: 7,
value: [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value], // 再次购买按钮对应: 待收货,已收货,已完成, 已退款
label: '再次购买',
},
{
id: 8,
value: [SaleOrderStatusBooking.value], // 按钮对应: 待接单
label: '退款',
},
])
// 判断是否显示该按钮
const orderBtnsShow = (item) => {
if (orderInfo) {
if (item.id == 1) {
// 取消订单按钮
return (orderInfo.actual_amount == 0 && item.value.includes(orderInfo.status)) // 在待发货之前没有付过款
}
else if (item.id == 2) {
// 去付款按钮
return (orderInfo.wait_pay_amount != 0 && item.value.includes(orderInfo.status)) // 只要没有付完款就显示
}
else if (item.id == 3) {
// 申请退款, 只有大货才有
return (orderInfo.sale_mode == SaLeModeBulk.value && orderInfo.actual_amount != 0 && item.value.includes(orderInfo.status)) // 大货在待发货付过款
}
else if (item.id == 8) {
// 退款按钮(直接退款不用申请), 只有散剪和剪板有
return (orderInfo.sale_mode != SaLeModeBulk.value && orderInfo.actual_amount != 0 && item.value.includes(orderInfo.status)) // 散剪和剪板在待接单时付过款
}
else {
// 其他按钮
return item.value.includes(orderInfo.status)
}
}
}
// 显示的按钮数组
const orderBtnsShowList: { id: number; value: any; label: string }[] = useMemo(() => {
return orderBtnsList.current.filter((item) => {
return orderBtnsShow(item)
})
}, [orderInfo])
// 点击按钮操作
const submitBtns = (val, index) => {
(val == 1) && cancelOrder(); // 取消订单按钮
(val == 2) && onClick?.(2); // 去付款按钮
(val == 6) && receiveOrder() // 确认收货
}
// 取消订单
const { fetchData: cancelFetchData } = CancelOrderApi()
const cancelOrder = () => {
Taro.showModal({
title: '要取消该订单吗?',
async success(res) {
if (res.confirm) {
const res = await cancelFetchData({ id: orderInfo?.orderId })
if (res.success) {
alert.success('取消成功')
onClick?.(1)
}
else {
alert.none(res.msg)
}
}
else if (res.cancel) {
console.log('用户点击取消')
} }
} },
})
}
//显示的按钮数组 // 确认订单
const orderBtnsShowList: {id: number, value: any, label: string}[] = useMemo(() => { const { fetchData: receiveOrderFetchData } = ReceiveOrderApi()
return orderBtnsList.current.filter(item => { const receiveOrder = async() => {
return orderBtnsShow(item) console.log('123456')
}) Taro.showModal({
}, [orderInfo]) title: '确定收货?',
async success(res) {
if (res.confirm) {
const res = await receiveOrderFetchData({ sale_order_id: orderInfo?.orderId })
if (res.success) {
onClick?.(6)
alert.success('收货成功')
}
else {
alert.error('收货失败')
}
}
else if (res.cancel) {
console.log('用户点击取消')
}
},
})
}
// 显示更多按钮
const [showMore, setShowMore] = useState(false)
const styleTop = useMemo(() => {
return { top: `-${(orderBtnsShowList.length - 3) * 70 + 10}rpx`, left: `-${10}rpx` }
}, [orderBtnsShowList])
return (
<View className={styles.btns_list}>
{(orderBtnsShowList.length > 3) && <View className={styles.more}>
<Text onClick={() => setShowMore(true)}></Text>
{showMore && <View className={styles.more_con}>
<View className={styles.more_list} style={styleTop}>
{orderBtnsShowList.map((item, index) => {
return ((index >= 3) && <View className={styles.more_item} key={item.id} onClick={() => submitBtns(item.id, index)}>{item.label}</View>)
})}
</View>
<View className={styles.more_bg} catchMove onClick={() => setShowMore(false)}></View>
</View>}
</View>}
//点击按钮操作 <View className={styles.list_scroll}>
const submitBtns = (val, index) => { {orderBtnsShowList.map((item, index) =>
(val == 1)&&cancelOrder(); //取消订单按钮 (index < 3) && <View key={item.id} className={styles.btns_item} onClick={() => submitBtns(item.id, index)}>{item.label}</View>,
(val == 2)&&onClick?.(2); //去付款按钮 )}
(val == 6)&&receiveOrder(); //确认收货 </View>
}
//取消订单 </View>
const {fetchData: cancelFetchData} = CancelOrderApi() )
const cancelOrder = () => { })
Taro.showModal({
title: '要取消该订单吗?',
success: async function (res) {
if (res.confirm) {
let res = await cancelFetchData({id: orderInfo?.orderId})
if(res.success) {
alert.success('取消成功')
onClick?.(1)
} else {
alert.none(res.msg)
}
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
//确认订单
const {fetchData: receiveOrderFetchData} = ReceiveOrderApi()
const receiveOrder = async () => {
console.log('123456')
Taro.showModal({
title: '确定收货?',
success: async function (res) {
if (res.confirm) {
let res = await receiveOrderFetchData({sale_order_id: orderInfo?.orderId})
if(res.success){
onClick?.(6)
alert.success('收货成功')
} else {
alert.error('收货失败')
}
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
//显示更多按钮
const [showMore, setShowMore] = useState(false)
const styleTop = useMemo(() => {
return {top:`-${(orderBtnsShowList.length - 3)*70 + 10}rpx`, left: `-${10}rpx`}
}, [orderBtnsShowList])
return (
<View className={styles.btns_list}>
{(orderBtnsShowList.length > 3)&&<View className={styles.more}>
<Text onClick={() => setShowMore(true)}></Text>
{showMore&&<View className={styles.more_con}>
<View className={styles.more_list} style={styleTop}>
{orderBtnsShowList.map((item, index) => {
return ((index >= 3) &&<View className={styles.more_item} key={item.id} onClick={() => submitBtns(item.id, index)}>{item.label}</View>)
})}
</View>
<View className={styles.more_bg} catchMove onClick={() => setShowMore(false)}></View>
</View>}
</View>}
<View className={styles.list_scroll}>
{orderBtnsShowList.map((item, index) =>
(index < 3)&&<View key={item.id} className={styles.btns_item} onClick={() => submitBtns(item.id, index)}>{item.label}</View>
)}
</View>
</View>
)
})

View File

@ -1,33 +1,33 @@
import { CancelOrderApi, ReceiveOrderApi } from '@/api/order'
import { alert, goLink } from '@/common/common'
import { ORDER_STATUS, SALE_MODE, SUBSCRIPTION_MESSAGE_SCENE } from '@/common/enum'
import { Text, View } from '@tarojs/components' import { Text, View } from '@tarojs/components'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import { useRef, memo, useState, useMemo } from 'react' import { memo, useMemo, useRef, useState } from 'react'
import classnames from 'classnames' import classnames from 'classnames'
import styles from './index.module.scss' import styles from './index.module.scss'
import { ORDER_STATUS, SALE_MODE, SUBSCRIPTION_MESSAGE_SCENE } from '@/common/enum'
import { alert, goLink } from '@/common/common'
import { CancelOrderApi, ReceiveOrderApi } from '@/api/order'
import { AddShoppingCartApi } from '@/api/shopCart' import { AddShoppingCartApi } from '@/api/shopCart'
import { ApplyRefundApi } from '@/api/salesAfterOrder' import { ApplyRefundApi } from '@/api/salesAfterOrder'
import { UseSubscriptionMessage } from '@/use/useCommon' import { UseSubscriptionMessage } from '@/use/useCommon'
import { throttle } from '@/common/util' import { throttle } from '@/common/util'
type Param = { interface Param {
orderInfo: { orderInfo: {
status: number //订单状态 status: number // 订单状态
orderId: number //订单id orderId: number // 订单id
actual_amount: number //实付金额 actual_amount: number // 实付金额
wait_pay_amount: number //待付金额 wait_pay_amount: number // 待付金额
sale_mode: number //订单类型 sale_mode: number // 订单类型
av_return_roll?: number //可退数量 av_return_roll?: number // 可退数量
is_return?: true | false //是否申请了售后 is_return?: true | false // 是否申请了售后
is_should_collect_audit?: true | false //应收单是否审核 is_should_collect_audit?: true | false // 应收单是否审核
} }
showStatus?: 'detail' | 'list' //订单详情,订单列表 showStatus?: 'detail' | 'list' // 订单详情,订单列表
onClick?: (val: number) => void //点击后触发的事件,返回订单状态 onClick?: (val: number) => void // 点击后触发的事件,返回订单状态
} }
export default memo(({ orderInfo, showStatus = 'detail', onClick }: Param) => { export default memo(({ orderInfo, showStatus = 'detail', onClick }: Param) => {
//订单状态枚举 // 订单状态枚举
const { const {
SaleOrderStatusBooking, SaleOrderStatusBooking,
SaleOrderStatusArranging, SaleOrderStatusArranging,
@ -42,19 +42,19 @@ export default memo(({ orderInfo, showStatus = 'detail', onClick }: Param) => {
SaleOrderStatusTaking, SaleOrderStatusTaking,
} = ORDER_STATUS } = ORDER_STATUS
//订单类型 // 订单类型
const { SaLeModeBulk, SaleModeLengthCut, SaLeModeWeightCut } = SALE_MODE const { SaLeModeBulk, SaleModeLengthCut, SaLeModeWeightCut } = SALE_MODE
//注册按钮, id:按钮id唯一label按钮名称sort排序数字越大越靠后validatarFunc验证 // 注册按钮, id:按钮id唯一label按钮名称sort排序数字越大越靠后validatarFunc验证
type orderBtnsListParams = { id: number; label: string; sort: number; validatarFunc: (val: typeof orderInfo) => any } interface orderBtnsListParams { id: number; label: string; sort: number; validatarFunc: (val: typeof orderInfo) => any }
const orderBtnsList = useRef<orderBtnsListParams[]>([ const orderBtnsList = useRef<orderBtnsListParams[]>([
{ {
id: 1, id: 1,
label: '取消订单', label: '取消订单',
sort: 1, sort: 1,
validatarFunc: (orderInfo) => { validatarFunc: (orderInfo) => {
//在待发货之前没有付过款 // 在待发货之前没有付过款
let orderStatus = [ const orderStatus = [
SaleorderstatusWaitingPrePayment.value, SaleorderstatusWaitingPrePayment.value,
SaleOrderStatusBooking.value, SaleOrderStatusBooking.value,
SaleOrderStatusArranging.value, SaleOrderStatusArranging.value,
@ -71,8 +71,8 @@ export default memo(({ orderInfo, showStatus = 'detail', onClick }: Param) => {
label: '去付款', label: '去付款',
sort: 100, sort: 100,
validatarFunc: (orderInfo) => { validatarFunc: (orderInfo) => {
//只要没有付完款就显示 // 只要没有付完款就显示
let orderStatus = [ const orderStatus = [
SaleOrderStatusTaking.value, SaleOrderStatusTaking.value,
SaleorderstatusWaitingPrePayment.value, SaleorderstatusWaitingPrePayment.value,
SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingPayment.value,
@ -89,8 +89,8 @@ export default memo(({ orderInfo, showStatus = 'detail', onClick }: Param) => {
label: '申请退款', label: '申请退款',
sort: 5, sort: 5,
validatarFunc: (orderInfo) => { validatarFunc: (orderInfo) => {
//大货在待发货付过款 // 大货在待发货付过款
let orderStatus = [SaleOrderStatusWaitingDelivery.value, SaleOrderStatusTaking.value] const orderStatus = [SaleOrderStatusWaitingDelivery.value, SaleOrderStatusTaking.value]
return orderInfo.sale_mode == SaLeModeBulk.value && orderInfo.actual_amount > 0 && orderInfo.av_return_roll && orderStatus.includes(orderInfo.status) return orderInfo.sale_mode == SaLeModeBulk.value && orderInfo.actual_amount > 0 && orderInfo.av_return_roll && orderStatus.includes(orderInfo.status)
}, },
}, },
@ -99,7 +99,7 @@ export default memo(({ orderInfo, showStatus = 'detail', onClick }: Param) => {
label: '申请退货', label: '申请退货',
sort: 5, sort: 5,
validatarFunc: (orderInfo) => { validatarFunc: (orderInfo) => {
let orderStatus = [SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusRefund.value] const orderStatus = [SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusRefund.value]
return orderInfo.av_return_roll && orderStatus.includes(orderInfo.status) return orderInfo.av_return_roll && orderStatus.includes(orderInfo.status)
}, },
}, },
@ -108,7 +108,7 @@ export default memo(({ orderInfo, showStatus = 'detail', onClick }: Param) => {
label: '确认收货', label: '确认收货',
sort: 10, sort: 10,
validatarFunc: (orderInfo) => { validatarFunc: (orderInfo) => {
let orderStatus = [SaleOrderStatusWaitingReceipt.value] const orderStatus = [SaleOrderStatusWaitingReceipt.value]
return orderStatus.includes(orderInfo.status) return orderStatus.includes(orderInfo.status)
}, },
}, },
@ -125,8 +125,8 @@ export default memo(({ orderInfo, showStatus = 'detail', onClick }: Param) => {
label: '退款', label: '退款',
sort: 5, sort: 5,
validatarFunc: (orderInfo) => { validatarFunc: (orderInfo) => {
//散剪和剪板在待接单时付过款 // 散剪和剪板在待接单时付过款
let orderStatus = [SaleOrderStatusBooking.value] const orderStatus = [SaleOrderStatusBooking.value]
return orderInfo.sale_mode != SaLeModeBulk.value && orderInfo.actual_amount > 0 && orderStatus.includes(orderInfo.status) return orderInfo.sale_mode != SaLeModeBulk.value && orderInfo.actual_amount > 0 && orderStatus.includes(orderInfo.status)
}, },
}, },
@ -143,132 +143,144 @@ export default memo(({ orderInfo, showStatus = 'detail', onClick }: Param) => {
label: '销售码单', label: '销售码单',
sort: 9, sort: 9,
validatarFunc: (orderInfo) => { validatarFunc: (orderInfo) => {
if (orderInfo.sale_mode === 1 && showStatus == 'detail') return true if (orderInfo.sale_mode === 1 && showStatus == 'detail') { return true }
if (orderInfo.sale_mode !== 1 && showStatus == 'detail') return orderInfo.is_should_collect_audit if (orderInfo.sale_mode !== 1 && showStatus == 'detail') { return orderInfo.is_should_collect_audit }
}, },
}, },
]) ])
//显示的按钮数组 // 显示的按钮数组
const orderBtnsShowList: orderBtnsListParams[] = useMemo(() => { const orderBtnsShowList: orderBtnsListParams[] = useMemo(() => {
let list = orderBtnsList.current.filter((item) => { const list = orderBtnsList.current.filter((item) => {
return item.validatarFunc(orderInfo) return item.validatarFunc(orderInfo)
}) })
return list.sort((a, b) => a.sort - b.sort) return list.sort((a, b) => a.sort - b.sort)
}, [orderInfo]) }, [orderInfo])
//小程序订阅 // 小程序订阅
const { ApplyGoods } = SUBSCRIPTION_MESSAGE_SCENE const { ApplyGoods } = SUBSCRIPTION_MESSAGE_SCENE
const { openSubscriptionMessage } = UseSubscriptionMessage() const { openSubscriptionMessage } = UseSubscriptionMessage()
//点击按钮操作 // 点击按钮操作
const submitBtns = throttle(async (val, index) => { const submitBtns = throttle(async(val, index) => {
if (val == 1) { if (val == 1) {
cancelOrder() cancelOrder()
} else if (val == 6) { }
else if (val == 6) {
receiveOrder() receiveOrder()
} else if (val == 5) { }
else if (val == 5) {
applyProduct() applyProduct()
} else if (val == 3) { }
else if (val == 3) {
bigApplyRefurn() bigApplyRefurn()
} else if (val == 8) { }
else if (val == 8) {
applyRefund() applyRefund()
} else { }
else {
onClick?.(val) onClick?.(val)
} }
}, 800) }, 800)
//大货申请退款 // 大货申请退款
const bigApplyRefurn = () => { const bigApplyRefurn = () => {
Taro.showModal({ Taro.showModal({
title: '要申请退款吗?', title: '要申请退款吗?',
success: async function (res) { async success(res) {
if (res.confirm) { if (res.confirm) {
await openSubscriptionMessage({ orderId: orderInfo?.orderId, scenes: ApplyGoods.value }) await openSubscriptionMessage({ orderId: orderInfo?.orderId, scenes: ApplyGoods.value })
onClick?.(3) onClick?.(3)
} else { }
else {
console.log('用户点击取消') console.log('用户点击取消')
} }
}, },
}) })
} }
//取消订单 // 取消订单
const { fetchData: cancelFetchData } = CancelOrderApi() const { fetchData: cancelFetchData } = CancelOrderApi()
const cancelOrder = () => { const cancelOrder = () => {
Taro.showModal({ Taro.showModal({
title: '要取消该订单吗?', title: '要取消该订单吗?',
success: async function (res) { async success(res) {
if (res.confirm) { if (res.confirm) {
let res = await cancelFetchData({ id: orderInfo?.orderId }) const res = await cancelFetchData({ id: orderInfo?.orderId })
if (res.success) { if (res.success) {
alert.success('取消成功') alert.success('取消成功')
onClick?.(1) onClick?.(1)
} else { }
else {
alert.none(res.msg) alert.none(res.msg)
} }
} else if (res.cancel) { }
else if (res.cancel) {
console.log('用户点击取消') console.log('用户点击取消')
} }
}, },
}) })
} }
//确认订单 // 确认订单
const { fetchData: receiveOrderFetchData } = ReceiveOrderApi() const { fetchData: receiveOrderFetchData } = ReceiveOrderApi()
const receiveOrder = async () => { const receiveOrder = async() => {
Taro.showModal({ Taro.showModal({
title: '确定收货?', title: '确定收货?',
success: async function (res) { async success(res) {
if (res.confirm) { if (res.confirm) {
alert.showLoading('收货中', true) alert.showLoading('收货中', true)
let res = await receiveOrderFetchData({ sale_order_id: orderInfo?.orderId }) const res = await receiveOrderFetchData({ sale_order_id: orderInfo?.orderId })
if (res.success) { if (res.success) {
onClick?.(6) onClick?.(6)
alert.success('收货成功') alert.success('收货成功')
} else { }
else {
alert.error('收货失败') alert.error('收货失败')
} }
alert.hideLoading() alert.hideLoading()
} else if (res.cancel) { }
else if (res.cancel) {
console.log('用户点击取消') console.log('用户点击取消')
} }
}, },
}) })
} }
//退款 // 退款
const { fetchData: fetchDataApplyRefund } = ApplyRefundApi() const { fetchData: fetchDataApplyRefund } = ApplyRefundApi()
const applyRefund = async () => { const applyRefund = async() => {
Taro.showModal({ Taro.showModal({
title: '确定退款?', title: '确定退款?',
success: async function async(res) { success: async function async(res) {
if (res.confirm) { if (res.confirm) {
await openSubscriptionMessage({ orderId: orderInfo?.orderId, scenes: ApplyGoods.value }) await openSubscriptionMessage({ orderId: orderInfo?.orderId, scenes: ApplyGoods.value })
alert.showLoading('申请中', true) alert.showLoading('申请中', true)
let res = await fetchDataApplyRefund({ sale_order_id: orderInfo?.orderId }) const res = await fetchDataApplyRefund({ sale_order_id: orderInfo?.orderId })
if (res.success) { if (res.success) {
alert.success('申请成功') alert.success('申请成功')
} else { }
else {
alert.error('申请失败') alert.error('申请失败')
} }
alert.hideLoading() alert.hideLoading()
onClick?.(8) onClick?.(8)
} else if (res.cancel) { }
else if (res.cancel) {
console.log('用户点击取消') console.log('用户点击取消')
} }
}, },
}) })
} }
//申请退货 // 申请退货
const applyProduct = async () => { const applyProduct = async() => {
if (!orderInfo?.av_return_roll) return alert.none('该订单没有可退条数') if (!orderInfo?.av_return_roll) { return alert.none('该订单没有可退条数') }
await openSubscriptionMessage({ orderId: orderInfo?.orderId, scenes: ApplyGoods.value }) await openSubscriptionMessage({ orderId: orderInfo?.orderId, scenes: ApplyGoods.value })
goLink('/pages/applyAfterSales/index', { id: orderInfo?.orderId }) goLink('/pages/applyAfterSales/index', { id: orderInfo?.orderId })
} }
//显示更多按钮 // 显示更多按钮
const [showMore, setShowMore] = useState(false) const [showMore, setShowMore] = useState(false)
const styleTop = useMemo(() => { const styleTop = useMemo(() => {
return { top: `-${(orderBtnsShowList.length - 3) * 70 + 10}rpx`, left: `-${10}rpx` } return { top: `-${(orderBtnsShowList.length - 3) * 70 + 10}rpx`, left: `-${10}rpx` }

View File

@ -1,74 +1,75 @@
import { View } from "@tarojs/components"; import { View } from '@tarojs/components'
import style from "./index.module.scss" import classnames from 'classnames'
import classnames from "classnames"; import type { ReactNode } from 'react'
import { memo, ReactNode, useEffect, useMemo, useRef } from "react"; import { memo, useEffect, useMemo, useRef } from 'react'
import CloseBtnIcon from "@/components/closeBtn" import style from './index.module.scss'
import CloseBtnIcon from '@/components/closeBtn'
export interface Params { export interface Params {
title?: string, //标题 title?: string // 标题
show?: false|true, //显示显示弹窗 show?: false|true // 显示显示弹窗
showTitle?: false|true, //是否显示标题 showTitle?: false|true // 是否显示标题
onClose?:() => void, //关闭事件 onClose?: () => void // 关闭事件
children?: ReactNode, //插槽内容 children?: ReactNode // 插槽内容
// IconButton?: ReactNode, // // IconButton?: ReactNode, //
showIconButton?: false|true, //是否显示关闭按钮 showIconButton?: false|true // 是否显示关闭按钮
position?: 'bottom'|'top'|'right', //弹出位置 position?: 'bottom'|'top'|'right' // 弹出位置
animationEnd?: () => void //弹出动画结束 animationEnd?: () => void // 弹出动画结束
} }
export default memo(( export default memo((
{ {
title = '标题', title = '标题',
show = false, show = false,
showTitle = true, showTitle = true,
onClose, onClose,
showIconButton = false, showIconButton = false,
children, children,
position = 'bottom', position = 'bottom',
animationEnd animationEnd,
}:Params) => { }: Params) => {
const animationTime = useRef<any>(null)
const animationTime = useRef<any>(null) useEffect(() => {
useEffect(() => { if (show) {
if(show) { animationTime.current = setTimeout(() => {
animationTime.current = setTimeout(() => { animationEnd?.()
animationEnd?.() }, 260)
}, 260) }
} else { else {
clearTimeout(animationTime.current) clearTimeout(animationTime.current)
} }
}, [show]) }, [show])
useEffect(() => { useEffect(() => {
return () => { return () => {
clearTimeout(animationTime.current) clearTimeout(animationTime.current)
} }
}, []) }, [])
return ( return (
<> <>
<View className={style.drawer_main}> <View className={style.drawer_main}>
<View catchMove={true} className={`${style.drawer} ${show?style.drawer_active:''}` }> <View catchMove className={`${style.drawer} ${show ? style.drawer_active : ''}`}>
<View <View
className={classnames(style.drawer_mask, {[style.drawer_mask_active]: show})} className={classnames(style.drawer_mask, { [style.drawer_mask_active]: show })}
onClick={() => onClose?.()} onClick={() => onClose?.()}
> >
<View <View
className={classnames(style.drawer_container, style['drawer_container_'+position], {[style.drawer_container_active]: show})} className={classnames(style.drawer_container, style[`drawer_container_${position}`], { [style.drawer_container_active]: show })}
onClick={(e) => e.stopPropagation()} onClick={e => e.stopPropagation()}
> >
{showTitle&&<View className={style.drawer_container_title}>{title}</View>} {showTitle && <View className={style.drawer_container_title}>{title}</View>}
{showIconButton&&<View className={style.common_close_btn_icon}> {showIconButton && <View className={style.common_close_btn_icon}>
<CloseBtnIcon onClose={() => onClose?.()}/> <CloseBtnIcon onClose={() => onClose?.()} />
</View>} </View>}
<View className={style.drawer_container_context}> <View className={style.drawer_container_context}>
{show&&children} {show && children}
</View> </View>
<View className="common_safe_area_y"></View> <View className="common_safe_area_y"></View>
</View>
</View>
</View>
</View> </View>
</> </View>
) </View>
</View>
</>
)
}) })

View File

@ -1,12 +1,12 @@
import { Image, View } from '@tarojs/components' import { Image, View } from '@tarojs/components'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import { goLink } from '@/common/common'
import styles from './index.module.scss'
import { formatHashTag, formatImgUrl } from '@/common/fotmat'
import LabAndImg from '../LabAndImg'
import { useCallback, useMemo } from 'react' import { useCallback, useMemo } from 'react'
import LabAndImg from '../LabAndImg'
import styles from './index.module.scss'
import { goLink } from '@/common/common'
import { formatHashTag, formatImgUrl } from '@/common/fotmat'
type Params = { interface Params {
desStatus?: true | false desStatus?: true | false
productList?: any[] productList?: any[]
} }
@ -35,7 +35,7 @@ export default ({ desStatus = true, productList = [] }: Params) => {
<View className={styles.tag}>{item.width}</View> <View className={styles.tag}>{item.width}</View>
<View className={styles.tag_g}>{item.weight_density}</View> <View className={styles.tag_g}>{item.weight_density}</View>
</View> </View>
<View className={styles.introduce}>{item.craft + '' + item.component}</View> <View className={styles.introduce}>{`${item.craft}${item.component}`}</View>
{desStatus && <View className={styles.des}>{item.describe}</View>} {desStatus && <View className={styles.des}>{item.describe}</View>}
</View> </View>
</View> </View>

View File

@ -1,11 +1,11 @@
import { Input, View } from '@tarojs/components' import { Input, View } from '@tarojs/components'
import classnames from 'classnames'
import { forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from 'react'
import styles from './index.module.scss' import styles from './index.module.scss'
import CloseBtn from '@/components/closeBtn' import CloseBtn from '@/components/closeBtn'
import classnames from 'classnames'
import { debounce } from '@/common/util' import { debounce } from '@/common/util'
import { forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from 'react'
type Params = { interface Params {
clickOnSearch?: (val: string) => void clickOnSearch?: (val: string) => void
disabled?: false | true disabled?: false | true
placeholder?: string placeholder?: string
@ -16,7 +16,7 @@ type Params = {
showBtn?: false | true showBtn?: false | true
btnStyle?: Object btnStyle?: Object
btnTitle?: string btnTitle?: string
debounceTime?: number //防抖时间,不设默认为零 debounceTime?: number // 防抖时间,不设默认为零
defaultValue?: string defaultValue?: string
borderRadius?: string borderRadius?: string
} }
@ -25,17 +25,17 @@ export default memo(
forwardRef( forwardRef(
( (
{ {
clickOnSearch, //点击筛选按钮触发 clickOnSearch, // 点击筛选按钮触发
changeOnSearch, //输入文字触发 changeOnSearch, // 输入文字触发
disabled = false, //是否禁用 disabled = false, // 是否禁用
placeholder = '输入搜索内容', placeholder = '输入搜索内容',
showIcon = true, //是否显示关闭图标 showIcon = true, // 是否显示关闭图标
showBtn = false, //是否显示搜索按钮 showBtn = false, // 是否显示搜索按钮
btnStyle = {}, btnStyle = {},
placeIcon = 'inner', //搜索图标位置inner在里面out在外面 placeIcon = 'inner', // 搜索图标位置inner在里面out在外面
btnTitle = '搜索', //搜索文字 btnTitle = '搜索', // 搜索文字
debounceTime = 0, //防抖时间,不设默认为零 debounceTime = 0, // 防抖时间,不设默认为零
defaultValue = '', //默认值 defaultValue = '', // 默认值
borderRadius = '50rpx', borderRadius = '50rpx',
}: Params, }: Params,
ref, ref,
@ -84,19 +84,21 @@ export default memo(
'icon-sousuo', 'icon-sousuo',
styles.icon_a_sousuo1_self, styles.icon_a_sousuo1_self,
placeIcon == 'inner' ? styles.icon_inner : styles.icon_out, placeIcon == 'inner' ? styles.icon_inner : styles.icon_out,
)}></View> )}
></View>
)} )}
<Input <Input
style={{ borderRadius }} style={{ borderRadius }}
alwaysEmbed={true} alwaysEmbed
cursorSpacing={150} cursorSpacing={150}
placeholderStyle='color:#ABABAB; font-size:26rpx' placeholderStyle="color:#ABABAB; font-size:26rpx"
onConfirm={onSearch} onConfirm={onSearch}
className={classnames(placeIcon == 'out' && styles.input_out)} className={classnames(placeIcon == 'out' && styles.input_out)}
disabled={disabled} disabled={disabled}
value={inputCon} value={inputCon}
placeholder={placeholder} placeholder={placeholder}
onInput={(e) => onInputEven(e)}></Input> onInput={e => onInputEven(e)}
></Input>
{!!inputCon && ( {!!inputCon && (
<View className={styles.search_closeBtn}> <View className={styles.search_closeBtn}>
<CloseBtn onClose={() => clearInput()} styleObj={{ width: '20rpx', height: '20rpx', backgroundColor: '#fff', border: '0' }} /> <CloseBtn onClose={() => clearInput()} styleObj={{ width: '20rpx', height: '20rpx', backgroundColor: '#fff', border: '0' }} />

View File

@ -1,8 +1,9 @@
import { Input, View } from '@tarojs/components' import { Input, View } from '@tarojs/components'
import { memo, ReactHTMLElement, ReactNode, useDebugValue, useMemo } from 'react' import type { ReactNode } from 'react'
import { ReactHTMLElement, memo, useDebugValue, useMemo } from 'react'
import styles from './index.module.scss' import styles from './index.module.scss'
type Params = { interface Params {
showIcon?: false | true showIcon?: false | true
disabled?: false | true disabled?: false | true
placeholder?: string placeholder?: string
@ -18,7 +19,7 @@ type Params = {
} }
export default memo((props: Params) => { export default memo((props: Params) => {
let { const {
showTitle = true, showTitle = true,
title = '标题', title = '标题',
showIcon = false, showIcon = false,
@ -31,14 +32,14 @@ export default memo((props: Params) => {
titleStyle = {}, titleStyle = {},
} = props } = props
let stylen = useMemo(() => { const stylen = useMemo(() => {
if (!showBorder) { if (!showBorder) {
return { borderBottom: 0 } return { borderBottom: 0 }
} }
return {} return {}
}, [showBorder]) }, [showBorder])
return ( return (
<View className={styles.searchInput_main} style={{ height: height, ...stylen }}> <View className={styles.searchInput_main} style={{ height, ...stylen }}>
{showTitle && ( {showTitle && (
<View className={styles.searchInput_title} style={titleStyle}> <View className={styles.searchInput_title} style={titleStyle}>
{title} {title}
@ -47,12 +48,12 @@ export default memo((props: Params) => {
<View className={styles.searchInput_con}> <View className={styles.searchInput_con}>
{(!props.children && ( {(!props.children && (
<Input <Input
alwaysEmbed={true} alwaysEmbed
cursorSpacing={150} cursorSpacing={150}
disabled={disabled} disabled={disabled}
placeholder={placeholder} placeholder={placeholder}
onClick={() => clickOnInput?.()} onClick={() => clickOnInput?.()}
onInput={(e) => changeOnInput?.(e.detail.value)} onInput={e => changeOnInput?.(e.detail.value)}
/> />
)) || <>{props.children}</>} )) || <>{props.children}</>}
</View> </View>

View File

@ -1,14 +1,15 @@
import { CustomWrapper, View } from '@tarojs/components' import { CustomWrapper, View } from '@tarojs/components'
import { memo, useCallback, useMemo } from 'react' import { memo, useCallback, useMemo } from 'react'
import classnames from 'classnames' import classnames from 'classnames'
import Big from 'big.js'
import styles from './index.module.scss' import styles from './index.module.scss'
import MCheckbox from '@/components/checkbox' import MCheckbox from '@/components/checkbox'
import Counter from '@/components/counter' import Counter from '@/components/counter'
import LabAndImg from '@/components/LabAndImg' import LabAndImg from '@/components/LabAndImg'
import { formatHashTag, formatImgUrl, formatPriceDiv } from '@/common/fotmat' import { formatHashTag, formatImgUrl, formatPriceDiv } from '@/common/fotmat'
import Big from 'big.js' import type { saleModeType } from '@/common/enum'
import { saleModeType } from '@/common/enum'
type param = { interface param {
sale_model: saleModeType sale_model: saleModeType
onChangeSelect: (val: any) => any onChangeSelect: (val: any) => any
onChangeCount: (val: any) => any onChangeCount: (val: any) => any
@ -16,7 +17,7 @@ type param = {
} }
export default memo((props: param) => { export default memo((props: param) => {
let { onChangeCount, onChangeSelect, item, sale_model } = props const { onChangeCount, onChangeSelect, item, sale_model } = props
const selectCallBack = useCallback(() => { const selectCallBack = useCallback(() => {
onChangeSelect({ ...item, selected: true }) onChangeSelect({ ...item, selected: true })
@ -27,8 +28,8 @@ export default memo((props: param) => {
const getLabAndImg = useCallback(() => {}, []) const getLabAndImg = useCallback(() => {}, [])
const getInputValue = useCallback( const getInputValue = useCallback(
(e) => { (e) => {
let roll = item.sale_mode == 0 ? parseFloat(e) : 0 const roll = item.sale_mode == 0 ? parseFloat(e) : 0
let length = item.sale_mode != 0 ? parseFloat(new Big(parseFloat(e)).times(100)) : 0 const length = item.sale_mode != 0 ? parseFloat(new Big(parseFloat(e)).times(100)) : 0
onChangeCount({ ...item, roll, length }) onChangeCount({ ...item, roll, length })
}, },
[item], [item],
@ -38,20 +39,20 @@ export default memo((props: param) => {
}, [item]) }, [item])
const clickProduct = useCallback(() => { const clickProduct = useCallback(() => {
if (sale_model == item.sale_mode) onChangeSelect({ ...item, selected: !item.selected }) if (sale_model == item.sale_mode) { onChangeSelect({ ...item, selected: !item.selected }) }
}, [item]) }, [item])
console.log('刷新2', item) console.log('刷新2', item)
//格式化金额 // 格式化金额
const formatPirce = useCallback((price) => { const formatPirce = useCallback((price) => {
return Number(formatPriceDiv(price)) return Number(formatPriceDiv(price))
}, []) }, [])
//格式化数量 // 格式化数量
const formatCount = useCallback((item) => { const formatCount = useCallback((item) => {
return item.sale_mode == 0 ? item.roll : item.length / 100 return item.sale_mode == 0 ? item.roll : item.length / 100
}, []) }, [])
//格式化单位 // 格式化单位
const formatUnit = useCallback((item) => { const formatUnit = useCallback((item) => {
return item.sale_mode == 0 ? '条' : '米' return item.sale_mode == 0 ? '条' : '米'
}, []) }, [])
@ -78,7 +79,7 @@ export default memo((props: param) => {
</View> </View>
<View className={styles.count}> <View className={styles.count}>
<View className={styles.des}> <View className={styles.des}>
<View className={styles.subtitle}>{item.product_color_code + ' ' + item.product_color_name}</View> <View className={styles.subtitle}>{`${item.product_color_code} ${item.product_color_name}`}</View>
<View className={styles.tag}>{item.sale_mode_name}</View> <View className={styles.tag}>{item.sale_mode_name}</View>
</View> </View>
<View className={styles.btn_count}> <View className={styles.btn_count}>

View File

@ -1,29 +1,29 @@
import { Image, ScrollView, View } from '@tarojs/components' import { Image, ScrollView, View } from '@tarojs/components'
import Popup from '@/components/popup'
import classnames from 'classnames'
import MCheckbox from '@/components/checkbox'
import LoadingCard from '@/components/loadingCard'
import InfiniteScroll from '@/components/infiniteScroll'
import styles from './index.module.scss'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import { alert, goLink } from '@/common/common' import classnames from 'classnames'
import { GetShoppingCartApi, DelShoppingCartApi, UpdateShoppingCartApi } from '@/api/shopCart' import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { formatHashTag, formatImgUrl, formatPriceDiv } from '@/common/fotmat'
import { setParam } from '@/common/system'
import { debounce, throttle } from '@/common/util'
import Counter from '../counter' import Counter from '../counter'
import { ApplyOrderAccessApi, GetAdminUserInfoApi, SubscriptionMessageApi } from '@/api/user'
import useCommonData from '@/use/useCommonData'
import BindSalesmanPopup from '../bindSalesmanPopup' import BindSalesmanPopup from '../bindSalesmanPopup'
import LabAndImgShow from '../LabAndImgShow' import LabAndImgShow from '../LabAndImgShow'
import LabAndImg from '../LabAndImg' import LabAndImg from '../LabAndImg'
import styles from './index.module.scss'
import Popup from '@/components/popup'
import MCheckbox from '@/components/checkbox'
import LoadingCard from '@/components/loadingCard'
import InfiniteScroll from '@/components/infiniteScroll'
import { alert, goLink } from '@/common/common'
import { DelShoppingCartApi, GetShoppingCartApi, UpdateShoppingCartApi } from '@/api/shopCart'
import { formatHashTag, formatImgUrl, formatPriceDiv } from '@/common/fotmat'
import { setParam } from '@/common/system'
import { debounce, throttle } from '@/common/util'
import { ApplyOrderAccessApi, GetAdminUserInfoApi, SubscriptionMessageApi } from '@/api/user'
import useCommonData from '@/use/useCommonData'
type param = { interface param {
show?: true | false show?: true | false
onClose?: () => void onClose?: () => void
intoStatus?: 'again' | 'shop' intoStatus?: 'again' | 'shop'
default_sale_mode?: number //面料类型0大货 1剪版2散剪 default_sale_mode?: number // 面料类型0大货 1剪版2散剪
} }
export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode }: param) => { export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode }: param) => {
const selectList = [ const selectList = [
@ -32,7 +32,7 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
{ value: 2, title: '散剪', unit: '米', eunit: 'kg', step: 1, digits: 2, minNum: 3, maxNum: 100000, defaultNum: 3 }, { value: 2, title: '散剪', unit: '米', eunit: 'kg', step: 1, digits: 2, minNum: 3, maxNum: 100000, defaultNum: 3 },
] ]
//切换面料类型 // 切换面料类型
const [selectIndex, setSelectIndex] = useState(default_sale_mode || 0) const [selectIndex, setSelectIndex] = useState(default_sale_mode || 0)
const selectProduct = (index: number) => { const selectProduct = (index: number) => {
setSelectIndex(index) setSelectIndex(index)
@ -48,53 +48,55 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
const MCheckboxRef = useRef(null) const MCheckboxRef = useRef(null)
//获取购物车数据数量 // 获取购物车数据数量
const { setShopCount } = useCommonData() const { setShopCount } = useCommonData()
//重置勾选数据 // 重置勾选数据
const resetList = () => { const resetList = () => {
list?.map((item) => { list?.map((item) => {
if (selectIndex == item.sale_mode || selectIndex == -1) { if (selectIndex == item.sale_mode || selectIndex == -1) {
checkboxData[item.id] = true checkboxData[item.id] = true
} else { }
else {
checkboxData[item.id] = false checkboxData[item.id] = false
} }
}) })
setCheckboxData(() => ({ ...checkboxData })) setCheckboxData(() => ({ ...checkboxData }))
} }
//获取数据 // 获取数据
const [list, setList] = useState<any[]>([]) const [list, setList] = useState<any[]>([])
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const { fetchData } = GetShoppingCartApi() const { fetchData } = GetShoppingCartApi()
const getShoppingCart = async () => { const getShoppingCart = async() => {
const { data } = await fetchData() const { data } = await fetchData()
let color_list = data.color_list || [] const color_list = data.color_list || []
setShopCount(color_list.length) setShopCount(color_list.length)
initList(color_list) initList(color_list)
setList(color_list) setList(color_list)
setLoading(false) setLoading(false)
} }
//初始化全部数据默认勾选 // 初始化全部数据默认勾选
const [checkboxData, setCheckboxData] = useState<{ [index: number]: true | false }>({}) const [checkboxData, setCheckboxData] = useState<Record<number, true | false>>({})
const initStatus = useRef(false) const initStatus = useRef(false)
const initList = (color_list) => { const initList = (color_list) => {
if (initStatus.current) { if (initStatus.current) {
color_list?.map((item) => { color_list?.map((item) => {
if (selectIndex == item.sale_mode) checkboxData[item.id] = true if (selectIndex == item.sale_mode) { checkboxData[item.id] = true }
}) })
initStatus.current = false initStatus.current = false
} }
setCheckboxData(() => checkboxData) setCheckboxData(() => checkboxData)
} }
//显示是展示数据 // 显示是展示数据
useEffect(() => { useEffect(() => {
if (!show) { if (!show) {
setList([]) setList([])
setSelectIndex(default_sale_mode || 0) setSelectIndex(default_sale_mode || 0)
} else { }
else {
setLoading(true) setLoading(true)
initStatus.current = true initStatus.current = true
getShoppingCart() getShoppingCart()
@ -113,57 +115,57 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
setShowPopup(show) setShowPopup(show)
}, [show]) }, [show])
//全选反选 // 全选反选
const [selectStatus, setSelectStatus] = useState(false) const [selectStatus, setSelectStatus] = useState(false)
const selectAll = () => { const selectAll = () => {
list.map((item) => { list.map((item) => {
if (selectIndex == item.sale_mode || selectIndex == -1) checkboxData[item.id] = !selectStatus if (selectIndex == item.sale_mode || selectIndex == -1) { checkboxData[item.id] = !selectStatus }
}) })
setSelectStatus(!selectStatus) setSelectStatus(!selectStatus)
setCheckboxData(() => ({ ...checkboxData })) setCheckboxData(() => ({ ...checkboxData }))
} }
//checkbox选中回调 // checkbox选中回调
const selectCallBack = useCallback((item) => { const selectCallBack = useCallback((item) => {
checkboxData[item.id] = true checkboxData[item.id] = true
checkSelect() checkSelect()
setCheckboxData((e) => ({ ...e, ...checkboxData })) setCheckboxData(e => ({ ...e, ...checkboxData }))
}, []) }, [])
//checkbox选中判断是否全部选中全部选中后是全选否则反选 // checkbox选中判断是否全部选中全部选中后是全选否则反选
const checkSelect = () => { const checkSelect = () => {
let list_count = 0 let list_count = 0
let select_count = 0 let select_count = 0
list?.map((item) => { list?.map((item) => {
if (selectIndex == -1 || selectIndex == item.sale_mode) { if (selectIndex == -1 || selectIndex == item.sale_mode) {
list_count++ list_count++
if (checkboxData[item.id]) select_count++ if (checkboxData[item.id]) { select_count++ }
} }
}) })
setSelectStatus(select_count == list_count) setSelectStatus(select_count == list_count)
} }
//checkbox关闭回调 // checkbox关闭回调
const colseCallBack = useCallback((item) => { const colseCallBack = useCallback((item) => {
checkboxData[item.id] = false checkboxData[item.id] = false
checkSelect() checkSelect()
setCheckboxData((e) => ({ ...e, ...checkboxData })) setCheckboxData(e => ({ ...e, ...checkboxData }))
}, []) }, [])
//popup关闭 // popup关闭
const closePopup = () => { const closePopup = () => {
onClose?.() onClose?.()
setShowPopup(false) setShowPopup(false)
} }
//删除购物车内容 // 删除购物车内容
const { fetchData: delShopFetchData } = DelShoppingCartApi() const { fetchData: delShopFetchData } = DelShoppingCartApi()
const delSelect = () => { const delSelect = () => {
getSelectId() getSelectId()
if (selectIds.current.length <= 0) return alert.none('请选择要删除的面料!') if (selectIds.current.length <= 0) { return alert.none('请选择要删除的面料!') }
Taro.showModal({ Taro.showModal({
content: '删除所选商品?', content: '删除所选商品?',
success: async function (res) { async success(res) {
if (res.confirm) { if (res.confirm) {
const res = await delShopFetchData({ id: selectIds.current }) const res = await delShopFetchData({ id: selectIds.current })
if (res.success) { if (res.success) {
@ -172,20 +174,22 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
title: '成功', title: '成功',
icon: 'success', icon: 'success',
}) })
} else { }
else {
Taro.showToast({ Taro.showToast({
title: res.msg, title: res.msg,
icon: 'none', icon: 'none',
}) })
} }
} else if (res.cancel) { }
else if (res.cancel) {
console.log('用户点击取消') console.log('用户点击取消')
} }
}, },
}) })
} }
//获取面料选中的id // 获取面料选中的id
const selectIds = useRef<number[]>([]) const selectIds = useRef<number[]>([])
const getSelectId = () => { const getSelectId = () => {
selectIds.current = [] selectIds.current = []
@ -196,27 +200,27 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
}) })
} }
//格式化金额 // 格式化金额
const formatPirce = useCallback((price) => { const formatPirce = useCallback((price) => {
return Number(formatPriceDiv(price)) return Number(formatPriceDiv(price))
}, []) }, [])
//格式化数量 // 格式化数量
const formatCount = useCallback((item) => { const formatCount = useCallback((item) => {
return item.sale_mode == 0 ? item.roll : item.length / 100 return item.sale_mode == 0 ? item.roll : item.length / 100
}, []) }, [])
//格式化单位 // 格式化单位
const formatUnit = useCallback((item) => { const formatUnit = useCallback((item) => {
return item.sale_mode == 0 ? '条' : '米' return item.sale_mode == 0 ? '条' : '米'
}, []) }, [])
//预估金额和总条数 // 预估金额和总条数
const estimatePrice = useMemo(() => { const estimatePrice = useMemo(() => {
let estimate_amount = 0 let estimate_amount = 0
let product_list = new Set() //面料 const product_list = new Set() // 面料
let color_count = 0 //颜色数量 let color_count = 0 // 颜色数量
let all_count = 0 //总数量 let all_count = 0 // 总数量
list.map((item) => { list.map((item) => {
if (checkboxData[item.id]) { if (checkboxData[item.id]) {
estimate_amount += item.estimate_amount estimate_amount += item.estimate_amount
@ -225,7 +229,7 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
all_count += item.sale_mode == 0 ? item.roll : item.length all_count += item.sale_mode == 0 ? item.roll : item.length
} }
}) })
let all_count_text = selectIndex == 0 ? all_count + ' 条' : all_count / 100 + ' 米' const all_count_text = selectIndex == 0 ? `${all_count}` : `${all_count / 100}`
return { return {
price: Number(formatPriceDiv(estimate_amount)).toFixed(2), price: Number(formatPriceDiv(estimate_amount)).toFixed(2),
countText: `已选 ${product_list.size} 种面料,${color_count} 个颜色,共 ${all_count_text}`, countText: `已选 ${product_list.size} 种面料,${color_count} 个颜色,共 ${all_count_text}`,
@ -233,13 +237,13 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
} }
}, [list, checkboxData]) }, [list, checkboxData])
//去结算 // 去结算
const { fetchData: useFetchData } = GetAdminUserInfoApi() const { fetchData: useFetchData } = GetAdminUserInfoApi()
const { fetchData: applyOrderAccessFetchData } = ApplyOrderAccessApi() const { fetchData: applyOrderAccessFetchData } = ApplyOrderAccessApi()
const orderDetail = throttle(async () => { const orderDetail = throttle(async() => {
let res = await useFetchData() const res = await useFetchData()
if (res.data.order_access_status !== 3) { if (res.data.order_access_status !== 3) {
if (res.data.order_access_status == 1) applyOrderAccessFetchData() if (res.data.order_access_status == 1) { applyOrderAccessFetchData() }
setShowBindSalesman(() => true) setShowBindSalesman(() => true)
onClose?.() onClose?.()
return false return false
@ -247,36 +251,38 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
getSelectId() getSelectId()
if (selectIds.current.length == 0) { if (selectIds.current.length == 0) {
alert.error('请选择面料') alert.error('请选择面料')
} else { }
let ids = selectIds.current.join('-') else {
setParam({ ids, sale_mode: selectIndex }) //临时存储 const ids = selectIds.current.join('-')
setParam({ ids, sale_mode: selectIndex }) // 临时存储
closePopup() closePopup()
if (intoStatus == 'again') { if (intoStatus == 'again') {
goLink('/pages/order/comfirm', {}, 'redirectTo') goLink('/pages/order/comfirm', {}, 'redirectTo')
} else { }
else {
goLink('/pages/order/comfirm') goLink('/pages/order/comfirm')
} }
} }
}, 500) }, 500)
//计数组件-当后端修改完成才修改前端显示 // 计数组件-当后端修改完成才修改前端显示
const { fetchData: fetchDataUpdateShoppingCart } = UpdateShoppingCartApi() const { fetchData: fetchDataUpdateShoppingCart } = UpdateShoppingCartApi()
const [UpdateShoppingCartLoading, setUpdateShoppingCartLoading] = useState(false) const [UpdateShoppingCartLoading, setUpdateShoppingCartLoading] = useState(false)
const getInputValue = debounce(async (num, item) => { const getInputValue = debounce(async(num, item) => {
let roll = item.sale_mode == 0 ? parseFloat(num) : 0 const roll = item.sale_mode == 0 ? parseFloat(num) : 0
let length = item.sale_mode != 0 ? parseFloat(num) * 100 : 0 const length = item.sale_mode != 0 ? parseFloat(num) * 100 : 0
setUpdateShoppingCartLoading(() => true) setUpdateShoppingCartLoading(() => true)
let res = await fetchDataUpdateShoppingCart({ id: item.id, roll, length }) const res = await fetchDataUpdateShoppingCart({ id: item.id, roll, length })
setUpdateShoppingCartLoading(() => false) setUpdateShoppingCartLoading(() => false)
if (res.success) { if (res.success) {
getShoppingCart() getShoppingCart()
} }
}, 300) }, 300)
//绑定业务员和电话号码 // 绑定业务员和电话号码
const [showBindSalesman, setShowBindSalesman] = useState(false) const [showBindSalesman, setShowBindSalesman] = useState(false)
//显示图片弹窗 // 显示图片弹窗
const [showLabImage, setShowLabImage] = useState(false) const [showLabImage, setShowLabImage] = useState(false)
const [labImageValue, setLabImageValue] = useState() const [labImageValue, setLabImageValue] = useState()
const getLabAndImg = useCallback((val) => { const getLabAndImg = useCallback((val) => {
@ -305,7 +311,8 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
<View <View
key={item.value} key={item.value}
onClick={() => selectProduct(item.value)} onClick={() => selectProduct(item.value)}
className={classnames(styles.search_item, selectIndex == item.value && styles.search_item_select)}> className={classnames(styles.search_item, selectIndex == item.value && styles.search_item_select)}
>
{item.title} {item.title}
</View> </View>
) )
@ -320,7 +327,8 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
return ( return (
<View <View
key={item} key={item}
className={classnames(styles.product_item, selectIndex != -1 && selectIndex != item.sale_mode && styles.no_product_item_select)}> className={classnames(styles.product_item, selectIndex != -1 && selectIndex != item.sale_mode && styles.no_product_item_select)}
>
<View className={styles.checkbox}> <View className={styles.checkbox}>
<MCheckbox <MCheckbox
disabled={selectIndex != -1 && selectIndex != item.sale_mode} disabled={selectIndex != -1 && selectIndex != item.sale_mode}
@ -347,16 +355,16 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
</View> </View>
<View className={styles.count}> <View className={styles.count}>
<View className={styles.des}> <View className={styles.des}>
<View className={styles.subtitle}>{item.product_color_code + ' ' + item.product_color_name}</View> <View className={styles.subtitle}>{`${item.product_color_code} ${item.product_color_name}`}</View>
<View className={styles.tag}>{item.sale_mode_name}</View> <View className={styles.tag}>{item.sale_mode_name}</View>
</View> </View>
<View className={styles.btn_count}> <View className={styles.btn_count}>
<Counter <Counter
onBlue={(e) => getInputValue(e, item)} onBlue={e => getInputValue(e, item)}
defaultNum={formatCount(item)} defaultNum={formatCount(item)}
step={selectList[selectIndex].step} step={selectList[selectIndex].step}
digits={selectList[selectIndex].digits} digits={selectList[selectIndex].digits}
onClickBtn={(e) => getInputValue(e, item)} onClickBtn={e => getInputValue(e, item)}
unit={formatUnit(item)} unit={formatUnit(item)}
minNum={selectList[selectIndex].minNum} minNum={selectList[selectIndex].minNum}
maxNum={selectList[selectIndex].maxNum} maxNum={selectList[selectIndex].maxNum}

View File

@ -1,33 +1,33 @@
import { Image, ScrollView, View } from '@tarojs/components' import { Image, ScrollView, View } from '@tarojs/components'
import Popup from '@/components/popup'
import classnames from 'classnames'
import MCheckbox from '@/components/checkbox'
import LoadingCard from '@/components/loadingCard'
import InfiniteScroll from '@/components/infiniteScroll'
import styles from './index.module.scss'
import { useCallback, useEffect, useMemo, useRef, useState, useTransition } from 'react'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import { alert, goLink } from '@/common/common' import classnames from 'classnames'
import { GetShoppingCartApi, DelShoppingCartApi, UpdateShoppingCartApi } from '@/api/shopCart' import { useCallback, useEffect, useMemo, useRef, useState, useTransition } from 'react'
import { formatHashTag, formatImgUrl, formatPriceDiv } from '@/common/fotmat'
import { setParam } from '@/common/system'
import { debounce, throttle } from '@/common/util'
import Counter from '../counter' import Counter from '../counter'
import { ApplyOrderAccessApi, GetAdminUserInfoApi, SubscriptionMessageApi } from '@/api/user'
import useCommonData from '@/use/useCommonData'
import BindSalesmanPopup from '../bindSalesmanPopup' import BindSalesmanPopup from '../bindSalesmanPopup'
import LabAndImgShow from '../LabAndImgShow' import LabAndImgShow from '../LabAndImgShow'
import LabAndImg from '../LabAndImg' import LabAndImg from '../LabAndImg'
import styles from './index.module.scss'
import ProductItem from './components/productItem' import ProductItem from './components/productItem'
import { saleModeType } from '@/common/enum' import Popup from '@/components/popup'
import MCheckbox from '@/components/checkbox'
import LoadingCard from '@/components/loadingCard'
import InfiniteScroll from '@/components/infiniteScroll'
import { alert, goLink } from '@/common/common'
import { DelShoppingCartApi, GetShoppingCartApi, UpdateShoppingCartApi } from '@/api/shopCart'
import { formatHashTag, formatImgUrl, formatPriceDiv } from '@/common/fotmat'
import { setParam } from '@/common/system'
import { debounce, throttle } from '@/common/util'
import { ApplyOrderAccessApi, GetAdminUserInfoApi, SubscriptionMessageApi } from '@/api/user'
import useCommonData from '@/use/useCommonData'
import type { saleModeType } from '@/common/enum'
type param = { interface param {
show?: true | false show?: true | false
onClose?: () => void onClose?: () => void
intoStatus?: 'again' | 'shop' intoStatus?: 'again' | 'shop'
default_sale_mode?: saleModeType //面料类型0大货 1剪版2散剪 default_sale_mode?: saleModeType // 面料类型0大货 1剪版2散剪
} }
type modelClassType = { interface modelClassType {
value: saleModeType value: saleModeType
title: string title: string
unit: string unit: string
@ -47,7 +47,7 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
const [isPending, startTransition] = useTransition() const [isPending, startTransition] = useTransition()
//切换面料类型 // 切换面料类型
const [selectIndex, setSelectIndex] = useState<saleModeType>(default_sale_mode || 0) const [selectIndex, setSelectIndex] = useState<saleModeType>(default_sale_mode || 0)
const selectProduct = (index: 0 | 1 | 2) => { const selectProduct = (index: 0 | 1 | 2) => {
setSelectIndex(index) setSelectIndex(index)
@ -65,26 +65,26 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
}) })
}, [selectIndex]) }, [selectIndex])
//获取购物车数据数量 // 获取购物车数据数量
const { getShopCount } = useCommonData() const { getShopCount } = useCommonData()
//获取所有数据数据 // 获取所有数据数据
const [list, setList] = useState<{ [id: number]: any }>({}) const [list, setList] = useState<Record<number, any>>({})
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const { fetchData: getShoppingFetchData } = GetShoppingCartApi() const { fetchData: getShoppingFetchData } = GetShoppingCartApi()
const getShoppingCart = async () => { const getShoppingCart = async() => {
const { data } = await getShoppingFetchData() const { data } = await getShoppingFetchData()
let color_list = data.color_list || [] const color_list = data.color_list || []
initList(color_list) initList(color_list)
setLoading(false) setLoading(false)
} }
//更新单条数据 // 更新单条数据
const getShoppingCartInfo = async (item) => { const getShoppingCartInfo = async(item) => {
const res = await getShoppingFetchData({ id: item.id }) const res = await getShoppingFetchData({ id: item.id })
if (res.success) { if (res.success) {
let info = res.data.color_list[0] const info = res.data.color_list[0]
let newInfo = { const newInfo = {
...item, ...item,
estimate_amount: info.estimate_amount, estimate_amount: info.estimate_amount,
estimate_weight: info.estimate_weight, estimate_weight: info.estimate_weight,
@ -95,7 +95,7 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
sale_price: info.sale_price, sale_price: info.sale_price,
standard_price: info.standard_price, standard_price: info.standard_price,
} }
setList((e) => ({ ...e, [item['id']]: newInfo })) setList(e => ({ ...e, [item.id]: newInfo }))
} }
} }
@ -103,9 +103,9 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
return Object.values(list) return Object.values(list)
}, [list]) }, [list])
//初始化全部数据默认勾选 // 初始化全部数据默认勾选
const initList = (color_list) => { const initList = (color_list) => {
let obj = {} const obj = {}
color_list?.map((item) => { color_list?.map((item) => {
item.selected = selectIndex == item.sale_mode item.selected = selectIndex == item.sale_mode
const { unit, eunit, step, digits, minNum, maxNum } = selectList[item.sale_mode] const { unit, eunit, step, digits, minNum, maxNum } = selectList[item.sale_mode]
@ -115,25 +115,27 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
setList(() => ({ ...obj })) setList(() => ({ ...obj }))
} }
//重置勾选数据 // 重置勾选数据
const resetList = () => { const resetList = () => {
Object.values(list)?.map((item) => { Object.values(list)?.map((item) => {
if (selectIndex == item.sale_mode) { if (selectIndex == item.sale_mode) {
item.selected = true item.selected = true
} else { }
else {
item.selected = false item.selected = false
} }
list[item['id']] = { ...item } list[item.id] = { ...item }
}) })
setList(() => ({ ...list })) setList(() => ({ ...list }))
} }
//显示时展示数据 // 显示时展示数据
useEffect(() => { useEffect(() => {
if (!show) { if (!show) {
setList({}) setList({})
setSelectIndex(default_sale_mode || 0) setSelectIndex(default_sale_mode || 0)
} else { }
else {
setLoading(true) setLoading(true)
getShoppingCart() getShoppingCart()
setShowBindSalesman(() => false) setShowBindSalesman(() => false)
@ -145,56 +147,56 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
setShowPopup(show) setShowPopup(show)
}, [show]) }, [show])
//全选反选 // 全选反选
const [selectStatus, setSelectStatus] = useState(false) const [selectStatus, setSelectStatus] = useState(false)
const selectAll = () => { const selectAll = () => {
Object.values(list)?.map((item) => { Object.values(list)?.map((item) => {
if (selectIndex == item.sale_mode) { if (selectIndex == item.sale_mode) {
item.selected = !selectStatus item.selected = !selectStatus
list[item['id']] = { ...item } list[item.id] = { ...item }
} }
}) })
setList(() => ({ ...list })) setList(() => ({ ...list }))
setSelectStatus(!selectStatus) setSelectStatus(!selectStatus)
} }
//checkbox选中判断是否全部选中全部选中后是全选否则反选 // checkbox选中判断是否全部选中全部选中后是全选否则反选
useEffect(() => { useEffect(() => {
let list_count = 0 let list_count = 0
let select_count = 0 let select_count = 0
Object.values(list)?.map((item) => { Object.values(list)?.map((item) => {
if (selectIndex == item.sale_mode) { if (selectIndex == item.sale_mode) {
list_count++ list_count++
if (item.selected) select_count++ if (item.selected) { select_count++ }
} }
}) })
setSelectStatus(select_count == list_count) setSelectStatus(select_count == list_count)
}, [list]) }, [list])
//修改数量 // 修改数量
const onChangeCount = useCallback((item) => { const onChangeCount = useCallback((item) => {
getInputValue(item) getInputValue(item)
}, []) }, [])
//修改选择 // 修改选择
const onChangeSelect = useCallback((item) => { const onChangeSelect = useCallback((item) => {
setList((e) => ({ ...e, [item.id]: { ...item } })) setList(e => ({ ...e, [item.id]: { ...item } }))
}, []) }, [])
//popup关闭 // popup关闭
const closePopup = () => { const closePopup = () => {
onClose?.() onClose?.()
setShowPopup(false) setShowPopup(false)
} }
//删除购物车内容 // 删除购物车内容
const { fetchData: delShopFetchData } = DelShoppingCartApi() const { fetchData: delShopFetchData } = DelShoppingCartApi()
const delSelect = () => { const delSelect = () => {
getSelectId() getSelectId()
if (selectIds.current.length <= 0) return alert.none('请选择要删除的面料!') if (selectIds.current.length <= 0) { return alert.none('请选择要删除的面料!') }
Taro.showModal({ Taro.showModal({
content: '删除所选商品?', content: '删除所选商品?',
success: async function (res) { async success(res) {
if (res.confirm) { if (res.confirm) {
const res = await delShopFetchData({ id: selectIds.current }) const res = await delShopFetchData({ id: selectIds.current })
if (res.success) { if (res.success) {
@ -204,20 +206,22 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
title: '成功', title: '成功',
icon: 'success', icon: 'success',
}) })
} else { }
else {
Taro.showToast({ Taro.showToast({
title: res.msg, title: res.msg,
icon: 'none', icon: 'none',
}) })
} }
} else if (res.cancel) { }
else if (res.cancel) {
console.log('用户点击取消') console.log('用户点击取消')
} }
}, },
}) })
} }
//获取面料选中的id // 获取面料选中的id
const selectIds = useRef<number[]>([]) const selectIds = useRef<number[]>([])
const getSelectId = () => { const getSelectId = () => {
selectIds.current = [] selectIds.current = []
@ -228,12 +232,12 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
}) })
} }
//预估金额和总条数 // 预估金额和总条数
const estimatePrice = useMemo(() => { const estimatePrice = useMemo(() => {
let estimate_amount = 0 let estimate_amount = 0
let product_list = new Set() //面料 const product_list = new Set() // 面料
let color_count = 0 //颜色数量 let color_count = 0 // 颜色数量
let all_count = 0 //总数量 let all_count = 0 // 总数量
Object.values(list)?.map((item) => { Object.values(list)?.map((item) => {
if (item.selected) { if (item.selected) {
estimate_amount += item.estimate_amount estimate_amount += item.estimate_amount
@ -242,7 +246,7 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
all_count += item.sale_mode == 0 ? parseFloat(item.roll) : parseFloat(item.length) all_count += item.sale_mode == 0 ? parseFloat(item.roll) : parseFloat(item.length)
} }
}) })
let all_count_text = selectIndex == 0 ? all_count + ' 条' : all_count / 100 + ' 米' const all_count_text = selectIndex == 0 ? `${all_count}` : `${all_count / 100}`
console.log('text::', list) console.log('text::', list)
return { return {
price: Number(formatPriceDiv(estimate_amount)).toFixed(2), price: Number(formatPriceDiv(estimate_amount)).toFixed(2),
@ -251,13 +255,13 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
} }
}, [list]) }, [list])
//去结算 // 去结算
const { fetchData: useFetchData } = GetAdminUserInfoApi() const { fetchData: useFetchData } = GetAdminUserInfoApi()
const { fetchData: applyOrderAccessFetchData } = ApplyOrderAccessApi() const { fetchData: applyOrderAccessFetchData } = ApplyOrderAccessApi()
const orderDetail = throttle(async () => { const orderDetail = throttle(async() => {
let res = await useFetchData() const res = await useFetchData()
if (res.data.order_access_status !== 3) { if (res.data.order_access_status !== 3) {
if (res.data.order_access_status == 1) applyOrderAccessFetchData() if (res.data.order_access_status == 1) { applyOrderAccessFetchData() }
setShowBindSalesman(() => true) setShowBindSalesman(() => true)
onClose?.() onClose?.()
return false return false
@ -265,34 +269,37 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
getSelectId() getSelectId()
if (selectIds.current.length == 0) { if (selectIds.current.length == 0) {
alert.error('请选择面料') alert.error('请选择面料')
} else { }
let ids = selectIds.current.join('-') else {
setParam({ ids, sale_mode: selectIndex }) //临时存储 const ids = selectIds.current.join('-')
setParam({ ids, sale_mode: selectIndex }) // 临时存储
closePopup() closePopup()
if (intoStatus == 'again') { if (intoStatus == 'again') {
goLink('/pages/order/comfirm', null, 'redirectTo') goLink('/pages/order/comfirm', null, 'redirectTo')
} else { }
else {
goLink('/pages/order/comfirm') goLink('/pages/order/comfirm')
} }
} }
}, 500) }, 500)
//计数组件-当后端修改完成才修改前端显示 // 计数组件-当后端修改完成才修改前端显示
const { fetchData: fetchDataUpdateShoppingCart } = UpdateShoppingCartApi() const { fetchData: fetchDataUpdateShoppingCart } = UpdateShoppingCartApi()
const getInputValue = debounce(async (item) => { const getInputValue = debounce(async(item) => {
let res = await fetchDataUpdateShoppingCart({ id: item.id, roll: item.roll, length: item.length }) const res = await fetchDataUpdateShoppingCart({ id: item.id, roll: item.roll, length: item.length })
if (res.success) { if (res.success) {
console.log('item修改', item) console.log('item修改', item)
getShoppingCartInfo(item) getShoppingCartInfo(item)
} else { }
setList((e) => ({ ...e })) else {
setList(e => ({ ...e }))
} }
}, 300) }, 300)
//绑定业务员和电话号码 // 绑定业务员和电话号码
const [showBindSalesman, setShowBindSalesman] = useState(false) const [showBindSalesman, setShowBindSalesman] = useState(false)
//显示图片弹窗 // 显示图片弹窗
const [showLabImage, setShowLabImage] = useState(false) const [showLabImage, setShowLabImage] = useState(false)
const [labImageValue, setLabImageValue] = useState() const [labImageValue, setLabImageValue] = useState()
const getLabAndImg = useCallback((val) => { const getLabAndImg = useCallback((val) => {
@ -326,7 +333,8 @@ export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode
<View <View
key={item.value} key={item.value}
onClick={() => selectProduct(item.value)} onClick={() => selectProduct(item.value)}
className={classnames(styles.search_item, selectIndex == item.value && styles.search_item_select)}> className={classnames(styles.search_item, selectIndex == item.value && styles.search_item_select)}
>
{item.title} {item.title}
</View> </View>
) )

View File

@ -1,14 +1,16 @@
import { ScrollView, View } from '@tarojs/components' import { ScrollView, View } from '@tarojs/components'
import React, { memo, ReactNode, useEffect, useLayoutEffect, useRef, useState } from 'react'
import styles from './index.module.scss'
import classnames from 'classnames'
import Taro, { getCurrentInstance, useReady, useRouter } from '@tarojs/taro' import Taro, { getCurrentInstance, useReady, useRouter } from '@tarojs/taro'
import InfiniteScroll, { StatusParam } from '../infiniteScroll' import type { ReactNode } from 'react'
import React, { memo, useEffect, useLayoutEffect, useRef, useState } from 'react'
import classnames from 'classnames'
import type { StatusParam } from '../infiniteScroll'
import InfiniteScroll from '../infiniteScroll'
import LoadingCard from '../loadingCard' import LoadingCard from '../loadingCard'
import styles from './index.module.scss'
import ProductClass from '@/pages/index/components/productClass' import ProductClass from '@/pages/index/components/productClass'
import { GetClassList } from '@/api/material' import { GetClassList } from '@/api/material'
type Params = { interface Params {
list?: any[] list?: any[]
defaultValue?: number | string defaultValue?: number | string
children?: ReactNode children?: ReactNode
@ -38,7 +40,7 @@ export default memo(
statusMore = 0, statusMore = 0,
selectClass, selectClass,
}: Params) => { }: Params) => {
let num_half = useRef(0) const num_half = useRef(0)
const [selected, setSelected] = useState(defaultValue) const [selected, setSelected] = useState(defaultValue)
const [tabId, setTabId] = useState('') const [tabId, setTabId] = useState('')
@ -66,24 +68,25 @@ export default memo(
const computeSelectTab = (index) => { const computeSelectTab = (index) => {
if (index + 1 > num_half.current) { if (index + 1 > num_half.current) {
let num = index + 1 - num_half.current const num = index + 1 - num_half.current
setTabId(list[num].id.toString()) setTabId(list[num].id.toString())
} else { }
else {
setTabId(list[0].id.toString()) setTabId(list[0].id.toString())
} }
} }
useEffect(() => { useEffect(() => {
Taro.nextTick(() => { Taro.nextTick(() => {
let query = Taro.createSelectorQuery() const query = Taro.createSelectorQuery()
query query
.select('.side_bar_select') .select('.side_bar_select')
.boundingClientRect((rect) => { .boundingClientRect((rect) => {
console.log('rect::', rect) console.log('rect::', rect)
let clientHeight = rect.height const clientHeight = rect.height
let clientWidth = rect.width const clientWidth = rect.width
let ratio = 750 / clientWidth const ratio = 750 / clientWidth
let height = clientHeight * ratio const height = clientHeight * ratio
num_half.current = Math.ceil(height / 2 / heightItem) num_half.current = Math.ceil(height / 2 / heightItem)
console.log('num_half::', num_half) console.log('num_half::', num_half)
init() init()
@ -92,13 +95,13 @@ export default memo(
}) })
}, []) }, [])
//二级面料系列分类 // 二级面料系列分类
const [openClass, setOpenClass] = useState(false) const [openClass, setOpenClass] = useState(false)
const [classList, setClassList] = useState([]) const [classList, setClassList] = useState([])
const [classId, setClassId] = useState(-1) const [classId, setClassId] = useState(-1)
const { fetchData } = GetClassList() const { fetchData } = GetClassList()
const getClassData = async (id) => { const getClassData = async(id) => {
let res = await fetchData({ id }) const res = await fetchData({ id })
if (res.success) { if (res.success) {
if (res.data?.list.length > 0) { if (res.data?.list.length > 0) {
res.data.list = [{ id: -1, name: '全部' }, ...res.data.list] res.data.list = [{ id: -1, name: '全部' }, ...res.data.list]
@ -107,7 +110,7 @@ export default memo(
} }
} }
useEffect(() => { useEffect(() => {
if (selected) getClassData(selected) if (selected) { getClassData(selected) }
}, [selected]) }, [selected])
const getSelectClass = (id) => { const getSelectClass = (id) => {
@ -118,13 +121,14 @@ export default memo(
return ( return (
<> <>
<View className={classnames(styles.sideBar_main, 'side_bar_select')}> <View className={classnames(styles.sideBar_main, 'side_bar_select')}>
<ScrollView scrollWithAnimation={true} style={{ height }} className={styles.sideBar_select} scrollY scrollIntoView={`tab_${tabId}`}> <ScrollView scrollWithAnimation style={{ height }} className={styles.sideBar_select} scrollY scrollIntoView={`tab_${tabId}`}>
{list?.map((item, index) => { {list?.map((item, index) => {
return ( return (
<View className={styles.sideBar_select_title} id={`tab_${item.id}`} key={item.id} style={{ height: `${heightItem}rpx` }}> <View className={styles.sideBar_select_title} id={`tab_${item.id}`} key={item.id} style={{ height: `${heightItem}rpx` }}>
<View <View
className={classnames(styles.sideBar_select_title_item, { [styles.sideBar_select_title_select]: selected == item.id })} className={classnames(styles.sideBar_select_title_item, { [styles.sideBar_select_title_select]: selected == item.id })}
onClick={() => clickEvent({ item, index })}> onClick={() => clickEvent({ item, index })}
>
<View className={styles.title_con}>{item.name}</View> <View className={styles.title_con}>{item.name}</View>
</View> </View>
</View> </View>
@ -134,7 +138,7 @@ export default memo(
<View className={styles.sideBar_con} style={{ paddingTop: classList.length > 0 ? '90rpx' : '20rpx' }}> <View className={styles.sideBar_con} style={{ paddingTop: classList.length > 0 ? '90rpx' : '20rpx' }}>
{classList.length > 0 && ( {classList.length > 0 && (
<View className={styles.product_class} style={{ height: openClass ? '100%' : '' }}> <View className={styles.product_class} style={{ height: openClass ? '100%' : '' }}>
<ProductClass list={classList} open={openClass} onOpenClick={(val) => setOpenClass(val)} onSelect={getSelectClass} defaultSelectId={classId} /> <ProductClass list={classList} open={openClass} onOpenClick={val => setOpenClass(val)} onSelect={getSelectClass} defaultSelectId={classId} />
</View> </View>
)} )}
<InfiniteScroll <InfiniteScroll
@ -142,8 +146,9 @@ export default memo(
hasMore={hasMore} hasMore={hasMore}
selfonScrollToLower={() => selfOnScrolltolower?.()} selfonScrollToLower={() => selfOnScrolltolower?.()}
refresherTriggered={refresherTriggered} refresherTriggered={refresherTriggered}
refresherEnabled={true} refresherEnabled
selfOnRefresherRefresh={() => selfOnRefresherRefresh?.()}> selfOnRefresherRefresh={() => selfOnRefresherRefresh?.()}
>
{children} {children}
</InfiniteScroll> </InfiniteScroll>
</View> </View>

View File

@ -1,45 +1,45 @@
import { View } from "@tarojs/components" import { View } from '@tarojs/components'
import classnames from "classnames"; import classnames from 'classnames'
import { forwardRef, useEffect, useImperativeHandle, useState } from "react"; import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'
import styles from './index.module.scss' import styles from './index.module.scss'
type params = { interface params {
status?: 'top'|'bottom'|'none', status?: 'top'|'bottom'|'none'
onChange?: (val:{status:string, value:string}) => void, onChange?: (val: { status: string; value: string }) => void
sortValue?: {desc: string, asc: string} //排序规则,后端制定 sortValue?: { desc: string; asc: string } // 排序规则,后端制定
} }
type sortParam = 'none'|'top'|'bottom' type sortParam = 'none'|'top'|'bottom'
export default forwardRef(({status = 'none', onChange, sortValue}: params,ref) => { export default forwardRef(({ status = 'none', onChange, sortValue }: params, ref) => {
const [sortStatus, setSortStatus] = useState<sortParam>() const [sortStatus, setSortStatus] = useState<sortParam>()
useEffect(() => { useEffect(() => {
setSortStatus(() => status) setSortStatus(() => status)
}, [status]) }, [status])
const changeSort = ():{status:sortParam, value:string} => { const changeSort = (): { status: sortParam; value: string } => {
let status:sortParam = 'none' let status: sortParam = 'none'
let value = '' let value = ''
if(sortStatus == 'none') { if (sortStatus == 'none') {
status = 'top' status = 'top'
value = sortValue?.asc! value = sortValue?.asc!
}
if(sortStatus == 'top') {
status = 'bottom'
value = sortValue?.desc!
}
if(sortStatus == 'bottom') status = 'none'
setSortStatus(() => status)
onChange?.({status, value})
return {status, value}
} }
useImperativeHandle(ref, () => ({ if (sortStatus == 'top') {
changeSort status = 'bottom'
})) value = sortValue?.desc!
}
return ( if (sortStatus == 'bottom') { status = 'none' }
<> setSortStatus(() => status)
<View className={styles.click} onClick={changeSort}> onChange?.({ status, value })
<View className={classnames(styles.top, sortStatus == 'top'&&styles.selected)} ></View> return { status, value }
<View className={classnames(styles.bottom, sortStatus == 'bottom'&&styles.selected)}></View> }
</View> useImperativeHandle(ref, () => ({
</> changeSort,
) }))
})
return (
<>
<View className={styles.click} onClick={changeSort}>
<View className={classnames(styles.top, sortStatus == 'top' && styles.selected)} ></View>
<View className={classnames(styles.bottom, sortStatus == 'bottom' && styles.selected)}></View>
</View>
</>
)
})

View File

@ -1,61 +1,60 @@
import { ScrollView, View } from "@tarojs/components"; import { ScrollView, View } from '@tarojs/components'
import { memo, useState, ReactNode, useEffect } from "react"; import type { ReactNode } from 'react'
import classnames from "classnames"; import { memo, useEffect, useState } from 'react'
import classnames from 'classnames'
import styles from './index.module.scss' import styles from './index.module.scss'
interface ListProps {
type ListProps = { title: string
title: string, value: number
value: number
} }
type Params = { interface Params {
list?: ListProps[], list?: ListProps[]
defaultValue?: number|string, defaultValue?: number|string
children?: ReactNode, children?: ReactNode
tabsOnClick?: (ListProps) => void, tabsOnClick?: (ListProps) => void
style?:Object, style?: Object
} }
export default memo(({list = [], defaultValue = 0, tabsOnClick, style={}}: Params) => { export default memo(({ list = [], defaultValue = 0, tabsOnClick, style = {} }: Params) => {
const [selected, setSelected] = useState(defaultValue)
const [selected, setSelected] = useState(defaultValue) const [tabId, setTabId] = useState('')
const [tabId, setTabId] = useState('')
useEffect(() => { useEffect(() => {
const index = list?.findIndex(item => { const index = list?.findIndex((item) => {
return item.value == defaultValue return item.value == defaultValue
}) })
if(index !== -1) { if (index !== -1) {
const num = index > 0?( index - 1) : 0 const num = index > 0 ? (index - 1) : 0
setTabId(list[num].value.toString()) setTabId(list[num].value.toString())
}
}, [])
const clickEvent = ({item, index}: {item:ListProps, index:number}) => {
setSelected(item.value)
tabsOnClick?.(item)
const num = index > 0?( index - 1) : 0
setTabId(list[num].value.toString())
} }
return ( }, [])
<>
<View className={styles.tabs_main} id="tabs_main_ref"> const clickEvent = ({ item, index }: { item: ListProps; index: number }) => {
<ScrollView className={styles.tabs_scroll} scrollX scrollWithAnimation={true} scrollIntoView={`tabs_${tabId}`}> setSelected(item.value)
<View className={styles.tabs_scroll}> tabsOnClick?.(item)
{ const num = index > 0 ? (index - 1) : 0
list.map((item, index) => { setTabId(list[num].value.toString())
return ( }
<View key={item.value} id={`tabs_${item.value}`} className={styles.tabs_item} onClick={() => clickEvent({item,index})}> return (
<View className={classnames(styles.tabs_item_con, {[styles.tabs_item_select]:selected == item.value})}>{item.title}</View> <>
</View> <View className={styles.tabs_main} id="tabs_main_ref">
) <ScrollView className={styles.tabs_scroll} scrollX scrollWithAnimation scrollIntoView={`tabs_${tabId}`}>
}) <View className={styles.tabs_scroll}>
} {
</View> list.map((item, index) => {
</ScrollView> return (
</View> <View key={item.value} id={`tabs_${item.value}`} className={styles.tabs_item} onClick={() => clickEvent({ item, index })}>
</> <View className={classnames(styles.tabs_item_con, { [styles.tabs_item_select]: selected == item.value })}>{item.title}</View>
) </View>
}) )
})
}
</View>
</ScrollView>
</View>
</>
)
})

View File

@ -1,48 +1,48 @@
import {Textarea, View } from "@tarojs/components"; import { Textarea, View } from '@tarojs/components'
import { memo, useEffect, useMemo, useState } from "react"; import { memo, useEffect, useMemo, useState } from 'react'
import styles from './index.module.scss' import classnames from 'classnames'
import classnames from "classnames"; import styles from './index.module.scss'
//其他说明 // 其他说明
type Param = { interface Param {
title?: string, title?: string
onChange?: (val: string) => void, onChange?: (val: string) => void
placeholder?: string, placeholder?: string
defaultValue?: string, defaultValue?: string
onlyRead?: false|true onlyRead?: false|true
} }
export default memo(({onChange, title = '', placeholder = '请输入', defaultValue, onlyRead = false}:Param) => { export default memo(({ onChange, title = '', placeholder = '请输入', defaultValue, onlyRead = false }: Param) => {
const [descData, setDescData] = useState({ const [descData, setDescData] = useState({
number: 0, number: 0,
value: '', value: '',
count: 200, count: 200,
show: false show: false,
}) })
const getDesc = (value = '') => { const getDesc = (value = '') => {
let res = value let res = value
if(value.length > descData.count) { if (value.length > descData.count) {
res = value.slice(0, descData.count) res = value.slice(0, descData.count)
}
setDescData({ ...descData, number: res.length, value: res })
onChange?.(res)
}
useEffect(() => {
getDesc(defaultValue)
}, [defaultValue])
const toggleShowRealTextarea = (show) => {
setDescData({ ...descData, show })
}
return (
<View className={styles.other_desc}>
<View className={styles.title}>{title}</View>
<View className={styles.textarea}>
{(descData.show && !onlyRead) && <Textarea autoFocus value={descData.value} onBlur={() => toggleShowRealTextarea(false)} className={styles.textarea_con} cursorSpacing={100} maxlength={descData.count} onInput={e => getDesc(e.detail.value)}></Textarea>
|| <View className={classnames(styles.textarea_con_pretend, descData.value && styles.textarea_con_pretend_ed)} onClick={() => toggleShowRealTextarea(true)}>{descData.value || placeholder}</View>
} }
setDescData({...descData, number:res.length, value: res}) <View className={styles.descDataNum}>{`${descData.number}/${descData.count}`}</View>
onChange?.(res) </View>
} </View>
)
useEffect(() => {
getDesc(defaultValue)
}, [defaultValue])
const toggleShowRealTextarea = (show) => {
setDescData({...descData, show:show})
}
return (
<View className={styles.other_desc}>
<View className={styles.title}>{title}</View>
<View className={styles.textarea}>
{(descData.show && !onlyRead)&&<Textarea autoFocus value={descData.value} onBlur={() => toggleShowRealTextarea(false)} className={styles.textarea_con} cursorSpacing={100} maxlength={descData.count} onInput={(e) => getDesc(e.detail.value)}></Textarea>||
<View className={classnames(styles.textarea_con_pretend, descData.value&&styles.textarea_con_pretend_ed)} onClick={() => toggleShowRealTextarea(true)}>{descData.value||placeholder}</View>
}
<View className={styles.descDataNum}>{descData.number +'/'+ descData.count}</View>
</View>
</View>
)
}) })

View File

@ -1,13 +1,13 @@
import Taro, { FC } from '@tarojs/taro' import Taro from '@tarojs/taro'
import { memo, useEffect, useState } from 'react'
import useUploadCDNImg from '@/use/useUploadImage'
import { Image, Text, View } from '@tarojs/components' import { Image, Text, View } from '@tarojs/components'
import { formatImgUrl } from '@/common/fotmat' import { FC, memo, useEffect, useState } from 'react'
import classnames from 'classnames' import classnames from 'classnames'
import styles from './index.module.scss' import styles from './index.module.scss'
import useUploadCDNImg from '@/use/useUploadImage'
import { formatImgUrl } from '@/common/fotmat'
//图片列表 // 图片列表
type ImageParam = { interface ImageParam {
onChange?: (val: string[]) => void onChange?: (val: string[]) => void
defaultList?: string[] defaultList?: string[]
onlyRead?: false | true onlyRead?: false | true
@ -20,28 +20,28 @@ const PictureItem: FC<ImageParam> = memo(({ onChange, defaultList, onlyRead = fa
setImageLise(defaultList || []) setImageLise(defaultList || [])
}, [defaultList]) }, [defaultList])
//上传图片 // 上传图片
const uploadImage = async () => { const uploadImage = async() => {
let list: any = await getWxPhoto('after-sale', 5) const list: any = await getWxPhoto('after-sale', 5)
let images: any[] = [] const images: any[] = []
list?.map((item) => { list?.map((item) => {
images.push(item.url) images.push(item.url)
}) })
setImageLise([...imageList, ...images]) setImageLise([...imageList, ...images])
} }
//删除图片 // 删除图片
const delImage = (index) => { const delImage = (index) => {
imageList.splice(index, 1) imageList.splice(index, 1)
setImageLise(() => [...imageList]) setImageLise(() => [...imageList])
} }
//监听上传的图片变化 // 监听上传的图片变化
useEffect(() => { useEffect(() => {
onChange?.(imageList) onChange?.(imageList)
}, [imageList]) }, [imageList])
//预览图片 // 预览图片
const showImage = () => { const showImage = () => {
let list = imageList?.map((item) => { const list = imageList?.map((item) => {
return formatImgUrl(item, '!w800') return formatImgUrl(item, '!w800')
}) })
Taro.previewImage({ Taro.previewImage({
@ -54,7 +54,7 @@ const PictureItem: FC<ImageParam> = memo(({ onChange, defaultList, onlyRead = fa
<View className={styles.image_main}> <View className={styles.image_main}>
{imageList?.map((item, index) => ( {imageList?.map((item, index) => (
<View className={styles.ImgItem}> <View className={styles.ImgItem}>
<Image mode='aspectFill' src={formatImgUrl(item)} onClick={showImage}></Image> <Image mode="aspectFill" src={formatImgUrl(item)} onClick={showImage}></Image>
{!onlyRead && <View onClick={() => delImage(index)} className={classnames(styles.miconfont_close, 'iconfont icon-qingkong')}></View>} {!onlyRead && <View onClick={() => delImage(index)} className={classnames(styles.miconfont_close, 'iconfont icon-qingkong')}></View>}
</View> </View>
))} ))}

View File

@ -1,3 +1,3 @@
export const SET_SHOPCOUNT = 'set_shopCount' export const SET_SHOPCOUNT = 'set_shopCount'
export const CLEAR_SHOPCOUNT = 'clear_shopCount' export const CLEAR_SHOPCOUNT = 'clear_shopCount'
export const STORAGE_SHOPCOUNT = 'storage_shopcount' export const STORAGE_SHOPCOUNT = 'storage_shopcount'

View File

@ -8,4 +8,4 @@ export const CLEAR_SESSIONKEY = 'clearSessionkey'
export const CLEAR_USERINFO = 'clearUserInfo' export const CLEAR_USERINFO = 'clearUserInfo'
export const CLEAR_ADMINUSERINFO = 'clearAdminUserInfo' export const CLEAR_ADMINUSERINFO = 'clearAdminUserInfo'
export const CLEAR_SORTCODE = 'clearSortCode' export const CLEAR_SORTCODE = 'clearSortCode'
export const LOGIN_STATUS = 'loginStatus' export const LOGIN_STATUS = 'loginStatus'

View File

@ -1,9 +1,9 @@
import { alert, retrieval } from '@/common/common'
import Address from '@/components/address'
import FromList from '@/components/FromList'
import { Button, Input, Text, Textarea, View } from '@tarojs/components' import { Button, Input, Text, Textarea, View } from '@tarojs/components'
import Taro, { setNavigationBarTitle, useRouter } from '@tarojs/taro' import Taro, { setNavigationBarTitle, useRouter } from '@tarojs/taro'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { alert, retrieval } from '@/common/common'
import Address from '@/components/address'
import FromList from '@/components/FromList'
import './index.scss' import './index.scss'
import { addressAddApi, addressDetailApi, addressEditApi } from '@/api/addressManager' import { addressAddApi, addressDetailApi, addressEditApi } from '@/api/addressManager'
import useLogin from '@/use/useLogin' import useLogin from '@/use/useLogin'
@ -15,14 +15,15 @@ export default () => {
useEffect(() => { useEffect(() => {
if (type == 'add') { if (type == 'add') {
setNavigationBarTitle({ title: '新增收货地址' }) setNavigationBarTitle({ title: '新增收货地址' })
} else { }
else {
initalFormData() initalFormData()
setNavigationBarTitle({ title: '编辑收货地址' }) setNavigationBarTitle({ title: '编辑收货地址' })
} }
}, []) }, [])
// 获取编辑地址信息 // 获取编辑地址信息
const { fetchData: getFromData } = addressDetailApi() const { fetchData: getFromData } = addressDetailApi()
const initalFormData = async () => { const initalFormData = async() => {
const detail = await getFromData({ id }) const detail = await getFromData({ id })
const { province_id, province_name, city_id, city_name, district_id, district_name } = detail.data const { province_id, province_name, city_id, city_name, district_id, district_name } = detail.data
const siteArray = [{ id: province_id, name: province_name }] const siteArray = [{ id: province_id, name: province_name }]
@ -31,7 +32,7 @@ export default () => {
setFormData({ setFormData({
name: detail.data.name, name: detail.data.name,
phone: detail.data.phone, phone: detail.data.phone,
site: siteArray.map((item) => item.name).join(' '), site: siteArray.map(item => item.name).join(' '),
siteArray: siteArray as any, siteArray: siteArray as any,
district_id: detail.data.district_id, district_id: detail.data.district_id,
address_detail: detail.data.address_detail, address_detail: detail.data.address_detail,
@ -81,29 +82,30 @@ export default () => {
} }
const handleSave = () => { const handleSave = () => {
retrieval(formData, rules) retrieval(formData, rules)
.then(async () => { .then(async() => {
const result = const result
type == 'add' = type == 'add'
? await fetchData({ ? await fetchData({
name: formData.name, name: formData.name,
phone: formData.phone, phone: formData.phone,
district_id: formData.district_id, district_id: formData.district_id,
address_detail: formData.address_detail, address_detail: formData.address_detail,
is_default: formData.is_default, is_default: formData.is_default,
}) })
: await editFetch({ : await editFetch({
name: formData.name, name: formData.name,
phone: formData.phone, phone: formData.phone,
district_id: formData.district_id, district_id: formData.district_id,
address_detail: formData.address_detail, address_detail: formData.address_detail,
is_default: formData.is_default, is_default: formData.is_default,
id: formData.id, id: formData.id,
}) })
if (result.success) { if (result.success) {
Taro.eventCenter.trigger('addressList:refresh') Taro.eventCenter.trigger('addressList:refresh')
Taro.navigateBack() Taro.navigateBack()
alert.success('保存成功') alert.success('保存成功')
} else { }
else {
alert.error(result.msg) alert.error(result.msg)
} }
}) })
@ -126,51 +128,54 @@ export default () => {
setFormData({ setFormData({
...formData, ...formData,
siteArray: ev, siteArray: ev,
site: ev.map((item) => item.name + ' '), site: ev.map(item => `${item.name} `),
district_id: ev[ev.length - 1]?.id, district_id: ev[ev.length - 1]?.id,
}) })
} else { }
else {
alert.error('请选择地址') alert.error('请选择地址')
} }
} }
return ( return (
<View className='add-address'> <View className="add-address">
<FromList <FromList
onInput={(ev: any) => setFormData({ ...formData, name: ev.detail.value })} onInput={(ev: any) => setFormData({ ...formData, name: ev.detail.value })}
value={formData['name']} value={formData.name}
label='联系人' label="联系人"
placeholder='请输入收货人姓名' placeholder="请输入收货人姓名"
/> />
<FromList <FromList
primordialType='number' primordialType="number"
onInput={(ev: any) => setFormData({ ...formData, phone: ev.detail.value })} onInput={(ev: any) => setFormData({ ...formData, phone: ev.detail.value })}
value={formData['phone']} value={formData.phone}
label='联系方式' label="联系方式"
placeholder='请输入联系方式' placeholder="请输入联系方式"
/> />
<FromList value={formData['site']} onClick={() => setShowSiteModal(true)} label='收货地址' type='select' placeholder='请选择/省/市/区' /> <FromList value={formData.site} onClick={() => setShowSiteModal(true)} label="收货地址" type="select" placeholder="请选择/省/市/区" />
<FromList <FromList
onInput={(ev: any) => setFormData({ ...formData, address_detail: ev.detail.value })} onInput={(ev: any) => setFormData({ ...formData, address_detail: ev.detail.value })}
value={formData['address_detail']} value={formData.address_detail}
label='详细地址' label="详细地址"
type='textarea' type="textarea"
placeholder='请输入详细地址(街道、门牌号等)' placeholder="请输入详细地址(街道、门牌号等)"
/> />
<View className='add-address-default'> <View className="add-address-default">
<Text></Text> <Text></Text>
<View onClick={() => setFormData({ ...formData, is_default: !formData.is_default })}> <View onClick={() => setFormData({ ...formData, is_default: !formData.is_default })}>
{formData.is_default ? ( {formData.is_default
<View className='add-address-default-active'> ? (
<Text className='iconfont icon-tick' /> <View className="add-address-default-active">
</View> <Text className="iconfont icon-tick" />
) : ( </View>
<View className='add-address-default-noactive'></View> )
)} : (
<View className="add-address-default-noactive"></View>
)}
</View> </View>
</View> </View>
<Button style={{ background: hozon ? '#007aff' : '' }} hoverClass='none' className={`add-address-save`} onClick={handleSave}> <Button style={{ background: hozon ? '#007aff' : '' }} hoverClass="none" className="add-address-save" onClick={handleSave}>
</Button> </Button>
<Address addressOnChange={handleSetSite} defaultValue={formData.siteArray} addressOnClose={() => setShowSiteModal(false)} show={showSiteModal} /> <Address addressOnChange={handleSetSite} defaultValue={formData.siteArray} addressOnClose={() => setShowSiteModal(false)} show={showSiteModal} />

View File

@ -1,16 +1,16 @@
import AddressList from "@/components/AddressList" import { Button, ScrollView, Text, View } from '@tarojs/components'
import useLogin from "@/use/useLogin" import { stopPullDownRefresh, usePullDownRefresh } from '@tarojs/taro'
import { Button, ScrollView, Text, View } from "@tarojs/components" import { useState } from 'react'
import { stopPullDownRefresh, usePullDownRefresh } from "@tarojs/taro" import useLogin from '@/use/useLogin'
import { useState } from "react" import AddressList from '@/components/AddressList'
import "./index.scss" import './index.scss'
export default ()=>{ export default () => {
useLogin() useLogin()
return ( return (
<View className="address-manager"> <View className="address-manager">
<AddressList refresherEnabled={true}/> <AddressList refresherEnabled />
</View> </View>
) )
} }

View File

@ -1,56 +1,56 @@
import { formatHashTag, formatImgUrl } from "@/common/fotmat"; import { Image, Text, View } from '@tarojs/components'
import Counter from "@/components/counter"; import type { FC } from 'react'
import MCheckbox from "@/components/checkbox"; import { memo, useCallback } from 'react'
import { Image, Text, View } from "@tarojs/components"; import styles from './index.module.scss'
import { FC, memo, useCallback } from "react"; import { formatHashTag, formatImgUrl } from '@/common/fotmat'
import styles from './index.module.scss' import Counter from '@/components/counter'
import MCheckbox from '@/components/checkbox'
type OrderParam = { interface OrderParam {
list?: any[], list?: any[]
sale_mode?: number, sale_mode?: number
sale_mode_name?: string, sale_mode_name?: string
unit?: string, unit?: string
total_colors?: number, total_colors?: number
total_fabrics?: number, total_fabrics?: number
total_number?: number, total_number?: number
status?: number, //订单状态 status?: number // 订单状态
av_return_product?: any[] //申请售后列表 av_return_product?: any[] // 申请售后列表
} }
type Param = { interface Param {
order: OrderParam, order: OrderParam
onSelectChange?: (val: {color_id:number, length: number, status: true|false, sale_order_detail_id:number}) => void onSelectChange?: (val: { color_id: number; length: number; status: true|false; sale_order_detail_id: number }) => void
} }
const kindeList:FC<Param> = memo(({order, onSelectChange}) => { const kindeList: FC<Param> = memo(({ order, onSelectChange }) => {
// checkbox选中回调
const selectCallBack = (colorItem) => {
onSelectChange?.({ color_id: colorItem.product_color_id, length: colorItem.length, sale_order_detail_id: colorItem.sale_order_detail_id, status: true })
}
//checkbox选中回调 // checkbox关闭回调
const selectCallBack = (colorItem) => { const colseCallBack = (colorItem) => {
onSelectChange?.({color_id:colorItem.product_color_id, length:colorItem.length, sale_order_detail_id:colorItem.sale_order_detail_id, status: true}) onSelectChange?.({ color_id: colorItem.product_color_id, length: colorItem.length, status: false, sale_order_detail_id: colorItem.sale_order_detail_id })
} }
//checkbox关闭回调 return (
const colseCallBack = (colorItem) => { <View className={styles.apply_after_sales_list}>
onSelectChange?.({color_id:colorItem.product_color_id, length:colorItem.length, status: false, sale_order_detail_id:colorItem.sale_order_detail_id,}) {order?.av_return_product?.map(item => <View className={styles.apply_after_sales_item} >
} <View className={styles.apply_after_sales_title}>
<View className={styles.tag}>{order.sale_mode_name}</View>
return ( <View className={styles.title}>{formatHashTag(item.product_code, item.product_name)}</View>
<View className={styles.apply_after_sales_list}>
{order?.av_return_product?.map(item => <View className={styles.apply_after_sales_item} >
<View className={styles.apply_after_sales_title}>
<View className={styles.tag}>{order.sale_mode_name}</View>
<View className={styles.title}>{formatHashTag(item.product_code, item.product_name)}</View>
</View>
<View className={styles.color_list}>
{item?.av_product_color?.map(colorItem => <View className={styles.color_item}>
<View className={styles.image}><Image src={formatImgUrl('')}/></View>
<View className={styles.name_and_number}><Text>{colorItem.product_color_code + ' ' + colorItem.product_color_name}</Text><Text>x {colorItem.length/100} m</Text></View>
<MCheckbox status={item.select} onSelect={() => selectCallBack(colorItem)} onClose={() => colseCallBack(colorItem)}/>
</View>)}
</View>
</View>)}
</View> </View>
) <View className={styles.color_list}>
{item?.av_product_color?.map(colorItem => <View className={styles.color_item}>
<View className={styles.image}><Image src={formatImgUrl('')} /></View>
<View className={styles.name_and_number}><Text>{`${colorItem.product_color_code} ${colorItem.product_color_name}`}</Text><Text>x {colorItem.length / 100} m</Text></View>
<MCheckbox status={item.select} onSelect={() => selectCallBack(colorItem)} onClose={() => colseCallBack(colorItem)} />
</View>)}
</View>
</View>)}
</View>
)
}) })
export default kindeList export default kindeList

View File

@ -1,55 +1,55 @@
import { formatHashTag, formatImgUrl } from "@/common/fotmat"; import { Image, Text, View } from '@tarojs/components'
import Counter from "@/components/counter"; import type { FC } from 'react'
import MCheckbox from "@/components/checkbox"; import { memo, useCallback } from 'react'
import { Image, Text, View } from "@tarojs/components"; import styles from './index.module.scss'
import { FC, memo, useCallback } from "react"; import { formatHashTag, formatImgUrl } from '@/common/fotmat'
import styles from './index.module.scss' import Counter from '@/components/counter'
import MCheckbox from '@/components/checkbox'
type OrderParam = { interface OrderParam {
list?: any[], list?: any[]
sale_mode?: number, sale_mode?: number
sale_mode_name?: string, sale_mode_name?: string
unit?: string, unit?: string
total_colors?: number, total_colors?: number
total_fabrics?: number, total_fabrics?: number
total_number?: number, total_number?: number
status?: number, //订单状态 status?: number // 订单状态
av_return_product?: any[] //申请售后列表 av_return_product?: any[] // 申请售后列表
} }
type Param = { interface Param {
order: OrderParam, order: OrderParam
onNumChange?: (val:any) => void onNumChange?: (val: any) => void
} }
const kindeList:FC<Param> = memo(({order, onNumChange}) => { const kindeList: FC<Param> = memo(({ order, onNumChange }) => {
// 计步器返回值
const getCounterChange = useCallback((colorItem) => {
return (number) => {
onNumChange?.({ number, color_id: colorItem.product_color_id, sale_order_detail_id: colorItem.sale_order_detail_id })
}
}, [order])
//计步器返回值 return (
const getCounterChange = useCallback((colorItem) => { <View className={styles.apply_after_sales_list}>
return (number) => { {order?.av_return_product?.map(item => <View className={styles.apply_after_sales_item}>
onNumChange?.({number, color_id: colorItem.product_color_id, sale_order_detail_id:colorItem.sale_order_detail_id}) <View className={styles.apply_after_sales_title}>
} <View className={styles.tag}>{order.sale_mode_name}</View>
}, [order]) <View className={styles.title}>{formatHashTag(item.product_code, item.product_name)}</View>
return (
<View className={styles.apply_after_sales_list}>
{order?.av_return_product?.map(item => <View className={styles.apply_after_sales_item}>
<View className={styles.apply_after_sales_title}>
<View className={styles.tag}>{order.sale_mode_name}</View>
<View className={styles.title}>{formatHashTag(item.product_code, item.product_name)}</View>
</View>
<View className={styles.color_list}>
{item?.av_product_color?.map(colorItem => <View className={styles.color_item}>
<View className={styles.image}><Image src={formatImgUrl('')}/></View>
<View className={styles.name_and_number}><Text>{colorItem.product_color_code + ' ' + colorItem.product_color_name}</Text><Text>x {colorItem.roll}</Text></View>
<View className={styles.btn_count}>
<Counter maxNum={colorItem.roll} onChange={getCounterChange(colorItem)}/>
</View>
</View>)}
</View>
</View>)}
</View> </View>
) <View className={styles.color_list}>
{item?.av_product_color?.map(colorItem => <View className={styles.color_item}>
<View className={styles.image}><Image src={formatImgUrl('')} /></View>
<View className={styles.name_and_number}><Text>{`${colorItem.product_color_code} ${colorItem.product_color_name}`}</Text><Text>x {colorItem.roll}</Text></View>
<View className={styles.btn_count}>
<Counter maxNum={colorItem.roll} onChange={getCounterChange(colorItem)} />
</View>
</View>)}
</View>
</View>)}
</View>
)
}) })
export default kindeList export default kindeList

View File

@ -1,41 +1,41 @@
import {Textarea, View } from "@tarojs/components"; import { Textarea, View } from '@tarojs/components'
import { memo, useMemo, useState } from "react"; import { memo, useMemo, useState } from 'react'
import styles from './index.module.scss' import classnames from 'classnames'
import classnames from "classnames"; import styles from './index.module.scss'
//其他说明 // 其他说明
type Param = { interface Param {
onChange: (val: string) => void onChange: (val: string) => void
} }
export default memo(({onChange}:Param) => { export default memo(({ onChange }: Param) => {
const [descData, setDescData] = useState({ const [descData, setDescData] = useState({
number: 0, number: 0,
value: '', value: '',
count: 200, count: 200,
show: false show: false,
}) })
const getDesc = (e) => { const getDesc = (e) => {
let value = e.detail.value const value = e.detail.value
let res = value let res = value
if(value.length > descData.count) { if (value.length > descData.count) {
res = value.slice(0, descData.count) res = value.slice(0, descData.count)
}
setDescData({...descData, number:res.length, value: res})
onChange?.(res)
} }
setDescData({ ...descData, number: res.length, value: res })
onChange?.(res)
}
const toggleShowRealTextarea = (show) => { const toggleShowRealTextarea = (show) => {
setDescData({...descData, show:show}) setDescData({ ...descData, show })
} }
return ( return (
<View className={styles.other_desc}> <View className={styles.other_desc}>
<View className={styles.title}></View> <View className={styles.title}></View>
<View className={styles.textarea}> <View className={styles.textarea}>
{descData.show&&<Textarea autoFocus value={descData.value} onBlur={() => toggleShowRealTextarea(false)} className={styles.textarea_con} cursorSpacing={100} maxlength={descData.count} onInput={(e) => getDesc(e)}></Textarea>|| {descData.show && <Textarea autoFocus value={descData.value} onBlur={() => toggleShowRealTextarea(false)} className={styles.textarea_con} cursorSpacing={100} maxlength={descData.count} onInput={e => getDesc(e)}></Textarea>
<View className={classnames(styles.textarea_con_pretend, descData.value&&styles.textarea_con_pretend_ed)} onClick={() => toggleShowRealTextarea(true)}>{descData.value||'一般情况下选填,当退货说明=“其它问题”时,必填'}</View> || <View className={classnames(styles.textarea_con_pretend, descData.value && styles.textarea_con_pretend_ed)} onClick={() => toggleShowRealTextarea(true)}>{descData.value || '一般情况下选填,当退货说明=“其它问题”时,必填'}</View>
} }
<View className={styles.descDataNum}>{descData.number +'/'+ descData.count}</View> <View className={styles.descDataNum}>{`${descData.number}/${descData.count}`}</View>
</View> </View>
</View> </View>
) )
}) })

View File

@ -1,44 +1,44 @@
import Popup from "@/components/popup"; import { ScrollView, Text, View } from '@tarojs/components'
import { ScrollView, Text, View } from "@tarojs/components"; import { memo, useEffect, useMemo, useState } from 'react'
import { memo, useEffect, useMemo, useState } from "react"; import classnames from 'classnames'
import classnames from "classnames"; import styles from './index.module.scss'
import styles from './index.module.scss' import Popup from '@/components/popup'
//原因选择 // 原因选择
type Param = {id:number, name:string, typle?:number} interface Param { id: number; name: string; typle?: number }
type ReasonInfoParam = { interface ReasonInfoParam {
show?: boolean, //显示 show?: boolean // 显示
onClose?: () => void, //关闭 onClose?: () => void // 关闭
title?: string, //标题 title?: string // 标题
list?: {id:number, name:string, typle?:number, children?:Param[]}[], //数据列表 list?: { id: number; name: string; typle?: number; children?: Param[] }[] // 数据列表
onSelect?: (val: object) => void, //选择 onSelect?: (val: object) => void // 选择
defaultValue?: number, //默认选中 defaultValue?: number // 默认选中
} }
export default memo(({show = false, onClose, title = '', list = [], onSelect, defaultValue}: ReasonInfoParam) => { export default memo(({ show = false, onClose, title = '', list = [], onSelect, defaultValue }: ReasonInfoParam) => {
const [hasNextData, setHasNextData] = useState(true) //是否有下一级数据 const [hasNextData, setHasNextData] = useState(true) // 是否有下一级数据
const [selectData, setSelectData] = useState() const [selectData, setSelectData] = useState()
const [headerList, setHeaderList] = useState<{id: number, name: string}[]>([]) const [headerList, setHeaderList] = useState<{ id: number; name: string }[]>([])
const onSelectData = (item) => { const onSelectData = (item) => {
setHeaderList((e) => [...e, {id:item.id, name:item.name}]) setHeaderList(e => [...e, { id: item.id, name: item.name }])
} }
useEffect(() => { useEffect(() => {
console.log('headerList::', headerList) console.log('headerList::', headerList)
}, [headerList]) }, [headerList])
return ( return (
<Popup showIconButton={false} show={show} title={title} onClose={onClose} > <Popup showIconButton={false} show={show} title={title} onClose={onClose} >
<View className={styles.reason_return_con}> <View className={styles.reason_return_con}>
<View className={styles.reason_title}> <View className={styles.reason_title}>
{headerList.map(item => { {headerList.map((item) => {
return <Text key={item.id}>{item.name}</Text> return <Text key={item.id}>{item.name}</Text>
})} })}
{hasNextData&&<Text></Text>} {hasNextData && <Text></Text>}
</View> </View>
<ScrollView scrollY className={styles.reason_scroll}> <ScrollView scrollY className={styles.reason_scroll}>
<View className={styles.reason_list}> <View className={styles.reason_list}>
{list.map(item => <View onClick={() => onSelectData(item)} key={item.id} className={classnames(styles.reason_item, item.id == defaultValue&&styles.select_item)}>{item.name}</View> )} {list.map(item => <View onClick={() => onSelectData(item)} key={item.id} className={classnames(styles.reason_item, item.id == defaultValue && styles.select_item)}>{item.name}</View>)}
</View> </View>
</ScrollView> </ScrollView>
</View> </View>
</Popup> </Popup>
) )
}) })

Some files were not shown because too many files have changed in this diff Show More