| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- import { defineComponent, onMounted, reactive, ref, nextTick, onUnmounted } from 'vue';
- import styles from './index.module.less';
- import { List, Popup, DatePicker, Popover, Field, Picker, showToast } from 'vant';
- import request from '@/helpers/request';
- import { useRoute, useRouter } from 'vue-router';
- import OEmpty from '@/components/m-empty';
- import MWxTip from '@/components/m-wx-tip';
- import OSearch from '@/components/m-search';
- import positionIcon from './images/position_icon.png';
- import scIcon1 from './images/sc_icon1.png';
- import scIcon2 from './images/sc_icon2.png';
- import scIcon3 from './images/sc_icon3.png';
- import schoolIcon from './images/school_icon.png';
- import searchIcon from './images/search_icon.png';
- import searchBtn from './images/search_btn.png';
- import totalBoxBg from './images/total_box_icon.png';
- import wxShareIcon from './images/wx_share_icon.png';
- import { drawCircle } from './drawGraph'
- import useWeChatShare from '@/hooks/useWeChatShare';
- import { browser } from '@/helpers/utils';
- import OFullRefresh from '@/components/m-full-refresh';
- export default defineComponent({
- name: 'questionnaire-statistics-new',
- setup() {
- const route = useRoute();
- const router = useRouter();
- const tabName = ref('all');
- const forms = reactive({
- schoolName: '',
- id: route.query.id,
- // id: '1687275949971763202',
- yearStatus: false,
- schoolId: null,
- classList: [] as any,
- page: 1,
- rows: 20,
- isClick: false,
- tenantId: route.query.id,
- areaList: [] as any,
- areaColumns: [] as any,
- areaStatus: false,
- areaPopupShow: false,
- areaOptionIndex: [] as any,
- currentArea: null as any, // 当前的区域
- currentAreaInfo: null as any,
- schoolList: [] as any,
- totalInfo: {} as any,
- sortType: 'DESC' as any, // 排序方式,ASC(升序)/DESC(降序)
- sortField: 'totalNum', // totalNum: 总人数,supportNum:支持人数,supportRate:支持率
- areaIdx: 0 as any,
- });
- const refreshing = ref(false);
- const loading = ref(true);
- const finished = ref(false);
- const showContact = ref(false);
- const list = ref([]);
- const queryArea = async () => {
- try {
- const { data } = await request.get(
- `/edu-app/open/tenantInfo/getArea?tenantId=${forms.tenantId}`, {
- hideLoading: false,
- }
- );
- forms.areaList = data || []
- data.forEach((item: any, index: number) => {
- const {provinceName='',cityName='',regionName=''} = item
- forms.areaColumns.push({
- text: provinceName + ' ' + cityName + ' ' + (regionName ? regionName : ''),
- value: index
- })
- })
- // 没有缓存
- if (!sessionStorage.getItem('areaIdx')) {
- const defaultIndex = data.findIndex((item: any) => item.defaultFlag)
- forms.areaIdx = defaultIndex !== -1 ? Number(defaultIndex) : 0
- }
- forms.currentArea = forms.areaColumns.length ? forms.areaColumns[forms.areaIdx].text : ''
- forms.currentAreaInfo = forms.areaList.length ? forms.areaList[forms.areaIdx] : null;
- } catch (error) {
-
- }
- await queryInfo();
- await getList();
- }
- const queryInfo = async () => {
- try {
- const { provinceCode='',cityCode='',regionCode='' } = forms.currentAreaInfo
- const res = await request.post(
- '/edu-app/open/schoolMeetingQuestion/areaSummarySum',
- {
- data: {
- tenantId: forms.tenantId,
- provinceCode,
- cityCode,
- districtCode: regionCode,
- }
- }
- );
- forms.totalInfo = res.data|| {}
- nextTick(() => {
- let percentage = 0;
- state.intervalOne = setInterval(() => {
- if (percentage <= forms.totalInfo.supportRate) {
- // console.log(percentage,forms.totalInfo.supportRate)
- drawCircle('circle1', 1, percentage)
- }
- if (percentage <= forms.totalInfo.participationRate) {
- drawCircle('circle2', 2, percentage)
- }
- if (percentage === Math.floor(Number(forms.totalInfo.supportRate))) {
- drawCircle('circle1', 1, forms.totalInfo.supportRate)
- }
- if (percentage === Math.floor(Number(forms.totalInfo.participationRate))) {
- drawCircle('circle2', 2, forms.totalInfo.participationRate)
- }
- percentage += 1; // 每次增加1%
- if (percentage > Math.max(forms.totalInfo.supportRate, forms.totalInfo.participationRate)) {
- clearDataAnimation();
- }
- }, 25); // 每25ms更新一次
- });
- } catch (error) {
-
- }
- }
- const getList = async () => {
- try {
- const { provinceCode='',cityCode='',regionCode='' } = forms.currentAreaInfo
- const res = await request.post(
- '/edu-app/open/schoolMeetingQuestion/areaSummary',
- {
- data: {
- tenantId: forms.tenantId,
- schoolName: forms.schoolName,
- provinceCode,
- cityCode,
- districtCode: regionCode,
- sortType: forms.sortType,
- sortField: forms.sortField,
- }
- }
- );
- forms.schoolList = res?.data || []
- } catch {
- //
- } finally {
- //
- }
-
- };
- const state = reactive({
- saveLoading: false,
- image: null as any,
- shareLoading: false,
- intervalOne: null as any,
- });
- // 微信分享学校
- const wxShareItem = (event: MouseEvent, item: any) => {
- showToast('分享学校链接');
- const shareTitle = '测试';
- const weChatShare = useWeChatShare(
- shareTitle,
- '科技赋能音乐(器乐)学习,在每一个孩子心中奏响美妙的乐章。',
- window.location.origin + '/classroom-app/shareImg/questionnaire-statistics-new.png'
- );
- if (browser().weixin) {
- weChatShare.getAppSignature()
- }
- event.stopPropagation(); // 阻止事件冒泡
- }
- const skipDetail = (id: any) => {
- // sessionStorage.setItem('areaIdx', forms.areaIdx)
- sessionStorage.setItem('areaTenantName', forms.totalInfo.tenantName || '')
- sessionStorage.setItem('qsFilterParams', JSON.stringify({
- schoolName: forms.schoolName,
- sortType: forms.sortType,
- sortField: forms.sortField,
- }))
- router.push({
- path: '/statistics-detail-new',
- query: {
- id,
- }
- });
- }
- const filterList = (val: string) => {
- if (forms.sortField !== val) {
- forms.sortType = 'DESC'
- } else {
- forms.sortType = forms.sortType === 'DESC' ? 'ASC' : 'DESC'
- }
- forms.sortField = val
- getList()
- }
- const formatNumberWithComma = (num: number | string) => {
- // 将数字转换为字符串,去掉小数点后面的部分
- let [integer, decimal] = num.toString().split('.');
-
- // 使用正则表达式添加千分位分隔符
- integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
-
- // 如果有小数部分,则保留小数部分
- return decimal ? `${integer}.${decimal}` : integer;
- }
- const initWxShare = () => {
- const shareTitle = (forms.totalInfo.tenantName||'') + '音乐(器乐)数字化转型问卷统计';
- const weChatShare = useWeChatShare(
- shareTitle,
- '科技赋能音乐(器乐)学习,在每一个孩子心中奏响美妙的乐章。',
- window.location.origin + '/classroom-app/shareImg/questionnaire-statistics-new.png'
- );
- if (browser().weixin) {
- weChatShare.getAppSignature()
- }
- }
- const onRefresh = async () => {
- // console.log('刷新111')
- clearDataAnimation();
- forms.areaColumns = []
- finished.value = false;
- // 重新加载数据
- // 将 loading 设置为 true,表示处于加载状态
- loading.value = true;
- await queryArea();
- refreshing.value = false
- };
- const clearDataAnimation = () => {
- clearInterval(state.intervalOne); // 停止定时器
- state.intervalOne = null;
- }
- onMounted(async () => {
- console.log('刷新页面')
- forms.areaIdx = sessionStorage.getItem('areaIdx') || 0;
- // @ts-ignore
- const qsFilterParams: any = sessionStorage.getItem('qsFilterParams') ? JSON.parse(sessionStorage.getItem('qsFilterParams')) : {};
- forms.schoolName = qsFilterParams.schoolName || ''
- forms.sortField = qsFilterParams.sortField || 'totalNum'
- forms.sortType = qsFilterParams.sortType || 'DESC'
- await queryArea();
- nextTick(() => {
- initWxShare()
- });
- });
- onUnmounted(() => {
- clearDataAnimation();
- });
- return () => (
- <OFullRefresh
- v-model:modelValue={refreshing.value}
- freshDisabled={forms.areaStatus}
- onRefresh={onRefresh}
- class={styles.refreshC}>
- <div class={[styles.statisBody]}>
- {
- forms.areaColumns.length > 1 &&
- <div class={[styles.spColumn, forms.areaStatus && styles.openVal]} onClick={() => {
- forms.areaOptionIndex = [Number(forms.areaIdx)]
- forms.areaStatus = true
- }}>
- <img src={positionIcon} />
- <p>{forms.currentArea}</p>
- <i></i>
- </div>
- }
- {/** 参与学校统计 */}
- <div class={styles.sTotal}>
- <div class={[styles.stOne, styles.stOneLine]}>
- <div class={styles.soTitle}><span class={styles.sOrange}>{formatNumberWithComma(forms.totalInfo.schoolNum||0)}</span><i>所</i></div>
- <p class={styles.soDesc}><img src={schoolIcon} />参与学校</p>
- </div>
- <div class={styles.stOne}>
- <div class={styles.soTitle}><span class={styles.sRed}>{formatNumberWithComma(forms.totalInfo.totalNum||0)}</span><i>人</i></div>
- <p class={styles.soDesc}><img src={scIcon1} />参与调查</p>
- </div>
- </div>
- {/** 圆环统计 */}
- <div class={styles.sRing}>
- <div class={[styles.srItem,styles.srItemOne]}>
- <div class={styles.siLeft}>
- <canvas id="circle1" width="85" height="85"></canvas>
- <p>支持率</p>
- </div>
- <div class={styles.siRight}>
- <div><span class={styles.sBlue}>{formatNumberWithComma(forms.totalInfo.supportNum||0)}</span><i>人</i></div>
- <p>支持开展</p>
- </div>
- </div>
- <div class={styles.srItem}>
- <div class={styles.siLeft}>
- <canvas id="circle2" width="85" height="85"></canvas>
- <p>参加率</p>
- </div>
- <div class={styles.siRight}>
- <div><span class={styles.sGreen}>{formatNumberWithComma(forms.totalInfo.participationNum||0)}</span><i>人</i></div>
- <p>报名参加</p>
- </div>
- </div>
- </div>
- {/** 搜索栏 */}
- <div class={styles.searechInfo}>
- <img src={searchIcon} class={styles.searchIcon} />
- <Field
- clearable={true}
- inputAlign="left"
- placeholder="请输入学校名称"
- autocomplete="off"
- center
- maxlength={30}
- v-model={forms.schoolName}
- onUpdate:modelValue={(val: any) => {
- // 输入框内容变化时触发
- console.log('搜索内容变化',val)
- forms.schoolName = val
- sessionStorage.setItem('qsFilterParams', JSON.stringify({
- schoolName: forms.schoolName,
- sortType: forms.sortType,
- sortField: forms.sortField,
- }))
- getList()
- }}>
- </Field>
- <img src={searchBtn} class={styles.searchBtn} onClick={getList} />
- </div>
- {/** 排序栏 */}
- <ul class={styles.sortColumn}>
- <li class={forms.sortField === 'totalNum' && styles.sortActive} onClick={() => filterList('totalNum')}>
- <span>参与调查人数</span>
- <i class={[(forms.sortField === 'totalNum' && forms.sortType === 'DESC') && styles.actDown, (forms.sortField === 'totalNum' && forms.sortType === 'ASC') && styles.actUp]}></i>
- </li>
- <li class={forms.sortField === 'supportNum' && styles.sortActive} onClick={() => filterList('supportNum')}>
- <span>支持人数</span>
- <i class={[(forms.sortField === 'supportNum' && forms.sortType === 'DESC') && styles.actDown, (forms.sortField === 'supportNum' && forms.sortType === 'ASC') && styles.actUp]}></i>
- </li>
- <li class={forms.sortField === 'supportRate' && styles.sortActive} onClick={() => filterList('supportRate')}>
- <span>支持率</span>
- <i class={[(forms.sortField === 'supportRate' && forms.sortType === 'DESC') && styles.actDown, (forms.sortField === 'supportRate' && forms.sortType === 'ASC') && styles.actUp]}></i>
- </li>
- <li class={forms.sortField === 'participationNum' && styles.sortActive} onClick={() => filterList('participationNum')}>
- <span>参加人数</span>
- <i class={[(forms.sortField === 'participationNum' && forms.sortType === 'DESC') && styles.actDown, (forms.sortField === 'participationNum' && forms.sortType === 'ASC') && styles.actUp]}></i>
- </li>
- <li class={forms.sortField === 'participationRate' && styles.sortActive} onClick={() => filterList('participationRate')}>
- <span>参加率</span>
- <i class={[(forms.sortField === 'participationRate' && forms.sortType === 'DESC') && styles.actDown, (forms.sortField === 'participationRate' && forms.sortType === 'ASC') && styles.actUp]}></i>
- </li>
- </ul>
- {/** 学校列表 */}
- {
- forms.schoolList.length ?
- <div class={styles.scList}>
- {forms.schoolList.map((item: any) => (
- <div class={styles.sItem} onClick={() => skipDetail(item.schoolAreaId)}>
- <img class={styles.shareIcon} src={wxShareIcon} onClick={(event: MouseEvent) => wxShareItem(event, item)} />
- <div class={styles.itemTile}>
- <img src={schoolIcon} />
- <p>{item.schoolName}</p>
- {/* <i></i> */}
- </div>
- <div class={[styles.itemDesc]}><span class={styles.sRed}>{formatNumberWithComma(item.totalNum || 0)}</span> 人参与调查</div>
- <ul class={styles.itemContent}>
- <li>
- <div class={styles.icTop}>
- <span class={styles.sBlue}>{formatNumberWithComma(item.supportNum || 0)}</span><i>人</i>
- </div>
- <p>支持开展</p>
- </li>
- <li>
- <div class={styles.icTop}>
- <span class={styles.sBlue}>{Number(item.supportRate || 0).toFixed(2)}%</span>
- </div>
- <p>支持率</p>
- </li>
- <li>
- <div class={styles.icTop}>
- <span class={styles.sGreen}>{formatNumberWithComma(item.participationNum || 0)}</span><i>人</i>
- </div>
- <p>报名参加</p>
- </li>
- <li>
- <div class={styles.icTop}>
- <span class={styles.sGreen}>{Number(item.participationRate || 0).toFixed(2)}%</span>
- </div>
- <p>参加率</p>
- </li>
- </ul>
- </div>
- ))}
- </div> :
- <OEmpty description="暂无内容" class={styles.emptyC} />
- }
- {/* 区域 */}
- <Popup
- v-model:show={forms.areaStatus}
- position="bottom"
- round
- safeAreaInsetBottom
- lazyRender={false}
- class={'popupBottomSearch'}
- onOpen={() => {
- forms.areaPopupShow = true;
- }}
- onClosed={() => {
- forms.areaPopupShow = false;
- }}>
- {forms.areaPopupShow && (
- <Picker
- showToolbar
- v-model={forms.areaOptionIndex}
- columns={forms.areaColumns}
- onCancel={() => (forms.areaStatus = false)}
- onConfirm={(val: any) => {
- // forms.gradeAndClassIndex = [val.selectedOptions[0].value, val.selectedOptions[1].value]
- // forms.currentArea = val.selectedOptions[0].text;
- // forms.currentClass = val.selectedOptions[1].text;
- forms.currentArea = val.selectedOptions[0].text
- forms.areaOptionIndex = [val.selectedOptions[0].value]
- forms.areaIdx = val.selectedOptions[0].value
- forms.areaStatus = false;
- forms.schoolName = '';
- forms.currentAreaInfo = forms.areaList[val.selectedOptions[0].value]
- sessionStorage.setItem('areaIdx', forms.areaIdx)
- clearDataAnimation()
- queryInfo()
- getList()
- // console.log('选择1111',val,forms.areaOptionIndex)
- }}
- />
- )}
- </Popup>
- {/* <MWxTip /> */}
- </div>
- </OFullRefresh>
- );
- }
- });
|