|
@@ -11,14 +11,19 @@ import {
|
|
|
Tab,
|
|
|
Tabs,
|
|
|
DatePicker,
|
|
|
- Button
|
|
|
+ Button,
|
|
|
+ DropdownMenu,
|
|
|
+ DropdownItem,
|
|
|
+ Popover
|
|
|
} from 'vant';
|
|
|
import MSticky from '@/components/m-sticky';
|
|
|
import personIcon from './images/personIcon.png';
|
|
|
import homeIcon from './images/homeIcon.png';
|
|
|
import memberIcon from './images/memberIcon.png';
|
|
|
import memberRateIcon from './images/memberRateIcon.png';
|
|
|
-import sanIcon from './images/san.png';
|
|
|
+// import sanIcon from './images/san.png';
|
|
|
+import iconArrow from './images/icon-arrow.png';
|
|
|
+import iconArrowActive from './images/icon-arrow-active.png';
|
|
|
import iconQrcode from './images/icon-qrcode.png';
|
|
|
import qrcodeBg from './images/qrcode-bg.png';
|
|
|
import qrbg from './images/qr-bg.png';
|
|
@@ -35,6 +40,8 @@ import numeral from 'numeral';
|
|
|
import MQrcode from '@/components/m-qrcode';
|
|
|
import html2canvas from 'html2canvas';
|
|
|
import MWxTip from '@/components/m-wx-tip';
|
|
|
+import deepClone from '@/helpers/deep-clone';
|
|
|
+import { number } from 'echarts';
|
|
|
export default defineComponent({
|
|
|
name: 'tenant-apply-data',
|
|
|
setup() {
|
|
@@ -57,6 +64,7 @@ export default defineComponent({
|
|
|
sortKey: 'CLASS' as 'CLASS' | 'MEMBER',
|
|
|
sortId: 'desc',
|
|
|
sortName: '报名人数降序',
|
|
|
+ sortType: 'desc',
|
|
|
sortList: [
|
|
|
{ value: 'desc', text: '报名人数降序' },
|
|
|
{ value: 'asc', text: '报名人数升序' },
|
|
@@ -66,9 +74,28 @@ export default defineComponent({
|
|
|
page: 1,
|
|
|
rows: 20,
|
|
|
isClick: false,
|
|
|
+ showDropdown: false,
|
|
|
qrcodeStatus: false,
|
|
|
url: '1', // 二维码
|
|
|
- urlItem: {} as any
|
|
|
+ urlItem: {} as any,
|
|
|
+
|
|
|
+ provinceList: [] as any, // 省
|
|
|
+ cityList: [] as any, // 市
|
|
|
+ areaList: [] as any, // 区
|
|
|
+ // 确认之后
|
|
|
+ searchConfirmObj: {
|
|
|
+ type: 'province' as 'province' | 'city' | 'area' | '',
|
|
|
+ label: '全部地区',
|
|
|
+ value: null as any,
|
|
|
+ list: [] as any
|
|
|
+ },
|
|
|
+ // 弹窗
|
|
|
+ searchObj: {
|
|
|
+ type: 'province' as 'province' | 'city' | 'area' | '',
|
|
|
+ label: '全部地区',
|
|
|
+ value: null as any,
|
|
|
+ list: [] as any
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
const refreshing = ref(false);
|
|
@@ -77,32 +104,32 @@ export default defineComponent({
|
|
|
const showContact = ref(false);
|
|
|
const list = ref([]);
|
|
|
|
|
|
- const getSchoolList = async () => {
|
|
|
- try {
|
|
|
- const { data } = await request.get('/edu-app/open/school/list', {
|
|
|
- params: {
|
|
|
- tenantId: forms.id
|
|
|
- }
|
|
|
- });
|
|
|
- const temp = [
|
|
|
- {
|
|
|
- value: '',
|
|
|
- text: '全部学校'
|
|
|
- }
|
|
|
- ];
|
|
|
- if (Array.isArray(data)) {
|
|
|
- data.forEach((item: any) => {
|
|
|
- temp.push({
|
|
|
- value: item.id,
|
|
|
- text: item.name
|
|
|
- });
|
|
|
- });
|
|
|
- forms.classList = temp;
|
|
|
- }
|
|
|
- } catch {
|
|
|
- //
|
|
|
- }
|
|
|
- };
|
|
|
+ // const getSchoolList = async () => {
|
|
|
+ // try {
|
|
|
+ // const { data } = await request.get('/edu-app/open/school/list', {
|
|
|
+ // params: {
|
|
|
+ // tenantId: forms.id
|
|
|
+ // }
|
|
|
+ // });
|
|
|
+ // const temp = [
|
|
|
+ // {
|
|
|
+ // value: '',
|
|
|
+ // text: '全部学校'
|
|
|
+ // }
|
|
|
+ // ];
|
|
|
+ // if (Array.isArray(data)) {
|
|
|
+ // data.forEach((item: any) => {
|
|
|
+ // temp.push({
|
|
|
+ // value: item.id,
|
|
|
+ // text: item.name
|
|
|
+ // });
|
|
|
+ // });
|
|
|
+ // forms.classList = temp;
|
|
|
+ // }
|
|
|
+ // } catch {
|
|
|
+ // //
|
|
|
+ // }
|
|
|
+ // };
|
|
|
|
|
|
const getList = async () => {
|
|
|
if (forms.isClick) {
|
|
@@ -115,18 +142,27 @@ export default defineComponent({
|
|
|
refreshing.value = false;
|
|
|
}
|
|
|
try {
|
|
|
+ const params: any = {
|
|
|
+ tenantId: forms.id,
|
|
|
+ page: forms.page,
|
|
|
+ rows: forms.rows,
|
|
|
+ year: forms.yearName,
|
|
|
+ keyword: forms.keyword,
|
|
|
+ sort: forms.sortId,
|
|
|
+ sortKey: forms.sortKey
|
|
|
+ };
|
|
|
+
|
|
|
+ if (forms.searchConfirmObj.type === 'province') {
|
|
|
+ params.provinceCode = forms.searchConfirmObj.value;
|
|
|
+ } else if (forms.searchConfirmObj.type === 'city') {
|
|
|
+ params.cityCode = forms.searchConfirmObj.value;
|
|
|
+ } else if (forms.searchConfirmObj.type === 'area') {
|
|
|
+ params.regionCode = forms.searchConfirmObj.value;
|
|
|
+ }
|
|
|
const res = await request.post(
|
|
|
'/edu-app/open/school/schoolRegisterPage',
|
|
|
{
|
|
|
- data: {
|
|
|
- tenantId: forms.id,
|
|
|
- page: forms.page,
|
|
|
- rows: forms.rows,
|
|
|
- year: forms.yearName,
|
|
|
- keyword: forms.keyword,
|
|
|
- sort: forms.sortId,
|
|
|
- sortKey: forms.sortKey
|
|
|
- }
|
|
|
+ data: params
|
|
|
}
|
|
|
);
|
|
|
|
|
@@ -213,6 +249,66 @@ export default defineComponent({
|
|
|
return Math.round((memberNum / studentNum) * 1000) / 10;
|
|
|
};
|
|
|
|
|
|
+ const dropdownItemRef = ref();
|
|
|
+ const getAreas = async () => {
|
|
|
+ try {
|
|
|
+ const { data } = await request.get(
|
|
|
+ '/edu-app/open/sysArea/queryProvince?tenantId=' + forms.id
|
|
|
+ );
|
|
|
+ forms.provinceList = data || [];
|
|
|
+ } catch {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const formatParentAreaId = (id: any, list: any, ids = [] as any) => {
|
|
|
+ for (const item of list) {
|
|
|
+ if (item.code == id) {
|
|
|
+ return [...ids, id];
|
|
|
+ }
|
|
|
+ if (item.areas && item.areas.length > 0) {
|
|
|
+ const cIds: any = formatParentAreaId(id, item.areas, [
|
|
|
+ ...ids,
|
|
|
+ item.code
|
|
|
+ ]);
|
|
|
+ if (cIds.includes(id)) {
|
|
|
+ return cIds;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ids;
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 切换状态 */
|
|
|
+ const onChangeArea = (type: 'province' | 'city' | 'area', item: any) => {
|
|
|
+ forms.searchObj.type = type;
|
|
|
+ forms.searchObj.value = item.code;
|
|
|
+ forms.searchObj.label = item.name;
|
|
|
+ forms.searchObj.list = formatParentAreaId(item.code, forms.provinceList);
|
|
|
+ if (type === 'province') {
|
|
|
+ forms.cityList = item.areas || [];
|
|
|
+ forms.areaList = [];
|
|
|
+ } else if (type === 'city') {
|
|
|
+ forms.areaList = item.areas || [];
|
|
|
+ } else if (type === 'area') {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const formatAreaDefaultData = (index: number, ids: number[], item: any) => {
|
|
|
+ const type: any = ['province', 'city', 'area'];
|
|
|
+ if (ids.length <= 0) return;
|
|
|
+ item.forEach((item: any) => {
|
|
|
+ if (item.code === ids[index]) {
|
|
|
+ onChangeArea(type[index], item);
|
|
|
+
|
|
|
+ if (ids[index]) {
|
|
|
+ formatAreaDefaultData(index + 1, ids, item.areas || []);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
onMounted(async () => {
|
|
|
if (route.query.name) {
|
|
|
document.title = route.query.name + '报名统计';
|
|
@@ -221,18 +317,28 @@ export default defineComponent({
|
|
|
}
|
|
|
|
|
|
// await getSchoolList();
|
|
|
+ getAreas();
|
|
|
await getStat();
|
|
|
await getList();
|
|
|
});
|
|
|
const getStat = async () => {
|
|
|
try {
|
|
|
+ const params: any = {
|
|
|
+ tenantId: forms.id,
|
|
|
+ year: forms.yearName
|
|
|
+ };
|
|
|
+
|
|
|
+ if (forms.searchConfirmObj.type === 'province') {
|
|
|
+ params.provinceCode = forms.searchConfirmObj.value;
|
|
|
+ } else if (forms.searchConfirmObj.type === 'city') {
|
|
|
+ params.cityCode = forms.searchConfirmObj.value;
|
|
|
+ } else if (forms.searchConfirmObj.type === 'area') {
|
|
|
+ params.regionCode = forms.searchConfirmObj.value;
|
|
|
+ }
|
|
|
const { data } = await request.post(
|
|
|
'/edu-app/open/school/schoolRegisterStat',
|
|
|
{
|
|
|
- data: {
|
|
|
- tenantId: forms.id,
|
|
|
- year: forms.yearName
|
|
|
- }
|
|
|
+ data: params
|
|
|
}
|
|
|
);
|
|
|
forms.statObj = data;
|
|
@@ -246,27 +352,138 @@ export default defineComponent({
|
|
|
<MSticky position="top">
|
|
|
<div class={styles.top}>
|
|
|
<div class={styles.topWrap}>
|
|
|
- <div class={styles.topHead}>
|
|
|
+ <div class={[styles.topHead, styles.topHeadIndex]}>
|
|
|
<img src={topDot} class={styles.topDot} alt="" />
|
|
|
汇总数据
|
|
|
</div>
|
|
|
- {/* <div
|
|
|
- class={styles.timerWrap}
|
|
|
- onClick={() => {
|
|
|
- forms.yearStatus = true;
|
|
|
- }}>
|
|
|
- {forms.yearName}年{' '}
|
|
|
- <img
|
|
|
- src={sanIcon}
|
|
|
- class={[
|
|
|
- styles.sanIcon,
|
|
|
- forms.yearStatus ? styles.routeSan : ''
|
|
|
- ]}
|
|
|
- alt=""
|
|
|
- />
|
|
|
- </div> */}
|
|
|
+
|
|
|
+ <DropdownMenu>
|
|
|
+ <DropdownItem
|
|
|
+ ref={dropdownItemRef}
|
|
|
+ onOpen={() => {
|
|
|
+ forms.searchObj = deepClone(forms.searchConfirmObj);
|
|
|
+
|
|
|
+ if (forms.searchObj.list.length > 0) {
|
|
|
+ formatAreaDefaultData(
|
|
|
+ 0,
|
|
|
+ forms.searchObj.list,
|
|
|
+ forms.provinceList
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }}>
|
|
|
+ {{
|
|
|
+ title: () => (
|
|
|
+ <div class={[styles.areaWrap, 'areaWrapActive']}>
|
|
|
+ <i class={styles.iconAddress}></i>
|
|
|
+ <span>{forms.searchConfirmObj.label}</span>
|
|
|
+ <i class={[styles.iconArrow, 'iconArrowActive']}></i>
|
|
|
+ </div>
|
|
|
+ ),
|
|
|
+ default: () => (
|
|
|
+ <div class={styles.areaSection}>
|
|
|
+ <div class={[styles.areaList]}>
|
|
|
+ {forms.provinceList.length > 0 && (
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.areaItem,
|
|
|
+ forms.cityList.length > 0 &&
|
|
|
+ 'van-hairline--right'
|
|
|
+ ]}>
|
|
|
+ {forms.provinceList.map((item: any) => (
|
|
|
+ <span
|
|
|
+ onClick={() => onChangeArea('province', item)}
|
|
|
+ class={[
|
|
|
+ styles.areaItemChild,
|
|
|
+ forms.searchObj.list.includes(item.code) &&
|
|
|
+ styles.areaItemChildActive
|
|
|
+ ]}>
|
|
|
+ {item.name}
|
|
|
+ </span>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {forms.cityList.length > 0 && (
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.areaItem,
|
|
|
+ forms.areaList.length > 0 &&
|
|
|
+ 'van-hairline--right'
|
|
|
+ ]}>
|
|
|
+ {forms.cityList.map((item: any) => (
|
|
|
+ <span
|
|
|
+ onClick={() => onChangeArea('city', item)}
|
|
|
+ class={[
|
|
|
+ styles.areaItemChild,
|
|
|
+ forms.searchObj.list.includes(item.code) &&
|
|
|
+ styles.areaItemChildActive
|
|
|
+ ]}>
|
|
|
+ {item.name}
|
|
|
+ </span>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {forms.areaList.length > 0 && (
|
|
|
+ <div class={[styles.areaItem]}>
|
|
|
+ {forms.areaList.map((item: any) => (
|
|
|
+ <span
|
|
|
+ onClick={() => onChangeArea('area', item)}
|
|
|
+ class={[
|
|
|
+ styles.areaItemChild,
|
|
|
+ forms.searchObj.list.includes(item.code) &&
|
|
|
+ styles.areaItemChildActive
|
|
|
+ ]}>
|
|
|
+ {item.name}
|
|
|
+ </span>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ <div class={[styles.btnGroup, 'van-hairline--top']}>
|
|
|
+ <Button
|
|
|
+ round
|
|
|
+ block
|
|
|
+ onClick={async () => {
|
|
|
+ forms.searchObj.type = '';
|
|
|
+ forms.searchObj.label = '全部地区';
|
|
|
+ forms.searchObj.value = null;
|
|
|
+ forms.searchObj.list = [];
|
|
|
+ forms.searchConfirmObj = deepClone(
|
|
|
+ forms.searchObj
|
|
|
+ );
|
|
|
+ dropdownItemRef.value?.toggle(false);
|
|
|
+ forms.page = 1;
|
|
|
+ refreshing.value = true;
|
|
|
+ await getStat();
|
|
|
+ await getList();
|
|
|
+ }}>
|
|
|
+ 重置
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ round
|
|
|
+ type="primary"
|
|
|
+ block
|
|
|
+ onClick={async () => {
|
|
|
+ forms.searchConfirmObj = deepClone(
|
|
|
+ forms.searchObj
|
|
|
+ );
|
|
|
+ dropdownItemRef.value?.toggle(false);
|
|
|
+ forms.page = 1;
|
|
|
+ refreshing.value = true;
|
|
|
+ await getStat();
|
|
|
+ await getList();
|
|
|
+ }}>
|
|
|
+ 确定
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ </DropdownItem>
|
|
|
+ </DropdownMenu>
|
|
|
</div>
|
|
|
- <div class={styles.cardWrap}>
|
|
|
+ <div class={[styles.cardWrap, styles.cardWrapIndex]}>
|
|
|
<div class={[styles.schoolCard, styles.cardItem]}>
|
|
|
<div class={styles.cardNum}>
|
|
|
{numeral(forms.statObj.schoolNum).format('0,0')}
|
|
@@ -330,19 +547,75 @@ export default defineComponent({
|
|
|
}}></OSearch>
|
|
|
</div>
|
|
|
|
|
|
- <div
|
|
|
- class={styles.timerWrap}
|
|
|
- onClick={() => (forms.perponStatus = true)}>
|
|
|
- {forms.sortName}{' '}
|
|
|
- <img
|
|
|
- src={sanIcon}
|
|
|
- class={[
|
|
|
- styles.sanIcon,
|
|
|
- forms.perponStatus ? styles.routeSan : ''
|
|
|
- ]}
|
|
|
- alt=""
|
|
|
- />
|
|
|
- </div>
|
|
|
+ <Popover
|
|
|
+ v-model:show={forms.perponStatus}
|
|
|
+ showArrow={false}
|
|
|
+ placement="bottom-end"
|
|
|
+ offset={[0, 12]}>
|
|
|
+ {{
|
|
|
+ reference: () => (
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.timerWrap,
|
|
|
+ forms.perponStatus && styles.timerWrapActive
|
|
|
+ ]}
|
|
|
+ // onClick={() => (forms.perponStatus = true)}
|
|
|
+ >
|
|
|
+ {forms.sortName}
|
|
|
+ <img
|
|
|
+ src={forms.perponStatus ? iconArrowActive : iconArrow}
|
|
|
+ class={[styles.sanIcon]}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ ),
|
|
|
+ default: () => (
|
|
|
+ <div class={styles.popSearchList}>
|
|
|
+ {forms.sortList.map((item: any, index: number) => (
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.popSearchItem,
|
|
|
+ index < forms.sortList.length - 1 &&
|
|
|
+ 'van-hairline--bottom'
|
|
|
+ ]}>
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.popSearchItemChild,
|
|
|
+ forms.sortType === item.value &&
|
|
|
+ styles.popSearchItemActive
|
|
|
+ ]}
|
|
|
+ onClick={() => {
|
|
|
+ const selectedOption = item;
|
|
|
+ if (
|
|
|
+ selectedOption.value === 'desc' ||
|
|
|
+ selectedOption.value === 'asc'
|
|
|
+ ) {
|
|
|
+ forms.sortId = selectedOption.value;
|
|
|
+ forms.sortKey = 'CLASS';
|
|
|
+ }
|
|
|
+ if (selectedOption.value === 'mdesc') {
|
|
|
+ forms.sortId = 'desc';
|
|
|
+ forms.sortKey = 'MEMBER';
|
|
|
+ }
|
|
|
+ if (selectedOption.value === 'masc') {
|
|
|
+ forms.sortId = 'asc';
|
|
|
+ forms.sortKey = 'MEMBER';
|
|
|
+ }
|
|
|
+
|
|
|
+ forms.sortType = selectedOption.value;
|
|
|
+ forms.sortName = selectedOption.text;
|
|
|
+ refreshing.value = true;
|
|
|
+ getList();
|
|
|
+ forms.perponStatus = false;
|
|
|
+ }}>
|
|
|
+ {item.text}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ </Popover>
|
|
|
</div>
|
|
|
</div>
|
|
|
</MSticky>
|
|
@@ -446,7 +719,7 @@ export default defineComponent({
|
|
|
/>
|
|
|
</Popup>
|
|
|
|
|
|
- <Popup
|
|
|
+ {/* <Popup
|
|
|
v-model:show={forms.perponStatus}
|
|
|
position="bottom"
|
|
|
round
|
|
@@ -479,7 +752,7 @@ export default defineComponent({
|
|
|
forms.perponStatus = false;
|
|
|
}}
|
|
|
/>
|
|
|
- </Popup>
|
|
|
+ </Popup> */}
|
|
|
|
|
|
<Popup v-model:show={forms.qrcodeStatus} class={styles.popupQrcode}>
|
|
|
<i
|