Commit 443e583d by kuangshu

Merge branch 'develop' into test

parents 1a5e134c 6b7ac716
# 多彩校园小程序版
## 项目说明
本项目采用 [Taro](https://taro.aotu.io/) 框架编写小程序,使用 [React](https://reactjs.org/) + [Typescript](http://www.typescriptlang.org/) 语法编写页面逻辑,并编译为小程序代码,项目只为源码部分,上传微信的部分为`./dist/`文件夹下的编译产物。相关文档可自行查阅。
## 安装依赖 & 使用说明
```bash
npm install -g @tarojs/cli # 安装taro的项目工具
npm install # 安装依赖
npm run dev:weapp # 启动开发服务 热更新
npm run build:weapp # 将文件打包到 dist目录下
```
## 目录结构
```bash
| - config # 项目打包配置
| - dist # 项目打包产物
| - src # 项目源码目录
| | - api # 所有请求
| | - common # 部分公用逻辑
| | - components # 公用组件
| | - constants # 静态变量配置(不同分支配置地址)
| | - hooks # 公用Hooks逻辑
| | - images # 图片静态资源
| | - pages # 小程序页面
| | - store # 全局的状态管理 redux
| | - types # 类型定义
| | - utils # 工具函数
| | - app.scss # 全局公共样式
| | - app.tsx # 项目入口
| - project.config.json # 微信开发相关配置
| - tsconfig.json # typescript配置
```
项目基本按照 React 的项目框架完成。路由注册在`app.tsx`中的`config`内注册`pages`即可。
## 微信登录流程
每次进入小程序,获取用户 code 后,请求登录接口获取用户信息以及请求 token,在之后的所有请求中将 token 加入请求的 header。
附微信登录流程:
![Image 微信登录流程](https://res.wx.qq.com/wxdoc/dist/assets/img/api-login.2fcc9f35.jpg)
......@@ -15,13 +15,6 @@ import './app.scss';
// }
class App extends Component {
/**
* 指定config的类型声明为: Taro.Config
*
* 由于 typescript 对于 object 类型推导只能推出 Key 的基本类型
* 对于像 navigationBarTextStyle: 'black' 这样的推导出的类型是 string
* 提示和声明 navigationBarTextStyle: 'black' | 'white' 类型冲突, 需要显示声明类型
*/
config: Config = {
pages: [
'pages/index/index',
......
......@@ -5,7 +5,7 @@ const useAppBackState = (): boolean => {
useEffect(() => {
let entity = Taro.getLaunchOptionsSync();
console.log(entity);
if (entity.scene === 1069 || entity.scene === 1036) {
if (entity && (entity.scene === 1069 || entity.scene === 1036)) {
setState(true);
}
}, []);
......
......@@ -117,7 +117,7 @@ const useBluetooth = ({
'device.name: ',
device.name,
' deviceCode: ',
deviceCode,
deviceCode
);
if (device.name === deviceCode) {
......@@ -140,7 +140,7 @@ const useBluetooth = ({
}
: {};
Taro.startBluetoothDevicesDiscovery(entity);
}),
})
)
.then(createBLEConnection)
.then(getDeviceServices)
......@@ -165,7 +165,7 @@ const useBluetooth = ({
let abStr = '';
Taro.onBLECharacteristicValueChange(res => {
console.log(
`characteristic ${res.characteristicId} has changed, now is ${res.value}`,
`characteristic ${res.characteristicId} has changed, now is ${res.value}`
);
console.log(res.value);
let datastr = ab2str(res.value);
......@@ -223,7 +223,7 @@ const useBluetooth = ({
Taro.onBLEConnectionStateChange(res => {
console.log(
`device ${res.deviceId} state has changed, connected: ${res.connected}`,
`device ${res.deviceId} state has changed, connected: ${res.connected}`
);
if (res.connected) {
dispatch({ type: 'DEVICE_STATE_CHANGE', payload: true });
......@@ -251,7 +251,7 @@ const useBluetooth = ({
}, [state]);
const getDeviceServices = (
deviceId: string,
deviceId: string
): Promise<{
deviceId: string;
serviceId: string;
......@@ -263,7 +263,7 @@ const useBluetooth = ({
let tempService = serviceArr.find(
item =>
item.uuid.toLocaleLowerCase() ===
'6e401103-b5a3-f393-e0a9-e50e24dcca9e',
'6e401103-b5a3-f393-e0a9-e50e24dcca9e'
);
let service: Taro.getBLEDeviceServices.PromisedPropServicesItem = tempService
? tempService
......@@ -297,7 +297,7 @@ const useBluetooth = ({
console.log(getBLEDeviceCharacteristicsParams);
return Taro.getBLEDeviceCharacteristics(
getBLEDeviceCharacteristicsParams,
getBLEDeviceCharacteristicsParams
).then(res => {
console.log('getBLEDeviceCharacteristics', res);
......@@ -378,7 +378,7 @@ const useBluetooth = ({
});
});
},
[state.deviceInfo.deviceId, state.deviceInfo.serviceId],
[state.deviceInfo.deviceId, state.deviceInfo.serviceId]
);
const sendMessageToDevice = useCallback(
......@@ -393,10 +393,10 @@ const useBluetooth = ({
value: str2ab(msg),
});
} else {
return Promise.reject();
return Promise.reject(new Error('no writeId'));
}
},
[state],
[state]
);
const openBluetoothAdapter = () => {
......@@ -406,6 +406,8 @@ const useBluetooth = ({
dispatch({ type: 'BLUETOOTH_STATE_CHANGE', payload: true });
})
.catch(res => {
console.log(res);
if (res.errCode === 10001) {
Taro.onBluetoothAdapterStateChange(function(res) {
console.log('onBluetoothAdapterStateChange', res);
......
......@@ -13,10 +13,10 @@ import useWasherStart from './hooks/useWasherStart';
const AppointmentPay = () => {
const orderData = useSelector(
(state: { washer: WasherStoreState }) => state.washer.orderInfo,
(state: { washer: WasherStoreState }) => state.washer.orderInfo
);
const userInfo = useSelector(
(state: { userinfo: Customer }) => state.userinfo,
(state: { userinfo: Customer }) => state.userinfo
);
const count = useCountDown(orderData.payTimeout);
const [deviceCode, setDeviceCode] = useState('');
......@@ -105,7 +105,8 @@ const AppointmentPay = () => {
{orderData.services.map(service => (
<View
key={service.id}
className='AppointmentPay-contentValueItem'>
className='AppointmentPay-contentValueItem'
>
{service.name}-{service.duration}分钟
</View>
))}
......@@ -122,7 +123,11 @@ const AppointmentPay = () => {
<View className='AppointmentPay-contentPayicon'>
<Image src={WxIcon} />
</View>
<View>微信支付</View>
{orderData.paymentWayId === 6 ? (
<View>艾米支付</View>
) : (
<View>豆支付</View>
)}
</View>
</View>
</View>
......@@ -134,15 +139,18 @@ const AppointmentPay = () => {
</View>
)}
<View className='AppointmentPay-CountDown'>
请在{count}秒后完成支付
{count ? `请在${count}秒内完成支付` : '已超时,请重新下单'}
</View>
</View>
{count ? (
<View className='AppointmentPay-footer' onClick={payStartHandle}>
预约支付
{orderData.orderType === 2 ? '预约支付' : '确认支付'}
</View>
) : (
<View className='AppointmentPay-footer disabled'>预约支付</View>
<View className='AppointmentPay-footer disabled'>
{orderData.orderType === 2 ? '预约支付' : '确认支付'}
</View>
)}
</View>
);
......
......@@ -33,7 +33,7 @@ const WasherStart = () => {
initOptionProgramIds,
);
const [paywayId, setPaywayId] = useState(0);
const [orderType, setOrderType] = useState(0);
// const [orderType, setOrderType] = useState(0);
const goAppointmentPayHandle = (orderType: number) => {
if (!programId) {
......@@ -48,16 +48,8 @@ const WasherStart = () => {
icon: 'none',
});
}
setOrderType(orderType);
};
const goAccountPage = (e: ITouchEvent) => {
e.stopPropagation();
Taro.navigateTo({
url: '/pages/Account/Account',
});
};
// setOrderType(orderType);
useEffect(() => {
if (data.deviceCode && orderType) {
Taro.showLoading();
let modelServiceIds = programId.toString();
......@@ -92,7 +84,13 @@ const WasherStart = () => {
});
});
}
}, [data.deviceCode, orderType]);
};
const goAccountPage = (e: ITouchEvent) => {
e.stopPropagation();
Taro.navigateTo({
url: '/pages/Account/Account',
});
};
return (
<View className='WasherStart'>
......
import useBluetooth from '@/hooks/useBluetooth';
import useDeviceWS from '@/hooks/useDeviceWS';
import { WM_SOCKET_URL } from '@/constants';
import { useEffect } from '@tarojs/taro';
import { useEffect, useState } from '@tarojs/taro';
import { str2ab } from '@/utils/arrayBuffer';
const useWasherStart = (code: string) => {
const errorData: Error | null = useState(null);
const services = [
'6E401103-B5A3-F393-E0A9-E50E24DCCA9E',
'6E400002-B5A3-F393-E0A9-E50E24DCCA9E',
......@@ -18,7 +20,7 @@ const useWasherStart = (code: string) => {
},
err => {
console.log(err);
},
}
);
};
const getSocketData = (data: string) => {
......@@ -68,6 +70,7 @@ const useWasherStart = (code: string) => {
}, [bluetoothState, wsState.socketState, code]);
return {
errorData,
wsState,
bluetoothState,
};
......
......@@ -37,6 +37,7 @@ const WashingMachineHome = (props: {
.then(res => {
console.log(res);
const result: string = res.result;
onChange({
type: '',
timeStamp: 0,
......@@ -46,6 +47,7 @@ const WashingMachineHome = (props: {
preventDefault: () => {},
stopPropagation: () => {},
});
setDeviceCode(result);
})
.catch(err => {
console.log(err);
......@@ -93,7 +95,8 @@ const WashingMachineHome = (props: {
/>
<View
className='WashingMachineHome-sreach-inputbox_text'
onClick={searchHandle}>
onClick={searchHandle}
>
搜索
</View>
</View>
......@@ -108,20 +111,23 @@ const WashingMachineHome = (props: {
className={`WashingMachineHome-list_titleItem ${
showState === FetchWasherStatus.unusing ? 'actived' : ''
}`}
onClick={() => setShowState(0)}>
onClick={() => setShowState(0)}
>
空闲中
</Text>
<Text
className={`WashingMachineHome-list_titleItem ${
showState === FetchWasherStatus.using ? 'actived' : ''
}`}
onClick={() => setShowState(1)}>
onClick={() => setShowState(1)}
>
将结束
</Text>
</View>
<View
className='WashingMachineHome-list_titleLocation'
onClick={() => props.showLocationHandle(true)}>
onClick={() => props.showLocationHandle(true)}
>
位置筛选
</View>
</View>
......@@ -144,7 +150,8 @@ const WashingMachineHome = (props: {
</View>
<View
className='WashingMachineHome-list_nocontentBtn'
onClick={refreshList}>
onClick={refreshList}
>
刷新看看
</View>
</View>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment