index.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. import {
  2. defineComponent,
  3. onMounted,
  4. onUnmounted,
  5. reactive,
  6. ref,
  7. nextTick
  8. } from 'vue';
  9. import styles from './index.module.less';
  10. // import signinTips from './images/signin-tips.png';
  11. import {
  12. Button,
  13. CellGroup,
  14. Field,
  15. Picker,
  16. Popup,
  17. closeToast,
  18. showToast,
  19. Loading
  20. } from 'vant';
  21. import { useRoute, useRouter } from 'vue-router';
  22. import threeMan from './images/update/three-man.png';
  23. import OWxTip from '@/components/m-wx-tip';
  24. import { browser, getHttpOrigin, getUrlCode } from '@/helpers/utils';
  25. import qs from 'query-string';
  26. import request from '@/helpers/request';
  27. import { goWechatAuth, goWechatAuthTemp } from '@/state';
  28. import { useInterval, useIntervalFn } from '@vueuse/core';
  29. import MMessageTip from '@/components/m-message-tip';
  30. import TCPlayer from 'tcplayer.js';
  31. import 'tcplayer.js/dist/tcplayer.css';
  32. import { _initVideo } from './initVideo';
  33. import nextBtn from './images/next_btn.png';
  34. import useWeChatShare from '@/hooks/useWeChatShare';
  35. export default defineComponent({
  36. name: 'intention-questionnaire',
  37. setup() {
  38. const route = useRoute();
  39. const shareTitle = route.query.type === 'primarySchoolNo' ? '(小学)关于开展音乐(器乐)课堂数字化转型的调查问卷' :
  40. route.query.type === 'juniorSchoolNo' ? '(初中)关于开展音乐(器乐)课堂数字化转型的调查问卷' :
  41. '关于开展音乐(器乐)课堂数字化转型的调查问卷'
  42. const weChatShare = useWeChatShare(
  43. shareTitle,
  44. '科学的教育改变世界,科技的力量让音乐传播更远,让孩子奏响心中的乐章',
  45. window.location.origin + '/classroom-app/shareImg/question-share.png'
  46. );
  47. // 页面定时
  48. const pageTimer = useInterval(1000, { controls: true });
  49. pageTimer.pause();
  50. const router = useRouter();
  51. const forms = reactive({
  52. loading: true,
  53. code: null as any,
  54. openId: '' as any,
  55. isPageHide: false,
  56. contentA:
  57. '<p style="text-align: left; font-size:13px;"><strong style="font-size:15px;">尊敬的家长: 您好!</strong></p><p style="text-align: left;">非常感谢您一直以来对学校工作给予的大力支持与密切关注。为深入贯彻教育部《关于全面实施学校美育浸润行动的通知》(教体艺〔2023〕5 号)文件精神,积极顺应艺术素质测评结果纳入中考的教育改革趋势,致力于让学生在在校期间熟练掌握 1 - 2 项艺术专长,全面提升学生的艺术素养。</p><p style="text-align: left;">我校计划在北京知勉公益基金会的支持下,启动音乐(器乐)课堂数字化转型工作。为了确保此项工作顺利开展,现向您详细介绍相关情况,并诚恳征询您的宝贵意见,学校将根据您的意见反馈决定开展与否。</p>', // 第一段
  58. contentB:
  59. '<p style="text-align: left;"><strong style="font-size:15px; color: #0B8BFE;">二、为什么要开展数字化转型</strong></p><p style="text-align: left;">1.解决学习难题:数字化转型将为乐器学习和练习制定明确标准,学生能实时知晓练习的对错,练习结果也可量化呈现,有效解决学生不会练、家长无法辅导的困扰。</p><p style="text-align: left;">2.适应教改趋势:随着教育改革的推进,艺术素质测评结果已逐步纳入中考,数字化转型将助力学生更好地适应这一变化,提升综合素养。</p><p style="text-align: left;">3.关注身心健康:乐器学习能成为学生缓解学习压力的有效途径,有助于学生保持身心健康,实现全面发展。</p><p style="text-align: left;"><br></p>', // 第二段
  60. contentC:
  61. '<p style="text-align: left;"><strong style="font-size:15px; color: #0B8BFE;">三、开展原则</strong></p><p style="text-align: left;">本次活动面向全体学生,完全遵循学生自愿参加的原则。</p><p style="text-align: left;">1.若学生选择参加转型,家长需自行为学生准备好自用的乐器(硬件)和“器乐数字 Ai”应用(软件,用于联通学校音乐课堂)两项学习工具。</p><p style="text-align: left;">2.若学生不参加转型,可继续按原有方式进行音乐课学习。</p>',
  62. contentD:
  63. '<p style="text-align: left;"><strong style="font-size:15px; color: #0B8BFE;">五、事项说明</strong></p><p style="text-align: left;">1.学校不涉及任何费用收取。学生所需的自用工具在市面上均可购买到,家长可自行根据实际情况为学生准备。</p><p style="text-align: left;">2.如学生有参加数字化转型的意愿,但存在特殊或特困情况,可先向学校进行登记,学校将尽力寻求资源协助家长解决。</p><p style="text-align: left;">在您了解上述内容后,请点击下一步进行意见填写:</p>',
  64. introductionVideo: 'https://oss.dayaedu.com/ktyq/02/1739345029052.mp4',
  65. introductionVideoTime: 117,
  66. coverImg: 'https://oss.dayaedu.com/ktyq/02/1739362815061.png',
  67. introductionVideo2: 'https://oss.dayaedu.com/ktyq/02/1739345326291.mp4',
  68. introductionVideoTime2: 111,
  69. coverImg2: 'https://oss.dayaedu.com/ktyq/02/1739324215341.png',
  70. player1: null as any,
  71. player2: null as any,
  72. player1Speed: 1,
  73. player2Speed: 1,
  74. videoLoading1: true,
  75. videoLoading2: true,
  76. meetingType: 'primarySchoolNo' as
  77. | 'primarySchoolNo'
  78. | 'primarySchoolYes'
  79. | 'juniorSchoolNo'
  80. | 'juniorSchool'
  81. | any,
  82. intentionInfo: null as any,
  83. contentShow: false
  84. });
  85. const showPopup = ref(false);
  86. const showPopupMessage = ref('');
  87. // 播放视频总时长
  88. const videoIntervalRef = useInterval(1000, { controls: true });
  89. videoIntervalRef.pause();
  90. const videoIntervalRef2 = useInterval(1000, { controls: true });
  91. videoIntervalRef2.pause();
  92. onMounted(async () => {
  93. forms.meetingType = route.query.type || forms.meetingType;
  94. forms.code = route.query.code || forms.code;
  95. // nextTick(() => {
  96. // const videoRef: any = document.querySelector('#register-video')
  97. // const videoRef2: any = document.querySelector('#register-video2')
  98. // if(videoRef) {
  99. // const rect = videoRef?.getBoundingClientRect()
  100. // console.log(rect)
  101. // videoRef.style.height = rect.width / 16 * 9 + 'px'
  102. // }
  103. // if(videoRef2) {
  104. // const rect = videoRef2?.getBoundingClientRect()
  105. // console.log(rect)
  106. // videoRef2.style.height = rect.width / 16 * 9 + 'px'
  107. // }
  108. // })
  109. try {
  110. // 判断是否获取微信code码
  111. if (!forms.code && browser().weixin) return;
  112. const { data } = await request.get(
  113. '/edu-app/open/meetingQuestionSetting/detail?type=' +
  114. forms.meetingType +
  115. '&weChatCode=' +
  116. forms.code
  117. );
  118. if (data) {
  119. forms.contentA = data.contentA || forms.contentA;
  120. forms.contentB = data.contentB || forms.contentB;
  121. forms.contentC = data.contentC || forms.contentC;
  122. forms.contentD = data.contentD || forms.contentD;
  123. forms.openId = data.openId || forms.openId;
  124. sessionStorage.setItem('active-open-id', forms.openId);
  125. sessionStorage.removeItem('isWxcode');
  126. }
  127. forms.contentShow = true;
  128. } catch {
  129. forms.contentShow = true;
  130. }
  131. console.log('初始化视频', 111);
  132. forms.player1 = _initVideo('one', forms, videoIntervalRef);
  133. forms.player2 = _initVideo('two', forms, videoIntervalRef2);
  134. });
  135. const getAppIdAndCode = async (url?: string) => {
  136. try {
  137. // const { data } = await request.get(
  138. // '/edu-app/open/paramConfig/wechatAppId'
  139. // );
  140. // // 判断是否有微信appId
  141. // if (data) {
  142. // sessionStorage.setItem('isWxcode', '1');
  143. // closeToast();
  144. // goWechatAuth(data, url);
  145. // }
  146. sessionStorage.setItem('isWxcode', '1');
  147. closeToast()
  148. goWechatAuthTemp('wxccc2efd2678adbe3', url)
  149. } catch (e) {
  150. //
  151. console.log(e);
  152. }
  153. };
  154. if (browser().weixin) {
  155. //授权
  156. const openId = sessionStorage.getItem('active-open-id');
  157. forms.openId = openId;
  158. const code = getUrlCode();
  159. const isWxcode = sessionStorage.getItem('isWxcode');
  160. if (!code || isWxcode !== '1') {
  161. const newUrl =
  162. getHttpOrigin() +
  163. window.location.pathname +
  164. '#' +
  165. route.path +
  166. '?' +
  167. qs.stringify({
  168. ...route.query
  169. });
  170. getAppIdAndCode(newUrl);
  171. return '';
  172. } else {
  173. forms.code = code;
  174. // 获取微信分享签名
  175. weChatShare.getAppSignature()
  176. }
  177. }
  178. const nextSkip = () => {
  179. router.push({
  180. path: '/fill-questionnaire',
  181. query: {
  182. openId: forms.openId, //
  183. meetingType: forms.meetingType
  184. }
  185. });
  186. };
  187. const onPageShow = () => {
  188. console.log(forms.isPageHide, 'showInfo');
  189. if (forms.isPageHide) {
  190. //window.location.reload();
  191. }
  192. };
  193. // 处理监听页面返回不刷新的问题
  194. window.addEventListener('pageshow', onPageShow);
  195. const onPageHide = () => {
  196. console.log(forms.isPageHide, 'showInfo');
  197. forms.isPageHide = true;
  198. };
  199. window.addEventListener('pagehide', onPageHide);
  200. onUnmounted(() => {
  201. window.removeEventListener('pageshow', onPageShow);
  202. window.removeEventListener('pagehide', onPageHide);
  203. forms.player1?.pause();
  204. forms.player1?.src('');
  205. forms.player1?.dispose();
  206. forms.player2?.pause();
  207. forms.player2?.src('');
  208. forms.player2?.dispose();
  209. });
  210. return () => (
  211. <div class={styles['intention-page']}>
  212. <div
  213. class={[
  214. styles['content-box'],
  215. !forms.contentShow && styles.hideContent
  216. ]}>
  217. <div class={styles.contentBody} v-html={forms.contentA}></div>
  218. <div class={styles.contentBody}>
  219. <div class={styles.cbTitle}>
  220. 一、什么是音乐(器乐)课堂数字化转型<span>(详见视频介绍)</span>
  221. </div>
  222. <div class={styles.videoBoxCon}>
  223. <div class={styles.videoBox}>
  224. <div class={[styles['video-content']]}>
  225. <video
  226. id="register-video"
  227. class={styles['video']}
  228. src={forms.introductionVideo}
  229. playsinline={true}
  230. poster={forms.coverImg}
  231. preload="auto"></video>
  232. </div>
  233. </div>
  234. </div>
  235. </div>
  236. <div class={styles.contentBody} v-html={forms.contentB}></div>
  237. <div class={styles.contentBody} v-html={forms.contentC}></div>
  238. <div class={styles.contentBody}>
  239. <div class={styles.cbTitle}>
  240. 四、什么是器乐数字 Ai<span>(详见视频介绍)</span>
  241. </div>
  242. <div class={styles.videoBoxCon}>
  243. <div class={styles.videoBox}>
  244. <div class={[styles['video-content']]}>
  245. <video
  246. id="register-video2"
  247. class={styles['video']}
  248. src={forms.introductionVideo2}
  249. playsinline={true}
  250. poster={forms.coverImg2}
  251. preload="auto"></video>
  252. </div>
  253. </div>
  254. </div>
  255. </div>
  256. <div class={styles.contentBody} v-html={forms.contentD}></div>
  257. </div>
  258. {/* 是否在微信中打开 */}
  259. <OWxTip />
  260. {forms.openId && (
  261. <div class={styles.bottomBtn}>
  262. <p>
  263. 在您了解上述内容后,<i>请点击下一步进行意见填写</i>
  264. </p>
  265. <img class={styles.nextBtn} src={nextBtn} onClick={nextSkip} />
  266. </div>
  267. )}
  268. </div>
  269. );
  270. }
  271. });