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({ |
||||
navigationStyle: 'custom', |
||||
navigationBarTitleText:'医学道', |
||||
onReachBottomDistance: 30 |
||||
}) |
||||
|
@ -1,3 +1,4 @@ |
||||
export default definePageConfig({ |
||||
navigationStyle: 'custom', |
||||
navigationBarTitleText: '登录' |
||||
}) |
||||
|
@ -1,3 +1,3 @@ |
||||
export default definePageConfig({ |
||||
navigationBarTitleText: '注册', |
||||
navigationBarTitleText: '登记', |
||||
}) |
||||
|
@ -1,49 +1,103 @@ |
||||
import {FC} from "react"; |
||||
import {Button, Form, Input, View} from "@tarojs/components"; |
||||
import {getCurrentInstance} from "@tarojs/runtime"; |
||||
import Taro from "@tarojs/taro"; |
||||
import Taro, {useLoad, useRouter} from "@tarojs/taro"; |
||||
import {userApi} from "@/api"; |
||||
import {Profile} from '@/store' |
||||
|
||||
const BingUser: FC = () => { |
||||
const {company_id, department_id, start_time, end_time} = getCurrentInstance()?.router?.params as unknown as Offline |
||||
|
||||
Taro.useLoad(() => { |
||||
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'}) |
||||
} |
||||
// const {depid, start_time, end_time} = getCurrentInstance()?.router?.params as unknown as Offline
|
||||
const {setUser, setToken, setCompany} = Profile.useContainer() |
||||
const router = useRouter() |
||||
|
||||
|
||||
// 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, |
||||
}) |
||||
return |
||||
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 ( |
||||
<View className='h-10 bg-white p-2'> |
||||
<Form className='form'> |
||||
<Form className='form' onSubmit={submit}> |
||||
|
||||
<View className='item'> |
||||
<View>用户名</View> |
||||
<Input placeholder='请输入用户名' focus/> |
||||
<Input placeholder='请输入用户名' focus name='user_name'/> |
||||
</View> |
||||
|
||||
<View className='item'> |
||||
<View>手机号</View> |
||||
<Input type='number' placeholder='请输入手机号'/> |
||||
<Input type='number' placeholder='请输入手机号' name='phone_number'/> |
||||
</View> |
||||
|
||||
<Button className='button mt-3' formType='submit'>登录</Button> |
||||
<Button className='button mt-3' formType='submit'>登记</Button> |
||||
</Form> |
||||
</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