refactor: 统一术语「成员」→「用户」,代码格式化

- 页面文案、注释、Toast 提示统一改为"用户"
- lefu 模块缩进格式化(空格→Tab)
- selectMemberDrawer 组件注释统一

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
17792275749
2026-06-10 15:18:58 +08:00
co-authored by Claude Opus 4.7
parent 97c135786c
commit 485725a486
15 changed files with 443 additions and 445 deletions
@@ -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
View File
@@ -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'
/** 顶层加载插件(对齐 demorequirePlugin 必须在文件顶层调用) */ /** 顶层加载插件(对齐 demorequirePlugin 必须在文件顶层调用) */
@@ -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()
+2 -2
View File
@@ -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 -1
View File
@@ -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"
+1 -1
View File
@@ -167,7 +167,7 @@
} }
} }
/* 从已有成员中选择(蓝色描边幽灵按钮) */ /* 从已有用户中选择(蓝色描边幽灵按钮) */
.ghost-btn { .ghost-btn {
color: #1385FA; color: #1385FA;
width: 580rpx; width: 580rpx;
+5 -5
View File
@@ -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) {
+6 -6
View File
@@ -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"
+2 -2
View File
@@ -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;
+2 -2
View File
@@ -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
+3 -3
View File
@@ -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>
+1 -1
View File
@@ -184,7 +184,7 @@ Page({
}) })
}, },
/* 点击「成员管理」→ 跳转成员管理页,sn 由目标页从缓存读取 */ /* 点击「用户管理」→ 跳转用户管理页,sn 由目标页从缓存读取 */
onTapMember() { onTapMember() {
wx.navigateTo({ url: '/pages/equipmentMember/equipmentMember' }) wx.navigateTo({ url: '/pages/equipmentMember/equipmentMember' })
}, },
+2 -4
View File
@@ -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": {}
} }