🎈 perf(我的页面优化):

This commit is contained in:
czm 2022-08-01 00:32:59 +08:00
parent 2b15dc578c
commit 6ea58ad911
10 changed files with 1672 additions and 1587 deletions

View File

@ -10,6 +10,8 @@ const CURRENT_VERSION = `Version: ${JSON.stringify(process.env.CODE_BRANCH || ve
'',
)
console.log('process::', process)
const config = {
projectName: 'EShop',
date: '2022-4-6',

View File

@ -1,53 +1,58 @@
import Popup from "@/components/popup";
import { Input, ScrollView, Text, View } from "@tarojs/components";
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
import classnames from "classnames";
import styles from './index.module.scss'
import TextareaEnhance from "@/components/textareaEnhance";
import { CreateFavoriteApi, FavoriteListApi } from "@/api/favorite";
import { alert, goLink } from "@/common/common";
import { getFilterData } from "@/common/util";
import Popup from '@/components/popup'
import { Input, ScrollView, Text, View } from '@tarojs/components'
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import classnames from 'classnames'
import styles from './index.module.scss'
import TextareaEnhance from '@/components/textareaEnhance'
import { CreateFavoriteApi, FavoriteListApi } from '@/api/favorite'
import { alert, goLink } from '@/common/common'
import { getFilterData } from '@/common/util'
//原因选择
type ReasonInfoParam = {
show?: boolean, //显示
onClose?: () => void, //关闭
onAdd?: (val: any) => void
show?: boolean //显示
onClose?: () => void //关闭
onAdd?: (val: any) => void
}
export default memo(({show = false, onClose, onAdd}: ReasonInfoParam) => {
//获取列表
const [list, setList] = useState([])
const {fetchData: fetchDataList} = FavoriteListApi()
const getFavoriteList = async () => {
let res = await fetchDataList(getFilterData())
setList(() => res.data.list)
}
useEffect(() => {
if(show) getFavoriteList()
}, [show])
export default memo(({ show = false, onClose, onAdd }: ReasonInfoParam) => {
//获取列表
const [list, setList] = useState([])
const { fetchData: fetchDataList } = FavoriteListApi()
const getFavoriteList = async () => {
let res = await fetchDataList(getFilterData())
setList(() => res.data.list)
}
useEffect(() => {
if (show) getFavoriteList()
}, [show])
const onCreate = () => {
onClose?.()
goLink('/pages/collection/index')
}
const onCreate = () => {
onClose?.()
goLink('/pages/collection/index')
}
return (
<Popup show={show} onClose={onClose} showTitle={false} >
<View className={styles.collection_con}>
<View className={styles.header}>
<Text className={styles.title}></Text>
<View className={styles.miconfont_con} >
<Text className={classnames(styles.miconfont, 'iconfont icon-jia')}></Text>
<Text onClick={onCreate}></Text>
</View>
</View>
<ScrollView scrollY className={styles.scrollView}>
{list?.map((item: any) => <View onClick={() => onAdd?.(item)} className={styles.collection_item}>
<View className={styles.name}>{item.name}<Text>{item.product_color_list?.length||0}</Text></View>
<View className={styles.desc}>{item.remark}</View>
</View>)}
</ScrollView>
return (
<Popup show={show} onClose={onClose} showTitle={false}>
<View className={styles.collection_con}>
<View className={styles.header}>
<Text className={styles.title}></Text>
<View className={styles.miconfont_con}>
<Text className={classnames(styles.miconfont, 'iconfont icon-jia')}></Text>
<Text onClick={onCreate}></Text>
</View>
</View>
<ScrollView scrollY className={styles.scrollView}>
{list?.map((item: any) => (
<View onClick={() => onAdd?.(item)} className={styles.collection_item}>
<View className={styles.name}>
{item.name}
<Text>{item.product_color_list?.length || 0}</Text>
</View>
<View className={styles.desc}>{item.remark}</View>
</View>
</Popup>
)
})
))}
</ScrollView>
</View>
</Popup>
)
})

View File

@ -1,380 +1,406 @@
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 { alert, goLink } from "@/common/common";
import {GetShoppingCartApi, DelShoppingCartApi, UpdateShoppingCartApi} from "@/api/shopCart"
import { formatHashTag, formatImgUrl, formatPriceDiv } from "@/common/fotmat";
import { setParam } from "@/common/system";
import { debounce, throttle } from "@/common/util";
import Counter from "../counter";
import { ApplyOrderAccessApi, GetAdminUserInfoApi, SubscriptionMessageApi } from "@/api/user";
import useCommonData from "@/use/useCommonData";
import BindSalesmanPopup from "../bindSalesmanPopup";
import LabAndImgShow from "../LabAndImgShow";
import LabAndImg from "../LabAndImg";
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 { alert, goLink } from '@/common/common'
import { GetShoppingCartApi, DelShoppingCartApi, UpdateShoppingCartApi } from '@/api/shopCart'
import { formatHashTag, formatImgUrl, formatPriceDiv } from '@/common/fotmat'
import { setParam } from '@/common/system'
import { debounce, throttle } from '@/common/util'
import Counter from '../counter'
import { ApplyOrderAccessApi, GetAdminUserInfoApi, SubscriptionMessageApi } from '@/api/user'
import useCommonData from '@/use/useCommonData'
import BindSalesmanPopup from '../bindSalesmanPopup'
import LabAndImgShow from '../LabAndImgShow'
import LabAndImg from '../LabAndImg'
type param = {
show?: true|false,
onClose?: () => void,
intoStatus?: 'again'|'shop',
default_sale_mode?: number, //面料类型0大货 1剪版2散剪
show?: true | false
onClose?: () => void
intoStatus?: 'again' | 'shop'
default_sale_mode?: number //面料类型0大货 1剪版2散剪
}
export default ({show = false, onClose, intoStatus='shop', default_sale_mode}: param) => {
const selectList = [
{value:0, title:'大货', unit:'条', eunit:'kg', step:1, digits:0, minNum:1, maxNum:100000, defaultNum:1},
{value:1,title:'剪板', unit:'米', eunit:'m', step:1, digits:2, minNum:0.5, maxNum:9.99, defaultNum:1},
{value:2,title:'散剪', unit:'米', eunit:'kg', step:1, digits:2, minNum:5, maxNum:100000, defaultNum:10},
]
export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode }: param) => {
const selectList = [
{ value: 0, title: '大货', unit: '条', eunit: 'kg', step: 1, digits: 0, minNum: 1, maxNum: 100000, defaultNum: 1 },
{ value: 1, title: '剪板', unit: '米', eunit: 'm', step: 1, digits: 2, minNum: 0.5, maxNum: 9.99, defaultNum: 1 },
{ value: 2, title: '散剪', unit: '米', eunit: 'kg', step: 1, digits: 2, minNum: 5, maxNum: 100000, defaultNum: 10 },
]
//切换面料类型
const [selectIndex, setSelectIndex] = useState(default_sale_mode||0)
const selectProduct = (index:number) => {
setSelectIndex(index)
}
useEffect(() => {
setSelectIndex(() => default_sale_mode!)
}, [default_sale_mode])
//切换面料类型
const [selectIndex, setSelectIndex] = useState(default_sale_mode || 0)
const selectProduct = (index: number) => {
setSelectIndex(index)
}
useEffect(() => {
setSelectIndex(() => default_sale_mode!)
}, [default_sale_mode])
useEffect(() => {
resetList()
setSelectStatus(true)
}, [selectIndex])
useEffect(() => {
resetList()
setSelectStatus(true)
}, [selectIndex])
//获取购物车数据数量
const {setShopCount} = useCommonData()
//获取购物车数据数量
const { setShopCount } = useCommonData()
//重置勾选数据
const resetList = () => {
list?.map(item => {
if(selectIndex == item.sale_mode || selectIndex == -1) {
checkboxData[item.id] = true
} else {
checkboxData[item.id] = false
}
})
setCheckboxData(() => ({...checkboxData}))
}
//获取数据
const [list, setList] = useState<any[]>([])
const [loading, setLoading] = useState(false)
const {fetchData} = GetShoppingCartApi()
const getShoppingCart = async () => {
const {data} = await fetchData()
let color_list = data.color_list||[]
setShopCount(color_list.length)
initList(color_list)
setList(color_list)
setLoading(false)
}
//初始化全部数据默认勾选
const [checkboxData, setCheckboxData] = useState<{[index:number]:true|false}>({})
const initStatus = useRef(false)
const initList = (color_list) => {
if(initStatus.current) {
color_list?.map(item => {
if(selectIndex == item.sale_mode) checkboxData[item.id] = true
})
initStatus.current = false
}
setCheckboxData(() => checkboxData)
}
//显示是展示数据
useEffect(() => {
if(!show) {
setList([])
setSelectIndex(default_sale_mode||0)
} else {
setLoading(true)
initStatus.current = true
getShoppingCart()
setShowBindSalesman(() => false)
}
}, [show])
useEffect(() => {
return () => {
setList([])
}
}, [])
const [showPopup, setShowPopup] = useState(false)
useEffect(() => {
setShowPopup(show)
}, [show])
//全选反选
const [selectStatus, setSelectStatus] = useState(false)
const selectAll = () => {
list.map(item => {
if(selectIndex == item.sale_mode || selectIndex == -1)
checkboxData[item.id] = !selectStatus
})
setSelectStatus(!selectStatus)
setCheckboxData(() => ({...checkboxData}))
}
//checkbox选中回调
const selectCallBack = (item) => {
//重置勾选数据
const resetList = () => {
list?.map((item) => {
if (selectIndex == item.sale_mode || selectIndex == -1) {
checkboxData[item.id] = true
checkSelect()
setCheckboxData(() => ({...checkboxData}))
}
//checkbox选中判断是否全部选中全部选中后是全选否则反选
const checkSelect = () => {
let list_count = 0
let select_count = 0
list?.map(item => {
if(selectIndex == -1 || selectIndex == item.sale_mode) {
list_count ++
if(checkboxData[item.id]) select_count++
}
})
setSelectStatus(select_count == list_count)
}
//checkbox关闭回调
const colseCallBack = (item) => {
} else {
checkboxData[item.id] = false
checkSelect()
setCheckboxData(() => ({...checkboxData}))
}
})
setCheckboxData(() => ({ ...checkboxData }))
}
//获取数据
const [list, setList] = useState<any[]>([])
const [loading, setLoading] = useState(false)
const { fetchData } = GetShoppingCartApi()
const getShoppingCart = async () => {
const { data } = await fetchData()
let color_list = data.color_list || []
setShopCount(color_list.length)
initList(color_list)
setList(color_list)
setLoading(false)
}
//初始化全部数据默认勾选
const [checkboxData, setCheckboxData] = useState<{ [index: number]: true | false }>({})
const initStatus = useRef(false)
const initList = (color_list) => {
if (initStatus.current) {
color_list?.map((item) => {
if (selectIndex == item.sale_mode) checkboxData[item.id] = true
})
initStatus.current = false
}
setCheckboxData(() => checkboxData)
}
//popup关闭
const closePopup = () => {
onClose?.()
setShowPopup(false)
//显示是展示数据
useEffect(() => {
if (!show) {
setList([])
setSelectIndex(default_sale_mode || 0)
} else {
setLoading(true)
initStatus.current = true
getShoppingCart()
setShowBindSalesman(() => false)
}
}, [show])
//删除购物车内容
const {fetchData:delShopFetchData} = DelShoppingCartApi()
const delSelect = () => {
getSelectId()
if(selectIds.current.length <= 0) return alert.none('请选择要删除的面料!')
Taro.showModal({
content: '删除所选商品?',
success: async function (res) {
if (res.confirm) {
const res = await delShopFetchData({id:selectIds.current})
if(res.success) {
getShoppingCart()
Taro.showToast({
title: '成功',
icon: 'success',
})
} else {
Taro.showToast({
title: res.msg,
icon: 'none',
})
}
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
useEffect(() => {
return () => {
setList([])
}
}, [])
//获取面料选中的id
const selectIds = useRef<number[]>([])
const getSelectId = () => {
selectIds.current = []
list?.map(item => {
if(selectIndex == -1 || selectIndex == item.sale_mode) {
checkboxData[item.id]&&selectIds.current.push(item.id)
}
})
}
const [showPopup, setShowPopup] = useState(false)
useEffect(() => {
setShowPopup(show)
}, [show])
//格式化金额
const formatPirce = useCallback((price) => {
return Number(formatPriceDiv(price))
}, [])
//全选反选
const [selectStatus, setSelectStatus] = useState(false)
const selectAll = () => {
list.map((item) => {
if (selectIndex == item.sale_mode || selectIndex == -1) checkboxData[item.id] = !selectStatus
})
setSelectStatus(!selectStatus)
setCheckboxData(() => ({ ...checkboxData }))
}
//格式化数量
const formatCount = useCallback((item) => {
return item.sale_mode == 0? item.roll : (item.length/100)
}, [])
//checkbox选中回调
const selectCallBack = (item) => {
checkboxData[item.id] = true
checkSelect()
setCheckboxData(() => ({ ...checkboxData }))
}
//格式化单位
const formatUnit = useCallback((item) => {
return item.sale_mode == 0? '条':'米'
}, [])
//checkbox选中判断是否全部选中全部选中后是全选否则反选
const checkSelect = () => {
let list_count = 0
let select_count = 0
list?.map((item) => {
if (selectIndex == -1 || selectIndex == item.sale_mode) {
list_count++
if (checkboxData[item.id]) select_count++
}
})
setSelectStatus(select_count == list_count)
}
//预估金额和总条数
const estimatePrice = useMemo(() => {
let estimate_amount = 0
let product_list = new Set() //面料
let color_count = 0 //颜色数量
let all_count = 0 //总数量
list.map(item => {
if(checkboxData[item.id]) {
estimate_amount += item.estimate_amount
product_list.add(item.product_id)
color_count++
all_count += item.sale_mode == 0?item.roll: (item.length)
}
})
let all_count_text = selectIndex == 0?all_count + ' 条': (all_count/100) + ' 米'
return {price: Number(formatPriceDiv(estimate_amount)).toFixed(2), countText: `已选 ${product_list.size} 种面料,${color_count} 个颜色,共 ${all_count_text}`, color_count}
},[list, checkboxData])
//checkbox关闭回调
const colseCallBack = (item) => {
checkboxData[item.id] = false
checkSelect()
setCheckboxData(() => ({ ...checkboxData }))
}
//去结算
const {fetchData: useFetchData} = GetAdminUserInfoApi()
const {fetchData: applyOrderAccessFetchData} = ApplyOrderAccessApi()
const orderDetail = throttle( async () => {
let res = await useFetchData()
if(res.data.order_access_status !== 3) {
if(res.data.order_access_status == 1) applyOrderAccessFetchData()
setShowBindSalesman(() => true)
onClose?.()
return false
}
getSelectId()
if(selectIds.current.length == 0) {
alert.error('请选择面料')
} else {
let ids = selectIds.current.join('-')
setParam({ids, sale_mode:selectIndex}) //临时存储
closePopup()
if(intoStatus == "again") {
goLink('/pages/order/comfirm', {}, 'redirectTo')
} else {
goLink('/pages/order/comfirm')
}
}
}, 500)
//popup关闭
const closePopup = () => {
onClose?.()
setShowPopup(false)
}
//计数组件-当后端修改完成才修改前端显示
const {fetchData: fetchDataUpdateShoppingCart} = UpdateShoppingCartApi()
const [UpdateShoppingCartLoading, setUpdateShoppingCartLoading] = useState(false)
const getInputValue = debounce(async (num, item) => {
let roll = item.sale_mode == 0?parseFloat(num):0
let length = item.sale_mode != 0?(parseFloat(num)*100):0
setUpdateShoppingCartLoading(() => true)
let res = await fetchDataUpdateShoppingCart({id: item.id, roll, length})
setUpdateShoppingCartLoading(() => false)
if(res.success) {
//删除购物车内容
const { fetchData: delShopFetchData } = DelShoppingCartApi()
const delSelect = () => {
getSelectId()
if (selectIds.current.length <= 0) return alert.none('请选择要删除的面料!')
Taro.showModal({
content: '删除所选商品?',
success: async function (res) {
if (res.confirm) {
const res = await delShopFetchData({ id: selectIds.current })
if (res.success) {
getShoppingCart()
Taro.showToast({
title: '成功',
icon: 'success',
})
} else {
Taro.showToast({
title: res.msg,
icon: 'none',
})
}
} else if (res.cancel) {
console.log('用户点击取消')
}
}, 300)
},
})
}
//绑定业务员和电话号码
const [showBindSalesman, setShowBindSalesman] = useState(false)
//获取面料选中的id
const selectIds = useRef<number[]>([])
const getSelectId = () => {
selectIds.current = []
list?.map((item) => {
if (selectIndex == -1 || selectIndex == item.sale_mode) {
checkboxData[item.id] && selectIds.current.push(item.id)
}
})
}
//显示图片弹窗
const [showLabImage, setShowLabImage] = useState(false)
const [labImageValue, setLabImageValue] = useState()
const getLabAndImg = useCallback((val) => {
setShowLabImage(() => true)
setLabImageValue(val)
}, [])
const closeLabImgShow = useCallback(() => {
setShowLabImage(() => false)
}, [])
//格式化金额
const formatPirce = useCallback((price) => {
return Number(formatPriceDiv(price))
}, [])
return (
<View className={styles.shop_cart_main}>
<Popup showTitle={false} show={showPopup} onClose={() => closePopup()} >
<View className={styles.popup_con}>
<View className={styles.header}>
<View onClick={selectAll}>{!selectStatus?'全选':'反选'}</View>
<View onClick={delSelect}>
<text className={classnames('iconfont', 'icon-shanchu', styles.miconfont)}></text>
</View>
</View>
<View className={styles.count_all}>{estimatePrice.countText}</View>
<View className={styles.search}>
{selectList.map((item) => {
return <View key={item.value} onClick={() => selectProduct(item.value)} className={classnames(styles.search_item, (selectIndex==item.value)&&styles.search_item_select)}>{item.title}</View>
})}
</View>
<View className={styles.con}>
{loading&&<LoadingCard/>}
{!loading&&list?.length > 0&&<InfiniteScroll moreStatus={false} >
<View className={styles.product_list}>
{list?.map((item, index) => {
return <View key={index} className={classnames(styles.product_item, (selectIndex!=-1&&selectIndex!= item.sale_mode)&&styles.no_product_item_select)}>
<View className={styles.checkbox}>
<MCheckbox disabled={selectIndex!=-1&&selectIndex!=item.sale_mode} status={!!checkboxData[item.id]} onSelect={() => selectCallBack(item)} onClose={() => colseCallBack(item)}/>
</View>
<View className={styles.img}>
<LabAndImg value={{lab:item.lab,rgb:item.rgb,texture_url:item.texture_url, title:item.product_color_code}} showStatus={false} onClick={getLabAndImg}/>
</View>
<View className={styles.product_item_name}>
<View className={styles.product_item_name_header}>
<View className={styles.title}>{formatHashTag(item.product_code, item.product_name)}</View>
<View className={styles.price}><text></text>{formatPirce(item.sale_price)}<text>/{selectList[item.sale_mode].eunit}</text></View>
</View>
<View className={styles.count}>
<View className={styles.des}>
<View className={styles.subtitle}>{item.product_color_code +' ' + item.product_color_name}</View>
<View className={styles.tag}>{item.sale_mode_name}</View>
</View>
<View className={styles.btn_count}>
<Counter
onBlue={(e) => getInputValue(e, item)}
defaultNum={formatCount(item)}
step={selectList[selectIndex].step}
digits={selectList[selectIndex].digits}
onClickBtn={(e) => getInputValue(e, item)}
unit={formatUnit(item)}
minNum={selectList[selectIndex].minNum}
maxNum={selectList[selectIndex].maxNum}
disable={UpdateShoppingCartLoading}
/>
</View>
</View>
</View>
</View>
})}
</View>
</InfiniteScroll>}
{!loading&&list?.length == 0 &&<View className={styles.empty}>
<View className={styles.title}></View>
<View className={styles.btn}></View>
</View>}
</View>
<View className={styles.buy_btn}>
<View className={styles.buy_con}>
<View className={styles.icon}>
<View className={classnames('iconfont', 'icon-gouwuche', styles.miconfont)}></View>
</View>
<View className={styles.price_con}>
<View className={styles.price_real}><text></text>{estimatePrice.price}</View>
<View className={styles.price_forecast}></View>
</View>
<View className={styles.goPay} onClick={() => orderDetail()}>
({estimatePrice.color_count})
</View>
</View>
</View>
//格式化数量
const formatCount = useCallback((item) => {
return item.sale_mode == 0 ? item.roll : item.length / 100
}, [])
//格式化单位
const formatUnit = useCallback((item) => {
return item.sale_mode == 0 ? '条' : '米'
}, [])
//预估金额和总条数
const estimatePrice = useMemo(() => {
let estimate_amount = 0
let product_list = new Set() //面料
let color_count = 0 //颜色数量
let all_count = 0 //总数量
list.map((item) => {
if (checkboxData[item.id]) {
estimate_amount += item.estimate_amount
product_list.add(item.product_id)
color_count++
all_count += item.sale_mode == 0 ? item.roll : item.length
}
})
let all_count_text = selectIndex == 0 ? all_count + ' 条' : all_count / 100 + ' 米'
return {
price: Number(formatPriceDiv(estimate_amount)).toFixed(2),
countText: `已选 ${product_list.size} 种面料,${color_count} 个颜色,共 ${all_count_text}`,
color_count,
}
}, [list, checkboxData])
//去结算
const { fetchData: useFetchData } = GetAdminUserInfoApi()
const { fetchData: applyOrderAccessFetchData } = ApplyOrderAccessApi()
const orderDetail = throttle(async () => {
let res = await useFetchData()
if (res.data.order_access_status !== 3) {
if (res.data.order_access_status == 1) applyOrderAccessFetchData()
setShowBindSalesman(() => true)
onClose?.()
return false
}
getSelectId()
if (selectIds.current.length == 0) {
alert.error('请选择面料')
} else {
let ids = selectIds.current.join('-')
setParam({ ids, sale_mode: selectIndex }) //临时存储
closePopup()
if (intoStatus == 'again') {
goLink('/pages/order/comfirm', {}, 'redirectTo')
} else {
goLink('/pages/order/comfirm')
}
}
}, 500)
//计数组件-当后端修改完成才修改前端显示
const { fetchData: fetchDataUpdateShoppingCart } = UpdateShoppingCartApi()
const [UpdateShoppingCartLoading, setUpdateShoppingCartLoading] = useState(false)
const getInputValue = debounce(async (num, item) => {
let roll = item.sale_mode == 0 ? parseFloat(num) : 0
let length = item.sale_mode != 0 ? parseFloat(num) * 100 : 0
setUpdateShoppingCartLoading(() => true)
let res = await fetchDataUpdateShoppingCart({ id: item.id, roll, length })
setUpdateShoppingCartLoading(() => false)
if (res.success) {
getShoppingCart()
}
}, 300)
//绑定业务员和电话号码
const [showBindSalesman, setShowBindSalesman] = useState(false)
//显示图片弹窗
const [showLabImage, setShowLabImage] = useState(false)
const [labImageValue, setLabImageValue] = useState()
const getLabAndImg = useCallback((val) => {
setShowLabImage(() => true)
setLabImageValue(val)
}, [])
const closeLabImgShow = useCallback(() => {
setShowLabImage(() => false)
}, [])
return (
<View className={styles.shop_cart_main}>
<Popup showTitle={false} show={showPopup} onClose={() => closePopup()}>
<View className={styles.popup_con}>
<View className={styles.header}>
<View onClick={selectAll}>{!selectStatus ? '全选' : '反选'}</View>
<View onClick={delSelect}>
<text className={classnames('iconfont', 'icon-shanchu', styles.miconfont)}></text>
</View>
</View>
<View className={styles.count_all}>{estimatePrice.countText}</View>
<View className={styles.search}>
{selectList.map((item) => {
return (
<View
key={item.value}
onClick={() => selectProduct(item.value)}
className={classnames(styles.search_item, selectIndex == item.value && styles.search_item_select)}>
{item.title}
</View>
</Popup>
<View>
<BindSalesmanPopup show={showBindSalesman} onClose={() => setShowBindSalesman(false)}/>
</View>
<View>
<LabAndImgShow value={labImageValue} show={showLabImage} onClose={closeLabImgShow}/>
)
})}
</View>
<View className={styles.con}>
{loading && <LoadingCard />}
{!loading && list?.length > 0 && (
<InfiniteScroll moreStatus={false}>
<View className={styles.product_list}>
{list?.map((item) => {
return (
<View
key={item}
className={classnames(styles.product_item, selectIndex != -1 && selectIndex != item.sale_mode && styles.no_product_item_select)}>
<View className={styles.checkbox}>
<MCheckbox
disabled={selectIndex != -1 && selectIndex != item.sale_mode}
status={!!checkboxData[item.id]}
onSelect={() => selectCallBack(item)}
onClose={() => colseCallBack(item)}
/>
</View>
<View className={styles.img}>
<LabAndImg
value={{ lab: item.lab, rgb: item.rgb, texture_url: item.texture_url, title: item.product_color_code }}
showStatus={false}
onClick={getLabAndImg}
/>
</View>
<View className={styles.product_item_name}>
<View className={styles.product_item_name_header}>
<View className={styles.title}>{formatHashTag(item.product_code, item.product_name)}</View>
<View className={styles.price}>
<text></text>
{formatPirce(item.sale_price)}
<text>/{selectList[item.sale_mode].eunit}</text>
</View>
</View>
<View className={styles.count}>
<View className={styles.des}>
<View className={styles.subtitle}>{item.product_color_code + ' ' + item.product_color_name}</View>
<View className={styles.tag}>{item.sale_mode_name}</View>
</View>
<View className={styles.btn_count}>
<Counter
onBlue={(e) => getInputValue(e, item)}
defaultNum={formatCount(item)}
step={selectList[selectIndex].step}
digits={selectList[selectIndex].digits}
onClickBtn={(e) => getInputValue(e, item)}
unit={formatUnit(item)}
minNum={selectList[selectIndex].minNum}
maxNum={selectList[selectIndex].maxNum}
disable={UpdateShoppingCartLoading}
/>
</View>
</View>
</View>
</View>
)
})}
</View>
</InfiniteScroll>
)}
{!loading && list?.length == 0 && (
<View className={styles.empty}>
<View className={styles.title}></View>
<View className={styles.btn}></View>
</View>
)}
</View>
<View className={styles.buy_btn}>
<View className={styles.buy_con}>
<View className={styles.icon}>
<View className={classnames('iconfont', 'icon-gouwuche', styles.miconfont)}></View>
</View>
<View className={styles.price_con}>
<View className={styles.price_real}>
<text></text>
{estimatePrice.price}
</View>
<View className={styles.price_forecast}></View>
</View>
<View className={styles.goPay} onClick={() => orderDetail()}>
({estimatePrice.color_count})
</View>
</View>
</View>
</View>
)
</Popup>
<View>
<BindSalesmanPopup show={showBindSalesman} onClose={() => setShowBindSalesman(false)} />
</View>
<View>
<LabAndImgShow value={labImageValue} show={showLabImage} onClose={closeLabImgShow} />
</View>
</View>
)
}

View File

@ -1,306 +1,333 @@
import {View, Text } from "@tarojs/components"
import Popup from "@/components/popup"
import LoadingCard from "@/components/loadingCard";
import Search from "@/components/search";
import Counter from "../counter";
import { View, Text } from '@tarojs/components'
import Popup from '@/components/popup'
import LoadingCard from '@/components/loadingCard'
import Search from '@/components/search'
import Counter from '../counter'
import Big from 'big.js'
import classnames from "classnames";
import styles from "./index.module.scss"
import { memo, useCallback, useEffect, useRef, useState } from "react";
import { useSelector } from "@/reducers/hooks"
import {GetColorList} from "@/api/materialColor"
import {AddShoppingCartApi} from "@/api/shopCart"
import Taro, { useRouter } from "@tarojs/taro";
import UseLogin from "@/use/useLogin"
import { formatHashTag, formatPriceDiv } from "@/common/fotmat";
import { getFilterData } from "@/common/util";
import LabAndImg from "@/components/LabAndImg";
import classnames from 'classnames'
import styles from './index.module.scss'
import { memo, useCallback, useEffect, useRef, useState } from 'react'
import { useSelector } from '@/reducers/hooks'
import { GetColorList } from '@/api/materialColor'
import { AddShoppingCartApi } from '@/api/shopCart'
import Taro, { useRouter } from '@tarojs/taro'
import UseLogin from '@/use/useLogin'
import { formatHashTag, formatPriceDiv } from '@/common/fotmat'
import { getFilterData } from '@/common/util'
import LabAndImg from '@/components/LabAndImg'
import VirtualList from '@tarojs/components/virtual-list'
import useCommonData from "@/use/useCommonData";
import LabAndImgShow from "@/components/LabAndImgShow";
import useCommonData from '@/use/useCommonData'
import LabAndImgShow from '@/components/LabAndImgShow'
type param = {
show?: true|false,
onClose?: () => void,
title?: string,
productId?: number
show?: true | false
onClose?: () => void
title?: string
productId?: number
}
export default memo(({show = false, onClose, title = '', productId = 0}: param) => {
const {adminUserInfo} = useSelector(state => state.userInfo)
export default memo(({ show = false, onClose, title = '', productId = 0 }: param) => {
const { adminUserInfo } = useSelector((state) => state.userInfo)
const [selectList, _] = useState([
{id: 0, step:1, digits:0, maxNum:100000, defaultNum:1, title:'大货', unit:'条', eunit:'kg', priceField:'bulk_price'},
{id: 1, step:1, digits:2, maxNum:9.99, defaultNum:1, title:'剪板', unit:'米', eunit:'m', priceField:'length_cut_price'},
{id: 2, step:1, digits:2, minNum:10, maxNum:100000, defaultNum:10, title:'散剪', unit:'米', eunit:'kg', priceField:'weight_cut_price'},
])
const [selectIndex, setSelectIndex] = useState(0)
const selectProduct = (index:number) => {
setSelectIndex(() => index)
const [selectList, _] = useState([
{ id: 0, step: 1, digits: 0, maxNum: 100000, defaultNum: 1, title: '大货', unit: '条', eunit: 'kg', priceField: 'bulk_price' },
{ id: 1, step: 1, digits: 2, maxNum: 9.99, defaultNum: 1, title: '剪板', unit: '米', eunit: 'm', priceField: 'length_cut_price' },
{ id: 2, step: 1, digits: 2, minNum: 10, maxNum: 100000, defaultNum: 10, title: '散剪', unit: '米', eunit: 'kg', priceField: 'weight_cut_price' },
])
const [selectIndex, setSelectIndex] = useState(0)
const selectProduct = (index: number) => {
setSelectIndex(() => index)
}
//重置数据
useEffect(() => {
const newList = initList(list)
setList([...newList])
condition.current.code_or_name = null
setSearchShow(false)
}, [selectIndex])
//获取面料颜色列表
const { fetchData: colorFetchData, state: colorState } = GetColorList()
const [list, setList] = useState<any[]>([])
const condition = useRef({ physical_warehouse: adminUserInfo?.physical_warehouse, sale_mode: selectIndex, product_id: 0, code_or_name: null })
const getColorList = async () => {
let { data } = await colorFetchData(getFilterData(condition.current))
let lists = initList(data.list)
setList(() => [...lists])
}
const [showPopup, setShowPopup] = useState(false)
//显示获取
useEffect(() => {
if (show) {
setSelectIndex(0)
condition.current.code_or_name = null
setSearchShow(false)
condition.current.product_id = productId
getColorList()
}
setShowPopup(show)
}, [show])
//重置数据
useEffect(() => {
const newList = initList(list)
setList([...newList])
condition.current.code_or_name = null
setSearchShow(false)
}, [selectIndex])
//获取面料颜色列表
const {fetchData:colorFetchData, state: colorState} = GetColorList()
const [list, setList] = useState<any[]>([])
const condition = useRef({physical_warehouse:adminUserInfo?.physical_warehouse, sale_mode:selectIndex, product_id:0, code_or_name:null})
const getColorList = async () => {
let {data} = await colorFetchData(getFilterData(condition.current))
let lists = initList(data.list)
setList(() => [...lists])
}
const [showPopup, setShowPopup] = useState(false)
//显示获取
useEffect(() => {
if(show) {
setSelectIndex(0)
condition.current.code_or_name = null
setSearchShow(false)
condition.current.product_id = productId
getColorList()
}
setShowPopup(show)
}, [show])
//初始化列表数据
const initList = useCallback((list) => {
const newList = list.map(item => {
item.count = 0
item.show = false
return item
})
return newList
}, [])
//卸载数据
useEffect(() => {
return () => {
setList([])
}
}, [])
//popup关闭
const closePopup = () => {
onClose?.()
setShowPopup(false)
setList([])
}
//计算总数量和总米/件数
const [selectCount, setSelectCount] = useState<{sumCount:number, kindCount:number, color_list:any[]}>({
sumCount: 0,
kindCount: 0,
color_list: []
//初始化列表数据
const initList = useCallback((list) => {
const newList = list.map((item) => {
item.count = 0
item.show = false
return item
})
useEffect(() => {
let sumCount = 0, kindCount = 0, color_list:any[] = []
let color_list_info = {}
list.map(item => {
if(item.count > 0) {
sumCount = Big(sumCount).add(item.count).toNumber()
kindCount ++
color_list_info = selectIndex == 0? {product_color_id:item.id, roll:item.count}:{product_color_id:item.id, length:(item.count*100)}
color_list.push(color_list_info)
}
})
setSelectCount({...selectCount, sumCount, kindCount, color_list})
}, [list])
return newList
}, [])
//计数组件
const getInputValue = useCallback((num, item) => {
item.count = parseFloat(num)
if(num == 0) item.show = false
setList(() => [...list])
}, [list])
const onAdd = (item) => {
item.show = true
item.count = selectList[selectIndex].defaultNum
setList((list) => [...list])
//卸载数据
useEffect(() => {
return () => {
setList([])
}
}, [])
//搜索显示与隐藏
const [searchShow, setSearchShow] = useState(false)
const changeSearchShow = () => {
setSearchShow(true)
}
//popup关闭
const closePopup = () => {
onClose?.()
setShowPopup(false)
setList([])
}
//添加购物车
const {getShopCount} = useCommonData()
const {getSelfUserInfo} = UseLogin()
const {fetchData:addFetchData} = AddShoppingCartApi()
const addShopCart = async () => {
try {
await getSelfUserInfo()
} catch(msg) {
Taro.showToast({
icon:'none',
title:'授权失败,请求完善授权'
})
return false
}
if(selectCount.sumCount == 0) {
Taro.showToast({
icon:'none',
title:'请选择面料颜色!'
})
return false
}
const state = await addFetchData({
"sale_mode": selectIndex,
color_list: selectCount.color_list
})
if(state.success) {
Taro.showToast({
title:'添加成功'
})
getShopCount()
onClose?.()
} else {
Taro.showToast({
icon:'none',
title: state.msg
})
}
}
//筛选数据
const searchInput = useCallback((e) => {
condition.current.code_or_name = e
getColorList()
}, [])
//清空搜索内容
const searchRef = useRef<any>(null)
const clearSearch = () => {
searchRef.current.clearInput()
setSearchShow(false)
}
//格式化金额
const formatPrice = useCallback((item) => {
const price = Number(formatPriceDiv(item[selectList[selectIndex].priceField]))
return <View className={styles.priceText}><Text>¥</Text>{price}<Text> /{selectList[selectIndex].eunit}</Text></View>
}, [selectIndex])
//显示图片弹窗
const [showLabImage, setShowLabImage] = useState(false)
const [labImageValue, setLabImageValue] = useState()
const getLabAndImg = useCallback((val) => {
setShowLabImage(() => true)
setLabImageValue(val)
}, [])
const closeLabImgShow = useCallback(() => {
setShowLabImage(() => false)
}, [])
//虚拟滚动
const Rows = memo(({id, index, style, data}:any) => {
let item = data[index]
return (
<>
{item&&<View className={styles.item} key={item.id}>
<View className={styles.item_color}>
<LabAndImg value={{lab:item.lab,rgb:item.rgb,texture_url:item.texture_url, title:item.code}} showStatus={false} onClick={getLabAndImg}/>
</View>
<View className={styles.item_con}>
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
<View className={styles.num}>
{formatPrice(item)}
</View>
</View>
<View className={styles.btn_con}>
{!item.show&&<View className={styles.btn} onClick={() => onAdd(item)}></View>
||<View className={styles.btn_count}>
<Counter
otherData={item}
onBlue={getInputValue}
defaultNum={item.count}
step={selectList[selectIndex].step}
digits={selectList[selectIndex].digits}
onClickBtn={getInputValue}
unit={selectList[selectIndex].unit}
minNum={selectList[selectIndex].minNum}
maxNum={selectList[selectIndex].maxNum}
/>
</View>}
</View>
</View>||<View className={styles.item}></View>
}
</>
)
//计算总数量和总米/件数
const [selectCount, setSelectCount] = useState<{ sumCount: number; kindCount: number; color_list: any[] }>({
sumCount: 0,
kindCount: 0,
color_list: [],
})
useEffect(() => {
let sumCount = 0,
kindCount = 0,
color_list: any[] = []
let color_list_info = {}
list.map((item) => {
if (item.count > 0) {
sumCount = Big(sumCount).add(item.count).toNumber()
kindCount++
color_list_info = selectIndex == 0 ? { product_color_id: item.id, roll: item.count } : { product_color_id: item.id, length: item.count * 100 }
color_list.push(color_list_info)
}
})
setSelectCount({ ...selectCount, sumCount, kindCount, color_list })
}, [list])
return (
<View className={styles.shop_cart_main}>
<Popup showTitle={false} show={showPopup} onClose={() => closePopup()} >
<View className={styles.popup_con}>
<View className={styles.header}>{title}</View>
<View className={styles.search}>
<View className={styles.search_title}>:</View>
<View className={styles.search_list}>
{selectList.map((item, index) => {
return <View key={index} onClick={() => selectProduct(index)} className={classnames(styles.search_item, (selectIndex==index)&&styles.search_item_select)}>{item.title}</View>
})}
</View>
</View>
{searchShow&&<View className={styles.colorFind}>
<View className={styles.search}>
<Search placeIcon="out" ref={searchRef} changeOnSearch={searchInput} debounceTime={400}/>
</View>
<View className={styles.text} onClick={() => clearSearch()}></View>
</View>}
<View className={styles.colorNum}>
<View className={styles.title}> ({list.length})</View>
{!searchShow&&<View className={classnames('iconfont icon-sousuo', styles.miconfont)} onClick={() => changeSearchShow()}></View>}
</View>
<View className={styles.product_color_con}>
{(list.length <= 0 && colorState.loading)&&<LoadingCard/>}
{(list.length > 0&& !colorState.loading)&&
<View className={styles.color_con}>
<VirtualList
className={styles.virtual_list}
height={400} /* 列表的高度 */
width='100%' /* 列表的宽度 */
itemData={list} /* 渲染列表的数据 */
itemCount={list.length + 1} /* 渲染列表的长度 */
itemSize={100} /* 列表单项的高度 */
overscanCount={1}
>
{Rows}
</VirtualList>
<View className="common_safe_area_y"></View>
</View>}
{(list.length <= 0 && !colorState.loading)&&<View className={styles.noData}></View>}
</View>
<View className={styles.buy_btn}>
<View className={styles.buy_btn_con}>
<View className={styles.count}>{selectCount.kindCount}{selectCount.sumCount}{selectList[selectIndex].unit}</View>
<View className={classnames(styles.add_cart, selectCount.kindCount&&styles.select_add_cart)} onClick={() => addShopCart()}></View>
</View>
</View>
</View>
<View className="common_safe_area_y"></View>
</Popup>
<View>
<LabAndImgShow value={labImageValue} show={showLabImage} onClose={closeLabImgShow}/>
</View>
//计数组件
const getInputValue = useCallback(
(num, item) => {
item.count = parseFloat(num)
if (num == 0) item.show = false
setList(() => [...list])
},
[list],
)
const onAdd = (item) => {
item.show = true
item.count = selectList[selectIndex].defaultNum
setList((list) => [...list])
}
//搜索显示与隐藏
const [searchShow, setSearchShow] = useState(false)
const changeSearchShow = () => {
setSearchShow(true)
}
//添加购物车
const { getShopCount } = useCommonData()
const { getSelfUserInfo } = UseLogin()
const { fetchData: addFetchData } = AddShoppingCartApi()
const addShopCart = async () => {
try {
await getSelfUserInfo()
} catch (msg) {
Taro.showToast({
icon: 'none',
title: '授权失败,请求完善授权',
})
return false
}
if (selectCount.sumCount == 0) {
Taro.showToast({
icon: 'none',
title: '请选择面料颜色!',
})
return false
}
const state = await addFetchData({
sale_mode: selectIndex,
color_list: selectCount.color_list,
})
if (state.success) {
Taro.showToast({
title: '添加成功',
})
getShopCount()
onClose?.()
} else {
Taro.showToast({
icon: 'none',
title: state.msg,
})
}
}
//筛选数据
const searchInput = useCallback((e) => {
condition.current.code_or_name = e
getColorList()
}, [])
//清空搜索内容
const searchRef = useRef<any>(null)
const clearSearch = () => {
searchRef.current.clearInput()
setSearchShow(false)
}
//格式化金额
const formatPrice = useCallback(
(item) => {
const price = Number(formatPriceDiv(item[selectList[selectIndex].priceField]))
return (
<View className={styles.priceText}>
<Text>¥</Text>
{price}
<Text> /{selectList[selectIndex].eunit}</Text>
</View>
)
})
)
},
[selectIndex],
)
//显示图片弹窗
const [showLabImage, setShowLabImage] = useState(false)
const [labImageValue, setLabImageValue] = useState()
const getLabAndImg = useCallback((val) => {
setShowLabImage(() => true)
setLabImageValue(val)
}, [])
const closeLabImgShow = useCallback(() => {
setShowLabImage(() => false)
}, [])
//虚拟滚动
const Rows = memo(({ id, index, style, data }: any) => {
let item = data[index]
return (
<>
{(item && (
<View className={styles.item} key={item.id}>
<View className={styles.item_color}>
<LabAndImg value={{ lab: item.lab, rgb: item.rgb, texture_url: item.texture_url, title: item.code }} showStatus={false} onClick={getLabAndImg} />
</View>
<View className={styles.item_con}>
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
<View className={styles.num}>{formatPrice(item)}</View>
</View>
<View className={styles.btn_con}>
{(!item.show && (
<View className={styles.btn} onClick={() => onAdd(item)}>
</View>
)) || (
<View className={styles.btn_count}>
<Counter
otherData={item}
onBlue={getInputValue}
defaultNum={item.count}
step={selectList[selectIndex].step}
digits={selectList[selectIndex].digits}
onClickBtn={getInputValue}
unit={selectList[selectIndex].unit}
minNum={selectList[selectIndex].minNum}
maxNum={selectList[selectIndex].maxNum}
/>
</View>
)}
</View>
</View>
)) || <View className={styles.item}></View>}
</>
)
})
return (
<View className={styles.shop_cart_main}>
<Popup showTitle={false} show={showPopup} onClose={() => closePopup()}>
<View className={styles.popup_con}>
<View className={styles.header}>{title}</View>
<View className={styles.search}>
<View className={styles.search_title}>:</View>
<View className={styles.search_list}>
{selectList.map((item, index) => {
return (
<View
key={index}
onClick={() => selectProduct(index)}
className={classnames(styles.search_item, selectIndex == index && styles.search_item_select)}>
{item.title}
</View>
)
})}
</View>
</View>
{searchShow && (
<View className={styles.colorFind}>
<View className={styles.search}>
<Search placeIcon='out' ref={searchRef} changeOnSearch={searchInput} debounceTime={400} />
</View>
<View className={styles.text} onClick={() => clearSearch()}>
</View>
</View>
)}
<View className={styles.colorNum}>
<View className={styles.title}> ({list.length})</View>
{!searchShow && <View className={classnames('iconfont icon-sousuo', styles.miconfont)} onClick={() => changeSearchShow()}></View>}
</View>
<View className={styles.product_color_con}>
{list.length <= 0 && colorState.loading && <LoadingCard />}
{list.length > 0 && !colorState.loading && (
<View className={styles.color_con}>
<VirtualList
className={styles.virtual_list}
height={400} /* 列表的高度 */
width='100%' /* 列表的宽度 */
itemData={list} /* 渲染列表的数据 */
itemCount={list.length + 1} /* 渲染列表的长度 */
itemSize={100} /* 列表单项的高度 */
overscanCount={1}>
{Rows}
</VirtualList>
<View className='common_safe_area_y'></View>
</View>
)}
{list.length <= 0 && !colorState.loading && <View className={styles.noData}></View>}
</View>
<View className={styles.buy_btn}>
<View className={styles.buy_btn_con}>
<View className={styles.count}>
{selectCount.kindCount}{selectCount.sumCount}
{selectList[selectIndex].unit}
</View>
<View className={classnames(styles.add_cart, selectCount.kindCount && styles.select_add_cart)} onClick={() => addShopCart()}>
</View>
</View>
</View>
</View>
<View className='common_safe_area_y'></View>
</Popup>
<View>
<LabAndImgShow value={labImageValue} show={showLabImage} onClose={closeLabImgShow} />
</View>
</View>
)
})

View File

@ -1,57 +1,56 @@
import { Button, RichText, Text, View } from '@tarojs/components'
import Taro, { useDidShow, usePullDownRefresh, useRouter } from '@tarojs/taro';
import classnames from "classnames";
import DesSwiper from './components/swiper';
import OrderCount from './components/orderCount';
import ShopCart from '@/components/shopCart';
import styles from './index.module.scss'
import { useCallback, useEffect, useMemo, useState } from 'react';
import {formatHashTag} from '@/common/fotmat'
import {GetProductDetailApi} from '@/api/material'
import useLogin from '@/use/useLogin';
import { AnalysisShortCodeApi, GetShortCodeApi } from '@/api/share';
import { SHARE_SCENE } from '@/common/enum';
import useUserInfo from '@/use/useUserInfo';
import LabAndImg from '@/components/LabAndImg';
import { alert } from '@/common/common';
import AddCollection from '@/components/addCollection';
import { AddFavoriteApi, DelFavoriteProductApi } from '@/api/favorite';
import useCommonData from '@/use/useCommonData';
import { IMG_CND_Prefix } from '@/common/constant';
import Taro, { useDidShow, usePullDownRefresh, useRouter } from '@tarojs/taro'
import classnames from 'classnames'
import DesSwiper from './components/swiper'
import OrderCount from './components/orderCount'
import ShopCart from '@/components/shopCart'
import styles from './index.module.scss'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { formatHashTag } from '@/common/fotmat'
import { GetProductDetailApi } from '@/api/material'
import useLogin from '@/use/useLogin'
import { AnalysisShortCodeApi, GetShortCodeApi } from '@/api/share'
import { SHARE_SCENE } from '@/common/enum'
import useUserInfo from '@/use/useUserInfo'
import LabAndImg from '@/components/LabAndImg'
import { alert } from '@/common/common'
import AddCollection from '@/components/addCollection'
import { AddFavoriteApi, DelFavoriteProductApi } from '@/api/favorite'
import useCommonData from '@/use/useCommonData'
import { IMG_CND_Prefix } from '@/common/constant'
type item = {title:string, img:string, url:string, id:number}
type item = { title: string; img: string; url: string; id: number }
type Params = {
list?: item[]
swiperOnClick?: (val: item) => void,
swiperOnClick?: (val: item) => void
style?: Object
}
export default (props:Params) => {
const {getPhoneNumber, userInfo} = useLogin()
export default (props: Params) => {
const { getPhoneNumber, userInfo } = useLogin()
//获取参数(有两种参数1.商品id, 2.页面分享)
const router = useRouter()
const [params, setParams] = useState({id: '', share: null})
const [params, setParams] = useState({ id: '', share: null })
//判断是否是分享过来的参数
const judgeParam = async () => {
if(router.params.id) {
setParams({...params, id:router.params.id})
}else if(router.params.share) {
const judgeParam = async () => {
if (router.params.id) {
setParams({ ...params, id: router.params.id })
} else if (router.params.share) {
analysisShortCode()
}
}
//解析短码参数
const {fetchData: fetchDataAnalysisShortCode} = AnalysisShortCodeApi()
const { fetchData: fetchDataAnalysisShortCode } = AnalysisShortCodeApi()
const analysisShortCode = async () => {
let res = await fetchDataAnalysisShortCode({md5_key: router.params.share})
setParams({id: res.data.product_id, share: res.data})
let res = await fetchDataAnalysisShortCode({ md5_key: router.params.share })
setParams({ id: res.data.product_id, share: res.data })
}
//获取购物车数据数量
const {getShopCount, commonData} = useCommonData()
const { getShopCount, commonData } = useCommonData()
useDidShow(() => {
judgeParam()
@ -60,32 +59,31 @@ export default (props:Params) => {
})
useEffect(() => {
if(params.id) {
if (params.id) {
getProductDetail()
}
}, [params])
//获取数据
const [productInfo, setProductInfo] = useState<any>({})
const {fetchData} = GetProductDetailApi()
const { fetchData } = GetProductDetailApi()
const getProductDetail = async () => {
let {data} = await fetchData({id: params.id})
let { data } = await fetchData({ id: params.id })
setProductInfo(data)
Taro.stopPullDownRefresh()
}
useEffect(() => {
if(productInfo.code) {
if (productInfo.code) {
getShortCode()
setCollectStatus(() => productInfo.is_favorite)
}
}, [productInfo])
//面料名称
const productName = useMemo(() => {
return formatHashTag(productInfo.code, productInfo.name)
},[productInfo])
}, [productInfo])
const [showCart, setShowCart] = useState(false)
const [showOrderCount, setShowOrderCount] = useState(false)
@ -94,65 +92,72 @@ export default (props:Params) => {
// `
const html = ``
const {setSortCode, userInfo : userObj } = useUserInfo()
const { setSortCode, userInfo: userObj } = useUserInfo()
//详情页获取分享短码
const {ShareDetail} = SHARE_SCENE
const {fetchData: fetchDataShortCode} = GetShortCodeApi()
const { ShareDetail } = SHARE_SCENE
const { fetchData: fetchDataShortCode } = GetShortCodeApi()
const getShortCode = async () => {
const {data: resDetail} = await fetchDataShortCode({"share_user_id": userObj.adminUserInfo.user_id, type:ShareDetail.value, product_id: parseInt(params.id)})
const img = IMG_CND_Prefix + (productInfo.texture_url?productInfo.texture_url.split(',')[0]:'/mall/share_img_01.png')
setSortCode({... userObj.sort_code, shareShortDetail: {title: productName as string, code: resDetail.md5_key, img:img}})
const { data: resDetail } = await fetchDataShortCode({
share_user_id: userObj.adminUserInfo.user_id,
type: ShareDetail.value,
product_id: parseInt(params.id),
})
const img = IMG_CND_Prefix + (productInfo.texture_url ? productInfo.texture_url.split(',')[0] : '/mall/share_img_01.png')
setSortCode({ ...userObj.sort_code, shareShortDetail: { title: productName as string, code: resDetail.md5_key, img: img } })
}
//授权手机号和下单
const placeOrder = async (status = 'to_phone',e:any = {}) => {
if(!productInfo.id) return false
if(status == 'to_phone') {
if(!e.detail.code) return alert.error('请授权手机号')
const placeOrder = async (status = 'to_phone', e: any = {}) => {
if (!productInfo.id) return false
if (status == 'to_phone') {
if (!e.detail.code) return alert.error('请授权手机号')
try {
await getPhoneNumber(e.detail.code)
} catch(msg) {
} catch (msg) {
Taro.showToast({
icon:"none",
title: msg
icon: 'none',
title: msg,
})
return false
}
}
}
setShowOrderCount(true)
}
//收藏功能
const [collectStatus, setCollectStatus] = useState(false)
const [collectionShow, setCollectionShow] = useState(false)
const {fetchData: addFavoritefetchData} = AddFavoriteApi()
const { fetchData: addFavoritefetchData } = AddFavoriteApi()
const openCollection = () => {
if(productInfo.is_favorite) {
if (productInfo.is_favorite) {
delFavoriteProduct()
} else {
setCollectionShow(true)
}
}
const onAdd = useCallback(async (val) => {
let res = await addFavoritefetchData({favorite_id: val.id, product_id: Number(params.id)})
if(res.success) {
alert.success('添加成功')
setCollectStatus(true)
getProductDetail()
} else {
alert.none(res.msg)
}
setCollectionShow(false)
}, [params])
const onAdd = useCallback(
async (val) => {
let res = await addFavoritefetchData({ favorite_id: val.id, product_id: Number(params.id) })
if (res.success) {
alert.success('添加成功')
setCollectStatus(true)
getProductDetail()
} else {
alert.none(res.msg)
}
setCollectionShow(false)
},
[params],
)
const closeCollection = useCallback(() => {
setCollectionShow(false)
}, [])
//取消收藏
const {fetchData: delFavoriteProductFetchData} = DelFavoriteProductApi()
const { fetchData: delFavoriteProductFetchData } = DelFavoriteProductApi()
const delFavoriteProduct = async () => {
let res = await delFavoriteProductFetchData({favorite_id: productInfo.favorite_id, product_id:[productInfo.id]})
if(res.success) {
let res = await delFavoriteProductFetchData({ favorite_id: productInfo.favorite_id, product_id: [productInfo.id] })
if (res.success) {
setCollectStatus(false)
getProductDetail()
alert.none('已取消收藏')
@ -163,67 +168,85 @@ export default (props:Params) => {
usePullDownRefresh(() => {
getProductDetail()
})
return (
<View className={styles.main}>
<DesSwiper list={productInfo.texture_url?productInfo.texture_url.toString().split(','):[]}/>
<DesSwiper list={productInfo.texture_url ? productInfo.texture_url.toString().split(',') : []} />
<View className={styles.product_header}>
<View className={styles.title}>
{productInfo.code&&<View className={styles.name}>{productName}</View>}
{productInfo.code && <View className={styles.name}>{productName}</View>}
<View className={styles.des}>{productInfo.describe}</View>
</View>
<View className={styles.share}>
<View className={classnames('iconfont icon-fenxiang', styles.miconfont)}></View>
<View className={styles.text}></View>
<Button open-type="share" className={styles.shareBtn}></Button>
<Button open-type='share' className={styles.shareBtn}></Button>
</View>
<View className={styles.collect} onClick={openCollection}>
<View className={classnames(`iconfont ${collectStatus?'icon-shoucang-pressed':'icon-shoucang'}`, styles.miconfont, collectStatus&&styles.collected)} ></View>
<View
className={classnames(
`iconfont ${collectStatus ? 'icon-shoucang-pressed' : 'icon-shoucang'}`,
styles.miconfont,
collectStatus && styles.collected,
)}></View>
<View className={styles.text}></View>
</View>
</View>
<View className={styles.des_data}>
<View className={styles.title}></View>
<View className={styles.con}>
<View className={styles.des_text}><Text>{productInfo.code}</Text></View>
<View className={styles.des_text}><Text>{productInfo.width}</Text></View>
<View className={styles.des_text}><Text>{productInfo.weight_density}</Text></View>
<View className={styles.des_text}><Text>{productInfo.component}</Text></View>
<View className={styles.des_text}>
<Text>{productInfo.code}</Text>
</View>
<View className={styles.des_text}>
<Text>{productInfo.width}</Text>
</View>
<View className={styles.des_text}>
<Text>{productInfo.weight_density}</Text>
</View>
<View className={styles.des_text}>
<Text>{productInfo.component}</Text>
</View>
</View>
</View>
<View className={styles.product_color}>
<View className={styles.title}> ({productInfo?.product_color_list?.length})</View>
<View className={styles.list}>
{productInfo?.product_color_list?.map(item => {
return <View key={item.id} className={styles.item}>
<View className={styles.item_color}>
<LabAndImg value={{lab:item.lab,rgb:item.rgb,texture_url:item.texture_url, title: item.code}} showStatus={true}/>
</View>
<View className={styles.item_name}>{item.code}</View>
<View className={styles.list}>
{productInfo?.product_color_list?.map((item) => {
return (
<View key={item.id} className={styles.item}>
<View className={styles.item_color}>
<LabAndImg value={{ lab: item.lab, rgb: item.rgb, texture_url: item.texture_url, title: item.code }} showStatus={true} />
</View>
})}
</View>
<View className={styles.item_name}>{item.code}</View>
</View>
)
})}
</View>
</View>
<View className={styles.product_detail}>
<RichText nodes={html}></RichText>
<RichText nodes={html}></RichText>
</View>
<View className={styles.product_buy}>
<View className={styles.buy_cart} onClick={() => setShowCart(true)}>
<View className={styles.buy_cart} onClick={() => setShowCart(true)}>
<View className={classnames('iconfont icon-gouwuche', styles.miconfont)}></View>
<View className={styles.text}></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>}
</View>
{
(!userInfo.adminUserInfo?.is_authorize_phone)&&<View className={styles.buy_btn} >
<Button className={styles.phoneBtn} open-type="getPhoneNumber" onGetPhoneNumber={(e) => placeOrder('to_phone',e)}></Button>
</View>
|| <View className={styles.buy_btn} onClick={() => placeOrder('to_order')}></View>
}
{(!userInfo.adminUserInfo?.is_authorize_phone && (
<View className={styles.buy_btn}>
<Button className={styles.phoneBtn} open-type='getPhoneNumber' onGetPhoneNumber={(e) => placeOrder('to_phone', e)}></Button>
</View>
)) || (
<View className={styles.buy_btn} onClick={() => placeOrder('to_order')}>
</View>
)}
</View>
<OrderCount show={showOrderCount} onClose={() => setShowOrderCount(false)} title={productName} productId={productInfo.id}/>
<ShopCart show={showCart} onClose={() => setShowCart(false)}/>
<AddCollection show={collectionShow} onAdd={onAdd} onClose={closeCollection}/>
<OrderCount show={showOrderCount} onClose={() => setShowOrderCount(false)} title={productName} productId={productInfo.id} />
<ShopCart show={showCart} onClose={() => setShowCart(false)} />
<AddCollection show={collectionShow} onAdd={onAdd} onClose={closeCollection} />
<View className='common_safe_area_y'></View>
</View>
)

View File

@ -1,47 +1,54 @@
import { ScrollView, View } from "@tarojs/components"
import { memo, useEffect, useState } from "react"
import styles from './index.module.scss'
import classnames from "classnames";
import { ScrollView, View } from '@tarojs/components'
import { memo, useEffect, useState } from 'react'
import styles from './index.module.scss'
import classnames from 'classnames'
type Param = {
list: {id: number, name: string}[],
defaultId?: number|null,
onSelect?: (val: number) => void
list: { id: number; name: string }[]
defaultId?: number | null
onSelect?: (val: number) => void
}
export default memo(({list = [], defaultId = null, onSelect}: Param) => {
const [selectInfo, setSelectInfo] = useState({
selected: -1, //当前选中的id
tabId: '', //需要滚动到的id
})
useEffect(() => {
if(defaultId) {
console.log('defaultId:::', defaultId)
const index = list?.findIndex(item => {
return item.id == defaultId
})
if(index !== -1) {
const num = index > 0?( index - 1) : 0
setSelectInfo((e) => ({...e, tabId:list[num].id.toString()}))
}
}
setSelectInfo((e) => ({...e, selected: defaultId||-1}))
}, [defaultId])
const clickEvent = ({item, index}: {item:any, index:number}) => {
const num = index > 0?( index - 1) : 0
setSelectInfo((e) => ({...e, tabId:list[num].id.toString(), selected: item.id}))
onSelect?.(item.id)
export default memo(({ list = [], defaultId = null, onSelect }: Param) => {
const [selectInfo, setSelectInfo] = useState({
selected: -1, //当前选中的id
tabId: '', //需要滚动到的id
})
useEffect(() => {
if (defaultId) {
console.log('defaultId:::', defaultId)
const index = list?.findIndex((item) => {
return item.id == defaultId
})
if (index !== -1) {
const num = index > 0 ? index - 1 : 0
setSelectInfo((e) => ({ ...e, tabId: list[num].id.toString() }))
}
}
setSelectInfo((e) => ({ ...e, selected: defaultId || -1 }))
}, [defaultId])
const clickEvent = ({ item, index }: { item: any; index: number }) => {
const num = index > 0 ? index - 1 : 0
setSelectInfo((e) => ({ ...e, tabId: list[num].id.toString(), selected: item.id }))
onSelect?.(item.id)
}
return (
<View className={styles.order_status_list}>
<ScrollView scrollX scrollIntoView={`tabs_${selectInfo.tabId}`} scrollWithAnimation={true}>
<View className={styles.order_list_scroll}>
{list.map((item, index) => {
return <View key={item.id} id={`tabs_${item.id}`} onClick={() => clickEvent({item, index})} className={classnames(styles.order_status_item, (selectInfo.selected==item.id)&&styles.selected)}>{item.name}</View>
})}
</View>
</ScrollView>
return (
<View className={styles.order_status_list}>
<ScrollView scrollX scrollIntoView={`tabs_${selectInfo.tabId}`} scrollWithAnimation={true}>
<View className={styles.order_list_scroll}>
{list.map((item, index) => {
return (
<View
key={item.id}
id={`tabs_${item.id}`}
onClick={() => clickEvent({ item, index })}
className={classnames(styles.order_status_item, selectInfo.selected == item.id && styles.selected)}>
{item.name}
</View>
)
})}
</View>
)
</ScrollView>
</View>
)
})

View File

@ -1,220 +1,221 @@
import { Image, ScrollView, Text, View } from "@tarojs/components"
import classnames from "classnames";
import Filter from "@/components/filter";
import { Image, ScrollView, Text, View } from '@tarojs/components'
import classnames from 'classnames'
import Filter from '@/components/filter'
import InfiniteScroll from '@/components/infiniteScroll'
import SortBtn from "@/components/sortBtn";
import SearchInput from "@/components/searchInput";
import LinkBlueTooth from "@/components/bluetooth/LinkBlueTooth";
import {useBluetooth} from "@/use/contextBlueTooth"
import {toRgb} from '@/common/bluetooth/color/colorSpace'
import styles from './hightSearchList.module.scss'
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import Taro, { useDidShow, usePullDownRefresh, useReady } from "@tarojs/taro";
import {GetLabProductApi} from "@/api/material"
import { dataLoadingStatus, getFilterData } from "@/common/util";
import { formatHashTag, formatImgUrl } from "@/common/fotmat";
import useLogin from "@/use/useLogin";
import { goLink } from "@/common/common";
import SelectData, {ListProps} from "./components/selectData";
import LabAndImg from "@/components/LabAndImg";
import SortBtn from '@/components/sortBtn'
import SearchInput from '@/components/searchInput'
import LinkBlueTooth from '@/components/bluetooth/LinkBlueTooth'
import { useBluetooth } from '@/use/contextBlueTooth'
import { toRgb } from '@/common/bluetooth/color/colorSpace'
import styles from './hightSearchList.module.scss'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import Taro, { useDidShow, usePullDownRefresh, useReady } from '@tarojs/taro'
import { GetLabProductApi } from '@/api/material'
import { dataLoadingStatus, getFilterData } from '@/common/util'
import { formatHashTag, formatImgUrl } from '@/common/fotmat'
import useLogin from '@/use/useLogin'
import { goLink } from '@/common/common'
import SelectData, { ListProps } from './components/selectData'
import LabAndImg from '@/components/LabAndImg'
export default () => {
useLogin()
useLogin()
const firstOpen = useRef(true)
const [showFilter, setShowFilter] = useState(false)
//搜索参数
const [searchField, setSearchField] = useState({
l: '',
a: '',
b: '',
page : 1,
size : 10,
width: '',
weight_density: '',
product_kind_id: '',
component: '',
abstract_sort_key: ''
const firstOpen = useRef(true)
const [showFilter, setShowFilter] = useState(false)
//搜索参数
const [searchField, setSearchField] = useState({
l: '',
a: '',
b: '',
page: 1,
size: 10,
width: '',
weight_density: '',
product_kind_id: '',
component: '',
abstract_sort_key: '',
})
//获取面料列表
const [materialList, setMaterialList] = useState<{ list: any[]; total: number }>({ list: [], total: 0 })
const { fetchData: materialFetchData, state: materialState } = GetLabProductApi()
const getProductList = async () => {
let { data } = await materialFetchData(getFilterData(searchField))
setMaterialList({ list: data.list, total: data.total })
Taro.stopPullDownRefresh()
firstOpen.current = false
}
//监听筛选条件变化
useEffect(() => {
getProductList()
}, [searchField])
//上拉加载数据
const pageNum = useRef({ size: searchField.size, page: searchField.page })
const getScrolltolower = () => {
if (materialList.list.length < materialList.total) {
pageNum.current.page++
const size = pageNum.current.size * pageNum.current.page
setSearchField({ ...searchField, size })
}
}
//数据加载状态
const statusMore = useMemo(() => {
return dataLoadingStatus({ list: materialList.list, total: materialList.total, status: materialState.loading })
}, [materialList, materialState])
const { state: colorState, measureAndGetLab } = useBluetooth()
const getLab = () => {
if (colorState.connected) {
measureAndGetLab()
} else {
Taro.showToast({
title: '请链接设备',
icon: 'none',
})
}
}
//监听lab数据变化
const [blueToothColor, setBlueToothColor] = useState('')
useEffect(() => {
if (colorState.deviceLab && !firstOpen.current) {
const rgb = toRgb([colorState.deviceLab.L, colorState.deviceLab.a, colorState.deviceLab.b])
setBlueToothColor(`rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`)
setSearchField({ ...searchField, l: rgb[0], a: rgb[1], b: rgb[2], size: 10, page: 1 })
setMaterialList(() => ({ list: [], total: 0 }))
pageNum.current = { size: 10, page: 1 }
}
}, [colorState.deviceLab])
const goLinkPage = (item) => {
goLink('/pages/details/index', { id: item.product_id })
}
//获取筛选条件
const getFiltr = (e) => {
pageNum.current.page = 1
setMaterialList(() => ({ list: [], total: 0 }))
const { data } = e
setSearchField({
...searchField,
width: data?.width,
weight_density: data?.weight,
size: 10,
component: data?.element,
product_kind_id: data?.seriesId,
})
formatSelectList(e)
}
//获取面料列表
const [materialList, setMaterialList] = useState<{list:any[], total:number}>({list:[], total:0})
const {fetchData: materialFetchData, state: materialState} = GetLabProductApi()
const getProductList = async () => {
let {data} = await materialFetchData(getFilterData(searchField))
setMaterialList({list:data.list, total:data.total})
Taro.stopPullDownRefresh()
firstOpen.current = false
//筛选条件格式化
const [selectList, setSelectList] = useState<ListProps[]>()
const formatSelectList = (val = { data: {}, field: {} }) => {
let data: ListProps[] = []
for (let key in val.data) {
if (key !== 'seriesId' && val.data[key] != '') {
data.push({ title: val.field[key], value: val.data[key] })
}
}
setSelectList([...data])
}
//监听筛选条件变化
useEffect(() => {
getProductList()
}, [searchField])
//页面下拉刷新
usePullDownRefresh(() => {
setSearchField({ ...searchField, size: 10 })
})
//上拉加载数据
const pageNum = useRef({size: searchField.size, page: searchField.page})
const getScrolltolower = () => {
if(materialList.list.length < materialList.total) {
pageNum.current.page++
const size = pageNum.current.size * pageNum.current.page
setSearchField({...searchField, size })
}
//排序
type sortParam = 'none' | 'top' | 'bottom'
const sortComprehensiveRef = useRef<any>(null)
const sortCollectionRef = useRef<any>(null)
const [sortStatus, setSortStatus] = useState<{ comprehensive: sortParam; collection: sortParam }>({
comprehensive: 'none',
collection: 'none',
})
const changeSort = (val) => {
setMaterialList(() => ({ list: [], total: 0 }))
if (val == 1) {
const { status, value } = sortComprehensiveRef.current.changeSort()
setSortStatus((e) => ({ ...e, comprehensive: status, collection: 'none' }))
setSearchField((e) => ({ ...e, abstract_sort_key: value, size: 10, page: 1 }))
} else {
const { status, value } = sortCollectionRef.current.changeSort()
setSortStatus((e) => ({ ...e, collection: status, comprehensive: 'none' }))
setSearchField((e) => ({ ...e, abstract_sort_key: value, size: 10, page: 1 }))
}
pageNum.current = { size: 10, page: 1 }
}
//数据加载状态
const statusMore = useMemo(() => {
return dataLoadingStatus({list:materialList.list, total: materialList.total, status: materialState.loading})
}, [materialList, materialState])
const {state: colorState, measureAndGetLab} = useBluetooth()
const getLab = () => {
if(colorState.connected) {
measureAndGetLab()
} else {
Taro.showToast({
title: '请链接设备',
icon: 'none'
})
}
}
//监听lab数据变化
const [blueToothColor, setBlueToothColor] = useState('')
useEffect(() => {
if(colorState.deviceLab && !firstOpen.current) {
const rgb = toRgb([colorState.deviceLab.L, colorState.deviceLab.a, colorState.deviceLab.b])
setBlueToothColor(`rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`)
setSearchField({...searchField, l:rgb[0], a:rgb[1], b:rgb[2], size:10, page:1})
setMaterialList(() => ({list:[], total:0}))
pageNum.current = {size: 10, page: 1}
}
}, [colorState.deviceLab])
const goLinkPage = (item) => {
goLink('/pages/details/index',{id:item.product_id})
}
//获取筛选条件
const getFiltr = (e) => {
pageNum.current.page = 1
setMaterialList(() => ({list:[], total:0}))
const {data} = e
setSearchField({
...searchField,
width: data?.width,
weight_density: data?.weight,
size: 10,
component: data?.element,
product_kind_id: data?.seriesId
})
formatSelectList(e)
}
//筛选条件格式化
const [selectList , setSelectList] = useState<ListProps[]>()
const formatSelectList = (val = {data:{}, field:{}}) => {
let data:ListProps[] = []
for(let key in val.data) {
if(key !== 'seriesId'&& val.data[key] != '') {
data.push({title:val.field[key], value:val.data[key]})
}
}
setSelectList([...data])
}
//页面下拉刷新
usePullDownRefresh(() => {
setSearchField({...searchField ,size : 10})
})
//排序
type sortParam = 'none'|'top'|'bottom'
const sortComprehensiveRef = useRef<any>(null)
const sortCollectionRef = useRef<any>(null)
const [sortStatus, setSortStatus] = useState<{comprehensive:sortParam, collection:sortParam}>({
comprehensive: 'none',
collection: 'none'
})
const changeSort = (val) => {
setMaterialList(() => ({list:[], total:0}))
if(val == 1) {
const {status, value} = sortComprehensiveRef.current.changeSort()
setSortStatus((e) => ({...e, comprehensive: status, collection: 'none'}))
setSearchField((e) => ({...e, abstract_sort_key: value, size:10, page:1}))
} else {
const {status, value} = sortCollectionRef.current.changeSort()
setSortStatus((e) => ({...e, collection: status, comprehensive: 'none'}))
setSearchField((e) => ({...e, abstract_sort_key: value, size:10, page:1}))
}
pageNum.current = {size: 10, page: 1}
}
const labAndImgObj = useCallback((item) => {
const img = item?item.texture_url.split(',')[0]:''
return {lab:item.lab,rgb:item.rgb,texture_url:img}
}, [materialList])
return (
<View className={styles.main}>
<View className={styles.search}>
<View className={styles.SearchInput}>
<LinkBlueTooth/>
<SearchInput title="提取颜色" showBorder={false}>
<View className={styles.bluetooth_color} onClick={() => getLab()}>
{blueToothColor&&<View className={classnames(styles.color_bock)} style={{background:blueToothColor}}></View>||
<View className={classnames(styles.color_bock_no)} ></View>
}
</View>
</SearchInput>
</View>
const labAndImgObj = useCallback(
(item) => {
const img = item ? item.texture_url.split(',')[0] : ''
return { lab: item.lab, rgb: item.rgb, texture_url: img }
},
[materialList],
)
return (
<View className={styles.main}>
<View className={styles.search}>
<View className={styles.SearchInput}>
<LinkBlueTooth />
<SearchInput title='提取颜色' showBorder={false}>
<View className={styles.bluetooth_color} onClick={() => getLab()}>
{(blueToothColor && <View className={classnames(styles.color_bock)} style={{ background: blueToothColor }}></View>) || (
<View className={classnames(styles.color_bock_no)}></View>
)}
</View>
<View className={styles.filter}>
<View className={styles.filter_all}>
<View className={styles.text_zh} onClick={() => changeSort(1)}>
<Text></Text>
<SortBtn status={sortStatus.comprehensive} ref={sortComprehensiveRef} sortValue={{desc: '1', asc: '-1'}}/>
</View>
<View className={styles.text_sc} onClick={() => changeSort(2)}>
<Text></Text>
<SortBtn status={sortStatus.collection} ref={sortCollectionRef} sortValue={{desc: '2', asc: '-2'}}/>
</View>
</View>
<View className={styles.filter_btn_con}>
<View className={styles.filter_scroll}>
<SelectData list={selectList}/>
</View>
<View className={styles.filter_more} onClick={() => setShowFilter(true)}>
<Text></Text>
<Text className={classnames('iconfont icon-shaixuan', styles.miconfont)}></Text>
</View>
</View>
</View>
<View className={styles.list}>
<View className={classnames(styles.list_num, styles.list_num_shadow)}> ({materialList.total})</View>
<View className={styles.scroll}>
<InfiniteScroll
selfonScrollToLower={getScrolltolower}
statusMore={statusMore}
>
<View className={styles.product_list}>
{materialList.list.map(item => {
return <View key={item.id} className={styles.product_item} onClick={() => goLinkPage(item)}>
<View className={styles.product_img}>
<LabAndImg value={labAndImgObj(item)}/>
<View className={styles.color_num}>{(item.product_color_code)}</View>
</View>
<View className={styles.product_info}>
<View className={styles.title}>{formatHashTag(item.product_code, item.product_name)}</View>
<View className={styles.introduce}>{item.product_kind_name}</View>
</View>
</View>
})}
</View>
</InfiniteScroll>
</View>
</View>
<Filter show={showFilter} onFiltr={(e) => getFiltr(e)} onClose={() => setShowFilter(false)}/>
</SearchInput>
</View>
)
}
</View>
<View className={styles.filter}>
<View className={styles.filter_all}>
<View className={styles.text_zh} onClick={() => changeSort(1)}>
<Text></Text>
<SortBtn status={sortStatus.comprehensive} ref={sortComprehensiveRef} sortValue={{ desc: '1', asc: '-1' }} />
</View>
<View className={styles.text_sc} onClick={() => changeSort(2)}>
<Text></Text>
<SortBtn status={sortStatus.collection} ref={sortCollectionRef} sortValue={{ desc: '2', asc: '-2' }} />
</View>
</View>
<View className={styles.filter_btn_con}>
<View className={styles.filter_scroll}>
<SelectData list={selectList} />
</View>
<View className={styles.filter_more} onClick={() => setShowFilter(true)}>
<Text></Text>
<Text className={classnames('iconfont icon-shaixuan', styles.miconfont)}></Text>
</View>
</View>
</View>
<View className={styles.list}>
<View className={classnames(styles.list_num, styles.list_num_shadow)}> ({materialList.total})</View>
<View className={styles.scroll}>
<InfiniteScroll selfonScrollToLower={getScrolltolower} statusMore={statusMore}>
<View className={styles.product_list}>
{materialList.list.map((item) => {
return (
<View key={item.id} className={styles.product_item} onClick={() => goLinkPage(item)}>
<View className={styles.product_img}>
<LabAndImg value={labAndImgObj(item)} />
<View className={styles.color_num}>{item.product_color_code}</View>
</View>
<View className={styles.product_info}>
<View className={styles.title}>{formatHashTag(item.product_code, item.product_name)}</View>
<View className={styles.introduce}>{item.product_kind_name}</View>
</View>
</View>
)
})}
</View>
</InfiniteScroll>
</View>
</View>
<Filter show={showFilter} onFiltr={(e) => getFiltr(e)} onClose={() => setShowFilter(false)} />
</View>
)
}

View File

@ -1,36 +1,35 @@
import { Text, View } from '@tarojs/components'
import Search from '@/components/search'
import { alert, goLink } from '@/common/common';
import classnames from "classnames";
import styles from './search.module.scss'
import { useEffect, useRef, useState } from 'react';
import {GetHotSearchApi, GetSearchHistoryApi, AddSearchHistoryApi} from "@/api/search"
import { SCENE } from '@/common/constant';
import useLogin from '@/use/useLogin';
import Taro, { useDidShow, useShareAppMessage } from '@tarojs/taro';
import { alert, goLink } from '@/common/common'
import classnames from 'classnames'
import styles from './search.module.scss'
import { useEffect, useRef, useState } from 'react'
import { GetHotSearchApi, GetSearchHistoryApi, AddSearchHistoryApi } from '@/api/search'
import { SCENE } from '@/common/constant'
import useLogin from '@/use/useLogin'
import Taro, { useDidShow, useShareAppMessage } from '@tarojs/taro'
type searchDataParam = {'search_key':''}
type searchDataParam = { search_key: '' }
export default () => {
useLogin()
const [searchData, setSearchData] = useState<{hotField: searchDataParam[], historyField: searchDataParam[]}>({
const [searchData, setSearchData] = useState<{ hotField: searchDataParam[]; historyField: searchDataParam[] }>({
hotField: [],
historyField: []
historyField: [],
})
//获取热门搜索数据
const {fetchData:hotFetchData} = GetHotSearchApi()
const { fetchData: hotFetchData } = GetHotSearchApi()
const getHotSearch = async () => {
let {data} = await hotFetchData({page:1, size:10})
setSearchData((val) => ({...val, hotField: data.list}))
let { data } = await hotFetchData({ page: 1, size: 10 })
setSearchData((val) => ({ ...val, hotField: data.list }))
}
//获取历史搜索数据
const {fetchData:HistoryFetchData} = GetSearchHistoryApi()
const { fetchData: HistoryFetchData } = GetSearchHistoryApi()
const getSearchHistory = async () => {
let {data} = await HistoryFetchData({page:1, size:10})
setSearchData((val) => ({...val, historyField: data.list}))
let { data } = await HistoryFetchData({ page: 1, size: 10 })
setSearchData((val) => ({ ...val, historyField: data.list }))
}
useDidShow(() => {
@ -39,53 +38,65 @@ export default () => {
})
//添加搜索关键字
const addSearchField = useRef({key: '', screen: SCENE.SearchScene})
const {fetchData:addFetchData} = AddSearchHistoryApi()
const addSearchField = useRef({ key: '', screen: SCENE.SearchScene })
const { fetchData: addFetchData } = AddSearchHistoryApi()
const addSearchHistory = async () => {
await addFetchData(addSearchField.current)
// goLink('/pages/searchList/searchList', {key: addSearchField.current.key})
}
//搜索事件, status = true 添加搜索, status = false 直接跳转
const searchEvent = (e, status = true) => {
if(e == "") {
if (e == '') {
alert.error('请输入关键词')
return false
}
}
addSearchField.current.key = e
status&&addSearchHistory()
status && addSearchHistory()
Taro.navigateTo({
url: `/pages/searchList/searchList?key=${addSearchField.current.key}`
url: `/pages/searchList/searchList?key=${addSearchField.current.key}`,
})
}
return (
<View className={styles.main}>
<View className={styles.search}>
<Search style={{width: '100%'}} placeholder="请输入面料关键词" placeIcon="out" showBtn={true} clickOnSearch={(e) => searchEvent(e)}/>
<Search style={{ width: '100%' }} placeholder='请输入面料关键词' placeIcon='out' showBtn={true} clickOnSearch={(e) => searchEvent(e)} />
</View>
<View className={styles.up_search} onClick={() => goLink('/pages/searchList/hightSearchList')}></View>
{searchData?.hotField.length > 0 && <View className={styles.hot}>
<View className={styles.hot_header}>
<View className={styles.hot_header_title}></View>
<View className={styles.up_search} onClick={() => goLink('/pages/searchList/hightSearchList')}>
</View>
{searchData?.hotField.length > 0 && (
<View className={styles.hot}>
<View className={styles.hot_header}>
<View className={styles.hot_header_title}></View>
</View>
<View className={styles.list}>
{searchData.hotField.map((item) => {
return (
<View className={styles.item} onClick={() => searchEvent(item.search_key, false)}>
{item.search_key}
</View>
)
})}
</View>
</View>
<View className={styles.list}>
{searchData.hotField.map((item, index) => {
return <View key={index} className={styles.item} onClick={() => searchEvent(item.search_key, false)}>{item.search_key}</View>
})}
)}
{searchData?.historyField.length > 0 && (
<View className={styles.history}>
<View className={styles.history_header}>
<View className={styles.history_header_title}></View>
{/* <View className={classnames('iconfont icon-shanchu', styles.miconfont)}></View> */}
</View>
<View className={styles.list}>
{searchData?.historyField?.map((item) => (
<View className={styles.item} onClick={() => searchEvent(item.search_key, false)}>
{item.search_key}
</View>
))}
</View>
</View>
</View>}
{searchData?.historyField.length > 0 && <View className={styles.history}>
<View className={styles.history_header}>
<View className={styles.history_header_title}></View>
{/* <View className={classnames('iconfont icon-shanchu', styles.miconfont)}></View> */}
</View>
<View className={styles.list}>
{searchData?.historyField?.map((item, index) => <View key={index} className={styles.item} onClick={() => searchEvent(item.search_key, false)}>{item.search_key}</View>)}
</View>
</View>}
)}
</View>
)
}

View File

@ -1,198 +1,199 @@
import { Image, ScrollView, Text, View } from "@tarojs/components"
import classnames from "classnames";
import { Image, ScrollView, Text, View } from '@tarojs/components'
import classnames from 'classnames'
import Search from '@/components/search'
import Filter from "@/components/filter";
import Filter from '@/components/filter'
import InfiniteScroll from '@/components/infiniteScroll'
import SortBtn from "@/components/sortBtn";
import SelectData, {ListProps} from "./components/selectData";
import { goLink } from "@/common/common";
import styles from './searchList.module.scss'
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import {GetProductListApi} from "@/api/material"
import Taro, { useDidShow, usePullDownRefresh, useRouter } from "@tarojs/taro";
import { formatHashTag, formatImgUrl } from "@/common/fotmat";
import { dataLoadingStatus, getFilterData } from "@/common/util";
import useLogin from "@/use/useLogin";
import LabAndImg from "@/components/LabAndImg";
import SortBtn from '@/components/sortBtn'
import SelectData, { ListProps } from './components/selectData'
import { goLink } from '@/common/common'
import styles from './searchList.module.scss'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { GetProductListApi } from '@/api/material'
import Taro, { useDidShow, usePullDownRefresh, useRouter } from '@tarojs/taro'
import { formatHashTag, formatImgUrl } from '@/common/fotmat'
import { dataLoadingStatus, getFilterData } from '@/common/util'
import useLogin from '@/use/useLogin'
import LabAndImg from '@/components/LabAndImg'
export default () => {
useLogin()
useLogin()
const [showFilter, setShowFilter] = useState(false)
const router = useRouter()
const [showFilter, setShowFilter] = useState(false)
const router = useRouter()
//搜索参数
const [searchField, setSearchField] = useState({
code_or_name: router.params.key,
page : 1,
size : 10,
width: '',
weight_density: '',
product_kind_id: '',
component: '',
abstract_sort_key: ''
//搜索参数
const [searchField, setSearchField] = useState({
code_or_name: router.params.key,
page: 1,
size: 10,
width: '',
weight_density: '',
product_kind_id: '',
component: '',
abstract_sort_key: '',
})
//获取面料列表
const [materialList, setMaterialList] = useState<{ list: any[]; total: number }>({ list: [], total: 0 })
const { fetchData: materialFetchData, state: materialState } = GetProductListApi()
const getProductList = async () => {
let { data } = await materialFetchData(getFilterData(searchField))
setMaterialList({ list: data.list, total: data.total })
Taro.stopPullDownRefresh()
}
//监听筛选条件变化
useEffect(() => {
getProductList()
}, [searchField])
//上拉加载数据
const pageNum = useRef({ size: searchField.size, page: searchField.page })
const getScrolltolower = () => {
if (materialList.list.length < materialList.total) {
pageNum.current.page++
const size = pageNum.current.size * pageNum.current.page
setSearchField({ ...searchField, size })
}
}
//数据加载状态
const statusMore = useMemo(() => {
return dataLoadingStatus({ list: materialList.list, total: materialList.total, status: materialState.loading })
}, [materialList, materialState])
//输入了搜索关键字
const getSearchData = useCallback((e) => {
pageNum.current.page = 1
setMaterialList(() => ({ list: [], total: 0 }))
setSearchField((val) => ({ ...val, code_or_name: e, size: 10 }))
pageNum.current = { size: 10, page: 1 }
}, [])
const goLinkPage = (item) => {
goLink('/pages/details/index', { id: item.id })
}
//页面下拉刷新
usePullDownRefresh(() => {
setSearchField({ ...searchField, size: 10 })
})
//获取筛选条件
const getFiltr = (e) => {
pageNum.current.page = 1
setMaterialList(() => ({ list: [], total: 0 }))
const { data } = e
setSearchField({
...searchField,
width: data?.width,
weight_density: data?.weight,
size: 10,
component: data?.element,
product_kind_id: data?.seriesId,
})
//获取面料列表
const [materialList, setMaterialList] = useState<{list:any[], total:number}>({list:[], total:0})
const {fetchData: materialFetchData, state: materialState} = GetProductListApi()
const getProductList = async () => {
let {data} = await materialFetchData(getFilterData(searchField))
setMaterialList({list:data.list, total:data.total})
Taro.stopPullDownRefresh()
formatSelectList(e)
}
//筛选条件格式化
const [selectList, setSelectList] = useState<ListProps[]>()
const formatSelectList = (val = { data: {}, field: {} }) => {
let data: ListProps[] = []
for (let key in val.data) {
if (key !== 'seriesId' && val.data[key] != '') {
data.push({ title: val.field[key], value: val.data[key] })
}
}
setSelectList([...data])
}
//监听筛选条件变化
useEffect(() => {
getProductList()
}, [searchField])
//上拉加载数据
const pageNum = useRef({size: searchField.size, page: searchField.page})
const getScrolltolower = () => {
if(materialList.list.length < materialList.total) {
pageNum.current.page++
const size = pageNum.current.size * pageNum.current.page
setSearchField({...searchField, size })
}
//排序
type sortParam = 'none' | 'top' | 'bottom'
const sortComprehensiveRef = useRef<any>(null)
const sortCollectionRef = useRef<any>(null)
const [sortStatus, setSortStatus] = useState<{ comprehensive: sortParam; collection: sortParam }>({
comprehensive: 'none',
collection: 'none',
})
const changeSort = (val) => {
if (val == 1) {
const { status, value } = sortComprehensiveRef.current.changeSort()
setSortStatus((e) => ({ ...e, comprehensive: status, collection: 'none' }))
setSearchField((e) => ({ ...e, abstract_sort_key: value, size: 10, page: 1 }))
} else {
const { status, value } = sortCollectionRef.current.changeSort()
setSortStatus((e) => ({ ...e, collection: status, comprehensive: 'none' }))
setSearchField((e) => ({ ...e, abstract_sort_key: value, size: 10, page: 1 }))
}
pageNum.current = { size: 10, page: 1 }
}
//数据加载状态
const statusMore = useMemo(() => {
return dataLoadingStatus({list:materialList.list, total: materialList.total, status: materialState.loading})
}, [materialList, materialState])
//输入了搜索关键字
const getSearchData = useCallback((e) => {
pageNum.current.page = 1
setMaterialList(() => ({list:[], total:0}))
setSearchField((val) => ({...val, code_or_name:e, size:10}))
pageNum.current = {size: 10, page: 1}
}, [])
const goLinkPage = (item) => {
goLink('/pages/details/index',{id:item.id})
}
//页面下拉刷新
usePullDownRefresh(() => {
setSearchField({...searchField ,size : 10})
})
//获取筛选条件
const getFiltr = (e) => {
pageNum.current.page = 1
setMaterialList(() => ({list:[], total:0}))
const {data} = e
setSearchField({
...searchField,
width: data?.width,
weight_density: data?.weight,
size: 10,
component: data?.element,
product_kind_id: data?.seriesId
})
formatSelectList(e)
}
//筛选条件格式化
const [selectList , setSelectList] = useState<ListProps[]>()
const formatSelectList = (val = {data:{}, field:{}}) => {
let data:ListProps[] = []
for(let key in val.data) {
if(key !== 'seriesId'&& val.data[key] != '') {
data.push({title:val.field[key], value:val.data[key]})
}
}
setSelectList([...data])
}
//排序
type sortParam = 'none'|'top'|'bottom'
const sortComprehensiveRef = useRef<any>(null)
const sortCollectionRef = useRef<any>(null)
const [sortStatus, setSortStatus] = useState<{comprehensive:sortParam, collection:sortParam}>({
comprehensive: 'none',
collection: 'none'
})
const changeSort = (val) => {
if(val == 1) {
const {status, value} = sortComprehensiveRef.current.changeSort()
setSortStatus((e) => ({...e, comprehensive: status, collection: 'none'}))
setSearchField((e) => ({...e, abstract_sort_key: value, size:10, page:1}))
} else {
const {status, value} = sortCollectionRef.current.changeSort()
setSortStatus((e) => ({...e, collection: status, comprehensive: 'none'}))
setSearchField((e) => ({...e, abstract_sort_key: value, size:10, page:1}))
}
pageNum.current = {size: 10, page: 1}
}
const labAndImgObj = useCallback((item) => {
const img = item?item.texture_url.split(',')[0]:''
return {lab:item.lab,rgb:item.rgb,texture_url:img}
}, [materialList])
return (
<View className={styles.main}>
<View className={styles.search}>
<Search placeIcon="out" placeholder="请输入面料关键词" defaultValue={router.params.key} changeOnSearch={getSearchData} debounceTime={300}/>
</View>
<View className={styles.filter}>
<View className={styles.filter_all}>
<View className={styles.text_zh} onClick={() => changeSort(1)}>
<Text></Text>
<SortBtn status={sortStatus.comprehensive} ref={sortComprehensiveRef} sortValue={{desc: '1', asc: '-1'}}/>
</View>
<View className={styles.text_sc} onClick={() => changeSort(2)}>
<Text></Text>
<SortBtn status={sortStatus.collection} ref={sortCollectionRef} sortValue={{desc: '2', asc: '-2'}}/>
</View>
<View className={styles.text_ss} onClick={() => goLink('/pages/searchList/hightSearchList')}>
<Text></Text>
<Text className={classnames('iconfont icon-sousuo', styles.miconfont)}></Text>
</View>
</View>
<View className={styles.filter_btn_con}>
<View className={styles.filter_scroll}>
<SelectData list={selectList}/>
</View>
<View className={styles.filter_more} onClick={() => setShowFilter(true)}>
<Text></Text>
<Text className={classnames('iconfont icon-shaixuan', styles.miconfont)}></Text>
</View>
</View>
</View>
<View className={styles.list}>
<View className={classnames(styles.list_num, styles.list_num_shadow)}> ({materialList.total})</View>
<View className={styles.scroll}>
<InfiniteScroll
selfonScrollToLower={getScrolltolower}
statusMore={statusMore}
>
<View className={styles.product_list}>
{materialList.list.map(item => {
return <View key={item.id} className={styles.product_item} onClick={() => goLinkPage(item)}>
<View className={styles.product_img}>
<LabAndImg value={labAndImgObj(item)}/>
<View className={styles.color_num}>{(item.product_color_count)}</View>
</View>
<View className={styles.product_info}>
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
<View className={styles.tag_list}>
<View className={styles.tag}>{item.width}</View>
<View className={styles.tag}>{item.weight_density}</View>
</View>
<View className={styles.introduce}>{item.component}</View>
</View>
</View>
})}
</View>
</InfiniteScroll>
</View>
</View>
<Filter show={showFilter} onClose={() => setShowFilter(false)} onFiltr={(e) => getFiltr(e)} />
const labAndImgObj = useCallback(
(item) => {
const img = item ? item.texture_url.split(',')[0] : ''
return { lab: item.lab, rgb: item.rgb, texture_url: img }
},
[materialList],
)
return (
<View className={styles.main}>
<View className={styles.search}>
<Search placeIcon='out' placeholder='请输入面料关键词' defaultValue={router.params.key} changeOnSearch={getSearchData} debounceTime={300} />
</View>
<View className={styles.filter}>
<View className={styles.filter_all}>
<View className={styles.text_zh} onClick={() => changeSort(1)}>
<Text></Text>
<SortBtn status={sortStatus.comprehensive} ref={sortComprehensiveRef} sortValue={{ desc: '1', asc: '-1' }} />
</View>
<View className={styles.text_sc} onClick={() => changeSort(2)}>
<Text></Text>
<SortBtn status={sortStatus.collection} ref={sortCollectionRef} sortValue={{ desc: '2', asc: '-2' }} />
</View>
<View className={styles.text_ss} onClick={() => goLink('/pages/searchList/hightSearchList')}>
<Text></Text>
<Text className={classnames('iconfont icon-sousuo', styles.miconfont)}></Text>
</View>
</View>
)
}
<View className={styles.filter_btn_con}>
<View className={styles.filter_scroll}>
<SelectData list={selectList} />
</View>
<View className={styles.filter_more} onClick={() => setShowFilter(true)}>
<Text></Text>
<Text className={classnames('iconfont icon-shaixuan', styles.miconfont)}></Text>
</View>
</View>
</View>
<View className={styles.list}>
<View className={classnames(styles.list_num, styles.list_num_shadow)}> ({materialList.total})</View>
<View className={styles.scroll}>
<InfiniteScroll selfonScrollToLower={getScrolltolower} statusMore={statusMore}>
<View className={styles.product_list}>
{materialList.list.map((item) => {
return (
<View key={item.id} className={styles.product_item} onClick={() => goLinkPage(item)}>
<View className={styles.product_img}>
<LabAndImg value={labAndImgObj(item)} />
<View className={styles.color_num}>{item.product_color_count}</View>
</View>
<View className={styles.product_info}>
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
<View className={styles.tag_list}>
<View className={styles.tag}>{item.width}</View>
<View className={styles.tag}>{item.weight_density}</View>
</View>
<View className={styles.introduce}>{item.component}</View>
</View>
</View>
)
})}
</View>
</InfiniteScroll>
</View>
</View>
<Filter show={showFilter} onClose={() => setShowFilter(false)} onFiltr={(e) => getFiltr(e)} />
</View>
)
}

View File

@ -1,223 +1,211 @@
import { View, Image, Text, Navigator, Button } from "@tarojs/components"
import { memo, useEffect, useState } from "react"
import { View, Image, Text, Navigator, Button } from '@tarojs/components'
import { memo, useEffect, useState } from 'react'
import styles from './index.module.scss'
import classnames from "classnames";
import { useSelector } from "@/reducers/hooks";
import { alert, goLink } from "@/common/common";
import classnames from 'classnames'
import { useSelector } from '@/reducers/hooks'
import { alert, goLink } from '@/common/common'
import useLogin from '@/use/useLogin'
import { BASE_URL } from '@/common/constant'
import Taro, { useShareAppMessage } from "@tarojs/taro";
import { userassets, userorderStatistics } from "@/api/mine"
import { formatPriceDiv } from "@/common/fotmat"
import { useDidShow, } from '@tarojs/taro'
import { GetAdminUserInfoApi } from "@/api/user";
import Taro, { useShareAppMessage } from '@tarojs/taro'
import { userassets, userorderStatistics } from '@/api/mine'
import { formatPriceDiv } from '@/common/fotmat'
import { useDidShow } from '@tarojs/taro'
import { GetAdminUserInfoApi } from '@/api/user'
export default () => {
// 用户信息
const { getSelfUserInfo, getAdminUserInfo } = useLogin()
const { adminUserInfo } = useSelector((state) => state.userInfo)
// 用户信息
const { getSelfUserInfo, getAdminUserInfo } = useLogin();
const { adminUserInfo } = useSelector(state => state.userInfo);
const [current_version, setCurrent_version] = useState(CURRENT_VERSION)
const [current_githash, setCurrent_githash] = useState(CURRENT_GITHASH)
const [current_env, setCurrent_env] = useState(CURRENT_ENV)
const [current_version,setCurrent_version] = useState(CURRENT_VERSION)
const [current_githash,setCurrent_githash] = useState(CURRENT_GITHASH)
const [current_env,setCurrent_env] = useState(CURRENT_ENV)
const handleAuth = async () => {
console.log('授权面版')
getSelfUserInfo()
.then()
.catch(() => {
alert.none('授权失败,请授权后再使用')
})
}
const { fetchData: Apiassets, state } = userassets()
const { fetchData: ApigetTotal, state: stateData } = userorderStatistics()
//分享
useShareAppMessage(res => {
if (res.from !== 'button') {
// 来自页面内转发按钮
console.log('点击个德')
}
return {
title: '转发啦',
path: '/page/user?id=123'
}
})
const handleAuth = async () => {
console.log('授权面版')
getSelfUserInfo().then().catch(() => {
alert.none("授权失败,请授权后再使用");
});
}
const { fetchData: Apiassets, state } = userassets()
const { fetchData: ApigetTotal, state: stateData } = userorderStatistics()
useDidShow(() => {
ApigetTotal()
getAdminUserInfo()
Apiassets()
})
const checkGo = () => {
if (adminUserInfo?.authentication_status === 0 || adminUserInfo?.authentication_status === 1 || adminUserInfo?.authentication_status === 2 || adminUserInfo?.authentication_status === 3) {
Taro.showModal({
title: '提示',
content: '你还未认证,认证后解锁更多功能',
cancelText: '稍后认证',
confirmText: '去认证',
success: function (res) {
if (res.confirm) {
Taro.navigateTo({ url: '/pages/certification/index' })
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
} else {
Taro.navigateTo({
url: "/pages/creditLine/index"
})
}
}
return (
<View className={styles.main}>
<Header data={adminUserInfo} MenuData={stateData} />
<Assets data={state} checkShow={() => checkGo()} userInfo={adminUserInfo}/>
<Main />
{/* {(adminUserInfo as any)?.authentication_status==1&&<Modal data={adminUserInfo}/>} */}
{/* 测试暂时添加 */}
<View style={{ fontSize: '26rpx',color:'#707070', textAlign: 'center' }}>{current_version}</View>
{current_env === 'development' &&<View style={{ fontSize: '26rpx',color:'#707070', textAlign: 'center' }}>{BASE_URL}</View>}
{!adminUserInfo?.is_authorize_name && <View onClick={handleAuth} className={styles["auth-suspension"]}></View>}
</View>
)
useDidShow(() => {
ApigetTotal()
getAdminUserInfo()
Apiassets()
})
const checkGo = () => {
if (
adminUserInfo?.authentication_status === 0 ||
adminUserInfo?.authentication_status === 1 ||
adminUserInfo?.authentication_status === 2 ||
adminUserInfo?.authentication_status === 3
) {
Taro.showModal({
title: '提示',
content: '你还未认证,认证后解锁更多功能',
cancelText: '稍后认证',
confirmText: '去认证',
success: function (res) {
if (res.confirm) {
Taro.navigateTo({ url: '/pages/certification/index' })
} else if (res.cancel) {
console.log('用户点击取消')
}
},
})
} else {
Taro.navigateTo({
url: '/pages/creditLine/index',
})
}
}
return (
<View className={styles.main}>
<Header data={adminUserInfo} MenuData={stateData} />
<Assets data={state} checkShow={() => checkGo()} userInfo={adminUserInfo} />
<Main />
{/* {(adminUserInfo as any)?.authentication_status==1&&<Modal data={adminUserInfo}/>} */}
{/* 测试暂时添加 */}
<View style={{ fontSize: '26rpx', color: '#707070', textAlign: 'center' }}>{current_version}</View>
{current_env === 'development' && <View style={{ fontSize: '26rpx', color: '#707070', textAlign: 'center' }}>{BASE_URL}</View>}
{!adminUserInfo?.is_authorize_name && <View onClick={handleAuth} className={styles['auth-suspension']}></View>}
</View>
)
}
// 提示弹窗
const Modal = memo((props: any) => {
const { data } = props;
const [modalShow, setModalShow] = useState(true);
const handleouter = () => {
}
return (
<>
{modalShow &&
<View onClick={handleouter} catchMove className={styles['tips-modal']}>
<View className={styles['tips-modal-content']} onClick={e => e.stopPropagation()}>
<View className={styles['tips-modal-title']}></View>
<View className={styles['tips-modal-letter']}>
<View className={styles['tips-modal-letter-beginn']}>To: 万丰园纺织科技</View>
<View className={styles['tips-modal-letter-text']}>使</View>
<View className={styles['tips-modal-letter-end']}></View>
</View>
<View className={styles['tips-modal-button']}>
<Button hoverClass="none" openType="contact"></Button>
<View onClick={() => setModalShow(false)}></View>
</View>
</View>
</View>
}
</>
)
const { data } = props
const [modalShow, setModalShow] = useState(true)
const handleouter = () => {}
return (
<>
{modalShow && (
<View onClick={handleouter} catchMove className={styles['tips-modal']}>
<View className={styles['tips-modal-content']} onClick={(e) => e.stopPropagation()}>
<View className={styles['tips-modal-title']}></View>
<View className={styles['tips-modal-letter']}>
<View className={styles['tips-modal-letter-beginn']}>To: 万丰园纺织科技</View>
<View className={styles['tips-modal-letter-text']}>
使
</View>
<View className={styles['tips-modal-letter-end']}></View>
</View>
<View className={styles['tips-modal-button']}>
<Button hoverClass='none' openType='contact'>
</Button>
<View onClick={() => setModalShow(false)}></View>
</View>
</View>
</View>
)}
</>
)
})
// 头部 | 订单
const Header = memo((props: any) => {
const { data } = props;
console.log(props, 'propsprops')
let menu = [{ text: "待配布", icon: "icon-daipeibu", url: "/pages/order/orderList/index?status=0" }, { text: "待付款", icon: "icon-daifukuan", url: "/pages/order/orderList/index?status=1" },
{ text: "待发货", icon: "icon-daifahuo", url: "/pages/order/orderList/index?status=2" }, { text: "待收货", icon: "icon-yifahuo", url: "/pages/order/orderList/index?status=3" },
{ text: "退款/售后", icon: "icon-a-tuikuanshouhou", url: "/pages/salesAfter/salesAfterList/index" }];
const { getPhoneNumber } = useLogin();
const mGetPhoneNumber = (ev) => {
if (ev.detail?.code) {
getPhoneNumber(ev.detail.code);
} else {
alert.none("绑定失败!");
}
}
const navTo = () => {
Taro.navigateTo({
// url: '/pages/certification/index'
url: '/pages/userEdit/index'
})
}
return (
<View className={styles.header}>
<View className={`${styles.crad} ${styles['header-card']}`}>
<View className={styles['card-info']}>
<View className={styles['arcd-info-left']}>
<View className={styles['arcd-info-left-portrait']}>
<Image src={data?.avatar_url} />
</View>
<View className={styles['arcd-info-left-desc']}>
<View className={styles['arcd-info-left-nickname']}>
{/* {state.data.user_name} */}
{data?.user_name}
</View>
<View className={styles['arcd-info-left-phone']}>
{data?.phone ? data?.phone?.replace(data?.phone?.substring(3, 7), "****") : <Button openType="getPhoneNumber" onGetPhoneNumber={mGetPhoneNumber}></Button>}
</View>
</View>
</View>
<View className={styles['card-info-right']}>
<Navigator hoverClass="none" url="/pages/userEdit/index" className={styles['setup-icon']}>
<View className={classnames(
styles['icon-wrapper'],
'iconfont',
'icon-shezhi',
)}></View>
<View className={styles['icon-point']}></View>
</Navigator>
</View>
</View>
<View className={styles['auth']}>
{((data?.authentication_status == 0 || data?.authentication_status == 1) && data?.order_access_status == 3) &&
<View className={styles['auth-box']} onClick={() => navTo()}>
<View className={styles['auth-left-box']}>
<View className={styles['auth-tag']}>
</View>
<View className={styles['auth-cont']}>
</View>
</View>
<Text className="iconfont icon-a-moreback"></Text>
</View>
}
{(data?.authentication_status == 3 && data?.order_access_status == 3) &&
<View className={styles['auth-box']} onClick={() => navTo()}>
<View className={styles['auth-left-box']}>
<View className={styles['auth-tagthree']}>
</View>
<View className={styles['auth-cont']}>
</View>
</View>
<Text className="iconfont icon-a-moreback"></Text>
</View>
}
{(data?.authentication_status == 2 && data?.order_access_status == 3) &&
<View className={styles['auth-box']} onClick={() => navTo()}>
<View className={styles['auth-left-box']}>
<View className={styles['auth-tagone']}>
</View>
<View className={styles['auth-contone']}>
{data?.company_name || '暂未加入或注册组织'}
</View>
</View>
<Text className="iconfont icon-a-moreback"></Text>
</View>
}
{(data?.authentication_status == 4 && data?.order_access_status == 3) &&
<View className={styles['auth-box']} onClick={() => navTo()}>
<View className={styles['auth-left-box']}>
<View className={styles['auth-tagtwo']}>
<View className={styles['iconFont-color']}>
<Text className="iconfont icon-xtianzhangqi"></Text>
</View>
<View className={styles['auth-font']}></View>
</View>
<View className={styles['auth-contone']}>
{data?.company_name}
</View>
</View>
<Text className="iconfont icon-a-moreback"></Text>
</View>
}
{/* <View className={`${styles['auth-top']} ${data?.authentication_status==4&&"auth-tips-adopt"}`}>
const { data } = props
console.log(props, 'propsprops')
let menu = [
{ text: '待配布', icon: 'icon-daipeibu', url: '/pages/order/orderList/index?status=0' },
{ text: '待付款', icon: 'icon-daifukuan', url: '/pages/order/orderList/index?status=1' },
{ text: '待发货', icon: 'icon-daifahuo', url: '/pages/order/orderList/index?status=2' },
{ text: '待收货', icon: 'icon-yifahuo', url: '/pages/order/orderList/index?status=3' },
{ text: '退款/售后', icon: 'icon-a-tuikuanshouhou', url: '/pages/salesAfter/salesAfterList/index' },
]
const { getPhoneNumber } = useLogin()
const mGetPhoneNumber = (ev) => {
if (ev.detail?.code) {
getPhoneNumber(ev.detail.code)
} else {
alert.none('绑定失败!')
}
}
const navTo = () => {
Taro.navigateTo({
// url: '/pages/certification/index',
url: '/pages/userEdit/index',
})
}
return (
<View className={styles.header}>
<View className={`${styles.crad} ${styles['header-card']}`}>
<View className={styles['card-info']}>
<View className={styles['arcd-info-left']}>
<View className={styles['arcd-info-left-portrait']}>
<Image src={data?.avatar_url} />
</View>
<View className={styles['arcd-info-left-desc']}>
<View className={styles['arcd-info-left-nickname']}>
{/* {state.data.user_name} */}
{data?.user_name}
</View>
<View className={styles['arcd-info-left-phone']}>
{data?.phone ? (
data?.phone?.replace(data?.phone?.substring(3, 7), '****')
) : (
<Button openType='getPhoneNumber' onGetPhoneNumber={mGetPhoneNumber}>
</Button>
)}
</View>
</View>
</View>
<View className={styles['card-info-right']}>
<Navigator hoverClass='none' url='/pages/userEdit/index' className={styles['setup-icon']}>
<View className={classnames(styles['icon-wrapper'], 'iconfont', 'icon-shezhi')}></View>
<View className={styles['icon-point']}></View>
</Navigator>
</View>
</View>
<View className={styles['auth']}>
{(data?.authentication_status == 0 || data?.authentication_status == 1) && data?.order_access_status == 3 && (
<View className={styles['auth-box']} onClick={() => navTo()}>
<View className={styles['auth-left-box']}>
<View className={styles['auth-tag']}></View>
<View className={styles['auth-cont']}>{data?.company_name || '暂未加入或注册组织'}</View>
</View>
<Text className='iconfont icon-a-moreback'></Text>
</View>
)}
{data?.authentication_status == 3 && data?.order_access_status == 3 && (
<View className={styles['auth-box']} onClick={() => navTo()}>
<View className={styles['auth-left-box']}>
<View className={styles['auth-tagthree']}></View>
<View className={styles['auth-cont']}>{data?.company_name || '暂未加入或注册组织'}</View>
</View>
<Text className='iconfont icon-a-moreback'></Text>
</View>
)}
{data?.authentication_status == 2 && data?.order_access_status == 3 && (
<View className={styles['auth-box']} onClick={() => navTo()}>
<View className={styles['auth-left-box']}>
<View className={styles['auth-tagone']}></View>
<View className={styles['auth-contone']}>{data?.company_name || '暂未加入或注册组织'}</View>
</View>
<Text className='iconfont icon-a-moreback'></Text>
</View>
)}
{data?.authentication_status == 4 && data?.order_access_status == 3 && (
<View className={styles['auth-box']} onClick={() => navTo()}>
<View className={styles['auth-left-box']}>
<View className={styles['auth-tagtwo']}>
<View className={styles['iconFont-color']}>
<Text className='iconfont icon-xtianzhangqi'></Text>
</View>
<View className={styles['auth-font']}></View>
</View>
<View className={styles['auth-contone']}>{data?.company_name}</View>
</View>
<Text className='iconfont icon-a-moreback'></Text>
</View>
)}
{/* <View className={`${styles['auth-top']} ${data?.authentication_status==4&&"auth-tips-adopt"}`}>
<View className={`${styles['auth-status']} ${data?.authentication_status==2&&styles['auth-status-ongoing']} ${data?.authentication_status==4&&styles['auth-status-adopt']}`}>
<Text>1</Text>
{data?.authentication_status==1&&"未认证"}
@ -230,137 +218,131 @@ const Header = memo((props: any) => {
{data?.authentication_status==3&&<Navigator hoverClass="none" url="/pages/certification/index" className={styles['auth-tips']}> <Text className="iconfont icon-a-moreback"/></Navigator>}
{data?.authentication_status==4&&<View className={styles['auth-tips']}> <Text className="iconfont icon-a-moreback"/></View>}
</View> */}
{/* <View className={`${styles['auth-company']} ${data?.authentication_status==4&&"auth-tips-adopt"}`}>
{/* <View className={`${styles['auth-company']} ${data?.authentication_status==4&&"auth-tips-adopt"}`}>
{data?.authentication_status==1&&"暂未加入或注册组织"}
{data?.authentication_status==2&&data?.company_name}
{data?.authentication_status==3&&data?.company_name}
{data?.authentication_status==4&&data?.company_name}
</View> */}
</View>
<View className={styles['card-main']}>
<View className={styles['card-main-title']}>
<View className={styles.card_main_title_order}></View>
<View className={styles.order_more} onClick={() => goLink('/pages/order/orderList/index')}><Text className="iconfont icon-a-moreback"></Text></View>
</View>
<View className={styles['card-main-title-content']}>
{
menu.map((item, index) => {
return (
<Navigator hoverClass="none" url={item.url} className={styles['card-main-title-content-item']}>
<Text className={`iconfont ${item.icon}`}></Text>
<View>{item.text}</View>
{
index == 0 && props.MenuData.data.wait_match !== 0 &&
<View className={styles['card-main-title-content-item-badge']}>
{props.MenuData.data.wait_match > 99 ? '99+' : props.MenuData.data.wait_match}
</View>
}
{
index == 1 && props.MenuData.data.wait_pay !== 0 &&
<View className={styles['card-main-title-content-item-badge']}>
{props.MenuData.data.wait_pay > 99 ? '99+' : props.MenuData.data.wait_pay}
</View>
}
{
index == 2 && props.MenuData.data.wait_shipped !== 0 &&
<View className={styles['card-main-title-content-item-badge']}>
{props.MenuData.data.wait_shipped > 99 ? '99+' : props.MenuData.data.wait_shipped}
</View>
}
{
index == 3 && props.MenuData.data.already_shipped !== 0 &&
<View className={styles['card-main-title-content-item-badge']}>
{props.MenuData.data.already_shipped > 99 ? '99+' : props.MenuData.data.already_shipped}
</View>
}
{
index == 4 && props.MenuData.data.after_return !== 0 &&
<View className={styles['card-main-title-content-item-badge']}>
{props.MenuData.data.after_return > 99 ? '99+' : props.MenuData.data.after_return}
</View>
}
</Navigator>
)
})
}
</View>
</View>
</View>
</View>
)
</View>
<View className={styles['card-main']}>
<View className={styles['card-main-title']}>
<View className={styles.card_main_title_order}></View>
<View className={styles.order_more} onClick={() => goLink('/pages/order/orderList/index')}>
<Text className='iconfont icon-a-moreback'></Text>
</View>
</View>
<View className={styles['card-main-title-content']}>
{menu.map((item, index) => {
return (
<Navigator hoverClass='none' url={item.url} className={styles['card-main-title-content-item']}>
<Text className={`iconfont ${item.icon}`}></Text>
<View>{item.text}</View>
{index == 0 && props.MenuData.data.wait_match !== 0 && (
<View className={styles['card-main-title-content-item-badge']}>
{props.MenuData.data.wait_match > 99 ? '99+' : props.MenuData.data.wait_match}
</View>
)}
{index == 1 && props.MenuData.data.wait_pay !== 0 && (
<View className={styles['card-main-title-content-item-badge']}>
{props.MenuData.data.wait_pay > 99 ? '99+' : props.MenuData.data.wait_pay}
</View>
)}
{index == 2 && props.MenuData.data.wait_shipped !== 0 && (
<View className={styles['card-main-title-content-item-badge']}>
{props.MenuData.data.wait_shipped > 99 ? '99+' : props.MenuData.data.wait_shipped}
</View>
)}
{index == 3 && props.MenuData.data.already_shipped !== 0 && (
<View className={styles['card-main-title-content-item-badge']}>
{props.MenuData.data.already_shipped > 99 ? '99+' : props.MenuData.data.already_shipped}
</View>
)}
{index == 4 && props.MenuData.data.after_return !== 0 && (
<View className={styles['card-main-title-content-item-badge']}>
{props.MenuData.data.after_return > 99 ? '99+' : props.MenuData.data.after_return}
</View>
)}
</Navigator>
)
})}
</View>
</View>
</View>
</View>
)
})
// 我的资产
const Assets = (props: any) => {
return (
<>
{(props?.userInfo?.order_access_status == 3) &&<View className={`${styles.assets} ${styles.crad} ${styles['main-card']}`}>
<View className={`${styles['assets-title']}`}></View>
<View className={`${styles['assets-content']}`}>
<Navigator hoverClass="none" url="/pages/depositBeforehand/index">
<View className={`${styles['assets-content-item-top']}`}>
<Text className={`${styles['assets-content-item-top-before']}`}>¥</Text>
<Text className={`${styles['assets-content-item-top-content']}`}>{formatPriceDiv(props.data.data.wallet_money || 0, 100, true)}</Text>
{/* <Text className={`${styles['assets-content-item-top-after']}`}>{props.wallet_money || 0}</Text> */}
</View>
<Text className={`${styles['assets-content-item-tips']}`}></Text>
</Navigator>
{/* <View>
return (
<>
{(props?.userInfo?.order_access_status == 3 && (
<View className={`${styles.assets} ${styles.crad} ${styles['main-card']}`}>
<View className={`${styles['assets-title']}`}></View>
<View className={`${styles['assets-content']}`}>
<Navigator hoverClass='none' url='/pages/depositBeforehand/index'>
<View className={`${styles['assets-content-item-top']}`}>
<Text className={`${styles['assets-content-item-top-before']}`}>¥</Text>
<Text className={`${styles['assets-content-item-top-content']}`}>{formatPriceDiv(props.data.data.wallet_money || 0, 100, true)}</Text>
{/* <Text className={`${styles['assets-content-item-top-after']}`}>{props.wallet_money || 0}</Text> */}
</View>
<Text className={`${styles['assets-content-item-tips']}`}></Text>
</Navigator>
{/* <View>
<View className={`${styles['assets-content-item-top']}`}>
<Text className={`${styles['assets-content-item-top-content']}`}>{props.data.data.coupon_count || 0}</Text>
<Text className={`${styles['assets-content-item-top-after']}`}></Text>
</View>
<Text className={`${styles['assets-content-item-tips']}`}></Text>
</View> */}
<Navigator hoverClass="none" onClick={() => props.checkShow()}>
<View className={`${styles['assets-content-item-top']}`} >
<Text className={`${styles['assets-content-item-top-before']}`}>¥</Text>
<Text className={`${styles['assets-content-item-top-content']}`}>{formatPriceDiv(props.data.data.credit_line || 0, 100, true)}</Text>
{/* <Text className={`${styles['assets-content-item-top-after']}`}>.-00</Text> */}
</View>
<Text className={`${styles['assets-content-item-tips']}`}></Text>
</Navigator>
</View>
</View>||<View className={styles['main-card']}></View>}
</>
)
};
<Navigator hoverClass='none' onClick={() => props.checkShow()}>
<View className={`${styles['assets-content-item-top']}`}>
<Text className={`${styles['assets-content-item-top-before']}`}>¥</Text>
<Text className={`${styles['assets-content-item-top-content']}`}>{formatPriceDiv(props.data.data.credit_line || 0, 100, true)}</Text>
{/* <Text className={`${styles['assets-content-item-top-after']}`}>.-00</Text> */}
</View>
<Text className={`${styles['assets-content-item-tips']}`}></Text>
</Navigator>
</View>
</View>
)) || <View className={styles['main-card']}></View>}
</>
)
}
// 功能
const Main = memo(() => {
let menu = [
{ text: "我的客服", icon: "icon-wodekefu", type: 'customer', label:'(0757) 8270 6695'},
{ text: "地址管理", icon: "icon-daohang", url: "/pages/addressManager/index", type: 'url' },
{ text: "码单管理", icon: "icon-a-yuanmadanmadanguanli", url: "/pages/weightList/index", type: 'url' },
{ text: "我的收藏", icon: "icon-shoucang", url: "/pages/collection/index", type: 'url' },
{ text: "颜色对比", icon: "icon-yanseduibi", url: "/pages/sampleComparison/index", type: 'url' },
// { text: "分享推广", icon: "icon-fenxiang" },
{ text: "邀请码", icon: "icon-yaoqingma", url: "/pages/bindSalesman/index", type: 'url' },
]
const navigation = (item) => {
if(item.type === 'url') goLink(item.url)
}
return (
<View className={`${styles.crad} ${styles['card-main']} ${styles['card-feature']}`}>
<View className={styles['card-main-list-content']}>
{
menu.map((item, index) => {
return (
<View hoverClass="none" onClick={() => navigation(item)} key={index} className={styles['card-main-list-content-item']}>
<View className={styles['card-main-list-content-item-left']}>
<Text className={`iconfont ${item.icon}`}></Text>
<View>{item.text}</View>
</View>
<View className={styles.label}>{item.label}</View>
<View className={styles['card-main-list-content-item-right']}>
<Text className="iconfont icon-a-moreback"></Text>
</View>
{item.type === 'customer' && <Button openType="contact" className={styles.customer}></Button>}
</View>
)
})
}
</View>
</View>
)
})
let menu = [
{ text: '我的客服', icon: 'icon-wodekefu', type: 'customer', label: '(0757) 8270 6695' },
{ text: '地址管理', icon: 'icon-daohang', url: '/pages/addressManager/index', type: 'url' },
{ text: '码单管理', icon: 'icon-a-yuanmadanmadanguanli', url: '/pages/weightList/index', type: 'url' },
{ text: '我的收藏', icon: 'icon-shoucang', url: '/pages/collection/index', type: 'url' },
{ text: '颜色对比', icon: 'icon-yanseduibi', url: '/pages/sampleComparison/index', type: 'url' },
// { text: "分享推广", icon: "icon-fenxiang" },
{ text: '邀请码', icon: 'icon-yaoqingma', url: '/pages/bindSalesman/index', type: 'url' },
]
const navigation = (item) => {
if (item.type === 'url') goLink(item.url)
}
return (
<View className={`${styles.crad} ${styles['card-main']} ${styles['card-feature']}`}>
<View className={styles['card-main-list-content']}>
{menu.map((item, index) => {
return (
<View hoverClass='none' onClick={() => navigation(item)} key={index} className={styles['card-main-list-content-item']}>
<View className={styles['card-main-list-content-item-left']}>
<Text className={`iconfont ${item.icon}`}></Text>
<View>{item.text}</View>
</View>
<View className={styles.label}>{item.label}</View>
<View className={styles['card-main-list-content-item-right']}>
<Text className='iconfont icon-a-moreback'></Text>
</View>
{item.type === 'customer' && <Button openType='contact' className={styles.customer}></Button>}
</View>
)
})}
</View>
</View>
)
})