完善功能、首页、报名、个人中心

This commit is contained in:
awei 2024-02-22 15:35:23 +08:00
parent c2c83a06ea
commit 9b42afdcfa
22 changed files with 268 additions and 1105 deletions

View File

@ -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

View File

@ -1 +0,0 @@
node scripts/verifyCommit.js

View File

@ -1 +0,0 @@
pnpm lint

View File

@ -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"
]
}
} }
} }

File diff suppressed because it is too large Load Diff

23
src/api/user.ts Normal file
View 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,
})
}

View File

@ -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,
})
}

View File

@ -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
View File

@ -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']
} }
} }

View File

@ -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>

View File

@ -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)

View File

@ -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,
}) })

View File

@ -26,6 +26,15 @@ const routes: Array<RouteRecordRaw> = [
title: '报名', title: '报名',
}, },
}, },
// 个人中心
{
path: 'user/:miceLink',
name: 'User',
component: () => import('@/views/user/index.vue'),
meta: {
title: '个人中心',
},
},
], ],
}, },
] ]

View File

@ -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
}) })

View 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
View File

@ -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>
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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
View 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>

View File

@ -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

View File

@ -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/, ''),