feat: 计划更新

develop
xjs 2025-02-26 09:22:03 +08:00
parent 3607732513
commit 0d7a24f708
25 changed files with 623 additions and 144 deletions

View File

@ -102,6 +102,12 @@
"useNavbarWeixin": true,
"cities": true,
"getCities": true,
"useCityInfo": true
"useCityInfo": true,
"useRules": true,
"rules": true,
"optionalSubjectList": true,
"requireSubjectList": true,
"optionalSubject": true,
"requireSubject": true
}
}

View File

@ -1,49 +1,6 @@
<p align="center">
<a href="https://github.com/feige996/unibest">
<img width="160" src="./src/static/logo.svg">
</a>
</p>
# 六维志愿
<h1 align="center">
<a href="https://github.com/feige996/unibest" target="_blank">unibest - 最好的 uniapp 开发框架</a>
</h1>
<div align="center">
旧仓库 codercup 进不去了star 也拿不回来,这里也展示一下那个地址的 star.
[![GitHub Repo stars](https://img.shields.io/github/stars/codercup/unibest?style=flat&logo=github)](https://github.com/codercup/unibest)
[![GitHub forks](https://img.shields.io/github/forks/codercup/unibest?style=flat&logo=github)](https://github.com/codercup/unibest)
</div>
<div align="center">
[![GitHub Repo stars](https://img.shields.io/github/stars/feige996/unibest?style=flat&logo=github)](https://github.com/feige996/unibest)
[![GitHub forks](https://img.shields.io/github/forks/feige996/unibest?style=flat&logo=github)](https://github.com/feige996/unibest)
[![star](https://gitee.com/feige996/unibest/badge/star.svg?theme=dark)](https://gitee.com/feige996/unibest/stargazers)
[![fork](https://gitee.com/feige996/unibest/badge/fork.svg?theme=dark)](https://gitee.com/feige996/unibest/members)
![node version](https://img.shields.io/badge/node-%3E%3D18-green)
![pnpm version](https://img.shields.io/badge/pnpm-%3E%3D7.30-green)
![GitHub package.json version (subfolder of monorepo)](https://img.shields.io/github/package-json/v/feige996/unibest)
![GitHub License](https://img.shields.io/github/license/feige996/unibest)
</div>
`unibest` —— 最好的 `uniapp` 开发模板,由 `uniapp` + `Vue3` + `Ts` + `Vite5` + `UnoCss` + `wot-ui` + `z-paging` 构成,使用了最新的前端技术栈,无需依靠 `HBuilderX`,通过命令行方式运行 `web`、`小程序` 和 `App`(编辑器推荐 `VSCode`,可选 `webstorm`)。
`unibest` 内置了 `约定式路由`、`layout布局`、`请求封装`、`请求拦截`、`登录拦截`、`UnoCSS`、`i18n多语言` 等基础功能,提供了 `代码提示`、`自动格式化`、`统一配置`、`代码片段` 等辅助功能,让你编写 `uniapp` 拥有 `best` 体验 `unibest 的由来`)。
![](https://raw.githubusercontent.com/andreasbm/readme/master/screenshots/lines/rainbow.png)
<p align="center">
<a href="https://unibest.tech/" target="_blank">📖 文档地址(new)</a>
<span style="margin:0 10px;">|</span>
<a href="https://feige996.github.io/hello-unibest/" target="_blank">📱 DEMO 地址</a>
</p>
---
注意旧的地址 [codercup](https://github.com/codercup/unibest) 我进不去了,使用新的 [feige996](https://github.com/feige996/unibest)。PR和 issue 也请使用新地址,否则无法合并。
六维志愿小程序
## 平台兼容性
@ -79,16 +36,3 @@
- web平台 `pnpm build:h5`,打包后的文件在 `dist/build/h5`可以放到web服务器如nginx运行。如果最终不是放在根目录可以在 `manifest.config.ts` 文件的 `h5.router.base` 属性进行修改。
- weixin平台`pnpm build:mp-weixin`, 打包后的文件在 `dist/build/mp-weixin`,然后通过微信开发者工具导入,并点击右上角的“上传”按钮进行上传。
- APP平台`pnpm build:app`, 然后打开 `HBuilderX`,导入刚刚生成的`dist/build/app` 文件夹,选择发行 - APP云打包。
## 📄 License
[MIT](https://opensource.org/license/mit/)
Copyright (c) 2025 菲鸽
## 捐赠
<p align='center'>
<img alt="special sponsor appwrite" src="./screenshots/pay-1.png" height="330" style="display:inline-block; height:330px;">
<img alt="special sponsor appwrite" src="./screenshots/pay-2.png" height="330" style="display:inline-block; height:330px; margin-left:10px;">
</p>

View File

@ -161,6 +161,14 @@ export default defineUniPages({
navigationBarTitleText: '城市',
},
},
{
path: 'pages/home/schoolRank/index',
type: 'page',
style: {
navigationStyle: 'custom',
navigationBarTitleText: '院校排行榜',
},
},
{
path: 'pages/customerService/index/index',
type: 'page',

View File

@ -1,32 +1,4 @@
<template>
<!-- <view
class="tabbar-container fixed bottom-0 left-0 w-full h-[120rpx] flex items-center justify-around text-[#999999] z-[200] bg-white py-[10rpx] px-0"
:style="`padding-bottom:${safeAreaInsets.bottom}px;`"
>
<block class="flex items-center w-full">
<view
class="tabbar-item h-[100rpx] flex flex-col justify-center w-full items-center text-center"
v-for="(item, index) in tabbarList"
:key="index"
:class="[item.centerItem ? 'center-item' : '']"
@click.stop="changeItem(item)"
>
<view class="item-top w-[48rpx] h-[48rpx] p-[10rpx]">
<image
class="w-full h-full object-container"
:src="currentPage == item.id ? item.selectIcon : item.icon"
></image>
</view>
<view
class="item-bottom text-[20rpx] mt-[6rpx]"
:class="[currentPage == item.id ? 'item-active text-[#3370ff]' : '']"
>
<text>{{ item.text }}</text>
</view>
</view>
</block>
</view> -->
<wd-tabbar :bordered="false" safeAreaInsetBottom :placeholder="true" fixed>
<view
class="tabbar-item h-[100rpx] flex flex-col justify-center w-full items-center text-center"
@ -54,9 +26,6 @@
<script setup lang="ts">
import { TabesItem } from '@/service/app/types'
import { tabbarList } from '@/hooks/useTabbarList'
import useNavbarWeixin from '@/hooks/useNavbarWeixin'
const { safeAreaInsets } = useNavbarWeixin()
const tabbar = ref(1)
@ -73,7 +42,7 @@ const changeItem = (item: TabesItem) => {
})
}
onBeforeMount(() => {
onMounted(() => {
uni.hideTabBar()
})
</script>

View File

@ -1,5 +1,5 @@
<template>
<wd-fab :draggable="true" :expandable="false" :gap="{ bottom: 200 }">
<wd-fab :draggable="true" :expandable="false" :gap="{ bottom: 170 }">
<template #trigger>
<view class="btn-wrapper" @click.stop="handleClick">
<image

View File

@ -20,6 +20,7 @@
:hover-stop-propagation="false"
v-for="item in swiperList"
:key="item.id"
@click="toSchool(item.type)"
>
<text class="font-semibold text-[#303030] text-[32rpx] inline-block">
{{ item.name }}
@ -57,6 +58,12 @@ const swiperList = [
{ id: 3, name: '软科', type: '3' },
{ id: 4, name: 'QS', type: '4' },
]
const toSchool = (id: string) => {
uni.navigateTo({
url: `/pages/home/schoolRank/index?type=${id}`,
})
}
</script>
<style lang="scss" scoped>

View File

@ -0,0 +1,79 @@
<script setup>
import { onMounted, reactive, ref } from 'vue'
// virBox -- list
const virHeight = ref(0)
const itemHeight = 40
const listObj = reactive({
list: [], //
totalList: [], // myList
})
const transY = ref(0)
onMounted(() => {
const myList = []
for (let i = 0; i < 10000; i++) {
myList.push(i) //
}
listObj.totalList = myList // myList 访
listObj.list = myList.slice(0, 30) // 5
virHeight.value = itemHeight * myList.length // scrollBox -- virBox = *
})
const onScroll = (e) => {
// e.detail.scrollTop uniapp scroll-view
const scrollTop = e.detail.scrollTop
console.log('滚动位置:', scrollTop)
//
const start = Math.floor(scrollTop / itemHeight)
const end = Math.ceil((scrollTop + 200) / itemHeight) // 5
//
listObj.list = listObj.totalList.slice(start, end)
//
transY.value = scrollTop
}
</script>
<template>
<!-- 使用 scroll-view 组件来实现滚动 -->
<scroll-view class="scrollBox" scroll-y="true" @scroll="onScroll">
<!-- 虚拟滚动容器不需要实际渲染内容 -->
<view class="virBox" :style="{ height: this.virHeight * 2 + 'rpx' }"></view>
<!-- 列表渲染 -->
<view class="list" :style="{ transform: `translateY(${this.transY * 2}rpx)` }">
<view class="item" v-for="item in listObj.list" :key="item">
{{ item }}
</view>
</view>
</scroll-view>
</template>
<style>
.scrollBox {
position: relative;
width: 100%;
height: 100%;
overflow-y: scroll;
}
.virBox {
width: 100%;
height: 100%;
}
.list {
position: absolute;
top: 0rpx;
left: 0rpx;
width: 100%;
height: 100%;
background: violet;
}
.item {
height: 80rpx;
line-height: 80rpx;
}
</style>

View File

@ -1,5 +1,7 @@
import { getVolunteerInitialization } from '@/service/index/api'
import { useCityStore } from '@/store/city'
import { useUserStore } from '@/store/user'
import { City } from '@/types/app-type'
import { pinyin } from 'pinyin-pro'
interface Province {
@ -7,6 +9,7 @@ interface Province {
}
const cityStore = useCityStore()
const userStore = useUserStore()
export const cities = []
export const useCityInfo = () => {
@ -16,7 +19,9 @@ export const useCityInfo = () => {
const li = groupByFirstLetter(list)
cityStore.setCities(li)
const defaultCity = list.filter((item) => item.provincename === '山东省')[0] as City
cityStore.setUserCity(defaultCity)
if (userStore.userInfo.city.code === '0') {
userStore.setUserCity(defaultCity)
}
}
})
}

27
src/hooks/useRules.ts Normal file
View File

@ -0,0 +1,27 @@
import { getCountryRules } from '@/service/index/api'
import { useRulesStore } from '@/store/rules'
import { useUserStore } from '@/store/user'
import { RuleResult } from '@/types/app-type'
const rulesStore = useRulesStore()
const userStore = useUserStore()
export const requireSubjectList = ref([])
export const optionalSubjectList = ref([])
// 单选 必选学科
export const requireSubject = ref('')
// 任意选择科目
export const optionalSubject = ref([])
export const useRules = () => {
getCountryRules().then((res) => {
if (res.code === 200) {
const results = res.result as RuleResult[]
rulesStore.setRules(results)
const matchRule = results.filter((item) => item.p === userStore.userInfo.city.policy)
const matchRules = matchRule.length > 0 ? matchRule[0].rule : []
requireSubjectList.value = matchRules.filter((item) => item?.isfirst === 'true')
optionalSubjectList.value = matchRules.filter((item) => !(item?.isfirst === 'true'))
}
})
}

View File

@ -159,6 +159,14 @@
"navigationBarTitleText": "排名"
}
},
{
"path": "pages/home/schoolRank/index",
"type": "page",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "院校排行榜"
}
},
{
"path": "pages/news/index/index",
"type": "page",

View File

@ -19,8 +19,11 @@
<script lang="ts" setup>
import { useCityStore } from '@/store/city'
import { useUserStore } from '@/store'
import { City } from '@/types/app-type'
const cityStore = useCityStore()
const userStore = useUserStore()
const cities = cityStore.userCity.cities ?? []
@ -29,7 +32,7 @@ const navigatorBack = () => {
}
const chooseCity = (city: City) => {
cityStore.setUserCity(city)
userStore.setUserCity(city)
navigatorBack()
}
</script>

View File

@ -1,19 +1,15 @@
<route lang="json5" type="home">
{
style: {
navigationStyle: 'custom',
},
}
</route>
<template>
<scroll-view class="" :scroll-y="true">
<view class="gradient-background relative">
<wd-navbar safeAreaInsetTop custom-class="bg-transparent!" :bordered="false">
<template #left>
<navigator open-type="navigate" class="left-icon" url="/pages/home/city/index">
<text class="color-[#303030] font-[28rpx] font-medium">
{{ cityStore.userCity.city.provincename }}
<text
class="color-[#303030] font-[28rpx] font-medium"
:selectable="false"
:decode="false"
>
{{ userStore.userInfo.city.provincename ?? '城市' }}
</text>
</navigator>
</template>
@ -42,7 +38,7 @@
<script setup lang="ts">
import TabBar from '@/components/bar/TabBar.vue'
import { useCityInfo } from '@/hooks/useCityInfoHook'
import { useCityStore } from '@/store/city'
import { useUserStore } from '@/store'
import Banner from '@/components/home/Banner.vue'
import HomeSubMenu from '@/components/home/SubMenu.vue'
@ -50,7 +46,7 @@ import HotRank from '@/components/home/HotRank.vue'
import Consultation from '@/components/home/Consultation.vue'
import Fab from '@/components/fab/Fab.vue'
const cityStore = useCityStore()
const userStore = useUserStore()
useCityInfo()

View File

@ -1,7 +1,7 @@
<template>
<view class="wraper overflow-hidden flex flex-col" :bordered="false">
<view class="h-screen overflow-hidden flex flex-col bg-[#F8F8F8]" :bordered="false">
<wd-navbar title="成绩填写" left-arrow @click-left="navigatorBack" safeAreaInsetTop></wd-navbar>
<view class="px-[32rpx] pt-[47rpx] flex flex-col bg-[#F8F8F8]" hover-class="none">
<view class="px-[32rpx] pt-[47rpx] flex flex-col" hover-class="none">
<text class="text-[22rpx] text-[#636363] text-normal" :selectable="false" :decode="false">
为了使推荐更准确请您认真填写
</text>
@ -16,9 +16,9 @@
custom-class="mt-[24rpx] rounded-[16rpx] bg-white flex items-center px-[32rpx] py-[24rpx]"
custom-input-class="h-full flex items-center"
type="number"
v-model="value"
v-model="score"
placeholder="请输入分数"
@change="handleChange"
@input="handleChange"
inputmode="numeric"
:focus="true"
:no-border="true"
@ -27,16 +27,207 @@
<text class="" :selectable="false" :decode="false"></text>
</template>
</wd-input>
<wd-picker
custom-class="mt-[16rpx]"
:columns="termList"
value-key="code"
label-key="name"
v-model="term"
@confirm="handleTerm"
/>
</view>
<view class="mt-[32rpx] px-[32rpx]" hover-class="none" v-if="requireSubjectList.length > 0">
<view class="mb-[16rpx]" hover-class="none">
<text class="" :selectable="false" :decode="false">首选科目</text>
<text class="text-[24rpx] text-gray">({{ requireSubjectList.length }}选1)</text>
</view>
<wd-radio-group
v-model="requireSubject"
cell
inline
custom-class="grid md:grid-cols-4 grid-cols-3 gap-[32rpx] justify-items-center bg-[#F8F8F8]!"
checked-color="#1580FF"
>
<wd-radio
v-for="item in requireSubjectList"
:key="item.code"
:value="item.code"
shape="button"
custom-class="w-[152rpx]! h-[76rpx] p-0! mr-0! "
custom-label-class="w-[152rpx]! h-[76rpx]! rounded-[8rpx]! checkbox-item-border"
>
{{ item.name }}
</wd-radio>
</wd-radio-group>
</view>
<view class="mt-[32rpx] px-[32rpx]" hover-class="none">
<view class="mb-[16rpx]" hover-class="none" v-if="requireSubjectList.length > 0">
<text class="" :selectable="false" :decode="false">次选科目</text>
<text class="text-[24rpx] text-gray">
({{ optionalSubjectList.length }}{{ requireSubjectList.length > 0 ? 2 : 3 }})
</text>
</view>
<wd-checkbox-group
v-model="optionalSubject"
custom-class="grid md:grid-cols-4 grid-cols-3 gap-[32rpx] justify-items-center bg-[#F8F8F8]!"
:max="3"
checked-color="#1580FF"
>
<wd-checkbox
v-for="item in optionalSubjectList"
:key="item.code"
:model-value="item.code"
cell
shape="button"
custom-class="w-[152rpx]! h-[76rpx] p-0! mr-0!"
custom-label-class="w-[152rpx]! h-[76rpx]! rounded-[8rpx]! checkbox-item-border bg-white!"
>
{{ item.name }}
</wd-checkbox>
</wd-checkbox-group>
</view>
<wd-button
block
custom-class="mt-auto mb-[32rpx] rounded-[8rpx]! bg-[#1580FF]! mx-[32rpx]"
@click="saveScore"
:disabled="btnFlag < 3"
>
保存
</wd-button>
<view class="bg-white" :style="`height: ${safeAreaInsets.bottom}px`" hover-class="none"></view>
<wd-toast />
</view>
</template>
<script lang="ts" setup>
import useNavbarWeixin from '@/hooks/useNavbarWeixin'
import { useUserStore } from '@/store/user'
import { useRules, requireSubjectList, optionalSubjectList } from '@/hooks/useRules'
import { useToast } from 'wot-design-uni'
const { safeAreaInsets } = useNavbarWeixin()
const toast = useToast()
const userStore = useUserStore()
//
const term = ref(userStore.userInfo.city.lizations[0].code)
const termList = ref<{ name: string; code: number }[]>(userStore.userInfo.city.lizations)
const handleTerm = () => {
//
}
const navigatorBack = () => {
uni.navigateBack()
}
const value = ref('')
//
const score = ref<number | ''>(userStore.userInfo.estimatedAchievement.score)
const handleChange = (e: any) => {
const _score = score.value || 0
if (_score > userStore.userInfo.city.allscore) {
score.value = userStore.userInfo.city?.allscore
}
}
const handleChange = (e: any) => {}
//
const requireSubject = ref(userStore.userInfo.estimatedAchievement.requireSubject?.code || '')
//
const optionalSubject = ref(
userStore.userInfo.estimatedAchievement.optionSubject.map((item) => item.code),
)
//
const btnFlag = computed(() => {
let num = 0
if (requireSubject.value !== '') {
num++
}
num = num + optionalSubject.value.length
return num
})
const unsubscribe = userStore.$onAction(({ name, store, args, after, onError }) => {
const startTime = Date.now()
console.log(`Start "${name}" with params [${args.join(', ')}].`)
after((result) => {
console.log(`Finished "${name}" after ${Date.now() - startTime}ms.\nResult: ${result}.`)
})
onError((error) => {
console.warn(`Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`)
})
})
// manually remove the listener
unsubscribe()
onBeforeMount(() => {
useRules()
})
const saveScore = () => {
if (score.value === '') {
toast.warning('请检查分数')
return
}
const data = {
year: term, //
score: score.value, //
optionalSubject: optionalSubjectList.value.filter((item) =>
optionalSubject.value.includes(item.code),
), //
requireSubject: requireSubject.value, //
cityCode: userStore.userInfo.city.code, // code
}
userStore.setEstimatedAchievement(data)
uni.showToast({
title: '保存成功',
icon: 'none',
})
setTimeout(() => {
uni.navigateBack()
}, 500)
}
</script>
<style lang="scss" scoped>
:deep(.checkbox-item-border) {
border: 2rpx solid #fff;
.wd-icon-check-bold {
display: none;
}
}
:deep(.wd-checkbox.is-button.is-checked .wd-checkbox__label) {
background-color: rgba(21, 128, 255, 0.1) !important;
}
:deep(.wd-radio__label) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
width: 100% !important;
height: 100% !important;
padding: 0 !important;
line-height: unset !important;
background-color: #fff !important;
border-radius: 8rpx !important;
}
:deep(.wd-radio__shape) {
display: none !important;
}
:deep(.wd-radio.is-button.is-checked .wd-radio__label) {
background-color: rgba(21, 128, 255, 0.1) !important;
}
</style>

View File

@ -0,0 +1,115 @@
<template>
<view class="h-screen overflow-hidden flex flex-col bg-[#F8F8F8]">
<view class="relative h-max" hover-class="none" :hover-stop-propagation="false">
<wd-navbar
title="院校排行榜"
left-arrow
@click-left="navigatorBack"
safeAreaInsetTop
:bordered="false"
custom-class="bg-transparent! z-[99]"
></wd-navbar>
<image
class="h-[400rpx] w-full mt-[-40rpx]"
:style="{ marginTop: `-${safeAreaInsets.top * 2}px` }"
src="/static/images/schoolRank/background.svg"
/>
<image
class="h-[78rpx] w-[270rpx] absolute top-[249rpx] left-[102rpx]"
src="/static/images/schoolRank/title.svg"
/>
<image
class="h-[190rpx] w-[190rpx] absolute top-[194rpx] left-[460rpx]"
src="/static/images/schoolRank/trophy.svg"
/>
</view>
<view
class="rank-body flex flex-col items-center justify-center"
hover-class="none"
:hover-stop-propagation="false"
>
<view
class="flex items-center justify-center swiper-box-wrapper mt-[24rpx] px-[32rpx]"
hover-class="none"
:hover-stop-propagation="false"
>
<view
:class="[
'swiper-box',
'flex',
'items-center',
'justify-center',
tab === item.type ? 'active' : '',
]"
hover-class="none"
:hover-stop-propagation="false"
v-for="item in swiperList"
:key="item.id"
@click="tab = item.type"
>
{{ item.name }}
</view>
</view>
<view class="scroll-wrapper" hover-class="none">
<Scroll></Scroll>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
import Scroll from '@/components/scroll/Scroll.vue'
import useNavbarWeixin from '@/hooks/useNavbarWeixin'
const { safeAreaInsets } = useNavbarWeixin()
const navigatorBack = () => {
uni.navigateBack()
}
const swiperList = [
{ id: 1, name: '武书联', type: '1' },
{ id: 2, name: '校友会', type: '2' },
{ id: 3, name: '软科', type: '3' },
{ id: 4, name: 'QS', type: '4' },
]
const tab = ref<string>('1')
onLoad((option) => {
tab.value = option?.type || '1'
})
</script>
<style lang="scss" scoped>
.rank-body {
height: calc(100% - 400rpx);
}
.swiper-box {
width: 160rpx;
height: 52rpx;
font-size: 28rpx;
font-weight: 500;
color: #a28c6c;
background-color: #f5efe1;
border-radius: 8rpx;
}
.swiper-box:not(:last-child) {
margin-right: 16px;
}
.active {
color: #684817;
background: linear-gradient(270deg, #f2ce95 0%, #f8deba 100%);
}
.scroll-wrapper {
flex: 1 1 auto;
width: 100%;
height: 0;
}
</style>

View File

@ -10,5 +10,9 @@ export const sysDictType = (params: any) => {
}
export const getVolunteerInitialization = () => {
return http.get('/api/v1/base/volunteerInitialization.json', { staticType: 'static' })
return http.get('/api/busProvinceInitialization/list')
}
export const getCountryRules = () => {
return http.get('/api/v1/base/rules.json', { staticType: 'static' })
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 42 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 617 KiB

View File

@ -1,16 +1,8 @@
import { IUserCity } from '@/types/app-type'
import { defineStore } from 'pinia'
import { ref } from 'vue'
const initState = {
city: {
allscore: 0,
code: '0',
isopen: 0,
lizations: [{ name: '0', policy: 0, code: 0 }],
policy: 0,
provincename: '',
years: 0,
},
cities: [],
}
@ -19,10 +11,6 @@ export const useCityStore = defineStore(
() => {
const userCity = ref<IUserCity>({ ...initState })
const setUserCity = (val: City) => {
userCity.value.city = val
}
const setCities = (val: Array<any>) => {
userCity.value.cities = val
}
@ -37,7 +25,6 @@ export const useCityStore = defineStore(
return {
userCity,
setUserCity,
clearUserCity,
setCities,

36
src/store/rules.ts Normal file
View File

@ -0,0 +1,36 @@
import { RulesStore } from '@/types/app-type'
import { defineStore } from 'pinia'
const initState = {
rules: [],
}
export const useRulesStore = defineStore(
'rules',
() => {
const store = ref<RulesStore>({ ...initState })
const setRules = (val: Array<any>) => {
store.value.rules = val
}
const clearRules = () => {
store.value = { ...initState }
}
// 一般没有reset需求不需要的可以删除
const reset = () => {
store.value = { ...initState }
}
return {
store,
clearRules,
setRules,
reset,
}
},
{
persist: true,
},
)

View File

@ -1,17 +1,49 @@
import { City, ExtraUserInfo } from '@/types/app-type'
import { defineStore } from 'pinia'
import { ref } from 'vue'
const initState = { nickname: '', avatar: '' }
const initState = {
nickname: '',
avatar: '',
city: {
allscore: 0,
code: '0',
isopen: 0,
lizations: [],
policy: 0,
provincename: '',
years: 0,
},
estimatedAchievement: {
year: 0, // 学期
score: 0, // 成绩
requireSubject: { code: 0, name: '', simplename: '' },
optionSubject: [],
cityCode: 0,
},
}
export const useUserStore = defineStore(
'user',
() => {
const userInfo = ref<IUserInfo>({ ...initState })
const userInfo = ref<ExtraUserInfo>({ ...initState })
const setUserInfo = (val: IUserInfo) => {
// 设置用户信息
const setUserInfo = (val: ExtraUserInfo) => {
userInfo.value = val
}
// 设置用户所在城市
const setUserCity = (val: City) => {
userInfo.value.city = val
}
// 设置预估成绩
const setEstimatedAchievement = (val: any) => {
userInfo.value.estimatedAchievement = val
}
// 清除用户信息
const clearUserInfo = () => {
userInfo.value = { ...initState }
}
@ -27,6 +59,8 @@ export const useUserStore = defineStore(
clearUserInfo,
isLogined,
reset,
setUserCity,
setEstimatedAchievement,
}
},
{

35
src/types/app-type.d.ts vendored Normal file
View File

@ -0,0 +1,35 @@
export type Rule = {
code: number
name: string
simplename: string
isfirst?: string
}
export type RuleResult = { p: number; rule: Rule[] }
export type RulesStore = {
rules: RuleResult[]
}
export type City = {
allscore: number
code: string
isopen: number
lizations: { name: string; policy: number; code: number }[]
policy: number
provincename: string
years: number
}
export type IUserCity = {
cities: Array<{ letter: string; provinces: { id: number; provincename: string } }>
}
export type ExtraUserInfo = {
city?: City
estimatedAchievement: {
year: number
score: number
requireSubject: Rule
optionSubject: Rule[]
}
} & IUserInfo

View File

@ -63,11 +63,16 @@ declare global {
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
const optionalSubject: typeof import('../hooks/useRules')['optionalSubject']
const optionalSubjectList: typeof import('../hooks/useRules')['optionalSubjectList']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const requireSubject: typeof import('../hooks/useRules')['requireSubject']
const requireSubjectList: typeof import('../hooks/useRules')['requireSubjectList']
const resolveComponent: typeof import('vue')['resolveComponent']
const rules: typeof import('../hooks/useRules')['rules']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
@ -86,6 +91,7 @@ declare global {
const useModel: typeof import('vue')['useModel']
const useNavbarWeixin: typeof import('../hooks/useNavbarWeixin')['default']
const useRequest: typeof import('../hooks/useRequest')['default']
const useRules: typeof import('../hooks/useRules')['useRules']
const useSlots: typeof import('vue')['useSlots']
const useTemplateRef: typeof import('vue')['useTemplateRef']
const useUpload: typeof import('../hooks/useUpload')['default']
@ -163,10 +169,14 @@ declare module 'vue' {
readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
readonly onWatcherCleanup: UnwrapRef<typeof import('vue')['onWatcherCleanup']>
readonly optionalSubject: UnwrapRef<typeof import('../hooks/useRules')['optionalSubject']>
readonly optionalSubjectList: UnwrapRef<typeof import('../hooks/useRules')['optionalSubjectList']>
readonly provide: UnwrapRef<typeof import('vue')['provide']>
readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
readonly ref: UnwrapRef<typeof import('vue')['ref']>
readonly requireSubject: UnwrapRef<typeof import('../hooks/useRules')['requireSubject']>
readonly requireSubjectList: UnwrapRef<typeof import('../hooks/useRules')['requireSubjectList']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
@ -186,6 +196,7 @@ declare module 'vue' {
readonly useModel: UnwrapRef<typeof import('vue')['useModel']>
readonly useNavbarWeixin: UnwrapRef<typeof import('../hooks/useNavbarWeixin')['default']>
readonly useRequest: UnwrapRef<typeof import('../hooks/useRequest')['default']>
readonly useRules: UnwrapRef<typeof import('../hooks/useRules')['useRules']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
readonly useTemplateRef: UnwrapRef<typeof import('vue')['useTemplateRef']>
readonly useUpload: UnwrapRef<typeof import('../hooks/useUpload')['default']>

View File

@ -19,6 +19,7 @@ interface NavigateToOptions {
"/pages/home/line/index" |
"/pages/home/major/index" |
"/pages/home/rank/index" |
"/pages/home/schoolRank/index" |
"/pages/news/index/index" |
"/pages/place/index/index" |
"/pages/ucenter/index/index";

14
src/typings.d.ts vendored
View File

@ -23,20 +23,6 @@ declare global {
openid?: string
token?: string
}
type City = {
allscore: number
code: string
isopen: number
lizations: { name: string; policy: number; code: number }[]
policy: number
provincename: string
years: number
}
type IUserCity = {
city: City
cities: Array<{ letter: string; provinces: { id: number; provincename: string } }>
}
}
export {} // 防止模块污染