refactor: 统一术语「成员」→「用户」,代码格式化
- 页面文案、注释、Toast 提示统一改为"用户" - lefu 模块缩进格式化(空格→Tab) - selectMemberDrawer 组件注释统一 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
97c135786c
commit
485725a486
@@ -108,14 +108,14 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 成员滚动列表 */
|
/* 用户滚动列表 */
|
||||||
.drawer-list {
|
.drawer-list {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding-bottom: env(safe-area-inset-bottom);
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 成员行 */
|
/* 用户行 */
|
||||||
.member-item {
|
.member-item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 90rpx;
|
height: 90rpx;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ interface HistoryApiItem {
|
|||||||
relationType: number | string | null
|
relationType: number | string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 抽屉内部成员项(含回填所需全量字段) */
|
/** 抽屉内部用户项(含回填所需全量字段) */
|
||||||
interface ExistingMember {
|
interface ExistingMember {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
@@ -44,9 +44,9 @@ interface ExistingMember {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 选择已有成员抽屉组件
|
* 选择已有用户抽屉组件
|
||||||
* Properties: show(控制显示)
|
* Properties: show(控制显示)
|
||||||
* Events: close(关闭), select(选中成员,携带 ExistingMember)
|
* Events: close(关闭), select(选中用户,携带 ExistingMember)
|
||||||
*/
|
*/
|
||||||
Component({
|
Component({
|
||||||
properties: {
|
properties: {
|
||||||
@@ -55,12 +55,12 @@ Component({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false
|
value: false
|
||||||
},
|
},
|
||||||
/** 数据来源模式:addMember=新增成员选择 / history=历史数据切换成员 */
|
/** 数据来源模式:addMember=新增用户选择 / history=历史数据切换用户 */
|
||||||
source: {
|
source: {
|
||||||
type: String,
|
type: String,
|
||||||
value: 'addMember'
|
value: 'addMember'
|
||||||
},
|
},
|
||||||
/** 需要排除的用户 ID(history 模式下排除当前查看的成员) */
|
/** 需要排除的用户 ID(history 模式下排除当前查看的用户) */
|
||||||
excludeUserId: {
|
excludeUserId: {
|
||||||
type: String,
|
type: String,
|
||||||
value: ''
|
value: ''
|
||||||
@@ -72,7 +72,7 @@ Component({
|
|||||||
innerShow: false,
|
innerShow: false,
|
||||||
/** 控制 --visible 类,触发 CSS transition */
|
/** 控制 --visible 类,触发 CSS transition */
|
||||||
animVisible: false,
|
animVisible: false,
|
||||||
/** 成员列表(组件内部拉取) */
|
/** 用户列表(组件内部拉取) */
|
||||||
members: [] as ExistingMember[]
|
members: [] as ExistingMember[]
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ Component({
|
|||||||
return Math.max(0, age)
|
return Math.max(0, age)
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 调接口获取可选成员列表,根据 source 调不同接口 */
|
/** 调接口获取可选用户列表,根据 source 调不同接口 */
|
||||||
_fetchMembers() {
|
_fetchMembers() {
|
||||||
const userInfo = wx.getStorageSync('userInfo') as { userId?: string } | null
|
const userInfo = wx.getStorageSync('userInfo') as { userId?: string } | null
|
||||||
const userId = userInfo?.userId ?? ''
|
const userId = userInfo?.userId ?? ''
|
||||||
@@ -175,7 +175,7 @@ Component({
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 点击成员行,触发 select 事件
|
* 点击用户行,触发 select 事件
|
||||||
* @param e 携带 data-member 的点击事件
|
* @param e 携带 data-member 的点击事件
|
||||||
*/
|
*/
|
||||||
onTapMember(e: WechatMiniprogram.TouchEvent) {
|
onTapMember(e: WechatMiniprogram.TouchEvent) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!-- 选择已有成员抽屉 -->
|
<!-- 选择已有用户抽屉 -->
|
||||||
<block wx:if="{{ innerShow }}">
|
<block wx:if="{{ innerShow }}">
|
||||||
<!-- 遮罩 -->
|
<!-- 遮罩 -->
|
||||||
<view class="drawer-mask {{ animVisible ? 'drawer-mask--visible' : '' }}" bind:tap="onTapMask"></view>
|
<view class="drawer-mask {{ animVisible ? 'drawer-mask--visible' : '' }}" bind:tap="onTapMask"></view>
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<!-- 标题栏 -->
|
<!-- 标题栏 -->
|
||||||
<view class="drawer-header">
|
<view class="drawer-header">
|
||||||
<text class="drawer-title">选择已有成员</text>
|
<text class="drawer-title">选择已有用户</text>
|
||||||
<view class="drawer-close" bind:tap="onTapClose">
|
<view class="drawer-close" bind:tap="onTapClose">
|
||||||
<view class="drawer-close-icon"></view>
|
<view class="drawer-close-icon"></view>
|
||||||
</view>
|
</view>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
<!-- 分隔线 -->
|
<!-- 分隔线 -->
|
||||||
<view class="drawer-divider"></view>
|
<view class="drawer-divider"></view>
|
||||||
|
|
||||||
<!-- 成员列表 -->
|
<!-- 用户列表 -->
|
||||||
<block wx:if="{{ members.length }}">
|
<block wx:if="{{ members.length }}">
|
||||||
<scroll-view class="drawer-list" scroll-y>
|
<scroll-view class="drawer-list" scroll-y>
|
||||||
<block wx:for="{{ members }}" wx:key="id">
|
<block wx:for="{{ members }}" wx:key="id">
|
||||||
@@ -52,11 +52,11 @@
|
|||||||
</scroll-view>
|
</scroll-view>
|
||||||
</block>
|
</block>
|
||||||
|
|
||||||
<!-- 无成员:占位 -->
|
<!-- 无用户:占位 -->
|
||||||
<block wx:else>
|
<block wx:else>
|
||||||
<view class="drawer-empty">
|
<view class="drawer-empty">
|
||||||
<image class="drawer-empty-icon" src="/images/selectMemberDrawer/noData.png" mode="aspectFit"/>
|
<image class="drawer-empty-icon" src="/images/selectMemberDrawer/noData.png" mode="aspectFit"/>
|
||||||
<text class="drawer-empty-text">暂无可选成员</text>
|
<text class="drawer-empty-text">暂无可选用户</text>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
+402
-402
@@ -1,16 +1,16 @@
|
|||||||
import { get } from '../utils/request/index'
|
import { get } from '../utils/request/index'
|
||||||
import type {
|
import type {
|
||||||
RawDevice,
|
RawDevice,
|
||||||
LeFuPlugin,
|
LeFuPlugin,
|
||||||
ScannedDevice,
|
ScannedDevice,
|
||||||
LeFuWifiItem,
|
LeFuWifiItem,
|
||||||
ProgressData,
|
ProgressData,
|
||||||
LockData,
|
LockData,
|
||||||
LeFuConfig,
|
LeFuConfig,
|
||||||
DeviceSetting,
|
DeviceSetting,
|
||||||
DeviceMember,
|
DeviceMember,
|
||||||
DeviceInfo,
|
DeviceInfo,
|
||||||
FirmwareVersion,
|
FirmwareVersion,
|
||||||
} from './types'
|
} from './types'
|
||||||
|
|
||||||
/** 顶层加载插件(对齐 demo,requirePlugin 必须在文件顶层调用) */
|
/** 顶层加载插件(对齐 demo,requirePlugin 必须在文件顶层调用) */
|
||||||
@@ -18,441 +18,441 @@ const plugin = requirePlugin('ppScale-plugin') as LeFuPlugin
|
|||||||
|
|
||||||
/** 乐福 SDK 配置 */
|
/** 乐福 SDK 配置 */
|
||||||
const LEFU_CONFIG: LeFuConfig = {
|
const LEFU_CONFIG: LeFuConfig = {
|
||||||
key: 'lefudc91611833e18d94',
|
key: 'lefudc91611833e18d94',
|
||||||
secret: 'eQ50JYimMp0X7uhNLj6D3lTEk4TUUvEG7dvaqKM9t1U=',
|
secret: 'eQ50JYimMp0X7uhNLj6D3lTEk4TUUvEG7dvaqKM9t1U=',
|
||||||
// domain1: 'http://10.10.10.10:8889',
|
// domain1: 'http://10.10.10.10:8889',
|
||||||
// domain2: 'http://10.10.10.10:8889/weight',
|
// domain2: 'http://10.10.10.10:8889/weight',
|
||||||
domain1: 'http://device.shuziweidao.com:80/gateway',
|
domain1: 'http://device.shuziweidao.com:80/gateway',
|
||||||
domain2: 'http://device.shuziweidao.com:80/weight',
|
domain2: 'http://device.shuziweidao.com:80/weight',
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 支持的设备型号配置列表(5款) */
|
/** 支持的设备型号配置列表(5款) */
|
||||||
const DEVICE_SETTINGS: DeviceSetting[] = [
|
const DEVICE_SETTINGS: DeviceSetting[] = [
|
||||||
{
|
{
|
||||||
advLength: 999, calorieStatus: 0, createBy: null,
|
advLength: 999, calorieStatus: 0, createBy: null,
|
||||||
deviceAccuracyType: 2, deviceCalcuteType: 3, deviceConnectType: 2,
|
deviceAccuracyType: 2, deviceCalcuteType: 3, deviceConnectType: 2,
|
||||||
deviceFuncType: 223, deviceName: 'CF568_G', devicePowerType: 3,
|
deviceFuncType: 223, deviceName: 'CF568_G', devicePowerType: 3,
|
||||||
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,11',
|
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,11',
|
||||||
id: 65, imgUrl: null, macAddressStart: 6, remark: null,
|
id: 65, imgUrl: null, macAddressStart: 6, remark: null,
|
||||||
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
advLength: 999, calorieStatus: 0, createBy: null,
|
advLength: 999, calorieStatus: 0, createBy: null,
|
||||||
deviceAccuracyType: 2, deviceCalcuteType: 3, deviceConnectType: 2,
|
deviceAccuracyType: 2, deviceCalcuteType: 3, deviceConnectType: 2,
|
||||||
deviceFuncType: 223, deviceName: 'YX-B4-568-BW', devicePowerType: 3,
|
deviceFuncType: 223, deviceName: 'YX-B4-568-BW', devicePowerType: 3,
|
||||||
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,11',
|
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,11',
|
||||||
id: 65, imgUrl: null, macAddressStart: 6, remark: null,
|
id: 65, imgUrl: null, macAddressStart: 6, remark: null,
|
||||||
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
advLength: 999, calorieStatus: 0, createBy: null,
|
advLength: 999, calorieStatus: 0, createBy: null,
|
||||||
deviceAccuracyType: 2, deviceCalcuteType: 4, deviceConnectType: 2,
|
deviceAccuracyType: 2, deviceCalcuteType: 4, deviceConnectType: 2,
|
||||||
deviceFuncType: 65759, deviceName: 'CF636_G', devicePowerType: 3,
|
deviceFuncType: 65759, deviceName: 'CF636_G', devicePowerType: 3,
|
||||||
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,2',
|
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,2',
|
||||||
id: 216, imgUrl: null, macAddressStart: 6, remark: null,
|
id: 216, imgUrl: null, macAddressStart: 6, remark: null,
|
||||||
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
advLength: 999, calorieStatus: 0, createBy: null,
|
advLength: 999, calorieStatus: 0, createBy: null,
|
||||||
deviceAccuracyType: 2, deviceCalcuteType: 4, deviceConnectType: 2,
|
deviceAccuracyType: 2, deviceCalcuteType: 4, deviceConnectType: 2,
|
||||||
deviceFuncType: 65759, deviceName: 'YX-B8-636-BW', devicePowerType: 3,
|
deviceFuncType: 65759, deviceName: 'YX-B8-636-BW', devicePowerType: 3,
|
||||||
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,2',
|
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,2',
|
||||||
id: 216, imgUrl: null, macAddressStart: 6, remark: null,
|
id: 216, imgUrl: null, macAddressStart: 6, remark: null,
|
||||||
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
advLength: 999, calorieStatus: 0, createBy: null,
|
advLength: 999, calorieStatus: 0, createBy: null,
|
||||||
deviceAccuracyType: 2, deviceCalcuteType: 4, deviceConnectType: 2,
|
deviceAccuracyType: 2, deviceCalcuteType: 4, deviceConnectType: 2,
|
||||||
deviceFuncType: 223, deviceName: 'CF577', devicePowerType: 3,
|
deviceFuncType: 223, deviceName: 'CF577', devicePowerType: 3,
|
||||||
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,11',
|
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,11',
|
||||||
id: 51, imgUrl: null, macAddressStart: 6, remark: null,
|
id: 51, imgUrl: null, macAddressStart: 6, remark: null,
|
||||||
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const TAG = '[LeFuService]'
|
const TAG = '[LeFuService]'
|
||||||
|
|
||||||
class LeFuService {
|
class LeFuService {
|
||||||
private _activeProtocol: any = null
|
private _activeProtocol: any = null
|
||||||
private _connectState = ''
|
private _connectState = ''
|
||||||
private _deviceInfo: DeviceInfo | null = null
|
private _deviceInfo: DeviceInfo | null = null
|
||||||
private _busSubscribed = false
|
private _busSubscribed = false
|
||||||
private _intentionalConnect = false
|
private _intentionalConnect = false
|
||||||
|
|
||||||
private _reconnectCount = 0
|
private _reconnectCount = 0
|
||||||
private readonly _maxReconnect = 3
|
private readonly _maxReconnect = 3
|
||||||
private _reconnectTimer: number | null = null
|
private _reconnectTimer: number | null = null
|
||||||
private _keepAliveTimer: number | null = null
|
private _keepAliveTimer: number | null = null
|
||||||
private _lastRawDevice: RawDevice | null = null
|
private _lastRawDevice: RawDevice | null = null
|
||||||
|
|
||||||
private _onDevicesListCb: ((devices: ScannedDevice[]) => void) | null = null
|
private _onDevicesListCb: ((devices: ScannedDevice[]) => void) | null = null
|
||||||
private _onConnectStateCb: ((state: string) => void) | null = null
|
private _onConnectStateCb: ((state: string) => void) | null = null
|
||||||
private _onDeviceConnectCb: (() => void) | null = null
|
private _onDeviceConnectCb: (() => void) | null = null
|
||||||
private _onProgressCb: ((data: ProgressData) => void) | null = null
|
private _onProgressCb: ((data: ProgressData) => void) | null = null
|
||||||
private _onLockedCb: ((data: LockData) => void) | null = null
|
private _onLockedCb: ((data: LockData) => void) | null = null
|
||||||
private _onDisconnectedCb: (() => void) | null = null
|
private _onDisconnectedCb: (() => void) | null = null
|
||||||
private _onDeviceInfoCb: ((info: DeviceInfo) => void) | null = null
|
private _onDeviceInfoCb: ((info: DeviceInfo) => void) | null = null
|
||||||
|
|
||||||
get config(): LeFuConfig { return LEFU_CONFIG }
|
get config(): LeFuConfig { return LEFU_CONFIG }
|
||||||
get isConnected(): boolean { return !!this._activeProtocol }
|
get isConnected(): boolean { return !!this._activeProtocol }
|
||||||
get connectState(): string { return this._connectState }
|
get connectState(): string { return this._connectState }
|
||||||
get BLUE_STATE(): Record<string, string> { return plugin.BLUE_STATE ?? {} }
|
get BLUE_STATE(): Record<string, string> { return plugin.BLUE_STATE ?? {} }
|
||||||
get deviceInfo(): DeviceInfo | null { return this._deviceInfo }
|
get deviceInfo(): DeviceInfo | null { return this._deviceInfo }
|
||||||
|
|
||||||
// ─── 回调注册 ─────────────────────────────────
|
// ─── 回调注册 ─────────────────────────────────
|
||||||
onDevicesList(cb: (devices: ScannedDevice[]) => void): void { this._onDevicesListCb = cb }
|
onDevicesList(cb: (devices: ScannedDevice[]) => void): void { this._onDevicesListCb = cb }
|
||||||
onConnectState(cb: (state: string) => void): void { this._onConnectStateCb = cb }
|
onConnectState(cb: (state: string) => void): void { this._onConnectStateCb = cb }
|
||||||
onDeviceConnect(cb: () => void): void { this._onDeviceConnectCb = cb }
|
onDeviceConnect(cb: () => void): void { this._onDeviceConnectCb = cb }
|
||||||
onMeasuring(cb: (data: ProgressData) => void): void { this._onProgressCb = cb }
|
onMeasuring(cb: (data: ProgressData) => void): void { this._onProgressCb = cb }
|
||||||
onLocked(cb: (data: LockData) => void): void { this._onLockedCb = cb }
|
onLocked(cb: (data: LockData) => void): void { this._onLockedCb = cb }
|
||||||
onDisconnected(cb: () => void): void { this._onDisconnectedCb = cb }
|
onDisconnected(cb: () => void): void { this._onDisconnectedCb = cb }
|
||||||
onDeviceInfo(cb: (info: DeviceInfo) => void): void { this._onDeviceInfoCb = cb }
|
onDeviceInfo(cb: (info: DeviceInfo) => void): void { this._onDeviceInfoCb = cb }
|
||||||
|
|
||||||
// ─── 扫描与连接 ───────────────────────────────
|
// ─── 扫描与连接 ───────────────────────────────
|
||||||
startScan(): void {
|
startScan(): void {
|
||||||
console.log(TAG, 'startScan()')
|
console.log(TAG, 'startScan()')
|
||||||
plugin.Blue.setDeviceSetting(DEVICE_SETTINGS)
|
plugin.Blue.setDeviceSetting(DEVICE_SETTINGS)
|
||||||
this._subscribeBus()
|
this._subscribeBus()
|
||||||
plugin.Blue.start(DEVICE_SETTINGS.map(s => s.deviceName), false)
|
plugin.Blue.start(DEVICE_SETTINGS.map(s => s.deviceName), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private _subscribeBus(): void {
|
private _subscribeBus(): void {
|
||||||
if (this._busSubscribed) {
|
if (this._busSubscribed) {
|
||||||
console.log(TAG, 'bus 已订阅,跳过')
|
console.log(TAG, 'bus 已订阅,跳过')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this._busSubscribed = true
|
this._busSubscribed = true
|
||||||
|
|
||||||
plugin.bus.subscribe('devicesList', (devList: RawDevice[]) => {
|
plugin.bus.subscribe('devicesList', (devList: RawDevice[]) => {
|
||||||
console.log(TAG, 'bus[devicesList],设备数:', devList?.length, devList)
|
console.log(TAG, 'bus[devicesList],设备数:', devList?.length, devList)
|
||||||
if (!devList?.length) {
|
if (!devList?.length) {
|
||||||
this._onDevicesListCb?.([])
|
this._onDevicesListCb?.([])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const devices: ScannedDevice[] = devList.map((item: RawDevice) => ({
|
const devices: ScannedDevice[] = devList.map((item: RawDevice) => ({
|
||||||
name: item.name || item.deviceName || '未知设备',
|
name: item.name || item.deviceName || '未知设备',
|
||||||
raw: item,
|
raw: item,
|
||||||
model: {},
|
model: {},
|
||||||
}))
|
}))
|
||||||
this._onDevicesListCb?.(devices)
|
this._onDevicesListCb?.(devices)
|
||||||
})
|
})
|
||||||
|
|
||||||
plugin.bus.subscribe('devicesModel', (res: any) => {
|
plugin.bus.subscribe('devicesModel', (res: any) => {
|
||||||
console.log(TAG, 'bus[devicesModel] 完整数据:', JSON.stringify(res))
|
console.log(TAG, 'bus[devicesModel] 完整数据:', JSON.stringify(res))
|
||||||
})
|
})
|
||||||
|
|
||||||
plugin.bus.subscribe('deviceInfo', (res: DeviceInfo) => {
|
plugin.bus.subscribe('deviceInfo', (res: DeviceInfo) => {
|
||||||
console.log(TAG, 'bus[deviceInfo]:', res)
|
console.log(TAG, 'bus[deviceInfo]:', res)
|
||||||
this._deviceInfo = res
|
this._deviceInfo = res
|
||||||
this._onDeviceInfoCb?.(res)
|
this._onDeviceInfoCb?.(res)
|
||||||
})
|
})
|
||||||
|
|
||||||
plugin.bus.subscribe('deviceConnect', () => {
|
plugin.bus.subscribe('deviceConnect', () => {
|
||||||
console.log(TAG, 'bus[deviceConnect]')
|
console.log(TAG, 'bus[deviceConnect]')
|
||||||
this._intentionalConnect = false
|
this._intentionalConnect = false
|
||||||
this._reconnectCount = 0
|
this._reconnectCount = 0
|
||||||
plugin.ScaleAction.startDataProgress(true)
|
plugin.ScaleAction.startDataProgress(true)
|
||||||
this._activeProtocol = plugin.ScaleAction.getActiveProtocol()
|
this._activeProtocol = plugin.ScaleAction.getActiveProtocol()
|
||||||
this._connectState = plugin.BLUE_STATE.CONNECTSUCCESS
|
this._connectState = plugin.BLUE_STATE.CONNECTSUCCESS
|
||||||
this._activeProtocol.codeUpdateMTU((mtuRes: any) => {
|
this._activeProtocol.codeUpdateMTU((mtuRes: any) => {
|
||||||
console.log(TAG, 'codeUpdateMTU:', mtuRes)
|
console.log(TAG, 'codeUpdateMTU:', mtuRes)
|
||||||
this._activeProtocol.codeSyncTime((syncRes: any) => {
|
this._activeProtocol.codeSyncTime((syncRes: any) => {
|
||||||
console.log(TAG, 'codeSyncTime:', syncRes)
|
console.log(TAG, 'codeSyncTime:', syncRes)
|
||||||
this._onDeviceConnectCb?.()
|
this._onDeviceConnectCb?.()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
plugin.bus.subscribe('connectState', (res: string) => {
|
plugin.bus.subscribe('connectState', (res: string) => {
|
||||||
console.log(TAG, 'bus[connectState]:', res)
|
console.log(TAG, 'bus[connectState]:', res)
|
||||||
this._connectState = res
|
this._connectState = res
|
||||||
this._onConnectStateCb?.(res)
|
this._onConnectStateCb?.(res)
|
||||||
if (res === plugin.BLUE_STATE.CONNECTSUCCESS) {
|
if (res === plugin.BLUE_STATE.CONNECTSUCCESS) {
|
||||||
this._startKeepAlive()
|
this._startKeepAlive()
|
||||||
}
|
}
|
||||||
if (res === plugin.BLUE_STATE.CONNECTFAILED) {
|
if (res === plugin.BLUE_STATE.CONNECTFAILED) {
|
||||||
this._stopKeepAlive()
|
this._stopKeepAlive()
|
||||||
if (!this._intentionalConnect) {
|
if (!this._intentionalConnect) {
|
||||||
this._doReconnect()
|
this._doReconnect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
plugin.bus.subscribe('progressData', (res: ProgressData) => {
|
plugin.bus.subscribe('progressData', (res: ProgressData) => {
|
||||||
this._onProgressCb?.(res)
|
this._onProgressCb?.(res)
|
||||||
})
|
})
|
||||||
|
|
||||||
plugin.bus.subscribe('lockData', (res: LockData) => {
|
plugin.bus.subscribe('lockData', (res: LockData) => {
|
||||||
this._onLockedCb?.(res)
|
this._onLockedCb?.(res)
|
||||||
})
|
})
|
||||||
|
|
||||||
plugin.bus.subscribe('deviceWillDisconnect', () => {
|
plugin.bus.subscribe('deviceWillDisconnect', () => {
|
||||||
console.warn(TAG, 'bus[deviceWillDisconnect],intentionalConnect:', this._intentionalConnect)
|
console.warn(TAG, 'bus[deviceWillDisconnect],intentionalConnect:', this._intentionalConnect)
|
||||||
this._activeProtocol = null
|
this._activeProtocol = null
|
||||||
this._stopKeepAlive()
|
this._stopKeepAlive()
|
||||||
this._onDisconnectedCb?.()
|
this._onDisconnectedCb?.()
|
||||||
if (!this._intentionalConnect) {
|
if (!this._intentionalConnect) {
|
||||||
this._doReconnect()
|
this._doReconnect()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(rawDevice: RawDevice): void {
|
connect(rawDevice: RawDevice): void {
|
||||||
console.log(TAG, 'connect():', rawDevice.name)
|
console.log(TAG, 'connect():', rawDevice.name)
|
||||||
this._lastRawDevice = rawDevice
|
this._lastRawDevice = rawDevice
|
||||||
this._intentionalConnect = true
|
this._intentionalConnect = true
|
||||||
this._stopKeepAlive()
|
this._stopKeepAlive()
|
||||||
this._stopReconnectTimer()
|
this._stopReconnectTimer()
|
||||||
this._activeProtocol = null
|
this._activeProtocol = null
|
||||||
this._connectState = ''
|
this._connectState = ''
|
||||||
this._deviceInfo = null
|
this._deviceInfo = null
|
||||||
// 直连缓存设备时不走 startScan,需手动初始化插件设备配置和总线订阅
|
// 直连缓存设备时不走 startScan,需手动初始化插件设备配置和总线订阅
|
||||||
plugin.Blue.setDeviceSetting(DEVICE_SETTINGS)
|
plugin.Blue.setDeviceSetting(DEVICE_SETTINGS)
|
||||||
this._subscribeBus()
|
this._subscribeBus()
|
||||||
plugin.Blue.stopBluetoothDevicesDiscovery()
|
plugin.Blue.stopBluetoothDevicesDiscovery()
|
||||||
// 0.0.25 新增:重新连接前必须清除协议缓存
|
// 0.0.25 新增:重新连接前必须清除协议缓存
|
||||||
plugin.Blue.clearProtocol()
|
plugin.Blue.clearProtocol()
|
||||||
plugin.Blue.createBLEConnection(rawDevice)
|
plugin.Blue.createBLEConnection(rawDevice)
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnect(): void {
|
disconnect(): void {
|
||||||
console.log(TAG, 'disconnect()')
|
console.log(TAG, 'disconnect()')
|
||||||
this._stopKeepAlive()
|
this._stopKeepAlive()
|
||||||
plugin.Blue.disconnect()
|
plugin.Blue.disconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 读缓存设备信息,自动扫描匹配后连接,已连接或无缓存时直接返回 */
|
/** 读缓存设备信息,自动扫描匹配后连接,已连接或无缓存时直接返回 */
|
||||||
autoConnect(): void {
|
autoConnect(): void {
|
||||||
if (this.isConnected) return
|
if (this.isConnected) return
|
||||||
const cached = wx.getStorageSync('connectDeviceInfo') as RawDevice | null
|
const cached = wx.getStorageSync('connectDeviceInfo') as RawDevice | null
|
||||||
const targetDeviceId = cached?.deviceId as string | undefined
|
const targetDeviceId = cached?.deviceId as string | undefined
|
||||||
if (!targetDeviceId) return
|
if (!targetDeviceId) return
|
||||||
|
|
||||||
let scanTimer: number | null = null
|
let scanTimer: number | null = null
|
||||||
|
|
||||||
wx.openBluetoothAdapter({
|
wx.openBluetoothAdapter({
|
||||||
success: () => {
|
success: () => {
|
||||||
scanTimer = setTimeout(() => {
|
scanTimer = setTimeout(() => {
|
||||||
this.stopScan()
|
this.stopScan()
|
||||||
}, 15000)
|
}, 15000)
|
||||||
|
|
||||||
this.onDevicesList((devices) => {
|
this.onDevicesList((devices) => {
|
||||||
const matched = devices.find(d => d.raw.deviceId === targetDeviceId)
|
const matched = devices.find(d => d.raw.deviceId === targetDeviceId)
|
||||||
if (!matched) return
|
if (!matched) return
|
||||||
if (scanTimer !== null) { clearTimeout(scanTimer); scanTimer = null }
|
if (scanTimer !== null) { clearTimeout(scanTimer); scanTimer = null }
|
||||||
this.stopScan()
|
this.stopScan()
|
||||||
wx.setStorageSync('connectDeviceInfo', matched.raw)
|
wx.setStorageSync('connectDeviceInfo', matched.raw)
|
||||||
this.connect(matched.raw)
|
this.connect(matched.raw)
|
||||||
})
|
})
|
||||||
this.startScan()
|
this.startScan()
|
||||||
},
|
},
|
||||||
fail: () => {
|
fail: () => {
|
||||||
if (scanTimer !== null) { clearTimeout(scanTimer); scanTimer = null }
|
if (scanTimer !== null) { clearTimeout(scanTimer); scanTimer = null }
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
stopScan(): void {
|
stopScan(): void {
|
||||||
console.log(TAG, 'stopScan()')
|
console.log(TAG, 'stopScan()')
|
||||||
this._stopReconnectTimer()
|
this._stopReconnectTimer()
|
||||||
wx.stopBluetoothDevicesDiscovery()
|
wx.stopBluetoothDevicesDiscovery()
|
||||||
this._onDevicesListCb = null
|
this._onDevicesListCb = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── WiFi 配网 ────────────────────────────────
|
// ─── WiFi 配网 ────────────────────────────────
|
||||||
getWifiList(): Promise<LeFuWifiItem[]> {
|
getWifiList(): Promise<LeFuWifiItem[]> {
|
||||||
console.log(TAG, 'getWifiList()')
|
console.log(TAG, 'getWifiList()')
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this._activeProtocol) {
|
if (!this._activeProtocol) {
|
||||||
reject(new Error('设备未连接,无法获取 WiFi 列表'))
|
reject(new Error('设备未连接,无法获取 WiFi 列表'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const timer = setTimeout(() => reject(new Error('获取 WiFi 列表超时')), 15000)
|
const timer = setTimeout(() => reject(new Error('获取 WiFi 列表超时')), 15000)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this._activeProtocol.dataFindSurroundDevice((res: any[]) => {
|
this._activeProtocol.dataFindSurroundDevice((res: any[]) => {
|
||||||
clearTimeout(timer)
|
clearTimeout(timer)
|
||||||
console.log(TAG, 'getWifiList 结果:', res)
|
console.log(TAG, 'getWifiList 结果:', res)
|
||||||
if (!res?.length) {
|
if (!res?.length) {
|
||||||
this._activeProtocol.dataExitWifiConfig(() => {})
|
this._activeProtocol.dataExitWifiConfig(() => { })
|
||||||
resolve([])
|
resolve([])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resolve(res.map((item: any) => ({ ssid: item.ssid || item.name || '', signal: item.signal })))
|
resolve(res.map((item: any) => ({ ssid: item.ssid || item.name || '', signal: item.signal })))
|
||||||
})
|
})
|
||||||
}, 2000)
|
}, 2000)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
configWifi(ssid: string, password: string): Promise<void> {
|
configWifi(ssid: string, password: string): Promise<void> {
|
||||||
const version = (this._deviceInfo?.modelNumber ?? '').split('-').length === 5 ? 'domain2' : 'domain1'
|
const version = (this._deviceInfo?.modelNumber ?? '').split('-').length === 5 ? 'domain2' : 'domain1'
|
||||||
const startTs = Date.now()
|
const startTs = Date.now()
|
||||||
console.log(TAG, 'configWifi():', ssid, version, 'ts=', startTs, 'activeProtocol=', !!this._activeProtocol)
|
console.log(TAG, 'configWifi():', ssid, version, 'ts=', startTs, 'activeProtocol=', !!this._activeProtocol)
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this._activeProtocol) {
|
if (!this._activeProtocol) {
|
||||||
console.warn(TAG, 'configWifi 早期 reject:_activeProtocol 为空')
|
console.warn(TAG, 'configWifi 早期 reject:_activeProtocol 为空')
|
||||||
reject(new Error('设备未连接,无法配网'))
|
reject(new Error('设备未连接,无法配网'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let settled = false
|
let settled = false
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
console.warn(TAG, 'configWifi 超时触发 elapsed=', Date.now() - startTs, 'settled=', settled)
|
console.warn(TAG, 'configWifi 超时触发 elapsed=', Date.now() - startTs, 'settled=', settled)
|
||||||
if (settled) return
|
if (settled) return
|
||||||
settled = true
|
settled = true
|
||||||
reject(new Error('配网超时,请重试'))
|
reject(new Error('配网超时,请重试'))
|
||||||
}, 20000)
|
}, 20000)
|
||||||
console.log(TAG, 'configWifi 已注册 20s 定时器 timerId=', timer)
|
console.log(TAG, 'configWifi 已注册 20s 定时器 timerId=', timer)
|
||||||
const callback = (res: number, ...extra: any[]) => {
|
const callback = (res: number, ...extra: any[]) => {
|
||||||
console.log(TAG, 'configWifi 回调 res=', res, 'extra=', extra, 'elapsed=', Date.now() - startTs, 'settled=', settled)
|
console.log(TAG, 'configWifi 回调 res=', res, 'extra=', extra, 'elapsed=', Date.now() - startTs, 'settled=', settled)
|
||||||
if (settled) return
|
if (settled) return
|
||||||
settled = true
|
settled = true
|
||||||
clearTimeout(timer)
|
clearTimeout(timer)
|
||||||
res === 23 ? resolve() : reject(new Error(`配网失败,错误码:${res}`))
|
res === 23 ? resolve() : reject(new Error(`配网失败,错误码:${res}`))
|
||||||
}
|
}
|
||||||
if (version === 'domain1') {
|
if (version === 'domain1') {
|
||||||
console.log(TAG, 'domain1 dataConfigNetWork')
|
console.log(TAG, 'domain1 dataConfigNetWork')
|
||||||
this._activeProtocol.dataConfigNetWork({ domain: LEFU_CONFIG.domain1, ssid, password }, callback)
|
this._activeProtocol.dataConfigNetWork({ domain: LEFU_CONFIG.domain1, ssid, password }, callback)
|
||||||
} else {
|
} else {
|
||||||
console.log(TAG, 'domain2 dataConfigUserNetWork')
|
console.log(TAG, 'domain2 dataConfigUserNetWork')
|
||||||
this._activeProtocol.dataConfigUserNetWork(
|
this._activeProtocol.dataConfigUserNetWork(
|
||||||
{ domain: LEFU_CONFIG.domain2, ssid, password, userName: 'apiUser', userPassword: '3acebb95eb49577e9c2a2082589b9bd6' },
|
{ domain: LEFU_CONFIG.domain2, ssid, password, userName: 'apiUser', userPassword: '3acebb95eb49577e9c2a2082589b9bd6' },
|
||||||
callback,
|
callback,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
checkWifiConfig(): Promise<boolean> {
|
checkWifiConfig(): Promise<boolean> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this._activeProtocol) { reject(new Error('设备未连接')); return }
|
if (!this._activeProtocol) { reject(new Error('设备未连接')); return }
|
||||||
this._activeProtocol.codeFetchWifiConfig((res: number | undefined | null) => {
|
this._activeProtocol.codeFetchWifiConfig((res: number | undefined | null) => {
|
||||||
resolve(res === 0x01)
|
resolve(res === 0x01)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── OTA 升级 ─────────────────────────────────
|
// ─── OTA 升级 ─────────────────────────────────
|
||||||
checkAndUpgrade(): Promise<boolean> {
|
checkAndUpgrade(): Promise<boolean> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this._activeProtocol) { reject(new Error('设备未连接')); return }
|
if (!this._activeProtocol) { reject(new Error('设备未连接')); return }
|
||||||
if (!this._deviceInfo) { reject(new Error('固件信息未就绪')); return }
|
if (!this._deviceInfo) { reject(new Error('固件信息未就绪')); return }
|
||||||
|
|
||||||
const { firmwareRevision, modelNumber } = this._deviceInfo
|
const { firmwareRevision, modelNumber } = this._deviceInfo
|
||||||
const [mcuVer, bleVer, wifiVer, resVer] = (firmwareRevision || '').split('.')
|
const [mcuVer, bleVer, wifiVer, resVer] = (firmwareRevision || '').split('.')
|
||||||
const isServerNewer = (dv: string, sv: string) => {
|
const isServerNewer = (dv: string, sv: string) => {
|
||||||
const dn = parseInt(dv, 10)
|
const dn = parseInt(dv, 10)
|
||||||
const sn = (sv || '').split('.').map(v => parseInt(v, 10)).reduce((a, v) => a * 1000 + v, 0)
|
const sn = (sv || '').split('.').map(v => parseInt(v, 10)).reduce((a, v) => a * 1000 + v, 0)
|
||||||
return sn > dn
|
return sn > dn
|
||||||
}
|
}
|
||||||
|
|
||||||
get<FirmwareVersion>('weighingScale/v2/firmware/version', { type: modelNumber }, { loading: false })
|
get<FirmwareVersion>('weighingScale/v2/firmware/version', { type: modelNumber }, { loading: false })
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const { mcuVersion, bleVersion, wifiVersion, resVersion } = res.result
|
const { mcuVersion, bleVersion, wifiVersion, resVersion } = res.result
|
||||||
const needUpdate = isServerNewer(mcuVer, mcuVersion) || isServerNewer(bleVer, bleVersion)
|
const needUpdate = isServerNewer(mcuVer, mcuVersion) || isServerNewer(bleVer, bleVersion)
|
||||||
|| isServerNewer(wifiVer, wifiVersion) || isServerNewer(resVer, resVersion)
|
|| isServerNewer(wifiVer, wifiVersion) || isServerNewer(resVer, resVersion)
|
||||||
if (!needUpdate) { resolve(false); return }
|
if (!needUpdate) { resolve(false); return }
|
||||||
this._activeProtocol.codeOtaUpdate((status: number) => {
|
this._activeProtocol.codeOtaUpdate((status: number) => {
|
||||||
console.log(`codeOtaUpdatecodeOtaUpdatecodeOtaUpdate ${status}`)
|
console.log(`codeOtaUpdatecodeOtaUpdatecodeOtaUpdate ${status}`)
|
||||||
status != 0 ? reject(new Error('OTA 升级失败')) : resolve(true)
|
status != 0 ? reject(new Error('OTA 升级失败')) : resolve(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(reject)
|
.catch(reject)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── 私有:保活与重连 ─────────────────────────
|
// ─── 私有:保活与重连 ─────────────────────────
|
||||||
private _startKeepAlive(): void {
|
private _startKeepAlive(): void {
|
||||||
this._stopKeepAlive()
|
this._stopKeepAlive()
|
||||||
this._keepAliveTimer = setInterval(() => { this._activeProtocol?.sendKeepAliveCode?.() }, 15000)
|
this._keepAliveTimer = setInterval(() => { this._activeProtocol?.sendKeepAliveCode?.() }, 15000)
|
||||||
}
|
}
|
||||||
|
|
||||||
private _stopKeepAlive(): void {
|
private _stopKeepAlive(): void {
|
||||||
if (this._keepAliveTimer !== null) {
|
if (this._keepAliveTimer !== null) {
|
||||||
clearInterval(this._keepAliveTimer)
|
clearInterval(this._keepAliveTimer)
|
||||||
this._keepAliveTimer = null
|
this._keepAliveTimer = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _stopReconnectTimer(): void {
|
private _stopReconnectTimer(): void {
|
||||||
if (this._reconnectTimer !== null) {
|
if (this._reconnectTimer !== null) {
|
||||||
clearTimeout(this._reconnectTimer)
|
clearTimeout(this._reconnectTimer)
|
||||||
this._reconnectTimer = null
|
this._reconnectTimer = null
|
||||||
}
|
}
|
||||||
this._reconnectCount = 0
|
this._reconnectCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private _doReconnect(): void {
|
private _doReconnect(): void {
|
||||||
if (this._reconnectCount >= this._maxReconnect) {
|
if (this._reconnectCount >= this._maxReconnect) {
|
||||||
console.warn(TAG, '重连次数已达上限')
|
console.warn(TAG, '重连次数已达上限')
|
||||||
this._onDisconnectedCb?.()
|
this._onDisconnectedCb?.()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!this._lastRawDevice) {
|
if (!this._lastRawDevice) {
|
||||||
console.warn(TAG, '无缓存设备,放弃重连')
|
console.warn(TAG, '无缓存设备,放弃重连')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this._reconnectCount++
|
this._reconnectCount++
|
||||||
console.log(TAG, `_doReconnect 第 ${this._reconnectCount} 次`)
|
console.log(TAG, `_doReconnect 第 ${this._reconnectCount} 次`)
|
||||||
this._stopReconnectTimer()
|
this._stopReconnectTimer()
|
||||||
this._reconnectTimer = setTimeout(() => {
|
this._reconnectTimer = setTimeout(() => {
|
||||||
plugin.Blue.clearProtocol()
|
plugin.Blue.clearProtocol()
|
||||||
plugin.Blue.createBLEConnection(this._lastRawDevice!)
|
plugin.Blue.createBLEConnection(this._lastRawDevice!)
|
||||||
}, 2000)
|
}, 2000)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── 清除设备成员(不下发) ─────────────────────
|
// ─── 清除设备用户(不下发) ─────────────────────
|
||||||
clearDeviceMembers(): Promise<void> {
|
clearDeviceMembers(): Promise<void> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this._activeProtocol) { reject(new Error('设备未连接')); return }
|
if (!this._activeProtocol) { reject(new Error('设备未连接')); return }
|
||||||
const timer = setTimeout(() => reject(new Error('清除设备成员超时')), 15000)
|
const timer = setTimeout(() => reject(new Error('清除设备用户超时')), 15000)
|
||||||
this._activeProtocol.codeClearDeviceData('01', (res: number) => {
|
this._activeProtocol.codeClearDeviceData('01', (res: number) => {
|
||||||
clearTimeout(timer)
|
clearTimeout(timer)
|
||||||
res === 0 ? resolve() : reject(new Error('清除设备成员失败'))
|
res === 0 ? resolve() : reject(new Error('清除设备用户失败'))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── 成员同步 ─────────────────────────────────
|
// ─── 用户同步 ─────────────────────────────────
|
||||||
syncMembersToDevice(members: DeviceMember[], onProgress?: (current: number, total: number) => void): Promise<void> {
|
syncMembersToDevice(members: DeviceMember[], onProgress?: (current: number, total: number) => void): Promise<void> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this._activeProtocol) { reject(new Error('设备未连接')); return }
|
if (!this._activeProtocol) { reject(new Error('设备未连接')); return }
|
||||||
const mainUser = members.find(m => m.isSelf)
|
const mainUser = members.find(m => m.isSelf)
|
||||||
if (!mainUser) { reject(new Error('缺少主用户')); return }
|
if (!mainUser) { reject(new Error('缺少主用户')); return }
|
||||||
|
|
||||||
const clearTimer = setTimeout(() => reject(new Error('清除设备成员超时')), 15000)
|
const clearTimer = setTimeout(() => reject(new Error('清除设备用户超时')), 15000)
|
||||||
this._activeProtocol.codeClearDeviceData('01', (clearRes: number) => {
|
this._activeProtocol.codeClearDeviceData('01', (clearRes: number) => {
|
||||||
clearTimeout(clearTimer)
|
clearTimeout(clearTimer)
|
||||||
if (clearRes != 0) { reject(new Error('清除设备成员失败')); return }
|
if (clearRes != 0) { reject(new Error('清除设备用户失败')); return }
|
||||||
|
|
||||||
let index = 0
|
let index = 0
|
||||||
let syncTimer: number | null = null
|
let syncTimer: number | null = null
|
||||||
const resetTimer = () => {
|
const resetTimer = () => {
|
||||||
if (syncTimer !== null) clearTimeout(syncTimer)
|
if (syncTimer !== null) clearTimeout(syncTimer)
|
||||||
syncTimer = setTimeout(() => reject(new Error(`第 ${index + 1} 个成员下发超时`)), 15000)
|
syncTimer = setTimeout(() => reject(new Error(`第 ${index + 1} 个用户下发超时`)), 15000)
|
||||||
}
|
}
|
||||||
const syncNext = () => {
|
const syncNext = () => {
|
||||||
if (index >= members.length) {
|
if (index >= members.length) {
|
||||||
if (syncTimer !== null) clearTimeout(syncTimer)
|
if (syncTimer !== null) clearTimeout(syncTimer)
|
||||||
resolve()
|
resolve()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const member = members[index]
|
const member = members[index]
|
||||||
onProgress?.(index + 1, members.length)
|
onProgress?.(index + 1, members.length)
|
||||||
resetTimer()
|
resetTimer()
|
||||||
this._activeProtocol.dataSyncUserInfo(
|
this._activeProtocol.dataSyncUserInfo(
|
||||||
{
|
{
|
||||||
userID: mainUser.id, userName: member.name,
|
userID: mainUser.id, userName: member.name,
|
||||||
memberID: member.isSelf ? '' : member.id,
|
memberID: member.isSelf ? '' : member.id,
|
||||||
age: member.age, gender: member.gender, height: member.height,
|
age: member.age, gender: member.gender, height: member.height,
|
||||||
isAthleteMode: 0, deviceHeaderIndex: index,
|
isAthleteMode: 0, deviceHeaderIndex: index,
|
||||||
currentWeight: '', targetWeight: '', idealWeight: '', recentData: [],
|
currentWeight: '', targetWeight: '', idealWeight: '', recentData: [],
|
||||||
},
|
},
|
||||||
(res: number) => { if (res === 0) index++; syncNext() },
|
(res: number) => { if (res === 0) index++; syncNext() },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
syncNext()
|
syncNext()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const lefuService = new LeFuService()
|
export const lefuService = new LeFuService()
|
||||||
|
|||||||
@@ -95,9 +95,9 @@ export interface FirmwareVersion {
|
|||||||
resVersion: string
|
resVersion: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 下发给设备的成员信息(lefu 层使用,业务层转换后传入) */
|
/** 下发给设备的用户信息(lefu 层使用,业务层转换后传入) */
|
||||||
export interface DeviceMember {
|
export interface DeviceMember {
|
||||||
/** 成员唯一 ID */
|
/** 用户唯一 ID */
|
||||||
id: string
|
id: string
|
||||||
/** 姓名 */
|
/** 姓名 */
|
||||||
name: string
|
name: string
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"navigationBarTitleText": "添加成员",
|
"navigationBarTitleText": "添加用户",
|
||||||
"usingComponents": {
|
"usingComponents": {
|
||||||
"select-member-drawer": "/components/selectMemberDrawer/selectMemberDrawer",
|
"select-member-drawer": "/components/selectMemberDrawer/selectMemberDrawer",
|
||||||
"user-info-confirm-modal": "/components/userInfoConfirmModal/userInfoConfirmModal"
|
"user-info-confirm-modal": "/components/userInfoConfirmModal/userInfoConfirmModal"
|
||||||
|
|||||||
@@ -167,7 +167,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 从已有成员中选择(蓝色描边幽灵按钮) */
|
/* 从已有用户中选择(蓝色描边幽灵按钮) */
|
||||||
.ghost-btn {
|
.ghost-btn {
|
||||||
color: #1385FA;
|
color: #1385FA;
|
||||||
width: 580rpx;
|
width: 580rpx;
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ interface IdCardParsed {
|
|||||||
birthday: string
|
birthday: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 从抽屉组件 select 事件接收的成员数据(完整 item) */
|
/** 从抽屉组件 select 事件接收的用户数据(完整 item) */
|
||||||
interface ExistingMember {
|
interface ExistingMember {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
@@ -78,8 +78,8 @@ interface ExistingMember {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加/编辑成员页
|
* 添加/编辑用户页
|
||||||
* URL 参数含 userId 时为编辑模式,隐藏「从已有成员中选择」按钮并预填表单
|
* URL 参数含 userId 时为编辑模式,隐藏「从已有用户中选择」按钮并预填表单
|
||||||
*/
|
*/
|
||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
@@ -97,7 +97,7 @@ Page({
|
|||||||
weight: ''
|
weight: ''
|
||||||
} as MemberForm,
|
} as MemberForm,
|
||||||
|
|
||||||
/** 从抽屉选中的完整成员数据,提交时作为 base spread */
|
/** 从抽屉选中的完整用户数据,提交时作为 base spread */
|
||||||
selectedMember: null as ExistingMember | null,
|
selectedMember: null as ExistingMember | null,
|
||||||
showSelectDrawer: false,
|
showSelectDrawer: false,
|
||||||
/** 正在请求身份证查询接口 */
|
/** 正在请求身份证查询接口 */
|
||||||
@@ -391,7 +391,7 @@ Page({
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
wx.showToast({ title: successMsg, icon: 'success' })
|
wx.showToast({ title: successMsg, icon: 'success' })
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 通知上一页(equipmentMember)刷新成员列表
|
// 通知上一页(equipmentMember)刷新用户列表
|
||||||
const pages = getCurrentPages()
|
const pages = getCurrentPages()
|
||||||
const prevPage = pages[pages.length - 2] as any
|
const prevPage = pages[pages.length - 2] as any
|
||||||
if (prevPage && prevPage.data?.sn) {
|
if (prevPage && prevPage.data?.sn) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<!-- 顶部浅蓝提示条 -->
|
<!-- 顶部浅蓝提示条 -->
|
||||||
<view class="tips">
|
<view class="tips">
|
||||||
<view class="tips-icon">!</view>
|
<view class="tips-icon">!</view>
|
||||||
<text class="tips-text">最多支持 10 位成员</text>
|
<text class="tips-text">最多支持 10 位用户</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="form">
|
<view class="form">
|
||||||
@@ -126,21 +126,21 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 从已有成员中选择(编辑模式隐藏) -->
|
<!-- 从已有用户中选择(编辑模式隐藏) -->
|
||||||
<block wx:if="{{ !isEdit }}">
|
<block wx:if="{{ !isEdit }}">
|
||||||
<view class="ghost-btn" bind:tap="onTapSelectExisting">从已有成员中选择</view>
|
<view class="ghost-btn" bind:tap="onTapSelectExisting">从已有用户中选择</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 底部双按钮:取消 / 保存成员信息 -->
|
<!-- 底部双按钮:取消 / 保存用户信息 -->
|
||||||
<view class="actions">
|
<view class="actions">
|
||||||
<view class="btn-cancel" bind:tap="onCancel">取消</view>
|
<view class="btn-cancel" bind:tap="onCancel">取消</view>
|
||||||
<view class="btn-primary" bind:tap="onSubmit">保存成员信息</view>
|
<view class="btn-primary" bind:tap="onSubmit">保存用户信息</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 选择已有成员抽屉 -->
|
<!-- 选择已有用户抽屉 -->
|
||||||
<select-member-drawer
|
<select-member-drawer
|
||||||
show="{{ showSelectDrawer }}"
|
show="{{ showSelectDrawer }}"
|
||||||
bind:close="onSelectMemberClose"
|
bind:close="onSelectMemberClose"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 成员信息行 */
|
/* 用户信息行 */
|
||||||
.userInfo {
|
.userInfo {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 切换成员按钮 */
|
/* 切换用户按钮 */
|
||||||
.btn {
|
.btn {
|
||||||
color: #1385FA;
|
color: #1385FA;
|
||||||
width: 120rpx;
|
width: 120rpx;
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ Page({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 打开切换成员抽屉 */
|
/** 打开切换用户抽屉 */
|
||||||
onTapSwitchMember() {
|
onTapSwitchMember() {
|
||||||
this.setData({ showSelectDrawer: true })
|
this.setData({ showSelectDrawer: true })
|
||||||
},
|
},
|
||||||
@@ -218,7 +218,7 @@ Page({
|
|||||||
this.setData({ showSelectDrawer: false })
|
this.setData({ showSelectDrawer: false })
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 选中成员后更新 userInfo 并重新请求数据 */
|
/** 选中用户后更新 userInfo 并重新请求数据 */
|
||||||
onSelectMember(e: WechatMiniprogram.CustomEvent) {
|
onSelectMember(e: WechatMiniprogram.CustomEvent) {
|
||||||
const m = e.detail as {
|
const m = e.detail as {
|
||||||
userId?: string
|
userId?: string
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
>
|
>
|
||||||
<view class="scrollViewContent">
|
<view class="scrollViewContent">
|
||||||
|
|
||||||
<!-- 数据卡(成员信息 + 时间 Tab + 统计) -->
|
<!-- 数据卡(用户信息 + 时间 Tab + 统计) -->
|
||||||
<view class="data-card">
|
<view class="data-card">
|
||||||
|
|
||||||
<!-- 成员信息 -->
|
<!-- 用户信息 -->
|
||||||
<view class="userInfo">
|
<view class="userInfo">
|
||||||
<view class="avatar">{{ userInfo.realname[0] }}</view>
|
<view class="avatar">{{ userInfo.realname[0] }}</view>
|
||||||
<view class="info">
|
<view class="info">
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
<view class="meta-text">{{ userInfo.height }}cm</view>
|
<view class="meta-text">{{ userInfo.height }}cm</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn" bind:tap="onTapSwitchMember">切换成员</view>
|
<view class="btn" bind:tap="onTapSwitchMember">切换用户</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="card-divider"></view>
|
<view class="card-divider"></view>
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ Page({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/* 点击「成员管理」→ 跳转成员管理页,sn 由目标页从缓存读取 */
|
/* 点击「用户管理」→ 跳转用户管理页,sn 由目标页从缓存读取 */
|
||||||
onTapMember() {
|
onTapMember() {
|
||||||
wx.navigateTo({ url: '/pages/equipmentMember/equipmentMember' })
|
wx.navigateTo({ url: '/pages/equipmentMember/equipmentMember' })
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -37,15 +37,13 @@
|
|||||||
<block wx:if="{{ item.connected }}">
|
<block wx:if="{{ item.connected }}">
|
||||||
<!-- 已连接:单按钮居中 -->
|
<!-- 已连接:单按钮居中 -->
|
||||||
<view class="card-actions card-actions-single">
|
<view class="card-actions card-actions-single">
|
||||||
<view class="btn-ghost-full" bind:tap="onTapMember">成员管理</view>
|
<view class="btn-ghost-full" bind:tap="onTapMember">用户管理</view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<block wx:else>
|
<block wx:else>
|
||||||
<!-- 未连接:双按钮 连接 / 成员管理 -->
|
<!-- 未连接:双按钮 连接 / 用户管理 -->
|
||||||
<view class="card-actions card-actions-single">
|
<view class="card-actions card-actions-single">
|
||||||
<view class="btn-ghost-full" data-connect-device-info="{{ item.connectDeviceInfo }}" data-user-info="{{ item }}" bind:tap="onTapConnect">连接</view>
|
<view class="btn-ghost-full" data-connect-device-info="{{ item.connectDeviceInfo }}" data-user-info="{{ item }}" bind:tap="onTapConnect">连接</view>
|
||||||
<!-- <view class="btn-ghost-half" data-connect-device-info="{{ item.connectDeviceInfo }}" data-user-info="{{ item }}" bind:tap="onTapConnect">连接</view>-->
|
|
||||||
<!-- <view class="btn-ghost-half" bind:tap="onTapMember">成员管理</view>-->
|
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"navigationBarTitleText": "设备成员",
|
"navigationBarTitleText": "设备用户",
|
||||||
"usingComponents": {}
|
"usingComponents": {}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user