shmily1213 пре 6 часа
родитељ
комит
236be43e41

+ 17 - 0
src/App.vue

@@ -33,4 +33,21 @@ image {
 .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>

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

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

+ 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;
 
 export type Routes = keyof typeof routes;

+ 5 - 1
src/config.ts

@@ -10,7 +10,11 @@ const config = {
     contactPhone: '400-1797-985',
     logo: '',
     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 = {
   development: {

+ 2 - 2
src/manifest.json

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

+ 24 - 0
src/pages.json

@@ -194,6 +194,30 @@
           "style": {
             "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": ""
+          }
         }
       ]
     },

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

@@ -21,7 +21,8 @@
       </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"
         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">
@@ -47,8 +48,9 @@
 <script lang="ts" setup>
 import { useUserStore } from '@/store/userStore';
 import { useTransferPage } from '@/hooks/useTransferPage';
+
 const userStore = useUserStore();
-const { transferTo } = useTransferPage();
+const { transferTo, routes } = useTransferPage();
 const avatar = computed(() => userStore.avatar);
 const nickName = computed(() => userStore.nickName);
 const phonenumber = computed(() => userStore.anonymousPhoneNumber);
@@ -90,7 +92,7 @@ const handleVip = () => {
 }
 
 const handleSettingClick = async () => {
-  transferTo('/pagesOther/pages/personal-center/setting/setting');
+  transferTo(routes.pageSetting);
 }
 </script>
 <style lang="scss" scoped></style>

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

@@ -10,7 +10,7 @@
       </view>
     </view>
     <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 class="text-danger mx-10">{{ overview.postJobs.length }}</span>
         <span>个</span>
@@ -29,7 +29,7 @@
       </view>
     </view>
     <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 class="text-danger mx-10">{{ overview.jobs.length }}</span>
         <span>个</span>
@@ -48,7 +48,7 @@
       </view>
     </view>
     <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 class="text-danger mx-10">{{ overview.postMajors.length }}</span>
         <span>个</span>

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

@@ -1,176 +1,175 @@
 <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>
 
 <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 {VOLUNTARY_SORTING} from "@/types/injectionSymbols";
+import { VOLUNTARY_SORTING } from "@/types/injectionSymbols";
 import {
-    addVoluntary,
-    getVoluntaryList,
-    removeVoluntaryByUniversity,
-    sortVoluntaryByUniversity
+  addVoluntary,
+  getVoluntaryList,
+  removeVoluntaryByUniversity,
+  sortVoluntaryByUniversity
 } from "@/api/modules/voluntary";
 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 {
-    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 paging = ref<ZPagingInstance>()
 const isSorting = ref<boolean>(false)
 const actionSheet = ref<InstanceType<typeof UvActionSheet>>()
 const actionRecord = ref<VoluntaryRecord>()
 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 = () => {
-    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) => {
-    actionRecord.value = record
-    actionSheet.value?.open()
+  actionRecord.value = record
+  actionSheet.value?.open()
 }
 
 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 = () => {
-    // 内部异常,重新取数
-    paging.value?.reload()
+  // 内部异常,重新取数
+  paging.value?.reload()
 }
 
 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)
 </script>
 
-<style lang="scss">
-
-</style>
+<style lang="scss"></style>

+ 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
src/static/mescroll-empty.png


BIN
src/static/personal/icon-protocol.png


+ 16 - 9
src/store/userStore.ts

@@ -1,7 +1,7 @@
 import { defineStore } from 'pinia';
 import { useTransferPage } from '@/hooks/useTransferPage';
 import { ref, computed } from 'vue';
-import { getUserInfo } from '@/api/modules/login';
+import { getUserInfo, logoutPhysical } from '@/api/modules/login';
 import config from '@/config';
 
 import { Study, UserStoreState } from '@/types';
@@ -11,7 +11,7 @@ import defaultAvatar from '@/static/personal/avatar_default.png'
 
 // @ts-ignore
 // 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 { getDirectedSchool, saveDirectedSchool } from '@/api/modules/study';
 // const oldUserStore = useOldUserStore()
@@ -266,14 +266,21 @@ export const useUserStore = defineStore('ie-user', {
       this.org = {
         ...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: {
     storage: {

+ 0 - 1
src/types/index.ts

@@ -7,7 +7,6 @@ import * as Major from "./major";
 import * as Career from "./career";
 import * as Tree from "./tree";
 import * as Voluntary from "./voluntary";
-import * as University from "./university";
 import * as Dropdown from "./dropdown";
 import * as University from "./university";
 import { VipCardInfo } from "./user";

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

@@ -173,8 +173,7 @@ const tool: IeTool = {
         cancelColor,
         confirmColor,
         success: (res) => {
-          if (res.confirm) resolve(res.confirm)
-          else reject(res.confirm)
+          resolve(res.confirm)
         },
         fail: reject
       });