From 85c591d7458dec1a38173c2cc709c4041c61f3aa Mon Sep 17 00:00:00 2001 From: Haiyi <1021441632@qq.com> Date: Tue, 28 Jun 2022 10:31:14 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=A0=B7=E5=93=81=E5=AF=B9=E6=AF=94?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- project.config.json | 3 +- src/app.config.ts | 9 +- src/common/constant.js | 6 +- .../compoents/bluetooth/LinkBlueTooth.tsx | 90 +++++++++++++++++++ .../compoents/bluetooth/Popup.tsx | 73 +++++++++++++++ .../css/linkBlueTooth.module.scss | 42 +++++++++ .../sampleComparison/css/popup.module.scss | 90 +++++++++++++++++++ src/pages/sampleComparison/index.module.scss | 6 ++ src/pages/sampleComparison/index.tsx | 46 ++++++++-- 9 files changed, 353 insertions(+), 12 deletions(-) create mode 100644 src/pages/sampleComparison/compoents/bluetooth/LinkBlueTooth.tsx create mode 100644 src/pages/sampleComparison/compoents/bluetooth/Popup.tsx create mode 100644 src/pages/sampleComparison/css/linkBlueTooth.module.scss create mode 100644 src/pages/sampleComparison/css/popup.module.scss diff --git a/project.config.json b/project.config.json index aab17ff..e796931 100644 --- a/project.config.json +++ b/project.config.json @@ -30,7 +30,8 @@ "outputPath": "" }, "disableUseStrict": false, - "useCompilerPlugins": false + "useCompilerPlugins": false, + "minifyWXML": true }, "compileType": "miniprogram", "libVersion": "2.24.5", diff --git a/src/app.config.ts b/src/app.config.ts index e735150..0d19c18 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -177,6 +177,13 @@ export default { pages: [ "index", ] - } + }, + { + root: "pages/sampleComparison", + pages: [ + "index", + ] + }, + ] } diff --git a/src/common/constant.js b/src/common/constant.js index 6fca6ae..6b30deb 100644 --- a/src/common/constant.js +++ b/src/common/constant.js @@ -1,16 +1,16 @@ -// export const BASE_URL = CURRENT_ENV.includes('development') ? `https://test.zzfzyc.com/lymarket` : `https://www.zzfzyc.com/lymarket` +export const BASE_URL = CURRENT_ENV.includes('development') ? `https://test.zzfzyc.com/lymarket` : `https://www.zzfzyc.com/lymarket` // export const BASE_URL = `http://192.168.0.75:50001/lymarket` // export const BASE_URL = `http://192.168.0.89:50001/lymarket` // export const BASE_URL = `http://10.0.0.5:50001/lymarket` // 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.30:40001/lymarket` // 发 +// export const BASE_URL = `http://192.168.1.9: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` // 正式环境 // export const BASE_URL = `http://192.168.1.4:40001/lymarket` // 王霞 -export const BASE_URL = `http://192.168.1.7:50001/lymarket` // 添 +// export const BASE_URL = `http://192.168.1.7:50001/lymarket` // 添 // export const BASE_URL = `http://192.168.1.15:50001/lymarket` // 杰 // CDN diff --git a/src/pages/sampleComparison/compoents/bluetooth/LinkBlueTooth.tsx b/src/pages/sampleComparison/compoents/bluetooth/LinkBlueTooth.tsx new file mode 100644 index 0000000..3d36166 --- /dev/null +++ b/src/pages/sampleComparison/compoents/bluetooth/LinkBlueTooth.tsx @@ -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 ( + <> + + + + + { + linkStatus == 1 && 请开启蓝牙 || + linkStatus == 2 && 未连接设备 || + linkStatus == 3 && {linkName} + } + + + setPopupShow(false)} + onLink={item => onLinkListen(item)} + onOff={onDisconnect} + onFind={onFindEven} + /> + + + + ); + +}) diff --git a/src/pages/sampleComparison/compoents/bluetooth/Popup.tsx b/src/pages/sampleComparison/compoents/bluetooth/Popup.tsx new file mode 100644 index 0000000..d8a9464 --- /dev/null +++ b/src/pages/sampleComparison/compoents/bluetooth/Popup.tsx @@ -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&& + + 搜索设备 + + + { + (state.devices&&state.devices.length > 0)&&state?.devices.map(item => { + return ( + onLink(item)}> + {item.name} + { + (!state.connecting&&!state.connected)&&链接|| + (state.connecting&&item.deviceId == state.connecting.deviceId)&&正在链接...|| + (state.connected&&item.deviceId == state.connected.deviceId)&&链接成功 + } + + ) + })|| + + { + (!state.discovering)&& <> + 暂无设备,请按以下条件检查 + 1.请确保取色仪处于激活状态 + 2.请确保取色仪没有链接其他设备 + 3.请打开手机定位 + || + 设备搜索中 + } + + + + } + + + { + state.connected&&断开链接|| + (!state.connected&&state.discovering)&&搜索中|| + 重新搜索 + } + + + + } + + ) +}) \ No newline at end of file diff --git a/src/pages/sampleComparison/css/linkBlueTooth.module.scss b/src/pages/sampleComparison/css/linkBlueTooth.module.scss new file mode 100644 index 0000000..0714b46 --- /dev/null +++ b/src/pages/sampleComparison/css/linkBlueTooth.module.scss @@ -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; + } + } +} \ No newline at end of file diff --git a/src/pages/sampleComparison/css/popup.module.scss b/src/pages/sampleComparison/css/popup.module.scss new file mode 100644 index 0000000..d6c273f --- /dev/null +++ b/src/pages/sampleComparison/css/popup.module.scss @@ -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; + } + } +} diff --git a/src/pages/sampleComparison/index.module.scss b/src/pages/sampleComparison/index.module.scss index 210c3fa..fd9517c 100644 --- a/src/pages/sampleComparison/index.module.scss +++ b/src/pages/sampleComparison/index.module.scss @@ -95,6 +95,12 @@ page { font-weight: 400; color: #707070; } + + } + + .color_bock { + width: 290px; + height: 290px; } .nameColor { diff --git a/src/pages/sampleComparison/index.tsx b/src/pages/sampleComparison/index.tsx index a71d7ab..b8c9cf7 100644 --- a/src/pages/sampleComparison/index.tsx +++ b/src/pages/sampleComparison/index.tsx @@ -1,10 +1,26 @@ 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' + export default () => { + //搜索参数 + const [searchField, setSearchField] = useState({ + l: '', + a: '', + b: '', + page: 1, + size: 10, + width: '', + weight_density: '', + product_kind_id: '', + component: '' + }) const { state: colorState, measureAndGetLab } = useBluetooth() const getLab = () => { if (colorState.connected) { @@ -16,9 +32,18 @@ export default () => { }) } } + //监听lab数据变化 + const [blueToothColor, setBlueToothColor] = useState('') + useEffect(() => { + if (colorState.deviceLab) { + 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 }) + } + }, [colorState.deviceLab]) return ( - + {/* 蓝牙设备 @@ -26,19 +51,26 @@ export default () => { - + */} + - 对比样品 - - 点击取色 - + 对比样品 + { + blueToothColor === '' && + getLab()}> + 点击取色 + + } + {blueToothColor && + + } -- 对比样品 - 点击取色 + getLab()}>点击取色 -- From 2de447402e27396aeb5796570ede338ad05a6d63 Mon Sep 17 00:00:00 2001 From: Haiyi <1021441632@qq.com> Date: Tue, 28 Jun 2022 14:04:59 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/sampleComparison/index.module.scss | 8 + src/pages/sampleComparison/index.tsx | 46 +- src/use/BlueToothCopy.tsx | 477 +++++++++++++++++++ 3 files changed, 522 insertions(+), 9 deletions(-) create mode 100644 src/use/BlueToothCopy.tsx diff --git a/src/pages/sampleComparison/index.module.scss b/src/pages/sampleComparison/index.module.scss index fd9517c..8ee7104 100644 --- a/src/pages/sampleComparison/index.module.scss +++ b/src/pages/sampleComparison/index.module.scss @@ -94,6 +94,7 @@ page { font-family: Microsoft YaHei, Microsoft YaHei-Regular; font-weight: 400; color: #707070; + } } @@ -101,6 +102,13 @@ page { .color_bock { width: 290px; height: 290px; + border-radius: 50%; + } + + .color_bocktwo { + width: 290px; + height: 290px; + border-radius: 50%; } .nameColor { diff --git a/src/pages/sampleComparison/index.tsx b/src/pages/sampleComparison/index.tsx index b8c9cf7..982e58c 100644 --- a/src/pages/sampleComparison/index.tsx +++ b/src/pages/sampleComparison/index.tsx @@ -3,6 +3,7 @@ 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 { useBluetoothTwo } from "@/use/BlueToothCopy" import classnames from "classnames"; import LinkBlueTooth from "./compoents/bluetooth/LinkBlueTooth"; import { toRgb } from '@/common/bluetooth/color/colorSpace' @@ -21,10 +22,22 @@ export default () => { product_kind_id: '', component: '' }) + + const [colorList, setColorList] = useState({ + one: [], + two: [] + }) 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 }) + console.log('colorList',colorList) + } } else { Taro.showToast({ title: '请链接设备', @@ -32,15 +45,24 @@ export default () => { }) } } + //监听lab数据变化 const [blueToothColor, setBlueToothColor] = useState('') + const [blueToothColorTwo, setBlueToothColorTwo] = useState('') useEffect(() => { if (colorState.deviceLab) { 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 }) + console.log(colorList, 'colorList.one.lengthcolorList.one.length') + if (colorList.one?.constructor === Object) { + setBlueToothColor(`rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`) + console.log(blueToothColor, 'blueToothColorblueToothColor') + } + if (colorList.two?.constructor === Object) { + setBlueToothColorTwo(`rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`) + } + // setSearchField({ ...searchField, l: rgb[0], a: rgb[1], b: rgb[2], size: 10 }) } - }, [colorState.deviceLab]) + }, [colorList]) return ( {/* @@ -58,7 +80,7 @@ export default () => { 对比样品 { blueToothColor === '' && - getLab()}> + getLab(1)}> 点击取色 } @@ -69,9 +91,15 @@ export default () => { 对比样品 - - getLab()}>点击取色 - + { + blueToothColorTwo === '' && + getLab(2)}> + 点击取色 + + } + {blueToothColorTwo && + + } -- diff --git a/src/use/BlueToothCopy.tsx b/src/use/BlueToothCopy.tsx new file mode 100644 index 0000000..0d07766 --- /dev/null +++ b/src/use/BlueToothCopy.tsx @@ -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(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} + */ + 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 +} + + +export const useBluetoothTwo = () => { + const res = React.useContext(Context) + if(res) { + return {...res} + } else { + return {} + } + +} \ No newline at end of file From 16e3c08f4ba238cc727104144b05af1d5c46c77a Mon Sep 17 00:00:00 2001 From: Haiyi <1021441632@qq.com> Date: Tue, 28 Jun 2022 20:14:25 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=A0=B7=E5=93=81=E5=AF=B9=E6=AF=94?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/mine.ts | 14 +++ src/pages/sampleComparison/index.module.scss | 41 +++++++ src/pages/sampleComparison/index.tsx | 123 ++++++++++++++----- src/pages/user/index.tsx | 48 +++++++- 4 files changed, 188 insertions(+), 38 deletions(-) diff --git a/src/api/mine.ts b/src/api/mine.ts index aa0ae5a..bb53baf 100644 --- a/src/api/mine.ts +++ b/src/api/mine.ts @@ -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", + }) +} \ No newline at end of file diff --git a/src/pages/sampleComparison/index.module.scss b/src/pages/sampleComparison/index.module.scss index 8ee7104..e46e9fe 100644 --- a/src/pages/sampleComparison/index.module.scss +++ b/src/pages/sampleComparison/index.module.scss @@ -209,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; + } + } } \ No newline at end of file diff --git a/src/pages/sampleComparison/index.tsx b/src/pages/sampleComparison/index.tsx index 982e58c..bfd1da2 100644 --- a/src/pages/sampleComparison/index.tsx +++ b/src/pages/sampleComparison/index.tsx @@ -2,30 +2,26 @@ 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 { useBluetoothTwo } from "@/use/BlueToothCopy" +import { useBluetooth } from "../../use/contextBlueTooth" import classnames from "classnames"; import LinkBlueTooth from "./compoents/bluetooth/LinkBlueTooth"; -import { toRgb } from '@/common/bluetooth/color/colorSpace' +import { toRgb } from '../../common/bluetooth/color/colorSpace' import styles from './index.module.scss' - +import { productabsorbcontrast } from "@/api/mine" export default () => { //搜索参数 const [searchField, setSearchField] = useState({ - l: '', - a: '', - b: '', - page: 1, - size: 10, - width: '', - weight_density: '', - product_kind_id: '', - component: '' + l1: '', + a1: '', + b1: '', + l2: '', + a2: '', + b2: '', }) const [colorList, setColorList] = useState({ - one: [], - two: [] + one: null, + two: null }) const { state: colorState, measureAndGetLab } = useBluetooth() @@ -36,7 +32,6 @@ export default () => { setColorList({ ...colorList, one: res }) } else { setColorList({ ...colorList, two: res }) - console.log('colorList',colorList) } } else { Taro.showToast({ @@ -45,24 +40,68 @@ 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) { - const rgb = toRgb([colorState.deviceLab.L, colorState.deviceLab.a, colorState.deviceLab.b]) - console.log(colorList, 'colorList.one.lengthcolorList.one.length') + 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]})`) - console.log(blueToothColor, 'blueToothColorblueToothColor') + 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] }) } - // setSearchField({ ...searchField, l: rgb[0], a: rgb[1], b: rgb[2], size: 10 }) } }, [colorList]) + const reset = () => { + setBlueToothColor('') + setBlueToothColorTwo('') + setTime('') + setTime('') + } + const [data, setData] = 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) { + + } + } return ( {/* @@ -77,17 +116,22 @@ export default () => { - 对比样品 + 基础样品 { blueToothColor === '' && getLab(1)}> 点击取色 } - {blueToothColor && + {blueToothColor && getLab(1)} style={{ background: blueToothColor }}> } - -- + { + time === '' && -- + } + { + time && {time} + } 对比样品 @@ -97,10 +141,15 @@ export default () => { 点击取色 } - {blueToothColorTwo && + {blueToothColorTwo && getLab(2)} style={{ background: blueToothColorTwo }}> } - -- + { + timeTwo === '' && -- + } + { + timeTwo && {timeTwo} + } @@ -109,12 +158,22 @@ export default () => { {/* 不合格 */} 合格 - {/* 暂无数据 */} - - 色差值: 0.2 - 无明显色差 - + { + data === '' && + 暂无数据 + } + { + data && + + 色差值: {(data as any).ciede_2000} + 无明显色差 + + } - + + reset()}>重置 + handTake()}>提交 + + ) } \ No newline at end of file diff --git a/src/pages/user/index.tsx b/src/pages/user/index.tsx index 23d14d6..af4d28d 100644 --- a/src/pages/user/index.tsx +++ b/src/pages/user/index.tsx @@ -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 ( -
+
checkGo()} />
{/* {(adminUserInfo as any)?.authentication_status==1&&} */} @@ -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/orderList/index" }]; @@ -224,7 +230,37 @@ const Header = memo((props: any) => { {item.text} - {index == 2 ? "99+" : 10} + { + index == 0 && props.MenuData.data.wait_match !== 0 && + + {props.MenuData.data.wait_match > 99 ? '99+' : props.MenuData.data.wait_match} + + } + { + index == 1 && props.MenuData.data.wait_pay !== 0 && + + {props.MenuData.data.wait_pay > 99 ? '99+' : props.MenuData.data.wait_pay} + + } + { + index == 2 && props.MenuData.data.wait_shipped !== 0 && + + {props.MenuData.data.wait_shipped > 99 ? '99+' : props.MenuData.data.wait_shipped} + + } + { + index == 3 && props.MenuData.data.already_shipped !== 0 && + + {props.MenuData.data.already_shipped > 99 ? '99+' : props.MenuData.data.already_shipped} + + } + { + index == 4 && props.MenuData.data.after_return !== 0 && + + {props.MenuData.data.after_return > 99 ? '99+' : props.MenuData.data.after_return} + + } + ) }) @@ -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 ( From 598fc7a81f544be7c36dc42a0670fd57655e66db Mon Sep 17 00:00:00 2001 From: Haiyi <1021441632@qq.com> Date: Wed, 29 Jun 2022 13:46:44 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=A0=B7=E5=93=81=E5=AF=B9=E6=AF=94100%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/sampleComparison/index.tsx | 35 ++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/pages/sampleComparison/index.tsx b/src/pages/sampleComparison/index.tsx index bfd1da2..6639e3a 100644 --- a/src/pages/sampleComparison/index.tsx +++ b/src/pages/sampleComparison/index.tsx @@ -76,8 +76,11 @@ export default () => { setBlueToothColorTwo('') setTime('') setTime('') + setData('') + setResult('') } const [data, setData] = useState('') + const [result, setResult] = useState('') const { fetchData } = productabsorbcontrast() const handTake = async () => { if (searchField.l1 === '') { @@ -99,7 +102,17 @@ export default () => { } 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 ( @@ -155,8 +168,15 @@ export default () => { 测量结果 - {/* 不合格 */} - 合格 + { + (data as any).ciede_2000 >= 1 && + 不合格 + } + { + (data as any).ciede_2000 <= 1 && + 合格 + } + { data === '' && @@ -166,7 +186,14 @@ export default () => { data && 色差值: {(data as any).ciede_2000} - 无明显色差 + { + !(data as any).reddish && !(data as any).yellowish && !(data as any).greenish && !(data as any).bluish && !(data as any).whitish && !(data as any).darker && + 无明显色差 + } + { + result && + {result} + } }