feat:微信支付
This commit is contained in:
parent
81c2f77434
commit
c44b29b11c
@ -1,15 +1,15 @@
|
||||
export * from './global';
|
||||
export * from './login';
|
||||
export * from './modules/warranty';
|
||||
export * from './modules/awardManage';
|
||||
export * from './modules/taskManage';
|
||||
export * from './modules/bindDevice';
|
||||
export * from './modules/parent';
|
||||
export * from './modules/mySupervisionService';
|
||||
export * from './modules/bindDevice';
|
||||
export * from './modules/mine';
|
||||
export * from './modules/academicReport';
|
||||
export * from './modules/deviceScreenshotRecord';
|
||||
export * from './modules/inviteBind';
|
||||
export * from './modules/home';
|
||||
export * from './modules/applicationManagement';
|
||||
export * from './global'
|
||||
export * from './login'
|
||||
export * from './modules/warranty'
|
||||
export * from './modules/awardManage'
|
||||
export * from './modules/taskManage'
|
||||
export * from './modules/bindDevice'
|
||||
export * from './modules/parent'
|
||||
export * from './modules/mySupervisionService'
|
||||
export * from './modules/bindDevice'
|
||||
export * from './modules/mine'
|
||||
export * from './modules/academic-report'
|
||||
export * from './modules/deviceScreenshotRecord'
|
||||
export * from './modules/inviteBind'
|
||||
export * from './modules/home'
|
||||
export * from './modules/app-mgr'
|
||||
|
@ -1,3 +1,4 @@
|
||||
import router from '@/router/router'
|
||||
import { http } from './request/request'
|
||||
/**
|
||||
* 手机号授权
|
||||
@ -50,7 +51,14 @@ export const wxLoginApi = async data =>
|
||||
* 获取用户信息
|
||||
* @param data 请求参数
|
||||
*/
|
||||
export const getUserInfoApi = async () => await http.get<any>('/sysUser/selectUser')
|
||||
export const getUserInfoApi = async () => {
|
||||
const data = await http.get<any>('/sysUser/selectUser')
|
||||
if (!data?.id) {
|
||||
router.toLogin()
|
||||
return undefined
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户信息
|
||||
|
@ -1,11 +1,17 @@
|
||||
import { http } from '../request/request'
|
||||
|
||||
/**
|
||||
* 查询学员学习数据
|
||||
*/
|
||||
export async function getStudentStudyDataApi(data: any) {
|
||||
return await http.get<any>('/sysUser/queryParentBindChildInfo', data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 学情报告-学科目录
|
||||
* @param data 请求参数
|
||||
*/
|
||||
export const subjectApi = async (gradeId: string) =>
|
||||
await http.get<any>(`/subject/list/${gradeId}`)
|
||||
export const subjectApi = async (gradeId: string) => await http.get<any>(`/subject/list/${gradeId}`)
|
||||
|
||||
/**
|
||||
* 学情报告-学习时长统计
|
@ -2,7 +2,7 @@ import { http } from '../request/request'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { getCache } from '@/utils'
|
||||
import db from '@/utils/db'
|
||||
import { userStore } from '@/store'
|
||||
import { useUserStore } from '@/store'
|
||||
|
||||
// 课表日历
|
||||
export const getScheduleList = async (data?: Record<string, any>): Promise<any> =>
|
||||
@ -64,7 +64,7 @@ export const getUserInfo = async (data?: Record<string, any>): Promise<any> =>
|
||||
await http.get<any>('/phone/inspectorTeacher/getCurrentTeacher')
|
||||
// 文件上传
|
||||
export const uploadFile = async (file): Promise<any> => {
|
||||
const { token } = storeToRefs(userStore())
|
||||
const { token } = storeToRefs(useUserStore())
|
||||
|
||||
const mergerToken = token.value
|
||||
|
||||
|
@ -4,15 +4,23 @@ import { http } from '../request/request'
|
||||
* 家长绑定的孩子
|
||||
* @param params 请求参数
|
||||
*/
|
||||
export const getParentBindChildApi = async (params: any) =>
|
||||
await http.get<any>('/parentBindChild/list', params)
|
||||
export const getParentBindChildApi = async (params: any) => {
|
||||
if (!params.size) {
|
||||
params.size = -1
|
||||
}
|
||||
return await http.get<any>('/parentBindChild/list', params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 家长绑定的设备
|
||||
* @param params 请求参数
|
||||
*/
|
||||
export const getParentBindDeviceApi = async (params: any) =>
|
||||
await http.get<any>('/parentBindDevice/list', params)
|
||||
export const getParentBindDeviceApi = async (params: any) => {
|
||||
if (!params.size) {
|
||||
params.size = -1
|
||||
}
|
||||
return await http.get<any>('/parentBindDevice/list', params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的孩子-绑定的家长
|
||||
@ -46,12 +54,10 @@ export const parentDeviceCurrentLoginApi = async (id: string) =>
|
||||
* 设备管理-绑定申请列表
|
||||
* @param params 请求参数
|
||||
*/
|
||||
export const applyBindInfoListApi = async () =>
|
||||
await http.get<any>('/parentBind/applyInfoList')
|
||||
export const applyBindInfoListApi = async () => await http.get<any>('/parentBind/applyInfoList')
|
||||
|
||||
/**
|
||||
* 设备管理-当前登录用户是否管理员
|
||||
* @param params 请求参数
|
||||
*/
|
||||
export const userInfoPermitApi = async () =>
|
||||
await http.get<any>('/parentBind/applyInfoPermit')
|
||||
export const userInfoPermitApi = async () => await http.get<any>('/parentBind/applyInfoPermit')
|
||||
|
@ -1,9 +1,18 @@
|
||||
import { http } from '../request/request';
|
||||
import { http } from '../request/request'
|
||||
|
||||
export const getChildList = async () => {
|
||||
return await http.get<any>('/inspectorParent/childList');
|
||||
};
|
||||
return await http.get<any>('/inspectorParent/childList')
|
||||
}
|
||||
|
||||
export const getModelList = async () => {
|
||||
return await http.get<any>('/inspectorParent/inspectorModeList');
|
||||
};
|
||||
return await http.get<any>('/inspectorParent/inspectorModeList')
|
||||
}
|
||||
|
||||
// 生成订单
|
||||
export async function createRechargeOrderApi(money: any) {
|
||||
return await http.post<any>('/orderManagement/createParentCoinOrder', {
|
||||
money,
|
||||
orderType: 4,
|
||||
paySubType: 'JSAPI',
|
||||
})
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import router from '@/router/router'
|
||||
import db from '@/utils/db'
|
||||
import toast from '@/utils/hud'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { userStore } from '@/store'
|
||||
import { useUserStore } from '@/store'
|
||||
|
||||
// 请求拦截器
|
||||
export const requestInterceptor = async (options: RequestOptions): Promise<RequestOptions> => {
|
||||
@ -14,7 +14,7 @@ export const requestInterceptor = async (options: RequestOptions): Promise<Reque
|
||||
const header: any = {
|
||||
...options?.header,
|
||||
}
|
||||
const { token } = storeToRefs(userStore())
|
||||
const { token } = storeToRefs(useUserStore())
|
||||
|
||||
// 获取token
|
||||
// 如果有token,添加到请求头
|
||||
|
@ -60,13 +60,13 @@ onMounted(async () => {
|
||||
text: '首页',
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/academicReport/index',
|
||||
pagePath: '/pages/academic-report/index',
|
||||
iconPath: '/static/tabBar/studyReportNo.png',
|
||||
selectedIconPath: '/static/tabBar/studyReport.png',
|
||||
text: '学情报告',
|
||||
},
|
||||
{
|
||||
pagePath: '/pages/applicationManagement/index',
|
||||
pagePath: '/pages/app-mgr/index',
|
||||
iconPath: '/static/tabBar/applicationNo.png',
|
||||
selectedIconPath: '/static/tabBar/application.png',
|
||||
text: '应用管控',
|
||||
@ -92,13 +92,13 @@ onMounted(async () => {
|
||||
// text: '首页',
|
||||
// },
|
||||
// {
|
||||
// pagePath: '/pages/academicReport/index',
|
||||
// pagePath: '/pages/academic-report/index',
|
||||
// iconPath: '/static/tabBar/studyReportNo.png',
|
||||
// selectedIconPath: '/static/tabBar/studyReport.png',
|
||||
// text: '学情报告',
|
||||
// },
|
||||
// {
|
||||
// pagePath: '/pages/applicationManagement/index',
|
||||
// pagePath: '/pages/app-mgr/index',
|
||||
// iconPath: '/static/tabBar/applicationNo.png',
|
||||
// selectedIconPath: '/static/tabBar/application.png',
|
||||
// text: '应用管控',
|
||||
|
44
src/components/mjui/mj-segment/mj-segment.vue
Normal file
44
src/components/mjui/mj-segment/mj-segment.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
defineOptions({ name: 'MjSegment' })
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: any
|
||||
options: {
|
||||
label: string
|
||||
value: any
|
||||
}[]
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: any): void
|
||||
}>()
|
||||
|
||||
const value = computed({
|
||||
get: () => props.modelValue,
|
||||
set: val => {
|
||||
emit('update:modelValue', val)
|
||||
},
|
||||
})
|
||||
|
||||
// 选项
|
||||
const values = ref([] as string[])
|
||||
|
||||
// 点击
|
||||
function click({ index }) {
|
||||
value.value = props.options[index].value
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.options,
|
||||
newVal => {
|
||||
values.value = newVal.map(item => item.label)
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<tui-segmented-control :values="values" @click="click" />
|
||||
</template>
|
@ -18,17 +18,17 @@
|
||||
</report-content-base>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import ColumnChart from '@/pages/academicReport/components/Echart/ColumnChart.vue';
|
||||
import ReportContentBase from '@/pages/inspector/student-detail/components/report-content-base.vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import ColumnChart from '@/pages/academic-report/components/Echart/ColumnChart.vue'
|
||||
import ReportContentBase from '@/pages/inspector/student-detail/components/report-content-base.vue'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
knowledgeGraphStatistics: any;
|
||||
}>();
|
||||
knowledgeGraphStatistics: any
|
||||
}>()
|
||||
|
||||
const data: any = computed(() => {
|
||||
if (!props.knowledgeGraphStatistics) {
|
||||
return {};
|
||||
return {}
|
||||
}
|
||||
return {
|
||||
categories: ['陌生数', '熟悉数', '掌握数'],
|
||||
@ -50,8 +50,8 @@ const data: any = computed(() => {
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.chart_title {
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { useWebSocket } from '@vueuse/core'
|
||||
import { userStore } from '@/store'
|
||||
import { useUserStore } from '@/store'
|
||||
import { ref } from 'vue'
|
||||
import type { UseWebSocketReturn } from '@vueuse/core'
|
||||
|
||||
let SOCKET: UseWebSocketReturn<any>
|
||||
export const useSocket = () => {
|
||||
const { token, userInfo } = userStore()
|
||||
const { token, userInfo } = useUserStore()
|
||||
const inspectorMessage = ref<any>()
|
||||
const inspectorDesktopMessage = ref([])
|
||||
const desktopPath = ref<string>()
|
||||
|
@ -13,13 +13,13 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/academicReport/index",
|
||||
"path": "pages/academic-report/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "学情报告"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/applicationManagement/index",
|
||||
"path": "pages/app-mgr/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "应用管控"
|
||||
}
|
||||
@ -387,7 +387,7 @@
|
||||
"text": "首页"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/academicReport/index",
|
||||
"pagePath": "pages/academic-report/index",
|
||||
"iconPath": "static/tabBar/studyReportNo.png",
|
||||
"selectedIconPath": "static/tabBar/studyReport.png",
|
||||
"text": "学情报告"
|
||||
|
126
src/pages/academic-report/components/childrenBox.vue
Normal file
126
src/pages/academic-report/components/childrenBox.vue
Normal file
@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<view class="single_box children_box">
|
||||
<view class="children">
|
||||
<view class="left">
|
||||
<image
|
||||
:src="showChild?.child?.avatar || defaultAvatar"
|
||||
mode=""
|
||||
class="children_avatar"
|
||||
></image>
|
||||
<view>
|
||||
<view class="name_vip">
|
||||
<text class="name">{{ showChild?.child?.name || '未绑定账号' }}</text>
|
||||
<image
|
||||
v-if="showChild?.child?.currentLevel"
|
||||
:src="`${OSS_URL}/iconfont/VIP/VIP_${showChild?.child?.currentLevel}.png`"
|
||||
class="vip"
|
||||
/>
|
||||
</view>
|
||||
<view class="time">
|
||||
<template v-if="showChild?.child?.vipEndTime">
|
||||
有效期至:{{
|
||||
showChild?.child?.vipEndTime
|
||||
? dayjs(showChild?.child?.vipEndTime).format('YYYY.MM.DD')
|
||||
: '-'
|
||||
}}
|
||||
</template>
|
||||
<template v-else>请先绑定孩子账号</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="list.length > 1">
|
||||
<image
|
||||
:class="{ icon: true, rotate: showAllChildren }"
|
||||
:src="arrow"
|
||||
@click="showAllChildren = !showAllChildren"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<template v-if="showAllChildren">
|
||||
<view
|
||||
v-for="(i, idx) in otherChildrenList"
|
||||
:key="idx"
|
||||
class="children"
|
||||
@click="handleShowChild(i)"
|
||||
>
|
||||
<view class="left">
|
||||
<image :src="i.child?.avatar || defaultAvatar" mode="" class="children_avatar"></image>
|
||||
<view>
|
||||
<view class="name_vip">
|
||||
<text class="name">{{ i.child?.name || '未绑定账号' }}</text>
|
||||
<image
|
||||
v-if="i.child?.currentLevel"
|
||||
:src="`${OSS_URL}/iconfont/VIP/VIP_${i.child?.currentLevel}.png`"
|
||||
class="vip"
|
||||
/>
|
||||
</view>
|
||||
<view class="time">
|
||||
有效期至:{{
|
||||
i.child?.vipEndTime ? dayjs(i.child?.vipEndTime).format('YYYY.MM.DD') : '-'
|
||||
}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<image
|
||||
class="icon checked_icon"
|
||||
:src="
|
||||
checkedId === i.child?.id
|
||||
? `${OSS_URL}/iconfont/checked.png`
|
||||
: `${OSS_URL}/iconfont/unchecked.png`
|
||||
"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
<view class="children_info">
|
||||
<view class="item">
|
||||
乐贝:<text class="level">{{ showChild?.child?.currency || '-' }}</text>
|
||||
</view>
|
||||
<view class="item">
|
||||
钻石:<text class="level">{{ showChild?.child?.diamond || '-' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import type { ChildrenType } from '@/pages/mine/interface'
|
||||
import '../index.scss'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
list: ChildrenType[]
|
||||
showItem: ChildrenType
|
||||
}>(),
|
||||
{
|
||||
list: () => [],
|
||||
showItem: () => ({}) as ChildrenType,
|
||||
},
|
||||
)
|
||||
const emits = defineEmits(['updateShowItem'])
|
||||
const otherChildrenList = computed(() =>
|
||||
props.list.filter(i => i.child?.id !== props.showItem.child?.id),
|
||||
)
|
||||
|
||||
const showChild = computed({
|
||||
get() {
|
||||
return props.showItem
|
||||
},
|
||||
set(newVal) {
|
||||
emits('updateShowItem', newVal)
|
||||
},
|
||||
})
|
||||
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const arrow = `${OSS_URL}/iconfont/down_arrow.png`
|
||||
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
const showAllChildren = ref(false)
|
||||
const checkedId = ref<string>()
|
||||
function handleShowChild(i: ChildrenType) {
|
||||
checkedId.value = i.child?.id
|
||||
setTimeout(() => {
|
||||
showChild.value = i
|
||||
}, 200)
|
||||
}
|
||||
</script>
|
50
src/pages/academic-report/index.vue
Normal file
50
src/pages/academic-report/index.vue
Normal file
@ -0,0 +1,50 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import Empty from '@/components/Empty/index.vue'
|
||||
import ChildrenBox from './components/childrenBox.vue'
|
||||
|
||||
import type { ChildrenType } from '@/pages/mine/interface'
|
||||
import './index.scss'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useBadgeStore } from '@/store/badge'
|
||||
import { useChildStore } from '@/store/child'
|
||||
import hud from '@/utils/hud'
|
||||
import { getStudentStudyDataApi } from '@/api'
|
||||
|
||||
const childStore = useChildStore()
|
||||
const { getChildren } = childStore
|
||||
const { children } = storeToRefs(childStore)
|
||||
const { refreshBadge } = useBadgeStore()
|
||||
|
||||
const empty = ref(false)
|
||||
const showChild = ref<ChildrenType>() // 展示的孩子
|
||||
|
||||
onShow(() => {
|
||||
Promise.all([getChildren(), refreshBadge()])
|
||||
.then(() => {
|
||||
if (!children.value?.length) return
|
||||
showChild.value = children.value[0]
|
||||
})
|
||||
.finally(() => {
|
||||
hud.hide()
|
||||
})
|
||||
|
||||
// 查询学习数据
|
||||
getStudentStudyDataApi({
|
||||
queryType: 1,
|
||||
queryRangeFlag: 1,
|
||||
})
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
hud.loading()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<mj-page class="page">
|
||||
<ChildrenBox :list="children" :showItem="showChild" />
|
||||
<Empty v-if="empty" content="暂无学情报告数据哦~" />
|
||||
</mj-page>
|
||||
</template>
|
@ -1,129 +0,0 @@
|
||||
<template>
|
||||
<view class="single_box children_box">
|
||||
<view class="children">
|
||||
<view class="left">
|
||||
<image
|
||||
:src="showChildren?.childAvatar ? showChildren?.childAvatar : defaultAvatar"
|
||||
mode=""
|
||||
class="children_avatar"
|
||||
></image>
|
||||
<view>
|
||||
<view class="name_vip">
|
||||
<text class="name">{{
|
||||
showChildren?.childName ? showChildren?.childName : '未绑定账号'
|
||||
}}</text>
|
||||
<image
|
||||
v-if="showChildren?.currentLevel"
|
||||
:src="`${OSS_URL}/iconfont/VIP/VIP_${showChildren?.currentLevel}.png`"
|
||||
class="vip"
|
||||
/>
|
||||
</view>
|
||||
<view class="time">
|
||||
<template v-if="showChildren?.vipEndTime">
|
||||
有效期至:{{
|
||||
showChildren?.vipEndTime
|
||||
? dayjs(showChildren?.vipEndTime).format('YYYY.MM.DD')
|
||||
: '-'
|
||||
}}
|
||||
</template>
|
||||
<template v-else>请先绑定孩子账号</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="list.length > 1">
|
||||
<image
|
||||
:class="{ icon: true, rotate: showAllChildren }"
|
||||
:src="arrow"
|
||||
@click="showAllChildren = !showAllChildren"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<template v-if="showAllChildren">
|
||||
<view
|
||||
v-for="(i, idx) in otherChildrenList"
|
||||
:key="idx"
|
||||
class="children"
|
||||
@click="handleShowChildren(i)"
|
||||
>
|
||||
<view class="left">
|
||||
<image
|
||||
:src="i.childAvatar ? i.childAvatar : defaultAvatar"
|
||||
mode=""
|
||||
class="children_avatar"
|
||||
></image>
|
||||
<view>
|
||||
<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>
|
||||
<image
|
||||
class="icon checked_icon"
|
||||
:src="
|
||||
checkedId === i.childId
|
||||
? `${OSS_URL}/iconfont/checked.png`
|
||||
: `${OSS_URL}/iconfont/unchecked.png`
|
||||
"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
<view class="children_info">
|
||||
<view class="item">
|
||||
年级:<text class="level">{{ showChildren?.gradeName || '-' }}</text>
|
||||
</view>
|
||||
<view class="item">
|
||||
等级:<text class="level">{{ showChildren?.expLevel || '-' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import type { ChildrenType } from '@/pages/mine/interface';
|
||||
import '../index.scss';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
list: ChildrenType[];
|
||||
showItem: ChildrenType;
|
||||
}>(),
|
||||
{
|
||||
list: () => [],
|
||||
showItem: () => ({}) as ChildrenType,
|
||||
},
|
||||
);
|
||||
const emits = defineEmits(['updateShowItem']);
|
||||
const otherChildrenList = computed(() =>
|
||||
props.list.filter(i => i.childId !== props.showItem.childId),
|
||||
);
|
||||
|
||||
const showChildren = computed({
|
||||
get() {
|
||||
return props.showItem;
|
||||
},
|
||||
set(newVal) {
|
||||
emits('updateShowItem', newVal);
|
||||
},
|
||||
});
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST;
|
||||
const arrow = `${OSS_URL}/iconfont/down_arrow.png`;
|
||||
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`;
|
||||
const showAllChildren = ref(false);
|
||||
const checkedId = ref<string>();
|
||||
function handleShowChildren(i: ChildrenType) {
|
||||
checkedId.value = i.childId;
|
||||
setTimeout(() => {
|
||||
showChildren.value = i;
|
||||
}, 200);
|
||||
}
|
||||
</script>
|
@ -1,89 +0,0 @@
|
||||
<template>
|
||||
<mj-page class="page">
|
||||
<ChildrenBox
|
||||
:list="childrenList"
|
||||
:showItem="showChildrenInfo"
|
||||
@updateShowItem="handleUpdateShowChild"
|
||||
/>
|
||||
<Empty v-if="empty" content="暂无学情报告数据哦~" />
|
||||
</mj-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import Empty from '@/components/Empty/index.vue'
|
||||
import ChildrenBox from './components/childrenBox.vue'
|
||||
|
||||
import type { ChildrenType } from '@/pages/mine/interface'
|
||||
import type { SubjectType } from './interface'
|
||||
import './index.scss'
|
||||
import { getParentBindChildApi, subjectApi } from '@/api'
|
||||
import { userStore, bindApplyStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import hud from '@/utils/hud'
|
||||
import { badgeStore } from '@/store/badge'
|
||||
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
const { refreshBadge } = badgeStore()
|
||||
|
||||
const childrenList = ref<ChildrenType[]>() // 所有孩子
|
||||
const empty = ref(false)
|
||||
const showChildrenInfo = ref<ChildrenType>() // 展示的孩子
|
||||
const subjectList = ref<SubjectType[]>() // 学科
|
||||
|
||||
const chooseSubject = ref<SubjectType>() // 选中学科
|
||||
|
||||
async function handleUpdateShowChild(val: ChildrenType) {
|
||||
showChildrenInfo.value = val
|
||||
chooseSubject.value = {
|
||||
name: '',
|
||||
pictureUrl: '',
|
||||
subject: '',
|
||||
subjectId: undefined,
|
||||
}
|
||||
try {
|
||||
hud.loading()
|
||||
await getSubject()
|
||||
} finally {
|
||||
hud.hide()
|
||||
}
|
||||
}
|
||||
// 学科选择
|
||||
function tapFilterSubject(i: SubjectType) {
|
||||
chooseSubject.value = i
|
||||
}
|
||||
|
||||
// 孩子列表
|
||||
async function getParentBindChild() {
|
||||
const data = await getParentBindChildApi({ parentId: userInfo.value.id, size: -1 })
|
||||
empty.value = data.rows?.length ? true : false
|
||||
childrenList.value = data.rows
|
||||
showChildrenInfo.value = data.rows?.[0]
|
||||
}
|
||||
// 学科列表
|
||||
async function getSubject() {
|
||||
if (!showChildrenInfo.value?.gradeId) {
|
||||
// hud.error('当前学生无年级,无法查看学情报告')
|
||||
subjectList.value = []
|
||||
return
|
||||
}
|
||||
const data = await subjectApi(showChildrenInfo.value.gradeId)
|
||||
subjectList.value = data
|
||||
chooseSubject.value = data[0]
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
refreshBadge()
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
hud.loading()
|
||||
await getParentBindChild()
|
||||
await getSubject()
|
||||
} finally {
|
||||
hud.hide()
|
||||
}
|
||||
})
|
||||
</script>
|
@ -143,13 +143,13 @@ import { getParentBindDeviceApi, parentDeviceCurrentLoginApi, queryAppRecordApi
|
||||
|
||||
import CustomPopup from '@/components/CustomPopup/index.vue'
|
||||
import Empty from '@/components/Empty/index.vue'
|
||||
import { userStore, bindApplyStore } from '@/store'
|
||||
import { useUserStore, bindApplyStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import db from '@/utils/db'
|
||||
import { badgeStore } from '@/store/badge'
|
||||
import { useBadgeStore } from '@/store/badge'
|
||||
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
const { refreshBadge } = badgeStore()
|
||||
const { userInfo } = storeToRefs(useUserStore())
|
||||
const { refreshBadge } = useBadgeStore()
|
||||
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`
|
@ -108,14 +108,14 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getCurInfo, parentBindAdmin } from '@/api'
|
||||
import { userStore, shareConfigStore } from '@/store'
|
||||
import { useUserStore, shareConfigStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import TipPopup from '@/components/TipPopup/index.vue'
|
||||
import router from '@/router/router'
|
||||
import jWeixin from 'weixin-js-sdk'
|
||||
const { initWeixinShareConfig } = shareConfigStore()
|
||||
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
const { userInfo } = storeToRefs(useUserStore())
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const show = ref(false)
|
||||
|
||||
|
@ -1,113 +1,20 @@
|
||||
<template>
|
||||
<mj-page class="teacher-content">
|
||||
<!-- <view v-if="equipmentList.length === 0" class="binding">
|
||||
<image class="scan" :src="scanQr" mode=""></image>扫码绑定设备
|
||||
</view> -->
|
||||
<view class="my_equipment">
|
||||
<view class="header">
|
||||
<text>我的设备</text>
|
||||
<image
|
||||
v-if="equipmentList.length > 1"
|
||||
:src="arrow"
|
||||
mode=""
|
||||
:class="{ arrow_icon: true, rotate: showAllDevice }"
|
||||
@click="showAllDevice = !showAllDevice"
|
||||
></image>
|
||||
</view>
|
||||
<view v-if="!showAllDevice" class="equipment_item">
|
||||
<view class="equipment_item_right">
|
||||
<view class="avatar">
|
||||
<image
|
||||
:src="
|
||||
showEquipment?.curDeviceUserAvatar
|
||||
? showEquipment?.curDeviceUserAvatar
|
||||
: defaultAvatar
|
||||
"
|
||||
mode=""
|
||||
></image>
|
||||
</view>
|
||||
<view class="right">
|
||||
<text class="nickname">{{
|
||||
showEquipment?.curDeviceUserName ? showEquipment?.curDeviceUserName : '未登录账号'
|
||||
}}</text>
|
||||
<text class="number">序列号:{{ showEquipment?.simSerialNumber }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<template v-else>
|
||||
<view
|
||||
v-for="(i, idx) in equipmentList"
|
||||
:key="idx"
|
||||
class="equipment_item"
|
||||
@click="chooseEquipment(i)"
|
||||
>
|
||||
<view class="equipment_item_right">
|
||||
<view class="avatar">
|
||||
<image
|
||||
:src="i?.curDeviceUserAvatar ? i?.curDeviceUserAvatar : defaultAvatar"
|
||||
mode=""
|
||||
></image>
|
||||
</view>
|
||||
<view class="right">
|
||||
<text class="nickname">{{
|
||||
i?.curDeviceUserName ? i?.curDeviceUserName : '未登录账号'
|
||||
}}</text>
|
||||
<text class="number">序列号:{{ i?.simSerialNumber }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="equipment_item_left">
|
||||
<image :src="i.id === showEquipment.id ? checked : unchecked" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<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">
|
||||
<template v-for="(i, idx) in functionList" :key="idx">
|
||||
<view class="item" @click="change(i)">
|
||||
<image class="item_bg" :src="i.developing ? i.developingBg : i.bg" mode=""></image>
|
||||
</view>
|
||||
</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 { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
|
||||
import { userStore } from '@/store'
|
||||
import { useUserStore } 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'
|
||||
import { useBadgeStore } from '@/store/badge'
|
||||
import { manualBindApi } from '@/api'
|
||||
import { useDeviceStore } from '@/store/device'
|
||||
|
||||
const store = userStore()
|
||||
const { getUserInfo } = store
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
const { refreshBadge } = badgeStore()
|
||||
const { getUserInfo } = useUserStore()
|
||||
const deviceStore = useDeviceStore()
|
||||
const { getDevices } = deviceStore
|
||||
const { devices } = storeToRefs(deviceStore)
|
||||
const { refreshBadge } = useBadgeStore()
|
||||
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`
|
||||
@ -150,12 +57,11 @@ const functionList = reactive([
|
||||
// type: 3,
|
||||
// },
|
||||
])
|
||||
const equipmentList = ref([])
|
||||
const showEquipment = ref()
|
||||
const showDevice = ref()
|
||||
|
||||
// 选择设备
|
||||
function chooseEquipment(i) {
|
||||
showEquipment.value = i
|
||||
function chooseEquipment(i: any) {
|
||||
showDevice.value = i
|
||||
}
|
||||
|
||||
// 扫码绑定
|
||||
@ -194,12 +100,7 @@ function confirmHandBind() {
|
||||
|
||||
// 底部点击
|
||||
function change(i: any) {
|
||||
if (equipmentList.value.length === 0) {
|
||||
// uni.showToast({
|
||||
// title: '扫码绑定设备',
|
||||
// icon: 'none',
|
||||
// duration: 2000,
|
||||
// });
|
||||
if (devices.value.length === 0) {
|
||||
router.navigateTo('/pages/home/bindDevice/index')
|
||||
return
|
||||
}
|
||||
@ -210,7 +111,7 @@ function change(i: any) {
|
||||
router.navigateTo({
|
||||
path: '/pages/home/LockScreen/index',
|
||||
query: {
|
||||
simSerialNumber: showEquipment.value.simSerialNumber,
|
||||
simSerialNumber: showDevice.value.simSerialNumber,
|
||||
},
|
||||
})
|
||||
break
|
||||
@ -219,7 +120,7 @@ function change(i: any) {
|
||||
router.navigateTo({
|
||||
path: '/pages/home/DesktopPreview/index',
|
||||
query: {
|
||||
simSerialNumber: showEquipment.value.simSerialNumber,
|
||||
simSerialNumber: showDevice.value.simSerialNumber,
|
||||
},
|
||||
})
|
||||
break
|
||||
@ -228,7 +129,7 @@ function change(i: any) {
|
||||
router.navigateTo({
|
||||
path: '/pages/home/TimeManagement/index',
|
||||
query: {
|
||||
simSerialNumber: showEquipment.value.simSerialNumber,
|
||||
simSerialNumber: showDevice.value.simSerialNumber,
|
||||
},
|
||||
})
|
||||
break
|
||||
@ -238,31 +139,103 @@ function change(i: any) {
|
||||
break
|
||||
}
|
||||
}
|
||||
// 我的设备
|
||||
async function getParentBindDevice() {
|
||||
hud.load({
|
||||
task: async () => {
|
||||
equipmentList.value = []
|
||||
showEquipment.value = {}
|
||||
const data = await getParentBindDeviceApi({ parentId: userInfo.value.id, size: -1 })
|
||||
if (data.rows?.length > 0) {
|
||||
equipmentList.value = data.rows
|
||||
showEquipment.value = data.rows[0]
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
refreshBadge()
|
||||
Promise.all([getDevices(), refreshBadge()])
|
||||
.then(() => {
|
||||
if (!devices.value?.length) return
|
||||
showDevice.value = devices.value[0]
|
||||
})
|
||||
.finally(() => {
|
||||
hud.hide()
|
||||
})
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
onLoad(async () => {
|
||||
await getUserInfo()
|
||||
getParentBindDevice()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
hud.loading()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<mj-page class="teacher-content">
|
||||
<!-- <view v-if="equipmentList.length === 0" class="binding">
|
||||
<image class="scan" :src="scanQr" mode=""></image>扫码绑定设备
|
||||
</view> -->
|
||||
<view class="my_equipment">
|
||||
<view class="header">
|
||||
<text>我的设备</text>
|
||||
<image
|
||||
v-if="devices.length > 1"
|
||||
:src="arrow"
|
||||
mode=""
|
||||
:class="{ arrow_icon: true, rotate: showAllDevice }"
|
||||
@click="showAllDevice = !showAllDevice"
|
||||
></image>
|
||||
</view>
|
||||
<view v-if="!showAllDevice && devices.length" class="equipment_item">
|
||||
<view class="equipment_item_right">
|
||||
<view class="avatar">
|
||||
<image :src="showDevice?.lastLoginUser?.avatar || defaultAvatar" mode=""></image>
|
||||
</view>
|
||||
<view class="right">
|
||||
<text class="nickname">{{ showDevice?.lastLoginUser?.name || '未登录账号' }}</text>
|
||||
<text class="number">序列号:{{ showDevice?.simSerialNumber }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<template v-else>
|
||||
<view
|
||||
v-for="(i, idx) in devices"
|
||||
:key="idx"
|
||||
class="equipment_item"
|
||||
@click="chooseEquipment(i)"
|
||||
>
|
||||
<view class="equipment_item_right">
|
||||
<view class="avatar">
|
||||
<image :src="i.lastLoginUser?.avatar || defaultAvatar" mode=""></image>
|
||||
</view>
|
||||
<view class="right">
|
||||
<text class="nickname">{{ i.lastLoginUser?.name || '未登录账号' }}</text>
|
||||
<text class="number">序列号:{{ i.simSerialNumber }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="equipment_item_left">
|
||||
<image :src="i.id === showDevice.id ? checked : unchecked" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<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">
|
||||
<template v-for="(i, idx) in functionList" :key="idx">
|
||||
<view class="item" @click="change(i)">
|
||||
<image class="item_bg" :src="i.developing ? i.developingBg : i.bg" mode=""></image>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 手动绑定弹框 -->
|
||||
<mj-dialog
|
||||
v-model="showHandBindPopup"
|
||||
title="手动绑定孩子账号"
|
||||
okText="绑定"
|
||||
:ok="confirmHandBind"
|
||||
>
|
||||
<input v-model="childAccount" class="single-input" placeholder="请输入孩子账号" type="text" />
|
||||
</mj-dialog>
|
||||
</mj-page>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.teacher-content {
|
||||
padding: 30rpx 30rpx 120rpx 30rpx;
|
||||
@ -411,21 +384,4 @@ 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>
|
||||
|
@ -58,7 +58,7 @@ import type { UserInfo } from '@/types/inspector/mine'
|
||||
import { queryUserRoles, switchRole } from '@/api/inspector/mine'
|
||||
import { getAvatarUrl } from '@/utils'
|
||||
import { getAuthUrlApi } from '@/api/login'
|
||||
import { userStore } from '@/store'
|
||||
import { useUserStore } from '@/store'
|
||||
import db from '@/utils/db'
|
||||
|
||||
const roleRef = ref(null)
|
||||
@ -67,7 +67,7 @@ const userInfo = inject<Ref<UserInfo>>('userInfo')
|
||||
|
||||
const roleList = ref<any[]>([])
|
||||
|
||||
const { getUserInfo: getLoginUserInfo } = userStore()
|
||||
const { getUserInfo: getLoginUserInfo } = useUserStore()
|
||||
|
||||
const queryRole = async () => {
|
||||
const data = await queryUserRoles({ phone: userInfo.value.phone })
|
||||
|
@ -181,8 +181,8 @@
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { userStore } from '@/store'
|
||||
const { logout } = userStore()
|
||||
import { useUserStore } from '@/store'
|
||||
const { logout } = useUserStore()
|
||||
import { onLaunch, onShow, onHide, onLoad } from '@dcloudio/uni-app'
|
||||
import { usepersonalStoreHook } from '@/store/inspector'
|
||||
import Picker from '../releasePlan/components/picker.vue'
|
||||
|
@ -34,50 +34,50 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { inject, provide, ref, watchEffect } from 'vue';
|
||||
import { inject, provide, ref, watchEffect } from 'vue'
|
||||
// import StudySituationReportContent from '@/pages/inspector/student-detail/components/study-situation-report-content.vue';
|
||||
// import VideoStudySummary from '@/pages/inspector/student-detail/components/study-situation-report/video-study-summary.vue';
|
||||
// import KnowledgeAtlas from '@/pages/inspector/student-detail/components/study-situation-report/knowledge-atlas.vue';
|
||||
// import ReviewQuestionsSummary from '@/pages/inspector/student-detail/components/study-situation-report/review-questions-summary.vue';
|
||||
// import LanguageSenseLearningStatistics from '@/pages/inspector/student-detail/components/study-situation-report/language-sense-learning-statistics.vue';
|
||||
import { getSubjectListByGrade } from '@/api/inspector/student-detail';
|
||||
import { getSubjectListByGrade } from '@/api/inspector/student-detail'
|
||||
|
||||
import StudyTime from '@/pages/academicReport/components/studyTime.vue';
|
||||
import VideoTime from '@/pages/academicReport/components/videoTime.vue';
|
||||
import KnowledgeChart from '@/pages/academicReport/components/knowledgeChart.vue';
|
||||
import ExerciseStatistics from '@/pages/academicReport/components/exerciseStatistics.vue';
|
||||
import LanguageStatistics from '@/pages/academicReport/components/languageStatistics.vue';
|
||||
import '@/pages/academicReport/index.scss';
|
||||
const studentInfo = inject('studentInfo', null);
|
||||
import StudyTime from '@/pages/academic-report/components/studyTime.vue'
|
||||
import VideoTime from '@/pages/academic-report/components/videoTime.vue'
|
||||
import KnowledgeChart from '@/pages/academic-report/components/knowledgeChart.vue'
|
||||
import ExerciseStatistics from '@/pages/academic-report/components/exerciseStatistics.vue'
|
||||
import LanguageStatistics from '@/pages/academic-report/components/languageStatistics.vue'
|
||||
import '@/pages/academic-report/index.scss'
|
||||
const studentInfo = inject('studentInfo', null)
|
||||
// 学科列表
|
||||
const subjectList = ref<any[]>([]);
|
||||
const subjectList = ref<any[]>([])
|
||||
// 当前学科id
|
||||
const currentSubjectId = ref<number>(0);
|
||||
const loading = ref(true);
|
||||
const currentSubjectId = ref<number>(0)
|
||||
const loading = ref(true)
|
||||
provide('studySituationParam', {
|
||||
subjectId: currentSubjectId,
|
||||
userId: studentInfo.value.userId,
|
||||
});
|
||||
})
|
||||
|
||||
const querySubjectList = async () => {
|
||||
loading.value = true;
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await getSubjectListByGrade(studentInfo.value.gradeId);
|
||||
const data = await getSubjectListByGrade(studentInfo.value.gradeId)
|
||||
subjectList.value = data.map((item: any) => ({
|
||||
name: item.name,
|
||||
value: item.subjectId,
|
||||
}));
|
||||
currentSubjectId.value = data[0].subjectId;
|
||||
}))
|
||||
currentSubjectId.value = data[0].subjectId
|
||||
} finally {
|
||||
loading.value = false;
|
||||
loading.value = false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
if (studentInfo.value.gradeId) {
|
||||
querySubjectList();
|
||||
querySubjectList()
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
@ -55,14 +55,14 @@
|
||||
import { ref, computed, nextTick, onMounted } from 'vue'
|
||||
|
||||
import { sendCodeMessageApi, smsLoginApi, wxLoginApi } from '@/api'
|
||||
import { userStore } from '@/store'
|
||||
import { useUserStore } from '@/store'
|
||||
import router from '@/router/router'
|
||||
import db from '@/utils/db'
|
||||
import hud from '@/utils/hud'
|
||||
|
||||
const emits = defineEmits(['reloadFun'])
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const { getUserInfo, setToken } = userStore()
|
||||
const { getUserInfo, setToken } = useUserStore()
|
||||
|
||||
const formatPhone = ref('')
|
||||
const verifyCode = ref('')
|
||||
|
93
src/pages/mine/Components/recharge/index.vue
Normal file
93
src/pages/mine/Components/recharge/index.vue
Normal file
@ -0,0 +1,93 @@
|
||||
<script setup lang="ts">
|
||||
import { createRechargeOrderApi } from '@/api'
|
||||
import hud from '@/utils/hud'
|
||||
import num from '@/utils/num'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
defineOptions({ name: 'Recharge' })
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
}>()
|
||||
|
||||
const show = computed({
|
||||
get: () => props.modelValue,
|
||||
set: val => {
|
||||
emit('update:modelValue', val)
|
||||
},
|
||||
})
|
||||
|
||||
// 金额
|
||||
const defaultMoneyType = 10
|
||||
const customMoneyType = 0
|
||||
const moneyTypeOptions = [
|
||||
{
|
||||
label: '10元',
|
||||
value: defaultMoneyType,
|
||||
},
|
||||
{
|
||||
label: '50元',
|
||||
value: '50',
|
||||
},
|
||||
{
|
||||
label: '100元',
|
||||
value: '100',
|
||||
},
|
||||
{
|
||||
label: '自定义',
|
||||
value: customMoneyType,
|
||||
},
|
||||
]
|
||||
const moneyType = ref(defaultMoneyType as any)
|
||||
const customMoney = ref('')
|
||||
|
||||
// 确定充值
|
||||
async function ok() {
|
||||
let money = moneyType.value
|
||||
if (moneyType.value === customMoneyType) {
|
||||
money = customMoney.value
|
||||
}
|
||||
money = Number(money)
|
||||
if (Number.isNaN(money) || money < defaultMoneyType || !num.isPositiveInt(num.toFixed2(money))) {
|
||||
hud.error(`请输入大于等于${defaultMoneyType}的正整数金额`)
|
||||
return
|
||||
}
|
||||
|
||||
// 生成订单
|
||||
const data = await createRechargeOrderApi(money)
|
||||
console.log(data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<mj-dialog v-model="show" title="乐贝充值" :ok="ok">
|
||||
<view class="title">请选择充值金额(1元=100乐贝)</view>
|
||||
<mj-segment v-model="moneyType" :options="moneyTypeOptions" />
|
||||
<input
|
||||
class="single-input"
|
||||
v-if="moneyType == customMoneyType"
|
||||
type="number"
|
||||
v-model="customMoney"
|
||||
placeholder="请输入自定义金额"
|
||||
/>
|
||||
</mj-dialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 60rpx;
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.single-input {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
</style>
|
@ -73,8 +73,8 @@ import { storeToRefs } from 'pinia'
|
||||
import Empty from '@/components/Empty/index.vue'
|
||||
import CustomPopup from '@/components/CustomPopup/index.vue'
|
||||
import { updateTaskStatusApi, getParentBindChildApi, getFamilyTaskStuApi } from '@/api'
|
||||
import { userStore } from '@/store'
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
import { useUserStore } from '@/store'
|
||||
const { userInfo } = storeToRefs(useUserStore())
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const pageStatus = ref('')
|
||||
const taskType = ref() // 任务类型 0-系统任务 1-自定义任务
|
||||
|
@ -1,82 +1,11 @@
|
||||
<template>
|
||||
<view class="about_mine">
|
||||
<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>
|
||||
|
||||
<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>
|
||||
</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>
|
||||
</template>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, onMounted, computed } from 'vue'
|
||||
import { reactive, ref, computed } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { getParentBindChildApi, getParentBindDeviceApi } from '@/api'
|
||||
import { userStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import router from '@/router/router'
|
||||
import dayjs from 'dayjs'
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
import { useChildStore } from '@/store/child'
|
||||
import { useDeviceStore } from '@/store/device'
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
||||
const empty = `${OSS_URL}/empty.png`
|
||||
@ -99,13 +28,19 @@ const navList = reactive([
|
||||
type: nav_device,
|
||||
},
|
||||
])
|
||||
const childList = ref<any[]>([])
|
||||
const deviceList = ref<any[]>([])
|
||||
// 孩子
|
||||
const childStore = useChildStore()
|
||||
const { getChildren } = childStore
|
||||
const { children } = storeToRefs(childStore)
|
||||
// 设备
|
||||
const deviceStore = useDeviceStore()
|
||||
const { getDevices } = deviceStore
|
||||
const { devices } = storeToRefs(deviceStore)
|
||||
|
||||
const noData = computed(() => {
|
||||
return (
|
||||
(activeNav.value.type === nav_child && childList.value.length === 0) ||
|
||||
(activeNav.value.type === nav_device && deviceList.value.length === 0)
|
||||
(activeNav.value.type === nav_child && children.value.length === 0) ||
|
||||
(activeNav.value.type === nav_device && devices.value.length === 0)
|
||||
)
|
||||
})
|
||||
|
||||
@ -116,21 +51,9 @@ function switchNav(i: any) {
|
||||
|
||||
const loadData = () => {
|
||||
if (activeNav.value.type === nav_child) {
|
||||
getParentBindChildApi({ parentId: userInfo.value.id, current: 1, size: 1000 })
|
||||
.then(res => {
|
||||
childList.value = res.rows || []
|
||||
})
|
||||
.catch(res => {
|
||||
childList.value = []
|
||||
})
|
||||
getChildren()
|
||||
} else {
|
||||
getParentBindDeviceApi({ parentId: userInfo.value.id, current: 1, size: 1000 })
|
||||
.then(res => {
|
||||
deviceList.value = res.rows || []
|
||||
})
|
||||
.catch(res => {
|
||||
deviceList.value = []
|
||||
})
|
||||
getDevices()
|
||||
}
|
||||
}
|
||||
// 进入详情
|
||||
@ -156,21 +79,85 @@ function handleBindDevice() {
|
||||
router.navigateTo('/pages/home/bindDevice/index')
|
||||
}
|
||||
|
||||
const toMySupervisionService = child => {
|
||||
router.navigateTo({
|
||||
path: `/pages/parents/mySupervisionService/index`,
|
||||
query: { id: child.childId },
|
||||
})
|
||||
}
|
||||
// const toMySupervisionService = child => {
|
||||
// router.navigateTo({
|
||||
// path: `/pages/parents/mySupervisionService/index`,
|
||||
// query: { id: child.childId },
|
||||
// })
|
||||
// }
|
||||
|
||||
onShow(() => {
|
||||
loadData()
|
||||
})
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="about_mine">
|
||||
<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>
|
||||
|
||||
<view v-else class="content">
|
||||
<!-- 我的孩子 -->
|
||||
<template v-if="activeNav.type === nav_child">
|
||||
<view
|
||||
v-for="(i, idx) in children"
|
||||
:key="idx"
|
||||
class="children"
|
||||
@click="handleDetailPage(activeNav.type, i)"
|
||||
>
|
||||
<image
|
||||
:src="i?.child?.avatar || defaultAvatar"
|
||||
mode=""
|
||||
class="children_avatar"
|
||||
></image>
|
||||
<view class="children-info">
|
||||
<view class="name_vip">
|
||||
<text class="name">{{ i.child?.name }}</text>
|
||||
<image
|
||||
v-if="i.child?.currentLevel"
|
||||
:src="`${OSS_URL}/iconfont/VIP/VIP_${i.child?.currentLevel}.png`"
|
||||
class="vip"
|
||||
/>
|
||||
</view>
|
||||
<view class="time">
|
||||
有效期至:{{
|
||||
i.child?.vipEndTime ? dayjs(i.child?.vipEndTime).format('YYYY.MM.DD') : '-'
|
||||
}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<!-- 我的设备 -->
|
||||
<template v-else>
|
||||
<view
|
||||
v-for="(i, idx) in devices"
|
||||
:key="idx"
|
||||
class="equipment"
|
||||
@click="handleDetailPage(activeNav.type, i)"
|
||||
>
|
||||
序列号:<text class="serial">{{ i.simSerialNumber }}</text>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.about_mine {
|
||||
.container {
|
@ -1,49 +1,3 @@
|
||||
<template>
|
||||
<view class="patriarch_list">
|
||||
<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>
|
||||
<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="right"><button class="unbind_btn" @click="handleUnbind(i as any)">解绑</button></view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<CustomPopup
|
||||
v-model="showCustomPopup"
|
||||
titleText="温馨提示"
|
||||
@handleConfirmBtn="handleConfirmPopup"
|
||||
>
|
||||
<view class="popup_box">
|
||||
<text v-if="type === 1" class="tip">
|
||||
确认解绑该账号?解绑后该家长<br />无法查看孩子的学情报告等数据
|
||||
</text>
|
||||
<text v-else class="tip"> 确认解绑该账号?解绑后该家长<br />无法查看该设备的情况</text>
|
||||
</view>
|
||||
</CustomPopup>
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
@ -64,20 +18,20 @@ const props = withDefaults(
|
||||
}>(),
|
||||
{
|
||||
type: 1,
|
||||
top: 445,
|
||||
top: 0,
|
||||
},
|
||||
)
|
||||
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 dataList = ref<(ChildrenType & DeviceType)[]>([])
|
||||
|
||||
const detailInfo = ref<ChildrenType & DeviceType>()
|
||||
|
||||
const loadData = () => {
|
||||
if (props.type === 1) {
|
||||
getParentBindChildApi({ childId: detailInfo.value.childId, current: 1, size: 1000 })
|
||||
getParentBindChildApi({ childId: detailInfo.value.child?.id, current: 1, size: 1000 })
|
||||
.then(res => {
|
||||
dataList.value = res.rows || []
|
||||
})
|
||||
@ -111,7 +65,7 @@ async function handleConfirmPopup() {
|
||||
if (props.type === 1) {
|
||||
await childUnBoundParentApi({
|
||||
parentId: (unbind.value as any).parentId,
|
||||
childId: detailInfo.value.childId,
|
||||
childId: detailInfo.value.child?.id,
|
||||
})
|
||||
} else {
|
||||
await parentUnBoundDeviceApi({
|
||||
@ -128,22 +82,69 @@ onLoad(option => {
|
||||
loadData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="patriarch_list">
|
||||
<view class="container" :style="{ margin: `${top}rpx 0 0 0` }">
|
||||
<view class="title">绑定家长</view>
|
||||
<view class="scroll-container">
|
||||
<view v-if="dataList.length === 0" class="empty_box">
|
||||
<Empty content="暂无绑定家长数据哦~" />
|
||||
</view>
|
||||
<view v-else class="content">
|
||||
<view v-for="(i, idx) in dataList" :key="idx" class="patriarch">
|
||||
<view class="left">
|
||||
<image
|
||||
:src="i.parent?.avatar || defaultAvatar"
|
||||
mode=""
|
||||
class="patriarch_avatar"
|
||||
></image>
|
||||
<view>
|
||||
<view class="header">
|
||||
<view class="name">{{ i.parent.name }}</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.parent.phone) }} </view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right"
|
||||
><button class="unbind_btn" @click="handleUnbind(i as any)">解绑</button></view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<CustomPopup
|
||||
v-model="showCustomPopup"
|
||||
titleText="温馨提示"
|
||||
@handleConfirmBtn="handleConfirmPopup"
|
||||
>
|
||||
<view class="popup_box">
|
||||
<text v-if="type === 1" class="tip">
|
||||
确认解绑该账号?解绑后该家长<br />无法查看孩子的学情报告等数据
|
||||
</text>
|
||||
<text v-else class="tip"> 确认解绑该账号?解绑后该家长<br />无法查看该设备的情况</text>
|
||||
</view>
|
||||
</CustomPopup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<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;
|
||||
@ -160,7 +161,7 @@ onLoad(option => {
|
||||
}
|
||||
}
|
||||
.title {
|
||||
margin: 0 0 10rpx 0;
|
||||
margin: 0 0 10rpx 30rpx;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
font-weight: 400;
|
||||
|
@ -1,46 +1,16 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<BackBar title="账号详情" />
|
||||
<view class="children">
|
||||
<view class="left">
|
||||
<image :src="detailInfo.childAvatar" mode="" class="children_avatar"></image>
|
||||
<view>
|
||||
<view class="name_vip">
|
||||
<text class="name">{{ detailInfo.childName }}</text>
|
||||
<image
|
||||
v-if="detailInfo.currentLevel"
|
||||
:src="`${OSS_URL}/iconfont/VIP/VIP_${detailInfo.currentLevel}.png`"
|
||||
class="vip"
|
||||
/>
|
||||
</view>
|
||||
<view class="time"> 有效期至:{{ dayjs(OSS_URL.vipEndTime).format('YYYY.MM.DD') }} </view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<button class="invite_btn" @click="clickShareBtn">邀请绑定</button>
|
||||
</view>
|
||||
</view>
|
||||
<bindPatriarch :type="1" :top="304" />
|
||||
<!-- 指示蒙层 -->
|
||||
<view v-if="showMaskTip" class="mask" @click="showMaskTip = false">
|
||||
<image :src="`${OSS_URL}/urm/invite_arrow.png`" mode="scaleToFill" class="invite_arrow" />
|
||||
<text class="word">点击右上角分享给好友哦~</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import dayjs from 'dayjs'
|
||||
import bindPatriarch from './bindPatriarch.vue'
|
||||
import type { ChildrenType } from '../interface'
|
||||
import { userStore, shareConfigStore } from '@/store'
|
||||
import { useUserStore, shareConfigStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { parentBindInviteApi } from '@/api'
|
||||
import { onMounted } from 'vue'
|
||||
const { initWeixinShareConfig } = shareConfigStore()
|
||||
const { appId } = storeToRefs(shareConfigStore())
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
const { userInfo } = storeToRefs(useUserStore())
|
||||
const detailInfo = ref<ChildrenType>({})
|
||||
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
||||
const showMaskTip = ref(false) // 指示蒙层
|
||||
@ -79,6 +49,40 @@ onMounted(async () => {
|
||||
share()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="page">
|
||||
<BackBar title="账号详情" />
|
||||
<view class="children">
|
||||
<view class="left">
|
||||
<image :src="detailInfo.child?.avatar" mode="" class="children_avatar"></image>
|
||||
<view>
|
||||
<view class="name_vip">
|
||||
<text class="name">{{ detailInfo.child?.name }}</text>
|
||||
<image
|
||||
v-if="detailInfo.child?.currentLevel"
|
||||
:src="`${OSS_URL}/iconfont/VIP/VIP_${detailInfo.child?.currentLevel}.png`"
|
||||
class="vip"
|
||||
/>
|
||||
</view>
|
||||
<view class="time">
|
||||
有效期至:{{ dayjs(detailInfo.child?.vipEndTime).format('YYYY.MM.DD') }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<button class="invite_btn" @click="clickShareBtn">邀请绑定</button>
|
||||
</view>
|
||||
</view>
|
||||
<bindPatriarch :type="1" />
|
||||
<!-- 指示蒙层 -->
|
||||
<view v-if="showMaskTip" class="mask" @click="showMaskTip = false">
|
||||
<image :src="`${OSS_URL}/urm/invite_arrow.png`" mode="scaleToFill" class="invite_arrow" />
|
||||
<text class="word">点击右上角分享给好友哦~</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
// padding: 30rpx;
|
||||
|
@ -1,49 +1,3 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<BackBar title="设备详情" />
|
||||
<view class="equipment">
|
||||
<view class="left">
|
||||
序列号:<text class="serial">{{ detailInfo.simSerialNumber }}</text>
|
||||
</view>
|
||||
<view class="right">
|
||||
<button class="invite_btn" @click="clickShareBtn">分享设备</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="current_login">
|
||||
<view class="title">当前登录</view>
|
||||
<view class="children">
|
||||
<image
|
||||
:src="
|
||||
currentLogin?.curDeviceUserAvatar ? currentLogin?.curDeviceUserAvatar : defaultAvatar
|
||||
"
|
||||
mode=""
|
||||
class="children_avatar"
|
||||
></image>
|
||||
<view>
|
||||
<view class="name_vip">
|
||||
<text class="name">{{
|
||||
currentLogin?.curDeviceUserName ? currentLogin?.curDeviceUserName : '未登录账号'
|
||||
}}</text>
|
||||
<image
|
||||
v-if="currentLogin?.currentLevel"
|
||||
:src="`${OSS_URL}/iconfont/VIP/VIP_${currentLogin?.currentLevel}.png`"
|
||||
class="vip"
|
||||
/>
|
||||
</view>
|
||||
<view v-if="currentLogin?.vipEndTime" class="time">
|
||||
有效期至:{{ dayjs(currentLogin?.vipEndTime).format('YYYY.MM.DD') }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<bindPatriarch :type="2" :top="519" />
|
||||
<!-- 指示蒙层 -->
|
||||
<view v-if="showMaskTip" class="mask" @click="showMaskTip = false">
|
||||
<image :src="`${OSS_URL}/urm/invite_arrow.png`" mode="scaleToFill" class="invite_arrow" />
|
||||
<text class="word">点击右上角分享给好友哦~</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { onLoad, onShareAppMessage } from '@dcloudio/uni-app'
|
||||
@ -52,13 +6,13 @@ import type { DeviceType, CurrentLoginAccountType } from '../interface'
|
||||
|
||||
import bindPatriarch from './bindPatriarch.vue'
|
||||
import { parentDeviceCurrentLoginApi, parentBindInviteApi } from '@/api'
|
||||
import { userStore, shareConfigStore } from '@/store'
|
||||
import { useUserStore, shareConfigStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
const { initWeixinShareConfig } = shareConfigStore()
|
||||
const { appId } = storeToRefs(shareConfigStore())
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
const { userInfo } = storeToRefs(useUserStore())
|
||||
const showMaskTip = ref(false)
|
||||
const detailInfo = ref<DeviceType>()
|
||||
const currentLogin = ref<CurrentLoginAccountType>()
|
||||
@ -105,6 +59,50 @@ onLoad(option => {
|
||||
detailInfo.value = JSON.parse(decodeURIComponent(option.details))
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="page">
|
||||
<BackBar title="设备详情" />
|
||||
<view class="equipment">
|
||||
<view class="left">
|
||||
序列号:<text class="serial">{{ detailInfo.simSerialNumber }}</text>
|
||||
</view>
|
||||
<view class="right">
|
||||
<button class="invite_btn" @click="clickShareBtn">分享设备</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="current_login">
|
||||
<view class="title">当前登录</view>
|
||||
<view class="children">
|
||||
<image
|
||||
:src="currentLogin?.curDeviceUserAvatar || defaultAvatar"
|
||||
mode=""
|
||||
class="children_avatar"
|
||||
></image>
|
||||
<view>
|
||||
<view class="name_vip">
|
||||
<text class="name">{{ currentLogin?.curDeviceUserName || '未登录账号' }}</text>
|
||||
<image
|
||||
v-if="currentLogin?.currentLevel"
|
||||
:src="`${OSS_URL}/iconfont/VIP/VIP_${currentLogin?.currentLevel}.png`"
|
||||
class="vip"
|
||||
/>
|
||||
</view>
|
||||
<view v-if="currentLogin?.vipEndTime" class="time">
|
||||
有效期至:{{ dayjs(currentLogin?.vipEndTime).format('YYYY.MM.DD') }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<bindPatriarch :type="2" />
|
||||
<!-- 指示蒙层 -->
|
||||
<view v-if="showMaskTip" class="mask" @click="showMaskTip = false">
|
||||
<image :src="`${OSS_URL}/urm/invite_arrow.png`" mode="scaleToFill" class="invite_arrow" />
|
||||
<text class="word">点击右上角分享给好友哦~</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
// padding: 30rpx;
|
||||
@ -153,7 +151,7 @@ onLoad(option => {
|
||||
}
|
||||
.current_login {
|
||||
.title {
|
||||
margin: 40rpx 0 10rpx 0;
|
||||
margin: 40rpx 0 10rpx 30rpx;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
font-weight: 400;
|
||||
|
@ -1,20 +1,15 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<PatriarchCard />
|
||||
<AboutMine />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
|
||||
import PatriarchCard from './patriarchCard.vue'
|
||||
import AboutMine from './aboutMine.vue'
|
||||
import { badgeStore } from '@/store/badge'
|
||||
import PatriarchCard from './patriarch-card.vue'
|
||||
import AboutMine from './about-mine.vue'
|
||||
import { useUserStore, useBadgeStore } from '@/store'
|
||||
|
||||
const { refreshBadge } = badgeStore()
|
||||
const { refreshBadge } = useBadgeStore()
|
||||
const { getUserInfo } = useUserStore()
|
||||
|
||||
onShow(async () => {
|
||||
getUserInfo()
|
||||
refreshBadge()
|
||||
})
|
||||
</script>
|
||||
@ -24,3 +19,10 @@ onShow(async () => {
|
||||
padding: 30rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<mj-page class="content">
|
||||
<PatriarchCard />
|
||||
<AboutMine />
|
||||
</mj-page>
|
||||
</template>
|
||||
|
@ -1,27 +1,35 @@
|
||||
// 我的孩子
|
||||
export interface ChildrenType {
|
||||
createTime?: string
|
||||
createUser?: string
|
||||
updateTime?: string
|
||||
updateUser?: string
|
||||
id?: string
|
||||
parentId?: string
|
||||
childId?: string
|
||||
adminFlag?: number
|
||||
identityType?: null
|
||||
bindFlag?: number
|
||||
bindTime?: string
|
||||
unBindTime?: string
|
||||
childName?: string
|
||||
childAvatar?: string
|
||||
parentName?: string
|
||||
parentAvatar?: string
|
||||
parentPhone?: string
|
||||
vipEndTime?: string
|
||||
type ParentInfo = {
|
||||
id?: any
|
||||
name?: string
|
||||
account?: string
|
||||
avatar?: string
|
||||
phone?: string
|
||||
}
|
||||
|
||||
type ChildInfo = {
|
||||
id?: any
|
||||
name?: string
|
||||
diamond?: number
|
||||
currency?: number
|
||||
account?: string
|
||||
avatar?: string
|
||||
vipEndTime?: string // yyyy-MM-dd HH:mm:ss
|
||||
currentLevel?: number
|
||||
gradeId?: string
|
||||
gradeName?: string
|
||||
expLevel?: number
|
||||
gradeId?: number
|
||||
gradeName?: string
|
||||
}
|
||||
|
||||
export interface ChildrenType {
|
||||
id?: number
|
||||
bindFlag?: 0 | 1 // 0-未绑定 1-已绑定
|
||||
bindTime?: string // yyyy-MM-dd HH:mm:ss
|
||||
unBindTime?: string // yyyy-MM-dd HH:mm:ss
|
||||
adminFlag?: 0 | 1 // 0-否 1-是
|
||||
identityType?: 1 | 2 | 3 | 4 | 5 | 6 | 7 // 1:父亲,2:母亲,3:爷爷,4:奶奶,5:外公,6:外婆,7:其他
|
||||
child?: ChildInfo
|
||||
parent?: ParentInfo
|
||||
}
|
||||
// 我的设备
|
||||
export interface DeviceType {
|
||||
|
@ -1,49 +1,18 @@
|
||||
<template>
|
||||
<view class="patriarch_card">
|
||||
<view class="info" @click="handlePrefectInfo">
|
||||
<image
|
||||
:src="userInfo.avatarUrl ? userInfo.avatarUrl : defaultAvatar"
|
||||
mode=""
|
||||
class="header"
|
||||
></image>
|
||||
<text class="name">{{ userInfo.nickName }}</text>
|
||||
<text class="identity">家长</text>
|
||||
</view>
|
||||
<view class="function">
|
||||
<template v-for="i in list" :key="i.title">
|
||||
<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.id === id_apply && bindApplyList?.length" class="unread">
|
||||
{{ bindApplyList?.length }}
|
||||
</text>
|
||||
</view>
|
||||
<text class="title">{{ i.title }}</text>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { bindApplyStore, userStore } from '@/store'
|
||||
import { bindApplyStore, useUserStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import router from '@/router/router'
|
||||
import recharge from './Components/recharge/index.vue'
|
||||
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
const { userInfo } = storeToRefs(useUserStore())
|
||||
const { bindApplyList } = storeToRefs(bindApplyStore())
|
||||
const id_apply = 2
|
||||
const id_apply = 1
|
||||
const id_recharge = 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',
|
||||
// },
|
||||
{
|
||||
id: id_apply,
|
||||
title: '绑定申请',
|
||||
@ -51,6 +20,18 @@ const list = ref([
|
||||
show: true,
|
||||
url: '/pages/mine/bindApply/index',
|
||||
},
|
||||
{
|
||||
id: id_recharge,
|
||||
title: '乐贝充值',
|
||||
photo: `${OSS_URL}/urm/my_award_manage.png`,
|
||||
show: true,
|
||||
},
|
||||
// {
|
||||
// title: '扫码绑定',
|
||||
// photo: `${OSS_URL}/urm/my_scan_binding.png`,
|
||||
// show: true,
|
||||
// url: '/pages/home/bindDevice/index',
|
||||
// },
|
||||
// {
|
||||
// title: '电子保修卡',
|
||||
// photo: `${OSS_URL}/urm/my_warranty.png`,
|
||||
@ -76,10 +57,16 @@ const list = ref([
|
||||
// url: '/pages/mine/awardManage/index',
|
||||
// },
|
||||
])
|
||||
|
||||
const showRecharge = ref(false)
|
||||
function handleJump(i: any) {
|
||||
router.navigateTo({
|
||||
path: i.url,
|
||||
})
|
||||
if (i.url) {
|
||||
router.navigateTo({
|
||||
path: i.url,
|
||||
})
|
||||
} else if (i.id === id_recharge) {
|
||||
showRecharge.value = true
|
||||
}
|
||||
}
|
||||
// 完善信息
|
||||
function handlePrefectInfo() {
|
||||
@ -92,6 +79,43 @@ function handlePrefectInfo() {
|
||||
onMounted(() => {})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="patriarch_card">
|
||||
<view class="info" @click="handlePrefectInfo">
|
||||
<image
|
||||
:src="userInfo.avatarUrl ? userInfo.avatarUrl : defaultAvatar"
|
||||
mode=""
|
||||
class="header"
|
||||
></image>
|
||||
<view class="right">
|
||||
<view class="right-top">
|
||||
<text class="name">{{ userInfo.nickName }}</text>
|
||||
<text class="identity">家长</text>
|
||||
</view>
|
||||
<view class="right-bottom">
|
||||
<text
|
||||
>乐贝:<text class="currency">{{ userInfo.currency }}</text></text
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="function">
|
||||
<template v-for="i in list" :key="i.title">
|
||||
<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.id === id_apply && bindApplyList?.length" class="unread">
|
||||
{{ bindApplyList?.length }}
|
||||
</text>
|
||||
</view>
|
||||
<text class="title">{{ i.title }}</text>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<recharge v-model="showRecharge" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.patriarch_card {
|
||||
padding: 30rpx;
|
||||
@ -101,6 +125,7 @@ onMounted(() => {})
|
||||
.info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 30rpx;
|
||||
|
||||
.header {
|
||||
width: 100rpx;
|
||||
@ -108,23 +133,46 @@ onMounted(() => {})
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.name {
|
||||
display: inline-block;
|
||||
margin: 0 10rpx 0 20rpx;
|
||||
font-weight: 500;
|
||||
font-size: 32rpx;
|
||||
line-height: 48rpx;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
}
|
||||
.right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rpx;
|
||||
justify-content: ce;
|
||||
|
||||
.identity {
|
||||
display: inline-block;
|
||||
padding: 0 10rpx 0 10rpx;
|
||||
background-color: rgba(93, 185, 255, 1);
|
||||
border-radius: 6rpx;
|
||||
font-size: 22rpx;
|
||||
line-height: 30rpx;
|
||||
color: #fff;
|
||||
.right-top {
|
||||
display: flex;
|
||||
gap: 10rpx;
|
||||
align-items: center;
|
||||
|
||||
.name {
|
||||
display: inline-block;
|
||||
font-weight: 500;
|
||||
font-size: 32rpx;
|
||||
line-height: 48rpx;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
}
|
||||
|
||||
.identity {
|
||||
display: block;
|
||||
height: 30rpx;
|
||||
padding: 0 10rpx;
|
||||
background-color: rgba(93, 185, 255, 1);
|
||||
border-radius: 6rpx;
|
||||
font-size: 22rpx;
|
||||
line-height: 30rpx;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.right-bottom {
|
||||
font-size: 28rpx;
|
||||
line-height: 40rpx;
|
||||
color: $font-aux-color;
|
||||
|
||||
.currency {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ import { storeToRefs } from 'pinia'
|
||||
import router from '@/router/router'
|
||||
import CustomPopup from '@/components/CustomPopup/index.vue'
|
||||
// #ifdef H5
|
||||
import { h5Authorization, userStore } from '@/store'
|
||||
import { h5Authorization, useUserStore } from '@/store'
|
||||
import hud from '@/utils/hud'
|
||||
const { authorizedLogin } = h5Authorization()
|
||||
// #endif
|
||||
@ -72,7 +72,7 @@ const popupRef = ref(null)
|
||||
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`
|
||||
const store = userStore()
|
||||
const store = useUserStore()
|
||||
const { logout, getUserInfo } = store
|
||||
const { userInfo } = storeToRefs(store)
|
||||
const indicatorStyle = ref(`height: 50px;`)
|
||||
|
@ -1,7 +1,7 @@
|
||||
import db from '@/utils/db'
|
||||
import type { PiniaPluginContext, StateTree, Store } from 'pinia'
|
||||
|
||||
const cache = ['user']
|
||||
const cache = ['user', 'device', 'child']
|
||||
|
||||
function getStoreKey(key: string) {
|
||||
return `store_${key}`
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import { userStore } from '@/store'
|
||||
import { useUserStore } from '@/store'
|
||||
import db from '../utils/db'
|
||||
import page from '../utils/page'
|
||||
import qs from 'qs'
|
||||
@ -111,7 +111,7 @@ function beforeEach(options: RouterOptions) {
|
||||
console.log('beforeEach', from, to)
|
||||
|
||||
// 执行跳转
|
||||
const { token } = storeToRefs(userStore())
|
||||
const { token } = storeToRefs(useUserStore())
|
||||
if (!noTokenRoutes.includes(to.path) && !token.value) {
|
||||
console.log('token 过期')
|
||||
toLogin(to)
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { userStore } from '@/store'
|
||||
import { useUserStore } from '@/store'
|
||||
import { bindAuthInfoApi } from '@/api'
|
||||
import db from '@/utils/db'
|
||||
|
||||
@ -22,7 +22,7 @@ export const h5Authorization = defineStore('h5Authorization', () => {
|
||||
// setCache('H5_OPENID', res.data.openId);
|
||||
// setCache('H5_UNIONID', res.data.unionId);
|
||||
// setCache('token', res.data.token);
|
||||
const { afterLogin } = userStore()
|
||||
const { afterLogin } = useUserStore()
|
||||
await afterLogin()
|
||||
})
|
||||
} else {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { bindApplyStore } from './bindApply'
|
||||
|
||||
export const badgeStore = defineStore('badge', () => {
|
||||
export const useBadgeStore = defineStore('badge', () => {
|
||||
const { getApplyBindInfoList } = bindApplyStore()
|
||||
|
||||
async function refreshBadge() {
|
||||
|
20
src/store/child.ts
Normal file
20
src/store/child.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { defineStore, storeToRefs } from 'pinia'
|
||||
import { useUserStore } from './user'
|
||||
import { getParentBindChildApi } from '@/api'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export const useChildStore = defineStore('child', () => {
|
||||
const children = ref([] as any)
|
||||
const { userInfo } = storeToRefs(useUserStore())
|
||||
|
||||
async function getChildren() {
|
||||
children.value =
|
||||
(
|
||||
await getParentBindChildApi({
|
||||
parentId: userInfo.value?.id,
|
||||
})
|
||||
)?.rows || []
|
||||
return children.value
|
||||
}
|
||||
return { children, getChildren }
|
||||
})
|
20
src/store/device.ts
Normal file
20
src/store/device.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { defineStore, storeToRefs } from 'pinia'
|
||||
import { useUserStore } from './user'
|
||||
import { getParentBindDeviceApi } from '@/api'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export const useDeviceStore = defineStore('device', () => {
|
||||
const devices = ref([] as any)
|
||||
const { userInfo } = storeToRefs(useUserStore())
|
||||
|
||||
async function getDevices() {
|
||||
devices.value =
|
||||
(
|
||||
await getParentBindDeviceApi({
|
||||
parentId: userInfo.value?.id,
|
||||
})
|
||||
)?.rows || []
|
||||
return devices.value
|
||||
}
|
||||
return { devices, getDevices }
|
||||
})
|
@ -1,6 +1,9 @@
|
||||
export * from './user';
|
||||
export * from './global';
|
||||
export * from './H5Authorization';
|
||||
export * from './share';
|
||||
export * from './bindApply';
|
||||
export * from './socket';
|
||||
export * from './user'
|
||||
export * from './global'
|
||||
export * from './H5Authorization'
|
||||
export * from './share'
|
||||
export * from './bindApply'
|
||||
export * from './socket'
|
||||
export * from './badge'
|
||||
export * from './device'
|
||||
export * from './child'
|
||||
|
@ -4,9 +4,9 @@ import { ref } from 'vue'
|
||||
import { global } from './global'
|
||||
import { getCache, setCache } from '@/utils'
|
||||
import db from '@/utils/db'
|
||||
import { userStore } from './user'
|
||||
import { useUserStore } from './user'
|
||||
export const socket = defineStore('socket', () => {
|
||||
const { token } = storeToRefs(userStore())
|
||||
const { token } = storeToRefs(useUserStore())
|
||||
const socket = ref()
|
||||
const status = ref(true) // true在线 false离线
|
||||
let hbTimer: any
|
||||
|
@ -7,7 +7,7 @@ import { global } from '@/store'
|
||||
import router from '@/router/router'
|
||||
import db from '@/utils/db'
|
||||
|
||||
export const userStore = defineStore('user', () => {
|
||||
export const useUserStore = defineStore('user', () => {
|
||||
const userInfo = ref({} as any)
|
||||
const token = ref('')
|
||||
const { getDicts } = global()
|
||||
|
@ -44,3 +44,22 @@ button {
|
||||
.custom-popup {
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
}
|
||||
|
||||
.tui-dialog__hd {
|
||||
padding: 32rpx 24rpx 16rpx !important;
|
||||
}
|
||||
|
||||
.single-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;
|
||||
}
|
||||
}
|
||||
|
47
src/utils/num.ts
Normal file
47
src/utils/num.ts
Normal file
@ -0,0 +1,47 @@
|
||||
// 数字相关
|
||||
|
||||
// 去掉小数点后面无用的0
|
||||
function trimZero(num: any) {
|
||||
if (num === undefined || num === null) return ''
|
||||
let str = `${num}`
|
||||
if (!str.includes('.')) {
|
||||
// 没有小数点,直接返回
|
||||
return str
|
||||
}
|
||||
while (str.endsWith('0')) {
|
||||
str = str.slice(0, -1)
|
||||
}
|
||||
if (str.endsWith('.')) {
|
||||
str = str.slice(0, -1)
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
function toFixed2(num: any) {
|
||||
num = Number(num)
|
||||
if (Number.isNaN(num)) return ''
|
||||
return trimZero(num.toFixed(2))
|
||||
}
|
||||
|
||||
function toPercent(val: any) {
|
||||
val = Number(val)
|
||||
if (Number.isNaN(val)) return ''
|
||||
return `${toFixed2(val * 100)}%`
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为正整数
|
||||
*/
|
||||
function isPositiveInt(val: any) {
|
||||
val = String(val)
|
||||
if (val.includes('.')) return false
|
||||
const numVal = Number(val)
|
||||
return !Number.isNaN(numVal) && numVal > 0
|
||||
}
|
||||
|
||||
export default {
|
||||
trimZero,
|
||||
toFixed2,
|
||||
toPercent,
|
||||
isPositiveInt,
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user