parent
7f4092cc8a
commit
8e34ddb5af
@ -0,0 +1,12 @@ |
|||||||
|
import {request} from "@/api/request"; |
||||||
|
|
||||||
|
export interface LoginParams { |
||||||
|
appid: string |
||||||
|
route: string |
||||||
|
} |
||||||
|
|
||||||
|
export const loginApi = { |
||||||
|
getParams() { |
||||||
|
return request<LoginParams>("/api/v1/auth/login/app", "GET"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
import {CSSProperties, FC} from "react"; |
||||||
|
import {Button} from "@tarojs/components"; |
||||||
|
import styles from './myButton.module.scss' |
||||||
|
import {ButtonProps} from "@tarojs/components/types/Button"; |
||||||
|
|
||||||
|
interface Props extends ButtonProps { |
||||||
|
fillet?: boolean |
||||||
|
loading?: boolean |
||||||
|
} |
||||||
|
|
||||||
|
const MyButton: FC<Props> = (props) => { |
||||||
|
|
||||||
|
const buttonStyle = (): CSSProperties => { |
||||||
|
const style: CSSProperties = {} |
||||||
|
switch (props.type) { |
||||||
|
case 'default': |
||||||
|
style.background = '#f5f8f7' |
||||||
|
break |
||||||
|
case 'warn': |
||||||
|
style.background = '#c94f4f' |
||||||
|
break |
||||||
|
} |
||||||
|
|
||||||
|
if (props.fillet) { |
||||||
|
style.borderRadius = '100px' |
||||||
|
} |
||||||
|
|
||||||
|
return style |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<Button |
||||||
|
{...props} |
||||||
|
style={buttonStyle()} |
||||||
|
className={styles.Mybutton}> |
||||||
|
{props.children} |
||||||
|
</Button> |
||||||
|
) |
||||||
|
} |
||||||
|
export default MyButton |
@ -0,0 +1,10 @@ |
|||||||
|
.Mybutton { |
||||||
|
line-height: 76rpx; |
||||||
|
background: #45D4A8; |
||||||
|
border-radius: 10rpx; |
||||||
|
color: #fff; |
||||||
|
font-size: 32rpx; |
||||||
|
border: none !important; |
||||||
|
outline: none !important; |
||||||
|
position: sticky; |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
.customPageContainer { |
||||||
|
position: fixed; |
||||||
|
top: 0; |
||||||
|
right: 0; |
||||||
|
left: 0; |
||||||
|
bottom: 0; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
|
||||||
|
.overlay { |
||||||
|
background: rgba(#000, .5); |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.content { |
||||||
|
width: 100%; |
||||||
|
background: #fff; |
||||||
|
position: absolute; |
||||||
|
padding: 0 30px env(safe-area-inset-bottom); |
||||||
|
box-sizing: border-box; |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
import {PageContainer, PageContainerProps, View} from "@tarojs/components"; |
||||||
|
import {CSSProperties, FC, useEffect, useState} from "react"; |
||||||
|
import styles from './custom-page-container.module.scss' |
||||||
|
|
||||||
|
const PageContainerInner: FC<PageContainerProps> = (props) => { |
||||||
|
const [visible, setVisible] = useState(props.show) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (props.show != visible) { |
||||||
|
setVisible(props.show); |
||||||
|
|
||||||
|
// todo 目前仅仅支持 after
|
||||||
|
if (!props.show) { |
||||||
|
(props.onBeforeLeave as Function)?.(); |
||||||
|
(props.onAfterLeave as Function)?.(); |
||||||
|
} |
||||||
|
} |
||||||
|
}, [props.show]) |
||||||
|
|
||||||
|
if (!props.show) { |
||||||
|
return null |
||||||
|
} |
||||||
|
|
||||||
|
const contentStyle = (): CSSProperties => { |
||||||
|
let style: CSSProperties = {} |
||||||
|
|
||||||
|
switch (props.position) { |
||||||
|
case "top": |
||||||
|
style.borderRadius = '0 0 30px 30px' |
||||||
|
style.top = 0 |
||||||
|
break |
||||||
|
case 'bottom': |
||||||
|
style.borderRadius = '30px 30px 0 0' |
||||||
|
style.bottom = 0 |
||||||
|
break |
||||||
|
case 'center': |
||||||
|
style.borderRadius = '30px' |
||||||
|
break |
||||||
|
} |
||||||
|
|
||||||
|
return style |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<View className={styles.customPageContainer}> |
||||||
|
<View className={styles.overlay} onClick={props.onClickOverlay}></View> |
||||||
|
<View className={styles.content} style={contentStyle()}>{props.children}</View> |
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
const CustomPageContainer: FC<PageContainerProps> = (props) => { |
||||||
|
if (process.env.TARO_ENV !== 'h5') { |
||||||
|
return (<PageContainer {...props} />) |
||||||
|
} |
||||||
|
return (<PageContainerInner {...props} />); |
||||||
|
} |
||||||
|
|
||||||
|
export default CustomPageContainer |
@ -0,0 +1,4 @@ |
|||||||
|
export default definePageConfig({ |
||||||
|
navigationStyle: 'custom', |
||||||
|
navigationBarTitleText: '验证' |
||||||
|
}) |
@ -0,0 +1,68 @@ |
|||||||
|
.container { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.navbar, |
||||||
|
.brand { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
|
||||||
|
.navbar { |
||||||
|
position: relative; |
||||||
|
line-height: 1; |
||||||
|
font-size: 28px; |
||||||
|
} |
||||||
|
|
||||||
|
.brand { |
||||||
|
width: 140px; |
||||||
|
height: 140px; |
||||||
|
background: #fff; |
||||||
|
border-radius: 20px; |
||||||
|
margin: 250px auto 145px; |
||||||
|
|
||||||
|
image { |
||||||
|
width: 100px; |
||||||
|
height: 100px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.loginTips { |
||||||
|
margin: 24px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.submit { |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
gap: 12px; |
||||||
|
margin: 0 auto; |
||||||
|
|
||||||
|
a { |
||||||
|
|
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
.errorTips { |
||||||
|
position: fixed; |
||||||
|
top: 10%; |
||||||
|
left: 24px; |
||||||
|
right: 24px; |
||||||
|
background: red; |
||||||
|
color: white; |
||||||
|
padding: 24px; |
||||||
|
border-radius: 20px; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
gap: 12px; |
||||||
|
} |
||||||
|
|
||||||
|
.bing { |
||||||
|
height: 50vh; |
||||||
|
padding: 50px 30px 0; |
||||||
|
} |
@ -0,0 +1,90 @@ |
|||||||
|
import {FC, useRef, useState} from "react"; |
||||||
|
import {Button, Form, Image, Input, View} from "@tarojs/components"; |
||||||
|
import {Profile} from "@/store"; |
||||||
|
import {userApi} from "@/api"; |
||||||
|
import Taro, {useRouter} from "@tarojs/taro"; |
||||||
|
import {regexTel} from "@/utils/regu"; |
||||||
|
import styles from './check.module.scss' |
||||||
|
|
||||||
|
const uuid = () => { |
||||||
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { |
||||||
|
const r = Math.random() * 16 | 0 |
||||||
|
const v = c === 'x' ? r : (r & 0x3 | 0x8) |
||||||
|
return v.toString(16) |
||||||
|
}).replace(/-/g, '') |
||||||
|
} |
||||||
|
|
||||||
|
const Bing: FC = () => { |
||||||
|
const form = useRef<HTMLFormElement | null>(null) |
||||||
|
const [loading, setLoading] = useState(false) |
||||||
|
const {setUser, setToken, setCompany} = Profile.useContainer() |
||||||
|
const [captchaKey, setCaptchaKey] = useState(uuid()) |
||||||
|
const router = useRouter() |
||||||
|
|
||||||
|
async function Submit(data) { |
||||||
|
setLoading(true) |
||||||
|
const value = data.target.value |
||||||
|
if (!regexTel.exec(value.phone_number)) { |
||||||
|
Taro.showToast({title: '手机号错误', icon: 'error'}) |
||||||
|
setLoading(false) |
||||||
|
return |
||||||
|
} |
||||||
|
try { |
||||||
|
const res = await userApi.checkout({ |
||||||
|
...value, |
||||||
|
catch_key: captchaKey, |
||||||
|
openid: router.params.openid, |
||||||
|
}) |
||||||
|
if (res) { |
||||||
|
setCompany(res.company) |
||||||
|
setUser(res.user) |
||||||
|
setToken(res.token) |
||||||
|
Taro.switchTab({url: '/pages/index/index'}) |
||||||
|
} |
||||||
|
} catch (e) { |
||||||
|
setCaptchaKey(uuid) |
||||||
|
} |
||||||
|
setLoading(false) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<View className='h-10 pt-6 px-3 bg-white'> |
||||||
|
<Form className='form' onSubmit={Submit} ref={form}> |
||||||
|
<View className='item'> |
||||||
|
<View>手机号</View> |
||||||
|
<Input name='phone_number' placeholder={'请输入手机号'} value='18708100736'/> |
||||||
|
</View> |
||||||
|
|
||||||
|
<View className='item'> |
||||||
|
<View>验证码</View> |
||||||
|
|
||||||
|
<View className='flex align-center flex-1'> |
||||||
|
<Input name='code' className='flex-1' placeholder={'请输入验证码'}/> |
||||||
|
<Image className='w-2 ml-1' style='height:28px' |
||||||
|
src={process.env.TARO_APP_API + '/api/v1/captcha?key=' + captchaKey} |
||||||
|
onClick={() => setCaptchaKey(uuid)}/> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
<Button |
||||||
|
className={'button ' + styles.submit} |
||||||
|
style={{margin: '30px auto'}} |
||||||
|
formType='submit' |
||||||
|
disabled={loading} |
||||||
|
> |
||||||
|
提交 |
||||||
|
</Button> |
||||||
|
</Form> |
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
const Index: FC = () => { |
||||||
|
return ( |
||||||
|
<Profile.Provider> |
||||||
|
<Bing/> |
||||||
|
</Profile.Provider> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export default Index; |
@ -1,4 +1,5 @@ |
|||||||
export default definePageConfig({ |
export default definePageConfig({ |
||||||
navigationStyle: 'custom', |
navigationStyle: 'custom', |
||||||
|
navigationBarTitleText:'医学道', |
||||||
onReachBottomDistance: 30 |
onReachBottomDistance: 30 |
||||||
}) |
}) |
||||||
|
@ -1,3 +1,4 @@ |
|||||||
export default definePageConfig({ |
export default definePageConfig({ |
||||||
navigationStyle: 'custom', |
navigationStyle: 'custom', |
||||||
|
navigationBarTitleText: '登录' |
||||||
}) |
}) |
||||||
|
@ -1,3 +1,3 @@ |
|||||||
export default definePageConfig({ |
export default definePageConfig({ |
||||||
navigationBarTitleText: '注册', |
navigationBarTitleText: '登记', |
||||||
}) |
}) |
||||||
|
@ -1,49 +1,103 @@ |
|||||||
import {FC} from "react"; |
import {FC} from "react"; |
||||||
import {Button, Form, Input, View} from "@tarojs/components"; |
import {Button, Form, Input, View} from "@tarojs/components"; |
||||||
import {getCurrentInstance} from "@tarojs/runtime"; |
import Taro, {useLoad, useRouter} from "@tarojs/taro"; |
||||||
import Taro from "@tarojs/taro"; |
import {userApi} from "@/api"; |
||||||
|
import {Profile} from '@/store' |
||||||
|
|
||||||
const BingUser: FC = () => { |
const BingUser: FC = () => { |
||||||
const {company_id, department_id, start_time, end_time} = getCurrentInstance()?.router?.params as unknown as Offline |
// const {depid, start_time, end_time} = getCurrentInstance()?.router?.params as unknown as Offline
|
||||||
|
const {setUser, setToken, setCompany} = Profile.useContainer() |
||||||
Taro.useLoad(() => { |
const router = useRouter() |
||||||
const time = Date.now() |
|
||||||
if (!company_id |
|
||||||
|| !department_id |
|
||||||
|| !start_time |
|
||||||
|| !end_time |
|
||||||
|| time > new Date(end_time).getTime() |
|
||||||
|| time < new Date(start_time).getTime()) { |
|
||||||
Taro.showModal({ |
|
||||||
title: '二维码已过期', |
|
||||||
success() { |
|
||||||
Taro.reLaunch({url: '/pages/login/login'}) |
|
||||||
} |
|
||||||
}) |
|
||||||
return |
|
||||||
} |
|
||||||
|
|
||||||
}) |
|
||||||
|
|
||||||
|
// Taro.useLoad(() => {
|
||||||
|
// const time = Date.now()
|
||||||
|
// if (!depid
|
||||||
|
// || !start_time
|
||||||
|
// || !end_time
|
||||||
|
// || time > new Date(end_time).getTime()
|
||||||
|
// || time < new Date(start_time).getTime()) {
|
||||||
|
// Taro.showModal({
|
||||||
|
// title: '二维码已过期',
|
||||||
|
// success() {
|
||||||
|
// Taro.reLaunch({url: '/pages/login/login'})
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
function submit(e) { |
||||||
|
const value = e.detail.value |
||||||
|
// if (!value.user_name || !value.phone_number) {
|
||||||
|
// Taro.showToast({title: '请认真填写', icon: "error"})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (!regexTel.exec(value.phone_number)) {
|
||||||
|
// Taro.showToast({title: '手机号错误', icon: 'error'})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
Taro.showLoading() |
||||||
|
|
||||||
|
Taro.login({ |
||||||
|
success: async (res) => { |
||||||
|
const data = await userApi.meetingSave({ |
||||||
|
...value, |
||||||
|
code: res.code, |
||||||
|
ticket: router.params.ticket, |
||||||
|
}) |
||||||
|
setCompany(data.company) |
||||||
|
setUser(data.user) |
||||||
|
setToken(data.token) |
||||||
|
Taro.switchTab({url: '/pages/index/index'}) |
||||||
|
}, |
||||||
|
fail: () => { |
||||||
|
Taro.showToast({title: '获取微信登录失败', icon: "error"}) |
||||||
|
}, |
||||||
|
complete() { |
||||||
|
Taro.hideLoading() |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
return ( |
return ( |
||||||
<View className='h-10 bg-white p-2'> |
<View className='h-10 bg-white p-2'> |
||||||
<Form className='form'> |
<Form className='form' onSubmit={submit}> |
||||||
|
|
||||||
<View className='item'> |
<View className='item'> |
||||||
<View>用户名</View> |
<View>用户名</View> |
||||||
<Input placeholder='请输入用户名' focus/> |
<Input placeholder='请输入用户名' focus name='user_name'/> |
||||||
</View> |
</View> |
||||||
|
|
||||||
<View className='item'> |
<View className='item'> |
||||||
<View>手机号</View> |
<View>手机号</View> |
||||||
<Input type='number' placeholder='请输入手机号'/> |
<Input type='number' placeholder='请输入手机号' name='phone_number'/> |
||||||
</View> |
</View> |
||||||
|
|
||||||
<Button className='button mt-3' formType='submit'>登录</Button> |
<Button className='button mt-3' formType='submit'>登记</Button> |
||||||
</Form> |
</Form> |
||||||
</View> |
</View> |
||||||
) |
) |
||||||
} |
} |
||||||
|
|
||||||
export default BingUser |
const BingUserIndex = () => { |
||||||
|
const router = useRouter() |
||||||
|
|
||||||
|
useLoad(() => { |
||||||
|
if (!router.params.ticket) { |
||||||
|
Taro.reLaunch({ |
||||||
|
url: "/pages/index/index" |
||||||
|
}) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
return ( |
||||||
|
<Profile.Provider> |
||||||
|
<BingUser/> |
||||||
|
</Profile.Provider> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default BingUserIndex |
||||||
|
Loading…
Reference in new issue