356 lines
12 KiB
TypeScript
356 lines
12 KiB
TypeScript
import { ScrollView, Text, View } from '@tarojs/components'
|
||
import Taro, { useDidShow, useRouter, useUnload } from '@tarojs/taro'
|
||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||
import classNames from 'classnames'
|
||
import styles from './index.module.scss'
|
||
import Search from '@/components/search'
|
||
import NormalButton from '@/components/normalButton'
|
||
import LabAndImg from '@/components/LabAndImg2'
|
||
import Tag from '@/components/tag'
|
||
import MCheckbox from '@/components/checkbox'
|
||
import InfiniteScroll from '@/components/infiniteScroll'
|
||
import { dataLoadingStatus, debounce, getFilterData } from '@/common/util'
|
||
import { alert, goLink } from '@/common/common'
|
||
import { formatHashTag, formatRemoveHashTag } from '@/common/format'
|
||
import Popup from '@/components/popup'
|
||
import IconFont from '@/components/iconfont/iconfont'
|
||
import { GetCutSampleOrderColorList, GetCutSampleOrderProducts } from '@/api/sampleCutting'
|
||
|
||
export interface SampleCuttingCache {
|
||
product_id: number
|
||
product_code_and_name: string
|
||
multipleSelection: {
|
||
product_color_id: number
|
||
product_color_code: string
|
||
product_color_name: string
|
||
lab: {
|
||
l: number
|
||
a: number
|
||
b: number
|
||
}
|
||
rgb: {
|
||
r: number
|
||
g: number
|
||
b: number
|
||
}
|
||
texture_url: string
|
||
count: number
|
||
}[]
|
||
}
|
||
const SampleCuttingList = () => {
|
||
const router = useRouter()
|
||
const isAdd = router?.params?.isAddSampleCutIdList
|
||
|
||
const { fetchData, state } = GetCutSampleOrderProducts()
|
||
|
||
const [orderList, setOrderList] = useState<{ list: any[]; total: number }>({
|
||
list: [],
|
||
total: 0,
|
||
})
|
||
const multipleSelection = useRef<SampleCuttingCache[]>([])
|
||
// 搜索
|
||
const getSearchData = debounce((value: string) => {
|
||
console.log('search', value)
|
||
setSearchField(val => ({ ...val, product_code_and_name: value }))
|
||
}, 300)
|
||
// 取消
|
||
const handleCancel = () => {
|
||
Taro.navigateBack()
|
||
}
|
||
|
||
// redirectTo 会触发 onLoad 事件
|
||
let isRedirect = false
|
||
// 确认
|
||
const handleSubmit = () => {
|
||
Taro.setStorageSync('sampleCuttingCache', JSON.stringify(multipleSelection.current))
|
||
if (router?.params.isGoBack) {
|
||
isRedirect = true
|
||
Taro.navigateBack({
|
||
delta: 1,
|
||
})
|
||
}
|
||
else {
|
||
isRedirect = true
|
||
// 携带id跳转
|
||
goLink('/pages/sampleCutting/addSampleCutting/index', null, 'redirectTo')
|
||
}
|
||
}
|
||
|
||
const labAndImgObj = useCallback((item) => {
|
||
return { lab: item?.lab, rgb: item?.rgb, texture_url: item?.texture_url }
|
||
}, [])
|
||
// 页码和页数
|
||
const [searchField, setSearchField] = useState<{ product_code_and_name?: string; product_ids?: string; page: number; size: number }>({
|
||
product_code_and_name: '',
|
||
product_ids: '',
|
||
page: 1,
|
||
size: 10,
|
||
})
|
||
|
||
const getData = async() => {
|
||
console.log('searchField==>', searchField)
|
||
const res = await fetchData(getFilterData(searchField))
|
||
if (!res.success) {
|
||
return alert.error(res.msg)
|
||
}
|
||
setOrderList({ list: res.data.list, total: res.data.total })
|
||
}
|
||
|
||
useEffect(() => {
|
||
getData()
|
||
}, [searchField])
|
||
|
||
useDidShow(() => {
|
||
const cache = Taro.getStorageSync('sampleCuttingCache')
|
||
if (cache) {
|
||
multipleSelection.current = JSON.parse(cache) as SampleCuttingCache[]
|
||
}
|
||
|
||
if (isAdd) {
|
||
console.log('isAdd', isAdd)
|
||
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
|
||
setSearchField(val => ({ ...val, product_ids: isAdd }))
|
||
}
|
||
})
|
||
|
||
// 上拉加载数据
|
||
const pageNum = useRef({ size: searchField.size, page: searchField.page })
|
||
// 列表下拉刷新
|
||
const [refresherTriggeredStatus, setRefresherTriggeredStatus] = useState(false)
|
||
// 下拉刷新
|
||
const getRefresherRefresh = async() => {
|
||
pageNum.current.size = 1
|
||
setRefresherTriggeredStatus(true)
|
||
setSearchField(val => ({ ...val, size: 10 }))
|
||
}
|
||
// 数据加载状态
|
||
const statusMore = useMemo(() => {
|
||
return dataLoadingStatus({ list: orderList.list, total: orderList.total, status: state.loading! })
|
||
}, [orderList, state.loading])
|
||
|
||
const getScrollToLower = useCallback(() => {
|
||
if (orderList.list.length < orderList.total) {
|
||
pageNum.current.page++
|
||
const size = pageNum.current.size * pageNum.current.page
|
||
setSearchField({ ...searchField, size })
|
||
}
|
||
}, [orderList])
|
||
|
||
const { fetchData: getColorList } = GetCutSampleOrderColorList()
|
||
const currentSelect = useRef<any>({})
|
||
const handleClickAddButton = async(item: any) => {
|
||
currentSelect.current = item
|
||
const res = await getColorList({ id: item.id })
|
||
if (res.success) {
|
||
setProductList(res.data.list)
|
||
const index = multipleSelection.current.findIndex(val => val.product_id === item.id)
|
||
if (index !== -1) {
|
||
setProductMultipleSelection(multipleSelection.current[index].multipleSelection)
|
||
}
|
||
else {
|
||
setProductMultipleSelection([])
|
||
}
|
||
setShow(true)
|
||
}
|
||
else {
|
||
return alert.error(res.msg)
|
||
}
|
||
}
|
||
|
||
useUnload(() => {
|
||
console.log('onUnload', isRedirect)
|
||
if (!isRedirect) {
|
||
Taro.removeStorageSync('sampleCuttingCache')
|
||
}
|
||
})
|
||
|
||
const [show, setShow] = useState(false)
|
||
|
||
const onClose = () => {
|
||
setShow(false)
|
||
setProductMultipleSelection([])
|
||
}
|
||
|
||
const [productList, setProductList] = useState<any[]>([])
|
||
// 点击产品颜色
|
||
const handleClickProductColor = (item: any) => {
|
||
const index = productMultipleSelection.findIndex(val => val.product_color_id === item.product_color_id)
|
||
console.log(index, productMultipleSelection)
|
||
if (index !== -1) {
|
||
setProductMultipleSelection((prev) => {
|
||
prev.splice(index, 1)
|
||
return [...prev]
|
||
})
|
||
}
|
||
else {
|
||
setProductMultipleSelection(prev => [...prev, {
|
||
product_color_id: item.product_color_id,
|
||
product_color_code: item.product_color_code,
|
||
product_color_name: item.product_color_name,
|
||
lab: item.lab,
|
||
rgb: item.rgb,
|
||
texture_url: item.texture_url,
|
||
count: 1,
|
||
}])
|
||
}
|
||
}
|
||
|
||
const handleClose = () => {
|
||
onClose()
|
||
}
|
||
const handleAddProduct = () => {
|
||
const index = multipleSelection.current.findIndex(mul => mul.product_id === currentSelect.current.id)
|
||
if (index !== -1) {
|
||
multipleSelection.current[index].multipleSelection = productMultipleSelection
|
||
}
|
||
else {
|
||
multipleSelection.current.push({
|
||
product_id: currentSelect.current.id,
|
||
product_code_and_name: formatHashTag(currentSelect.current.code, currentSelect.current.name) as string,
|
||
multipleSelection: productMultipleSelection,
|
||
})
|
||
}
|
||
onClose()
|
||
}
|
||
const [productMultipleSelection, setProductMultipleSelection] = useState<SampleCuttingCache['multipleSelection']>([])
|
||
|
||
return <View className={styles.main}>
|
||
<View className={styles.search}>
|
||
<Search placeholder="请输入搜索面料剪样" showBtn={false} changeOnSearch={getSearchData} >
|
||
<View className={styles.search__cancel} onClick={handleCancel}>取消</View>
|
||
</Search>
|
||
</View>
|
||
<View className={styles.context}>
|
||
<InfiniteScroll
|
||
statusMore={statusMore}
|
||
selfonScrollToLower={getScrollToLower}
|
||
refresherEnabled
|
||
refresherTriggered={refresherTriggeredStatus}
|
||
selfOnRefresherRefresh={getRefresherRefresh}
|
||
safeAreaInsetBottom={false}
|
||
>
|
||
{
|
||
orderList.list.map((item) => {
|
||
return <View key={item.id} style={{ padding: '0 16px', backgroundColor: 'white' }}>
|
||
<View className={styles.colorCard}>
|
||
<View style={{ minWidth: '24%' }}>
|
||
<View className={styles.colorCard__image}>
|
||
<LabAndImg value={labAndImgObj(item)} />
|
||
{
|
||
item.is_multiple_product ? <View className={styles.imageTag}>24色</View> : null
|
||
}
|
||
</View>
|
||
</View>
|
||
<View className={styles.colorCard__content}>
|
||
<View className={styles.colorCard__title}>{formatHashTag(item.code, item.name)}</View>
|
||
<View className={styles.colorCard__code}>
|
||
<Tag customStyle={{ marginRight: '5px', marginBottom: '2px', padding: '5px', background: '#e3ecff', color: '#558cff', borderColor: '#e3ecff' }} size="small" circle>{item.width}</Tag>
|
||
<Tag customStyle={{ marginRight: '5px', marginBottom: '2px', padding: '5px', background: '#e3ecff', color: '#558cff', borderColor: '#e3ecff' }} size="small" circle>{item.weight_density}</Tag>
|
||
</View>
|
||
<View className={styles.colorCard__code}>
|
||
{item.component}
|
||
</View>
|
||
</View>
|
||
<View className={styles.addButton}>
|
||
<NormalButton
|
||
type="primary"
|
||
size="small"
|
||
customStyles={{ padding: '0 40rpx' }}
|
||
plain
|
||
round
|
||
onClick={() => handleClickAddButton(item)}
|
||
>
|
||
{
|
||
isAdd?.includes(item.id) || multipleSelection.current.some(mul => mul.product_id === item.id) ? '继续添加' : '添加'
|
||
}
|
||
</NormalButton>
|
||
{/* <MCheckbox
|
||
disabled={isAdd?.includes(item.id)}
|
||
status={isAdd?.includes(item.id) || item.status}
|
||
onSelect={() => onSelect(item)}
|
||
onClose={() => onUnSelect(item)}
|
||
/> */}
|
||
</View>
|
||
</View>
|
||
</View>
|
||
})
|
||
}
|
||
</InfiniteScroll>
|
||
|
||
</View>
|
||
<View className={styles.bottomBar}>
|
||
<NormalButton
|
||
customClassName={styles.bottomBar__button}
|
||
type="primary"
|
||
round
|
||
disabled={multipleSelection.current.length === 0}
|
||
onClick={handleSubmit}
|
||
>
|
||
{
|
||
multipleSelection.current.length ? `确认(已选 ${multipleSelection.current.length} 个)` : '确认'
|
||
}
|
||
</NormalButton>
|
||
|
||
</View>
|
||
<Popup show={show} onClose={onClose} showTitle={false}>
|
||
<View className={styles.collection_con}>
|
||
<View className={styles.header}>
|
||
<View className={styles.title}>{formatHashTag(currentSelect.current.code, currentSelect.current.name)}( {productList.length} )</View>
|
||
<View className={styles.sub_title}>
|
||
剪样大小为A4,大约22cm*30cm
|
||
</View>
|
||
</View>
|
||
<View className={styles.productList}>
|
||
{
|
||
productList.map((item, index) => {
|
||
const isChecked = productMultipleSelection.some(mul => mul.product_color_id === item.product_color_id)
|
||
return <View key={index} className={styles.item} onClick={() => handleClickProductColor(item)}>
|
||
<View className={classNames(styles.item_color, isChecked ? styles.productColorActive : null)}>
|
||
{
|
||
isChecked
|
||
? <View className={styles.activeIcon}>
|
||
<IconFont name="icon-lujing" size={20} color="white"></IconFont>
|
||
</View>
|
||
: null
|
||
}
|
||
<LabAndImg
|
||
value={item}
|
||
round
|
||
name={formatRemoveHashTag(item.product_color_code)}
|
||
/>
|
||
</View>
|
||
<View className={styles.item_name}>{item.product_color_name}</View>
|
||
</View>
|
||
})
|
||
}
|
||
</View>
|
||
|
||
</View>
|
||
<View className={classNames(styles.bottomBar, styles.popup_bottom)}>
|
||
<NormalButton
|
||
customClassName={styles.bottomBar__button}
|
||
type="primary"
|
||
round
|
||
plain
|
||
customStyles={{ width: '48%' }}
|
||
onClick={handleClose}
|
||
>
|
||
取消
|
||
</NormalButton>
|
||
<NormalButton
|
||
customClassName={styles.bottomBar__button}
|
||
type="primary"
|
||
round
|
||
customStyles={{ width: '48%' }}
|
||
disabled={productMultipleSelection.length === 0}
|
||
onClick={handleAddProduct}
|
||
>
|
||
领取剪样({productMultipleSelection.length})
|
||
</NormalButton>
|
||
|
||
</View>
|
||
</Popup>
|
||
</View>
|
||
}
|
||
export default SampleCuttingList
|