高级搜索

This commit is contained in:
2022-04-18 18:47:22 +08:00
parent 7c299748c3
commit 4a7f7b316f
26 changed files with 1584 additions and 84 deletions
@@ -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 "@/components/bluetooth/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}>
<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
View 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>
}
</>
)
})
@@ -0,0 +1,30 @@
.main{
.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;
}
}
}
@@ -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;
}
}
}
+2 -1
View File
@@ -20,6 +20,7 @@
border-radius: 50px;
padding: 0 60px;
box-sizing: border-box;
z-index:0;
&::-webkit-input-placeholder { /* WebKit browsers */
color: #999;
font-size: 16px;
@@ -55,7 +56,7 @@
position: absolute;
left: 10px;
margin-right: 0;
z-index: 10;
}
.icon_out{
margin-right: 10px;
+13 -9
View File
@@ -4,20 +4,24 @@
align-items: center;
min-height: 62px;
padding: 10px 0;
border-bottom: 1px solid #f3f3f3;
border-bottom: 1px solid #F0F0F0;
.searchInput_title {
width: 150px;
min-height: 50px;
font-size: 28px;
border-right: 1px solid #f3f3f3;
color: $color_font_on;
border-right: 1px solid #F0F0F0;
color: $color_font_two;
margin-right: 20px;
padding-left: 20px;
&::before{
content: "";
height: 50px;
width: 1px;
background-color: #f3f3f3;
}
display: flex;
align-items: center;
// &::before{
// content: "";
// height: 50px;
// width: 1px;
// background-color: #F0F0F0;
// }
}
.searchInput_con{
flex:1;
+7 -4
View File
@@ -1,5 +1,5 @@
import { Input, View } from "@tarojs/components";
import { memo, useDebugValue, useMemo } from "react";
import { memo, ReactHTMLElement, ReactNode, useDebugValue, useMemo } from "react";
import styles from './index.module.scss';
type Params = {
@@ -10,7 +10,8 @@ type Params = {
showTitle?: false|true,
showBorder?: false|true,
changeOnInput?: (string) => void,
clickOnInput?: () => void
clickOnInput?: () => void,
children?: ReactNode
}
@@ -37,9 +38,11 @@ export default memo((props: Params) => {
<View className={styles.searchInput_main} style={stylen}>
{showTitle&&<View className={styles.searchInput_title}>{title}</View>}
<View className={styles.searchInput_con}>
<Input disabled={disabled} placeholder={placeholder} onClick={() => clickOnInput?.()} onInput={(e) => changeOnInput?.(e.detail.value)}/>
{!props.children&&<Input disabled={disabled} placeholder={placeholder} onClick={() => clickOnInput?.()} onInput={(e) => changeOnInput?.(e.detail.value)}/>
||<View>{props.children}</View>
}
</View>
{showIcon&&<View className={`iconfont icon-more ${styles.icon_more_self}`}></View>}
{showIcon&&<View className={`iconfont icon-jiantou ${styles.icon_more_self}`}></View>}
</View>
)
})
+16 -8
View File
@@ -1,20 +1,28 @@
.tabs_main{
display: flex;
width: 100%;
.tabs_scroll{
width: 100%;
display: flex;
white-space: nowrap;
border-bottom: 1px solid $color_font_two;
border-top: 1px solid $color_font_two;
height: 102px;
::-webkit-scrollbar {
display:none;
width:0;
height:0;
color:transparent;
}
.tabs_item{
flex:1;
display: inline-block;
padding: 10px 20px;
height: 100%;
box-sizing: border-box;
position: relative;
font-size: 24rpx;
background-color: #F0F0F0;
border-radius: 24rpx;
min-width: 126rpx;
height: 46.93rpx;
text-align: center;
line-height: 46.93rpx;
color: #707070;
margin-right: 20px;
.tabs_item_con{
height: 100%;
display: flex;
+5 -4
View File
@@ -13,10 +13,12 @@ type Params = {
list?: ListProps[],
defaultValue?: number|string,
children?: ReactNode,
tabsOnClick?: (ListProps) => void
tabsOnClick?: (ListProps) => void,
style?:Object,
}
export default memo(({list = [], defaultValue = 0, tabsOnClick}: Params) => {
export default memo(({list = [], defaultValue = 0, tabsOnClick, style={}}: Params) => {
const [selected, setSelected] = useState(defaultValue)
const [tabId, setTabId] = useState('')
@@ -46,8 +48,7 @@ export default memo(({list = [], defaultValue = 0, tabsOnClick}: Params) => {
list.map((item, index) => {
return (
<View key={item.value} id={`tabs_${item.value}`} className={styles.tabs_item} onClick={() => clickEvent({item,index})}>
<View className={classnames(styles.tabs_item_con, {[styles.tabs_item_select]:selected == item.value})}>{item.title}</View>
{(selected == item.value) && <View className={styles.tabs_index}></View>}
<View className={classnames(styles.tabs_item_con, {[styles.tabs_item_select]:selected == item.value})}>{item.title}</View>
</View>
)
})