feat:手动绑定孩子账号
This commit is contained in:
parent
549e25155c
commit
81c2f77434
11
.vscode/settings.json
vendored
11
.vscode/settings.json
vendored
@ -48,5 +48,14 @@
|
||||
"src/uni_modules/uni-search-bar/components/uni-search-bar/i18n",
|
||||
"src/uni_modules/z-paging/components/z-paging/i18n"
|
||||
],
|
||||
"cSpell.words": ["iconfont", "persistedstate", "pinia", "VITE", "Wechat", "Weixin", "xuexiaole"]
|
||||
"cSpell.words": [
|
||||
"dcloudio",
|
||||
"iconfont",
|
||||
"persistedstate",
|
||||
"pinia",
|
||||
"VITE",
|
||||
"Wechat",
|
||||
"Weixin",
|
||||
"xuexiaole"
|
||||
]
|
||||
}
|
||||
|
9
pnpm-lock.yaml
generated
9
pnpm-lock.yaml
generated
@ -1926,6 +1926,11 @@ packages:
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
acorn@8.15.0:
|
||||
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
address@1.2.2:
|
||||
resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
@ -7435,6 +7440,8 @@ snapshots:
|
||||
|
||||
acorn@8.11.3: {}
|
||||
|
||||
acorn@8.15.0: {}
|
||||
|
||||
address@1.2.2: {}
|
||||
|
||||
agent-base@6.0.2:
|
||||
@ -9309,7 +9316,7 @@ snapshots:
|
||||
jsdom@16.7.0:
|
||||
dependencies:
|
||||
abab: 2.0.6
|
||||
acorn: 8.11.3
|
||||
acorn: 8.15.0
|
||||
acorn-globals: 6.0.0
|
||||
cssom: 0.4.4
|
||||
cssstyle: 2.3.0
|
||||
|
@ -1,50 +1,50 @@
|
||||
import { http } from '../request/request';
|
||||
import { http } from '../request/request'
|
||||
|
||||
/**
|
||||
* 当前登录用户的绑定信息
|
||||
* @param params 请求参数
|
||||
*/
|
||||
export const getCurInfo = async (params: any) =>
|
||||
await http.get<any>('/parentBind/curInfo', params);
|
||||
export const getCurInfo = async (params: any) => await http.get<any>('/parentBind/curInfo', params)
|
||||
|
||||
/**
|
||||
* 家长绑定管理员
|
||||
* @param data 请求参数
|
||||
*/
|
||||
export const parentBindAdmin = async (data: any) =>
|
||||
await http.post<any>('/parentBind/admin', data);
|
||||
export const parentBindAdmin = async (data: any) => await http.post<any>('/parentBind/admin', data)
|
||||
|
||||
/**
|
||||
* 家长申请绑定
|
||||
* @param data 请求参数
|
||||
*/
|
||||
export const parentBindApply = async (data: any) =>
|
||||
await http.post<any>('/parentBind/apply', data);
|
||||
export const parentBindApply = async (data: any) => await http.post<any>('/parentBind/apply', data)
|
||||
|
||||
// 手动输入账号绑定孩子
|
||||
export const manualBindApi = async (childAcc: any) =>
|
||||
await http.postForm<any>('/parentBind/familyTeacherBindAcc', { childAcc })
|
||||
|
||||
/**
|
||||
* -设备当前管理员信息
|
||||
* @param params 请求参数
|
||||
*/
|
||||
export const adminInfo = async (params: any) =>
|
||||
await http.get<any>('/parentBind/adminInfo', params);
|
||||
export const adminInfo = async (params: any) => await http.get<any>('/parentBind/adminInfo', params)
|
||||
|
||||
/**
|
||||
* -家长申请绑定信息
|
||||
* @param params 请求参数
|
||||
*/
|
||||
export const applyInfo = async (params: any) =>
|
||||
await http.get<any>('/parentBind/apply/info', params);
|
||||
await http.get<any>('/parentBind/apply/info', params)
|
||||
|
||||
/**
|
||||
* 管理员审批
|
||||
* @param data 请求参数
|
||||
*/
|
||||
export const adminApproval = async (data: any) =>
|
||||
await http.post<any>('/parentBind/admin/approval', data);
|
||||
await http.post<any>('/parentBind/admin/approval', data)
|
||||
|
||||
/**
|
||||
* 时间管控保存
|
||||
* @param data 请求参数
|
||||
*/
|
||||
export const deviceTimeControl = async (data: any) =>
|
||||
await http.post<any>('/deviceTimeControl', data);
|
||||
await http.post<any>('/deviceTimeControl', data)
|
||||
|
@ -50,8 +50,8 @@ function switchTab(item, index) {
|
||||
onMounted(async () => {
|
||||
currentIndex.value = props.selectedIndex
|
||||
// 家长
|
||||
await getApplyBindInfoList()
|
||||
notice.value = db.get('applyBindMsg')
|
||||
notice.value = await getApplyBindInfoList()
|
||||
|
||||
list.value = [
|
||||
{
|
||||
pagePath: '/pages/home/index',
|
||||
|
69
src/components/mjui/mj-dialog/mj-dialog.vue
Normal file
69
src/components/mjui/mj-dialog/mj-dialog.vue
Normal file
@ -0,0 +1,69 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
defineOptions({ name: 'mj-dialog' })
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
title?: string
|
||||
hideCancel?: boolean
|
||||
hideOk?: boolean
|
||||
okText?: string
|
||||
cancelText?: string
|
||||
maskClosable?: boolean
|
||||
ok?: any
|
||||
cancel?: any
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
}>()
|
||||
|
||||
const show = computed({
|
||||
get: () => props.modelValue,
|
||||
set: val => {
|
||||
emit('update:modelValue', val)
|
||||
},
|
||||
})
|
||||
|
||||
// 按钮
|
||||
const btns = []
|
||||
if (!props.hideCancel) {
|
||||
btns.push({
|
||||
text: props.cancelText || '取消',
|
||||
color: '#999',
|
||||
})
|
||||
}
|
||||
if (!props.hideOk) {
|
||||
btns.push({
|
||||
text: props.okText || '确定',
|
||||
color: '#615dff',
|
||||
})
|
||||
}
|
||||
const buttons = ref(btns)
|
||||
|
||||
function btnClick({ index }) {
|
||||
if (index === 0) {
|
||||
props.cancel?.()
|
||||
emit('update:modelValue', false)
|
||||
} else {
|
||||
props.ok?.()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<tui-dialog
|
||||
:show="show"
|
||||
:title="title"
|
||||
:buttons="buttons"
|
||||
:maskClosable="maskClosable"
|
||||
@click="btnClick"
|
||||
>
|
||||
<template v-slot:content>
|
||||
<slot />
|
||||
</template>
|
||||
</tui-dialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -3,7 +3,7 @@ defineOptions({ name: 'mj-empty' })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<tui-no-data imgUrl="/static/nodata.png">暂无数据</tui-no-data>
|
||||
<tui-no-data imgUrl="/static/nodata.png">暂无数据</tui-no-data>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -57,7 +57,7 @@ const dialog_default_buttons = [
|
||||
},
|
||||
{
|
||||
text: '确定',
|
||||
color: '#333',
|
||||
color: '#615dff',
|
||||
},
|
||||
]
|
||||
|
||||
@ -90,6 +90,7 @@ function dialog(options: DialogOptions) {
|
||||
if (options.cancelColor) {
|
||||
options.buttons[0].color = options.cancelColor
|
||||
}
|
||||
// 事件
|
||||
}
|
||||
|
||||
// 确定按钮
|
||||
@ -118,9 +119,12 @@ function dialog(options: DialogOptions) {
|
||||
clickFn(hide, e)
|
||||
}
|
||||
// 点击了取消按钮
|
||||
if (cancelFn && e.index === 0) {
|
||||
cancelFn()
|
||||
hide()
|
||||
if (e.index === 0) {
|
||||
if (cancelFn) {
|
||||
cancelFn(hide)
|
||||
} else {
|
||||
hide()
|
||||
}
|
||||
}
|
||||
// 点击了确定按钮
|
||||
const okIdx = (options.buttons?.length || 1) - 1
|
||||
|
@ -392,12 +392,6 @@
|
||||
"selectedIconPath": "static/tabBar/studyReport.png",
|
||||
"text": "学情报告"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/applicationManagement/index",
|
||||
"iconPath": "static/tabBar/applicationNo.png",
|
||||
"selectedIconPath": "static/tabBar/application.png",
|
||||
"text": "应用管控"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/mine/index",
|
||||
"iconPath": "static/tabBar/mineno.png",
|
||||
|
@ -8,8 +8,9 @@
|
||||
<Empty v-if="empty" content="暂无学情报告数据哦~" />
|
||||
</mj-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import Empty from '@/components/Empty/index.vue'
|
||||
import ChildrenBox from './components/childrenBox.vue'
|
||||
@ -20,11 +21,11 @@ import './index.scss'
|
||||
import { getParentBindChildApi, subjectApi } from '@/api'
|
||||
import { userStore, bindApplyStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import db from '@/utils/db'
|
||||
import hud from '@/utils/hud'
|
||||
import { badgeStore } from '@/store/badge'
|
||||
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
const { getApplyBindInfoList } = bindApplyStore()
|
||||
const { refreshBadge } = badgeStore()
|
||||
|
||||
const childrenList = ref<ChildrenType[]>() // 所有孩子
|
||||
const empty = ref(false)
|
||||
@ -71,25 +72,9 @@ async function getSubject() {
|
||||
subjectList.value = data
|
||||
chooseSubject.value = data[0]
|
||||
}
|
||||
// 处理红点逻辑
|
||||
async function handleTabBarBadge() {
|
||||
await getApplyBindInfoList()
|
||||
const hasApplyMsg = db.get('applyBindMsg')
|
||||
|
||||
if (hasApplyMsg) {
|
||||
uni.setTabBarBadge({
|
||||
index: 3, // "我的"页面在tabBar中的索引
|
||||
text: '●',
|
||||
})
|
||||
} else {
|
||||
uni.removeTabBarBadge({
|
||||
index: 3,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
handleTabBarBadge()
|
||||
refreshBadge()
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
@ -97,7 +82,6 @@ onMounted(async () => {
|
||||
hud.loading()
|
||||
await getParentBindChild()
|
||||
await getSubject()
|
||||
handleTabBarBadge()
|
||||
} finally {
|
||||
hud.hide()
|
||||
}
|
||||
|
@ -72,7 +72,7 @@
|
||||
v-for="(i, idx) in navList"
|
||||
:key="idx"
|
||||
:class="{ navigate_item: true, active: activeNav.type === i.type }"
|
||||
@click="swicthNav(i)"
|
||||
@click="switchNav(i)"
|
||||
>{{ i.title }}</text
|
||||
>
|
||||
</view>
|
||||
@ -132,7 +132,6 @@
|
||||
</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@ -147,9 +146,10 @@ import Empty from '@/components/Empty/index.vue'
|
||||
import { userStore, bindApplyStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import db from '@/utils/db'
|
||||
import { badgeStore } from '@/store/badge'
|
||||
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
const { getApplyBindInfoList } = bindApplyStore()
|
||||
const { refreshBadge } = badgeStore()
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
const arrow = `${OSS_URL}/iconfont/down_arrow.png`
|
||||
@ -158,7 +158,6 @@ const unchecked = `${OSS_URL}/iconfont/unchecked.png`
|
||||
const showAllEquipment = ref(false)
|
||||
const showCustomPopup = ref(false)
|
||||
|
||||
|
||||
const methodPopup = ref(false)
|
||||
const methodList = ref([
|
||||
{
|
||||
@ -218,7 +217,7 @@ function handleChecked(i) {
|
||||
fetchAppRecord()
|
||||
}
|
||||
|
||||
function swicthNav(i) {
|
||||
function switchNav(i) {
|
||||
activeNav.value = i
|
||||
}
|
||||
// 管控
|
||||
@ -288,31 +287,14 @@ async function fetchAppRecord() {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
// 处理红点逻辑
|
||||
async function handleTabBarBadge() {
|
||||
await getApplyBindInfoList()
|
||||
const hasApplyMsg = db.get('applyBindMsg')
|
||||
|
||||
if (hasApplyMsg) {
|
||||
uni.setTabBarBadge({
|
||||
index: 3, // "我的"页面在tabBar中的索引
|
||||
text: '●'
|
||||
})
|
||||
} else {
|
||||
uni.removeTabBarBadge({
|
||||
index: 3
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
handleTabBarBadge()
|
||||
refreshBadge()
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
await getParentBindDevice()
|
||||
fetchAppRecord()
|
||||
handleTabBarBadge()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
@ -1,23 +1,23 @@
|
||||
<template>
|
||||
<z-paging ref="paging" v-model="dataList" :auto="false" @query="queryList">
|
||||
<view class="page-container">
|
||||
<BackBar title="历史截屏" />
|
||||
<template v-slot:empty>
|
||||
<view class="empty_box">
|
||||
<scroll-view scroll-y class="scroll-container">
|
||||
<view v-if="dataList.length === 0" class="empty_box">
|
||||
<Empty content="暂无历史截屏数据哦~" />
|
||||
</view>
|
||||
</template>
|
||||
<view class="content">
|
||||
<view
|
||||
v-for="(item, index) in dataList"
|
||||
:key="index"
|
||||
class="item"
|
||||
@click="previewImageFun(index)"
|
||||
>
|
||||
<image class="itemImage" :src="item.imageUrl" mode="aspectFill" />
|
||||
<view class="time">{{ item.createTime.replace(/-/g, '.') }}</view>
|
||||
<view v-else class="content">
|
||||
<view
|
||||
v-for="(item, index) in dataList"
|
||||
:key="index"
|
||||
class="item"
|
||||
@click="previewImageFun(index)"
|
||||
>
|
||||
<image class="itemImage" :src="item.imageUrl" mode="aspectFill" />
|
||||
<view class="time">{{ item.createTime.replace(/-/g, '.') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -26,16 +26,18 @@ import { deviceScreenshotRecordList } from '@/api';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import Empty from '@/components/Empty/index.vue';
|
||||
const dataList = ref([]);
|
||||
const paging = ref();
|
||||
|
||||
const simSerialNumber = ref();
|
||||
function queryList(pageNo: number, pageSize: number) {
|
||||
|
||||
function loadData() {
|
||||
deviceScreenshotRecordList({
|
||||
size: pageSize,
|
||||
current: pageNo,
|
||||
size: 1000,
|
||||
current: 1,
|
||||
simSerialNumber: simSerialNumber.value,
|
||||
}).then(res => {
|
||||
paging.value.complete(res.rows);
|
||||
dataList.value = res.rows || [];
|
||||
}).catch(() => {
|
||||
dataList.value = [];
|
||||
});
|
||||
}
|
||||
|
||||
@ -52,12 +54,23 @@ function previewImageFun(idx: any) {
|
||||
onLoad(option => {
|
||||
simSerialNumber.value = option.simSerialNumber;
|
||||
setTimeout(() => {
|
||||
paging.value?.reload(); // 刷新列表
|
||||
loadData();
|
||||
}, 500);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-container {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.scroll-container {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
@ -19,40 +19,40 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import { getDeviceScreenControlApi, lockDeviceScreenApi } from '@/api';
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST;
|
||||
const simSerialNumber = ref();
|
||||
const screenControlInfo = ref<any>({});
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getDeviceScreenControlApi, lockDeviceScreenApi } from '@/api'
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const simSerialNumber = ref()
|
||||
const screenControlInfo = ref<any>({})
|
||||
|
||||
async function handleMachineScreen() {
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: `${screenControlInfo?.value.lockFlag === 1}` ? '解屏中...' : '锁屏中...',
|
||||
});
|
||||
const data = await lockDeviceScreenApi(simSerialNumber.value);
|
||||
fetchDeviceScreen();
|
||||
title: `${screenControlInfo?.value.lockFlag === 1}` ? '解锁中...' : '锁屏中...',
|
||||
})
|
||||
const data = await lockDeviceScreenApi(simSerialNumber.value)
|
||||
fetchDeviceScreen()
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
async function fetchDeviceScreen() {
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
});
|
||||
const data = await getDeviceScreenControlApi(simSerialNumber.value);
|
||||
screenControlInfo.value = data ? data : {};
|
||||
})
|
||||
const data = await getDeviceScreenControlApi(simSerialNumber.value)
|
||||
screenControlInfo.value = data ? data : {}
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
onLoad(option => {
|
||||
simSerialNumber.value = option.simSerialNumber;
|
||||
fetchDeviceScreen();
|
||||
});
|
||||
simSerialNumber.value = option.simSerialNumber
|
||||
fetchDeviceScreen()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<mj-page class="teacher-content">
|
||||
<view v-if="equipmentList.length === 0" class="binding" @click="bindDevice">
|
||||
<!-- <view v-if="equipmentList.length === 0" class="binding">
|
||||
<image class="scan" :src="scanQr" mode=""></image>扫码绑定设备
|
||||
</view>
|
||||
<view v-else class="my_equipment">
|
||||
</view> -->
|
||||
<view class="my_equipment">
|
||||
<view class="header">
|
||||
<text>我的设备</text>
|
||||
<image
|
||||
@ -57,11 +57,15 @@
|
||||
</view>
|
||||
<view class="equipment_item_left">
|
||||
<image :src="i.id === showEquipment.id ? checked : unchecked" mode=""></image>
|
||||
</view> </view
|
||||
></template>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view class="binding" @click="bindDevice">
|
||||
<image class="scan" :src="scanQr" mode=""></image>扫码绑定设备
|
||||
<view class="binding">
|
||||
<view class="scan-bind" @click="scanBind">
|
||||
<image class="scan" :src="scanQr" mode=""></image>扫码绑定
|
||||
</view>
|
||||
<view class="hand-bind" @click="handBind"> 手动绑定 </view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="home_function">
|
||||
@ -72,25 +76,38 @@
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 手动绑定弹框 -->
|
||||
<mj-dialog
|
||||
v-model="showHandBindPopup"
|
||||
title="手动绑定孩子账号"
|
||||
okText="绑定"
|
||||
:ok="confirmHandBind"
|
||||
>
|
||||
<input
|
||||
v-model="childAccount"
|
||||
class="account-input"
|
||||
placeholder="请输入孩子账号"
|
||||
type="text"
|
||||
/>
|
||||
</mj-dialog>
|
||||
</mj-page>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { getParentBindDeviceApi, parentDeviceCurrentLoginApi } from '@/api'
|
||||
import { bindApplyStore } from '@/store'
|
||||
import db from '@/utils/db'
|
||||
|
||||
import { userStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import hud from '@/utils/hud'
|
||||
import router from '@/router/router'
|
||||
import { badgeStore } from '@/store/badge'
|
||||
import { getParentBindDeviceApi, manualBindApi } from '@/api'
|
||||
|
||||
const store = userStore()
|
||||
const { getUserInfo } = store
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
const { getApplyBindInfoList } = bindApplyStore()
|
||||
const { refreshBadge } = badgeStore()
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const scanQr = `${OSS_URL}/iconfont/scan_qr.png`
|
||||
const arrow = `${OSS_URL}/iconfont/down_arrow.png`
|
||||
@ -99,6 +116,10 @@ const unchecked = `${OSS_URL}/iconfont/unchecked.png`
|
||||
const showAllDevice = ref(false)
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
|
||||
// 手动绑定弹框相关
|
||||
const showHandBindPopup = ref(false)
|
||||
const childAccount = ref('')
|
||||
|
||||
const functionList = reactive([
|
||||
{
|
||||
name: '一键锁屏',
|
||||
@ -114,20 +135,20 @@ const functionList = reactive([
|
||||
developing: false,
|
||||
type: 1,
|
||||
},
|
||||
{
|
||||
name: '时间管控',
|
||||
bg: `${OSS_URL}/urm/home_time_control.png`,
|
||||
developingBg: '',
|
||||
developing: false,
|
||||
type: 2,
|
||||
},
|
||||
{
|
||||
name: '视频通话',
|
||||
bg: `${OSS_URL}/urm/home_video_call.png`,
|
||||
developingBg: `${OSS_URL}/urm/home_video_developing.png`,
|
||||
developing: true,
|
||||
type: 3,
|
||||
},
|
||||
// {
|
||||
// name: '时间管控',
|
||||
// bg: `${OSS_URL}/urm/home_time_control.png`,
|
||||
// developingBg: '',
|
||||
// developing: false,
|
||||
// type: 2,
|
||||
// },
|
||||
// {
|
||||
// name: '视频通话',
|
||||
// bg: `${OSS_URL}/urm/home_video_call.png`,
|
||||
// developingBg: `${OSS_URL}/urm/home_video_developing.png`,
|
||||
// developing: true,
|
||||
// type: 3,
|
||||
// },
|
||||
])
|
||||
const equipmentList = ref([])
|
||||
const showEquipment = ref()
|
||||
@ -137,10 +158,40 @@ function chooseEquipment(i) {
|
||||
showEquipment.value = i
|
||||
}
|
||||
|
||||
function bindDevice() {
|
||||
// 扫码绑定
|
||||
function scanBind() {
|
||||
router.navigateTo('/pages/home/bindDevice/index')
|
||||
}
|
||||
|
||||
// 手动绑定
|
||||
function handBind() {
|
||||
showHandBindPopup.value = true
|
||||
childAccount.value = ''
|
||||
}
|
||||
|
||||
// 确认手动绑定
|
||||
function confirmHandBind() {
|
||||
if (!childAccount.value.trim()) {
|
||||
hud.error('请输入孩子账号')
|
||||
return
|
||||
}
|
||||
|
||||
hud.load({
|
||||
task: async () => {
|
||||
const res = Number(await manualBindApi(childAccount.value))
|
||||
if (res === 1) {
|
||||
hud.success('绑定成功')
|
||||
} else if (res === 0) {
|
||||
hud.error('绑定失败')
|
||||
} else if (res === 2) {
|
||||
hud.success('已向管理员发送绑定请求')
|
||||
}
|
||||
showHandBindPopup.value = false
|
||||
},
|
||||
option: '绑定',
|
||||
})
|
||||
}
|
||||
|
||||
// 底部点击
|
||||
function change(i: any) {
|
||||
if (equipmentList.value.length === 0) {
|
||||
@ -198,43 +249,17 @@ async function getParentBindDevice() {
|
||||
equipmentList.value = data.rows
|
||||
showEquipment.value = data.rows[0]
|
||||
}
|
||||
// for (let i in data.rows) {
|
||||
// const _r = await parentDeviceCurrentLoginApi(data.rows[i].id)
|
||||
// equipmentList.value.push({
|
||||
// ...data.rows[i],
|
||||
// curDeviceUserName: _r.curDeviceUserName,
|
||||
// curDeviceUserAvatar: _r.curDeviceUserAvatar,
|
||||
// })
|
||||
// }
|
||||
// showEquipment.value = data.rows?.length > 0 ? equipmentList.value[0] : {}
|
||||
},
|
||||
})
|
||||
}
|
||||
// 处理红点逻辑
|
||||
async function handleTabBarBadge() {
|
||||
await getApplyBindInfoList()
|
||||
const hasApplyMsg = db.get('applyBindMsg')
|
||||
|
||||
if (hasApplyMsg) {
|
||||
uni.setTabBarBadge({
|
||||
index: 3, // "我的"页面在tabBar中的索引
|
||||
text: '●'
|
||||
})
|
||||
} else {
|
||||
uni.removeTabBarBadge({
|
||||
index: 3
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
handleTabBarBadge()
|
||||
refreshBadge()
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
await getUserInfo()
|
||||
getParentBindDevice()
|
||||
handleTabBarBadge()
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -248,7 +273,7 @@ onMounted(async () => {
|
||||
.binding {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 120rpx;
|
||||
background-color: #fff;
|
||||
@ -258,11 +283,19 @@ onMounted(async () => {
|
||||
font-size: 34rpx;
|
||||
font-weight: 500;
|
||||
line-height: 52rpx;
|
||||
|
||||
.scan {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 10rpx;
|
||||
.scan-bind {
|
||||
.scan {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
.scan-bind,
|
||||
.hand-bind {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
@ -378,4 +411,21 @@ onMounted(async () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 手动绑定弹框样式
|
||||
|
||||
.account-input {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8rpx;
|
||||
padding: 0 20rpx;
|
||||
font-size: 28rpx;
|
||||
box-sizing: border-box;
|
||||
color: #333;
|
||||
|
||||
&::placeholder {
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,143 +1,140 @@
|
||||
<template>
|
||||
<view class="about_mine">
|
||||
<z-paging
|
||||
ref="paging"
|
||||
v-model="dataList"
|
||||
:paging-style="{ margin: '402rpx 30rpx 0 30rpx' }"
|
||||
:style="{
|
||||
height: `calc(100% - 532rpx - 120rpx - 52rpx)`,
|
||||
}"
|
||||
@query="queryList"
|
||||
>
|
||||
<template #top>
|
||||
<view class="navigate">
|
||||
<text
|
||||
v-for="(i, idx) in navList"
|
||||
:key="idx"
|
||||
:class="{ navigate_item: true, active: activeNav.type === i.type }"
|
||||
@click="swicthNav(i)"
|
||||
>{{ i.title }}</text
|
||||
>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:empty>
|
||||
<view class="empty_box">
|
||||
<view class="container">
|
||||
<view class="navigate">
|
||||
<text
|
||||
v-for="(i, idx) in navList"
|
||||
:key="idx"
|
||||
:class="{ navigate_item: true, active: activeNav.type === i.type }"
|
||||
@click="switchNav(i)"
|
||||
>{{ i.title }}</text
|
||||
>
|
||||
</view>
|
||||
<scroll-view scroll-y class="scroll-container">
|
||||
<view v-if="noData" class="empty_box">
|
||||
<image :src="empty" mode="" class="empty"></image>
|
||||
<view class="tip">您还没有绑定任何数据,快去扫码绑定吧~</view>
|
||||
<button class="btn" @click="handleBindDevice">扫码绑定</button>
|
||||
</view>
|
||||
</template>
|
||||
<view class="content">
|
||||
<!-- 我的孩子 -->
|
||||
<template v-if="activeNav.type === 1">
|
||||
<view
|
||||
v-for="(i, idx) in dataList"
|
||||
:key="idx"
|
||||
class="children"
|
||||
@click="handleDetialPage(activeNav.type, i)"
|
||||
>
|
||||
<image
|
||||
:src="i?.childAvatar ? i?.childAvatar : defaultAvatar"
|
||||
mode=""
|
||||
class="children_avatar"
|
||||
></image>
|
||||
<view class="children-info">
|
||||
<view class="name_vip">
|
||||
<text class="name">{{ i.childName }}</text>
|
||||
<image
|
||||
v-if="i.currentLevel"
|
||||
:src="`${OSS_URL}/iconfont/VIP/VIP_${i.currentLevel}.png`"
|
||||
class="vip"
|
||||
/>
|
||||
</view>
|
||||
<view class="time">
|
||||
有效期至:{{ i.vipEndTime ? dayjs(i.vipEndTime).format('YYYY.MM.DD') : '-' }}
|
||||
|
||||
<view v-else class="content">
|
||||
<!-- 我的孩子 -->
|
||||
<template v-if="activeNav.type === nav_child">
|
||||
<view
|
||||
v-for="(i, idx) in childList"
|
||||
:key="idx"
|
||||
class="children"
|
||||
@click="handleDetailPage(activeNav.type, i)"
|
||||
>
|
||||
<image
|
||||
:src="i?.childAvatar ? i?.childAvatar : defaultAvatar"
|
||||
mode=""
|
||||
class="children_avatar"
|
||||
></image>
|
||||
<view class="children-info">
|
||||
<view class="name_vip">
|
||||
<text class="name">{{ i.childName }}</text>
|
||||
<image
|
||||
v-if="i.currentLevel"
|
||||
:src="`${OSS_URL}/iconfont/VIP/VIP_${i.currentLevel}.png`"
|
||||
class="vip"
|
||||
/>
|
||||
</view>
|
||||
<view class="time">
|
||||
有效期至:{{ i.vipEndTime ? dayjs(i.vipEndTime).format('YYYY.MM.DD') : '-' }}
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view v-if="i.havePurchasedInspector" class="service">
|
||||
<wd-button class="btn" :round="false" @click.stop="toMySupervisionService(i)"
|
||||
>督学服务</wd-button
|
||||
>
|
||||
</view> -->
|
||||
</view>
|
||||
<view v-if="i.havePurchasedInspector" class="service">
|
||||
<wd-button class="btn" :round="false" @click.stop="toMySupervisionService(i)"
|
||||
>督学服务</wd-button
|
||||
>
|
||||
</template>
|
||||
<!-- 我的设备 -->
|
||||
<template v-else>
|
||||
<view
|
||||
v-for="(i, idx) in deviceList"
|
||||
:key="idx"
|
||||
class="equipment"
|
||||
@click="handleDetailPage(activeNav.type, i)"
|
||||
>
|
||||
序列号:<text class="serial">{{ i.simSerialNumber }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<!-- 我的设备 -->
|
||||
<template v-else>
|
||||
<view
|
||||
v-for="(i, idx) in dataList"
|
||||
:key="idx"
|
||||
class="equipment"
|
||||
@click="handleDetialPage(activeNav.type, i)"
|
||||
>
|
||||
序列号:<text class="serial">{{ i.simSerialNumber }}</text>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</z-paging>
|
||||
</template>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, onMounted, nextTick } from 'vue'
|
||||
import { reactive, ref, onMounted, computed } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { getParentBindChildApi, getParentBindDeviceApi } from '@/api'
|
||||
import { userStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { getCache } from '@/utils'
|
||||
import router from '@/router/router'
|
||||
import type { ChildrenType, DeviceType } from './interface'
|
||||
import dayjs from 'dayjs'
|
||||
import db from '@/utils/db'
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
const empty = `${OSS_URL}/empty.png`
|
||||
|
||||
const nav_child = 1
|
||||
const nav_device = 2
|
||||
// 导航
|
||||
const activeNav = ref({
|
||||
title: '我的孩子',
|
||||
type: 1,
|
||||
type: nav_child,
|
||||
})
|
||||
|
||||
const navList = reactive([
|
||||
{
|
||||
title: '我的孩子',
|
||||
type: 1,
|
||||
type: nav_child,
|
||||
},
|
||||
{
|
||||
title: '我的设备',
|
||||
type: 2,
|
||||
type: nav_device,
|
||||
},
|
||||
])
|
||||
const dataList = ref<any[]>([])
|
||||
const paging = ref(null)
|
||||
const childList = ref<any[]>([])
|
||||
const deviceList = ref<any[]>([])
|
||||
|
||||
function swicthNav(i) {
|
||||
paging.value.reload(true)
|
||||
const noData = computed(() => {
|
||||
return (
|
||||
(activeNav.value.type === nav_child && childList.value.length === 0) ||
|
||||
(activeNav.value.type === nav_device && deviceList.value.length === 0)
|
||||
)
|
||||
})
|
||||
|
||||
function switchNav(i: any) {
|
||||
activeNav.value = i
|
||||
loadData()
|
||||
}
|
||||
|
||||
const queryList = (pageNo: number, pageSize: number) => {
|
||||
if (activeNav.value.type === 1) {
|
||||
getParentBindChildApi({ parentId: userInfo.value.id, current: pageNo, size: pageSize })
|
||||
const loadData = () => {
|
||||
if (activeNav.value.type === nav_child) {
|
||||
getParentBindChildApi({ parentId: userInfo.value.id, current: 1, size: 1000 })
|
||||
.then(res => {
|
||||
paging.value.complete(res.rows)
|
||||
childList.value = res.rows || []
|
||||
})
|
||||
.catch(res => {
|
||||
paging.value.complete(false)
|
||||
childList.value = []
|
||||
})
|
||||
} else {
|
||||
getParentBindDeviceApi({ parentId: userInfo.value.id, current: pageNo, size: pageSize })
|
||||
getParentBindDeviceApi({ parentId: userInfo.value.id, current: 1, size: 1000 })
|
||||
.then(res => {
|
||||
paging.value.complete(res.rows)
|
||||
deviceList.value = res.rows || []
|
||||
})
|
||||
.catch(res => {
|
||||
paging.value.complete(false)
|
||||
deviceList.value = []
|
||||
})
|
||||
}
|
||||
}
|
||||
// 进入详情
|
||||
function handleDetialPage(type: number, obj: any) {
|
||||
function handleDetailPage(type: number, obj: any) {
|
||||
let details = encodeURIComponent(JSON.stringify(obj))
|
||||
switch (type) {
|
||||
case 1:
|
||||
@ -167,20 +164,21 @@ const toMySupervisionService = child => {
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
if (paging.value) {
|
||||
paging.value.refresh()
|
||||
}
|
||||
loadData()
|
||||
})
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
onMounted(() => {})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.about_mine {
|
||||
// .paging_box {
|
||||
// height: calc(100vh - 532rpx - 120rpx - 52rpx);
|
||||
// }
|
||||
:deep(.zp-empty-view-center) {
|
||||
display: block;
|
||||
.container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.scroll-container {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
.empty_box {
|
||||
display: flex;
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<mj-page class="page">
|
||||
<BackBar title="绑定申请" />
|
||||
<Empty v-if="bindApplyList?.length === 0" content="暂无申请数据哦~" />
|
||||
<template v-else>
|
||||
@ -85,67 +85,71 @@
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</template>
|
||||
</view>
|
||||
</mj-page>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import type { BindApplyItemType } from '../interface';
|
||||
import { adminApproval } from '@/api';
|
||||
import { ref, onMounted, nextTick } from 'vue'
|
||||
import type { BindApplyItemType } from '../interface'
|
||||
import { adminApproval } from '@/api'
|
||||
|
||||
import { maskPhone, useRelation, debounce } from '@/hooks';
|
||||
import Empty from '@/components/Empty/index.vue';
|
||||
import { bindApplyStore } from '@/store';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useRelation, debounce } from '@/hooks'
|
||||
import Empty from '@/components/Empty/index.vue'
|
||||
import { bindApplyStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import hud from '@/utils/hud'
|
||||
|
||||
const { bindApplyList } = storeToRefs(bindApplyStore());
|
||||
const { getApplyBindInfoList } = bindApplyStore();
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST;
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`;
|
||||
const current = ref(0);
|
||||
const { bindApplyList } = storeToRefs(bindApplyStore())
|
||||
const { getApplyBindInfoList } = bindApplyStore()
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
const current = ref(0)
|
||||
|
||||
const showData = ref<BindApplyItemType>();
|
||||
const showData = ref<BindApplyItemType>()
|
||||
|
||||
async function handleBtnFn(e: boolean, id: string) {
|
||||
adminApproval({
|
||||
approvalFlag: e,
|
||||
id: id,
|
||||
}).then(async res => {
|
||||
uni.showToast({
|
||||
title: '提交成功!',
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
});
|
||||
await getApplyBindInfoList();
|
||||
if (current.value >= bindApplyList.value.length) {
|
||||
current.value = bindApplyList.value.length > 0 ? bindApplyList.value.length - 1 : 0;
|
||||
}
|
||||
showData.value = bindApplyList.value.length > 0 ? bindApplyList.value[current.value - 1] : {};
|
||||
});
|
||||
const option = e ? '同意' : '拒绝'
|
||||
hud.confirmLoad(`确定【${option}】绑定?`, {
|
||||
task: async () => {
|
||||
await adminApproval({
|
||||
approvalFlag: e,
|
||||
id: id,
|
||||
})
|
||||
await getApplyBindInfoList()
|
||||
await nextTick()
|
||||
if (current.value >= bindApplyList.value.length) {
|
||||
current.value = bindApplyList.value.length > 0 ? bindApplyList.value.length - 1 : 0
|
||||
}
|
||||
showData.value = bindApplyList.value.length > 0 ? bindApplyList.value[current.value - 1] : {}
|
||||
},
|
||||
option,
|
||||
hideSuccess: false,
|
||||
})
|
||||
}
|
||||
const subFun = debounce(handleBtnFn, 500);
|
||||
const subFun = debounce(handleBtnFn, 500)
|
||||
function switchPage(type) {
|
||||
switch (type) {
|
||||
case 'pre':
|
||||
if (current.value > 0) {
|
||||
current.value -= 1;
|
||||
showData.value = bindApplyList.value[current.value];
|
||||
current.value -= 1
|
||||
showData.value = bindApplyList.value[current.value]
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'next':
|
||||
if (current.value < bindApplyList.value.length - 1) {
|
||||
current.value += 1;
|
||||
showData.value = bindApplyList.value[current.value];
|
||||
current.value += 1
|
||||
showData.value = bindApplyList.value[current.value]
|
||||
}
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await getApplyBindInfoList();
|
||||
await getApplyBindInfoList()
|
||||
await nextTick()
|
||||
|
||||
showData.value = bindApplyList.value.length > 0 ? bindApplyList.value[0] : {};
|
||||
});
|
||||
showData.value = bindApplyList.value.length > 0 ? bindApplyList.value[0] : {}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -1,40 +1,35 @@
|
||||
<template>
|
||||
<view class="patriarch_list">
|
||||
<z-paging
|
||||
ref="paging"
|
||||
v-model="dataList"
|
||||
:paging-style="{ margin: `${top}rpx 30rpx 0 30rpx` }"
|
||||
@query="queryList"
|
||||
>
|
||||
<template #top>
|
||||
<view class="title">绑定家长</view>
|
||||
</template>
|
||||
<template v-slot:empty>
|
||||
<view class="empty_box">
|
||||
<view class="container" :style="{ margin: `${top}rpx 30rpx 0 30rpx` }">
|
||||
<view class="title">绑定家长</view>
|
||||
<scroll-view scroll-y class="scroll-container">
|
||||
<view v-if="dataList.length === 0" class="empty_box">
|
||||
<Empty content="暂无绑定家长数据哦~" />
|
||||
</view>
|
||||
</template>
|
||||
<view v-for="(i, idx) in dataList" :key="idx" class="patriarch">
|
||||
<view class="left">
|
||||
<image
|
||||
:src="i.parentAvatar ? i.parentAvatar : defaultAvatar"
|
||||
mode=""
|
||||
class="patriarch_avatar"
|
||||
></image>
|
||||
<view>
|
||||
<view class="header">
|
||||
<view class="name">{{ i.parentName }}</view>
|
||||
<view class="tag">
|
||||
<text v-if="i.adminFlag === 1" class="tag_item manager">管理员</text>
|
||||
<text class="tag_item relation">{{ useRelation1[i.identityType] }}</text>
|
||||
<view v-else class="content">
|
||||
<view v-for="(i, idx) in dataList" :key="idx" class="patriarch">
|
||||
<view class="left">
|
||||
<image
|
||||
:src="i.parentAvatar ? i.parentAvatar : defaultAvatar"
|
||||
mode=""
|
||||
class="patriarch_avatar"
|
||||
></image>
|
||||
<view>
|
||||
<view class="header">
|
||||
<view class="name">{{ i.parentName }}</view>
|
||||
<view class="tag">
|
||||
<text v-if="i.adminFlag === 1" class="tag_item manager">管理员</text>
|
||||
<text class="tag_item relation">{{ useRelation1[i.identityType as keyof typeof useRelation1] }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="phone"> {{ maskPhone(i.parentPhone) }} </view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="phone"> {{ maskPhone(i.parentPhone) }} </view>
|
||||
<view class="right"><button class="unbind_btn" @click="handleUnbind(i as any)">解绑</button></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right"><button class="unbind_btn" @click="handleUnbind(i)">解绑</button></view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<CustomPopup
|
||||
v-model="showCustomPopup"
|
||||
titleText="温馨提示"
|
||||
@ -76,31 +71,30 @@ const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
const showCustomPopup = ref(false)
|
||||
const unbind = ref<ChildrenType | DeviceType>()
|
||||
const dataList = ref<ChildrenType[] | DeviceType[]>()
|
||||
const paging = ref(null)
|
||||
const dataList = ref<ChildrenType[] | DeviceType[]>([])
|
||||
|
||||
const detailInfo = ref<ChildrenType & DeviceType>()
|
||||
|
||||
const queryList = (pageNo: number, pageSize: number) => {
|
||||
const loadData = () => {
|
||||
if (props.type === 1) {
|
||||
getParentBindChildApi({ childId: detailInfo.value.childId, current: pageNo, size: pageSize })
|
||||
getParentBindChildApi({ childId: detailInfo.value.childId, current: 1, size: 1000 })
|
||||
.then(res => {
|
||||
paging.value.complete(res.rows)
|
||||
dataList.value = res.rows || []
|
||||
})
|
||||
.catch(res => {
|
||||
paging.value.complete(false)
|
||||
dataList.value = []
|
||||
})
|
||||
} else {
|
||||
getParentBindDeviceApi({
|
||||
simSerialNumber: detailInfo.value.simSerialNumber,
|
||||
current: pageNo,
|
||||
size: pageSize,
|
||||
current: 1,
|
||||
size: 1000,
|
||||
})
|
||||
.then(res => {
|
||||
paging.value.complete(res.rows)
|
||||
dataList.value = res.rows || []
|
||||
})
|
||||
.catch(res => {
|
||||
paging.value.complete(false)
|
||||
dataList.value = []
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -116,25 +110,40 @@ async function handleConfirmPopup() {
|
||||
})
|
||||
if (props.type === 1) {
|
||||
await childUnBoundParentApi({
|
||||
parentId: unbind.value.parentId,
|
||||
parentId: (unbind.value as any).parentId,
|
||||
childId: detailInfo.value.childId,
|
||||
})
|
||||
} else {
|
||||
await parentUnBoundDeviceApi({
|
||||
parentId: unbind.value.parentId,
|
||||
parentId: (unbind.value as any).parentId,
|
||||
simSerialNumber: detailInfo.value.simSerialNumber,
|
||||
})
|
||||
}
|
||||
uni.hideLoading()
|
||||
paging.value.reload()
|
||||
loadData()
|
||||
showCustomPopup.value = false
|
||||
}
|
||||
onLoad(option => {
|
||||
detailInfo.value = JSON.parse(decodeURIComponent(option.details))
|
||||
loadData()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.patriarch_list {
|
||||
height: 100vh;
|
||||
|
||||
.container {
|
||||
height: calc(100vh - 445rpx);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.scroll-container {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.empty_box {
|
||||
.empty {
|
||||
margin-top: 0 !important;
|
||||
|
@ -1,36 +1,21 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<PatriarchCard />
|
||||
<AbountMine />
|
||||
|
||||
<AboutMine />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { bindApplyStore } from '@/store'
|
||||
import db from '@/utils/db'
|
||||
|
||||
import PatriarchCard from './patriarchCard.vue';
|
||||
import AbountMine from './aboutMine.vue';
|
||||
import PatriarchCard from './patriarchCard.vue'
|
||||
import AboutMine from './aboutMine.vue'
|
||||
import { badgeStore } from '@/store/badge'
|
||||
|
||||
const { getApplyBindInfoList } = bindApplyStore()
|
||||
const { refreshBadge } = badgeStore()
|
||||
|
||||
onShow(async () => {
|
||||
// 获取绑定申请信息并设置红点
|
||||
await getApplyBindInfoList()
|
||||
const hasApplyMsg = db.get('applyBindMsg')
|
||||
|
||||
if (hasApplyMsg) {
|
||||
uni.setTabBarBadge({
|
||||
index: 3, // "我的"页面在tabBar中的索引
|
||||
text: '●'
|
||||
})
|
||||
} else {
|
||||
uni.removeTabBarBadge({
|
||||
index: 3
|
||||
})
|
||||
}
|
||||
refreshBadge()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
@ -14,7 +14,9 @@
|
||||
<view v-if="i.show" class="function_item" @click="handleJump(i)">
|
||||
<view class="photo_box">
|
||||
<image :src="i.photo" mode="" class="photo"></image>
|
||||
<text v-if="i.title === '绑定申请' && getCache('applyBindMsg')" class="unread"></text>
|
||||
<text v-if="i.id === id_apply && bindApplyList?.length" class="unread">
|
||||
{{ bindApplyList?.length }}
|
||||
</text>
|
||||
</view>
|
||||
<text class="title">{{ i.title }}</text>
|
||||
</view>
|
||||
@ -25,24 +27,25 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { userStore } from '@/store'
|
||||
import { bindApplyStore, userStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { getCache } from '@/utils'
|
||||
import router from '@/router/router'
|
||||
import db from '@/utils/db'
|
||||
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
const { bindApplyList } = storeToRefs(bindApplyStore())
|
||||
const id_apply = 2
|
||||
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
const list = ref([
|
||||
// {
|
||||
// title: '扫码绑定',
|
||||
// photo: `${OSS_URL}/urm/my_scan_binding.png`,
|
||||
// show: true,
|
||||
// url: '/pages/home/bindDevice/index',
|
||||
// },
|
||||
{
|
||||
title: '扫码绑定',
|
||||
photo: `${OSS_URL}/urm/my_scan_binding.png`,
|
||||
show: true,
|
||||
url: '/pages/home/bindDevice/index',
|
||||
},
|
||||
{
|
||||
id: id_apply,
|
||||
title: '绑定申请',
|
||||
photo: `${OSS_URL}/urm/my_binding_apply.png`,
|
||||
show: true,
|
||||
@ -153,14 +156,19 @@ onMounted(() => {})
|
||||
}
|
||||
|
||||
.unread {
|
||||
$unread-wh: 24rpx;
|
||||
display: block;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
line-height: $unread-wh;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
width: $unread-wh;
|
||||
height: $unread-wh;
|
||||
font-size: $unread-wh - 6rpx;
|
||||
background-color: rgba(255, 40, 40, 1);
|
||||
border-radius: 50%;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
|
26
src/store/badge.ts
Normal file
26
src/store/badge.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { bindApplyStore } from './bindApply'
|
||||
|
||||
export const badgeStore = defineStore('badge', () => {
|
||||
const { getApplyBindInfoList } = bindApplyStore()
|
||||
|
||||
async function refreshBadge() {
|
||||
// 我的
|
||||
const mineIndex = 2
|
||||
const size = (await getApplyBindInfoList())?.length
|
||||
if (size) {
|
||||
uni.setTabBarBadge({
|
||||
index: mineIndex,
|
||||
text: `${size}`,
|
||||
})
|
||||
} else {
|
||||
uni.removeTabBarBadge({
|
||||
index: mineIndex,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
refreshBadge,
|
||||
}
|
||||
})
|
@ -1,26 +1,24 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { setCache } from '@/utils'
|
||||
import { applyBindInfoListApi } from '@/api'
|
||||
import type { BindApplyItemType } from '@/pages/mine/interface'
|
||||
import db from '@/utils/db'
|
||||
|
||||
export const bindApplyStore = defineStore('bindApplyStore', () => {
|
||||
const bindApplyList = ref<BindApplyItemType[]>()
|
||||
const applyBindMsg = ref(false)
|
||||
// 未处理的绑定申请列表
|
||||
const getApplyBindInfoList = async () => {
|
||||
try {
|
||||
const data = await applyBindInfoListApi()
|
||||
bindApplyList.value = data
|
||||
if (bindApplyList.value.length === 0) {
|
||||
db.set('applyBindMsg', false)
|
||||
} else {
|
||||
db.set('applyBindMsg', true)
|
||||
}
|
||||
applyBindMsg.value = data?.length
|
||||
return data
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
return {
|
||||
applyBindMsg,
|
||||
bindApplyList,
|
||||
getApplyBindInfoList,
|
||||
}
|
||||
|
@ -41,23 +41,23 @@ function _toast(type: string, msg: string, duration = default_duration) {
|
||||
})
|
||||
}
|
||||
|
||||
export async function info(text: string, duration?: number) {
|
||||
async function info(text: string, duration?: number) {
|
||||
return _toast('info', text, duration)
|
||||
}
|
||||
|
||||
export async function error(text: string, duration?: number) {
|
||||
async function error(text: string, duration?: number) {
|
||||
return _toast('error', text, duration)
|
||||
}
|
||||
|
||||
export async function warn(text: string, duration?: number) {
|
||||
async function warn(text: string, duration?: number) {
|
||||
return _toast('warn', text, duration)
|
||||
}
|
||||
|
||||
export async function success(text: string, duration?: number) {
|
||||
async function success(text: string, duration?: number) {
|
||||
return _toast('success', text, duration)
|
||||
}
|
||||
|
||||
export async function primary(text: string, duration?: number) {
|
||||
async function primary(text: string, duration?: number) {
|
||||
return _toast('primary', text, duration)
|
||||
}
|
||||
|
||||
@ -69,6 +69,17 @@ export function dialog(options: DialogOptions) {
|
||||
dict.callFn(dialog_dict_key, options)
|
||||
}
|
||||
|
||||
export function confirmLoad(content: any, options: LoadOptions) {
|
||||
dialog({
|
||||
title: '确认',
|
||||
content,
|
||||
ok: async (hide: any) => {
|
||||
hide()
|
||||
load(options)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function hide() {
|
||||
dict.callFn(hide_dict_key)
|
||||
}
|
||||
@ -136,4 +147,5 @@ export default {
|
||||
primary,
|
||||
hide,
|
||||
dialog,
|
||||
confirmLoad,
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user