| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- <template>
- <view>
- <swiper class="student-swiper" :class="students && students.length > 1 ? 'show-dots' : ''" :indicator-dots="students && students.length > 1" indicator-color="#ffffff"
- indicator-active-color="#666666" previous-margin="30rpx" next-margin="30rpx"
- v-if="students && students.length > 0" @change="onSwiperChange">
- <swiper-item v-for="student in students" :key="student.id" @click="onSwiperClick(student.id)">
- <view class="student-card">
- <image class="student-avatar" :src="student.avatar"></image>
- <view class="student-info">
- <text class="student-name">{{ student.name }}</text>
- <text class="student-class">{{ student.className }}</text>
- </view>
- </view>
- </swiper-item>
- </swiper>
- <view class="container">
- <view class="function-list">
- <!-- 留言功能 -->
- <view class="function-item" @click="goToMessage">
- <view class="function-icon">
- <Icon name="icon-jinchu" size="60" color="#393f51" />
- <view class="badge" v-if="hasNewMessage"></view>
- </view>
- <text class="function-name">留言</text>
- </view>
- <view class="function-item" @click="goToInOut">
- <view class="function-icon">
- <Icon name="icon-duihuapaopao2" size="60" color="#393f51" />
- <view class="badge" v-if="hasNewRecord"></view>
- </view>
- <text class="function-name">进出</text>
- </view>
- <view class="function-item" @click="goToBzrDm">
- <view class="function-icon">
- <Icon name="icon-dianming" size="60" color="#8992ef"/>
- </view>
- <text class="function-name">班主任点名</text>
- </view>
- <view class="function-item" @click="goXuncha">
- <view class="function-icon">
- <Icon name="icon-xuncha" size="60" color="#475fab" />
- </view>
- <text class="function-name">巡查</text>
- </view>
- <view class="function-item" @click="goToXfjl">
- <view class="function-icon">
- <Icon name="icon-xiaofeijilu" size="60" color="#c48c21" />
- </view>
- <text class="function-name">消费记录</text>
-
- </view>
-
- <view class="function-item" >
- <view class="function-icon">
- </view>
- <text class="function-name"></text>
- </view>
- <view class="function-item" >
- <view class="function-icon">
- </view>
- <text class="function-name"></text>
- </view>
- <view class="function-item" >
- <view class="function-icon">
- </view>
- <text class="function-name"></text>
- </view>
- <view class="function-item" >
- <view class="function-icon">
- </view>
- <text class="function-name"></text>
- </view>
- <view class="function-item" >
- <view class="function-icon">
- </view>
- <text class="function-name"></text>
- </view>
- <view class="function-item" >
- <view class="function-icon">
- </view>
- <text class="function-name"></text>
- </view>
- <view class="function-item" >
- <view class="function-icon">
- </view>
- <text class="function-name"></text>
- </view>
- </view>
- </view>
- </view>
- <LoginPopup />
- <!-- 底部导航栏,登录后才显示 -->
- <Tabbar v-show="isLogin"/>
- </template>
- <script setup>
- import { ref, computed } from 'vue'
- import { useUserStore } from '@/store/modules/user'
- import websocketService from '@/utils/websocket'
- import Icon from '@/components/icon/index.vue';
- import { onShow, onHide, onLoad, onUnload } from '@dcloudio/uni-app'
- // 组件导入
- import Tabbar from '@/components/tabbar/index.vue'
- import LoginPopup from '@/components/login/LoginPopup.vue'
- const userStore = useUserStore();
- const hasNewMessage = ref(false);
- const currentStudentIndex = ref(0);
- const isLogin = ref(false);
- const studentIds = ref([]);
- const students = ref([
- {
- id: 0,
- name: '请先登录',
- className: '请先登录',
- avatar: '/static/logo.png'
- },
-
- ])
- const goXuncha = () => {
- if (!checkLogin()) {
- pleaseLogin()
- return
- }
- uni.navigateTo({
- url: '/pages/xuncha/mp_excelRcXcdjl_edit'
- })
- }
- const checkLogin = () => {
- const userInfo = uni.getStorageSync('userInfo')
- console.log('userInfo', userInfo)
- if (!userInfo || !userInfo.yhsbToken) {
- return false
- }
- return true
- }
- const pleaseLogin = () => {
- uni.showToast({
- title: '请先登录',
- icon: 'none'
- })
- userStore.showLoginPopup()
- }
- const onSwiperChange = (e) => {
- currentStudentIndex.value = e.detail.current;
- }
- const onSwiperClick = (studentId) => {
- if (studentId == 0) {
- pleaseLogin()
- }
- }
- const goToInOut = () => {
- if (checkLogin()) {
- // 获取当前学生ID
- const currentStudentId = students.value[currentStudentIndex.value].id;
- // 检查 studentIds 数组中是否存在当前学生ID
- const index = studentIds.value.indexOf(currentStudentId);
- if (index !== -1) {
- // 如果存在,才从数组中移除
- this.studentIds.splice(index, 1);
- }
- uni.navigateTo({
- url: '/pages/parent/in-out?role=parent&studentId=' + students.value[currentStudentIndex.value].id
- })
- } else {
- pleaseLogin()
- }
- }
- const goToMessage = () => {
- if (checkLogin()) {
- uni.navigateTo({
- url: '/pages/parent/message?role=parent'
- })
- } else {
- pleaseLogin()
- }
- }
- const goToBzrDm = () => {
- if (checkLogin()) {
- uni.navigateTo({
- url: '/pages/kqjl/kqjl_bzrDm_list'
- })
- } else {
- pleaseLogin()
- }
- }
- const goToXfjl = () => {
- if (checkLogin()) {
- uni.navigateTo({
- url: '/pages/xfjl/index'
- })
- } else {
- pleaseLogin()
- }
- }
- const hasNewRecord = computed(() => {
- // 获取当前选中的学生ID
- const currentStudentId = students[currentStudentIndex.value]?.id;
- // 如果当前没有选中学生,返回 false
- if (!currentStudentId) return false;
- // 检查当前学生ID是否在 studentIds 数组中
- return this.studentIds.includes(currentStudentId);
- })
- const openPopup = () => {
- // 获取用户的当前设置,判断是否点击了“总是保持以上,不在询问”
- uni.getSetting({
- withSubscriptions: true, // 是否获取用户订阅消息的订阅状态,默认false不返回
- success(res) {
- console.log('res.authSetting', res)
- if (res.subscriptionsSetting['zrGisuG52Prtk7eJGLb_zZy9EDnglEEtaEhTi3y0VDc'] == 'accept') {
- console.log('用户点击了“总是保持以上,不再询问”')
- } else {
- console.log('用户没有点击“总是保持以上,不再询问”则每次都会调起订阅消息')
- //因为没有选择总是保持,所以需要调起授权弹窗再次授权
- authorizationBtn();
- }
- }
- })
- }
- const authorizationBtn = () => {
- console.log('authorizationBtn')
- uni.requestSubscribeMessage({
- tmplIds: ['zrGisuG52Prtk7eJGLb_zZy9EDnglEEtaEhTi3y0VDc'],
- success(res) {
- console.log(res)
- if (res['zrGisuG52Prtk7eJGLb_zZy9EDnglEEtaEhTi3y0VDc'] == 'accept') {
- console.log("成功")
- } else {
- console.log("拒绝")
- }
- }
- })
- }
- const requestDeviceAuth = async () => {
- try {
- // 先检查是否已授权
- const voipList = await new Promise((resolve, reject) => {
- uni.getDeviceVoIPList({
- success: res => resolve(res.list),
- fail: err => reject(err)
- })
- })
- console.log('voipList', voipList)
- // 如果已授权,直接返回
- if (voipList.some(device => device.status === 1)) {
- return true
- }
- // 获取设备票据(需要后端接口支持)
- // const ticketData = await userApi.getDeviceTicket()
- // 请求设备授权
- await new Promise((resolve, reject) => {
- uni.requestDeviceVoIP({
- isGroup: true,
- groupId: 'gbfI8Bx4yzDQ-v0Ngv03WOw',
- success: res => {
- console.log('授权成功:', res)
- },
- fail: err => {
- console.error('授权失败:', err)
- if (err.errCode === 9) {
- uni.showModal({
- title: '提示',
- content: '请在设置中开启设备通话权限',
- success: () => {
- uni.openSetting()
- }
- })
- }
- reject(err)
- }
- })
- })
- return true
- } catch (error) {
- console.error('设备授权处理失败:', error)
- return false
- }
- }
- const getUserInfo = async () => {
- const userInfo = uni.getStorageSync('userInfo')
- const userMoreInfo = await userApi.getUserInfo(userInfo.userId)
- console.log('userMoreInfo', userMoreInfo)
- this.nickname = userMoreInfo.username
- this.avatarUrl = userMoreInfo.avatar
- this.students = userMoreInfo.students || []
- }
- const handleInit = (data) => {
- console.log('handleInit', data)
- studentIds.value = data.studentIds || [];
- }
- const handleNewMessage = (data) => {
- console.log('handleNewMessage', data)
- if (!studentIds.value.includes(data.studentId)) {
- studentIds.value.push(data.studentId);
- }
- }
- const handleNewRecord = (data) => {
- console.log('handleNewRecord', data)
- }
- // 如果是一开始没登陆,然后登录了 都进这个事件
- const handLogin = (data) => {
- isLogin.value = true
- // requestDeviceAuth()
- // getUserInfo()
- // websocketService.connect()
- uni.$on('init', handleInit)
- uni.$on('newMessage', handleNewMessage)
- uni.$on('newRecord', handleNewRecord)
- students.value[0] = {
- id: 1,
- name: '已登录',
- className: '已登录',
- avatar: '/static/logo.png'
- }
- }
- onLoad(async () => {
- // 监听登录事件
- uni.$on('login',handLogin)
- if (checkLogin()) {
- // 如果已经登录,则执行登录后的操作
- handLogin()
- } else {
- isLogin.value = false
- }
- })
- onUnload(async () => {
- uni.$off('newMessage', handleNewMessage)
- uni.$off('newRecord', handleNewRecord)
- // websocketService.disconnect()
- })
- </script>
- <style lang="scss">
- .wx-swiper-dots.wx-swiper-dots-horizontal {
- width: calc(100% - 90rpx);
- display: flex;
- justify-content: flex-end;
- display: none;
- }
- .show-dots .wx-swiper-dots.wx-swiper-dots-horizontal{
- display: flex;
- }
- .wx-swiper-dot {
- border: 2rpx solid #666666 !important;
- background: #ffffff !important;
- }
- .wx-swiper-dot-active {
- background: #666666 !important;
- }
- .container {
- padding: 30rpx;
- }
- .student-swiper {
- height: 250rpx;
- margin-top: 40rpx;
- margin-bottom: 40rpx;
- border-bottom: 2rpx solid #dcdcdc;
- }
- .student-card {
- box-sizing: border-box;
- display: flex;
- align-items: center;
- padding: 30rpx;
- background: #FFFFFF;
- border-radius: 12rpx;
- box-shadow: 0rpx 6rpx 15rpx rgba(0, 0, 0, .3);
- margin: 10rpx 15rpx;
- }
- .student-avatar {
- width: 124rpx;
- height: 124rpx;
- border-radius: 50%;
- margin-right: 20rpx;
- }
- .student-info {
- display: flex;
- flex-direction: column;
- }
- .student-name {
- font-size: 36rpx;
- font-weight: bold;
- color: #333333;
- margin-bottom: 8rpx;
- }
- .student-class {
- font-size: 30rpx;
- color: #666666;
- }
- .function-list {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- gap: 30rpx;
- }
- .function-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- width: 135rpx;
- font-size: 28.87 rpx;
- color: #333333;
- }
- .function-icon {
- position: relative;
- width: 100rpx;
- height: 100rpx;
- background: #ffffff;
- border: 2rpx solid #e9e9e9;
- box-shadow: 5rpx 5rpx 10rpx rgba(0, 0, 0, .3);
- border-radius: 10rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 10rpx;
- }
- .function-icon image {
- width: 60rpx;
- height: 60rpx;
- }
- .badge {
- position: absolute;
- top: 1rpx;
- right: 1rpx;
- width: 20rpx;
- height: 20rpx;
- background: #eb6100;
- border-radius: 50%;
- }
- .function-name {
- font-size: 26rpx;
- color: #333333;
- }
- .login-btn {
- width: 100%;
- height: 88rpx;
- line-height: 88rpx;
- background: #666666;
- color: #fff;
- border-radius: 44rpx;
- font-size: 32rpx;
- border: none;
- }
- .login-btn::after {
- border: none;
- }
- .login-btn:active {
- opacity: 0.8;
- }
- </style>
|