| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010 |
- <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">
- <view class="student-card-left">
- <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>
- <view @click.stop="handleScan()" class="scan-btn" v-if="isLogin">
- <Icon name="icon-saoyisao2" size="72" color="#bfbfbf" />
- <text>扫一扫</text>
- </view>
- </view>
- </swiper-item>
- </swiper>
- <!-- 登录之后 -->
- <view class="container" v-if="isLogin">
- <view class="function-list">
- <!-- 充值功能 -->
- <view class="function-item" @click="goToRecharge">
- <view class="function-icon recharge-icon">
- <Icon name="icon-qianbao" size="60" color="#07c160" />
- </view>
- <text class="function-name">充值</text>
- </view>
- <!-- 呼叫留言 -->
- <view class="function-item" @click="goToCallCenter">
- <view class="function-icon">
- <Icon name="icon-dianhua" size="60" color="#ff9f43" />
- </view>
- <text class="function-name">呼叫留言</text>
- </view>
- <!-- 留言功能 -->
- <!-- <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="goToBzrDmWebview">
- <view class="function-icon">
- <Icon name="icon-dianming" size="60" color="#8992ef" />
- </view>
- <text class="function-name">班主任点名</text>
- </view> -->
- <view class="function-item" v-for="item in btnList" :key="item.id" @click="commonBtnClick(item)">
- <view class="function-icon">
- <image :src="getFullIconUrl(item.icon)" mode="aspectFill"></image>
- </view>
- <text class="function-name">{{ item.desc }}</text>
- </view>
- <!-- <view class="function-item" @click="goToDmWebview">
- <view class="function-icon">
- <Icon name="icon-dianming" size="60" color="#8992ef"/>
- </view>
- <text class="function-name">点名</text>
- </view> -->
- <view class="function-item" @click="goToXunChaWebview">
- <view class="function-icon">
- <Icon name="icon-xuncha" size="60" color="#475fab" />
- </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" @click="goToTestList">
- <view class="function-icon">
- <Icon name="icon-dianming" size="60" color="#ff6b6b"/>
- </view>
- <text class="function-name">测试通用列表</text>
- </view> -->
- <!-- <view class="function-item" @click="goToClyyWebview">
- <view class="function-icon">
- <Icon name="icon-cheliangyuyue" size="60" color="#54a400" />
- </view>
- <text class="function-name">车辆预约</text>
- </view> -->
- <!-- 测试订阅消息跳转 -->
- <!-- <view class="function-item" @click="goToNoticeRedirect">
- <view class="function-icon">
- <Icon name="icon-xiaoxi" size="60" color="#ff6b6b" />
- </view>
- <text class="function-name">测试订阅跳转</text>
- </view> -->
- <!-- <view class="function-item" @click="goToLoginTest">
- <view class="function-icon">
- <Icon name="icon-denglu" size="60" color="#40ac6d" />
- </view>
- <text class="function-name">登录测试(H5)</text>
- </view>-->
-
- </view>
- </view>
- <!-- 未登录显示 -->
- <view class="unlogin" v-else>
- <image :src="unloginImageUrl" mode="aspectFit" />
- </view>
- <!-- 登录确认弹窗 -->
- <LoginConfirmModal
- ref="loginConfirmModalRef"
- v-model:visible="showLoginConfirm"
- :loginType="currentLoginType"
- @confirm="handleLoginConfirm"
- @cancel="handleLoginCancel"
- />
- </view>
- </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 { goTo } from '@/utils/navigation'
- import { userApi } from '@/api/user';
- import { commonApi } from '@/api/common'
- import env from '@/config/env.js'
- import { getImageUrl } from '@/utils/util'
- // 组件导入
- import LoginPopup from '@/components/login/LoginPopup.vue'
- import LoginConfirmModal from '@/components/LoginConfirmModal/index.vue'
- const userStore = useUserStore();
- const hasNewMessage = ref(false);
- const currentStudentIndex = ref(0);
- const isLogin = ref(false);
- let userInfo = uni.getStorageSync('userInfo') || {};
- const messageListenersBound = ref(false)
- const studentIds = ref([]);
- const unloginImageUrl = "/static/images/unlogin.jpg";
- const students = ref([
- {
- id: 0,
- name: '请登录',
- className: '',
- avatar: '/static/logo.png'
- }
- ])
- // 登录确认弹窗相关
- const loginConfirmModalRef = ref(null)
- const showLoginConfirm = ref(false)
- const currentLoginType = ref({})
- const pendingLoginData = ref(null)
- const templateId = 'rVi7erjgdVRVBMgIhhHgPu9JMp3TM7Ug30x1ycAXY0w'
- // 登录类型配置映射
- const LOGIN_TYPE_MAP = {
- 1: { // PC端
- systemName: 'PC管理系统',
- title: '扫码登录',
- tip: '确认登录PC端管理系统吗?',
- icon: '/static/logo.png',
- },
- 2: { // 门系统
- systemName: '门禁系统',
- title: '扫码登录',
- tip: '确认登录门禁系统吗?',
- icon: '/static/logo.png',
- }
- // 未来可以继续扩展其他系统...
- }
- const btnList = ref([])
- const getFullIconUrl = (icon) => {
- return `${env.baseUrl}/skin/mp_easy/icon/${icon}.svg`
- }
- const commonBtnClick = (item) => {
- if (!checkLogin()) {
- pleaseLogin()
- return
- }
- console.log(`准备进入 ${item.desc},先检查订阅消息`)
- // 先处理订阅,订阅完成后再跳转
- openPopup(() => {
- console.log('订阅处理完成,准备跳转')
- goTo('/pages/common/webview', {
- dest: item.dest,
- title: item.desc,
- service: item.init
- })
- })
- }
- const goXuncha = () => {
- if (!checkLogin()) {
- pleaseLogin()
- return
- }
- }
- // 跳转到充值页面
- const goToRecharge = () => {
- if (!checkLogin()) {
- pleaseLogin()
- return
- }
- goTo('/pages/payment/recharge')
- }
- const goToCallCenter = () => {
- if (!checkLogin()) {
- pleaseLogin()
- return
- }
- goTo('/pages/parent/call-center')
- }
- const checkLogin = () => {
- if (typeof userInfo == 'string') {
- userInfo = JSON.parse(userInfo)
- }
- // console.log('userInfo', userInfo)
- if (!userInfo || !userInfo.yhsbToken) {
- return false
- }
- return true
- }
- const pleaseLogin = () => {
- uni.showToast({
- title: '请先登录',
- icon: 'none'
- })
- // 跳转到H5登录页面
- userStore.showH5Login()
- }
- // 扫码功能
- const handleScan = () => {
- console.log('handleScan')
- if (!checkLogin()) {
- pleaseLogin()
- return
- }
- // 调用微信小程序扫码API
- uni.scanCode({
- onlyFromCamera: false, // 允许从相册选择二维码图片
- scanType: ['qrCode', 'barCode'], // 支持二维码和条形码
- success: async (res) => {
- try {
- console.log('扫码结果:', res)
- const jsonStr = '{' + res.result.replace(/(\w+):/g, '"$1":') + '}';
- const obj = JSON.parse(jsonStr);
- console.log('扫码结果:', res, obj)
- // 获取登录类型配置
- const loginType = LOGIN_TYPE_MAP[obj.ss]
- if (!loginType) {
- uni.showToast({
- title: '不支持的登录类型',
- icon: 'none'
- })
- return
- }
- // 保存待处理的登录数据
- pendingLoginData.value = obj
- // 设置当前登录类型并显示确认弹窗
- currentLoginType.value = loginType
- showLoginConfirm.value = true
- } catch (error) {
- console.error('解析扫码结果失败:', error)
- uni.showToast({
- title: '二维码格式错误',
- icon: 'none'
- })
- }
- },
- fail: (err) => {
- console.error('扫码失败:', err)
- if (err.errMsg && err.errMsg.indexOf('cancel') === -1) {
- uni.showToast({
- title: '扫码失败',
- icon: 'none'
- })
- }
- }
- })
- }
- // 确认登录
- const handleLoginConfirm = async () => {
- if (!pendingLoginData.value) return
- const obj = pendingLoginData.value
- let resp = null
- try {
- uni.showLoading({
- title: '登录中...',
- mask: true
- })
- if (obj.ss == 1) { // PC端
- console.log('pc扫码登录')
- resp = await userApi.sacnLoginQrcode({ k: obj.k })
- } else if (obj.ss == 2) { // 门系统
- console.log('门系统扫码登录')
- resp = await userApi.sacnGateLoginQrcode({ k: obj.k })
- }
- console.log('扫码登录结果:', resp)
- uni.hideLoading()
- uni.showToast({
- title: '登录成功',
- icon: 'success'
- })
- } catch (error) {
- uni.hideLoading()
- console.error('登录失败:', error)
- uni.showToast({
- title: error.message || '登录失败',
- icon: 'none'
- })
- } finally {
- pendingLoginData.value = null
- }
- }
- // 取消登录
- const handleLoginCancel = () => {
- pendingLoginData.value = null
- console.log('用户取消登录')
- }
- const onSwiperChange = (e) => {
- currentStudentIndex.value = e.detail.current;
- }
- const onSwiperClick = (studentId) => {
- if (studentId == 0) {
- pleaseLogin()
- }else{
- goTo('/pages/my/changeInfo')
- }
- }
- 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()) {
- // 跳转到通用列表页面,传递班主任点名的配置
- const config = {
- ssServ: 'bjdm_cx',
- title: '班主任点名',
- baseParams: {}
- }
- const url = `/pages/bjdm/bjdm_bzrDm_list`
- goTo(url)
- } else {
- pleaseLogin()
- }
- }
- const goToTestList = () => {
- if (checkLogin()) {
- // 测试通用列表页面,可以传递不同的服务配置
- const config = {
- ssServ: 'bjdm_cx', // 可以改成其他服务测试
- title: '测试通用列表页面',
- baseParams: {
- // 可以添加额外的查询参数
- testParam: 'test'
- }
- }
- const url = `/pages/common/list?ssServ=${config.ssServ}&baseParams=${encodeURIComponent(JSON.stringify(config.baseParams))}`
- uni.navigateTo({
- url: url
- })
- } else {
- pleaseLogin()
- }
- }
- const goToXfjl = () => {
- if (checkLogin()) {
- uni.navigateTo({
- url: '/pages/xfjl/index'
- })
- } else {
- pleaseLogin()
- }
- }
- const goToClyy = () => {
- if (checkLogin()) {
- const yhid = uni.getStorageSync('userInfo').yhid
- // 测试通用列表页面,可以传递不同的服务配置
-
- // const url = `/pages/common/list?ssServ=${config.ssServ}&baseParams=${encodeURIComponent(JSON.stringify(config.baseParams))}`
- // goTo(url)
- goTo('/pages/clyy/clyy_inp')
- } else {
- pleaseLogin()
- }
- }
- const goToClyyWebview = () => {
- if (!checkLogin()) {
- pleaseLogin()
- return
- }
- console.log('准备进入车辆预约,先检查订阅消息')
- // 先处理订阅,订阅完成后再跳转
- openPopup(() => {
- console.log('订阅处理完成,准备跳转到车辆预约页面')
- goTo('/pages/common/webview', {
- dest: 'mp_clyy_inp',
- title: '车辆预约',
- })
- })
- }
- const goToXunChaWebview = () => {
-
- const testParams = {
- dest: 'mp_rcXcdjl_excelZxxzAdd', // 测试用的dest参数
- ssToken: '1b298017d5764bb39708ab3724739cbe', // 测试用的ssToken
- // 可以添加其他测试参数
- title: '校长巡查',
- }
- // 构建跳转URL
- const queryString = Object.keys(testParams)
- .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(testParams[key])}`)
- .join('&')
- // 跳转到redirect页面
-
- if (checkLogin()) {
- goTo(`/pages/common/webview?${queryString}`)
- // goTo('/pages/common/webview', {
- // dest: 'mp_excelRcXcdjl_edit',
-
- // ssToken: '39101b19b2c545b2a62c72177e033cc5',
- // })
- } else {
- pleaseLogin()
- }
- }
- const goToBzrDmWebview = () => {
- if (checkLogin()) {
- goTo('/pages/common/webview', {
- dest: 'mp_objList',
- title: '班主任点名(webview)',
- service: 'bjdm_cx'
- })
- // goTo('/pages/common/webview', {
- // dest: 'upload-image-demo',
-
- // })
- } else {
- pleaseLogin()
- }
- }
- const goToDmWebview = () => {
- goTo('/pages/common/webview', {
- dest: 'bjdm_bzrDm',
- title: '班主任点名(webview)',
- })
- }
- const goToLoginTest = () => {
- // console.log('🔐 跳转到H5登录测试页面')
- goTo('/pages/common/webview', {
- dest: 'login',
- title: '登录'
- })
- }
- // 测试订阅消息跳转
- const goToNoticeRedirect = () => {
- // 模拟订阅消息的参数,可以测试不同的dest和ssToken
- const testParams = {
- dest: 'mp_ccChk', // 测试用的dest参数
- ssToken: '5d8c4af16247457fbd9ea71f5982a733', // 测试用的ssToken
- // 可以添加其他测试参数
- testParam: 'test'
- }
- // 构建跳转URL
- const queryString = Object.keys(testParams)
- .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(testParams[key])}`)
- .join('&')
- // 跳转到redirect页面
- goTo(`/pages/common/webview?${queryString}`)
- }
- const hasNewRecord = computed(() => {
- // 获取当前选中的学生ID
- const currentStudentId = students[currentStudentIndex.value]?.id;
- // 如果当前没有选中学生,返回 false
- if (!currentStudentId) return false;
- // 检查当前学生ID是否在 studentIds 数组中
- return this.studentIds.includes(currentStudentId);
- })
- const openPopup = (callback) => {
- // console.log('openPopup 被调用')
- // 获取用户的当前设置,判断是否点击了"总是保持以上,不在询问"
- uni.getSetting({
- withSubscriptions: true, // 是否获取用户订阅消息的订阅状态,默认false不返回
- success(res) {
- // console.log('获取设置成功:', res)
- console.log('订阅设置:', res.subscriptionsSetting)
-
- if (res.subscriptionsSetting && res.subscriptionsSetting[templateId] === 'accept') {
- // console.log('用户已经同意订阅该模板消息')
- // // 已订阅,直接执行回调
- callback && callback()
- } else {
- console.log('用户未同意订阅或设置不存在,调起订阅消息弹窗')
- //因为没有选择总是保持,所以需要调起授权弹窗再次授权
- authorizationBtn(callback);
- }
- },
- fail(err) {
- console.error('获取设置失败:', err)
- // 获取设置失败,也尝试调起订阅弹窗
- authorizationBtn(callback);
- }
- })
- }
- const authorizationBtn = (callback) => {
- console.log('authorizationBtn')
- uni.requestSubscribeMessage({
- // tmplIds: ['5piwpV8roTajn7Mo2NrBpTjFTXwWEr002Ho-rw4HGQw'],
- tmplIds: [templateId],
- success(res) {
- console.log('订阅消息请求结果:', res)
- // const templateId = '5piwpV8roTajn7Mo2NrBpTjFTXwWEr002Ho-rw4HGQw'
- if (res[templateId] === 'accept') {
- console.log('用户同意订阅消息')
- uni.showToast({
- title: '订阅成功',
- icon: 'success'
- })
- } else {
- console.log('用户拒绝订阅消息')
- }
- // 无论用户是否同意,都执行回调
- callback && callback()
- },
- fail(err) {
- console.error('订阅消息请求失败:', err)
- // 失败也执行回调
- callback && callback()
- }
- })
- }
- 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: 'gUpNA_xJr-WkYBIeGofWSPQ',
- 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 () => {
- let userInfo = uni.getStorageSync('userInfo')
- if (typeof userInfo === 'string'){
- userInfo = JSON.parse(userInfo)
- }
- const userMoreInfo = await userApi.mp_infoHomep_load(userInfo.userId)
- console.log('userMoreInfo', userMoreInfo.data.ryInfo, typeof userMoreInfo.data.ryInfo)
- btnList.value = JSON.parse(userMoreInfo.data.btnList) // 更新按钮列表
-
- const rylbm = userMoreInfo.data.ryInfo?.rylbm;
- let huixian = '已登录';
- if (userMoreInfo.data.ryInfo?.bjid) { // 有班级id 优先班级
- const bjid = userMoreInfo.data.ryInfo?.bjid
- const bj = await commonApi.getDictByCbNameAndValue('bj', bjid)
- huixian = bj.data.result[bjid]
-
- }else if(userMoreInfo.data.ryInfo?.bmid){ // 教职工
- const bmid = userMoreInfo.data.ryInfo?.bmid
- const bm = await commonApi.getDictByCbNameAndValue('bm', bmid)
- huixian = bm.data.result[bmid]
- }else {
- huixian = '已登录'
- }
- // 如果有头像的话,则直接取头像
- if (userMoreInfo.data.ryInfo?.yszwj) {
- const avatar = getImageUrl(userMoreInfo.data.ryInfo.yszwj)
- students.value[0] = {
- id: 1,
- name: userInfo.xm,
- className: huixian,
- avatar: avatar
- }
- } else {
- // 如果性别码码为1,则取性别为男的头像 否则取性别为女
- if (userMoreInfo.data.ryInfo?.xbm == 1) {
- students.value[0] = {
- id: 1,
- name: userInfo.xm,
- className: huixian,
- avatar: '/static/images/yishuzhao_nan.svg'
- }
- } else {
- students.value[0] = {
- id: 1,
- name: userInfo.xm,
- className: huixian,
- avatar: '/static/images/yishuzhao_nv.svg'
- }
- }
- }
- let ryInfo = userMoreInfo.data.ryInfo
-
- console.log('ryInfo', ryInfo)
- uni.setStorageSync('userInfo', {
- ...userInfo,
- ...ryInfo,
- }) // 更新用户信息
-
- }
- 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()
- if (!messageListenersBound.value) {
- uni.$on('init', handleInit)
- uni.$on('newMessage', handleNewMessage)
- uni.$on('newRecord', handleNewRecord)
- messageListenersBound.value = true
- }
- }
- const handleOnShow = () => {
- // console.log('首页显示')
- uni.$on('login', handLogin)
- if (checkLogin()) {
- // 如果已经登录,则执行登录后的操作
- handLogin()
- } else {
- isLogin.value = false
- }
- }
- const handleOnHide = () => {
- // console.log('首页隐藏')
- }
- const handleOnLoad = () => {
- // console.log('首页加载')
- // 监听登录事件(只绑定一次)
- uni.$on('login', handLogin)
- if (checkLogin()) {
- // 如果已经登录,则执行登录后的操作
- handLogin()
- } else {
- isLogin.value = false
- }
- }
- const handleOnUnload = () => {
- // console.log('首页卸载')
- if (messageListenersBound.value) {
- uni.$off('newMessage', handleNewMessage)
- uni.$off('newRecord', handleNewRecord)
- messageListenersBound.value = false
- }
- // websocketService.disconnect()
- }
- // 暴露生命周期方法供主容器调用(主容器会调用这些而非页面级 onLoad/onShow)
- defineExpose({
- onShow: handleOnShow,
- onHide: handleOnHide,
- onLoad: handleOnLoad,
- onUnload: handleOnUnload
- })
- </script>
- <style lang="scss">
- .wx-swiper-dots.wx-swiper-dots-horizontal {
- width: calc(100% - 90rpx);
- display: flex;
- justify-content: flex-end;
- display: none;
- 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 {
- border-top: 2rpx solid #dcdcdc;
- padding: 30rpx;
- }
- .student-swiper {
- height: 250rpx;
- margin-top: 40rpx;
- // margin-bottom: 40rpx;
- }
- .student-card {
- box-sizing: border-box;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 30rpx;
- background: #FFFFFF;
- border-radius: 12rpx;
- box-shadow: 0rpx 6rpx 15rpx rgba(0, 0, 0, .3);
- margin: 10rpx 15rpx;
- }
- .student-card-left{
- display: flex;
- align-items: center;
- width: 70%;
- }
- .student-avatar {
- width: 124rpx;
- height: 124rpx;
- border-radius: 50%;
- margin-right: 20rpx;
- border: 2rpx solid #eee;
- flex-shrink: 0;
- }
- .student-info {
- height: 100rpx;
- display: flex;
- flex-direction: column;
- justify-content: flex-start;
- width: calc(100% - 124rpx);
- }
- .student-name {
- font-size: 36rpx;
- font-weight: bold;
- color: #333333;
- margin-bottom: 8rpx;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .student-class {
- font-size: 30rpx;
- color: #666666;
- }
- .scan-btn{
- display: flex;
- justify-content: center;
- align-items: center;
- flex-direction: column;
- color:#999999;
- font-size: 32rpx;
- gap: 4rpx;
- border-left: 2rpx solid #dcdcdc;
- padding-left: 40rpx;
- padding-right: 10rpx;
- flex-shrink: 0;
- }
- .function-list {
- display: grid;
- grid-template-columns: repeat(4, 1fr);
- gap: 30rpx;
- // padding: 0 20rpx;
- }
- .function-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- font-size: 28.87rpx;
- 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;
- }
- .unlogin {
- width: 100%;
- height: calc(100vh - 226rpx);
- image {
- width: 100%;
- height: 100%;
- }
- }
- </style>
|