feat(样品对比): 已移植EShop的样品对比模块

This commit is contained in:
xuan 2022-09-13 14:52:04 +08:00
parent b328419b96
commit 48e5986060
13 changed files with 848 additions and 94 deletions

View File

@ -1,6 +1,7 @@
export {LoginApi} from './login/index'
export { productabsorbcontrast } from './product/index'
import { useRequest } from "@/use/useHttp"
/**

1
src/api/product/index.ts Normal file
View File

@ -0,0 +1 @@
export { productabsorbcontrast } from './product'

View File

@ -0,0 +1,9 @@
import { useRequest } from "@/use/useHttp"
//取色对比
export const productabsorbcontrast = () => {
return useRequest({
url: `/v1/mall/product/color/absorb/contrast`,
method: 'get',
})
}

View File

@ -49,5 +49,10 @@ export default defineAppConfig({
'custom-wrapper': '/custom-wrapper',
...useGlobalIconFont(),
},
subPackages: [],
subPackages: [
{
root: 'pages/sampleComparison',
pages: ['index'],
},
],
})

View File

@ -1,6 +1,6 @@
import { View } from "@tarojs/components"
import { FC, ReactNode } from "react"
import IconFont from "../iconfont"
import { View } from '@tarojs/components'
import { FC, ReactNode } from 'react'
import IconFont from '../iconfont'
import styles from './index.module.scss'
import classname from 'classnames'
@ -16,8 +16,9 @@ interface PropsType {
iconSize?: number
}
const IconCard: FC<PropsType> = (props) => {
const { iconName, title, onClick, customClass = '', iconSize=72 } = props
const { iconName, title, onClick, customClass = '', iconSize = 72 } = props
const handleClick = (event) => {
console.log(event)
onClick && onClick(event)
}
return (

View File

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

View File

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

View File

@ -0,0 +1,42 @@
.main {
width: 690px;
height: 86px;
background: #ffffff;
border-radius: 10px;
margin-top: 24px;
margin-left: 30px;
.bluetooth_link {
display: flex;
align-items: center;
.link_status {
width: 12px;
height: 12px;
background: #f02409;
border-radius: 50%;
}
.link_statused {
background: #07C160;
}
.link_statused_no {
background: #f0ec09;
}
.link_name {
font-size: $font_size;
margin-left: 20px;
}
.link_name_no {
color: #f02409;
}
.link_name_no_link {
color: #f0ec09;
}
}
}

View File

@ -0,0 +1,90 @@
.popup{
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
.mask{
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
position: fixed;
top:0;
left:0;
z-index: 9;
}
.content{
z-index: 99;
background-color: #fff;
width: 75vw;
height: 600px;
position: fixed;
top: 50%;
left: 50%;
border-radius: 20px;
transform: translateX(-50%) translateY(-50%);
display: flex;
flex-direction: column;
font-size: 28px;
.title{
text-align: center;
margin: 20px;
}
.list{
height: 480px;
padding: 0 20px;
.scroll{
height: 100%;
}
.item{
margin-bottom: 20px;
display: flex;
justify-content: space-between;
border-bottom: 1px dashed #ccc;
padding: 15px 0;
color: #3b3b3b;
@mixin link{
font-size: 25px;
}
.link_success{
@include link;
color: green;
}
.link_ing {
color: orange;
}
}
.noDevice{
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #a8a8a8;
.n_item{
width: 100%;
text-align: left;
margin-top: 20px;
padding: 0 30px;
box-sizing: border-box;
}
}
}
.footer{
text-align: center;
padding: 20px 0;
background-color: #f1f1f1;
border-radius: 0 0 10px 10px;
display: flex;
justify-content: center;
align-items: center;
}
.finding{
color: orange;
}
.footer_off{
color: red;
}
}
}

View File

@ -0,0 +1,4 @@
export default {
navigationBarTitleText: '样品对比',
enableShareAppMessage: false,
}

View File

@ -0,0 +1,251 @@
page {
background: #f3f3f3;
overflow: hidden;
}
.body {
overflow: hidden;
.topBox {
margin-top: 24px;
margin-left: 30px;
width: 690px;
height: 86px;
background: #ffffff;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: space-between;
.leftBox {
display: flex;
align-items: center;
padding-left: 19px;
.leftFont {
font-size: 28px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
text-align: left;
color: #707070;
margin-right: 14px;
}
.borderBox {
width: 0px;
height: 62px;
border: 2px solid #f3f3f3;
margin-right: 39px;
}
.cricleBox {
width: 12px;
height: 12px;
background: #cccccc;
border-radius: 50%;
margin-right: 12px;
}
.notNet {
font-size: 28px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
color: #aaaaaa;
}
}
.iconMore {
margin-right: 30px;
font-size: 30px;
}
}
.contBox {
margin-top: 53px;
display: flex;
padding-left: 56px;
.firstBox {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.firstLeftName {
font-size: 26px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
color: #707070;
}
.firstLeftbox {
width: 290px;
height: 290px;
background: #dddddd;
margin-top: 13px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
border-radius: 50%;
.clickFont {
font-size: 28px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
color: #707070;
}
}
.color_bock {
width: 290px;
height: 290px;
border-radius: 50%;
}
.color_bocktwo {
width: 290px;
height: 290px;
border-radius: 50%;
}
.nameColor {
font-size: 24px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
color: #707070;
margin-top: 30px;
}
}
}
.reslutBox {
width: 692px;
height: 180px;
background: #ffffff;
margin-top: 30px;
margin-left: 29px;
border-radius: 20px;
overflow: hidden;
}
.reslutTitle {
overflow: hidden;
width: 100%;
margin-top: 41px;
display: flex;
align-items: center;
justify-content: space-between;
.titleLeft {
margin-left: 48px;
font-size: 26px;
font-family: Microsoft YaHei, Microsoft YaHei-Bold;
font-weight: 700;
color: #707070;
}
.titleRiht {
margin-right: 37px;
width: 136px;
height: 46px;
background: #ffd9d9;
border-radius: 10px;
font-size: 28px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
text-align: center;
color: #ff4a4a;
line-height: 46px;
}
.titleRiht1 {
background: #cdf3df;
margin-right: 37px;
width: 136px;
height: 46px;
border-radius: 10px;
font-size: 28px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
text-align: center;
line-height: 46px;
color: #07c160;
}
}
.notResult {
width: 100%;
text-align: center;
font-size: 26px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
color: #ababab;
margin-top: 14px;
}
.notBox {
margin-top: 32px;
display: flex;
align-items: center;
justify-content: space-between;
overflow: hidden;
.notLeft {
font-size: 26px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
color: #707070;
margin-left: 40px;
}
.notright {
font-size: 26px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
color: #707070;
margin-right: 37px;
}
}
.bottomBox {
position: fixed;
bottom: 0;
width: 750px;
height: 182px;
background: #f3f3f3;
box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.16);
overflow: hidden;
display: flex;
.leftBtn {
width: 264px;
height: 82px;
background: #ffffff;
border-radius: 42px;
font-size: 32px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
text-align: center;
color: #007aff;
line-height: 82px;
margin-top: 34px;
margin-left: 67px;
}
.rightBtn {
width: 264px;
height: 82px;
background: #007aff;
border-radius: 42px;
font-size: 32px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
text-align: center;
color: #ffffff;
line-height: 82px;
margin-top: 34px;
margin-left: 88px;
}
}
}

View File

@ -0,0 +1,186 @@
import { Image, Text, Textarea, View } from '@tarojs/components'
import Taro, { useDidShow, usePullDownRefresh, useRouter } from '@tarojs/taro'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useBluetooth } from '../../use/contextBlueTooth'
import classnames from 'classnames'
import LinkBlueTooth from './compoents/bluetooth/LinkBlueTooth'
import { toRgb } from '../../common/bluetooth/color/colorSpace'
import styles from './index.module.scss'
import { productabsorbcontrast } from '@/api/index'
export default () => {
//搜索参数
const [searchField, setSearchField] = useState({
l1: '',
a1: '',
b1: '',
l2: '',
a2: '',
b2: '',
})
type ColorList = {
one?: any
two?: any
}
const [colorList, setColorList] = useState<ColorList>({
one: null,
two: null,
})
const { state: colorState, measureAndGetLab } = useBluetooth()
const getLab = async (val) => {
if (colorState.connected) {
let res = await measureAndGetLab()
if (val === 1) {
setColorList({ ...colorList, one: res })
} else {
setColorList({ ...colorList, two: res })
}
} else {
Taro.showToast({
title: '请链接设备',
icon: 'none',
})
}
}
const getNowTime = () => {
const yy = new Date().getFullYear()
const MM = new Date().getMonth() + 1 < 10 ? '0' + (new Date().getMonth() + 1) : new Date().getMonth() + 1
const dd = new Date().getDate() < 10 ? '0' + new Date().getDate() : new Date().getDate()
const HH = new Date().getHours() < 10 ? '0' + new Date().getHours() : new Date().getHours()
const mm = new Date().getMinutes() < 10 ? '0' + new Date().getMinutes() : new Date().getMinutes()
const ss = new Date().getSeconds() < 10 ? '0' + new Date().getSeconds() : new Date().getSeconds()
return yy + '-' + MM + '-' + dd + ' ' + HH + ':' + mm + ':' + ss
}
//监听lab数据变化
const [blueToothColor, setBlueToothColor] = useState('')
const [blueToothColorTwo, setBlueToothColorTwo] = useState('')
const [time, setTime] = useState('')
const [timeTwo, setTimeTwo] = useState('')
useEffect(() => {
if (colorState.deviceLab) {
if ((colorList as any).one?.constructor === Object) {
const rgb = toRgb([(colorList as any).one?.L, (colorList as any).one?.a, (colorList as any).one?.b])
setBlueToothColor(`rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`)
setTime(getNowTime())
setSearchField({ ...searchField, l1: rgb[0], a1: rgb[1], b1: rgb[2] })
}
if ((colorList as any).two?.constructor === Object) {
const rgb = toRgb([(colorList as any).two?.L, (colorList as any).two?.a, (colorList as any).two?.b])
setBlueToothColorTwo(`rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`)
setTimeTwo(getNowTime())
setSearchField({ ...searchField, l2: rgb[0], a2: rgb[1], b2: rgb[2] })
}
}
}, [colorList])
const reset = () => {
setColorList({})
setBlueToothColor('')
setBlueToothColorTwo('')
setTime('')
setTimeTwo('')
setData('')
setResult('')
}
const [data, setData] = useState('')
const [result, setResult] = useState('')
const { fetchData } = productabsorbcontrast()
const handTake = async () => {
if (searchField.l1 === '') {
Taro.showToast({
title: '请填充基础样品',
icon: 'none',
})
return
}
if (searchField.l2 === '') {
Taro.showToast({
title: '请填充对比样品',
icon: 'none',
})
return
}
const query = {
...searchField,
}
const res = await fetchData(query)
if (res.data) {
setData(res.data)
let diffarray = [
res.data.reddish && '偏红',
res.data.yellowish && '偏黄',
res.data.greenish && '偏绿',
res.data.bluish && '偏蓝',
res.data.whitish && '偏亮',
res.data.darker && '偏暗',
]
let resCont = diffarray.filter((item) => item).join(',')
setResult(resCont)
}
}
return (
<View className={styles.body}>
{/* <View className={styles.topBox}>
<View className={styles.leftBox}>
<View className={styles.leftFont}></View>
<View className={styles.borderBox}></View>
<View className={styles.cricleBox}></View>
<View className={styles.notNet}></View>
</View>
<Text className={classnames("iconfont icon-a-moreback", styles.iconMore)}></Text>
</View> */}
<LinkBlueTooth />
<View className={styles.contBox}>
<View className={styles.firstBox} style='margin-right:27px'>
<View className={styles.firstLeftName}></View>
{blueToothColor === '' && (
<View className={styles.firstLeftbox} onClick={() => getLab(1)}>
<View className={styles.clickFont}></View>
</View>
)}
{blueToothColor && <View className={classnames(styles.color_bock)} onClick={() => getLab(1)} style={{ background: blueToothColor }}></View>}
{time === '' && <View className={styles.nameColor}>--</View>}
{time && <View className={styles.nameColor}>{time}</View>}
</View>
<View className={styles.firstBox}>
<View className={styles.firstLeftName}></View>
{blueToothColorTwo === '' && (
<View className={styles.firstLeftbox} onClick={() => getLab(2)}>
<View className={styles.clickFont}></View>
</View>
)}
{blueToothColorTwo && <View className={classnames(styles.color_bocktwo)} onClick={() => getLab(2)} style={{ background: blueToothColorTwo }}></View>}
{timeTwo === '' && <View className={styles.nameColor}>--</View>}
{timeTwo && <View className={styles.nameColor}>{timeTwo}</View>}
</View>
</View>
<View className={styles.reslutBox}>
<View className={styles.reslutTitle}>
<View className={styles.titleLeft}></View>
{(data as any).ciede_2000 >= 1 && <View className={styles.titleRiht}></View>}
{(data as any).ciede_2000 <= 1 && <View className={styles.titleRiht1}></View>}
</View>
{data === '' && <View className={styles.notResult}></View>}
{data && (
<View className={styles.notBox}>
<View className={styles.notLeft}>: {(data as any).ciede_2000}</View>
{!(data as any).reddish &&
!(data as any).yellowish &&
!(data as any).greenish &&
!(data as any).bluish &&
!(data as any).whitish &&
!(data as any).darker && <View className={styles.notright}></View>}
{result && <View className={styles.notright}>{result}</View>}
</View>
)}
</View>
<View className={styles.bottomBox}>
<View className={styles.leftBtn} onClick={() => reset()}>
</View>
<View className={styles.rightBtn} onClick={() => handTake()}>
</View>
</View>
</View>
)
}

View File

@ -13,11 +13,95 @@ import { goLink } from '@/common/common'
type IconfontName = Parameters<typeof IconFont>['0']['name']
type IconCardType = {
iconName: IconfontName,
name: string,
iconName: IconfontName
name: string
path: string
}
const feature: IconCardType[] = [
{
iconName: 'icon-lingquseka',
name: '领取色卡',
path: '',
},
{
iconName: 'icon-pandiansaoma',
name: '盘点扫码',
path: '',
},
{
iconName: 'icon-fahuoliebiao',
name: '发货列表',
path: '',
},
{
iconName: 'icon-yaoqingma',
name: '邀请码',
path: '',
},
{
iconName: 'icon-tihuoliebiao',
name: '提货列表',
path: '',
},
{
iconName: 'icon-shouhouzhongxin',
name: '退货退款',
path: '',
},
{
iconName: 'icon-shoukuanliebiao',
name: '收款列表',
path: '',
},
{
iconName: 'icon-kehuxinxi',
name: '客户列表',
path: '',
},
]
const fabric: IconCardType[] = [
{
iconName: 'icon-yansequyang',
name: '颜色取样',
path: '',
},
{
iconName: 'icon-qusechazhao',
name: '取色查找',
path: '',
},
{
iconName: 'icon-yangpinduibi',
name: '样品对比',
path: '/pages/sampleComparison/index',
},
]
const statisticAnalysis: IconCardType[] = [
{
iconName: 'icon-xiaoshou',
name: '销售',
path: '',
},
{
iconName: 'icon-duizhang',
name: '对账',
path: '',
},
{
iconName: 'icon-yuncangkucun',
name: '云仓库存',
path: '',
},
{
iconName: 'icon-qianzhicangkucun',
name: '前置仓库存',
path: '',
},
]
// 用户信息
const UserInfo: FC = () => {
const { removeToken, removeUserInfo, userInfo } = useUserInfo()
@ -27,92 +111,6 @@ const UserInfo: FC = () => {
// username: '',
// userno: '',
// })
const feature: IconCardType[] = [
{
iconName: 'icon-lingquseka',
name: '领取色卡',
path: '',
},
{
iconName: 'icon-pandiansaoma',
name: '盘点扫码',
path: '',
},
{
iconName: 'icon-fahuoliebiao',
name: '发货列表',
path: '',
},
{
iconName: 'icon-yaoqingma',
name: '邀请码',
path: '',
},
{
iconName: 'icon-tihuoliebiao',
name: '提货列表',
path: '',
},
{
iconName: 'icon-shouhouzhongxin',
name: '退货退款',
path: '',
},
{
iconName: 'icon-shoukuanliebiao',
name: '收款列表',
path: '',
},
{
iconName: 'icon-kehuxinxi',
name: '客户列表',
path: '',
},
]
const fabric: IconCardType[] = [
{
iconName: 'icon-yansequyang',
name: '颜色取样',
path: '',
},
{
iconName: 'icon-qusechazhao',
name: '取色查找',
path: '',
},
{
iconName: 'icon-yangpinduibi',
name: '样品对比',
path: '',
},
]
const statisticAnalysis: IconCardType[] = [
{
iconName: 'icon-xiaoshou',
name: '销售',
path: '',
},
{
iconName: 'icon-duizhang',
name: '对账',
path: '',
},
{
iconName: 'icon-yuncangkucun',
name: '云仓库存',
path: '',
},
{
iconName: 'icon-qianzhicangkucun',
name: '前置仓库存',
path: '',
},
]
// 退出登录
const handleLogout = () => {
@ -121,6 +119,11 @@ const UserInfo: FC = () => {
goLink('/pages/login/index', {}, 'reLaunch')
}
const handleClickIconCard = (item: IconCardType) => {
console.log('item==>', item)
goLink(item.path, {}, 'navigateTo')
}
return (
<>
<LayoutBlock circle>
@ -158,7 +161,7 @@ const UserInfo: FC = () => {
<View className={styles.layoutTitle}></View>
<View className={styles['grid-container']}>
{fabric.map((item) => {
return <IconCard iconName={item.iconName} title={item.name}></IconCard>
return <IconCard iconName={item.iconName} title={item.name} onClick={() => handleClickIconCard(item)}></IconCard>
})}
</View>
</LayoutBlock>