diff --git a/global.d.ts b/global.d.ts
index 6981aec..7dc913e 100644
--- a/global.d.ts
+++ b/global.d.ts
@@ -20,4 +20,5 @@ declare namespace NodeJS {
declare const CURRENT_VERSION: string
declare const CURRENT_GITHASH: string
declare const CURRENT_ENV: string
+declare const CURRENT_BASE_URL: string
diff --git a/src/api/shopping/index.ts b/src/api/shopping/index.ts
index 604a5e8..dc0dbe5 100644
--- a/src/api/shopping/index.ts
+++ b/src/api/shopping/index.ts
@@ -1,7 +1,7 @@
-import { useRequest } from "@/use/useHttp"
+import { useRequest } from '@/use/useHttp'
/**
* 修改购物车
- * @returns
+ * @returns
*/
export const ShoppingCartUpdateApi = () => {
return useRequest({
@@ -11,21 +11,31 @@ export const ShoppingCartUpdateApi = () => {
}
/**
* 删除购物车商品
- * @returns
+ * @returns
*/
- export const ShoppingCartDeleteApi = () => {
- return useRequest({
- url: `/v2/mp/shoppingCart/productColor`,
- method: "delete",
- })
+export const ShoppingCartDeleteApi = () => {
+ return useRequest({
+ url: `/v2/mp/shoppingCart/productColor`,
+ method: 'delete',
+ })
}
/**
* 获取购物车商品列表
- * @returns
+ * @returns
*/
- export const ShoppingCartListApi = () => {
- return useRequest({
- url: `/v2/mp/shoppingCart/productColor`,
- method: "get",
- })
+export const ShoppingCartListApi = () => {
+ return useRequest({
+ url: `/v2/mp/shoppingCart/productColor`,
+ method: 'get',
+ })
+}
+/**
+ * 调整购物车商品数量
+ * @returns
+ */
+export const AdjestShoppingCartApi = () => {
+ return useRequest({
+ url: `/v2/mp/shoppingCart/productColor/list`,
+ method: 'post',
+ })
}
diff --git a/src/common/constant.js b/src/common/constant.ts
similarity index 99%
rename from src/common/constant.js
rename to src/common/constant.ts
index 1647e3d..edec91f 100644
--- a/src/common/constant.js
+++ b/src/common/constant.ts
@@ -38,4 +38,4 @@ export const SCENE = {
SearchScene: 0, //商城面料搜索
}
//支付码单跳转链接
-export const PAY_H5_CODE_URL = CURRENT_ENV.includes('production') ? 'https://www.zzfzyc.com/cashier' : 'https://test.zzfzyc.com/cashier'
\ No newline at end of file
+export const PAY_H5_CODE_URL = CURRENT_ENV.includes('production') ? 'https://www.zzfzyc.com/cashier' : 'https://test.zzfzyc.com/cashier'
diff --git a/src/components/shoppingCart/index.module.scss b/src/components/shoppingCart/index.module.scss
index 7d79b4c..6e5df67 100644
--- a/src/components/shoppingCart/index.module.scss
+++ b/src/components/shoppingCart/index.module.scss
@@ -1,157 +1,141 @@
.shopcartBox {
- padding-left: 32px;
+ padding: 0 32px;
- .topTitle {
- font-size: 32px;
- font-family: PingFangSC-Medium, PingFang SC;
- font-weight: 500;
- color: #000000;
- margin-top: 24px;
- margin-bottom: 8px;
+ .topTitle {
+ font-size: 32px;
+ font-weight: 500;
+ color: #000000;
+ margin-top: 24px;
+ margin-bottom: 8px;
+ }
+
+ .selectFont {
+ font-size: 24px;
+ font-weight: 400;
+ color: #000000;
+ margin-bottom: 24px;
+ }
+
+ .line {
+ margin-bottom: 24px;
+ height: 1px;
+ background: #000000;
+ opacity: 0.1;
+ }
+
+ .typeFont {
+ font-size: 28px;
+ font-weight: 500;
+ color: #000000;
+ margin-bottom: 24px;
+ }
+
+ .flexType {
+ display: flex;
+ align-items: center;
+ margin-bottom: 32px;
+
+ .activemodeFont {
+ margin-right: 16px;
+ width: 160px;
+ height: 68px;
+ background: rgba(51, 127, 255, 0.1);
+ border-radius: 8px;
+ border: 1px solid #337fff;
+ box-sizing: border-box;
+ font-size: 28px;
+ font-weight: 400;
+ color: #337fff;
+ text-align: center;
+ line-height: 68px;
}
- .selectFont {
- font-size: 24px;
- font-family: PingFangSC-Regular, PingFang SC;
- font-weight: 400;
- color: #000000;
- margin-bottom: 24px;
+ .modeFont {
+ margin-right: 16px;
+ width: 160px;
+ height: 68px;
+ background: #e9e9e9;
+ border-radius: 8px;
+ opacity: 0.4;
+ font-size: 28px;
+ font-weight: 400;
+ color: #000000;
+ box-sizing: border-box;
+ text-align: center;
+ line-height: 68px;
+ }
+ }
+
+ .flexFonts {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 24px;
+ align-items: center;
+ padding-bottom: 10px;
+
+ .kingFont {
+ font-size: 28px;
+ font-weight: 500;
+ color: #000000;
}
- .line {
- margin-bottom: 24px;
- // width: 686px;
- margin-right: 32px;
- height: 1px;
- background: #000000;
- opacity: 0.1;
+ .danwei {
+ margin-left: 16px;
+ width: 148px;
+ height: 30px;
+ border-radius: 4px;
+ border: 1px solid #e42945;
+ font-size: 22px;
+ font-weight: 500;
+ color: #e42945;
+ text-align: center;
+ line-height: 30px;
}
+ }
- .typeFont {
- font-size: 28px;
- font-family: PingFangSC-Medium, PingFang SC;
- font-weight: 500;
- color: #000000;
- margin-bottom: 24px;
- }
+ .searchBox {
+ margin-bottom: 32px;
+ }
- .flexType {
- display: flex;
- align-items: center;
- margin-bottom: 32px;
+ .scrollviewBig {
+ .scrollview {
+ // height: 300px;
- .activemodeFont {
- margin-right: 16px;
- width: 160px;
- height: 68px;
- background: rgba(51, 127, 255, 0.1);
- border-radius: 8px;
- border: 1px solid #337FFF;
- box-sizing: border-box;
- font-size: 28px;
- font-family: PingFangSC-Regular, PingFang SC;
- font-weight: 400;
- color: #337FFF;
- text-align: center;
- line-height: 68px;
- }
-
- .modeFont {
- margin-right: 16px;
- width: 160px;
- height: 68px;
- background: #E9E9E9;
- border-radius: 8px;
- opacity: 0.4;
- font-size: 28px;
- font-family: PingFangSC-Regular, PingFang SC;
- font-weight: 400;
- color: #000000;
- box-sizing: border-box;
- text-align: center;
- line-height: 68px;
- }
- }
-
- .flexFonts {
- display: flex;
- margin-bottom: 24px;
- align-items: center;
- padding-bottom: 10px;
-
- .kingFont {
- font-size: 28px;
- font-family: PingFangSC-Medium, PingFang SC;
- font-weight: 500;
- color: #000000;
-
- }
-
- .danwei {
- margin-left: 16px;
- width: 148px;
- height: 30px;
- border-radius: 4px;
- border: 1PX solid #E42945;
- font-size: 22px;
- font-family: PingFangSC-Medium, PingFang SC;
- font-weight: 500;
- color: #E42945;
- text-align: center;
- line-height: 30px;
- }
- }
-
- .searchBox {
- // margin-left: 32px;
- margin-right: 32px;
- // width: 686px;
- margin-bottom: 32px;
- }
-
- .scrollviewBig {
- .scrollview {
- // height: 300px;
-
- .kongBox {
- height: 181px;
- width: 100%;
- }
- }
-
-
- }
-
- .kongOne {
- height: 200px;
- }
-
- .loading_more {
- height: 300px;
- padding-bottom: 200px;
- display: flex;
- align-items: center;
+ .kongBox {
+ height: 181px;
width: 100%;
- justify-content: center;
+ }
}
+ }
- .posBox {
- width: 100%;
- position: fixed;
- z-index: 999;
- bottom: calc($customTabBarHeight + env(safe-area-inset-bottom));
- }
+ .kongOne {
+ height: 200px;
+ }
- .noBottom {
- width: 100%;
- position: fixed;
- z-index: 999;
- bottom: env(safe-area-inset-bottom);
- }
+ .loading_more {
+ height: 300px;
+ padding-bottom: 200px;
+ display: flex;
+ align-items: center;
+ width: 100%;
+ justify-content: center;
+ }
+ .posBox {
+ width: 100%;
+ position: fixed;
+ z-index: 999;
+ bottom: calc($customTabBarHeight + env(safe-area-inset-bottom));
+ }
+ .noBottom {
+ width: 100%;
+ position: fixed;
+ z-index: 999;
+ bottom: env(safe-area-inset-bottom);
+ }
}
.scrllStyle {
- height: 900px;
-}
\ No newline at end of file
+ height: 75vh;
+}
diff --git a/src/components/shoppingCart/index.tsx b/src/components/shoppingCart/index.tsx
index 43d87b4..1a4711f 100644
--- a/src/components/shoppingCart/index.tsx
+++ b/src/components/shoppingCart/index.tsx
@@ -8,6 +8,7 @@ import Goods from "@/components/goodsItem"
import BottomCustomer from "@/components/BottomCustomer"
import VirtualList from '@tarojs/components/virtual-list'
import DotLoading from "@/components/dotLoading"
+import Divider from '../divider';
interface prosObj {
showPopup?: false | true,
closePopup?: () => void,
@@ -119,64 +120,89 @@ export default memo(forwardRef((props: prosObj, ref) => {
})
return (
- closePopup?.()}>
-
-
- {obj?.code}# {obj?.name}
- 已选 1 种面料,{selectTotal} 个颜色,共 {selectNums} {showModefont}
-
- 布料类型
-
- {
- typeList.map((item, index) => {
- return (
- { handCheck?.(item) }} key={index} className={classnames(item.checked ? styles.activemodeFont : styles.modeFont)}>{item.name}
- )
- })
- }
-
-
-
- 颜色分类({goodList?.length})
- {modeFont == 0 ? '大货' : modeFont == 1 ? '剪版' : '散剪'}单位:{showModefont}
-
-
-
-
- {
- goodList.length > 0 && <>
-
-
- {rows}
-
-
-
-
-
- >
- }
- {
- goodList.length === 0 && <>
- 加载中
- >
- }
- {
- !hasBottom &&
- }
-
- 0 && clientName !== '' ? false : true} handSure={() => { handSure() }}>
-
+ closePopup?.()}>
+
+
+
+ {obj?.code}# {obj?.name}
+
+
+ 已选 1 种面料,{selectTotal} 个颜色,共 {selectNums} {showModefont}
+
+
+ 布料类型
+
+ {typeList.map((item, index) => {
+ return (
+ {
+ handCheck?.(item)
+ }}
+ key={index}
+ className={classnames(item.checked ? styles.activemodeFont : styles.modeFont)}>
+ {item.name}
+
+ )
+ })}
+
+
+
+
+ 颜色分类({goodList?.length})
+
+ {modeFont == 0 ? '大货' : modeFont == 1 ? '剪版' : '散剪'}单位:{showModefont}
+
+
+
+
+
+
+ {goodList.length > 0 && (
+ <>
+
+
+ {rows}
+
-
-
+
+ >
+ )}
+ {goodList.length === 0 && (
+ <>
+
+ 加载中
+
+
+ >
+ )}
+ {!hasBottom && }
+
+ 0 && clientName !== '' ? false : true}
+ handSure={() => {
+ handSure()
+ }}>
+
+
+
+
)
diff --git a/src/pages/index/index.module.scss b/src/pages/index/index.module.scss
index 2d1bbd0..3fa31cb 100644
--- a/src/pages/index/index.module.scss
+++ b/src/pages/index/index.module.scss
@@ -8,7 +8,7 @@
width: 100%;
display: flex;
justify-content: space-between;
- padding: 20px 20px 30px 20px;
+ padding: 20px;
box-sizing: border-box;
align-items: center;
@@ -36,4 +36,4 @@
}
-//246
\ No newline at end of file
+//246
diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx
index 2f4f097..83a097b 100644
--- a/src/pages/index/index.tsx
+++ b/src/pages/index/index.tsx
@@ -2,7 +2,6 @@ import { View } from '@tarojs/components'
import Search from '@/components/search'
import SideBar from '@/components/sideBar'
import Product from '@/components/product'
-import MoveBtn from '@/components/moveBtn'
import ShopCart from '@/components/shoppingCart'
import { goLink } from '@/common/common'
import styles from './index.module.scss'
@@ -13,7 +12,6 @@ import { mpproductcolorlist, mpshoppingCartproductColorlist } from "@/api/order"
import { dataLoadingStatus } from '@/common/util'
import Taro, { useDidShow } from '@tarojs/taro'
import { getFilterData } from '@/common/util'
-import userInfo from '@/reducers/userInfo'
import { ClientListApi } from '@/api/order'
export default () => {
@@ -345,7 +343,7 @@ export default () => {
showCart(item)} />
-
+ {/* */}
handSure()}
clientName={clientObj?.clientName}
clientId={clientObj?.clientId}
diff --git a/src/pages/shopping/README.md b/src/pages/shopping/README.md
new file mode 100644
index 0000000..a5eeaa6
--- /dev/null
+++ b/src/pages/shopping/README.md
@@ -0,0 +1,16 @@
+购物页面的 组件结构
+
+> Shopping
+>
+> > ShoppingProvider
+> >
+> > > ShoppingCartContainer
+> > >
+> > > > ShoppingCartItem
+> > > >
+> > > > > GoodsList
+> > > > >
+> > > > > > ColorKindItem
+
+还用到发布订阅者模式 通知祖先组件请求接口更新数据
+
diff --git a/src/pages/shopping/components/colorKindItem/index.tsx b/src/pages/shopping/components/colorKindItem/index.tsx
index 8c8d85d..45411ec 100644
--- a/src/pages/shopping/components/colorKindItem/index.tsx
+++ b/src/pages/shopping/components/colorKindItem/index.tsx
@@ -8,18 +8,23 @@ import { debounce } from '@/common/util'
import { formatImgUrl, formatPriceDiv } from '@/common/format'
import { EnumSaleMode } from '@/common/Enumerate'
import { selectList } from '../../config'
+import { AdjestShoppingCartApi } from '@/api/shopping/index'
import { Goods, ShoppingDispatchType, ShoppingStateContextValue, useShoppingDispatch, useShoppingState } from '../../context'
+import { ShoppingStore } from '../../context/shoppingStore'
type PropsType = {
- state?: Goods
+ state?: {
+ multipleSelection: Goods[]
+ Observer: ShoppingStore
+ }
purchaserId: number
itemData: Record & object
orderType: EnumSaleMode
}
let ColorKindItem: FC = props => {
- console.log('Rerender component: ColorKindItem')
- const { state: multipleSelection, purchaserId, itemData, orderType = EnumSaleMode.Bulk } = props
+ const { state, purchaserId, itemData, orderType = EnumSaleMode.Bulk } = props
+ console.log('Rerender component: ColorKindItem', itemData.id)
const dispatch = useShoppingDispatch()
// console.log('checked==>', checked)
@@ -43,12 +48,12 @@ let ColorKindItem: FC = props => {
type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
data: {
purchaserId: purchaserId,
- multipleSelection: { ...multipleSelection, [itemData.id]: itemData },
+ multipleSelection: { ...state?.multipleSelection, [itemData.id]: itemData },
},
})
}
const handleClose = () => {
- const temp = multipleSelection
+ const temp = state?.multipleSelection
delete temp?.[itemData.id]
dispatch({
type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
@@ -58,26 +63,39 @@ let ColorKindItem: FC = props => {
},
})
}
+ const { fetchData } = AdjestShoppingCartApi()
-
- // TODO:需要新增调整条数/米数的接口 并在调整完成后重新请求整个购物车页面
+ // 调整条数/米数的接口 并在调整完成后重新请求整个购物车页面
const getInputValue = debounce(async (num, itemData) => {
+ const targetColor: Record = {
+ product_color_id: itemData.product_color_id,
+ roll: 0,
+ length: 0,
+ }
if (itemData.sale_mode === EnumSaleMode.Bulk) {
itemData.roll = num
+ targetColor.roll = num
} else {
itemData.length = num
+ targetColor.length = num
}
-
- }, 260)
-
-
+ const res = await fetchData({
+ color_list: [targetColor],
+ purchaser_id: purchaserId,
+ sale_mode: itemData.sale_mode,
+ sale_offset: itemData.sale_offset,
+ })
+ if (res.success) {
+ state?.Observer?.notify(purchaserId)
+ }
+ }, 400)
return (
@@ -101,8 +119,8 @@ let ColorKindItem: FC = props => {
digits={selectList[orderType].digits}
onClickBtn={e => getInputValue(e, itemData)}
unit={formatUnit(itemData)}
- minNum={selectList[orderType].minNum}
- maxNum={selectList[orderType].maxNum}
+ minNum={itemData.min_num}
+ maxNum={itemData.max_num}
/>
@@ -120,11 +138,11 @@ const withStateSlice = (comp, slice) => {
return memo(forwardRef(Wrapper))
}
-ColorKindItem = withStateSlice(
- ColorKindItem,
- (state: ShoppingStateContextValue, props: PropsType) => {
- return state.colorStore[props.purchaserId]['multipleSelection']
- },
-)
+ColorKindItem = withStateSlice(ColorKindItem, (state: ShoppingStateContextValue, props: PropsType) => {
+ return {
+ multipleSelection: state.colorStore[props.purchaserId]['multipleSelection'],
+ Observer: state.Observer,
+ }
+})
export default ColorKindItem
diff --git a/src/pages/shopping/components/shoppingCart/index.tsx b/src/pages/shopping/components/shoppingCart/index.tsx
index be53cdf..a16abff 100644
--- a/src/pages/shopping/components/shoppingCart/index.tsx
+++ b/src/pages/shopping/components/shoppingCart/index.tsx
@@ -1,4 +1,4 @@
-import { FC, ReactNode, useEffect, useReducer, useRef } from 'react'
+import { FC, ReactNode, useEffect, useMemo, useReducer, useRef } from 'react'
import {
ShoppingAction,
ShoppingDispatchContext,
@@ -8,6 +8,7 @@ import {
ShoppingStateContext,
} from '../../context'
import { ColorStore, ShoppingStateContextValue } from '../../context'
+import { ShoppingStore } from '../../context/shoppingStore'
export type TriggerCheckboxOptions = {
colorStore: ColorStore
@@ -15,15 +16,6 @@ export type TriggerCheckboxOptions = {
setSelectedAmount: ShoppingDispatchContextValue['UPDATE_SELECTED_AMOUNT']
}
-type InitialState = {
- colorStore: ColorStore
- currentCheckedPurchaserId: number
- currentCheckedSaleMode: number
- isManageStatus: boolean
- isMultipleSelection: boolean
- selectedAmount: number
-}
-
export interface ShoppingCartPropsType {
initialValues?: ColorStore
onTriggerCheckbox?: (options: TriggerCheckboxOptions) => void
@@ -35,18 +27,22 @@ export const ShoppingProvider: FC = props => {
const onTriggerCheckboxRef = useRef(onTriggerCheckbox)
onTriggerCheckboxRef.current = onTriggerCheckbox
+ // 发布订阅
+ const Observer = useMemo(() => new ShoppingStore(), [])
- const [state, dispatch] = useReducer<(state: ShoppingStateContextValue, action: ShoppingAction) => InitialState>(shoppingReducer, {
+ const [state, dispatch] = useReducer<(state: ShoppingStateContextValue, action: ShoppingAction) => ShoppingStateContextValue>(shoppingReducer, {
colorStore: initialValues || {},
currentCheckedPurchaserId: -1,
currentCheckedSaleMode: 0,
isManageStatus: false,
isMultipleSelection: false,
selectedAmount: 0,
+ Observer,
})
// 这里要在 useEffect 也就是刷新 state 后再调用,否则如果在 onFieldsChangeRef 修改值会覆盖掉上次修改
useEffect(() => {
+ console.log('onTriggerCheckboxRef start run')
onTriggerCheckboxRef.current?.({
colorStore: state.colorStore,
currentCheckedPurchaserId: state.currentCheckedPurchaserId,
@@ -54,6 +50,19 @@ export const ShoppingProvider: FC = props => {
})
}, [state.colorStore, state.currentCheckedPurchaserId])
+ // 加入一个监听,为 onFieldsChange 回调服务
+ // useEffect(() => {
+ // const unsubscribe = Observer.subscribe(() => {
+ // console.log('onTriggerCheckboxRef start run')
+ // onTriggerCheckboxRef.current?.({
+ // colorStore: state.colorStore,
+ // currentCheckedPurchaserId: state.currentCheckedPurchaserId,
+ // setSelectedAmount: amount => dispatch({ type: ShoppingDispatchType.UPDATE_SELECTED_AMOUNT, data: amount }),
+ // })
+ // })
+ // return unsubscribe
+ // }, [Observer])
+
return (
{children}
diff --git a/src/pages/shopping/components/shoppingCartItem/index.tsx b/src/pages/shopping/components/shoppingCartItem/index.tsx
index 247f2dd..11ae848 100644
--- a/src/pages/shopping/components/shoppingCartItem/index.tsx
+++ b/src/pages/shopping/components/shoppingCartItem/index.tsx
@@ -1,5 +1,5 @@
import { Text, View } from '@tarojs/components'
-import { FC, forwardRef, memo, useEffect, useMemo, useState, useTransition } from 'react'
+import { FC, forwardRef, memo, useEffect, useMemo, useRef, useState, useTransition } from 'react'
import styles from './index.module.scss'
import classnames from 'classnames'
import { formatMeterDiv } from '@/common/format'
@@ -14,6 +14,8 @@ import IconFont from '@/components/iconfont/iconfont'
import { isEmptyObject } from '@/common/common'
import classNames from 'classnames'
import LoadingCard from '@/components/loadingCard'
+import { ShoppingCartListApi } from '@/api'
+import { ShoppingStore } from '../../context/shoppingStore'
interface ButtonPropsType {
isActive: boolean
@@ -53,11 +55,13 @@ type PropsType = {
state?: {
multipleSelection?: GoodsMeta['multipleSelection']
currentCheckedPurchaserId?: number
+ Observer?: ShoppingStore
}
}
let ShoppingCartItem: FC = props => {
- const { itemData, state } = props
+ const { state } = props
+ const [itemData, setItemData] = useState(props.itemData)
const { multipleSelection, currentCheckedPurchaserId } = state!
const dispatch = useShoppingDispatch()
@@ -87,7 +91,10 @@ let ShoppingCartItem: FC = props => {
}
dispatch({ type: ShoppingDispatchType.UPDATE_SELECTED_AMOUNT, data: 0 })
dispatch({ type: ShoppingDispatchType.UPDATE_CURRENT_CHECKED_SALEMODE, data: selected })
- dispatch({ type: ShoppingDispatchType.UPDATE_CURRENT_CHECKED_PURCHASERID, data: itemData?.purchaser_id as number })
+ dispatch({
+ type: ShoppingDispatchType.UPDATE_CURRENT_CHECKED_PURCHASERID,
+ data: itemData?.purchaser_id as number,
+ })
dispatch({ type: ShoppingDispatchType.UPDATE_MULTIPLE_SELECTION, data: false })
}
@@ -131,6 +138,58 @@ let ShoppingCartItem: FC = props => {
}, [multipleSelection, currentCheckedPurchaserId, selected, itemData])
const [isPending, startTransition] = useTransition()
+ const { fetchData } = ShoppingCartListApi()
+
+ // 发布订阅
+
+ useEffect(() => {
+ const unsubscribe = state?.Observer?.subscribe(async id => {
+ if (itemData?.purchaser_id !== id) return
+ console.log('request new data start run')
+ const res = await fetchData({
+ purchaser_id: id,
+ })
+ console.log('res===>', res)
+ if (res.success) {
+ const newGoodsKind = Object.fromEntries(
+ res.data[0]?.[BackEndSaleModeListFieldMap[selected]].map(item => [
+ item?.id,
+ {
+ id: item?.id,
+ estimate_amount: item.estimate_amount,
+ product_code: item.product_code,
+ product_color_code: item.product_color_code,
+ sale_mode: item.sale_mode,
+ count: selected === EnumSaleMode.Bulk ? item.roll : Number(formatMeterDiv(item.length)),
+ },
+ ]),
+ )
+ dispatch({
+ type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
+ data: {
+ purchaserId: id,
+ goodsKind: newGoodsKind,
+ multipleSelection: Object.fromEntries(
+ Object.keys(multipleSelection!).map(id => [
+ id,
+ {
+ id,
+ estimate_amount: newGoodsKind[id].estimate_amount,
+ product_code: newGoodsKind[id].product_code,
+ product_color_code: newGoodsKind[id].product_color_code,
+ sale_mode: newGoodsKind[id].sale_mode,
+ count: selected === EnumSaleMode.Bulk ? newGoodsKind[id].roll : Number(formatMeterDiv(newGoodsKind[id].length)),
+ },
+ ]),
+ ),
+ },
+ })
+ setItemData(res.data[0])
+ }
+ })
+ // 取消订阅
+ return unsubscribe
+ }, [multipleSelection])
return (
= props => {
-
+
>
@@ -205,52 +270,78 @@ let ShoppingCartItem: FC = props => {
interface GoodsListPropType {
itemData?: ShoppingCartData
+ multipleSelection?: GoodsMeta['multipleSelection']
selected: EnumSaleMode
isPending: boolean
startTransition: React.TransitionStartFunction
}
const GoodsList = memo(props => {
- console.log('Rerender component: GoodsList')
- const { itemData, selected, isPending, startTransition } = props
+ console.log('Rerender component: GoodsList', props.multipleSelection)
+ const { itemData, selected, isPending, startTransition, multipleSelection } = props
+
+ const currentSelected = useRef(null)
+
const dispatch = useShoppingDispatch()
const [component, setComponent] = useState(null)
+ // 更新 GoodsList 组件
+ const updateComponent = () => {
+ setComponent(
+ itemData?.[BackEndSaleModeListFieldMap[selected]].length !== 0 ? (
+ itemData?.[BackEndSaleModeListFieldMap[selected]].map(item => {
+ return
+ })
+ ) : (
+ 暂无数据
+ ),
+ )
+ }
+
useEffect(() => {
- startTransition(() => {
- setComponent(
- itemData?.[BackEndSaleModeListFieldMap[selected]].length !== 0 ? (
- itemData?.[BackEndSaleModeListFieldMap[selected]].map(item => {
- dispatch({
- type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
- data: {
- purchaserId: itemData?.purchaser_id!,
- goodsKind: {
- [item?.id]: {
- id: item?.id,
- estimate_amount: item.estimate_amount,
- product_code: item.product_code,
- product_color_code: item.product_color_code,
- sale_mode: item.sale_mode,
- count: selected === EnumSaleMode.Bulk ? item.roll : Number(formatMeterDiv(item.length)),
- },
- },
- multipleSelection: {},
- },
- })
- return
- })
- ) : (
- 暂无数据
- ),
- )
- })
- }, [itemData, selected])
+ const newGoodsKind = Object.fromEntries(
+ itemData?.[BackEndSaleModeListFieldMap[selected]].map(item => [
+ item?.id,
+ {
+ id: item?.id,
+ estimate_amount: item.estimate_amount,
+ product_code: item.product_code,
+ product_color_code: item.product_color_code,
+ sale_mode: item.sale_mode,
+ count: selected === EnumSaleMode.Bulk ? item.roll : Number(formatMeterDiv(item.length)),
+ },
+ ]),
+ )
+ // 这里做一层比较是为了 重新渲染的时候如果没有切换订单类型的话就不让面料的选中状态初始化
+ if (currentSelected.current === selected) {
+ dispatch({
+ type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
+ data: {
+ purchaserId: itemData?.purchaser_id!,
+ goodsKind: newGoodsKind,
+ multipleSelection: multipleSelection,
+ },
+ })
+ updateComponent()
+ } else {
+ // 重新把当前的选中状态赋值给ref 作为下一次比较的旧状态
+ currentSelected.current = selected
+ dispatch({
+ type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
+ data: {
+ purchaserId: itemData?.purchaser_id!,
+ goodsKind: newGoodsKind,
+ multipleSelection: {},
+ },
+ })
+ startTransition(updateComponent)
+ }
+ }, [itemData, selected, multipleSelection])
return (
<>
{isPending ? (
-
+
) : (
@@ -262,12 +353,12 @@ const GoodsList = memo(props => {
// State 分割组件 思路就是把 context 直接通过 props 的形式传给组件,这样的话就解决了 context 强制刷新 memo 的问题了
// 那么当 context 内的 value 被更新的时候,react 只会强制渲染 Wrapper
const withStateSlice = (comp, slice) => {
- const MemoComp = memo(comp, (prevProps, nextProps)=>{
+ const MemoComp = memo(comp, (prevProps, nextProps) => {
let needMemo = true
if (JSON.stringify(prevProps.itemData) !== JSON.stringify(nextProps.itemData)) {
needMemo = false
}
- if(JSON.stringify(prevProps.state) !== JSON.stringify(nextProps.state)){
+ if (JSON.stringify(prevProps.state) !== JSON.stringify(nextProps.state)) {
needMemo = false
}
return needMemo
@@ -283,6 +374,7 @@ const withStateSlice = (comp, slice) => {
ShoppingCartItem = withStateSlice(ShoppingCartItem, (state: ShoppingStateContextValue, props) => ({
multipleSelection: state.colorStore?.[props.itemData?.purchaser_id]?.['multipleSelection'],
currentCheckedPurchaserId: state.currentCheckedPurchaserId,
+ Observer: state.Observer,
}))
export default ShoppingCartItem
diff --git a/src/pages/shopping/context/index.ts b/src/pages/shopping/context/index.ts
index d04e673..592136f 100644
--- a/src/pages/shopping/context/index.ts
+++ b/src/pages/shopping/context/index.ts
@@ -1,6 +1,7 @@
import { EnumSaleMode } from '@/common/Enumerate'
import React, { Dispatch } from 'react'
import { useContext } from 'react'
+import { ShoppingStore } from './shoppingStore'
/**
* 456: {
@@ -8,7 +9,13 @@ import { useContext } from 'react'
* colorKind: {
* 4562: {
* id: 4562,
- * checked: false
+ * ...
+ * }
+ * },
+ * multipleSelection: {
+ * 4562: {
+ * id: 4562,
+ * ...
* }
* }
* },
@@ -17,7 +24,7 @@ import { useContext } from 'react'
* colorKind: {
* 4562: {
* id: 4562,
- * checked: false
+ * ...
* }
* }
* }
@@ -40,9 +47,7 @@ export interface GoodsMeta {
goodsKind?: {
[id: Goods['id']]: Goods
}
- multipleSelection: {
- [id: Goods['id']]: Goods
- }
+ multipleSelection?: GoodsMeta['goodsKind']
}
export interface ShoppingStateContextValue {
@@ -52,6 +57,7 @@ export interface ShoppingStateContextValue {
currentCheckedSaleMode: EnumSaleMode
colorStore: ColorStore
selectedAmount: number
+ Observer: ShoppingStore
}
export enum ShoppingDispatchType {
@@ -63,7 +69,7 @@ export enum ShoppingDispatchType {
UPDATE_SELECTED_AMOUNT = 'UPDATE_SELECTED_AMOUNT',
UPDATE_CHANGED_CHECKBOX = 'UPDATE_CHANGED_CHECKBOX',
}
-// UPDATE_MultipleSelection
+
export interface ShoppingDispatchContextValue {
[ShoppingDispatchType.UPDATE_MANAGE_STATUS]: (isManageStatus: ShoppingStateContextValue['isManageStatus']) => void
[ShoppingDispatchType.UPDATE_MULTIPLE_SELECTION]: (isMultipleSelection: ShoppingStateContextValue['isMultipleSelection']) => void
@@ -109,7 +115,7 @@ export function shoppingReducer(state: ShoppingStateContextValue, action: Shoppi
[data.purchaserId as number]: {
purchaserId: data.purchaserId,
goodsKind: { ...state.colorStore[data.purchaserId]?.goodsKind, ...data.goodsKind },
- multipleSelection: { ...data.multipleSelection },
+ multipleSelection: data?.multipleSelection ? data.multipleSelection : state.colorStore[data.purchaserId]?.multipleSelection,
},
},
}
diff --git a/src/pages/shopping/context/shoppingStore.ts b/src/pages/shopping/context/shoppingStore.ts
index b5b5a9f..e93151a 100644
--- a/src/pages/shopping/context/shoppingStore.ts
+++ b/src/pages/shopping/context/shoppingStore.ts
@@ -1,7 +1,9 @@
-import { GoodsMeta, ColorStore } from '.'
+
// 用于优化数据流 结合发布订阅 更新组件内部状态可以组件自己处理
-export type SubscribeCallback = (changedGoods: GoodsMeta) => void
+import { ColorStore } from "."
+
+export type SubscribeCallback = (changedGoods: any) => void
export class ShoppingStore {
// 全局缓存
@@ -9,7 +11,7 @@ export class ShoppingStore {
// 监听器数组
private observers: SubscribeCallback[] = []
- constructor(initialValue: ColorStore) {
+ constructor(initialValue?: any) {
initialValue && this.updateStore(initialValue)
}
// 更新全局缓存
@@ -27,9 +29,9 @@ export class ShoppingStore {
}
}
// 通知
- notify(changedGoods: GoodsMeta) {
+ notify(changedGoods: any) {
// 循环调用
- this.observers.forEach((callback) => {
+ this.observers.forEach(callback => {
callback(changedGoods)
})
}
diff --git a/src/pages/shopping/index.tsx b/src/pages/shopping/index.tsx
index 5390982..07cd63b 100644
--- a/src/pages/shopping/index.tsx
+++ b/src/pages/shopping/index.tsx
@@ -21,7 +21,7 @@ export const Shopping: FC = memo(() => {
// 计算总的预估金额
const handleTriggerCheckbox = ({ colorStore, currentCheckedPurchaserId, setSelectedAmount }) => {
const multipleSelection = colorStore?.[currentCheckedPurchaserId]?.multipleSelection
- console.log('handleTriggerCheckbox==>', colorStore)
+ console.log('handleTriggerCheckbox==>', multipleSelection)
if (multipleSelection) {
const result = Object.values(multipleSelection).reduce((prev: number, value: Goods) => {
@@ -84,11 +84,18 @@ const ShoppingCartContainer: FC = () => {
setSearchOptions(prev => ({ ...prev, short_name_or_phone: e }))
}, [])
- const [shoppingCartData, setShoppingCartData] = useState<{ list: ShoppingCartData[]; total: number }>({ list: [], total: 0 })
+ const [shoppingCartData, setShoppingCartData] = useState<{
+ list: ShoppingCartData[]
+ total: number
+ }>({ list: [], total: 0 })
//数据加载状态
const statusMore = useMemo(() => {
- const status = dataLoadingStatus({ list: shoppingCartData.list, total: shoppingCartData.total, status: state.loading })
+ const status = dataLoadingStatus({
+ list: shoppingCartData.list,
+ total: shoppingCartData.total,
+ status: state.loading,
+ })
console.log('status==>', status)
return status
}, [shoppingCartData, state])
@@ -144,7 +151,7 @@ const ShoppingCartContainer: FC = () => {
// 批量某个客户的删除商品
const handleDelete = async () => {
const multipleSelection = colorStore?.[currentCheckedPurchaserId]?.['multipleSelection']
- let checked: Goods[] = Object.values(multipleSelection)
+ let checked: Goods[] = Object.values(multipleSelection!)
if (checked.length === 0) {
return Taro.showToast({ title: '请选择商品', icon: 'error' })
}
@@ -201,6 +208,7 @@ const ShoppingCartContainer: FC = () => {
setRefreshStatus(false)
}
}
+
return (