index.tsx 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. import { defineComponent, onMounted, reactive, ref, nextTick } from 'vue';
  2. import styles from './index.module.less';
  3. import {
  4. Cell,
  5. CellGroup,
  6. Col,
  7. List,
  8. Picker,
  9. Popup,
  10. Row,
  11. Tab,
  12. Tabs,
  13. DatePicker,
  14. Button,
  15. DropdownMenu,
  16. DropdownItem,
  17. Popover
  18. } from 'vant';
  19. import MSticky from '@/components/m-sticky';
  20. import personIcon from './images/personIcon.png';
  21. import homeIcon from './images/homeIcon.png';
  22. import memberIcon from './images/memberIcon.png';
  23. import memberRateIcon from './images/memberRateIcon.png';
  24. // import sanIcon from './images/san.png';
  25. import iconArrow from './images/icon-arrow.png';
  26. import iconArrowActive from './images/icon-arrow-active.png';
  27. import iconQrcode from './images/icon-qrcode.png';
  28. import qrcodeBg from './images/qrcode-bg.png';
  29. import qrbg from './images/qr-bg.png';
  30. import request from '@/helpers/request';
  31. import topDot from './images/topDot.png';
  32. import { useRoute, useRouter } from 'vue-router';
  33. // import { moneyFormat, numberFormat } from '@/helpers/utils';
  34. import OFullRefresh from '@/components/m-full-refresh';
  35. import OEmpty from '@/components/m-empty';
  36. // import arrowIcon from './images/arrowIcon.png';
  37. // import OHeader from '@/components/m-header';
  38. import OSearch from '@/components/m-search';
  39. import numeral from 'numeral';
  40. import MQrcode from '@/components/m-qrcode';
  41. import html2canvas from 'html2canvas';
  42. import MWxTip from '@/components/m-wx-tip';
  43. import deepClone from '@/helpers/deep-clone';
  44. import { number } from 'echarts';
  45. export default defineComponent({
  46. name: 'tenant-apply-data',
  47. setup() {
  48. const route = useRoute();
  49. const forms = reactive({
  50. keyword: '',
  51. id: route.query.id,
  52. // id: '1687275949971763202',
  53. yearStatus: false,
  54. schoolId: null,
  55. year: [new Date().getFullYear()] as any,
  56. yearName: new Date().getFullYear(),
  57. classList: [] as any,
  58. statObj: {
  59. registerNum: 0,
  60. schoolNum: 0,
  61. classNum: 0,
  62. registerMemberShipNum: 0
  63. } as any,
  64. perponStatus: false,
  65. sortKey: 'CLASS' as 'CLASS' | 'MEMBER',
  66. sortId: 'desc',
  67. sortName: '报名人数降序',
  68. sortType: 'desc',
  69. sortList: [
  70. { value: 'desc', text: '报名人数降序' },
  71. { value: 'asc', text: '报名人数升序' },
  72. { value: 'mdesc', text: '会员人数降序' },
  73. { value: 'masc', text: '会员人数升序' }
  74. ] as any,
  75. page: 1,
  76. rows: 20,
  77. isClick: false,
  78. showDropdown: false,
  79. qrcodeStatus: false,
  80. url: '1', // 二维码
  81. urlItem: {} as any,
  82. provinceList: [] as any, // 省
  83. cityList: [] as any, // 市
  84. areaList: [] as any, // 区
  85. // 确认之后
  86. searchConfirmObj: {
  87. type: 'province' as 'province' | 'city' | 'area' | '',
  88. label: '全部地区',
  89. value: null as any,
  90. list: [] as any
  91. },
  92. // 弹窗
  93. searchObj: {
  94. type: 'province' as 'province' | 'city' | 'area' | '',
  95. label: '全部地区',
  96. value: null as any,
  97. list: [] as any
  98. }
  99. });
  100. const refreshing = ref(false);
  101. const loading = ref(true);
  102. const finished = ref(false);
  103. const showContact = ref(false);
  104. const list = ref([]);
  105. // const getSchoolList = async () => {
  106. // try {
  107. // const { data } = await request.get('/edu-app/open/school/list', {
  108. // params: {
  109. // tenantId: forms.id
  110. // }
  111. // });
  112. // const temp = [
  113. // {
  114. // value: '',
  115. // text: '全部学校'
  116. // }
  117. // ];
  118. // if (Array.isArray(data)) {
  119. // data.forEach((item: any) => {
  120. // temp.push({
  121. // value: item.id,
  122. // text: item.name
  123. // });
  124. // });
  125. // forms.classList = temp;
  126. // }
  127. // } catch {
  128. // //
  129. // }
  130. // };
  131. const getList = async () => {
  132. if (forms.isClick) {
  133. return;
  134. }
  135. forms.isClick = true;
  136. if (refreshing.value) {
  137. list.value = [];
  138. forms.page = 1;
  139. refreshing.value = false;
  140. }
  141. try {
  142. const params: any = {
  143. tenantId: forms.id,
  144. page: forms.page,
  145. rows: forms.rows,
  146. year: forms.yearName,
  147. keyword: forms.keyword,
  148. sort: forms.sortId,
  149. sortKey: forms.sortKey
  150. };
  151. if (forms.searchConfirmObj.type === 'province') {
  152. params.provinceCode = forms.searchConfirmObj.value;
  153. } else if (forms.searchConfirmObj.type === 'city') {
  154. params.cityCode = forms.searchConfirmObj.value;
  155. } else if (forms.searchConfirmObj.type === 'area') {
  156. params.regionCode = forms.searchConfirmObj.value;
  157. }
  158. const res = await request.post(
  159. '/edu-app/open/school/schoolRegisterPage',
  160. {
  161. data: params
  162. }
  163. );
  164. if (list.value.length > 0 && res.data.current === 1) {
  165. return;
  166. }
  167. list.value = list.value.concat(res.data.rows || []);
  168. forms.page = res.data.current + 1;
  169. showContact.value = list.value.length > 0;
  170. loading.value = false;
  171. finished.value = res.data.current >= res.data.pages;
  172. } catch {
  173. showContact.value = false;
  174. finished.value = true;
  175. } finally {
  176. loading.value = false;
  177. }
  178. forms.isClick = false;
  179. };
  180. const onRefresh = () => {
  181. finished.value = false;
  182. // 重新加载数据
  183. // 将 loading 设置为 true,表示处于加载状态
  184. loading.value = true;
  185. getList();
  186. };
  187. const imgs = reactive({
  188. saveLoading: false,
  189. image: null as any,
  190. shareLoading: false
  191. });
  192. const downImg = () => {
  193. if (imgs.saveLoading) {
  194. return;
  195. }
  196. imgs.saveLoading = true;
  197. // 判断是否已经生成图片
  198. // if (imgs.image) {
  199. // saveImg();
  200. // } else {
  201. const container: any = document.getElementById(`preview-container`);
  202. // console.log('1212121', container);
  203. html2canvas(container, {
  204. allowTaint: true,
  205. useCORS: true,
  206. backgroundColor: null
  207. })
  208. .then(async canvas => {
  209. const url = canvas.toDataURL('image/png');
  210. imgs.image = url;
  211. // saveImg();
  212. forms.qrcodeStatus = true;
  213. imgs.saveLoading = false;
  214. })
  215. .catch(() => {
  216. // console.log(e, 'e');
  217. imgs.saveLoading = false;
  218. // console.log('222');
  219. });
  220. // }
  221. };
  222. const saveImg = async () => {
  223. // showLoadingToast({ message: '图片生成中...', forbidClick: true });
  224. setTimeout(() => {
  225. imgs.saveLoading = false;
  226. }, 100);
  227. const link = document.createElement('a');
  228. link.setAttribute('download', forms.urlItem.schoolName + '统计' + '.png');
  229. // 添加时间戳,防止浏览器缓存图
  230. link.href = imgs.image;
  231. link.click();
  232. };
  233. // 计算会员占比
  234. const formatMemberRate = (studentNum: any, memberNum: any) => {
  235. if (studentNum <= 0 || memberNum <= 0) {
  236. return 0;
  237. }
  238. // console.log(studentNum, memberNum);
  239. return Math.round((memberNum / studentNum) * 1000) / 10;
  240. };
  241. const dropdownItemRef = ref();
  242. const getAreas = async () => {
  243. try {
  244. const { data } = await request.get(
  245. '/edu-app/open/sysArea/queryProvince?tenantId=' + forms.id
  246. );
  247. forms.provinceList = data || [];
  248. } catch {
  249. //
  250. }
  251. };
  252. const formatParentAreaId = (id: any, list: any, ids = [] as any) => {
  253. for (const item of list) {
  254. if (item.code == id) {
  255. return [...ids, id];
  256. }
  257. if (item.areas && item.areas.length > 0) {
  258. const cIds: any = formatParentAreaId(id, item.areas, [
  259. ...ids,
  260. item.code
  261. ]);
  262. if (cIds.includes(id)) {
  263. return cIds;
  264. }
  265. }
  266. }
  267. return ids;
  268. };
  269. /** 切换状态 */
  270. const onChangeArea = (type: 'province' | 'city' | 'area', item: any) => {
  271. forms.searchObj.type = type;
  272. forms.searchObj.value = item.code;
  273. forms.searchObj.label = item.name;
  274. forms.searchObj.list = formatParentAreaId(item.code, forms.provinceList);
  275. if (type === 'province') {
  276. forms.cityList = item.areas || [];
  277. forms.areaList = [];
  278. } else if (type === 'city') {
  279. forms.areaList = item.areas || [];
  280. } else if (type === 'area') {
  281. //
  282. }
  283. };
  284. const formatAreaDefaultData = (index: number, ids: number[], item: any) => {
  285. const type: any = ['province', 'city', 'area'];
  286. if (ids.length <= 0) return;
  287. item.forEach((item: any) => {
  288. if (item.code === ids[index]) {
  289. onChangeArea(type[index], item);
  290. if (ids[index]) {
  291. formatAreaDefaultData(index + 1, ids, item.areas || []);
  292. }
  293. }
  294. });
  295. };
  296. onMounted(async () => {
  297. if (route.query.name) {
  298. document.title = route.query.name + '报名统计';
  299. } else {
  300. document.title = '学生报名统计';
  301. }
  302. // await getSchoolList();
  303. getAreas();
  304. await getStat();
  305. await getList();
  306. });
  307. const getStat = async () => {
  308. try {
  309. const params: any = {
  310. tenantId: forms.id,
  311. year: forms.yearName
  312. };
  313. if (forms.searchConfirmObj.type === 'province') {
  314. params.provinceCode = forms.searchConfirmObj.value;
  315. } else if (forms.searchConfirmObj.type === 'city') {
  316. params.cityCode = forms.searchConfirmObj.value;
  317. } else if (forms.searchConfirmObj.type === 'area') {
  318. params.regionCode = forms.searchConfirmObj.value;
  319. }
  320. const { data } = await request.post(
  321. '/edu-app/open/school/schoolRegisterStat',
  322. {
  323. data: params
  324. }
  325. );
  326. forms.statObj = data;
  327. } catch {
  328. //
  329. }
  330. };
  331. return () => (
  332. <div class={styles.tenantAllData}>
  333. {/* <OHeader isBack={false} /> */}
  334. <MSticky position="top">
  335. <div class={styles.top}>
  336. <div class={styles.topWrap}>
  337. <div class={[styles.topHead, styles.topHeadIndex]}>
  338. <img src={topDot} class={styles.topDot} alt="" />
  339. 汇总数据
  340. </div>
  341. <DropdownMenu>
  342. <DropdownItem
  343. ref={dropdownItemRef}
  344. onOpen={() => {
  345. forms.searchObj = deepClone(forms.searchConfirmObj);
  346. if (forms.searchObj.list.length > 0) {
  347. formatAreaDefaultData(
  348. 0,
  349. forms.searchObj.list,
  350. forms.provinceList
  351. );
  352. }
  353. }}>
  354. {{
  355. title: () => (
  356. <div class={[styles.areaWrap, 'areaWrapActive']}>
  357. <i class={styles.iconAddress}></i>
  358. <span>{forms.searchConfirmObj.label}</span>
  359. <i class={[styles.iconArrow, 'iconArrowActive']}></i>
  360. </div>
  361. ),
  362. default: () => (
  363. <div class={styles.areaSection}>
  364. <div class={[styles.areaList]}>
  365. {forms.provinceList.length > 0 && (
  366. <div
  367. class={[
  368. styles.areaItem,
  369. forms.cityList.length > 0 &&
  370. 'van-hairline--right'
  371. ]}>
  372. {forms.provinceList.map((item: any) => (
  373. <span
  374. onClick={() => onChangeArea('province', item)}
  375. class={[
  376. styles.areaItemChild,
  377. forms.searchObj.list.includes(item.code) &&
  378. styles.areaItemChildActive
  379. ]}>
  380. {item.name}
  381. </span>
  382. ))}
  383. </div>
  384. )}
  385. {forms.cityList.length > 0 && (
  386. <div
  387. class={[
  388. styles.areaItem,
  389. forms.areaList.length > 0 &&
  390. 'van-hairline--right'
  391. ]}>
  392. {forms.cityList.map((item: any) => (
  393. <span
  394. onClick={() => onChangeArea('city', item)}
  395. class={[
  396. styles.areaItemChild,
  397. forms.searchObj.list.includes(item.code) &&
  398. styles.areaItemChildActive
  399. ]}>
  400. {item.name}
  401. </span>
  402. ))}
  403. </div>
  404. )}
  405. {forms.areaList.length > 0 && (
  406. <div class={[styles.areaItem]}>
  407. {forms.areaList.map((item: any) => (
  408. <span
  409. onClick={() => onChangeArea('area', item)}
  410. class={[
  411. styles.areaItemChild,
  412. forms.searchObj.list.includes(item.code) &&
  413. styles.areaItemChildActive
  414. ]}>
  415. {item.name}
  416. </span>
  417. ))}
  418. </div>
  419. )}
  420. </div>
  421. <div class={[styles.btnGroup, 'van-hairline--top']}>
  422. <Button
  423. round
  424. block
  425. onClick={async () => {
  426. forms.searchObj.type = '';
  427. forms.searchObj.label = '全部地区';
  428. forms.searchObj.value = null;
  429. forms.searchObj.list = [];
  430. forms.searchConfirmObj = deepClone(
  431. forms.searchObj
  432. );
  433. dropdownItemRef.value?.toggle(false);
  434. forms.page = 1;
  435. refreshing.value = true;
  436. forms.cityList = [];
  437. forms.areaList = [];
  438. await getStat();
  439. await getList();
  440. }}>
  441. 重置
  442. </Button>
  443. <Button
  444. round
  445. type="primary"
  446. block
  447. onClick={async () => {
  448. forms.searchConfirmObj = deepClone(
  449. forms.searchObj
  450. );
  451. dropdownItemRef.value?.toggle(false);
  452. forms.page = 1;
  453. refreshing.value = true;
  454. await getStat();
  455. await getList();
  456. }}>
  457. 确定
  458. </Button>
  459. </div>
  460. </div>
  461. )
  462. }}
  463. </DropdownItem>
  464. </DropdownMenu>
  465. </div>
  466. <div class={[styles.cardWrap, styles.cardWrapIndex]}>
  467. {/* <div class={[styles.studentCard, styles.cardItem]}>
  468. <div class={styles.cardNum}>
  469. {numeral(forms.statObj.registerNum).format('0,0')}
  470. </div>
  471. <div class={styles.cardInfo}>
  472. <img src={personIcon} class={styles.cardInfoImg} alt="" />
  473. 报名人数
  474. </div>
  475. <div class={styles.cardLine}></div>
  476. </div> */}
  477. <div class={[styles.schoolCard, styles.cardItem]}>
  478. <div class={styles.cardNum}>
  479. {numeral(forms.statObj.schoolNum).format('0,0')}
  480. </div>
  481. <div class={styles.cardInfo}>
  482. <img src={homeIcon} class={styles.cardInfoImg} alt="" />
  483. 学校数量
  484. </div>
  485. <div class={styles.cardLine}></div>
  486. </div>
  487. <div class={[styles.memberCard, styles.cardItem]}>
  488. <div class={styles.cardNum}>
  489. {numeral(forms.statObj.registerMemberShipNum).format('0,0')}
  490. </div>
  491. <div class={styles.cardInfo}>
  492. <img src={memberIcon} class={styles.cardInfoImg} alt="" />
  493. 数字化人数
  494. </div>
  495. <div class={styles.cardLine}></div>
  496. </div>
  497. {/* <div class={[styles.memberRateCard, styles.cardItem]}>
  498. <div class={styles.cardNum}>
  499. {numeral(
  500. formatMemberRate(
  501. forms.statObj.registerNum || 0,
  502. forms.statObj.registerMemberShipNum || 0
  503. )
  504. ).format('0.0')}
  505. %
  506. </div>
  507. <div class={styles.cardInfo}>
  508. <img src={memberRateIcon} class={styles.cardInfoImg} alt="" />
  509. 数字化普及率
  510. </div>
  511. <div class={styles.cardLine}></div>
  512. </div> */}
  513. </div>
  514. <div class={styles.searchWrap}>
  515. <div class={styles.searechInfo}>
  516. <OSearch
  517. class={styles.allDataWrap}
  518. shape="round"
  519. background="#F6F8F9"
  520. inputBackground="white"
  521. placeholder="请输入学校名称"
  522. onSearch={val => {
  523. forms.keyword = val;
  524. forms.page = 1;
  525. refreshing.value = true;
  526. getList();
  527. }}></OSearch>
  528. </div>
  529. <Popover
  530. v-model:show={forms.perponStatus}
  531. showArrow={false}
  532. placement="bottom-end"
  533. offset={[0, 12]}>
  534. {{
  535. reference: () => (
  536. <div
  537. class={[
  538. styles.timerWrap,
  539. forms.perponStatus && styles.timerWrapActive
  540. ]}
  541. // onClick={() => (forms.perponStatus = true)}
  542. >
  543. {forms.sortName}
  544. <img
  545. src={forms.perponStatus ? iconArrowActive : iconArrow}
  546. class={[styles.sanIcon]}
  547. alt=""
  548. />
  549. </div>
  550. ),
  551. default: () => (
  552. <div class={styles.popSearchList}>
  553. {forms.sortList.map((item: any, index: number) => (
  554. <div
  555. class={[
  556. styles.popSearchItem,
  557. index < forms.sortList.length - 1 &&
  558. 'van-hairline--bottom'
  559. ]}>
  560. <div
  561. class={[
  562. styles.popSearchItemChild,
  563. forms.sortType === item.value &&
  564. styles.popSearchItemActive
  565. ]}
  566. onClick={() => {
  567. const selectedOption = item;
  568. if (
  569. selectedOption.value === 'desc' ||
  570. selectedOption.value === 'asc'
  571. ) {
  572. forms.sortId = selectedOption.value;
  573. forms.sortKey = 'CLASS';
  574. }
  575. if (selectedOption.value === 'mdesc') {
  576. forms.sortId = 'desc';
  577. forms.sortKey = 'MEMBER';
  578. }
  579. if (selectedOption.value === 'masc') {
  580. forms.sortId = 'asc';
  581. forms.sortKey = 'MEMBER';
  582. }
  583. forms.sortType = selectedOption.value;
  584. forms.sortName = selectedOption.text;
  585. refreshing.value = true;
  586. getList();
  587. forms.perponStatus = false;
  588. }}>
  589. {item.text}
  590. </div>
  591. </div>
  592. ))}
  593. </div>
  594. )
  595. }}
  596. </Popover>
  597. </div>
  598. </div>
  599. </MSticky>
  600. <div class={styles.schoolList}>
  601. {showContact.value ? (
  602. <OFullRefresh
  603. v-model:modelValue={refreshing.value}
  604. onRefresh={onRefresh}
  605. class={styles.refreshC}>
  606. <List
  607. loading-text=" "
  608. finished={finished.value}
  609. finished-text=" "
  610. onLoad={getList}>
  611. {list.value.map((item: any) => (
  612. <div class={[styles.schoolItem, styles.schoolItemOther]}>
  613. <div class={styles.schoolNameWrap}>
  614. {/* <p class={styles.title}>学校名称</p> */}
  615. <p class={styles.schoolName}>{item.schoolName}</p>
  616. </div>
  617. <div class={styles.schoolCountWrap}>
  618. {/* <div>
  619. <p class={styles.personNum}>
  620. {numeral(item.registerNum || 0).format('0,0')}
  621. </p>
  622. <p class={styles.title}>报名人数</p>
  623. </div> */}
  624. <div>
  625. <p class={styles.personNum}>
  626. {numeral(item.classNum || 0).format(
  627. '0,0'
  628. )}
  629. </p>
  630. <p class={styles.title}>班级数量</p>
  631. </div>
  632. <div>
  633. <p class={styles.personNum}>
  634. {numeral(item.registerMemberShipNum || 0).format(
  635. '0,0'
  636. )}
  637. {/* {item.registerMemberShipNum || 0} */}
  638. </p>
  639. <p class={styles.title}>数字化人数</p>
  640. </div>
  641. {/* <div>
  642. <p class={styles.personNum}>
  643. {numeral(
  644. formatMemberRate(
  645. item.registerNum || 0,
  646. item.registerMemberShipNum || 0
  647. )
  648. ).format('0.0')}
  649. %
  650. </p>
  651. <p class={styles.title}>数字化普及率</p>
  652. </div> */}
  653. <div
  654. onClick={() => {
  655. forms.urlItem = item;
  656. forms.url = `${location.origin}/classroom-app/#/tenantDataShool?id=${item.schoolId}&name=${item.schoolName}`;
  657. nextTick(() => {
  658. downImg();
  659. });
  660. }}>
  661. <p class={styles.personNum}>
  662. <img src={iconQrcode} />
  663. </p>
  664. <p class={styles.title}>统计二维码</p>
  665. </div>
  666. {/* <img class={[styles.arrow]} src={arrowIcon} alt="" /> */}
  667. </div>
  668. </div>
  669. ))}
  670. </List>
  671. </OFullRefresh>
  672. ) : null}
  673. {!showContact.value && !loading.value && (
  674. <OEmpty description="暂无学校信息" class={styles.emptyC} />
  675. )}
  676. </div>
  677. <Popup
  678. v-model:show={forms.yearStatus}
  679. position="bottom"
  680. round
  681. class={'popupBottomSearch'}>
  682. <DatePicker
  683. showToolbar
  684. v-model={forms.year}
  685. columns-type={['year']}
  686. onCancel={() => (forms.yearStatus = false)}
  687. onConfirm={(val: any) => {
  688. // console.log(val);
  689. // const selectedOption = val.selectedOptions[0];
  690. // console.log(selectedOption, 'selectedOption');
  691. // forms.schoolId = selectedOption.value;
  692. // // forms.schoolName = selectedOption.text;
  693. forms.year = [val.selectedValues[0]];
  694. forms.yearName = val.selectedValues[0];
  695. forms.page = 1;
  696. refreshing.value = true;
  697. getStat();
  698. getList();
  699. forms.yearStatus = false;
  700. }}
  701. />
  702. </Popup>
  703. {/* <Popup
  704. v-model:show={forms.perponStatus}
  705. position="bottom"
  706. round
  707. class={'popupBottomSearch'}>
  708. <Picker
  709. showToolbar
  710. columns={forms.sortList}
  711. onCancel={() => (forms.perponStatus = false)}
  712. onConfirm={(val: any) => {
  713. const selectedOption = val.selectedOptions[0];
  714. if (
  715. selectedOption.value === 'desc' ||
  716. selectedOption.value === 'asc'
  717. ) {
  718. forms.sortId = selectedOption.value;
  719. forms.sortKey = 'CLASS';
  720. }
  721. if (selectedOption.value === 'mdesc') {
  722. forms.sortId = 'desc';
  723. forms.sortKey = 'MEMBER';
  724. }
  725. if (selectedOption.value === 'masc') {
  726. forms.sortId = 'asc';
  727. forms.sortKey = 'MEMBER';
  728. }
  729. forms.sortName = selectedOption.text;
  730. refreshing.value = true;
  731. getList();
  732. forms.perponStatus = false;
  733. }}
  734. />
  735. </Popup> */}
  736. <Popup v-model:show={forms.qrcodeStatus} class={styles.popupQrcode}>
  737. <i
  738. class={styles.iconClose}
  739. onClick={() => (forms.qrcodeStatus = false)}></i>
  740. <div class={[styles.shareContaienr]}>
  741. {/* <img src={qrcodeBg} class={styles.qrcodeBg} /> */}
  742. <div class={styles.qrcodeBgDom}></div>
  743. <div class={styles.sectionGroup}>
  744. {/* <div class={styles.section}> */}
  745. {/* <div class={styles.memo}>{forms.urlItem.schoolName}</div>
  746. <div class={styles.qrcodeSection}>
  747. <img src={qrbg} class={styles.qrbg} />
  748. <MQrcode
  749. class={styles.mqrcode}
  750. text={forms.url}
  751. logoSize={'small'}
  752. size={'100%'}
  753. />
  754. </div> */}
  755. <img src={imgs.image} class={styles.image} />
  756. {/* </div> */}
  757. </div>
  758. </div>
  759. <p class={styles.btnText}>长按保存二维码</p>
  760. </Popup>
  761. <div class={styles.templateSection}>
  762. <div class={[styles.shareContaienr]}>
  763. <img src={qrcodeBg} class={styles.qrcodeBg} />
  764. <div class={styles.sectionGroup}>
  765. <div class={styles.section} id="preview-container">
  766. <div class={styles.memo}>{forms.urlItem.schoolName}</div>
  767. <div class={styles.qrcodeSection}>
  768. <img src={qrbg} class={styles.qrbg} />
  769. <MQrcode
  770. class={styles.mqrcode}
  771. text={forms.url}
  772. logoSize={'small'}
  773. size={'100%'}
  774. logoSrc={forms.urlItem.schoolLogo}
  775. />
  776. </div>
  777. </div>
  778. </div>
  779. </div>
  780. </div>
  781. <MWxTip />
  782. </div>
  783. );
  784. }
  785. });