线下汇款复制换行
This commit is contained in:
commit
a28d4859b0
@ -30,7 +30,8 @@
|
||||
"outputPath": ""
|
||||
},
|
||||
"disableUseStrict": false,
|
||||
"useCompilerPlugins": false
|
||||
"useCompilerPlugins": false,
|
||||
"minifyWXML": true
|
||||
},
|
||||
"compileType": "miniprogram",
|
||||
"libVersion": "2.24.5",
|
||||
|
@ -10,3 +10,17 @@ export const userassets = () => {
|
||||
method: "get",
|
||||
})
|
||||
}
|
||||
//取色对比
|
||||
export const productabsorbcontrast = () => {
|
||||
return useRequest({
|
||||
url: `/v1/mall/product/color/absorb/contrast`,
|
||||
method: "get",
|
||||
})
|
||||
}
|
||||
//订单统计
|
||||
export const userorderStatistics = () => {
|
||||
return useRequest({
|
||||
url: `/v1/mall/user/orderStatistics`,
|
||||
method: "get",
|
||||
})
|
||||
}
|
@ -177,6 +177,13 @@ export default {
|
||||
pages: [
|
||||
"index",
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
root: "pages/sampleComparison",
|
||||
pages: [
|
||||
"index",
|
||||
]
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
// export const BASE_URL = `http://192.168.0.89:40001/lymarket`
|
||||
// export const BASE_URL = `http://192.168.1.165:40001/lymarket` // 王霞
|
||||
// export const BASE_URL = `https://test.zzfzyc.com/lymarket` // 测试环境
|
||||
// export const BASE_URL = `http://192.168.1.9:40001/lymarket` // 发
|
||||
// export const BASE_URL = `http://192.168.1.30:40001/lymarket` // 发
|
||||
// export const BASE_URL = `http://192.168.1.30:50001/lymarket` // 发
|
||||
// export const BASE_URL = `https://dev.zzfzyc.com/lymarket` // 开发环境
|
||||
// export const BASE_URL = `https://www.zzfzyc.com/lymarket` // 正式环境
|
||||
|
@ -17,7 +17,7 @@ export default memo(({show = true, onClose}:Param) => {
|
||||
//复制功能
|
||||
const clipboardData = () => {
|
||||
Taro.setClipboardData({
|
||||
data: '开户名称:佛山市浩川盛世科技有限公司; 开户银行:招商银行汾江支行; 转账汇款账号:62062342120001221231212',
|
||||
data: '开户名称:佛山市浩川盛世科技有限公司;\n\r 开户银行:招商银行汾江支行;\n\r 转账汇款账号:62062342120001221231212;',
|
||||
success: function (res) {
|
||||
Taro.showToast({
|
||||
icon: 'none',
|
||||
|
@ -0,0 +1,90 @@
|
||||
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)
|
||||
}
|
||||
console.log('aaa:::', state.connected)
|
||||
}, [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>
|
||||
</>
|
||||
|
||||
);
|
||||
|
||||
})
|
73
src/pages/sampleComparison/compoents/bluetooth/Popup.tsx
Normal file
73
src/pages/sampleComparison/compoents/bluetooth/Popup.tsx
Normal file
@ -0,0 +1,73 @@
|
||||
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>
|
||||
}
|
||||
</>
|
||||
)
|
||||
})
|
42
src/pages/sampleComparison/css/linkBlueTooth.module.scss
Normal file
42
src/pages/sampleComparison/css/linkBlueTooth.module.scss
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
90
src/pages/sampleComparison/css/popup.module.scss
Normal file
90
src/pages/sampleComparison/css/popup.module.scss
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -94,7 +94,21 @@ page {
|
||||
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 {
|
||||
@ -195,4 +209,45 @@ page {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,38 @@
|
||||
|
||||
import { Image, Text, Textarea, View } from "@tarojs/components"
|
||||
import Taro, { useDidShow, usePullDownRefresh, useRouter } from "@tarojs/taro";
|
||||
import { useBluetooth } from "@/use/contextBlueTooth"
|
||||
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/mine"
|
||||
export default () => {
|
||||
//搜索参数
|
||||
const [searchField, setSearchField] = useState({
|
||||
l1: '',
|
||||
a1: '',
|
||||
b1: '',
|
||||
l2: '',
|
||||
a2: '',
|
||||
b2: '',
|
||||
})
|
||||
|
||||
const [colorList, setColorList] = useState({
|
||||
one: null,
|
||||
two: null
|
||||
})
|
||||
const { state: colorState, measureAndGetLab } = useBluetooth()
|
||||
const getLab = () => {
|
||||
|
||||
const getLab = async (val) => {
|
||||
if (colorState.connected) {
|
||||
measureAndGetLab()
|
||||
let res = await measureAndGetLab()
|
||||
if (val === 1) {
|
||||
setColorList({ ...colorList, one: res })
|
||||
} else {
|
||||
setColorList({ ...colorList, two: res })
|
||||
}
|
||||
} else {
|
||||
Taro.showToast({
|
||||
title: '请链接设备',
|
||||
@ -16,9 +40,84 @@ export default () => {
|
||||
})
|
||||
}
|
||||
}
|
||||
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.one?.constructor === Object) {
|
||||
const rgb = toRgb([colorList.one.L, colorList.one.a, colorList.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.two?.constructor === Object) {
|
||||
const rgb = toRgb([colorList.two.L, colorList.two.a, colorList.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 = () => {
|
||||
setBlueToothColor('')
|
||||
setBlueToothColorTwo('')
|
||||
setTime('')
|
||||
setTime('')
|
||||
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.topBox}>
|
||||
<View className={styles.leftBox}>
|
||||
<View className={styles.leftFont}>蓝牙设备</View>
|
||||
<View className={styles.borderBox}></View>
|
||||
@ -26,34 +125,81 @@ export default () => {
|
||||
<View className={styles.notNet}></View>
|
||||
</View>
|
||||
<Text className={classnames("iconfont icon-a-moreback", styles.iconMore)}></Text>
|
||||
</View>
|
||||
</View> */}
|
||||
<LinkBlueTooth />
|
||||
<View className={styles.contBox} >
|
||||
<View className={styles.firstBox} style="margin-right:27px">
|
||||
<View className={styles.firstLeftName}>对比样品</View>
|
||||
<View className={styles.firstLeftbox}>
|
||||
<View className={styles.firstLeftName} >基础样品</View>
|
||||
{
|
||||
blueToothColor === '' &&
|
||||
<View className={styles.firstLeftbox} onClick={() => getLab(1)}>
|
||||
<View className={styles.clickFont} >点击取色</View>
|
||||
</View>
|
||||
<View className={styles.nameColor}>--</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>
|
||||
<View className={styles.firstLeftbox}>
|
||||
{
|
||||
blueToothColorTwo === '' &&
|
||||
<View className={styles.firstLeftbox} onClick={() => getLab(2)}>
|
||||
<View className={styles.clickFont} >点击取色</View>
|
||||
</View>
|
||||
<View className={styles.nameColor}>--</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>
|
||||
{/* <View className={styles.titleRiht}>不合格</View> */}
|
||||
{
|
||||
(data as any).ciede_2000 >= 1 &&
|
||||
<View className={styles.titleRiht}>不合格</View>
|
||||
}
|
||||
{
|
||||
(data as any).ciede_2000 <= 1 &&
|
||||
<View className={styles.titleRiht1}>合格</View>
|
||||
}
|
||||
|
||||
</View>
|
||||
{/* <View className={styles.notResult}>暂无数据</View> */}
|
||||
{
|
||||
data === '' &&
|
||||
<View className={styles.notResult}>暂无数据</View>
|
||||
}
|
||||
{
|
||||
data &&
|
||||
<View className={styles.notBox}>
|
||||
<View className={styles.notLeft}>色差值: 0.2</View>
|
||||
<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 >
|
||||
)
|
||||
|
@ -7,8 +7,9 @@ import { alert, goLink } from "@/common/common";
|
||||
import useLogin from '@/use/useLogin'
|
||||
import { BASE_URL } from '@/common/constant'
|
||||
import Taro from "@tarojs/taro";
|
||||
import { userassets } from "@/api/mine"
|
||||
import { userassets, userorderStatistics } from "@/api/mine"
|
||||
import { formatPriceDiv } from "@/common/fotmat"
|
||||
import { useDidShow, } from '@tarojs/taro'
|
||||
export default () => {
|
||||
// 用户信息
|
||||
const { getSelfUserInfo } = useLogin();
|
||||
@ -23,10 +24,14 @@ export default () => {
|
||||
alert.none("授权失败,请授权后再使用");
|
||||
});
|
||||
}
|
||||
const { fetchData, state } = userassets()
|
||||
const { fetchData: Apiassets, state } = userassets()
|
||||
const { fetchData: ApigetTotal, state: stateData } = userorderStatistics()
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
Apiassets();
|
||||
}, [])
|
||||
useDidShow(() => {
|
||||
ApigetTotal()
|
||||
})
|
||||
const checkGo = () => {
|
||||
if (adminUserInfo?.authentication_status === 0 || adminUserInfo?.authentication_status === 1 || adminUserInfo?.authentication_status === 2 || adminUserInfo?.authentication_status === 3) {
|
||||
Taro.showModal({
|
||||
@ -50,7 +55,7 @@ export default () => {
|
||||
}
|
||||
return (
|
||||
<View className={styles.main}>
|
||||
<Header data={adminUserInfo} />
|
||||
<Header data={adminUserInfo} MenuData={stateData} />
|
||||
<Assets data={state} checkShow={() => checkGo()} />
|
||||
<Main />
|
||||
{/* {(adminUserInfo as any)?.authentication_status==1&&<Modal data={adminUserInfo}/>} */}
|
||||
@ -91,6 +96,7 @@ const Modal = memo((props: any) => {
|
||||
// 头部 | 订单
|
||||
const Header = memo((props: any) => {
|
||||
const { data } = props;
|
||||
console.log(props, 'propsprops')
|
||||
let menu = [{ text: "待配布", icon: "icon-daipeibu", url: "/pages/orderList/index" }, { text: "待付款", icon: "icon-daifukuan", url: "/pages/orderList/index" },
|
||||
{ text: "待发货", icon: "icon-daifahuo", url: "/pages/orderList/index" }, { text: "已发货", icon: "icon-yifahuo", url: "/pages/orderList/index" },
|
||||
{ text: "退款/售后", icon: "icon-a-tuikuanshouhou", url: "/pages/salesAfterList/index" }];
|
||||
@ -224,7 +230,37 @@ const Header = memo((props: any) => {
|
||||
<Navigator hoverClass="none" url={item.url} className={styles['card-main-title-content-item']}>
|
||||
<Text className={`iconfont ${item.icon}`}></Text>
|
||||
<View>{item.text}</View>
|
||||
<View className={styles['card-main-title-content-item-badge']}>{index == 2 ? "99+" : 10}</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>
|
||||
)
|
||||
})
|
||||
@ -271,7 +307,7 @@ const Assets = (props: any) => {
|
||||
|
||||
// 功能
|
||||
const Main = memo(() => {
|
||||
let menu = [{ text: "地址管理", icon: "icon-shoucang", url: "/pages/addressManager/index" }, { text: "码单管理", icon: "icon-shoucang", url: "/pages/weightList/index" },
|
||||
let menu = [{ text: "地址管理", icon: "icon-daohang", url: "/pages/addressManager/index" }, { text: "码单管理", icon: "icon-a-yuanmadanmadanguanli", url: "/pages/weightList/index" },
|
||||
{ text: "我的收藏", icon: "icon-shoucang" }, { text: "颜色对比", icon: "icon-yanseduibi", url: "/pages/sampleComparison/index" },
|
||||
{ text: "分享推广", icon: "icon-fenxiang" }, { text: "团队邀请", icon: "icon-yaoqingtuandui" }]
|
||||
return (
|
||||
|
477
src/use/BlueToothCopy.tsx
Normal file
477
src/use/BlueToothCopy.tsx
Normal file
@ -0,0 +1,477 @@
|
||||
import React, {useRef, useState } from "react"
|
||||
import Taro from "@tarojs/taro";
|
||||
import { Command } from "@/common/bluetooth/command";
|
||||
import { uint8ArrayToFloat32, uint8ArrayToHex, waitFor } from "@/common/bluetooth/utils";
|
||||
|
||||
|
||||
interface params {
|
||||
init: () => void
|
||||
state: Object,
|
||||
startScan: () => void,
|
||||
measureAndGetLab: () => any,
|
||||
getAdapterState: () => void,
|
||||
connect: (any) => void,
|
||||
disconnect: () => void
|
||||
}
|
||||
const Context = React.createContext<params|unknown>(null)
|
||||
|
||||
interface stateStype {
|
||||
listeners: any,
|
||||
discovering: boolean,
|
||||
available: boolean,
|
||||
connected: any,
|
||||
connecting: any,
|
||||
serviceRule: any,
|
||||
serviceId: any,
|
||||
characteristicRule: any,
|
||||
characteristicId: any,
|
||||
|
||||
/** 正在执行的命令 */
|
||||
command: any,
|
||||
responseResolve: any,
|
||||
responseReject: any,
|
||||
responseTimer: any,
|
||||
|
||||
/** 是否显示蓝牙调试信息 */
|
||||
debug: any,
|
||||
//搜索到的设备
|
||||
devices: any,
|
||||
//取色仪主动返回的数据
|
||||
deviceLab: any
|
||||
}
|
||||
|
||||
let stateObj: stateStype = {
|
||||
/** 事件监听器 */
|
||||
listeners: new Set(),
|
||||
/** 正在扫描设备 */
|
||||
discovering: false,
|
||||
/** 蓝牙是否可用 */
|
||||
available: true,
|
||||
/** 当前连接的设备 */
|
||||
connected: null,
|
||||
/** 正在连接的设备 */
|
||||
connecting: null,
|
||||
|
||||
serviceRule: /^0000FFE0/,
|
||||
serviceId: null,
|
||||
characteristicRule: /^0000FFE1/,
|
||||
characteristicId: null,
|
||||
|
||||
/** 正在执行的命令 */
|
||||
command: null,
|
||||
responseResolve: null,
|
||||
responseReject: null,
|
||||
responseTimer: null,
|
||||
|
||||
/** 是否显示蓝牙调试信息 */
|
||||
debug: true,
|
||||
//搜索到的设备
|
||||
devices: [],
|
||||
//取色仪主动返回的数据
|
||||
deviceLab: null
|
||||
}
|
||||
|
||||
export default (props) => {
|
||||
let refStatus = useRef(stateObj)
|
||||
let [state, setState] = useState(refStatus.current)
|
||||
|
||||
const changeStatus = (obj:Object): void => {
|
||||
refStatus.current = {...refStatus.current, ...obj}
|
||||
setState({...refStatus.current})
|
||||
}
|
||||
|
||||
const init = async () => {
|
||||
try{
|
||||
await openAdapter();
|
||||
}catch(e) {
|
||||
changeStatus({available:false})
|
||||
}
|
||||
|
||||
// 绑定事件通知
|
||||
Taro.onBluetoothAdapterStateChange(res => {
|
||||
emit({ type: 'stateUpdate', detail: res });
|
||||
});
|
||||
Taro.onBLEConnectionStateChange(res => {
|
||||
emit({ type: res.connected ? 'connected' : 'disconnect', detail: res });
|
||||
});
|
||||
Taro.onBLECharacteristicValueChange(({ value }) => notifySubscriber(value));
|
||||
subscribe(async ev => {
|
||||
if (ev.type === 'stateUpdate') {
|
||||
// 蓝牙状态发生的变化
|
||||
changeStatus({discovering:ev.detail.discovering, available:ev.detail.available})
|
||||
} else if (ev.type === 'disconnect' && refStatus.current.connected && refStatus.current.connected.deviceId === ev.detail.deviceId) {
|
||||
// 断开连接
|
||||
changeStatus({
|
||||
connected:null,
|
||||
serviceId:null,
|
||||
characteristicId:null,
|
||||
deviceLab:null,
|
||||
devices:[]
|
||||
})
|
||||
Taro.showToast({ icon: 'none', title: '蓝牙连接已断开' });
|
||||
} else if (ev.type === 'connected' && refStatus.current.connecting) {
|
||||
// 连接成功
|
||||
changeStatus({connected: refStatus.current.connecting, connecting: null})
|
||||
Taro.showToast({ title: '蓝牙已连接' });
|
||||
} else if (ev.type === 'measure') {
|
||||
//监听取色仪主动推送lab
|
||||
await measureAndGetLab()
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/** 打开蓝牙适配器 */
|
||||
const openAdapter = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
Taro.openBluetoothAdapter({
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送事件
|
||||
* @param {{type: string; data: any}} event
|
||||
*/
|
||||
const emit = (event) => {
|
||||
refStatus.current.listeners.forEach(cb => {
|
||||
cb && cb(event);
|
||||
});
|
||||
}
|
||||
|
||||
const subscribe = (cb) => {
|
||||
if (cb) {
|
||||
changeStatus({
|
||||
listeners: refStatus.current.listeners.add(cb)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取蓝牙适配器状态
|
||||
* @returns {Promise<{discovering: boolean; available: boolean}>}
|
||||
*/
|
||||
const getAdapterState = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
Taro.getBluetoothAdapterState({
|
||||
success: resolve,
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动设备扫描
|
||||
* @param {(res: { devices: { name: string, deviceId: string, RSSI: number }[] }) => void} cb
|
||||
* @param {number} duration
|
||||
*/
|
||||
const startScan = (duration = 30000) => {
|
||||
console.log('开始寻找')
|
||||
changeStatus({devices:[]})
|
||||
Taro.onBluetoothDeviceFound(getDevices);
|
||||
return new Promise((resolve, reject) => {
|
||||
Taro.startBluetoothDevicesDiscovery({
|
||||
allowDuplicatesKey: true,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
|
||||
if (duration > 0) {
|
||||
setTimeout(() => {
|
||||
Taro.offBluetoothDeviceFound(getDevices);
|
||||
Taro.stopBluetoothDevicesDiscovery();
|
||||
console.log("停止搜索")
|
||||
}, duration);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//获取搜索到的设备
|
||||
const getDevices = (res) => {
|
||||
res.devices.forEach(device => {
|
||||
// 排除掉已搜索到的设备和名称不合法的设备, 将新发现的设备添加到列表中
|
||||
if (/^CM/.test(device.name) && !refStatus.current.devices.find(i => i.deviceId === device.deviceId)) {
|
||||
changeStatus({devices: [ ...refStatus.current.devices, device ]})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接设备
|
||||
* @param {{ name: string, deviceId: string, RSSI: number }} device
|
||||
*/
|
||||
const connect = async (device) => {
|
||||
try {
|
||||
changeStatus({connecting: device})
|
||||
console.log('connecting::', device)
|
||||
await createConnection(device.deviceId);
|
||||
await discoverService(device.deviceId);
|
||||
await discoverCharacteristic(device.deviceId);
|
||||
await notifyCharacteristicValueChange(device.deviceId);
|
||||
} catch (e) {
|
||||
changeStatus({connecting: null})
|
||||
Taro.showToast({ icon: 'none', title: '蓝牙连接失败' });
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/** 断开当前连接的设备 */
|
||||
const disconnect = async () => {
|
||||
if (!refStatus.current.connected && !refStatus.current.connecting) return;
|
||||
if (refStatus.current.connected) {
|
||||
await closeConnection(refStatus.current.connected.deviceId);
|
||||
resetCommand();
|
||||
changeStatus({
|
||||
connected: null,
|
||||
serviceId: null,
|
||||
characteristicId: null,
|
||||
devices: [],
|
||||
deviceLab: null
|
||||
})
|
||||
}
|
||||
|
||||
if (refStatus.current.connecting) {
|
||||
await closeConnection(refStatus.current.connecting.deviceId);
|
||||
changeStatus({connecting:null})
|
||||
}
|
||||
}
|
||||
|
||||
/** 创建 BLE 连接 */
|
||||
function createConnection(deviceId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Taro.createBLEConnection({
|
||||
deviceId,
|
||||
timeout: 2000,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** 关闭 BLE 连接 */
|
||||
function closeConnection(deviceId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Taro.closeBLEConnection({
|
||||
deviceId,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** 搜索服务 */
|
||||
function discoverService(deviceId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Taro.getBLEDeviceServices({
|
||||
deviceId,
|
||||
success: ({ services }) => {
|
||||
const service = services.find(i => refStatus.current.serviceRule.test(i.uuid));
|
||||
if (!service) {
|
||||
reject(new Error('服务不可用'));
|
||||
} else {
|
||||
changeStatus({serviceId: service.uuid})
|
||||
resolve(service);
|
||||
}
|
||||
},
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** 搜索特征 */
|
||||
function discoverCharacteristic(deviceId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Taro.getBLEDeviceCharacteristics({
|
||||
deviceId,
|
||||
serviceId: refStatus.current.serviceId,
|
||||
success: ({ characteristics }) => {
|
||||
const characteristic = characteristics.find(i => refStatus.current.characteristicRule.test(i.uuid));
|
||||
if (!characteristic) {
|
||||
reject(new Error('特征不可用'));
|
||||
} else {
|
||||
changeStatus({characteristicId: characteristic.uuid})
|
||||
resolve(characteristic);
|
||||
}
|
||||
},
|
||||
fail: reject
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/** 启动特征通知 */
|
||||
function notifyCharacteristicValueChange(deviceId, stateParm = true) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Taro.notifyBLECharacteristicValueChange({
|
||||
deviceId,
|
||||
serviceId: refStatus.current.serviceId,
|
||||
characteristicId: refStatus.current.characteristicId,
|
||||
state:stateParm,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知订阅器
|
||||
* @param {ArrayBuffer} buffer
|
||||
*/
|
||||
function notifySubscriber(buffer) {
|
||||
if (refStatus.current.command) {
|
||||
if (refStatus.current.debug) {
|
||||
console.log(`[BLE RESP] ${uint8ArrayToHex(new Uint8Array(buffer))}`);
|
||||
}
|
||||
refStatus.current.command.fillResponse(buffer);
|
||||
if (refStatus.current.command.isComplete) {
|
||||
if (refStatus.current.command.isValid && refStatus.current.responseResolve) {
|
||||
refStatus.current.responseResolve(refStatus.current.command.response);
|
||||
} else if (!refStatus.current.command.isValid) {
|
||||
refStatus.current.responseReject(new Error('无效数据'));
|
||||
}
|
||||
resetCommand();
|
||||
}
|
||||
} else {
|
||||
const uint8Array = new Uint8Array(buffer);
|
||||
if (uint8Array[0] === 0xbb && uint8Array[1] === 1 && uint8Array[3] === 0) {
|
||||
const ev = { type: 'measure', detail: { mode: uint8Array[2] } };
|
||||
emit(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送命令
|
||||
* @param {Command}} command
|
||||
* @returns {Promise<Uint8Array>}
|
||||
*/
|
||||
function exec(command) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
if (refStatus.current.command) {
|
||||
reject(new Error('正在执行其他命令'));
|
||||
} else {
|
||||
try {
|
||||
refStatus.current.command = command;
|
||||
const data = command.data;
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
await sendData(data[i]);
|
||||
}
|
||||
|
||||
if (command.responseSize <= 0) {
|
||||
resolve(true);
|
||||
resetCommand();
|
||||
} else {
|
||||
refStatus.current.responseReject = reject;
|
||||
refStatus.current.responseResolve = resolve;
|
||||
refStatus.current.responseTimer = setTimeout(() => {
|
||||
reject(new Error('命令响应超时'));
|
||||
resetCommand();
|
||||
}, command.timeout);
|
||||
}
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送命令
|
||||
* @param {ArrayBuffer} buffer
|
||||
*/
|
||||
function sendData(buffer) {
|
||||
if (refStatus.current.debug) {
|
||||
console.log(`[BLE SEND] ${uint8ArrayToHex(new Uint8Array(buffer))}`);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log('current:::',refStatus.current)
|
||||
Taro.writeBLECharacteristicValue({
|
||||
deviceId: refStatus.current.connected.deviceId,
|
||||
serviceId: refStatus.current.serviceId,
|
||||
characteristicId: refStatus.current.characteristicId,
|
||||
value: buffer,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function resetCommand() {
|
||||
if (refStatus.current.responseTimer) {
|
||||
clearTimeout(refStatus.current.responseTimer);
|
||||
}
|
||||
changeStatus({
|
||||
command: null,
|
||||
responseResolve: null,
|
||||
responseReject: null,
|
||||
responseTimer: null
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 测量
|
||||
* @param {number} mode
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async function measure (mode = 0) {
|
||||
console.log('current1:::',Command.WakeUp)
|
||||
await exec(Command.WakeUp);
|
||||
console.log('current2:::',Command.WakeUp)
|
||||
await waitFor(50);
|
||||
console.log('current3:::',Command.WakeUp)
|
||||
return await exec(Command.measure(mode));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取测量的 lab 值
|
||||
* @param {number} mode
|
||||
* @returns {Promise<{ L: number, a: number, b: number }>}
|
||||
*/
|
||||
async function getLab(mode = 0) {
|
||||
await exec(Command.WakeUp);
|
||||
await waitFor(50);
|
||||
const data: any = await exec(Command.getLab(mode));
|
||||
return {
|
||||
L: uint8ArrayToFloat32(data.slice(5, 9)),
|
||||
a: uint8ArrayToFloat32(data.slice(9, 13)),
|
||||
b: uint8ArrayToFloat32(data.slice(13, 17)),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 测量并获取 lab 值
|
||||
* @param {number} mode
|
||||
* @returns {Promise<{L: number, a: number, b: number}>}
|
||||
*/
|
||||
async function measureAndGetLab(mode = 0) {
|
||||
await measure(mode);
|
||||
await waitFor(50);
|
||||
const lab = await getLab(mode);
|
||||
console.log('lab2::',lab)
|
||||
changeStatus({deviceLab:lab})
|
||||
return lab
|
||||
}
|
||||
|
||||
return <Context.Provider children={props.children} value={{
|
||||
init,
|
||||
state,
|
||||
startScan,
|
||||
measureAndGetLab,
|
||||
getAdapterState,
|
||||
connect,
|
||||
disconnect
|
||||
}} />
|
||||
}
|
||||
|
||||
|
||||
export const useBluetoothTwo = () => {
|
||||
const res = React.useContext<any>(Context)
|
||||
if(res) {
|
||||
return {...res}
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user