Procházet zdrojové kódy

Merge branch 'mp' of http://49.234.186.218:9000/root/ieplus-app into mp

abpcoder před 17 hodinami
rodič
revize
9e54edb66d
43 změnil soubory, kde provedl 2021 přidání a 1341 odebrání
  1. 3 0
      components.d.ts
  2. 1 2
      package.json
  3. 21 0
      src/App.vue
  4. 8 0
      src/api/modules/login.ts
  5. 433 433
      src/api/modules/university.ts
  6. 264 264
      src/common/enum.ts
  7. 17 1
      src/common/routes.ts
  8. 3 1
      src/components/ie-auto-resizer/ie-auto-resizer.vue
  9. 117 0
      src/components/ie-dropdown/ie-dropdown-hooks.ts
  10. 168 0
      src/components/ie-dropdown/ie-dropdown-item.vue
  11. 7 0
      src/components/ie-dropdown/ie-dropdown-popup.vue
  12. 41 0
      src/components/ie-dropdown/ie-dropdown.vue
  13. 9 9
      src/components/ie-popup/ie-popup.vue
  14. 5 1
      src/config.ts
  15. 44 0
      src/global.d.ts
  16. 2 2
      src/manifest.json
  17. 30 6
      src/pages.json
  18. 1 1
      src/pagesMain/pages/index/components/index-banner.vue
  19. 6 6
      src/pagesMain/pages/index/index.vue
  20. 5 3
      src/pagesMain/pages/me/components/me-info.vue
  21. 33 33
      src/pagesMain/pages/volunteer/volunteer.vue
  22. 3 3
      src/pagesOther/pages/career/detail/components/career-overview.vue
  23. 53 56
      src/pagesOther/pages/university/index/components/college-list.vue
  24. 90 14
      src/pagesOther/pages/university/index/components/plus/college-conditions-picker.vue
  25. 136 137
      src/pagesOther/pages/voluntary/list/list.vue
  26. 3 2
      src/pagesStudy/components/paper-work-item.vue
  27. 159 160
      src/pagesStudy/pages/targeted-add/targeted-add.vue
  28. 13 0
      src/pagesSystem/pages/privacy-policy/privacy-policy.vue
  29. 90 0
      src/pagesSystem/pages/setting/setting.vue
  30. 13 0
      src/pagesSystem/pages/user-protocol/user-protocol.vue
  31. 22 0
      src/pagesSystem/pages/webview/webview.vue
  32. binární
      src/static/mescroll-empty.png
  33. binární
      src/static/personal/icon-protocol.png
  34. 16 9
      src/store/userStore.ts
  35. 14 0
      src/types/dropdown.ts
  36. 3 4
      src/types/index.ts
  37. 4 4
      src/types/injectionSymbols.ts
  38. 93 83
      src/types/university.ts
  39. 68 68
      src/types/voluntary.ts
  40. 0 11
      src/utils/common.ts
  41. 22 0
      src/utils/format.ts
  42. 1 26
      src/utils/uni-tool.ts
  43. 0 2
      vite.config.js

+ 3 - 0
components.d.ts

@@ -12,6 +12,9 @@ declare module 'vue' {
     IeButtonIeButton: typeof import('./src/components/ie-button/ie-button.vue')['default']
     IeButtonIeButton: typeof import('./src/components/ie-button/ie-button.vue')['default']
     IeCardIeCard: typeof import('./src/components/ie-card/ie-card.vue')['default']
     IeCardIeCard: typeof import('./src/components/ie-card/ie-card.vue')['default']
     IeDictIeDict: typeof import('./src/components/ie-dict/ie-dict.vue')['default']
     IeDictIeDict: typeof import('./src/components/ie-dict/ie-dict.vue')['default']
+    IeDropdownIeDropdown: typeof import('./src/components/ie-dropdown/ie-dropdown.vue')['default']
+    IeDropdownIeDropdownItem: typeof import('./src/components/ie-dropdown/ie-dropdown-item.vue')['default']
+    IeDropdownIeDropdownPopup: typeof import('./src/components/ie-dropdown/ie-dropdown-popup.vue')['default']
     IeEmptyIeEmpty: typeof import('./src/components/ie-empty/ie-empty.vue')['default']
     IeEmptyIeEmpty: typeof import('./src/components/ie-empty/ie-empty.vue')['default']
     IeGapIeGap: typeof import('./src/components/ie-gap/ie-gap.vue')['default']
     IeGapIeGap: typeof import('./src/components/ie-gap/ie-gap.vue')['default']
     IeImageIeImage: typeof import('./src/components/ie-image/ie-image.vue')['default']
     IeImageIeImage: typeof import('./src/components/ie-image/ie-image.vue')['default']

+ 1 - 2
package.json

@@ -90,8 +90,7 @@
     "unplugin-auto-import": "^19.3.0",
     "unplugin-auto-import": "^19.3.0",
     "unplugin-vue-components": "^28.7.0",
     "unplugin-vue-components": "^28.7.0",
     "vite": "5.2.8",
     "vite": "5.2.8",
-    "vite-plugin-compression": "^0.5.1",
-    "vite-plugin-uni-polyfill": "^0.1.0"
+    "vite-plugin-compression": "^0.5.1"
   },
   },
   "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
   "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
 }
 }

+ 21 - 0
src/App.vue

@@ -29,4 +29,25 @@ export default {
 image {
 image {
   will-change: transform, width, height;
   will-change: transform, width, height;
 }
 }
+
+.uni-toast {
+  z-index: 9999;
+}
+
+.uni-modal {
+  border-radius: 6px;
+}
+
+.uni-modal__title {
+  font-weight: bold;
+}
+
+.uni-modal__bd {
+  padding-top: 50rpx;
+  padding-bottom: 50rpx;
+}
+
+.uni-modal__btn {
+  font-size: 16px;
+}
 </style>
 </style>

+ 8 - 0
src/api/modules/login.ts

@@ -70,4 +70,12 @@ export function getUserInfoWithToken(token: string) {
  */
  */
 export function updateUserInfo(params: UserInfo) {
 export function updateUserInfo(params: UserInfo) {
   return flyio.put('/front/user/userInfo', params) as Promise<ApiResponse<UserInfo>>;
   return flyio.put('/front/user/userInfo', params) as Promise<ApiResponse<UserInfo>>;
+}
+
+/**
+ * 永久注销账号
+ * @returns 
+ */
+export function logoutPhysical() {
+  return flyio.post('/logoutPhysical') as Promise<ApiResponse<any>>;
 }
 }

+ 433 - 433
src/api/modules/university.ts

@@ -1,442 +1,442 @@
-import {ApiResponse, ApiResponseList} from "@/types";
+import { ApiResponse, ApiResponseList } from "@/types";
 import flyio from "../flyio";
 import flyio from "../flyio";
-import {University, UniversityDetail, UniversityTier} from "@/types/university";
+import { University, UniversityDetail, UniversityFilter, UniversityTier } from "@/types/university";
 // import {sleep} from "@/uni_modules/uv-ui-tools/libs/function";
 // import {sleep} from "@/uni_modules/uv-ui-tools/libs/function";
 
 
 // 院校库 01 院校列表
 // 院校库 01 院校列表
 export function universityList(params: Record<string, any>) {
 export function universityList(params: Record<string, any>) {
-    return flyio.get('/front/university/list', params) as Promise<ApiResponseList<University>>
+  return flyio.get('/front/university/list', params) as Promise<ApiResponseList<University>>
 }
 }
 
 
 // 院校库 - 院校梯队
 // 院校库 - 院校梯队
 export function universityListByTier() {
 export function universityListByTier() {
-    // return new Promise(async (resolve, reject) => {
-    //     await sleep(300)
-    //     const mock = [{
-    //         typeName: '第一梯队',
-    //         typeValue: '1',
-    //         desc: '文化分280分以上',
-    //         list: [
-    //             {
-    //                 "id": 10827,
-    //                 "code": "10827",
-    //                 "name": "长沙民政职业技术学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/e6027a8c35f7426592f161c47f336fe7.jpg",
-    //                 "location": "湖南",
-    //                 "type": "理工类",
-    //                 "comScore": "85.63",
-    //                 "cityName": "长沙市",
-    //                 "star": "5★",
-    //                 "bxLevel": "双高,公办,国家级示范,现代学徒制试点学院,理工类",
-    //                 "features": "国家级示范,现代学徒制试点学院",
-    //                 "address": "湖南省长沙市雨花区香樟路22号",
-    //                 "hits": 4161780,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://zs.csmzxy.edu.cn/ddzs.htm",
-    //                 "area": 1024,
-    //                 "collect": 7915,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 10830,
-    //                 "code": "10830",
-    //                 "name": "湖南工业职业技术学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/83386e105f03474b91d7c1824e81fa0c.jpg",
-    //                 "location": "湖南",
-    //                 "type": "理工类",
-    //                 "comScore": "81.09",
-    //                 "cityName": "长沙市",
-    //                 "star": "5★-",
-    //                 "bxLevel": "双高,公办,国家级示范,理工类",
-    //                 "features": "国家级示范",
-    //                 "address": "湖南省长沙市岳麓区含浦科教园含浦大道139号",
-    //                 "hits": 2126,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://www.hunangy.com/zsjyc/",
-    //                 "area": 1031,
-    //                 "collect": 3169,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 10836,
-    //                 "code": "10836",
-    //                 "name": "株洲师范高等专科学校",
-    //                 "logo": "https://www.hnzzsz.com/template/blue/static/images/logo1.png",
-    //                 "location": "湖南",
-    //                 "managerType": "湖南省教育厅",
-    //                 "type": "师范类",
-    //                 "cityName": "株洲市",
-    //                 "bxLevel": "公办,师范类",
-    //                 "address": "湖南省株洲市云龙示范区智慧路89号",
-    //                 "hits": 9,
-    //                 "natureTypeCN": "公办",
-    //                 "area": 348,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 10865,
-    //                 "code": "10865",
-    //                 "name": "湖南信息职业技术学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/ed33a51d6ffa43ff89d93337f4a4369e.jpg",
-    //                 "location": "湖南",
-    //                 "type": "理工类",
-    //                 "comScore": "69.58",
-    //                 "cityName": "长沙市",
-    //                 "star": "3★",
-    //                 "bxLevel": "公办,理工类",
-    //                 "features": "",
-    //                 "address": "望城校区:湖南省长沙市望城区旺旺中路8号,芙蓉校区:湖南省长沙市芙蓉区职院街169号",
-    //                 "hits": 3268,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://zs.hniu.cn/recruit/index/index",
-    //                 "area": 345,
-    //                 "collect": 1594,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 12055,
-    //                 "code": "12055",
-    //                 "name": "长沙航空职业技术学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/f8ec6944910f42e8a2a430db9b37f622.jpg",
-    //                 "location": "湖南",
-    //                 "type": "理工类",
-    //                 "comScore": "80.01",
-    //                 "cityName": "长沙市",
-    //                 "star": "5★-",
-    //                 "bxLevel": "双高,公办,现代学徒制试点学院,理工类",
-    //                 "features": "现代学徒制试点学院",
-    //                 "address": "湖南省长沙市雨花区跳马镇(跳马校区),湖南省长沙市雨花区体院路348号(圭塘校区)",
-    //                 "hits": 1133,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://dzw.cavtc.cn/",
-    //                 "area": 1000,
-    //                 "collect": 484,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //
-    //
-    //         ]
-    //     }, {
-    //         typeName: '第二梯队',
-    //         typeValue: '2',
-    //         desc: '文化分270分以上',
-    //         list: [{
-    //             "id": 12300,
-    //             "code": "12300",
-    //             "name": "湖南大众传媒职业技术学院",
-    //             "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/2613786a1409452899cbbe1b2c413058.jpg",
-    //             "location": "湖南",
-    //             "type": "综合类",
-    //             "comScore": "71.73",
-    //             "cityName": "长沙市",
-    //             "star": "3★",
-    //             "bxLevel": "公办,国家级骨干,综合类",
-    //             "features": "国家级骨干",
-    //             "address": "湖南省长沙市星沙经济开发区特立路5号",
-    //             "hits": 6805,
-    //             "natureTypeCN": "公办",
-    //             "webSite": "http://www.hnmmc.cn:85/",
-    //             "area": 594,
-    //             "collect": 3048,
-    //             "enrollLocation": "湖南"
-    //         },
-    //             {
-    //                 "id": 12301,
-    //                 "code": "12301",
-    //                 "name": "永州职业技术学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/81a43cae8bb54211aa9be0849f47a708.jpg",
-    //                 "location": "湖南",
-    //                 "type": "综合类",
-    //                 "comScore": "73.17",
-    //                 "cityName": "永州市",
-    //                 "star": "4★",
-    //                 "bxLevel": "公办,国家级示范,现代学徒制试点学院,综合类",
-    //                 "features": "国家级示范,现代学徒制试点学院",
-    //                 "address": "湖南省永州市零陵区永州大道289号",
-    //                 "hits": 6508,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://hnyzzy.com/zsc/",
-    //                 "area": 3362,
-    //                 "collect": 2766,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 12302,
-    //                 "code": "12302",
-    //                 "name": "湖南铁道职业技术学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/23b6da550a584ea6b60886c6ae97b610.jpg",
-    //                 "location": "湖南",
-    //                 "type": "综合类",
-    //                 "comScore": "82.96",
-    //                 "cityName": "株洲市",
-    //                 "star": "5★",
-    //                 "bxLevel": "双高,公办,国家级示范,现代学徒制试点学院,综合类",
-    //                 "features": "国家级示范,现代学徒制试点学院",
-    //                 "address": "湖南省株洲市石峰区田心大道18号",
-    //                 "hits": 3804,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://zs.hnrpc.com/zsxt-web/zzzs/hntd/index.do",
-    //                 "area": 377,
-    //                 "collect": 1277,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 12304,
-    //                 "code": "12304",
-    //                 "name": "湖南科技职业学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/55654765a95d470f9ce32d6a2799cbdf.jpg",
-    //                 "location": "湖南",
-    //                 "type": "综合类",
-    //                 "comScore": "71.66",
-    //                 "cityName": "长沙市",
-    //                 "star": "3★",
-    //                 "bxLevel": "公办,国家级骨干,综合类",
-    //                 "features": "国家级骨干",
-    //                 "address": "雨花校区:湖南省长沙市井湾路784号,暮云校区:湖南省长沙市中意三路花园",
-    //                 "hits": 4326,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://zsb.hnkjxy.net.cn/",
-    //                 "area": 1000,
-    //                 "collect": 1683,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 12343,
-    //                 "code": "12343",
-    //                 "name": "湖南生物机电职业技术学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/7a6ac5559c424458a16fead8e6c522f9.jpg",
-    //                 "location": "湖南",
-    //                 "type": "农林类",
-    //                 "comScore": "73.31",
-    //                 "cityName": "长沙市",
-    //                 "star": "4★",
-    //                 "bxLevel": "双高,公办,现代学徒制试点学院,农林类",
-    //                 "features": "现代学徒制试点学院",
-    //                 "address": "湖南省长沙市芙蓉区隆平高科技园",
-    //                 "hits": 4992,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "https://zsjy.hnbemc.cn/",
-    //                 "area": 2470,
-    //                 "collect": 3353,
-    //                 "enrollLocation": "湖南"
-    //             }]
-    //     }, {
-    //         typeName: '第三梯队',
-    //         typeValue: '3',
-    //         desc: '文化分260分以上',
-    //         list: [{
-    //             "id": 12397,
-    //             "code": "12397",
-    //             "name": "湖南交通职业技术学院",
-    //             "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/4446a9570f03422a92472c0bc9980825.jpg",
-    //             "location": "湖南",
-    //             "type": "理工类",
-    //             "comScore": "78.85",
-    //             "cityName": "长沙市",
-    //             "star": "5★-",
-    //             "bxLevel": "双高,公办,国家级示范,理工类",
-    //             "features": "国家级示范",
-    //             "address": "湖南省长沙市黄兴镇湖南交通职业技术学院",
-    //             "hits": 5584,
-    //             "natureTypeCN": "公办",
-    //             "webSite": "http://zsw.hnjtzy.com.cn/",
-    //             "area": 728,
-    //             "collect": 2047,
-    //             "enrollLocation": "湖南"
-    //         },
-    //             {
-    //                 "id": 12401,
-    //                 "code": "12401",
-    //                 "name": "湖南商务职业技术学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/a0995669452c4f2e9ad4b9faa6903883.jpg",
-    //                 "location": "湖南",
-    //                 "type": "财经类",
-    //                 "comScore": "66.37",
-    //                 "cityName": "长沙市",
-    //                 "star": "3★",
-    //                 "bxLevel": "公办,财经类",
-    //                 "features": "",
-    //                 "address": "湖南省长沙市岳麓区雷锋大道335号",
-    //                 "hits": 3381,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://www.hnswxy.com/danzhao/",
-    //                 "area": 428,
-    //                 "collect": 1751,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 12423,
-    //                 "code": "12423",
-    //                 "name": "湖南体育职业学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/ffa48630d0da4dd89f7f9855dadb8565.jpg",
-    //                 "location": "湖南",
-    //                 "type": "体育类",
-    //                 "comScore": "64.69",
-    //                 "cityName": "长沙市",
-    //                 "star": "",
-    //                 "bxLevel": "公办,体育类",
-    //                 "features": "",
-    //                 "address": "湖南省长沙市雨花区体院北路71号",
-    //                 "hits": 1143,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://www.hntyxy.net/zsw.jhtml",
-    //                 "area": 689,
-    //                 "collect": 199,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 12425,
-    //                 "code": "12425",
-    //                 "name": "湖南工程职业技术学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/475316e2a3ef4674806730bac4499c55.jpg",
-    //                 "location": "湖南",
-    //                 "type": "理工类",
-    //                 "comScore": "69.67",
-    //                 "cityName": "长沙市",
-    //                 "star": "3★",
-    //                 "bxLevel": "公办,理工类",
-    //                 "features": "",
-    //                 "address": "湖南省长沙市万家丽北路水渡河100号",
-    //                 "hits": 753,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://hngczyzs.bibibi.net/recruit/index/index",
-    //                 "area": 600,
-    //                 "collect": 1790,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 12596,
-    //                 "code": "12596",
-    //                 "name": "保险职业学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/9e259e8a208f4865ab37397d649ee051.jpg",
-    //                 "location": "湖南",
-    //                 "type": "财经类",
-    //                 "comScore": "64.26",
-    //                 "cityName": "长沙市",
-    //                 "star": "",
-    //                 "bxLevel": "公办,财经类",
-    //                 "features": "",
-    //                 "address": "湖南省长沙市天心区中豹塘路196号",
-    //                 "hits": 3985,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "https://www.bxxy.com/html/folder/20070139-1.htm",
-    //                 "area": 157,
-    //                 "collect": 307,
-    //                 "enrollLocation": "湖南"
-    //             }]
-    //     }, {
-    //         typeName: '第四梯队',
-    //         typeValue: '4',
-    //         desc: '文化分250分以上',
-    //         list: [{
-    //             "id": 12597,
-    //             "code": "12597",
-    //             "name": "湖南外贸职业学院",
-    //             "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/4e039fa413b1435e8aaadff57306519c.jpg",
-    //             "location": "湖南",
-    //             "type": "财经类",
-    //             "comScore": "66.92",
-    //             "cityName": "长沙市",
-    //             "star": "3★",
-    //             "bxLevel": "公办,财经类",
-    //             "features": "",
-    //             "address": "湖南省长沙市芙蓉北路望城区丁字镇翻身垸",
-    //             "hits": 3086,
-    //             "natureTypeCN": "公办",
-    //             "webSite": "http://www.hnwmxy.com/hezuobangongshi/",
-    //             "area": 706,
-    //             "collect": 1945,
-    //             "enrollLocation": "湖南"
-    //         },
-    //             {
-    //                 "id": 12598,
-    //                 "code": "12598",
-    //                 "name": "湖南网络工程职业学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/6ed81c4da4ff4f44a356a1701459d2a5.jpg",
-    //                 "location": "湖南",
-    //                 "type": "综合类",
-    //                 "comScore": "67.38",
-    //                 "cityName": "长沙市",
-    //                 "star": "3★",
-    //                 "bxLevel": "公办,综合类",
-    //                 "features": "",
-    //                 "address": "湖南省长沙市青园路168号",
-    //                 "hits": 2689,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://www2.hnevc.com/zs/",
-    //                 "area": 264,
-    //                 "collect": 739,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 12600,
-    //                 "code": "12600",
-    //                 "name": "邵阳职业技术学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/d3ea79ff7cfe4951bc4e39d118fa5adf.jpg",
-    //                 "location": "湖南",
-    //                 "type": "综合类",
-    //                 "comScore": "64.27",
-    //                 "cityName": "邵阳市",
-    //                 "star": "",
-    //                 "bxLevel": "公办,其他,综合类",
-    //                 "features": "其他",
-    //                 "address": "湖南省邵阳市大祥区城南乡学院路",
-    //                 "hits": 1801,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://www.syzyedu.com/bm/default.aspx?depid=25",
-    //                 "area": 640,
-    //                 "collect": 497,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 12601,
-    //                 "code": "12601",
-    //                 "name": "湖南司法警官职业学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/b99a0e8c360e494ba3ddbf60cec9d21b.jpg",
-    //                 "location": "湖南",
-    //                 "type": "政法类",
-    //                 "comScore": "64.04",
-    //                 "cityName": "长沙市",
-    //                 "star": "",
-    //                 "bxLevel": "公办,政法类",
-    //                 "features": "",
-    //                 "address": "湖南省长沙市芙蓉区远大二路1069号",
-    //                 "hits": 3178,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://zs.hnsfjy.cn",
-    //                 "area": 0,
-    //                 "collect": 807,
-    //                 "enrollLocation": "湖南"
-    //             },
-    //             {
-    //                 "id": 12603,
-    //                 "code": "12603",
-    //                 "name": "长沙商贸旅游职业技术学院",
-    //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/ef1bcd5af239468299787456d9307da1.jpg",
-    //                 "location": "湖南",
-    //                 "type": "财经类",
-    //                 "comScore": "75.46",
-    //                 "cityName": "长沙市",
-    //                 "star": "4★",
-    //                 "bxLevel": "双高,公办,现代学徒制试点学院,财经类",
-    //                 "features": "现代学徒制试点学院",
-    //                 "address": "湖南省长沙市雨花区圭白路16号",
-    //                 "hits": 2215,
-    //                 "natureTypeCN": "公办",
-    //                 "webSite": "http://jyzs.hncpu.com:8080/",
-    //                 "area": 712,
-    //                 "collect": 5127,
-    //                 "enrollLocation": "湖南"
-    //             }]
-    //     }]
-    //     resolve({code: 200, data: mock})
-    // })
-    // 返回全量,不需要分页
-    return flyio.get('/front/university/listByTier') as Promise<ApiResponse<UniversityTier[]>>
+  // return new Promise(async (resolve, reject) => {
+  //     await sleep(300)
+  //     const mock = [{
+  //         typeName: '第一梯队',
+  //         typeValue: '1',
+  //         desc: '文化分280分以上',
+  //         list: [
+  //             {
+  //                 "id": 10827,
+  //                 "code": "10827",
+  //                 "name": "长沙民政职业技术学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/e6027a8c35f7426592f161c47f336fe7.jpg",
+  //                 "location": "湖南",
+  //                 "type": "理工类",
+  //                 "comScore": "85.63",
+  //                 "cityName": "长沙市",
+  //                 "star": "5★",
+  //                 "bxLevel": "双高,公办,国家级示范,现代学徒制试点学院,理工类",
+  //                 "features": "国家级示范,现代学徒制试点学院",
+  //                 "address": "湖南省长沙市雨花区香樟路22号",
+  //                 "hits": 4161780,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://zs.csmzxy.edu.cn/ddzs.htm",
+  //                 "area": 1024,
+  //                 "collect": 7915,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 10830,
+  //                 "code": "10830",
+  //                 "name": "湖南工业职业技术学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/83386e105f03474b91d7c1824e81fa0c.jpg",
+  //                 "location": "湖南",
+  //                 "type": "理工类",
+  //                 "comScore": "81.09",
+  //                 "cityName": "长沙市",
+  //                 "star": "5★-",
+  //                 "bxLevel": "双高,公办,国家级示范,理工类",
+  //                 "features": "国家级示范",
+  //                 "address": "湖南省长沙市岳麓区含浦科教园含浦大道139号",
+  //                 "hits": 2126,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://www.hunangy.com/zsjyc/",
+  //                 "area": 1031,
+  //                 "collect": 3169,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 10836,
+  //                 "code": "10836",
+  //                 "name": "株洲师范高等专科学校",
+  //                 "logo": "https://www.hnzzsz.com/template/blue/static/images/logo1.png",
+  //                 "location": "湖南",
+  //                 "managerType": "湖南省教育厅",
+  //                 "type": "师范类",
+  //                 "cityName": "株洲市",
+  //                 "bxLevel": "公办,师范类",
+  //                 "address": "湖南省株洲市云龙示范区智慧路89号",
+  //                 "hits": 9,
+  //                 "natureTypeCN": "公办",
+  //                 "area": 348,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 10865,
+  //                 "code": "10865",
+  //                 "name": "湖南信息职业技术学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/ed33a51d6ffa43ff89d93337f4a4369e.jpg",
+  //                 "location": "湖南",
+  //                 "type": "理工类",
+  //                 "comScore": "69.58",
+  //                 "cityName": "长沙市",
+  //                 "star": "3★",
+  //                 "bxLevel": "公办,理工类",
+  //                 "features": "",
+  //                 "address": "望城校区:湖南省长沙市望城区旺旺中路8号,芙蓉校区:湖南省长沙市芙蓉区职院街169号",
+  //                 "hits": 3268,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://zs.hniu.cn/recruit/index/index",
+  //                 "area": 345,
+  //                 "collect": 1594,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 12055,
+  //                 "code": "12055",
+  //                 "name": "长沙航空职业技术学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/f8ec6944910f42e8a2a430db9b37f622.jpg",
+  //                 "location": "湖南",
+  //                 "type": "理工类",
+  //                 "comScore": "80.01",
+  //                 "cityName": "长沙市",
+  //                 "star": "5★-",
+  //                 "bxLevel": "双高,公办,现代学徒制试点学院,理工类",
+  //                 "features": "现代学徒制试点学院",
+  //                 "address": "湖南省长沙市雨花区跳马镇(跳马校区),湖南省长沙市雨花区体院路348号(圭塘校区)",
+  //                 "hits": 1133,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://dzw.cavtc.cn/",
+  //                 "area": 1000,
+  //                 "collect": 484,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //
+  //
+  //         ]
+  //     }, {
+  //         typeName: '第二梯队',
+  //         typeValue: '2',
+  //         desc: '文化分270分以上',
+  //         list: [{
+  //             "id": 12300,
+  //             "code": "12300",
+  //             "name": "湖南大众传媒职业技术学院",
+  //             "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/2613786a1409452899cbbe1b2c413058.jpg",
+  //             "location": "湖南",
+  //             "type": "综合类",
+  //             "comScore": "71.73",
+  //             "cityName": "长沙市",
+  //             "star": "3★",
+  //             "bxLevel": "公办,国家级骨干,综合类",
+  //             "features": "国家级骨干",
+  //             "address": "湖南省长沙市星沙经济开发区特立路5号",
+  //             "hits": 6805,
+  //             "natureTypeCN": "公办",
+  //             "webSite": "http://www.hnmmc.cn:85/",
+  //             "area": 594,
+  //             "collect": 3048,
+  //             "enrollLocation": "湖南"
+  //         },
+  //             {
+  //                 "id": 12301,
+  //                 "code": "12301",
+  //                 "name": "永州职业技术学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/81a43cae8bb54211aa9be0849f47a708.jpg",
+  //                 "location": "湖南",
+  //                 "type": "综合类",
+  //                 "comScore": "73.17",
+  //                 "cityName": "永州市",
+  //                 "star": "4★",
+  //                 "bxLevel": "公办,国家级示范,现代学徒制试点学院,综合类",
+  //                 "features": "国家级示范,现代学徒制试点学院",
+  //                 "address": "湖南省永州市零陵区永州大道289号",
+  //                 "hits": 6508,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://hnyzzy.com/zsc/",
+  //                 "area": 3362,
+  //                 "collect": 2766,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 12302,
+  //                 "code": "12302",
+  //                 "name": "湖南铁道职业技术学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/23b6da550a584ea6b60886c6ae97b610.jpg",
+  //                 "location": "湖南",
+  //                 "type": "综合类",
+  //                 "comScore": "82.96",
+  //                 "cityName": "株洲市",
+  //                 "star": "5★",
+  //                 "bxLevel": "双高,公办,国家级示范,现代学徒制试点学院,综合类",
+  //                 "features": "国家级示范,现代学徒制试点学院",
+  //                 "address": "湖南省株洲市石峰区田心大道18号",
+  //                 "hits": 3804,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://zs.hnrpc.com/zsxt-web/zzzs/hntd/index.do",
+  //                 "area": 377,
+  //                 "collect": 1277,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 12304,
+  //                 "code": "12304",
+  //                 "name": "湖南科技职业学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/55654765a95d470f9ce32d6a2799cbdf.jpg",
+  //                 "location": "湖南",
+  //                 "type": "综合类",
+  //                 "comScore": "71.66",
+  //                 "cityName": "长沙市",
+  //                 "star": "3★",
+  //                 "bxLevel": "公办,国家级骨干,综合类",
+  //                 "features": "国家级骨干",
+  //                 "address": "雨花校区:湖南省长沙市井湾路784号,暮云校区:湖南省长沙市中意三路花园",
+  //                 "hits": 4326,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://zsb.hnkjxy.net.cn/",
+  //                 "area": 1000,
+  //                 "collect": 1683,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 12343,
+  //                 "code": "12343",
+  //                 "name": "湖南生物机电职业技术学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/7a6ac5559c424458a16fead8e6c522f9.jpg",
+  //                 "location": "湖南",
+  //                 "type": "农林类",
+  //                 "comScore": "73.31",
+  //                 "cityName": "长沙市",
+  //                 "star": "4★",
+  //                 "bxLevel": "双高,公办,现代学徒制试点学院,农林类",
+  //                 "features": "现代学徒制试点学院",
+  //                 "address": "湖南省长沙市芙蓉区隆平高科技园",
+  //                 "hits": 4992,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "https://zsjy.hnbemc.cn/",
+  //                 "area": 2470,
+  //                 "collect": 3353,
+  //                 "enrollLocation": "湖南"
+  //             }]
+  //     }, {
+  //         typeName: '第三梯队',
+  //         typeValue: '3',
+  //         desc: '文化分260分以上',
+  //         list: [{
+  //             "id": 12397,
+  //             "code": "12397",
+  //             "name": "湖南交通职业技术学院",
+  //             "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/4446a9570f03422a92472c0bc9980825.jpg",
+  //             "location": "湖南",
+  //             "type": "理工类",
+  //             "comScore": "78.85",
+  //             "cityName": "长沙市",
+  //             "star": "5★-",
+  //             "bxLevel": "双高,公办,国家级示范,理工类",
+  //             "features": "国家级示范",
+  //             "address": "湖南省长沙市黄兴镇湖南交通职业技术学院",
+  //             "hits": 5584,
+  //             "natureTypeCN": "公办",
+  //             "webSite": "http://zsw.hnjtzy.com.cn/",
+  //             "area": 728,
+  //             "collect": 2047,
+  //             "enrollLocation": "湖南"
+  //         },
+  //             {
+  //                 "id": 12401,
+  //                 "code": "12401",
+  //                 "name": "湖南商务职业技术学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/a0995669452c4f2e9ad4b9faa6903883.jpg",
+  //                 "location": "湖南",
+  //                 "type": "财经类",
+  //                 "comScore": "66.37",
+  //                 "cityName": "长沙市",
+  //                 "star": "3★",
+  //                 "bxLevel": "公办,财经类",
+  //                 "features": "",
+  //                 "address": "湖南省长沙市岳麓区雷锋大道335号",
+  //                 "hits": 3381,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://www.hnswxy.com/danzhao/",
+  //                 "area": 428,
+  //                 "collect": 1751,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 12423,
+  //                 "code": "12423",
+  //                 "name": "湖南体育职业学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/ffa48630d0da4dd89f7f9855dadb8565.jpg",
+  //                 "location": "湖南",
+  //                 "type": "体育类",
+  //                 "comScore": "64.69",
+  //                 "cityName": "长沙市",
+  //                 "star": "",
+  //                 "bxLevel": "公办,体育类",
+  //                 "features": "",
+  //                 "address": "湖南省长沙市雨花区体院北路71号",
+  //                 "hits": 1143,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://www.hntyxy.net/zsw.jhtml",
+  //                 "area": 689,
+  //                 "collect": 199,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 12425,
+  //                 "code": "12425",
+  //                 "name": "湖南工程职业技术学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/475316e2a3ef4674806730bac4499c55.jpg",
+  //                 "location": "湖南",
+  //                 "type": "理工类",
+  //                 "comScore": "69.67",
+  //                 "cityName": "长沙市",
+  //                 "star": "3★",
+  //                 "bxLevel": "公办,理工类",
+  //                 "features": "",
+  //                 "address": "湖南省长沙市万家丽北路水渡河100号",
+  //                 "hits": 753,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://hngczyzs.bibibi.net/recruit/index/index",
+  //                 "area": 600,
+  //                 "collect": 1790,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 12596,
+  //                 "code": "12596",
+  //                 "name": "保险职业学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/9e259e8a208f4865ab37397d649ee051.jpg",
+  //                 "location": "湖南",
+  //                 "type": "财经类",
+  //                 "comScore": "64.26",
+  //                 "cityName": "长沙市",
+  //                 "star": "",
+  //                 "bxLevel": "公办,财经类",
+  //                 "features": "",
+  //                 "address": "湖南省长沙市天心区中豹塘路196号",
+  //                 "hits": 3985,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "https://www.bxxy.com/html/folder/20070139-1.htm",
+  //                 "area": 157,
+  //                 "collect": 307,
+  //                 "enrollLocation": "湖南"
+  //             }]
+  //     }, {
+  //         typeName: '第四梯队',
+  //         typeValue: '4',
+  //         desc: '文化分250分以上',
+  //         list: [{
+  //             "id": 12597,
+  //             "code": "12597",
+  //             "name": "湖南外贸职业学院",
+  //             "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/4e039fa413b1435e8aaadff57306519c.jpg",
+  //             "location": "湖南",
+  //             "type": "财经类",
+  //             "comScore": "66.92",
+  //             "cityName": "长沙市",
+  //             "star": "3★",
+  //             "bxLevel": "公办,财经类",
+  //             "features": "",
+  //             "address": "湖南省长沙市芙蓉北路望城区丁字镇翻身垸",
+  //             "hits": 3086,
+  //             "natureTypeCN": "公办",
+  //             "webSite": "http://www.hnwmxy.com/hezuobangongshi/",
+  //             "area": 706,
+  //             "collect": 1945,
+  //             "enrollLocation": "湖南"
+  //         },
+  //             {
+  //                 "id": 12598,
+  //                 "code": "12598",
+  //                 "name": "湖南网络工程职业学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/6ed81c4da4ff4f44a356a1701459d2a5.jpg",
+  //                 "location": "湖南",
+  //                 "type": "综合类",
+  //                 "comScore": "67.38",
+  //                 "cityName": "长沙市",
+  //                 "star": "3★",
+  //                 "bxLevel": "公办,综合类",
+  //                 "features": "",
+  //                 "address": "湖南省长沙市青园路168号",
+  //                 "hits": 2689,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://www2.hnevc.com/zs/",
+  //                 "area": 264,
+  //                 "collect": 739,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 12600,
+  //                 "code": "12600",
+  //                 "name": "邵阳职业技术学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/d3ea79ff7cfe4951bc4e39d118fa5adf.jpg",
+  //                 "location": "湖南",
+  //                 "type": "综合类",
+  //                 "comScore": "64.27",
+  //                 "cityName": "邵阳市",
+  //                 "star": "",
+  //                 "bxLevel": "公办,其他,综合类",
+  //                 "features": "其他",
+  //                 "address": "湖南省邵阳市大祥区城南乡学院路",
+  //                 "hits": 1801,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://www.syzyedu.com/bm/default.aspx?depid=25",
+  //                 "area": 640,
+  //                 "collect": 497,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 12601,
+  //                 "code": "12601",
+  //                 "name": "湖南司法警官职业学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/b99a0e8c360e494ba3ddbf60cec9d21b.jpg",
+  //                 "location": "湖南",
+  //                 "type": "政法类",
+  //                 "comScore": "64.04",
+  //                 "cityName": "长沙市",
+  //                 "star": "",
+  //                 "bxLevel": "公办,政法类",
+  //                 "features": "",
+  //                 "address": "湖南省长沙市芙蓉区远大二路1069号",
+  //                 "hits": 3178,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://zs.hnsfjy.cn",
+  //                 "area": 0,
+  //                 "collect": 807,
+  //                 "enrollLocation": "湖南"
+  //             },
+  //             {
+  //                 "id": 12603,
+  //                 "code": "12603",
+  //                 "name": "长沙商贸旅游职业技术学院",
+  //                 "logo": "https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/ie/universityLog/ef1bcd5af239468299787456d9307da1.jpg",
+  //                 "location": "湖南",
+  //                 "type": "财经类",
+  //                 "comScore": "75.46",
+  //                 "cityName": "长沙市",
+  //                 "star": "4★",
+  //                 "bxLevel": "双高,公办,现代学徒制试点学院,财经类",
+  //                 "features": "现代学徒制试点学院",
+  //                 "address": "湖南省长沙市雨花区圭白路16号",
+  //                 "hits": 2215,
+  //                 "natureTypeCN": "公办",
+  //                 "webSite": "http://jyzs.hncpu.com:8080/",
+  //                 "area": 712,
+  //                 "collect": 5127,
+  //                 "enrollLocation": "湖南"
+  //             }]
+  //     }]
+  //     resolve({code: 200, data: mock})
+  // })
+  // 返回全量,不需要分页
+  return flyio.get('/front/university/listByTier') as Promise<ApiResponse<UniversityTier[]>>
 }
 }
 
 
 export function universityDetail(params: any) {
 export function universityDetail(params: any) {
-    return flyio.get('/front/university/detail', params) as Promise<ApiResponse<UniversityDetail>>
+  return flyio.get('/front/university/detail', params) as Promise<ApiResponse<UniversityDetail>>
 }
 }
 
 
 /**
 /**
@@ -445,7 +445,7 @@ export function universityDetail(params: any) {
  * @returns
  * @returns
  */
  */
 export function getUniversityList() {
 export function getUniversityList() {
-    return flyio.get('/front/student/university') as Promise<ApiResponse<any>>;
+  return flyio.get('/front/student/university') as Promise<ApiResponse<any>>;
 }
 }
 
 
 /**
 /**
@@ -454,28 +454,28 @@ export function getUniversityList() {
  * @returns
  * @returns
  */
  */
 export function getUniversityMajorList(params: { universityId: string }) {
 export function getUniversityMajorList(params: { universityId: string }) {
-    return flyio.get('/front/student/university/major', params) as Promise<ApiResponse<any>>;
+  return flyio.get('/front/student/university/major', params) as Promise<ApiResponse<any>>;
 }
 }
 
 
 /*院校筛选条件*/
 /*院校筛选条件*/
 export function getUniversityFilters() {
 export function getUniversityFilters() {
-    return flyio.get('/front/university/filters') as Promise<ApiResponse<Record<string, string[]>>>
+  return flyio.get('/front/university/filters') as Promise<ApiResponse<UniversityFilter>>
 }
 }
 
 
 // GET
 // GET
 // /prod-api/front/customer/university/add
 // /prod-api/front/customer/university/add
 // 03 关注院校
 // 03 关注院校
 export function concernUniversity(params: any) {
 export function concernUniversity(params: any) {
-    return flyio.get('/front/customer/university/add', params)
+  return flyio.get('/front/customer/university/add', params)
 }
 }
 
 
 // GET
 // GET
 // /prod-api/front/customer/university/remove
 // /prod-api/front/customer/university/remove
 // 02 移除关注院校
 // 02 移除关注院校
 export function removeConcernedUniversity(params: any) {
 export function removeConcernedUniversity(params: any) {
-    return flyio.get('/front/customer/university/remove', params)
+  return flyio.get('/front/customer/university/remove', params)
 }
 }
 
 
 export function getUniversitiesEnrollBrochureDetail(params: any) {
 export function getUniversitiesEnrollBrochureDetail(params: any) {
-    return flyio.get('/front/university/getUniversitiesEnrollBrochureDetail', params)
+  return flyio.get('/front/university/getUniversitiesEnrollBrochureDetail', params)
 }
 }

+ 264 - 264
src/common/enum.ts

@@ -2,170 +2,170 @@
  * 应用配置项的 key
  * 应用配置项的 key
  */
  */
 export enum EnumAppConfigKey {
 export enum EnumAppConfigKey {
-    /**
-     * 短信验证码是否开启图形验证
-     */
-    SMS_CAPTCHA_ENABLE = 'sys.sms.captchaEnabled'
+  /**
+   * 短信验证码是否开启图形验证
+   */
+  SMS_CAPTCHA_ENABLE = 'sys.sms.captchaEnabled'
 }
 }
 
 
 /**
 /**
  * 短信发送类型
  * 短信发送类型
  */
  */
 export enum EnumSmsApiType {
 export enum EnumSmsApiType {
-    /**
-     * 无需校验 无需token 发送短信-适用于登录
-     */
-    NO_VALIDATION_NO_TOKEN = 'NoValidationNoToken',
-    /**
-     * 需校验 需要 token 发送短信-适用于注册
-     */
-    NO_TOKEN = 'NoToken',
-    /**
-     * 普通发送短信
-     */
-    NORMAL = 'normal'
+  /**
+   * 无需校验 无需token 发送短信-适用于登录
+   */
+  NO_VALIDATION_NO_TOKEN = 'NoValidationNoToken',
+  /**
+   * 需校验 需要 token 发送短信-适用于注册
+   */
+  NO_TOKEN = 'NoToken',
+  /**
+   * 普通发送短信
+   */
+  NORMAL = 'normal'
 }
 }
 
 
 /**
 /**
  * 短信类型
  * 短信类型
  */
  */
 export enum EnumSmsType {
 export enum EnumSmsType {
-    /**
-     * code
-     */
-    CODE = 'CODE',
-    /**
-     * ecard
-     */
-    ECARD = 'ECARD',
-    /**
-     * password
-     */
-    PASSWORD = 'PASSWORD'
+  /**
+   * code
+   */
+  CODE = 'CODE',
+  /**
+   * ecard
+   */
+  ECARD = 'ECARD',
+  /**
+   * password
+   */
+  PASSWORD = 'PASSWORD'
 }
 }
 
 
 export enum EnumDictName {
 export enum EnumDictName {
-    /**
-     * 考生类别
-     */
-    EXAM_TYPE = 'exam_type'
+  /**
+   * 考生类别
+   */
+  EXAM_TYPE = 'exam_type'
 }
 }
 
 
 export enum STATIC_PAGE_PATH {
 export enum STATIC_PAGE_PATH {
-    /**
-     * 登录
-     */
-    LOGIN = '/pagesSystem/pages/login/login',
-    /**
-     * 注册
-     */
-    REGISTER = '/pagesSystem/pages/register/register',
-    /**
-     * 找回密码
-     */
-    FIND_PASSWORD = '/pagesSystem/pages/find-password/find-password',
-    /**
-     * 修改密码
-     */
-    CHANGE_PASSWORD = '/pagesSystem/pages/change-password/change-password',
-    /**
-     * 绑定手机号
-     */
-    BIND_PHONE = '/pagesSystem/pages/bind-phone/bind-phone'
+  /**
+   * 登录
+   */
+  LOGIN = '/pagesSystem/pages/login/login',
+  /**
+   * 注册
+   */
+  REGISTER = '/pagesSystem/pages/register/register',
+  /**
+   * 找回密码
+   */
+  FIND_PASSWORD = '/pagesSystem/pages/find-password/find-password',
+  /**
+   * 修改密码
+   */
+  CHANGE_PASSWORD = '/pagesSystem/pages/change-password/change-password',
+  /**
+   * 绑定手机号
+   */
+  BIND_PHONE = '/pagesSystem/pages/bind-phone/bind-phone'
 }
 }
 
 
 export enum EnumExamMode {
 export enum EnumExamMode {
-    /**
-     * 练习
-     */
-    PRACTICE = 1,
-    /**
-     * 考试
-     */
-    EXAM = 2
+  /**
+   * 练习
+   */
+  PRACTICE = 1,
+  /**
+   * 考试
+   */
+  EXAM = 2
 }
 }
 
 
 /**
 /**
  * 题目类型
  * 题目类型
  */
  */
 export enum EnumQuestionType {
 export enum EnumQuestionType {
-    /**
-     * 单选
-     */
-    SINGLE_CHOICE = 1,
-    /**
-     * 多选
-     */
-    MULTIPLE_CHOICE = 2,
-    /**
-     * 判断
-     */
-    JUDGMENT = 3,
-    /**
-     * 填空
-     */
-    FILL_IN_THE_BLANK = 4,
-    /**
-     * 主观题
-     */
-    SUBJECTIVE = 5,
-    /**
-     * 简答
-     */
-    SHORT_ANSWER = 6,
-    /**
-     * 问答题
-     */
-    ESSAY = 7,
-    /**
-     * 分析题
-     */
-    ANALYSIS = 8,
+  /**
+   * 单选
+   */
+  SINGLE_CHOICE = 1,
+  /**
+   * 多选
+   */
+  MULTIPLE_CHOICE = 2,
+  /**
+   * 判断
+   */
+  JUDGMENT = 3,
+  /**
+   * 填空
+   */
+  FILL_IN_THE_BLANK = 4,
+  /**
+   * 主观题
+   */
+  SUBJECTIVE = 5,
+  /**
+   * 简答
+   */
+  SHORT_ANSWER = 6,
+  /**
+   * 问答题
+   */
+  ESSAY = 7,
+  /**
+   * 分析题
+   */
+  ANALYSIS = 8,
 
 
-    /**
-     * 阅读题
-     */
-    OTHER = 99
+  /**
+   * 阅读题
+   */
+  OTHER = 99
 }
 }
 
 
 /**
 /**
  * 用户类型
  * 用户类型
  */
  */
 export enum EnumUserType {
 export enum EnumUserType {
-    /**
-     * 系统用户
-     */
-    SYSTEM = '00',
-    /**
-     * 学生
-     */
-    STUDENT = '01',
-    /**
-     * 教师
-     */
-    TEACHER = '11',
-    /**
-     * 代理商
-     */
-    AGENT = '10',
-    /**
-     * 机构
-     */
-    AGENCY = '12'
+  /**
+   * 系统用户
+   */
+  SYSTEM = '00',
+  /**
+   * 学生
+   */
+  STUDENT = '01',
+  /**
+   * 教师
+   */
+  TEACHER = '11',
+  /**
+   * 代理商
+   */
+  AGENT = '10',
+  /**
+   * 机构
+   */
+  AGENCY = '12'
 }
 }
 
 
 /**
 /**
  * 考试类型
  * 考试类型
  */
  */
 export enum EnumExamRecordType {
 export enum EnumExamRecordType {
-    /**
-     * 模拟考试
-     */
-    SIMULATED = 'simulated',
-    /**
-     * 组卷作业
-     */
-    HOMEWORK = 'homework'
+  /**
+   * 模拟考试
+   */
+  SIMULATED = 'simulated',
+  /**
+   * 组卷作业
+   */
+  HOMEWORK = 'homework'
 }
 }
 
 
 
 
@@ -173,177 +173,177 @@ export enum EnumExamRecordType {
  * 绑定场景
  * 绑定场景
  */
  */
 export enum EnumBindScene {
 export enum EnumBindScene {
-    /**
-     * 注册
-     */
-    REGISTER = 'register',
-    /**
-     * 注册绑定
-     */
-    REGISTER_BIND = 'register_bind',
-    /**
-     * 登录绑定
-     */
-    LOGIN_BIND = 'login_bind',
-    /**
-     * 老师或者代理商完善信息
-     */
-    IMPROVE = 'improve'
+  /**
+   * 注册
+   */
+  REGISTER = 'register',
+  /**
+   * 注册绑定
+   */
+  REGISTER_BIND = 'register_bind',
+  /**
+   * 登录绑定
+   */
+  LOGIN_BIND = 'login_bind',
+  /**
+   * 老师或者代理商完善信息
+   */
+  IMPROVE = 'improve'
 }
 }
 
 
 export enum EnumExamType {
 export enum EnumExamType {
-    /**
-     * 职高对口升学
-     */
-    VHS = 'VHS',
-    /**
-     * 单招(应届普高)
-     */
-    OHS = 'OHS',
-    /**
-     * 单招(中职)
-     */
-    SVS = 'SVS'
+  /**
+   * 职高对口升学
+   */
+  VHS = 'VHS',
+  /**
+   * 单招(应届普高)
+   */
+  OHS = 'OHS',
+  /**
+   * 单招(中职)
+   */
+  SVS = 'SVS'
 }
 }
 
 
 export enum EnumSimulatedRecordStatus {
 export enum EnumSimulatedRecordStatus {
-    /**
-     * 空卷
-     */
-    INIT = 1,
-    /**
-     * 签到
-     */
-    SIGN = 2,
-    /**
-     * 考试
-     */
-    EXAM = 3,
-    /**
-     * 交卷
-     */
-    SUBMIT = 4,
-    /**
-     * 阅卷
-     */
-    REVIEW = 5,
-    /**
-     * 发布
-     */
-    PUBLISH = 6,
-    /**
-     * 关闭
-     */
-    CLOSE = 7,
+  /**
+   * 空卷
+   */
+  INIT = 1,
+  /**
+   * 签到
+   */
+  SIGN = 2,
+  /**
+   * 考试
+   */
+  EXAM = 3,
+  /**
+   * 交卷
+   */
+  SUBMIT = 4,
+  /**
+   * 阅卷
+   */
+  REVIEW = 5,
+  /**
+   * 发布
+   */
+  PUBLISH = 6,
+  /**
+   * 关闭
+   */
+  CLOSE = 7,
 }
 }
 
 
 export enum EnumPaperType {
 export enum EnumPaperType {
-    /**
-     * 练习
-     */
-    PRACTICE = 'Practice',
-    /**
-     * 考试
-     */
-    SIMULATED = 'Simulated',
-    /**
-     * 教材同步练习
-     */
-    COURSE = 'Course',
-    /**
-     * 测试卷
-     */
-    TEST = 'Test'
+  /**
+   * 练习
+   */
+  PRACTICE = 'Practice',
+  /**
+   * 考试
+   */
+  SIMULATED = 'Simulated',
+  /**
+   * 教材同步练习
+   */
+  COURSE = 'Course',
+  /**
+   * 测试卷
+   */
+  TEST = 'Test'
 }
 }
 
 
 export enum EnumReviewMode {
 export enum EnumReviewMode {
-    /**
-     * 交卷后评卷
-     */
-    AFTER_SUBMIT = 1,
-    /**
-     * 答完一题就评卷
-     */
-    DURING_ANSWER = 2
+  /**
+   * 交卷后评卷
+   */
+  AFTER_SUBMIT = 1,
+  /**
+   * 答完一题就评卷
+   */
+  DURING_ANSWER = 2
 }
 }
 
 
 export enum EnumUserRole {
 export enum EnumUserRole {
-    /**
-     * 普通用户
-     */
-    NORMAL = 'normal',
-    /**
-     * 游客
-     */
-    GUEST = 'guest',
-    /**
-     * 会员
-     */
-    VIP = 'vip',
-    /**
-     * 代理商
-     */
-    AGENT = 'agent',
-    /**
-     * 教师
-     */
-    TEACHER = 'teacher'
+  /**
+   * 普通用户
+   */
+  NORMAL = 'normal',
+  /**
+   * 游客
+   */
+  GUEST = 'guest',
+  /**
+   * 会员
+   */
+  VIP = 'vip',
+  /**
+   * 代理商
+   */
+  AGENT = 'agent',
+  /**
+   * 教师
+   */
+  TEACHER = 'teacher'
 }
 }
 
 
 export enum EnumEvent {
 export enum EnumEvent {
-    /**
-     * 打开VIP弹窗
-     */
-    OPEN_VIP_POPUP = 'OPEN_VIP_POPUP'
+  /**
+   * 打开VIP弹窗
+   */
+  OPEN_VIP_POPUP = 'OPEN_VIP_POPUP'
 }
 }
 
 
 /**
 /**
  * 卡类型
  * 卡类型
  */
  */
 export enum CardType {
 export enum CardType {
-    VIP = 1,
-    DEPT = 2,
-    PLATFORM = 6,
-    /**
-     * 体验卡
-     */
-    EXPERIENCE = 9
+  VIP = 1,
+  DEPT = 2,
+  PLATFORM = 6,
+  /**
+   * 体验卡
+   */
+  EXPERIENCE = 9
 }
 }
 
 
 export enum EnumPaperWorkState {
 export enum EnumPaperWorkState {
-    /**
-     * 未完成
-     */
-    NOT_COMPLETED = 2,
-    /**
-     * 已完成
-     */
-    COMPLETED = 4
+  /**
+   * 未完成
+   */
+  NOT_COMPLETED = 2,
+  /**
+   * 已完成
+   */
+  COMPLETED = 4
 }
 }
 
 
 export enum EnumPaperBuildType {
 export enum EnumPaperBuildType {
-    /**
-     * 定向智能
-     */
-    EXACT_INTELLIGENT = 'ExactIntelligent',
-    /**
-     * 全量智能
-     */
-    FULL_INTELLIGENT = 'FullIntelligent',
-    /**
-     * 定向手动
-     */
-    EXACT_HAND = 'ExactHand',
-    /**
-     * 全量手动
-     */
-    FULL_HAND = 'FullHand'
+  /**
+   * 定向智能
+   */
+  EXACT_INTELLIGENT = 'ExactIntelligent',
+  /**
+   * 全量智能
+   */
+  FULL_INTELLIGENT = 'FullIntelligent',
+  /**
+   * 定向手动
+   */
+  EXACT_HAND = 'ExactHand',
+  /**
+   * 全量手动
+   */
+  FULL_HAND = 'FullHand'
 }
 }
 
 
 export enum EnumBrochureType {
 export enum EnumBrochureType {
-    INTRODUCTION = 1, // 学校概况
-    ENROLL_RULE = 2, // 招生简章
-    EXAM_TIME = 3, // 考试大纲
-    WORK = 4, // 就业
-    OTHER_RULE = 5 // 其它
+  INTRODUCTION = 1, // 学校概况
+  ENROLL_RULE = 2, // 招生简章
+  EXAM_TIME = 3, // 考试大纲
+  WORK = 4, // 就业
+  OTHER_RULE = 5 // 其它
 }
 }

+ 17 - 1
src/common/routes.ts

@@ -71,7 +71,23 @@ export const routes = {
   /*
   /*
   * 学习备考首页
   * 学习备考首页
   * */
   * */
-  studySimulate: '/pagesStudy/pages/simulation-entry/simulation-entry'
+  studySimulate: '/pagesStudy/pages/simulation-entry/simulation-entry',
+  /**
+   * 设置
+   */
+  pageSetting: '/pagesSystem/pages/setting/setting',
+  /**
+   * 网页
+   */
+  pageWebview: '/pagesSystem/pages/webview/webview',
+  /**
+   * 用户协议
+   */
+  pageUserProtocol: '/pagesSystem/pages/user-protocol/user-protocol',
+  /**
+   * 隐私政策
+   */
+  pagePrivacyPolicy: '/pagesSystem/pages/privacy-policy/privacy-policy',
 } as const;
 } as const;
 
 
 export type Routes = keyof typeof routes;
 export type Routes = keyof typeof routes;

+ 3 - 1
src/components/ie-auto-resizer/ie-auto-resizer.vue

@@ -1,7 +1,9 @@
 <template>
 <template>
 <view class="flex-1 min-h-1 relative">
 <view class="flex-1 min-h-1 relative">
   <view class="absolute inset-0">
   <view class="absolute inset-0">
-    <slot></slot>
+    <view class="h-full">
+      <slot></slot>
+    </view>
   </view>
   </view>
 </view>
 </view>
 </template>
 </template>

+ 117 - 0
src/components/ie-dropdown/ie-dropdown-hooks.ts

@@ -0,0 +1,117 @@
+import type { Dropdown } from "@/types";
+import type { InjectionKey } from "vue";
+
+export const DROPDOWN_SYMBOL = Symbol('DROPDOWN_SYMBOL') as InjectionKey<ReturnType<typeof useDropdown>>;
+
+/**
+ * 深拷贝一个值
+ * @param value 要拷贝的值
+ * @returns 深拷贝后的值
+ */
+const deepClone = (value: any): any => {
+  // 如果是基本类型或 null/undefined,直接返回
+  if (value == null || typeof value !== 'object') {
+    return value;
+  }
+
+  // 如果是数组,递归拷贝每个元素
+  if (Array.isArray(value)) {
+    return value.map(item => deepClone(item));
+  }
+
+  // 如果是对象,递归拷贝所有属性
+  const cloned: Record<string, any> = {};
+  for (const key in value) {
+    if (Object.prototype.hasOwnProperty.call(value, key)) {
+      cloned[key] = deepClone(value[key]);
+    }
+  }
+  return cloned;
+};
+
+/**
+ * 深度比较两个值是否严格相等
+ * @param a 第一个值
+ * @param b 第二个值
+ * @returns 是否相等
+ */
+const deepEqual = (a: any, b: any): boolean => {
+  // 如果引用相同,直接返回 true
+  if (a === b) return true;
+
+  // 如果其中一个为 null 或 undefined
+  if (a == null || b == null) return a === b;
+
+  // 如果类型不同,返回 false
+  if (typeof a !== typeof b) return false;
+
+  // 如果是基本类型(非对象),直接比较
+  if (typeof a !== 'object') return a === b;
+
+  // 如果是数组
+  if (Array.isArray(a) && Array.isArray(b)) {
+    if (a.length !== b.length) return false;
+    return a.every((item, index) => deepEqual(item, b[index]));
+  }
+
+  // 如果一个是数组,另一个不是,返回 false
+  if (Array.isArray(a) || Array.isArray(b)) return false;
+
+  // 如果是对象,比较所有键值对
+  const keysA = Object.keys(a);
+  const keysB = Object.keys(b);
+
+  // 键的数量不同,返回 false
+  if (keysA.length !== keysB.length) return false;
+
+  // 检查所有键是否都存在且值相等
+  for (const key of keysA) {
+    if (!keysB.includes(key)) return false;
+    if (!deepEqual(a[key], b[key])) return false;
+  }
+
+  return true;
+};
+
+export const useDropdown = (configs: Dropdown.DropdownItem[]) => {
+  const list = computed(() => configs);
+  const form = ref<Record<string, any>>({});
+  const openIndex = ref<number>(-1);
+
+  const open = (index: number) => {
+    openIndex.value = index;
+  }
+  const close = () => {
+    openIndex.value = -1;
+  }
+  const submit = (index: number, value: any) => {
+    form.value = {
+      ...form.value,
+      [list.value[index].prop]: value
+    };
+  }
+  const reset = (index: number) => {
+    form.value = {
+      ...form.value,
+      [list.value[index].prop]: list.value[index].value
+    };
+  }
+  const init = (initValue: Record<string, any>) => {
+    form.value = { ...initValue };
+    list.value.forEach(item => {
+      item.value = initValue[item.prop] || item.value;
+    });
+  }
+
+  return {
+    init,
+    form,
+    openIndex,
+    open,
+    close,
+    submit,
+    reset,
+    deepEqual,
+    deepClone
+  }
+}

+ 168 - 0
src/components/ie-dropdown/ie-dropdown-item.vue

@@ -0,0 +1,168 @@
+<template>
+  <view class=" h-full">
+    <view :id="`dropdown-trigger-${config.prop}`" class="w-full flex items-center justify-center gap-10 h-full relative"
+      @click="handleClick">
+      <view class="relative">
+        <view class="text-xs text-center ellipsis-1" :class="[show ? 'text-primary' : 'text-fore-title ']">
+          {{ config.label }}
+        </view>
+        <view class="absolute -top-4 -right-4 w-6 h-6 bg-red-500 rounded-full" v-if="hasValue"></view>
+      </view>
+      <view :class="['transition-transform duration-300 ease-out', { 'rotate-180': show }]">
+        <uv-icon name="arrow-down" :color="show ? 'primary' : 'info'" size="14" />
+      </view>
+    </view>
+    <view v-show="isOpen" class="fixed left-0 right-0 z-[9999]" :style="containerStyle">
+      <view class="fixed z-0 overflow-hidden" :id="`dropdown-content-${config.prop}`" :style="maskStyle"
+        @click="handleMaskClick">
+      </view>
+      <view class="relative z-1 overflow-hidden ">
+        <view class="left-0 right-0 z-1 w-full bg-white box-border transition-transform duration-300 ease-out"
+          :style="contentStyle" @click="">
+          <scroll-view class="relative max-h-[300px]" scroll-y>
+            <uv-checkbox-group v-model="checkboxValue" placement="column" iconPlacement="right" borderBottom>
+              <uv-checkbox :customStyle="{ marginBottom: '0', paddingBottom: '0', height: '38px', padding: '0 10px' }"
+                v-for="(item, index) in config.options" :key="index" :label="item.label"
+                :name="item.value"></uv-checkbox>
+            </uv-checkbox-group>
+          </scroll-view>
+          <view class="flex items-center justify-between gap-24 p-[12px]">
+            <view class="flex-1">
+              <uv-button type="primary" plain shape="circle" @click="handleReset">重置</uv-button>
+            </view>
+            <view class="flex-1">
+              <uv-button type="primary" shape="circle" @click="handleSubmit">
+                <text>确定</text>
+                <text v-if="checkboxValue.length > 0">({{ checkboxValue.length }})</text>
+              </uv-button>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+
+  </view>
+</template>
+<script lang="ts" setup>
+import { type Dropdown } from '@/types';
+import { DROPDOWN_SYMBOL } from './ie-dropdown-hooks';
+import { getCurrentInstance } from 'vue';
+
+const instance = getCurrentInstance();
+
+const props = defineProps<{
+  config: Dropdown.DropdownItem;
+  index: number;
+}>();
+const dropdown = inject(DROPDOWN_SYMBOL);
+const triggerSelector = `#dropdown-trigger-${props.config.prop}`;
+const isOpen = ref(false);
+const show = ref(false);
+const isMeasuringHeight = ref(false);
+const top = ref(0);
+const hasValue = computed(() => {
+  return dropdown?.form.value[props.config.prop] && dropdown?.form.value[props.config.prop].length > 0;
+});
+
+const checkboxValue = ref([]);
+const containerStyle = computed(() => {
+  return {
+    top: `${top.value + 1}px`,
+  }
+});
+const maskStyle = computed(() => {
+  return {
+    top: `${top.value + 1}px`,
+    left: 0,
+    right: 0,
+    bottom: 0,
+    backgroundColor: 'rgba(0, 0, 0, 0.3)',
+    opacity: show.value ? 1 : 0,
+    transition: 'opacity 0.3s ease-out',
+  }
+});
+const contentStyle = computed(() => {
+  return {
+    transform: `translateY(${show.value ? '0' : '-100%'})`,
+  }
+});
+
+watch(() => dropdown?.openIndex.value, (newVal) => {
+  if (newVal === props.index) {
+    open();
+  } else {
+    if (isOpen.value) {
+      close();
+    }
+  }
+});
+
+const handleReset = () => {
+  checkboxValue.value = [];
+}
+const handleSubmit = () => {
+  dropdown?.submit(props.index, checkboxValue.value);
+  dropdown?.close();
+}
+
+const open = async () => {
+  checkboxValue.value = dropdown?.form.value[props.config.prop] || [];
+  isOpen.value = true;
+  const triggerRect = await getRect(triggerSelector);
+  top.value = triggerRect.top + triggerRect.height;
+  setTimeout(() => {
+    nextTick(() => {
+      show.value = true;
+    });
+  }, 20);
+}
+
+const close = () => {
+  show.value = false;
+  setTimeout(() => {
+    isOpen.value = false;
+  }, 300);
+}
+
+const getRect = (selector: string) => {
+  return new Promise((resolve: (rect: { top: number, height: number }) => void) => {
+    const query = uni.createSelectorQuery().in(instance?.proxy);
+    query.select(selector).boundingClientRect(function (rect) {
+      resolve(rect as { top: number, height: number });
+    }).exec();
+  });
+}
+
+const measureHeight = (selector: string) => {
+  return new Promise((resolve: (height: number) => void) => {
+    isMeasuringHeight.value = true;
+    setTimeout(() => {
+      nextTick(() => {
+        getRect(selector).then((res: any) => {
+          isMeasuringHeight.value = false;
+          setTimeout(() => {
+            nextTick(() => {
+              resolve(res?.height ?? 0);
+            });
+          }, 50);
+        });
+      });
+    }, 50);
+  });
+}
+
+const handleMaskClick = () => {
+  if (isOpen.value) {
+    dropdown?.close();
+  }
+}
+
+const handleClick = () => {
+  if (isOpen.value) {
+    dropdown?.close();
+  } else {
+    dropdown?.open(props.index);
+  }
+}
+</script>
+<style lang="scss" scoped></style>

+ 7 - 0
src/components/ie-dropdown/ie-dropdown-popup.vue

@@ -0,0 +1,7 @@
+<template>
+
+</template>
+<script lang="ts" setup>
+
+</script>
+<style lang="scss" scoped></style>

+ 41 - 0
src/components/ie-dropdown/ie-dropdown.vue

@@ -0,0 +1,41 @@
+<template>
+  <view class="flex items-center gap-20 px-20 h-[44px] border-0 border-b border-solid border-border-light">
+    <view v-for="(item, index) in configs" :key="item.prop" class="flex-1 min-w-1 h-full">
+      <ie-dropdown-item :config="item" :index="index" />
+    </view>
+  </view>
+</template>
+<script lang="ts" setup>
+import IeDropdownItem from './ie-dropdown-item.vue';
+import type { Dropdown } from '@/types';
+import { useDropdown, DROPDOWN_SYMBOL } from './ie-dropdown-hooks';
+
+const emit = defineEmits<{
+  (e: 'change', value: any): void;
+}>();
+const modelValue = defineModel<Record<string, any>>();
+const props = defineProps<{
+  configs: Dropdown.DropdownItem[];
+}>();
+const dropdown = useDropdown(props.configs);
+
+const prevFormValue = ref<Record<string, any>>({});
+
+watch(() => dropdown.form.value, (newVal) => {
+  const oldVal = prevFormValue.value;
+  modelValue.value = newVal;
+  if (!dropdown.deepEqual(newVal, oldVal)) {
+    emit('change', newVal);
+  }
+  prevFormValue.value = dropdown.deepClone(newVal);
+}, {
+  deep: true
+});
+
+provide(DROPDOWN_SYMBOL, dropdown);
+onMounted(() => {
+  dropdown.init(modelValue.value || {});
+  prevFormValue.value = dropdown.deepClone(dropdown.form.value);
+});
+</script>
+<style lang="scss" scoped></style>

+ 9 - 9
src/components/ie-popup/ie-popup.vue

@@ -24,15 +24,15 @@
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
 type Props = {
 type Props = {
-  title: string;
-  cancelText: string;
-  confirmText: string;
-  mode: 'bottom' | 'center' | 'top';
-  round: number;
-  closeOnClickOverlay: boolean;
-  showToolbar: boolean;
-  showCancel: boolean;
-  showConfirm: boolean;
+  title?: string;
+  cancelText?: string;
+  confirmText?: string;
+  mode?: 'bottom' | 'center' | 'top';
+  round?: number;
+  closeOnClickOverlay?: boolean;
+  showToolbar?: boolean;
+  showCancel?: boolean;
+  showConfirm?: boolean;
 }
 }
 const props = withDefaults(defineProps<Props>(), {
 const props = withDefaults(defineProps<Props>(), {
   title: '',
   title: '',

+ 5 - 1
src/config.ts

@@ -10,7 +10,11 @@ const config = {
     contactPhone: '400-1797-985',
     contactPhone: '400-1797-985',
     logo: '',
     logo: '',
     orgName: '单招一卡通',
     orgName: '单招一卡通',
-  }
+  },
+  // 用户协议
+  userProtocolUrl: 'https://www.dz1kt.com/admin/protocol/mxjb_user_IE.html',
+  // 隐私政策
+  privacyPolicyUrl: 'https://www.dz1kt.com/admin/protocol/mxjb_privacy_IE.html',
 };
 };
 export const env = {
 export const env = {
   development: {
   development: {

+ 44 - 0
src/global.d.ts

@@ -8,6 +8,50 @@ declare global {
     $uv: any;
     $uv: any;
     $zp: any;
     $zp: any;
   }
   }
+  
+  /**
+   * 微信小程序 API 接口
+   */
+  interface Wx {
+    /**
+     * 打开浏览器
+     * @param options - 配置选项
+     * @param options.url - 要打开的网址
+     * @param options.success - 成功回调
+     * @param options.fail - 失败回调
+     */
+    openBrowser?: (options: {
+      url: string;
+      success?: () => void;
+      fail?: (err: any) => void;
+    }) => void;
+  }
+  
+  /**
+   * 支付宝小程序 API 接口
+   */
+  interface My {
+    /**
+     * 打开浏览器
+     * @param options - 配置选项
+     * @param options.url - 要打开的网址
+     */
+    openBrowser?: (options: { url: string }) => void;
+  }
+  
+  /**
+   * 微信小程序全局对象
+   * 仅在微信小程序环境中可用
+   * 使用条件编译指令 #ifdef MP-WEIXIN 确保只在微信小程序环境中使用
+   */
+  var wx: Wx;
+  
+  /**
+   * 支付宝小程序全局对象
+   * 仅在支付宝小程序环境中可用
+   * 使用条件编译指令 #ifdef MP-ALIPAY 确保只在支付宝小程序环境中使用
+   */
+  var my: My;
 }
 }
 
 
 declare module 'pinia' {
 declare module 'pinia' {

+ 2 - 2
src/manifest.json

@@ -2,8 +2,8 @@
     "name" : "单招一卡通",
     "name" : "单招一卡通",
     "appid" : "__UNI__37DEDFB",
     "appid" : "__UNI__37DEDFB",
     "description" : "单招一卡通,升学一路通!",
     "description" : "单招一卡通,升学一路通!",
-    "versionName" : "1.0.0",
-    "versionCode" : "100",
+    "versionName" : "4.0.0",
+    "versionCode" : "400",
     "transformPx" : false,
     "transformPx" : false,
     "app-plus" : {
     "app-plus" : {
         "usingComponents" : true,
         "usingComponents" : true,

+ 30 - 6
src/pages.json

@@ -87,6 +87,12 @@
             "navigationBarTitleText": ""
             "navigationBarTitleText": ""
           }
           }
         },
         },
+        {
+          "path": "pages/university/picker/picker",
+          "style": {
+            "navigationBarTitleText": ""
+          }
+        },
         {
         {
           "path": "pages/career/index/index",
           "path": "pages/career/index/index",
           "style": {
           "style": {
@@ -129,12 +135,6 @@
             "navigationBarTitleText": ""
             "navigationBarTitleText": ""
           }
           }
         },
         },
-        {
-          "path": "pages/university/picker/picker",
-          "style": {
-            "navigationBarTitleText": ""
-          }
-        },
         {
         {
           "path": "pages/university/intro/intro",
           "path": "pages/university/intro/intro",
           "style": {
           "style": {
@@ -194,6 +194,30 @@
           "style": {
           "style": {
             "navigationBarTitleText": ""
             "navigationBarTitleText": ""
           }
           }
+        },
+        {
+          "path": "pages/setting/setting",
+          "style": {
+            "navigationBarTitleText": ""
+          }
+        },
+        {
+          "path": "pages/webview/webview",
+          "style": {
+            "navigationBarTitleText": ""
+          }
+        },
+        {
+          "path": "pages/user-protocol/user-protocol",
+          "style": {
+            "navigationBarTitleText": ""
+          }
+        },
+        {
+          "path": "pages/privacy-policy/privacy-policy",
+          "style": {
+            "navigationBarTitleText": ""
+          }
         }
         }
       ]
       ]
     },
     },

+ 1 - 1
src/pagesMain/pages/index/components/index-banner.vue

@@ -15,7 +15,7 @@
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
 import { useTransferPage } from '@/hooks/useTransferPage';
 import { useTransferPage } from '@/hooks/useTransferPage';
-const { transferTo } = useTransferPage();
+const { transferTo, routes } = useTransferPage();
 import { useUserStore } from '@/store/userStore';
 import { useUserStore } from '@/store/userStore';
 import { Transfer } from '@/types';
 import { Transfer } from '@/types';
 import {routes} from "@/common/routes";
 import {routes} from "@/common/routes";

+ 6 - 6
src/pagesMain/pages/index/index.vue

@@ -2,16 +2,16 @@
   <ie-page bg-color="white">
   <ie-page bg-color="white">
     <ie-navbar transparent bg-color="#FFFFFF" :placeholder="false" custom-back :click-hover="false">
     <ie-navbar transparent bg-color="#FFFFFF" :placeholder="false" custom-back :click-hover="false">
       <template #headerLeft>
       <template #headerLeft>
-        <view class="flex items-center">
-          <view class="text-36 text-fore-title font-bold">{{ orgName }}</view>
-          <view class="w-6 h-6 rounded-2 bg-black mx-12"></view>
-          <view>升学备考好帮手</view>
+        <view class="flex items-center gap-7 text-fore-title">
+          <view class="text-38 font-bold">{{ orgName }}</view>
+          <text>·</text>
+          <view class="text-30 font-medium">升学备考好帮手</view>
         </view>
         </view>
       </template>
       </template>
       <template #headerRight="{ isTransparent }">
       <template #headerRight="{ isTransparent }">
         <view v-if="userStore.getLocation" class="ml-10 flex items-center gap-x-4" @click="handleChangeLocation">
         <view v-if="userStore.getLocation" class="ml-10 flex items-center gap-x-4" @click="handleChangeLocation">
-          <uv-icon name="map" size="14" :color="isTransparent ? '#333' : 'var(--primary-color)'" />
-          <text class="text-26 transition-colors duration-300"
+          <uv-icon name="map" size="16" :color="isTransparent ? '#333' : 'var(--primary-color)'" />
+          <text class="text-30 transition-colors duration-300 font-medium"
             :class="[isTransparent ? 'text-fore-title' : 'text-primary']">
             :class="[isTransparent ? 'text-fore-title' : 'text-primary']">
             {{ userStore.getLocation }}
             {{ userStore.getLocation }}
           </text>
           </text>

+ 5 - 3
src/pagesMain/pages/me/components/me-info.vue

@@ -21,7 +21,8 @@
       </view>
       </view>
     </view>
     </view>
 
 
-    <view v-if="isStudent" class="mt-50 h-184 rounded-15 relative bg-gradient-to-r from-[#253045] to-[#141D2F] overflow-hidden">
+    <view v-if="isStudent"
+      class="mt-50 h-184 rounded-15 relative bg-gradient-to-r from-[#253045] to-[#141D2F] overflow-hidden">
       <ie-image src="/static/personal/bg-vip-card.png"
       <ie-image src="/static/personal/bg-vip-card.png"
         custom-class="w-276 h-full absolute left-1/2 top-0 -translate-x-1/2 z-0" mode="heightFix" />
         custom-class="w-276 h-full absolute left-1/2 top-0 -translate-x-1/2 z-0" mode="heightFix" />
       <view class="h-full box-border px-45 flex items-center justify-between relative z-1">
       <view class="h-full box-border px-45 flex items-center justify-between relative z-1">
@@ -47,8 +48,9 @@
 <script lang="ts" setup>
 <script lang="ts" setup>
 import { useUserStore } from '@/store/userStore';
 import { useUserStore } from '@/store/userStore';
 import { useTransferPage } from '@/hooks/useTransferPage';
 import { useTransferPage } from '@/hooks/useTransferPage';
+
 const userStore = useUserStore();
 const userStore = useUserStore();
-const { transferTo } = useTransferPage();
+const { transferTo, routes } = useTransferPage();
 const avatar = computed(() => userStore.avatar);
 const avatar = computed(() => userStore.avatar);
 const nickName = computed(() => userStore.nickName);
 const nickName = computed(() => userStore.nickName);
 const phonenumber = computed(() => userStore.anonymousPhoneNumber);
 const phonenumber = computed(() => userStore.anonymousPhoneNumber);
@@ -90,7 +92,7 @@ const handleVip = () => {
 }
 }
 
 
 const handleSettingClick = async () => {
 const handleSettingClick = async () => {
-  transferTo('/pagesOther/pages/personal-center/setting/setting');
+  transferTo(routes.pageSetting);
 }
 }
 </script>
 </script>
 <style lang="scss" scoped></style>
 <style lang="scss" scoped></style>

+ 33 - 33
src/pagesMain/pages/volunteer/volunteer.vue

@@ -1,49 +1,49 @@
 <template>
 <template>
-    <ie-page bg-color="white">
-        <ie-navbar bg-color="#FFFFFF" transparent custom-back :click-hover="false">
-            <template #headerLeft>
-                <view class="flex items-center gap-7 text-fore-subtitle text-sm font-medium">
-                    <ie-image is-oss src="/volunteer/index/navbar_title.png" custom-class="w-146"/>
-                    <text>·</text>
-                    <text>{{ examTypeName }}</text>
-                </view>
-            </template>
-            <template #headerRight>
-                <view class="flex items-center gap-5 text-fore-subtitle text-base font-medium">
-                    <ie-image is-oss src="/volunteer/index/navbar_location.png" custom-class="w-24"/>
-                    <text>{{ userStore.getLocation }}</text>
-                </view>
-            </template>
-        </ie-navbar>
-        <volunteer-banner :style="{marginTop: (baseStickyTop + 10) + 'px'}"/>
-        <volunteer-menu/>
-        <ie-gap/>
-        <volunteer-policy/>
-        <volunteer-echelon/>
-        <template #tabbar>
-            <ie-tabbar :active="1"/>
-        </template>
-    </ie-page>
+  <ie-page bg-color="white">
+    <ie-navbar bg-color="#FFFFFF" transparent custom-back :click-hover="false">
+      <template #headerLeft>
+        <view class="flex items-center gap-7 text-fore-subtitle">
+          <ie-image is-oss src="/volunteer/index/navbar_title.png" custom-class="w-146 h-36" />
+          <text>·</text>
+          <text class="text-30 font-medium">{{ examTypeName }}</text>
+        </view>
+      </template>
+      <template #headerRight>
+        <view class="flex items-center gap-4 text-fore-subtitle font-medium">
+          <uv-icon name="map" size="16" color="#333" />
+          <text class="text-30">{{ userStore.getLocation }}</text>
+        </view>
+      </template>
+    </ie-navbar>
+    <volunteer-banner :style="{ marginTop: (baseStickyTop + 10) + 'px' }" />
+    <volunteer-menu />
+    <ie-gap />
+    <volunteer-policy />
+    <volunteer-echelon />
+    <template #tabbar>
+      <ie-tabbar :active="1" />
+    </template>
+  </ie-page>
 </template>
 </template>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
-import {useUserStore} from '@/store/userStore';
-import {useTransferPage} from '@/hooks/useTransferPage';
-import {EnumDictName} from '@/common/enum';
-import {useDictStore} from "@/store/dictStore";
-import {useNavbar} from "@/hooks/useNavbar";
+import { useUserStore } from '@/store/userStore';
+import { useTransferPage } from '@/hooks/useTransferPage';
+import { EnumDictName } from '@/common/enum';
+import { useDictStore } from "@/store/dictStore";
+import { useNavbar } from "@/hooks/useNavbar";
 import VolunteerBanner from "@/pagesMain/pages/volunteer/components/volunteer-banner.vue";
 import VolunteerBanner from "@/pagesMain/pages/volunteer/components/volunteer-banner.vue";
 import VolunteerMenu from "@/pagesMain/pages/volunteer/components/volunteer-menu.vue";
 import VolunteerMenu from "@/pagesMain/pages/volunteer/components/volunteer-menu.vue";
 import VolunteerPolicy from "@/pagesMain/pages/volunteer/components/volunteer-policy.vue";
 import VolunteerPolicy from "@/pagesMain/pages/volunteer/components/volunteer-policy.vue";
 import VolunteerEchelon from "@/pagesMain/pages/volunteer/components/volunteer-tier.vue";
 import VolunteerEchelon from "@/pagesMain/pages/volunteer/components/volunteer-tier.vue";
 
 
-const {transferTo} = useTransferPage();
+const { transferTo } = useTransferPage();
 const userStore = useUserStore();
 const userStore = useUserStore();
 const dictStore = useDictStore()
 const dictStore = useDictStore()
-const {baseStickyTop} = useNavbar();
+const { baseStickyTop } = useNavbar();
 
 
 const examTypeName = computed(() => {
 const examTypeName = computed(() => {
-    return dictStore.getDictLabel(EnumDictName.EXAM_TYPE, userStore.getExamType)
+  return dictStore.getDictLabel(EnumDictName.EXAM_TYPE, userStore.getExamType)
 })
 })
 
 
 // 为了让子组件触发页面滚动
 // 为了让子组件触发页面滚动

+ 3 - 3
src/pagesOther/pages/career/detail/components/career-overview.vue

@@ -10,7 +10,7 @@
       </view>
       </view>
     </view>
     </view>
     <view class="mt-20 bg-white">
     <view class="mt-20 bg-white">
-      <view class="text-30 px-30 py-20">
+      <view class="text-30 px-30 py-20 font-medium">
         <span>相关岗位</span>
         <span>相关岗位</span>
         <span class="text-danger mx-10">{{ overview.postJobs.length }}</span>
         <span class="text-danger mx-10">{{ overview.postJobs.length }}</span>
         <span>个</span>
         <span>个</span>
@@ -29,7 +29,7 @@
       </view>
       </view>
     </view>
     </view>
     <view class="mt-20 bg-white">
     <view class="mt-20 bg-white">
-      <view class="text-30 px-30 py-20">
+      <view class="text-30 px-30 py-20 font-medium">
         <span>相关职业</span>
         <span>相关职业</span>
         <span class="text-danger mx-10">{{ overview.jobs.length }}</span>
         <span class="text-danger mx-10">{{ overview.jobs.length }}</span>
         <span>个</span>
         <span>个</span>
@@ -48,7 +48,7 @@
       </view>
       </view>
     </view>
     </view>
     <view class="mt-20 bg-white">
     <view class="mt-20 bg-white">
-      <view class="text-30 px-30 py-20">
+      <view class="text-30 px-30 py-20 font-medium">
         <span>相关专业</span>
         <span>相关专业</span>
         <span class="text-danger mx-10">{{ overview.postMajors.length }}</span>
         <span class="text-danger mx-10">{{ overview.postMajors.length }}</span>
         <span>个</span>
         <span>个</span>

+ 53 - 56
src/pagesOther/pages/university/index/components/college-list.vue

@@ -1,88 +1,85 @@
 <template>
 <template>
-    <view class="h-full">
-        <z-paging ref="paging" v-model="list" @query="handleQuery">
-            <template #top>
-                <slot name="top"/>
-                <college-conditions-picker :options="filterOptions"/>
-                <ie-search v-model="queryParams.name" placeholder="输入院校名称" @search="handleSearch"
-                           @clear="handleSearch"/>
-            </template>
-            <view class="p-20 flex flex-col gap-20">
-                <college-item v-for="i in list" :key="i.code" :item="i" @click="handleDetail(i)"/>
-            </view>
-        </z-paging>
-    </view>
+  <view class="h-full">
+    <z-paging ref="paging" v-model="list" @query="handleQuery">
+      <template #top>
+        <slot name="top" />
+        <college-conditions-picker v-if="filterOptions" :options="filterOptions" @change="handleSearch" />
+        <ie-search v-model="queryParams.name" placeholder="输入院校名称" @search="handleSearch" @clear="handleSearch" />
+      </template>
+      <view class="p-20 flex flex-col gap-20">
+        <college-item v-for="i in list" :key="i.code" :item="i" @click="handleDetail(i)" />
+      </view>
+    </z-paging>
+  </view>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import {useTransferPage} from "@/hooks/useTransferPage";
-import {getUniversityFilters, universityList} from "@/api/modules/university";
-import {University, UniversityQueryDto} from "@/types/university";
-import {UNIVERSITY_FILTER} from "@/types/injectionSymbols";
+import { useTransferPage } from "@/hooks/useTransferPage";
+import { getUniversityFilters, universityList } from "@/api/modules/university";
+import type { University, UniversityQueryDto, UniversityFilter } from "@/types/university";
+import { UNIVERSITY_FILTER } from "@/types/injectionSymbols";
 import CollegeConditionsPicker from "@/pagesOther/pages/university/index/components/plus/college-conditions-picker.vue";
 import CollegeConditionsPicker from "@/pagesOther/pages/university/index/components/plus/college-conditions-picker.vue";
 import CollegeItem from "@/pagesOther/pages/university/index/components/plus/college-item.vue";
 import CollegeItem from "@/pagesOther/pages/university/index/components/plus/college-item.vue";
-import {routes} from "@/common/routes";
+import { routes } from "@/common/routes";
 
 
 const props = withDefaults(defineProps<{
 const props = withDefaults(defineProps<{
-    customItemClick: boolean;
-    extraFilter: Record<string, any>;
+  customItemClick?: boolean;
+  extraFilter?: Record<string, any>;
 }>(), {
 }>(), {
-    customItemClick: false,
-    extraFilter: () => ({})
+  customItemClick: false,
+  extraFilter: () => ({})
 })
 })
 const emits = defineEmits(['item-click'])
 const emits = defineEmits(['item-click'])
 
 
-const {prevData, transferTo} = useTransferPage()
+const { prevData, transferTo } = useTransferPage()
 const paging = ref<ZPagingInstance>()
 const paging = ref<ZPagingInstance>()
 const list = ref<University[]>([])
 const list = ref<University[]>([])
-const filterOptions = ref<Record<string, any>>({})
+const filterOptions = ref<UniversityFilter | null>(null)
 const queryParams = ref<UniversityQueryDto>({
 const queryParams = ref<UniversityQueryDto>({
-    name: '',
-    features: [],
-    type: [],
-    natureTypeCN: [],
-    location: [],
-    level: [],
-    tier: []
+  name: '',
+  features: [],
+  type: [],
+  natureTypeCN: [],
+  location: [],
+  level: [],
+  tier: []
 })
 })
 
 
 const handleSearch = async () => {
 const handleSearch = async () => {
-    paging.value?.reload();
+  paging.value?.reload();
 }
 }
 
 
 const handleQuery = (pageNum: number, pageSize: number) => {
 const handleQuery = (pageNum: number, pageSize: number) => {
-    const query = {pageNum, pageSize, ...props.extraFilter, ...queryParams.value}
-    universityList(query)
-        .then(res => paging.value?.completeByTotal(res.rows, res.total))
-        .catch(e => paging.value?.complete(false))
+  const filterParams: Record<string, string> = {};
+  Object.keys(queryParams.value).forEach(item => {
+    const value = queryParams.value[item as keyof UniversityQueryDto]
+    filterParams[item] = Array.isArray(value) ? value.join(',') : value
+  });
+  const query = { pageNum, pageSize, ...props.extraFilter, ...filterParams }
+  universityList(query)
+    .then(res => paging.value?.completeByTotal(res.rows, res.total))
+    .catch(e => paging.value?.complete(false))
 }
 }
 
 
 const handleDetail = (u: University) => {
 const handleDetail = (u: University) => {
-    if (props.customItemClick) return emits('item-click', u)
-    const {id, code, name} = u
-    transferTo(routes.universityDetail, {data: {id, code, name}})
+  if (props.customItemClick) {
+    return emits('item-click', u)
+  }
+  const { id, code, name } = u
+  transferTo(routes.universityDetail, { data: { id, code, name } })
 }
 }
 
 
 provide(UNIVERSITY_FILTER, queryParams)
 provide(UNIVERSITY_FILTER, queryParams)
 
 
-watch([
-    () => queryParams.value.features,
-    () => queryParams.value.type,
-    () => queryParams.value.natureTypeCN,
-    () => queryParams.value.location,
-    () => queryParams.value.level,
-    () => queryParams.value.tier
-], () => handleSearch())
-
 onMounted(async () => {
 onMounted(async () => {
-    const {data} = await getUniversityFilters()
-    filterOptions.value = data
-    // accept default query parameters
-    if (prevData.tier) queryParams.value.tier = [prevData.tier]
-})
+  const { data } = await getUniversityFilters()
+  filterOptions.value = data
+  // accept default query parameters
+  if (prevData.value.tier) {
+    queryParams.value.tier = [prevData.value.tier]
+  }
+});
 
 
 </script>
 </script>
 
 
-<style scoped>
-
-</style>
+<style scoped></style>

+ 90 - 14
src/pagesOther/pages/university/index/components/plus/college-conditions-picker.vue

@@ -1,26 +1,102 @@
 <template>
 <template>
+  <view>
+    <ie-dropdown :configs="configs" v-model="form" @change="handleChange" />
+  </view>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
 
 
-import {UNIVERSITY_FILTER} from "@/types/injectionSymbols";
-import {UniversityQueryDto} from "@/types/university";
+import type { Dropdown } from "@/types";
+import { UNIVERSITY_FILTER } from "@/types/injectionSymbols";
+import type { UniversityQueryDto, UniversityFilter } from "@/types/university";
 
 
 const props = defineProps<{
 const props = defineProps<{
-    options: Record<string, any>; // any: string[] | {id: name}
+  options: UniversityFilter;
 }>()
 }>()
 const filter = inject(UNIVERSITY_FILTER) || ref({} as UniversityQueryDto)
 const filter = inject(UNIVERSITY_FILTER) || ref({} as UniversityQueryDto)
 
 
-const config = [
-    // 用optionKey在props.options中取出选项,选择后的赋值给filter[prop]
-    {label: '院校层次', optionKey: 'features', prop: 'features'},
-    {label: '院校类型', optionKey: 'types', prop: 'type'},
-    {label: '办学类型', optionKey: 'natureTypes', prop: 'natureType'},
-    {label: '院校省份', optionKey: 'locations', prop: 'location'},
-    {label: '院校梯队', optionKey: 'tiers', prop: 'tier'},
-]
+const emit = defineEmits<{
+  (e: 'change', value: UniversityQueryDto): void;
+}>();
+const options = [
+  {
+    label: '院校层次',
+    prop: 'features',
+    optionKey: 'features',
+    keyName: 'label',
+    keyValue: 'value',
+  },
+  {
+    label: '院校类型',
+    prop: 'type',
+    optionKey: 'types',
+    keyName: 'label',
+    keyValue: 'value',
+  },
+  {
+    label: '办学类型',
+    prop: 'natureTypeCN',
+    optionKey: 'natureTypes',
+    keyName: 'label',
+    keyValue: 'value',
+  },
+  {
+    label: '院校省份',
+    prop: 'location',
+    optionKey: 'locations',
+    keyName: 'label',
+    keyValue: 'value',
+  },
+  {
+    label: '院校梯队',
+    prop: 'tier',
+    optionKey: 'tiers',
+    keyName: 'label',
+    keyValue: 'value',
+  },
+];
+const form = ref<Record<string, any>>({});
+const configs = computed<Dropdown.DropdownItem[]>(() => {
+  return options.map(item => {
+    const list = props.options[item.optionKey as keyof UniversityFilter] || [];
+    if (Array.isArray(list)) {
+      return {
+        label: item.label,
+        prop: item.prop,
+        keyName: item.keyName,
+        keyValue: item.keyValue,
+        options: list.map(item => {
+          return {
+            label: item,
+            value: item,
+          }
+        }),
+        value: []
+      }
+    } else {
+      return {
+        label: item.label,
+        prop: item.prop,
+        keyName: item.keyName,
+        keyValue: item.keyValue,
+        options: Object.entries(list).map(([key, value]) => {
+          return {
+            label: value,
+            value: key,
+          }
+        }),
+        value: []
+      }
+    }
+  });
+});
+const handleChange = (value: any) => {
+  filter.value = {
+    ...filter.value,
+    ...value,
+  }
+  emit('change', filter.value);
+}
 </script>
 </script>
 
 
-<style scoped>
-
-</style>
+<style scoped></style>

+ 136 - 137
src/pagesOther/pages/voluntary/list/list.vue

@@ -1,176 +1,175 @@
 <template>
 <template>
-    <ie-page>
-        <z-paging ref="paging" v-model="list" bg-color="#F6F8FA" safe-area-inset-bottom :scrollable="!isSorting"
-                  :refresher-enabled="!isSorting" @query="handleQuery">
-            <template #top>
-                <ie-navbar title="志愿表"/>
-            </template>
-            <view class="mt-20 bg-warning-light p-28 text-23 leading-38 text-fore-title">
-                <text class="font-bold">说明:</text>
-                目前志愿计划为2025年,排序前两个为第一、二志愿,可通过修改排序重新选择第一、二志愿
-            </view>
-            <view class="p-28 flex flex-col gap-28">
-                <voluntary-item v-for="(item,i) in list" :key="i" :data="item" :index="i"
-                                @more="showActions(item)" @error="handleError"/>
-            </view>
-        </z-paging>
-        <ie-safe-toolbar :height="84" :shadow="false">
-            <view class="px-30 py-16">
-                <ie-button @click="handleAdd">添加志愿</ie-button>
-            </view>
-        </ie-safe-toolbar>
-        <uv-action-sheet ref="actionSheet" :actions="moreActions" safe-area-inset-bottom close-on-click-overlay
-                         cancel-text="取消" @select="handleActionSelect"/>
-    </ie-page>
+  <ie-page>
+    <z-paging ref="paging" v-model="list" bg-color="#F6F8FA" safe-area-inset-bottom :scrollable="!isSorting"
+      :refresher-enabled="!isSorting" @query="handleQuery">
+      <template #top>
+        <ie-navbar title="志愿表" />
+      </template>
+      <view class="mt-20 bg-warning-light p-28 text-23 leading-38 text-fore-title">
+        <text class="font-bold">说明:</text>
+        目前志愿计划为2025年,排序前两个为第一、二志愿,可通过修改排序重新选择第一、二志愿
+      </view>
+      <view class="p-28 flex flex-col gap-28">
+        <voluntary-item v-for="(item, i) in list" :key="i" :data="item" :index="i" @more="showActions(item)"
+          @error="handleError" />
+      </view>
+    </z-paging>
+    <ie-safe-toolbar :height="84" :shadow="false">
+      <view class="px-30 py-16">
+        <ie-button @click="handleAdd">添加志愿</ie-button>
+      </view>
+    </ie-safe-toolbar>
+    <uv-action-sheet ref="actionSheet" :actions="moreActions" safe-area-inset-bottom close-on-click-overlay
+      cancel-text="取消" @select="handleActionSelect" />
+  </ie-page>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import {SelectedUniversityMajor, VoluntaryRecord} from "@/types/voluntary";
+import { SelectedUniversityMajor, VoluntaryRecord } from "@/types/voluntary";
 import VoluntaryItem from "@/pagesOther/pages/voluntary/list/components/voluntary-item.vue";
 import VoluntaryItem from "@/pagesOther/pages/voluntary/list/components/voluntary-item.vue";
-import {VOLUNTARY_SORTING} from "@/types/injectionSymbols";
+import { VOLUNTARY_SORTING } from "@/types/injectionSymbols";
 import {
 import {
-    addVoluntary,
-    getVoluntaryList,
-    removeVoluntaryByUniversity,
-    sortVoluntaryByUniversity
+  addVoluntary,
+  getVoluntaryList,
+  removeVoluntaryByUniversity,
+  sortVoluntaryByUniversity
 } from "@/api/modules/voluntary";
 } from "@/api/modules/voluntary";
 import UvActionSheet from "@/uni_modules/uv-action-sheet/components/uv-action-sheet/uv-action-sheet.vue";
 import UvActionSheet from "@/uni_modules/uv-action-sheet/components/uv-action-sheet/uv-action-sheet.vue";
-import {useTransferPage} from "@/hooks/useTransferPage";
-import {UniversityPickerPageOptions} from "@/types/transfer";
-import {routes} from "@/common/routes";
+import { useTransferPage } from "@/hooks/useTransferPage";
+import { UniversityPickerPageOptions } from "@/types/transfer";
+import { routes } from "@/common/routes";
 
 
 interface ActionItem {
 interface ActionItem {
-    id: string;
-    name: string;
-    icon?: string;
-    color?: string;
-    iconColor?: string;
-    disabled?: boolean;
+  id: string;
+  name: string;
+  icon?: string;
+  color?: string;
+  iconColor?: string;
+  disabled?: boolean;
 }
 }
 
 
-const {transferTo} = useTransferPage()
+const { transferTo } = useTransferPage()
 const list = ref<VoluntaryRecord[]>([])
 const list = ref<VoluntaryRecord[]>([])
 const paging = ref<ZPagingInstance>()
 const paging = ref<ZPagingInstance>()
 const isSorting = ref<boolean>(false)
 const isSorting = ref<boolean>(false)
 const actionSheet = ref<InstanceType<typeof UvActionSheet>>()
 const actionSheet = ref<InstanceType<typeof UvActionSheet>>()
 const actionRecord = ref<VoluntaryRecord>()
 const actionRecord = ref<VoluntaryRecord>()
 const moreActions = computed<ActionItem[]>(() => {
 const moreActions = computed<ActionItem[]>(() => {
-    const records = list.value
-    const current = actionRecord.value
-    const idx = current ? records.indexOf(current) : -1
-    const enableTop = records.length > 1 && idx > 0
-    const enableUp = records.length > 1 && idx > 0
-    const enableDown = records.length > 1 && idx < records.length - 1
-    return [{
-        id: 'top',
-        name: '置顶',
-        icon: 'pushpin-fill',
-        color: 'var(--primary-color)',
-        iconColor: enableTop ? 'primary' : 'info',
-        disabled: !enableTop
-    }, {
-        id: 'up',
-        name: '上移',
-        icon: 'arrow-upward',
-        iconColor: enableUp ? '' : 'info',
-        disabled: !enableUp
-    }, {
-        id: 'down',
-        name: '下移',
-        icon: 'arrow-downward',
-        iconColor: enableDown ? '' : 'info',
-        disabled: !enableDown
-    }, {
-        id: 'delete',
-        name: '删除',
-        icon: 'trash',
-        color: 'var(--danger)',
-        iconColor: 'error'
-    }]
+  const records = list.value
+  const current = actionRecord.value
+  const idx = current ? records.indexOf(current) : -1
+  const enableTop = records.length > 1 && idx > 0
+  const enableUp = records.length > 1 && idx > 0
+  const enableDown = records.length > 1 && idx < records.length - 1
+  return [{
+    id: 'top',
+    name: '置顶',
+    icon: 'pushpin-fill',
+    color: 'var(--primary-color)',
+    iconColor: enableTop ? 'primary' : 'info',
+    disabled: !enableTop
+  }, {
+    id: 'up',
+    name: '上移',
+    icon: 'arrow-upward',
+    iconColor: enableUp ? '' : 'info',
+    disabled: !enableUp
+  }, {
+    id: 'down',
+    name: '下移',
+    icon: 'arrow-downward',
+    iconColor: enableDown ? '' : 'info',
+    disabled: !enableDown
+  }, {
+    id: 'delete',
+    name: '删除',
+    icon: 'trash',
+    color: 'var(--danger)',
+    iconColor: 'error'
+  }]
 })
 })
 
 
 const handleQuery = () => {
 const handleQuery = () => {
-    getVoluntaryList().then(res => {
-        paging.value?.completeByNoMore(res.data, true)
-    }).catch(e => paging.value?.completeByError(e))
+  getVoluntaryList().then(res => {
+    paging.value?.completeByNoMore(res.data, true)
+  }).catch(e => paging.value?.completeByError(e))
 }
 }
 
 
 const showActions = (record: VoluntaryRecord) => {
 const showActions = (record: VoluntaryRecord) => {
-    actionRecord.value = record
-    actionSheet.value?.open()
+  actionRecord.value = record
+  actionSheet.value?.open()
 }
 }
 
 
 const handleActionSelect = async (e: ActionItem) => {
 const handleActionSelect = async (e: ActionItem) => {
-    const record = actionRecord.value
-    const recordList = list.value
-    if (!record) return
-    const idx = recordList.findIndex(r => r == record)
-    if (['top', 'up', 'down'].includes(e.id)) {
-        try {
-            switch (e.id) {
-                case 'top':
-                    if (idx > 0) {
-                        recordList.splice(idx, 1)
-                        recordList.unshift(record)
-                        await sortVoluntaryByUniversity(recordList.map(r => r.universityId))
-                        uni.$ie.showSuccess('保存成功')
-                    }
-                    break;
-                case 'up':
-                    if (idx > 0) {
-                        recordList.splice(idx, 1)
-                        recordList.splice(idx - 1, 0, record)
-                        await sortVoluntaryByUniversity(recordList.map(r => r.universityId))
-                        uni.$ie.showSuccess('保存成功')
-                    }
-                    break;
-                case 'down':
-                    if (idx < recordList.length - 1) {
-                        recordList.splice(idx, 1)
-                        recordList.splice(idx + 1, 0, record)
-                        await sortVoluntaryByUniversity(recordList.map(r => r.universityId))
-                        uni.$ie.showSuccess('保存成功')
-                    }
-                    break;
-            }
-        } catch (e) {
-            console.log('action ex', e)
-            paging.value?.reload() // 发生异常时,重新加载列表
-        }
-    } else if (e.id === 'delete') {
-        await uni.$ie.showConfirm({
-            title: '志愿删除提醒',
-            content: `删除'${record.universityName}',将同时删除该院校下所有意向专业。\n确认删除?!`
-        })
-        recordList.splice(idx, 1)
-        removeVoluntaryByUniversity(record.universityId)
-            .then(() => uni.$ie.showSuccess('删除成功'))
-            .catch(() => paging.value?.reload())
-    } else {
-        throw new Error('Unsupported action id: ' + e.id)
+  const record = actionRecord.value
+  const recordList = list.value
+  if (!record) return
+  const idx = recordList.findIndex(r => r == record)
+  if (['top', 'up', 'down'].includes(e.id)) {
+    try {
+      switch (e.id) {
+        case 'top':
+          if (idx > 0) {
+            recordList.splice(idx, 1)
+            recordList.unshift(record)
+            await sortVoluntaryByUniversity(recordList.map(r => r.universityId))
+            uni.$ie.showSuccess('保存成功')
+          }
+          break;
+        case 'up':
+          if (idx > 0) {
+            recordList.splice(idx, 1)
+            recordList.splice(idx - 1, 0, record)
+            await sortVoluntaryByUniversity(recordList.map(r => r.universityId))
+            uni.$ie.showSuccess('保存成功')
+          }
+          break;
+        case 'down':
+          if (idx < recordList.length - 1) {
+            recordList.splice(idx, 1)
+            recordList.splice(idx + 1, 0, record)
+            await sortVoluntaryByUniversity(recordList.map(r => r.universityId))
+            uni.$ie.showSuccess('保存成功')
+          }
+          break;
+      }
+    } catch (e) {
+      console.log('action ex', e)
+      paging.value?.reload() // 发生异常时,重新加载列表
     }
     }
+  } else if (e.id === 'delete') {
+    const confirm = await uni.$ie.showConfirm({
+      title: '志愿删除提醒',
+      content: `删除'${record.universityName}',将同时删除该院校下所有意向专业。\n确认删除?!`
+    })
+    if (confirm) {
+      await removeVoluntaryByUniversity(record.universityId)
+      uni.$ie.showSuccess('删除成功')
+      paging.value?.reload()
+    }
+  } else {
+    throw new Error('Unsupported action id: ' + e.id)
+  }
 }
 }
 
 
 const handleError = () => {
 const handleError = () => {
-    // 内部异常,重新取数
-    paging.value?.reload()
+  // 内部异常,重新取数
+  paging.value?.reload()
 }
 }
 
 
 const handleAdd = async () => {
 const handleAdd = async () => {
-    const option: UniversityPickerPageOptions = {
-        title: '选择你的意向院校专业',
-        fromVoluntary: true
-    }
-    const picked = await transferTo(routes.targetPicker, {data: option})
-    if (!picked) return
-    await addVoluntary(picked)
-    uni.$ie.showSuccess('保存成功')
-    paging.value?.reload()
+  const option: UniversityPickerPageOptions = {
+    title: '选择你的意向院校专业',
+    fromVoluntary: true
+  }
+  const picked = await transferTo(routes.targetPicker, { data: option })
+  if (!picked) return
+  await addVoluntary(picked)
+  uni.$ie.showSuccess('保存成功')
+  paging.value?.reload()
 }
 }
 
 
 provide(VOLUNTARY_SORTING, isSorting)
 provide(VOLUNTARY_SORTING, isSorting)
 </script>
 </script>
 
 
-<style lang="scss">
-
-</style>
+<style lang="scss"></style>

+ 3 - 2
src/pagesStudy/components/paper-work-item.vue

@@ -49,7 +49,8 @@ import { EnumPaperType, EnumPaperWorkState } from '@/common/enum';
 import { useTransferPage } from '@/hooks/useTransferPage';
 import { useTransferPage } from '@/hooks/useTransferPage';
 import { getPaperWorkDetail, getOpenExaminee } from '@/api/modules/study';
 import { getPaperWorkDetail, getOpenExaminee } from '@/api/modules/study';
 import { Study, Transfer } from '@/types';
 import { Study, Transfer } from '@/types';
-import { formatSeconds } from '@/utils/common';
+import { formatSeconds, formatTime } from '@/utils/format';
+
 const { transferTo } = useTransferPage();
 const { transferTo } = useTransferPage();
 const props = defineProps<{
 const props = defineProps<{
   data: Study.PaperWork;
   data: Study.PaperWork;
@@ -66,7 +67,7 @@ const batchName = computed(() => {
   return `${subjectName}(${batchName || ''})`;
   return `${subjectName}(${batchName || ''})`;
 });
 });
 const publishTime = computed(() => {
 const publishTime = computed(() => {
-  return uni.$ie.formatTime(props.data.publishTime, 'yyyy年mm月dd日 hh:MM:ss');
+  return formatTime(props.data.publishTime, 'yyyy年mm月dd日 hh:MM:ss');
 });
 });
 
 
 const handleDetail = () => {
 const handleDetail = () => {

+ 159 - 160
src/pagesStudy/pages/targeted-add/targeted-add.vue

@@ -1,206 +1,205 @@
 <template>
 <template>
-    <ie-page bg-color="#F6F8FA" :fix-height="true">
-        <ie-navbar :title="title"/>
-        <view class="mt-16 bg-white py-10">
-            <view class="">
-                <uv-cell-group :border="false">
-                    <uv-cell isLink :border="true" :cellStyle="cellStyle" :rightIconStyle="rightIconStyle"
-                             @click="handleUniversitySelect">
-                        <template #title>
-                            <text class="text-30 text-fore-subtitle whitespace-nowrap">选择院校</text>
-                        </template>
-                        <template #value>
-                            <text v-if="form.universityName" class="mx-10 text-30 text-fore-title">
-                                {{ form.universityName }}
-                            </text>
-                            <text v-else class="mr-10 text-30 text-fore-placeholder">请选择</text>
-                        </template>
-                    </uv-cell>
-                    <uv-cell isLink :border="false" :cellStyle="cellStyle" :rightIconStyle="rightIconStyle"
-                             @click="handleMajorSelect">
-                        <template #title>
-                            <text class="text-30 text-fore-subtitle whitespace-nowrap">选择专业</text>
-                        </template>
-                        <template #value>
-                            <text v-if="form.majorName" class="mx-10 text-30 text-fore-title">
-                                {{ form.majorName }}
-                            </text>
-                            <text v-else class="mr-10 text-30 text-fore-placeholder">请选择</text>
-                        </template>
-                    </uv-cell>
-                </uv-cell-group>
-            </view>
+  <ie-page bg-color="#F6F8FA" :fix-height="true">
+    <ie-navbar :title="title" />
+    <view class="mt-16 bg-white py-10">
+      <view class="">
+        <uv-cell-group :border="false">
+          <uv-cell isLink :border="true" :cellStyle="cellStyle" :rightIconStyle="rightIconStyle"
+            @click="handleUniversitySelect">
+            <template #title>
+              <text class="text-30 text-fore-subtitle whitespace-nowrap">选择院校</text>
+            </template>
+            <template #value>
+              <text v-if="form.universityName" class="mx-10 text-30 text-fore-title">
+                {{ form.universityName }}
+              </text>
+              <text v-else class="mr-10 text-30 text-fore-placeholder">请选择</text>
+            </template>
+          </uv-cell>
+          <uv-cell isLink :border="false" :cellStyle="cellStyle" :rightIconStyle="rightIconStyle"
+            @click="handleMajorSelect">
+            <template #title>
+              <text class="text-30 text-fore-subtitle whitespace-nowrap">选择专业</text>
+            </template>
+            <template #value>
+              <text v-if="form.majorName" class="mx-10 text-30 text-fore-title">
+                {{ form.majorName }}
+              </text>
+              <text v-else class="mr-10 text-30 text-fore-placeholder">请选择</text>
+            </template>
+          </uv-cell>
+        </uv-cell-group>
+      </view>
+    </view>
+    <ie-safe-toolbar :height="84" :shadow="false">
+      <view class="px-46 pt-24">
+        <ie-button type="primary" @click="handleAdd">确认</ie-button>
+      </view>
+    </ie-safe-toolbar>
+    <ie-popup ref="popupRef" title="选择专业" @confirm="handleConfirm">
+      <view class="h-[50vh] bg-white px-30 pt-20 flex flex-col">
+        <view>
+          <uv-search v-model="keyword" shape="square" :showAction="false" placeholder="请输入专业名称" />
         </view>
         </view>
-        <ie-safe-toolbar :height="84" :shadow="false">
-            <view class="px-46 pt-24">
-                <ie-button type="primary" @click="handleAdd">确认</ie-button>
-            </view>
-        </ie-safe-toolbar>
-        <ie-popup ref="popupRef" title="选择专业" @confirm="handleConfirm">
-            <view class="h-[50vh] bg-white px-30 pt-20 flex flex-col">
-                <view>
-                    <uv-search v-model="keyword" shape="square" :showAction="false" placeholder="请输入专业名称"/>
+        <view class="mt-20 flex-1 min-h-1">
+          <scroll-view scroll-y class="h-full">
+            <view v-for="item in filteredMajorList" :key="item.id"
+              class="px-20 py-16 bg-white sibling-border-top flex items-center gap-x-20" @click="handleSelect(item)">
+              <view class="flex-1 min-w-1 flex-shrink-0">
+                <view class="flex items-center gap-x-10 text-fore-title">
+                  <span class="text-30 " :class="[isActive(item) ? 'text-primary' : 'text-fore-title']">{{
+                    item.name
+                  }}</span>
+                  <span v-if="item.notice" class="text-22 text-fore-light flex-1 min-w-1 ellipsis-1"
+                    :class="[isActive(item) ? 'text-primary' : 'text-fore-title']">{{
+                      `(${item.notice})`
+                    }}</span>
                 </view>
                 </view>
-                <view class="mt-20 flex-1 min-h-1">
-                    <scroll-view scroll-y class="h-full">
-                        <view v-for="item in filteredMajorList" :key="item.id"
-                              class="px-20 py-16 bg-white sibling-border-top flex items-center gap-x-20"
-                              @click="handleSelect(item)">
-                            <view class="flex-1 min-w-1 flex-shrink-0">
-                                <view class="flex items-center gap-x-10 text-fore-title">
-                                <span class="text-30 " :class="[isActive(item) ? 'text-primary' : 'text-fore-title']">{{
-                                        item.name
-                                    }}</span>
-                                    <span v-if="item.notice" class="text-22 text-fore-light flex-1 min-w-1 ellipsis-1"
-                                          :class="[isActive(item) ? 'text-primary' : 'text-fore-title']">{{
-                                            `(${item.notice})`
-                                        }}</span>
-                                </view>
-                                <view class="mt-6 text-22 text-fore-light"
-                                      :class="[isActive(item) ? 'text-primary' : 'text-fore-light']">
-                                    {{
-                                        item.ancestors
-                                    }}
-                                </view>
-                            </view>
-                            <uv-icon v-if="isActive(item)" name="checkmark" size="20" color="#31A0FC"/>
-                        </view>
-                    </scroll-view>
+                <view class="mt-6 text-22 text-fore-light"
+                  :class="[isActive(item) ? 'text-primary' : 'text-fore-light']">
+                  {{
+                    item.ancestors
+                  }}
                 </view>
                 </view>
+              </view>
+              <uv-icon v-if="isActive(item)" name="checkmark" size="20" color="#31A0FC" />
             </view>
             </view>
-        </ie-popup>
-    </ie-page>
+          </scroll-view>
+        </view>
+      </view>
+    </ie-popup>
+  </ie-page>
 </template>
 </template>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
-import {useTransferPage} from '@/hooks/useTransferPage';
-import {University} from '@/types/university';
-import {DirectedSchool, UniversityMajor} from '@/types/study';
-import {SelectedUniversityMajor} from '@/types/voluntary';
-import {getUniversityMajorList} from '@/api/modules/university';
-import {useUserStore} from '@/store/userStore';
-import {routes} from "@/common/routes";
-import {UniversityPickerPageOptions} from "@/types/transfer";
+import { useTransferPage } from '@/hooks/useTransferPage';
+import { University } from '@/types/university';
+import { DirectedSchool, UniversityMajor } from '@/types/study';
+import { SelectedUniversityMajor } from '@/types/voluntary';
+import { getUniversityMajorList } from '@/api/modules/university';
+import { useUserStore } from '@/store/userStore';
+import { routes } from "@/common/routes";
+import { UniversityPickerPageOptions } from "@/types/transfer";
 
 
 const userStore = useUserStore();
 const userStore = useUserStore();
-const {prevData, transferTo, transferBack} = useTransferPage<UniversityPickerPageOptions, any>();
-const {directedSchoolList} = toRefs(userStore);
+const { prevData, transferTo, transferBack } = useTransferPage<UniversityPickerPageOptions, any>();
+const { directedSchoolList } = toRefs(userStore);
 const form = ref<Partial<SelectedUniversityMajor>>({});
 const form = ref<Partial<SelectedUniversityMajor>>({});
 const keyword = ref('');
 const keyword = ref('');
 const cellStyle = {
 const cellStyle = {
-    padding: '20rpx 40rpx'
+  padding: '20rpx 40rpx'
 }
 }
 const rightIconStyle = {
 const rightIconStyle = {
-    fontSize: '14px'
+  fontSize: '14px'
 }
 }
 const majorList = ref<UniversityMajor[]>([]);
 const majorList = ref<UniversityMajor[]>([]);
 const filteredMajorList = computed(() => {
 const filteredMajorList = computed(() => {
-    return majorList.value.filter(item => item.name.includes(keyword.value));
+  return majorList.value.filter(item => item.name.includes(keyword.value));
 });
 });
 const title = computed(() => prevData.value.title || '添加定向院校')
 const title = computed(() => prevData.value.title || '添加定向院校')
 const handleUniversitySelect = () => {
 const handleUniversitySelect = () => {
-    transferTo(routes.universityPicker).then((res: any) => {
-        if (res) {
-            const university = res as University;
-            if (university.code !== form.value.universityId) {
-                selectedMajor.value = null;
-                form.value.majorId = '';
-                form.value.majorName = '';
-            }
-            form.value.universityId = university.code;
-            form.value.universityName = university.name;
-            form.value.universityLogo = university.logo;
-            form.value.info = university;
-            loadMajorList(university.code);
-        }
-    });
+  transferTo(routes.universityPicker).then((res: any) => {
+    if (res) {
+      const university = res as University;
+      if (university.code !== form.value.universityId) {
+        selectedMajor.value = null;
+        form.value.majorId = '';
+        form.value.majorName = '';
+      }
+      form.value.universityId = university.code;
+      form.value.universityName = university.name;
+      form.value.universityLogo = university.logo;
+      form.value.info = university;
+      loadMajorList(university.code);
+    }
+  });
 }
 }
 
 
 const popupRef = ref();
 const popupRef = ref();
 const selectedMajor = ref<Pick<UniversityMajor, 'ancestors' | 'code' | 'id' | 'name'> | null>(null);
 const selectedMajor = ref<Pick<UniversityMajor, 'ancestors' | 'code' | 'id' | 'name'> | null>(null);
 const handleMajorSelect = () => {
 const handleMajorSelect = () => {
-    if (!form.value.universityId) {
-        uni.$ie.showToast('请选择院校');
-        return;
+  if (!form.value.universityId) {
+    uni.$ie.showToast('请选择院校');
+    return;
+  }
+  keyword.value = '';
+  if (form.value.majorId) {
+    selectedMajor.value = {
+      ancestors: form.value.majorAncestors || '',
+      code: form.value.majorId || '',
+      id: Number(form.value.majorId),
+      name: form.value.majorName || ''
     }
     }
-    keyword.value = '';
-    if (form.value.majorId) {
-        selectedMajor.value = {
-            ancestors: form.value.majorAncestors || '',
-            code: form.value.majorId || '',
-            id: Number(form.value.majorId),
-            name: form.value.majorName || ''
-        }
-    } else {
-        selectedMajor.value = null;
-    }
-    popupRef.value.open();
+  } else {
+    selectedMajor.value = null;
+  }
+  popupRef.value.open();
 }
 }
 
 
 const handleConfirm = () => {
 const handleConfirm = () => {
-    if (!selectedMajor.value) {
-        uni.$ie.showToast('请选择专业');
-        return;
-    }
-    form.value.majorAncestors = selectedMajor.value.ancestors;
-    form.value.majorId = selectedMajor.value.id.toString();
-    form.value.majorName = selectedMajor.value.name;
-    popupRef.value.close();
+  if (!selectedMajor.value) {
+    uni.$ie.showToast('请选择专业');
+    return;
+  }
+  form.value.majorAncestors = selectedMajor.value.ancestors;
+  form.value.majorId = selectedMajor.value.id.toString();
+  form.value.majorName = selectedMajor.value.name;
+  popupRef.value.close();
 }
 }
 const handleSelect = (item: UniversityMajor) => {
 const handleSelect = (item: UniversityMajor) => {
-    selectedMajor.value = item;
+  selectedMajor.value = item;
 }
 }
 
 
 const handleAdd = async () => {
 const handleAdd = async () => {
-    if (!form.value.universityId) {
-        uni.$ie.showToast('请选择院校');
-        return;
-    }
-    if (!form.value.majorId) {
-        uni.$ie.showToast('请选择专业');
-        return;
+  if (!form.value.universityId) {
+    uni.$ie.showToast('请选择院校');
+    return;
+  }
+  if (!form.value.majorId) {
+    uni.$ie.showToast('请选择专业');
+    return;
+  }
+  if (prevData.value.fromVoluntary === true) {
+    // 志愿类
+    if (prevData.value.selectedUniversityId === form.value.universityId &&
+      prevData.value.selectedMajorId === form.value.majorId) {
+      return uni.$ie.showToast('请勿选择相同院校专业')
     }
     }
-    if (prevData.value.fromVoluntary === true) {
-        // 志愿类
-        if (prevData.value.selectedUniversityId === form.value.universityId &&
-            prevData.value.selectedMajorId === form.value.majorId) {
-            return uni.$ie.showToast('请勿选择相同院校专业')
-        }
-        return transferBack(form.value)
-    }
-    // 检查数据是否已存在
-    const historyData = directedSchoolList.value;
-    const isExist = historyData.some(item => item.universityId === form.value.universityId && item.majorId === form.value.majorId);
-    if (isExist) {
-        uni.$ie.showToast('该院校专业已存在');
-        return;
-    }
-    uni.$ie.showLoading();
-    const params = {
-        ...form.value,
-        code: form.value.universityId
-    } as DirectedSchool;
-    await userStore.saveDirectedSchoolList([params, ...directedSchoolList.value]);
-    uni.$ie.hideLoading();
-    uni.$ie.showSuccess('保存成功');
-    setTimeout(() => {
-        transferTo('/pagesStudy/pages/targeted-setting/targeted-setting', {
-            type: 'redirectTo'
-        });
-    }, 600);
+    return transferBack(form.value)
+  }
+  // 检查数据是否已存在
+  const historyData = directedSchoolList.value;
+  const isExist = historyData.some(item => item.universityId === form.value.universityId && item.majorId === form.value.majorId);
+  if (isExist) {
+    uni.$ie.showToast('该院校专业已存在');
+    return;
+  }
+  uni.$ie.showLoading();
+  const params = {
+    ...form.value,
+    code: form.value.universityId
+  } as DirectedSchool;
+  await userStore.saveDirectedSchoolList([params, ...directedSchoolList.value]);
+  uni.$ie.hideLoading();
+  uni.$ie.showSuccess('保存成功');
+  setTimeout(() => {
+    transferTo('/pagesStudy/pages/targeted-setting/targeted-setting', {
+      type: 'redirectTo'
+    });
+  }, 600);
 }
 }
 const isActive = (item: UniversityMajor) => {
 const isActive = (item: UniversityMajor) => {
-    return selectedMajor.value && selectedMajor.value.id === item.id;
+  return selectedMajor.value && selectedMajor.value.id === item.id;
 }
 }
 const loadMajorList = async (universityId: string) => {
 const loadMajorList = async (universityId: string) => {
-    uni.$ie.showLoading();
-    const {data} = await getUniversityMajorList({universityId});
-    majorList.value = data;
-    uni.$ie.hideLoading();
+  uni.$ie.showLoading();
+  const { data } = await getUniversityMajorList({ universityId });
+  majorList.value = data;
+  uni.$ie.hideLoading();
 }
 }
 
 
 onLoad(() => {
 onLoad(() => {
-    handleUniversitySelect();
+  handleUniversitySelect();
 });
 });
 </script>
 </script>
 
 

+ 13 - 0
src/pagesSystem/pages/privacy-policy/privacy-policy.vue

@@ -0,0 +1,13 @@
+<template>
+  <view>
+    
+  </view>
+</template>
+
+<script setup>
+  
+</script>
+
+<style lang="scss">
+
+</style>

+ 90 - 0
src/pagesSystem/pages/setting/setting.vue

@@ -0,0 +1,90 @@
+<template>
+  <ie-page bg-color="#f8fcff">
+    <ie-navbar title="关于" />
+    <view class="flex items-center justify-center py-80">
+      <ie-image src="/static/logo.png" custom-class="w-160 h-160" mode="widthFix" />
+    </view>
+    <uv-cell-group class="bg-white !flex-none">
+      <uv-cell v-for="item in settings" :icon="item.icon" :is-link="item.isLink" :title="item.title" :value="item.value"
+        icon-style="font-size: 20px;" @click="item.handler()" />
+    </uv-cell-group>
+  </ie-page>
+</template>
+
+<script lang="ts" setup>
+import { useTransferPage } from '@/hooks/useTransferPage';
+import { useAppStore } from '@/store/appStore';
+import { useUserStore } from '@/store/userStore';
+import config from '@/config';
+
+const appStore = useAppStore();
+const userStore = useUserStore();
+const { transferTo, routes } = useTransferPage();
+const contactPhone = computed(() => userStore.orgInfo.contactPhone);
+
+const settings = computed(() => [
+  {
+    title: '服务协议',
+    icon: 'empty-order',
+    isLink: true,
+    handler: () => {
+      transferTo(routes.pageWebview, {
+        data: {
+          url: config.userProtocolUrl,
+          title: '服务协议'
+        }
+      });
+    }
+  },
+  {
+    title: '隐私政策',
+    icon: 'lock',
+    isLink: true,
+    handler: () => {
+      transferTo(routes.pageWebview, {
+        data: {
+          url: config.privacyPolicyUrl,
+          title: '隐私政策'
+        }
+      });
+    }
+  },
+  {
+    title: '当前版本',
+    icon: 'tags',
+    value: appStore.systemInfo?.appVersion,
+    handler: () => {
+    }
+  },
+  {
+    title: '注销账号',
+    icon: 'trash',
+    isLink: true,
+    handler: async () => {
+      uni.$ie.showConfirm({
+        title: '注销账号',
+        content: '是否注销账号,注销后卡号将不能再注册使用系统且永久失效。请谨慎操作!'
+      }).then(confirm => {
+        if (confirm) {
+          userStore.deleteAccount();
+        }
+      });
+    }
+  },
+  {
+    title: 'APP备案号',
+    icon: 'empty-permission',
+    value: '湘ICP备18012964号-8A',
+    handler: () => {
+    }
+  },
+  {
+    title: '客服电话',
+    icon: 'server-man',
+    value: contactPhone.value,
+    handler: () => { }
+  }
+]);
+</script>
+
+<style lang="scss"></style>

+ 13 - 0
src/pagesSystem/pages/user-protocol/user-protocol.vue

@@ -0,0 +1,13 @@
+<template>
+  <view>
+    
+  </view>
+</template>
+
+<script setup>
+  
+</script>
+
+<style lang="scss">
+
+</style>

+ 22 - 0
src/pagesSystem/pages/webview/webview.vue

@@ -0,0 +1,22 @@
+<template>
+  <ie-page :fix-height="true">
+    <ie-navbar :title="pageTitle" />
+    <ie-auto-resizer>
+      <web-view class="w-full h-full" :src="url" />
+    </ie-auto-resizer>
+  </ie-page>
+</template>
+
+<script lang="ts" setup>
+import { useTransferPage } from '@/hooks/useTransferPage';
+
+const { prevData } = useTransferPage();
+const url = ref('');
+const pageTitle = ref('');
+onLoad(() => {
+  url.value = prevData.value.url;
+  pageTitle.value = prevData.value.title;
+});
+</script>
+
+<style lang="scss"></style>

binární
src/static/mescroll-empty.png


binární
src/static/personal/icon-protocol.png


+ 16 - 9
src/store/userStore.ts

@@ -1,7 +1,7 @@
 import { defineStore } from 'pinia';
 import { defineStore } from 'pinia';
 import { useTransferPage } from '@/hooks/useTransferPage';
 import { useTransferPage } from '@/hooks/useTransferPage';
 import { ref, computed } from 'vue';
 import { ref, computed } from 'vue';
-import { getUserInfo } from '@/api/modules/login';
+import { getUserInfo, logoutPhysical } from '@/api/modules/login';
 import config from '@/config';
 import config from '@/config';
 
 
 import { Study, UserStoreState } from '@/types';
 import { Study, UserStoreState } from '@/types';
@@ -11,7 +11,7 @@ import defaultAvatar from '@/static/personal/avatar_default.png'
 
 
 // @ts-ignore
 // @ts-ignore
 // import { useUserStore as useOldUserStore } from '@/hooks/useUserStore';
 // import { useUserStore as useOldUserStore } from '@/hooks/useUserStore';
-import {CardType, EnumExamType, EnumReviewMode, EnumUserType} from '@/common/enum';
+import { CardType, EnumExamType, EnumReviewMode, EnumUserType } from '@/common/enum';
 import { OPEN_VIP_POPUP } from '@/types/injectionSymbols';
 import { OPEN_VIP_POPUP } from '@/types/injectionSymbols';
 import { getDirectedSchool, saveDirectedSchool } from '@/api/modules/study';
 import { getDirectedSchool, saveDirectedSchool } from '@/api/modules/study';
 // const oldUserStore = useOldUserStore()
 // const oldUserStore = useOldUserStore()
@@ -266,14 +266,21 @@ export const useUserStore = defineStore('ie-user', {
       this.org = {
       this.org = {
         ...config.defaultOrg,
         ...config.defaultOrg,
       };
       };
-      // oldUserStore.Logout();
-      // const { transferTo } = useTransferPage();
-      // setTimeout(() => {
-      //   transferTo('/pagesMain/pages/index/index', {
-      //     type: 'reLaunch'
-      //   })
-      // }, 300);
+      const { transferTo } = useTransferPage();
+      setTimeout(() => {
+        transferTo('/pagesMain/pages/index/index', {
+          type: 'reLaunch'
+        })
+      }, 300);
     },
     },
+    deleteAccount() {
+      uni.$ie.showLoading('注销中...');
+      logoutPhysical().then(() => {
+        this.logout();
+      }).finally(() => {
+        uni.$ie.hideLoading();
+      });
+    }
   },
   },
   persist: {
   persist: {
     storage: {
     storage: {

+ 14 - 0
src/types/dropdown.ts

@@ -0,0 +1,14 @@
+export interface DropdownItem {
+  placeholder?: string;
+  label: string;
+  value: string | number | string[] | number[];
+  prop: string;
+  keyName?: string;
+  keyValue?: string;
+  options?: DropdownOption[];
+}
+
+export interface DropdownOption {
+  label: string;
+  value: string | number;
+}

+ 3 - 4
src/types/index.ts

@@ -7,10 +7,13 @@ import * as Major from "./major";
 import * as Career from "./career";
 import * as Career from "./career";
 import * as Tree from "./tree";
 import * as Tree from "./tree";
 import * as Voluntary from "./voluntary";
 import * as Voluntary from "./voluntary";
+import * as Dropdown from "./dropdown";
 import * as University from "./university";
 import * as University from "./university";
 import { VipCardInfo } from "./user";
 import { VipCardInfo } from "./user";
 import { EnumExamMode, EnumExamType, EnumReviewMode } from "@/common/enum";
 import { EnumExamMode, EnumExamType, EnumReviewMode } from "@/common/enum";
 
 
+export { Study, User, News, Transfer, System, Major, Career, Tree, Voluntary, Dropdown, University };
+
 /// 接口响应
 /// 接口响应
 export interface ApiResponse<T> {
 export interface ApiResponse<T> {
   code: number;
   code: number;
@@ -143,7 +146,3 @@ export interface Entity {
   updateBy: string | null;
   updateBy: string | null;
   updateTime: string | null;
   updateTime: string | null;
 }
 }
-
-
-
-export { Study, User, News, Transfer, System, Major, Career, Tree, Voluntary, University };

+ 4 - 4
src/types/injectionSymbols.ts

@@ -1,7 +1,7 @@
-import type {InjectionKey} from 'vue'
-import {StudyPlan, StudyPlanStats} from './study';
-import {Study, Transfer, University, Voluntary, Major} from '.';
-import {useExam} from '@/composables/useExam';
+import type { InjectionKey } from 'vue'
+import { StudyPlan, StudyPlanStats } from './study';
+import { Study, Transfer, University, Voluntary, Major } from '.';
+import { useExam } from '@/composables/useExam';
 
 
 /**
 /**
  * 打开知识点记录详情
  * 打开知识点记录详情

+ 93 - 83
src/types/university.ts

@@ -1,73 +1,73 @@
-import {EnumBrochureType} from "@/common/enum";
+import { EnumBrochureType } from "@/common/enum";
 
 
 export interface University {
 export interface University {
-    bannerUrl: string;
-    address: string;
-    area: string | number;
-    bxLevel: string;
-    bxType: string; // 现在似乎没有值
-    cityName: string;
-    code: string;
-    collect: string | number;
-    collected: boolean;
-    comScore: string | number;
-    enrollLocation: string;
-    features: string;
-    hits: number;
-    id: number;
-    location: string;
-    logo: string;
-    name: string;
-    natureTypeCN: string;
-    star: string;
-    type: string;
-    webSite: string;
-    tier: string;
-    tierName: string;
-    introduction: string;
-    tel: string;
+  bannerUrl: string;
+  address: string;
+  area: string | number;
+  bxLevel: string;
+  bxType: string; // 现在似乎没有值
+  cityName: string;
+  code: string;
+  collect: string | number;
+  collected: boolean;
+  comScore: string | number;
+  enrollLocation: string;
+  features: string;
+  hits: number;
+  id: number;
+  location: string;
+  logo: string;
+  name: string;
+  natureTypeCN: string;
+  star: string;
+  type: string;
+  webSite: string;
+  tier: string;
+  tierName: string;
+  introduction: string;
+  tel: string;
 }
 }
 
 
 export interface UniversityProfession {
 export interface UniversityProfession {
-    "remark": string;
-    "id": string | number;
-    "collegeCode": string;
-    "type": string;
-    "code": string;
-    "name": string;
-    "ranking": number | null;
-    "count": number | null;
-    "hot": number | null;
-    "examType": string;
-    "enrollCode": string;
-    "majorDirection": string;
+  "remark": string;
+  "id": string | number;
+  "collegeCode": string;
+  "type": string;
+  "code": string;
+  "name": string;
+  "ranking": number | null;
+  "count": number | null;
+  "hot": number | null;
+  "examType": string;
+  "enrollCode": string;
+  "majorDirection": string;
 }
 }
 
 
 export interface UniversityBrochure {
 export interface UniversityBrochure {
-    "createBy": string;
-    "createTime": string;
-    "updateBy": string;
-    "updateTime": string;
-    "remark": string;
-    "id": number;
-    "year": string;
-    "collegeCode": string;
-    "collegeName": string;
-    "editor": string;
-    "url": string;
-    "summary": string;
-    "title": string;
-    "isArt": boolean|null;
-    "type": EnumBrochureType;
-    "metaDescription": string;
-    "content": string;
-    "tags": string;
-    "isShow": number;
-    "hits": number;
-    "createTime2": string;
-    "typeName": string;
+  "createBy": string;
+  "createTime": string;
+  "updateBy": string;
+  "updateTime": string;
+  "remark": string;
+  "id": number;
+  "year": string;
+  "collegeCode": string;
+  "collegeName": string;
+  "editor": string;
+  "url": string;
+  "summary": string;
+  "title": string;
+  "isArt": boolean | null;
+  "type": EnumBrochureType;
+  "metaDescription": string;
+  "content": string;
+  "tags": string;
+  "isShow": number;
+  "hits": number;
+  "createTime2": string;
+  "typeName": string;
 
 
-    "logo"?: string;
+  "logo"?: string;
 }
 }
 
 
 export type HistoryMode = 'plan' | 'enroll';
 export type HistoryMode = 'plan' | 'enroll';
@@ -107,33 +107,43 @@ export interface IPlanEnrollDescriptor {
 }
 }
 
 
 export interface UniversityDetail {
 export interface UniversityDetail {
-    baseInfo: University;
-    enrollBrochures: UniversityBrochure[];
-    enrollHistories: [];
-    planHistories: [];
-    professions: UniversityProfession[];
+  baseInfo: University;
+  enrollBrochures: UniversityBrochure[];
+  enrollHistories: [];
+  planHistories: [];
+  professions: UniversityProfession[];
 }
 }
 
 
 export interface UniversityQueryDto {
 export interface UniversityQueryDto {
-    name: string | null;
-    features: string[] | null;
-    type: string[] | null;
-    natureTypeCN: string[] | null;
-    location: string[] | null;
-    level: string[] | null;
-    tier: string[] | null;
+  name: string;
+  features: string[];
+  type: string[];
+  natureTypeCN: string[];
+  location: string[];
+  level: string[];
+  tier: string[];
 }
 }
 
 
 export interface UniversityTier {
 export interface UniversityTier {
-    typeName: string;
-    typeValue: string | number;
-    desc: string;
-    list: University[];
+  typeName: string;
+  typeValue: string | number;
+  desc: string;
+  list: University[];
+
+  /*UI props begin 后台不用管*/
+  colorFrom?: string;
+  colorTo?: string;
+  colorText?: string;
+  icon?: string;
+  /*UI props end*/
+}
 
 
-    /*UI props begin 后台不用管*/
-    colorFrom?: string;
-    colorTo?: string;
-    colorText?: string;
-    icon?: string;
-    /*UI props end*/
+export interface UniversityFilter {
+  features: string[];
+  types: string[];
+  natureTypes: string[];
+  bxTypes: string[];
+  locations: string[];
+  tiers: Record<number, string>;
+  stars: Record<number, string>;
 }
 }

+ 68 - 68
src/types/voluntary.ts

@@ -1,35 +1,35 @@
-import {DictItem, Study} from "@/types/index";
-import {University} from "@/types/university";
+import { DictItem, Study } from "@/types/index";
+import { University } from "@/types/university";
 
 
 export type EnumInputType = 'Score' | 'Number' | 'Text' | 'Radio' | 'Picker' | 'Checkbox' | 'Eyesight';
 export type EnumInputType = 'Score' | 'Number' | 'Text' | 'Radio' | 'Picker' | 'Checkbox' | 'Eyesight';
 export type EnumRuleCategory = 'Enroll' | 'Special';
 export type EnumRuleCategory = 'Enroll' | 'Special';
 export type EnumPickType = 'Danger' | 'Normal' | 'Safety';
 export type EnumPickType = 'Danger' | 'Normal' | 'Safety';
 
 
 export interface EnrollRuleItem {
 export interface EnrollRuleItem {
-    defaultValue?: string | number;
-    description?: string;
-    dictOptions?: DictItem[];
-    dotDisable?: boolean
-    enumInputType: EnumInputType;
-    enumRuleCategory: EnumRuleCategory;
-    fieldName: string;
-    keyboardMode?: string
-    label: string;
-    max?: number
-    min?: number
-    mutexOption?: string[] | number[];
-    options?: string[] | number[];
-    placeholder?: string;
-    regex?: string;
-    required?: boolean;
-    tips?: string;
-    readonly?: boolean;
+  defaultValue?: string | number;
+  description?: string;
+  dictOptions?: DictItem[];
+  dotDisable?: boolean
+  enumInputType: EnumInputType;
+  enumRuleCategory: EnumRuleCategory;
+  fieldName: string;
+  keyboardMode?: string
+  label: string;
+  max?: number
+  min?: number
+  mutexOption?: string[] | number[];
+  options?: string[] | number[];
+  placeholder?: string;
+  regex?: string;
+  required?: boolean;
+  tips?: string;
+  readonly?: boolean;
 }
 }
 
 
 export interface EnrollRule {
 export interface EnrollRule {
-    category: string;
-    content: string;
-    details: EnrollRuleItem[]
+  category: string;
+  content: string;
+  details: EnrollRuleItem[]
 }
 }
 
 
 export interface VoluntaryModel extends Record<string, string | number | null> {
 export interface VoluntaryModel extends Record<string, string | number | null> {
@@ -37,70 +37,70 @@ export interface VoluntaryModel extends Record<string, string | number | null> {
 }
 }
 
 
 export interface VoluntaryResultHistory {
 export interface VoluntaryResultHistory {
-    "year": string | number;
-    "score": string | number | null; // 最低分
-    "plan"?: number | null; // 计划人数
-    "enroll"?: number | null; // 录取人数
-    "diff"?: number | null; // 负表示低于录取分;正数表示高于录取分
-    "ruleContent"?: string; // 招录规则
-    "application"?: number | null; // 报名人数比值
-    "admission"?: number | null; // 计划人数比值
+  "year": string | number;
+  "score": string | number | null; // 最低分
+  "plan"?: number | null; // 计划人数
+  "enroll"?: number | null; // 录取人数
+  "diff"?: number | null; // 负表示低于录取分;正数表示高于录取分
+  "ruleContent"?: string; // 招录规则
+  "application"?: number | null; // 报名人数比值
+  "admission"?: number | null; // 计划人数比值
 }
 }
 
 
 export interface VoluntaryResultSkill {
 export interface VoluntaryResultSkill {
-    year: string | number;
-    cultureScore: number;
-    cultureRule: string;
-    enrollScore: number;
-    skillScore: number; // 反向测技能分
-    diff: number; // 负数表示低于skillScore,正数高于
+  year: string | number;
+  cultureScore: number;
+  cultureRule: string;
+  enrollScore: number;
+  skillScore: number; // 反向测技能分
+  diff: number; // 负数表示低于skillScore,正数高于
 }
 }
 
 
 export interface VoluntaryResult {
 export interface VoluntaryResult {
-    "universityCode": string;
-    "majorCode": string;
-    "majorEnrollCode": string;
-    "majorGroup": string;
-    "majorName": string;
-    "majorDirection": string;
-    "enumPickType": EnumPickType;
-    "enrollRate": number | null;
-    "enrollRateText": string;
-    "tips": string | null;
-    "histories"?: VoluntaryResultHistory[],
-    "skill": VoluntaryResultSkill
+  "universityCode": string;
+  "majorCode": string;
+  "majorEnrollCode": string;
+  "majorGroup": string;
+  "majorName": string;
+  "majorDirection": string;
+  "enumPickType": EnumPickType;
+  "enrollRate": number | null;
+  "enrollRateText": string;
+  "tips": string | null;
+  "histories"?: VoluntaryResultHistory[],
+  "skill": VoluntaryResultSkill
 }
 }
 
 
 export interface SelectedUniversityMajor extends Study.SelectedUniversityMajor {
 export interface SelectedUniversityMajor extends Study.SelectedUniversityMajor {
-    info?: University;
+  info?: University;
 }
 }
 
 
 export interface VoluntaryDto {
 export interface VoluntaryDto {
-    target: SelectedUniversityMajor;
-    rules: EnrollRule[];
-    model: VoluntaryModel;
-    result: VoluntaryResult;
+  target: SelectedUniversityMajor;
+  rules: EnrollRule[];
+  model: VoluntaryModel;
+  result: VoluntaryResult;
 }
 }
 
 
 export interface VoluntaryScoreItem {
 export interface VoluntaryScoreItem {
-    label: string;
-    score: number;
-    total: number;
-    labelWidth?: string;
-    scoreWidth?: string;
+  label: string;
+  score: number;
+  total: number;
+  labelWidth?: string;
+  scoreWidth?: string;
 }
 }
 
 
 export interface VoluntaryMajorItem {
 export interface VoluntaryMajorItem {
-    majorId: string;
-    majorName: string;
-    majorAncestors: string;
-    majorGroup: string;
+  majorId: string;
+  majorName: string;
+  majorAncestors: string;
+  majorGroup: string;
 }
 }
 
 
 export interface VoluntaryRecord {
 export interface VoluntaryRecord {
-    id: number;
-    universityLogo: string;
-    universityId: string;
-    universityName: string;
-    majors: VoluntaryMajorItem[]
+  id: number;
+  universityLogo: string;
+  universityId: string;
+  universityName: string;
+  majors: VoluntaryMajorItem[]
 }
 }

+ 0 - 11
src/utils/common.ts

@@ -1,11 +0,0 @@
-/**
- * 将秒转化为时分秒
- * @param seconds 秒
- * @returns 时分秒
- */
-export const formatSeconds = (seconds: number, gap: string = ':') => {
-  const hours = Math.floor(seconds / 3600);
-  const minutes = Math.floor((seconds % 3600) / 60);
-  const secs = seconds % 60;
-  return `${hours.toString().padStart(2, '0')}${gap}${minutes.toString().padStart(2, '0')}${gap}${secs.toString().padStart(2, '0')}`;
-};

+ 22 - 0
src/utils/format.ts

@@ -0,0 +1,22 @@
+/**
+ * 将秒转化为时分秒
+ * @param seconds 秒
+ * @returns 时分秒
+ */
+export const formatSeconds = (seconds: number, gap: string = ':') => {
+  const hours = Math.floor(seconds / 3600);
+  const minutes = Math.floor((seconds % 3600) / 60);
+  const secs = seconds % 60;
+  return `${hours.toString().padStart(2, '0')}${gap}${minutes.toString().padStart(2, '0')}${gap}${secs.toString().padStart(2, '0')}`;
+};
+
+export const formatPrice = (price: number) => {
+  return price / 100;
+}
+
+export const formatTime = (time: number | string, format: string = 'yyyy-mm-dd hh:MM:ss') => {
+  if (!time) {
+    return '';
+  }
+  return uni.$uv.timeFormat(time, format)
+}

+ 1 - 26
src/utils/uni-tool.ts

@@ -81,20 +81,6 @@ export interface IeTool {
    */
    */
   copy(content: string): void;
   copy(content: string): void;
 
 
-  /**
-   * 格式化价格
-   * @param price - 价格
-   * @returns 格式化后的价格
-   */
-  formatPrice(price: number): number;
-
-  /**
-   * 格式化时间
-   * @param time - 时间
-   * @returns 格式化后的时间
-   */
-  formatTime(time: number | string, format: string): string;
-
   /* 打开网址 */
   /* 打开网址 */
   openBrowser(url: string): void;
   openBrowser(url: string): void;
 }
 }
@@ -187,8 +173,7 @@ const tool: IeTool = {
         cancelColor,
         cancelColor,
         confirmColor,
         confirmColor,
         success: (res) => {
         success: (res) => {
-          if (res.confirm) resolve(res.confirm)
-          else reject(res.confirm)
+          resolve(res.confirm)
         },
         },
         fail: reject
         fail: reject
       });
       });
@@ -200,16 +185,6 @@ const tool: IeTool = {
       success: () => { }
       success: () => { }
     });
     });
   },
   },
-  formatPrice(price: number) {
-    return price / 100;
-  },
-  formatTime(time: number | string, format: string = 'yyyy-mm-dd hh:MM:ss') {
-    if (!time) {
-      return '';
-    }
-    // @ts-ignore
-    return uni.$uv.timeFormat(time, format)
-  },
   openBrowser(url: string) {
   openBrowser(url: string) {
     // 判断平台
     // 判断平台
     // #ifdef H5
     // #ifdef H5

+ 0 - 2
vite.config.js

@@ -6,7 +6,6 @@ import uniTailwind from '@uni-helper/vite-plugin-uni-tailwind';
 import AutoImport from 'unplugin-auto-import/vite';
 import AutoImport from 'unplugin-auto-import/vite';
 import Components from 'unplugin-vue-components/vite';
 import Components from 'unplugin-vue-components/vite';
 import { resolve } from 'node:path';
 import { resolve } from 'node:path';
-import uniPolyfill from 'vite-plugin-uni-polyfill';
 import viteCompression from "vite-plugin-compression";
 import viteCompression from "vite-plugin-compression";
 import { env as envConfig } from './src/config';
 import { env as envConfig } from './src/config';
 // https://vitejs.dev/config/
 // https://vitejs.dev/config/
@@ -67,7 +66,6 @@ export default defineConfig(({ mode }) => ({
     }),
     }),
     uni(),
     uni(),
     uniTailwind(),
     uniTailwind(),
-    uniPolyfill(), // 解决vueuse/core10版本及以上运行到小程序报错
   ],
   ],
   css: {
   css: {
     postcss: {
     postcss: {