完善功能、首页、报名、个人中心
This commit is contained in:
parent
c2c83a06ea
commit
9b42afdcfa
@ -1,2 +1,2 @@
|
|||||||
VITE_APP_PREVIEW=false
|
VITE_APP_PREVIEW=false
|
||||||
VITE_APP_API_BASE_URL=https://api.example.com
|
VITE_APP_API_BASE_URL=/api
|
||||||
|
@ -1 +0,0 @@
|
|||||||
node scripts/verifyCommit.js
|
|
@ -1 +0,0 @@
|
|||||||
pnpm lint
|
|
21
package.json
21
package.json
@ -7,15 +7,13 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "cross-env MOCK_SERVER_PORT=8086 vite",
|
"dev": "cross-env MOCK_SERVER_PORT=8086 vite",
|
||||||
"build": "vue-tsc --noEmit && vite build",
|
"build": "vite build",
|
||||||
"build:dev": "vue-tsc --noEmit && vite build --mode=development",
|
"build:dev": "vue-tsc --noEmit && vite build --mode=development",
|
||||||
"preview": "npm run build && vite preview",
|
"preview": "npm run build && vite preview",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"lint:fix": "eslint . --fix",
|
"lint:fix": "eslint . --fix",
|
||||||
"test": "vitest",
|
"test": "vitest",
|
||||||
"release": "bumpp --commit --push --tag",
|
"release": "bumpp --commit --push --tag"
|
||||||
"prepare": "husky",
|
|
||||||
"cz": "git-cz"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@unhead/vue": "^1.8.10",
|
"@unhead/vue": "^1.8.10",
|
||||||
@ -33,6 +31,7 @@
|
|||||||
"vant": "^4.8.4",
|
"vant": "^4.8.4",
|
||||||
"vconsole": "^3.15.1",
|
"vconsole": "^3.15.1",
|
||||||
"vue": "^3.4.15",
|
"vue": "^3.4.15",
|
||||||
|
"vue-cookies": "^1.8.3",
|
||||||
"vue-router": "^4.2.5"
|
"vue-router": "^4.2.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -48,12 +47,9 @@
|
|||||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||||
"autoprefixer": "^10.4.17",
|
"autoprefixer": "^10.4.17",
|
||||||
"bumpp": "^9.3.0",
|
"bumpp": "^9.3.0",
|
||||||
"commitizen": "^4.3.0",
|
|
||||||
"consola": "^3.2.3",
|
"consola": "^3.2.3",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"cz-emoji-chinese": "^0.3.1",
|
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"husky": "^9.0.10",
|
|
||||||
"less": "^4.2.0",
|
"less": "^4.2.0",
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"postcss-mobile-forever": "^4.1.1",
|
"postcss-mobile-forever": "^4.1.1",
|
||||||
@ -82,16 +78,5 @@
|
|||||||
"rollup": "^4.x"
|
"rollup": "^4.x"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"commitizen": {
|
|
||||||
"path": "./node_modules/cz-emoji-chinese"
|
|
||||||
},
|
|
||||||
"cz-emoji-chinese": {
|
|
||||||
"skipQuestions": [
|
|
||||||
"body",
|
|
||||||
"scope"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
915
pnpm-lock.yaml
915
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
23
src/api/user.ts
Normal file
23
src/api/user.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据openid获取参会用户信息
|
||||||
|
*/
|
||||||
|
export function getApplyInfoByOpenId(data: { openId: string, miceLink: string }) {
|
||||||
|
return request({
|
||||||
|
method: 'post',
|
||||||
|
url: '/backstageApply/getByOpenId',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据手机号获取参会用户信息
|
||||||
|
*/
|
||||||
|
export function getApplyInfoByPhone(data: { phone: string, miceLink: string }) {
|
||||||
|
return request({
|
||||||
|
method: 'post',
|
||||||
|
url: '/backstageApply/getByPhone',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
@ -10,3 +10,40 @@ export function getWeixinSignature(url: string) {
|
|||||||
data: { url },
|
data: { url },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拉取用户信息
|
||||||
|
*/
|
||||||
|
export function userSign(code: string) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('code', code)
|
||||||
|
return request({
|
||||||
|
method: 'post',
|
||||||
|
url: '/wx/getUserInfoBycode',
|
||||||
|
data: formData,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* openid获取用户信息
|
||||||
|
*/
|
||||||
|
export function getUserInfoByOpenId(openid: any) {
|
||||||
|
return request({
|
||||||
|
method: 'get',
|
||||||
|
url: `/wxUser/getInfoByOpenId/${openid}`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* openid 是否已经参会
|
||||||
|
*/
|
||||||
|
export function openidIsApply(data: { openId: string, miceLink: string }) {
|
||||||
|
return request({
|
||||||
|
method: 'post',
|
||||||
|
url: '/backstageApply/openIdIsApply',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
3
src/auto-imports.d.ts
vendored
3
src/auto-imports.d.ts
vendored
@ -43,6 +43,7 @@ declare global {
|
|||||||
const expect: typeof import('vitest')['expect']
|
const expect: typeof import('vitest')['expect']
|
||||||
const extendRef: typeof import('@vueuse/core')['extendRef']
|
const extendRef: typeof import('@vueuse/core')['extendRef']
|
||||||
const getActiveHead: typeof import('@unhead/vue')['getActiveHead']
|
const getActiveHead: typeof import('@unhead/vue')['getActiveHead']
|
||||||
|
const getCookie: typeof import('./composables/cookie')['getCookie']
|
||||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||||
const getUrlMiceLink: typeof import('./composables/mice')['getUrlMiceLink']
|
const getUrlMiceLink: typeof import('./composables/mice')['getUrlMiceLink']
|
||||||
@ -97,9 +98,11 @@ declare global {
|
|||||||
const refDefault: typeof import('@vueuse/core')['refDefault']
|
const refDefault: typeof import('@vueuse/core')['refDefault']
|
||||||
const refThrottled: typeof import('@vueuse/core')['refThrottled']
|
const refThrottled: typeof import('@vueuse/core')['refThrottled']
|
||||||
const refWithControl: typeof import('@vueuse/core')['refWithControl']
|
const refWithControl: typeof import('@vueuse/core')['refWithControl']
|
||||||
|
const removeCookie: typeof import('./composables/cookie')['removeCookie']
|
||||||
const resolveComponent: typeof import('vue')['resolveComponent']
|
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||||
const resolveRef: typeof import('@vueuse/core')['resolveRef']
|
const resolveRef: typeof import('@vueuse/core')['resolveRef']
|
||||||
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
|
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
|
||||||
|
const setCookie: typeof import('./composables/cookie')['setCookie']
|
||||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||||
const shallowRef: typeof import('vue')['shallowRef']
|
const shallowRef: typeof import('vue')['shallowRef']
|
||||||
|
8
src/components.d.ts
vendored
8
src/components.d.ts
vendored
@ -7,22 +7,14 @@ export {}
|
|||||||
|
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
Chart: typeof import('./components/chart/index.vue')['default']
|
|
||||||
Container: typeof import('./components/container/index.vue')['default']
|
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
VanButton: typeof import('vant/es')['Button']
|
VanButton: typeof import('vant/es')['Button']
|
||||||
VanCell: typeof import('vant/es')['Cell']
|
|
||||||
VanCellGroup: typeof import('vant/es')['CellGroup']
|
|
||||||
VanCheckbox: typeof import('vant/es')['Checkbox']
|
VanCheckbox: typeof import('vant/es')['Checkbox']
|
||||||
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
|
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
|
||||||
VanEmpty: typeof import('vant/es')['Empty']
|
|
||||||
VanField: typeof import('vant/es')['Field']
|
VanField: typeof import('vant/es')['Field']
|
||||||
VanForm: typeof import('vant/es')['Form']
|
VanForm: typeof import('vant/es')['Form']
|
||||||
VanIcon: typeof import('vant/es')['Icon']
|
VanIcon: typeof import('vant/es')['Icon']
|
||||||
VanNavBar: typeof import('vant/es')['NavBar']
|
|
||||||
VanSpace: typeof import('vant/es')['Space']
|
|
||||||
VanSwitch: typeof import('vant/es')['Switch']
|
|
||||||
VanTag: typeof import('vant/es')['Tag']
|
VanTag: typeof import('vant/es')['Tag']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import useMiceStore from '@/stores/modules/mice'
|
import useMiceStore from '@/stores/modules/mice'
|
||||||
|
import useUserStore from '@/stores/modules/user'
|
||||||
|
|
||||||
const miceInfoStore = useMiceStore()
|
const miceInfoStore = useMiceStore()
|
||||||
|
const { getOpenId } = useUserStore()
|
||||||
|
|
||||||
onMounted(() => {
|
getOpenId()
|
||||||
const miceeLink = getUrlMiceLink()
|
const miceeLink = getUrlMiceLink()
|
||||||
miceInfoStore.initMiceInfo(miceeLink)
|
miceInfoStore.initMiceInfo(miceeLink)
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import { createHead } from '@unhead/vue'
|
import { createHead } from '@unhead/vue'
|
||||||
|
import VueCookies from 'vue-cookies'
|
||||||
import App from '@/App.vue'
|
import App from '@/App.vue'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import pinia from '@/stores'
|
import pinia from '@/stores'
|
||||||
|
|
||||||
import 'virtual:uno.css'
|
import 'virtual:uno.css'
|
||||||
import '@/styles/app.less'
|
import '@/styles/app.less'
|
||||||
|
|
||||||
@ -23,6 +25,9 @@ import 'vant/es/image-preview/style'
|
|||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
const head = createHead()
|
const head = createHead()
|
||||||
|
|
||||||
|
// app.config.globalProperties.$cookies = VueCookies
|
||||||
|
app.provide('$cookies', VueCookies)
|
||||||
|
|
||||||
app.use(head)
|
app.use(head)
|
||||||
app.use(router)
|
app.use(router)
|
||||||
app.use(pinia)
|
app.use(pinia)
|
||||||
|
@ -7,7 +7,7 @@ import 'nprogress/nprogress.css'
|
|||||||
NProgress.configure({ showSpinner: true, parent: '#app' })
|
NProgress.configure({ showSpinner: true, parent: '#app' })
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.VITE_APP_PUBLIC_PATH),
|
history: createWebHistory(),
|
||||||
routes,
|
routes,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -26,6 +26,15 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
title: '报名',
|
title: '报名',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// 个人中心
|
||||||
|
{
|
||||||
|
path: 'user/:miceLink',
|
||||||
|
name: 'User',
|
||||||
|
component: () => import('@/views/user/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '个人中心',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -7,7 +7,14 @@ import { getMiceInfo } from '@/api/mice'
|
|||||||
const useMiceStore = defineStore('mice', () => {
|
const useMiceStore = defineStore('mice', () => {
|
||||||
const miceInfo = ref<any>({})
|
const miceInfo = ref<any>({})
|
||||||
|
|
||||||
|
// 初始化会议信息
|
||||||
function initMiceInfo(miceLink: string) {
|
function initMiceInfo(miceLink: string) {
|
||||||
|
if (!miceLink)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (miceInfo.value.linkName)
|
||||||
|
return
|
||||||
|
|
||||||
getMiceInfo({ miceLink }).then((res) => {
|
getMiceInfo({ miceLink }).then((res) => {
|
||||||
miceInfo.value = res
|
miceInfo.value = res
|
||||||
})
|
})
|
||||||
|
83
src/stores/modules/user.ts
Normal file
83
src/stores/modules/user.ts
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import type { VueCookies } from 'vue-cookies'
|
||||||
|
import { getUserInfoByOpenId, userSign } from '@/api/weixin'
|
||||||
|
import { getApplyInfoByOpenId } from '@/api/user'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会议信息
|
||||||
|
*/
|
||||||
|
const useUserStore = defineStore('user', () => {
|
||||||
|
const wxInfo = ref<any>({})
|
||||||
|
const router = useRouter()
|
||||||
|
const openId = ref('')
|
||||||
|
const userInfo = ref<any>({})
|
||||||
|
const applyInfo = ref<any>({})
|
||||||
|
|
||||||
|
// 获取openid
|
||||||
|
async function getOpenId() {
|
||||||
|
const APPID = 'wxa4d8f4b7c43cdf40'
|
||||||
|
const cookies = inject<VueCookies>('$cookies')
|
||||||
|
|
||||||
|
let user = {} as any
|
||||||
|
user = cookies.get('user')
|
||||||
|
// user = {
|
||||||
|
// openid: 'o_CUl6J2TlFYLbnTp8PqWle-DUSQ',
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 如果没有openId,跳转到授权页面
|
||||||
|
if (!user || !user.openid) {
|
||||||
|
if (!router.currentRoute.value.query.code) {
|
||||||
|
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${APPID}&redirect_uri=${window.location.href.split('#')[0]}&response_type=code&scope=snsapi_userinfo#wechat_redirect`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const code = router.currentRoute.value.query.code as string
|
||||||
|
// 获取微信用户信息
|
||||||
|
userSign(code).then((res: any) => {
|
||||||
|
cookies.set('user', JSON.stringify(res))
|
||||||
|
wxInfo.value = res
|
||||||
|
openId.value = res.openid
|
||||||
|
getUserInfo()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
openId.value = user.openid
|
||||||
|
wxInfo.value = user
|
||||||
|
getUserInfo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取参会用户信息
|
||||||
|
function getUserInfo() {
|
||||||
|
getUserInfoByOpenId(openId.value).then((res: any) => {
|
||||||
|
userInfo.value = res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据手机号获取参会信息
|
||||||
|
// function getApplyInfoByPhone() {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 根据openid获取参会信息
|
||||||
|
function getApplyUserInfo(miceLink) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
getApplyInfoByOpenId({ openId: openId.value, miceLink }).then((res: any) => {
|
||||||
|
applyInfo.value = res.backstageApply
|
||||||
|
resolve(res.backstageApply)
|
||||||
|
}).catch((err) => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
wxInfo,
|
||||||
|
openId,
|
||||||
|
userInfo,
|
||||||
|
getOpenId,
|
||||||
|
getApplyUserInfo,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default useUserStore
|
145
src/typed-router.d.ts
vendored
145
src/typed-router.d.ts
vendored
@ -1,145 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
/* prettier-ignore */
|
|
||||||
// @ts-nocheck
|
|
||||||
// Generated by unplugin-vue-router. ‼️ DO NOT MODIFY THIS FILE ‼️
|
|
||||||
// It's recommended to commit this file.
|
|
||||||
// Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry.
|
|
||||||
|
|
||||||
/// <reference types="unplugin-vue-router/client" />
|
|
||||||
|
|
||||||
import type {
|
|
||||||
// type safe route locations
|
|
||||||
RouteLocationTypedList,
|
|
||||||
RouteLocationResolvedTypedList,
|
|
||||||
RouteLocationNormalizedTypedList,
|
|
||||||
RouteLocationNormalizedLoadedTypedList,
|
|
||||||
RouteLocationAsString,
|
|
||||||
RouteLocationAsRelativeTypedList,
|
|
||||||
RouteLocationAsPathTypedList,
|
|
||||||
|
|
||||||
// helper types
|
|
||||||
// route definitions
|
|
||||||
RouteRecordInfo,
|
|
||||||
ParamValue,
|
|
||||||
ParamValueOneOrMore,
|
|
||||||
ParamValueZeroOrMore,
|
|
||||||
ParamValueZeroOrOne,
|
|
||||||
|
|
||||||
// vue-router extensions
|
|
||||||
_RouterTyped,
|
|
||||||
RouterLinkTyped,
|
|
||||||
RouterLinkPropsTyped,
|
|
||||||
NavigationGuard,
|
|
||||||
UseLinkFnTyped,
|
|
||||||
|
|
||||||
// data fetching
|
|
||||||
_DataLoader,
|
|
||||||
_DefineLoaderOptions,
|
|
||||||
} from 'unplugin-vue-router/types'
|
|
||||||
|
|
||||||
declare module 'vue-router/auto/routes' {
|
|
||||||
export interface RouteNamedMap {
|
|
||||||
export interface RouteNamedMap {
|
|
||||||
'//': RouteRecordInfo<'//', '/', Record<never, never>, Record<never, never>>,
|
|
||||||
} '/signUp/': RouteRecordInfo<'/signUp/', '/signUp', Record<never, never>, Record<never, never>>,
|
|
||||||
'/signUp/components/FormItem': RouteRecordInfo<'/signUp/components/FormItem', '/signUp/components/FormItem', Record<never, never>, Record<never, never>>,
|
|
||||||
'/signUp/components/SignForm': RouteRecordInfo<'/signUp/components/SignForm', '/signUp/components/SignForm', Record<never, never>, Record<never, never>>,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module 'vue-router/auto' {
|
|
||||||
import type { RouteNamedMap } from 'vue-router/auto/routes'
|
|
||||||
|
|
||||||
export type RouterTyped = _RouterTyped<RouteNamedMap>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type safe version of `RouteLocationNormalized` (the type of `to` and `from` in navigation guards).
|
|
||||||
* Allows passing the name of the route to be passed as a generic.
|
|
||||||
*/
|
|
||||||
export type RouteLocationNormalized<Name extends keyof RouteNamedMap = keyof RouteNamedMap> = RouteLocationNormalizedTypedList<RouteNamedMap>[Name]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type safe version of `RouteLocationNormalizedLoaded` (the return type of `useRoute()`).
|
|
||||||
* Allows passing the name of the route to be passed as a generic.
|
|
||||||
*/
|
|
||||||
export type RouteLocationNormalizedLoaded<Name extends keyof RouteNamedMap = keyof RouteNamedMap> = RouteLocationNormalizedLoadedTypedList<RouteNamedMap>[Name]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type safe version of `RouteLocationResolved` (the returned route of `router.resolve()`).
|
|
||||||
* Allows passing the name of the route to be passed as a generic.
|
|
||||||
*/
|
|
||||||
export type RouteLocationResolved<Name extends keyof RouteNamedMap = keyof RouteNamedMap> = RouteLocationResolvedTypedList<RouteNamedMap>[Name]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type safe version of `RouteLocation` . Allows passing the name of the route to be passed as a generic.
|
|
||||||
*/
|
|
||||||
export type RouteLocation<Name extends keyof RouteNamedMap = keyof RouteNamedMap> = RouteLocationTypedList<RouteNamedMap>[Name]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type safe version of `RouteLocationRaw` . Allows passing the name of the route to be passed as a generic.
|
|
||||||
*/
|
|
||||||
export type RouteLocationRaw<Name extends keyof RouteNamedMap = keyof RouteNamedMap> =
|
|
||||||
| RouteLocationAsString<RouteNamedMap>
|
|
||||||
| RouteLocationAsRelativeTypedList<RouteNamedMap>[Name]
|
|
||||||
| RouteLocationAsPathTypedList<RouteNamedMap>[Name]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a type safe params for a route location. Requires the name of the route to be passed as a generic.
|
|
||||||
*/
|
|
||||||
export type RouteParams<Name extends keyof RouteNamedMap> = RouteNamedMap[Name]['params']
|
|
||||||
/**
|
|
||||||
* Generate a type safe raw params for a route location. Requires the name of the route to be passed as a generic.
|
|
||||||
*/
|
|
||||||
export type RouteParamsRaw<Name extends keyof RouteNamedMap> = RouteNamedMap[Name]['paramsRaw']
|
|
||||||
|
|
||||||
export function useRouter(): RouterTyped
|
|
||||||
export function useRoute<Name extends keyof RouteNamedMap = keyof RouteNamedMap>(name?: Name): RouteLocationNormalizedLoadedTypedList<RouteNamedMap>[Name]
|
|
||||||
|
|
||||||
export const useLink: UseLinkFnTyped<RouteNamedMap>
|
|
||||||
|
|
||||||
export function onBeforeRouteLeave(guard: NavigationGuard<RouteNamedMap>): void
|
|
||||||
export function onBeforeRouteUpdate(guard: NavigationGuard<RouteNamedMap>): void
|
|
||||||
|
|
||||||
export const RouterLink: RouterLinkTyped<RouteNamedMap>
|
|
||||||
export const RouterLinkProps: RouterLinkPropsTyped<RouteNamedMap>
|
|
||||||
|
|
||||||
// Experimental Data Fetching
|
|
||||||
|
|
||||||
export function defineLoader<
|
|
||||||
P extends Promise<any>,
|
|
||||||
Name extends keyof RouteNamedMap = keyof RouteNamedMap,
|
|
||||||
isLazy extends boolean = false,
|
|
||||||
>(
|
|
||||||
name: Name,
|
|
||||||
loader: (route: RouteLocationNormalizedLoaded<Name>) => P,
|
|
||||||
options?: _DefineLoaderOptions<isLazy>,
|
|
||||||
): _DataLoader<Awaited<P>, isLazy>
|
|
||||||
export function defineLoader<
|
|
||||||
P extends Promise<any>,
|
|
||||||
isLazy extends boolean = false,
|
|
||||||
>(
|
|
||||||
loader: (route: RouteLocationNormalizedLoaded) => P,
|
|
||||||
options?: _DefineLoaderOptions<isLazy>,
|
|
||||||
): _DataLoader<Awaited<P>, isLazy>
|
|
||||||
|
|
||||||
export {
|
|
||||||
_definePage as definePage,
|
|
||||||
_HasDataLoaderMeta as HasDataLoaderMeta,
|
|
||||||
_setupDataFetchingGuard as setupDataFetchingGuard,
|
|
||||||
_stopDataFetchingScope as stopDataFetchingScope,
|
|
||||||
} from 'unplugin-vue-router/runtime'
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module 'vue-router' {
|
|
||||||
import type { RouteNamedMap } from 'vue-router/auto/routes'
|
|
||||||
|
|
||||||
export interface TypesConfig {
|
|
||||||
beforeRouteUpdate: NavigationGuard<RouteNamedMap>
|
|
||||||
beforeRouteLeave: NavigationGuard<RouteNamedMap>
|
|
||||||
|
|
||||||
$route: RouteLocationNormalizedLoadedTypedList<RouteNamedMap>[keyof RouteNamedMap]
|
|
||||||
$router: _RouterTyped<RouteNamedMap>
|
|
||||||
|
|
||||||
RouterLink: RouterLinkTyped<RouteNamedMap>
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,9 +12,9 @@ const miceInfoStore = useMiceStore()
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<img
|
<img
|
||||||
class="w-full"
|
class="h-200 w-full"
|
||||||
fit="contain"
|
fit="contain"
|
||||||
src="https://sn202108-1305501521.cos.ap-shanghai.myqcloud.com/202401162355044675902.jpg"
|
:src="miceInfoStore.miceInfo.posters"
|
||||||
>
|
>
|
||||||
<!-- 会议标题 -->
|
<!-- 会议标题 -->
|
||||||
<div class="van-hairline--bottom my-0 px-10 py-5 font-bold">
|
<div class="van-hairline--bottom my-0 px-10 py-5 font-bold">
|
||||||
@ -28,29 +28,34 @@ const miceInfoStore = useMiceStore()
|
|||||||
<van-tag plain type="primary">
|
<van-tag plain type="primary">
|
||||||
报名
|
报名
|
||||||
</van-tag>
|
</van-tag>
|
||||||
<span>2024-01-16 23:55:04</span>
|
<span v-if="miceInfoStore.miceInfo.regStartTime">{{ miceInfoStore.miceInfo.regStartTime.substr(0, 16) }} - {{ miceInfoStore.miceInfo.registerDeadline.substr(0, 16) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mice-info-item">
|
<div class="mice-info-item">
|
||||||
<van-icon name="clock-o" />
|
<van-icon name="clock-o" />
|
||||||
<van-tag plain type="primary">
|
<van-tag plain type="primary">
|
||||||
活动
|
活动
|
||||||
</van-tag>
|
</van-tag>
|
||||||
<span>2024-01-16 23:55:04</span>
|
<span v-if="miceInfoStore.miceInfo.startTime">{{ miceInfoStore.miceInfo.startTime.substr(0, 16) }} - {{ miceInfoStore.miceInfo.endTime.substr(0, 16) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mice-info-item">
|
<div class="mice-info-item">
|
||||||
<van-icon name="location-o" />
|
<van-icon name="location-o" />
|
||||||
<span>上海xxx</span>
|
<span v-if="miceInfoStore.miceInfo.address">
|
||||||
|
{{ JSON.parse(miceInfoStore.miceInfo.address).place }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mice-info-item">
|
<div v-if="miceInfoStore.miceInfo.phone" class="mice-info-item">
|
||||||
<van-icon name="phone-o" />
|
<van-icon name="phone-o" />
|
||||||
<span>12345678901</span>
|
<div>{{ JSON.parse(miceInfoStore.miceInfo.phone)[0].phone }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- <div class="phone-list" style="text-indent: 22px;">
|
||||||
|
12345678901
|
||||||
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 报名人数 -->
|
<!-- 报名人数 -->
|
||||||
<div class="sign-num van-hairline--bottom p-10 text-2xl">
|
<div class="van-hairline--bottom sign-num p-10 text-2xl">
|
||||||
<span>已报名</span>
|
<span>已报名</span>
|
||||||
<span>10人</span>
|
<span>{{ miceInfoStore.miceInfo.applyCount || 0 }}人</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 空白 -->
|
<!-- 空白 -->
|
||||||
@ -61,16 +66,16 @@ const miceInfoStore = useMiceStore()
|
|||||||
<div class="van-hairline--bottom p-10 font-semibold">
|
<div class="van-hairline--bottom p-10 font-semibold">
|
||||||
会议简介
|
会议简介
|
||||||
</div>
|
</div>
|
||||||
<div class="p-10" v-html="miceInfoStore.miceInfo.description" />
|
<div class="inner-html p-10" v-html="miceInfoStore.miceInfo.description" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 底部操作栏 -->
|
<!-- 底部操作栏 -->
|
||||||
<div class="bottom-actions">
|
<div class="bottom-actions">
|
||||||
<div class="bottom-item">
|
<div class="bottom-item bg-white" @click="$router.push(`/user/${miceInfoStore.miceInfo.linkName}`)">
|
||||||
<van-icon name="user-o" />
|
<van-icon name="user-o" />
|
||||||
<span>个人中心</span>
|
<span>个人中心</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sign">
|
<div class="sign" @click="$router.push(`/signUp/${miceInfoStore.miceInfo.linkName}`)">
|
||||||
立即报名
|
立即报名
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -126,4 +131,12 @@ const miceInfoStore = useMiceStore()
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inner-html {
|
||||||
|
padding-bottom: 60px;
|
||||||
|
:deep(img) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -3,18 +3,19 @@ import type { PropType } from 'vue'
|
|||||||
import { showToast } from 'vant'
|
import { showToast } from 'vant'
|
||||||
import FormItem from './FormItem.vue'
|
import FormItem from './FormItem.vue'
|
||||||
import { getSignUpFormConfig, signUp, smsSend } from '@/api/mice'
|
import { getSignUpFormConfig, signUp, smsSend } from '@/api/mice'
|
||||||
|
import useUserStore from '@/stores/modules/user'
|
||||||
|
|
||||||
const form = defineModel({
|
const form = defineModel({
|
||||||
type: Object as PropType<any>,
|
type: Object as PropType<any>,
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
|
const userStore = useUserStore()
|
||||||
|
const miceLink = getUrlMiceLink()
|
||||||
|
|
||||||
// 表单配置项
|
// 表单配置项
|
||||||
const formConfigs = ref<any[]>([])
|
const formConfigs = ref<any[]>([])
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const miceLink = getUrlMiceLink()
|
|
||||||
form.value.miceLink = miceLink
|
|
||||||
getSignUpFormConfig({ miceLink }).then((res: any) => {
|
getSignUpFormConfig({ miceLink }).then((res: any) => {
|
||||||
formConfigs.value = res
|
formConfigs.value = res
|
||||||
})
|
})
|
||||||
@ -22,8 +23,10 @@ onMounted(() => {
|
|||||||
|
|
||||||
// 提交注册报名
|
// 提交注册报名
|
||||||
function onSubmit() {
|
function onSubmit() {
|
||||||
signUp(form.value).then((res: any) => {
|
form.value.miceLink = miceLink
|
||||||
console.log(res)
|
form.value.openId = userStore.openId
|
||||||
|
signUp(form.value).then(() => {
|
||||||
|
// console.log(res)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,8 +35,8 @@ async function sendSmsHandler() {
|
|||||||
if (!form.value.phone || !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(form.value.phone)) {
|
if (!form.value.phone || !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(form.value.phone)) {
|
||||||
return showToast('请输入正确的手机号')
|
return showToast('请输入正确的手机号')
|
||||||
}
|
}
|
||||||
const res = await smsSend(form.value.phone)
|
await smsSend(form.value.phone)
|
||||||
console.log(res)
|
// console.log(res)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,8 +1,35 @@
|
|||||||
<script setup lang="ts" name="SignUp">
|
<script setup lang="ts" name="SignUp">
|
||||||
|
import { openidIsApply } from '@/api/weixin'
|
||||||
|
import useUserStore from '@/stores/modules/user'
|
||||||
import SignForm from '@/views/signUp/components/SignForm.vue'
|
import SignForm from '@/views/signUp/components/SignForm.vue'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
const formConfigs = ref<any[]>([])
|
const formConfigs = ref<any[]>([])
|
||||||
const form = ref({})
|
const form = ref({})
|
||||||
|
const userIsApply = ref(false)
|
||||||
|
|
||||||
|
// 验证用户是否已经报名
|
||||||
|
function checkIsApply() {
|
||||||
|
const miceLink = getUrlMiceLink()
|
||||||
|
openidIsApply({ openId: userStore.wxInfo.openid, miceLink }).then((res: any) => {
|
||||||
|
userIsApply.value = res
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
router.replace(`/user/${miceLink}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!userStore.openId) {
|
||||||
|
userStore.getOpenId()
|
||||||
|
}
|
||||||
|
|
||||||
|
checkIsApply()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
20
src/views/user/index.vue
Normal file
20
src/views/user/index.vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import useUserStore from '@/stores/modules/user'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const userApplyInfo = ref<any>({})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
userStore.getApplyUserInfo(getUrlMiceLink()).then((res) => {
|
||||||
|
userApplyInfo.value = res
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
个人中心
|
||||||
|
{{ userApplyInfo }}
|
||||||
|
</div>
|
||||||
|
</template>
|
@ -1,4 +1,4 @@
|
|||||||
import { defineConfig, presetAttributify, presetMini, presetUno } from 'unocss'
|
import { defineConfig, presetAttributify, presetUno } from 'unocss'
|
||||||
import presetRemToPx from '@unocss/preset-rem-to-px'
|
import presetRemToPx from '@unocss/preset-rem-to-px'
|
||||||
|
|
||||||
// 刚使用unocss的朋友,可以借助这个工具: https://to-unocss.netlify.app
|
// 刚使用unocss的朋友,可以借助这个工具: https://to-unocss.netlify.app
|
||||||
|
@ -20,6 +20,7 @@ export default ({ mode }: ConfigEnv): UserConfig => {
|
|||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
// 接口请求地址
|
// 接口请求地址
|
||||||
|
// target: 'http://localhost:8888/api',
|
||||||
target: 'https://jihui.huiyipro.com/api',
|
target: 'https://jihui.huiyipro.com/api',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: path => path.replace(/^\/api/, ''),
|
rewrite: path => path.replace(/^\/api/, ''),
|
||||||
|
Loading…
Reference in New Issue
Block a user