对接短信登录,

学习记录请求
main
king 1 year ago
parent dc1a72ce9a
commit 6201f78c93
  1. 4
      src/api/manage.ts
  2. 5
      src/api/user.ts
  3. 9
      src/pages/business/test/test.tsx
  4. 3
      src/pages/business/videoInfo/components/course.tsx
  5. 5
      src/pages/business/videoInfo/videoInfo.tsx
  6. 59
      src/pages/check/check.module.scss
  7. 72
      src/pages/check/check.tsx
  8. 9
      src/pages/manage/addCur/addCur.tsx
  9. 2
      src/pages/manage/depAdmin/depAdmin.tsx
  10. BIN
      src/static/img/tel.png
  11. BIN
      src/static/img/vCode.png

@ -105,8 +105,8 @@ export const ManageApi = {
return request<DepCurData>(`/api/v1/department/${data.id}/courses?page=${data.page}&size=${data.size}`, "GET")
},
/** 未添加课程 */
optionalCur(dep_id: number) {
return request<Curriculum[]>(`/api/v1//choose/${dep_id}/index`, "GET")
optionalCur(dep_id: number, page: number, pageSize: number) {
return request<Curriculum[]>(`/api/v1/course/choose/${dep_id}/index`, "GET", {page, pageSize})
},
addCur(data: AddCurProps) {
return request('/api/v1/course/user', "POST", data)

@ -14,9 +14,9 @@ export interface LoginData {
}
interface CheckoutBody {
catch_key: string
code: string
phone_number: string
openid: string
}
interface CheckoutData {
@ -87,5 +87,8 @@ export const userApi = {
return request<{
data: Record<number, number>
}>(`/api/v1/statistics/statistics/${user_id}?start_time=${data.start_time}&end_time=${data.end_time}`, "GET")
},
getCode(phone_number: number) {
return request('/api/v1/sms/send?phone_number='+phone_number, "GET")
}
}

@ -83,28 +83,25 @@ const Test = () => {
return (
<View className={styles.content}>
{data?.fill.map((d, index) => <ShortAnswer
{data?.fill.map((d) => <ShortAnswer
key={d.id}
data={d}
index={index}
onAnswer={onAnswer}
validate={validate}
/>)}
{data?.judge.map((d, index) => <Judge
{data?.judge.map((d) => <Judge
key={d.id}
data={d}
index={index}
onAnswer={onAnswer}
validate={validate}
/>)}
{
data?.multi.map((d, index) => <Multi
data?.multi.map((d) => <Multi
key={d.id}
data={d}
onAnswer={onAnswer}
index={index}
validate={validate}/>)
}

@ -16,7 +16,7 @@ interface Props {
id: number,
courseId: number
preview?: boolean
curEnd: () => void
curEnd: (test?:boolean) => void
}
@ -44,6 +44,7 @@ const Course: FC<Props> = ({id, courseId, preview, curEnd}: Props) => {
startRecording && curriculum.curEnd(courseId, id, {...startRecording, duration: data?.duration!}) //结束
if (testId) {
Taro.navigateTo({url: `/pages/business/test/test?testId=${testId}`})
curEnd(true)
} else {
curEnd()
}

@ -26,10 +26,12 @@ const VideoInfo: FC = () => {
}
}, [playing, playId])
const curEnd = () => {
const curEnd = (test?: boolean) => {
setPlaying(false)
if (!test) { // 没有考题才会请求
getData(false).then()
}
}
function setHors(is_complete: boolean, play_id: number) {
setPlaying(true)
@ -76,6 +78,7 @@ const VideoInfo: FC = () => {
const courseHourRecordsFinish = data?.learn_hour_records.find(d => d.id === playId)?.courseHourRecordsFinish
if (typeof courseHourRecordsFinish === 'number') {
if (courseHourRecordsFinish === 1) {
console.log(playing)
if (!playing) {
playNext()
}

@ -1,39 +1,3 @@
.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;
@ -42,27 +6,18 @@ image {
margin: 0 auto;
a {
color: #fff;
}
}
.errorTips {
position: fixed;
top: 10%;
left: 24px;
right: 24px;
background: red;
color: white;
padding: 24px;
border-radius: 20px;
.formItem {
display: flex;
align-items: center;
gap: 12px;
border-bottom: 1px solid #ededed;
padding: 30px 0;
}
.bing {
height: 50vh;
padding: 50px 30px 0;
.image {
width: 50px;
vertical-align: top;
margin-right: 20px;
}

@ -1,25 +1,28 @@
import {FC, useRef, useState} from "react";
import {FC, useCallback, useEffect, useRef, useState} from "react";
import {Button, Form, Image, Input, View} from "@tarojs/components";
import {Profile} from "@/store";
import {userApi} from "@/api";
import Taro 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, '')
}
import code from '@/static/img/vCode.png'
import tel from '@/static/img/tel.png'
const Bing: FC = () => {
const form = useRef<HTMLFormElement | null>(null)
const [loading, setLoading] = useState(false)
const [codeTime, setCodeTime] = useState(0)
const {setUser, setToken, setCompany} = Profile.useContainer()
const [captchaKey, setCaptchaKey] = useState(uuid())
const openid = localStorage.getItem('openid')
const [phone_number, setPhone_number] = useState<number | undefined>(undefined)
useEffect(() => {
if (codeTime > 0) {
setTimeout(() => {
setCodeTime(codeTime - 1)
}, 1000)
}
}, [codeTime])
async function Submit(data) {
setLoading(true)
@ -32,7 +35,6 @@ const Bing: FC = () => {
try {
const res = await userApi.checkout({
...value,
catch_key: captchaKey,
openid,
})
if (res) {
@ -42,27 +44,53 @@ const Bing: FC = () => {
Taro.switchTab({url: '/pages/index/index'})
}
} catch (e) {
setCaptchaKey(uuid)
}
setLoading(false)
}
const getCode = useCallback(async () => {
if (codeTime > 0) return;
if (!phone_number || !regexTel.exec(String(phone_number))) {
Taro.showToast({title: '手机号错误', icon: 'error'})
setLoading(false)
return
}
try {
await userApi.getCode(phone_number)
Taro.showToast({title: '请注意查收', icon: "none"})
setCodeTime(60)
} catch (e) {
Taro.showToast({title: '获取短信验证码失败', icon: "error"})
}
}, [codeTime, phone_number])
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={'请输入手机号'}/>
<Form onSubmit={Submit} ref={form}>
<View className={styles.formItem}>
<View>
<Image src={tel} className={styles.image}/>
</View>
<Input
type='number'
name='phone_number'
placeholder={'请输入手机号'}
value={String(phone_number)}
onInput={(e) => setPhone_number(Number(e.detail.value))}/>
</View>
<View className='item'>
<View></View>
<View className={styles.formItem}>
<View>
<Image src={code} className={styles.image}/>
</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)}/>
<Input type='number' name='code' className='flex-1' placeholder='请输入短信验证码'/>
<View onClick={getCode}>
{codeTime > 0 ? `${codeTime}` : '获取验证码'}
</View>
</View>
</View>

@ -1,7 +1,7 @@
import {View} from "@tarojs/components";
import {getCurrentInstance} from "@tarojs/runtime";
import {ManageApi} from "@/api/manage";
import React, {FC, useEffect, useState} from "react";
import React, {FC, useCallback, useEffect, useState} from "react";
import Taro from "@tarojs/taro";
import VideoCover from "@/components/videoCover/videoCover";
import Empty from "@/components/empty/empty";
@ -15,18 +15,19 @@ interface AddProps {
const AddCur = () => {
const {id} = getCurrentInstance()?.router?.params as { id: string }
const [data, setData] = useState<Curriculum[]>([])
const [page] = useState(1)
async function getData() {
const getData = useCallback(async () => {
try {
const res = await ManageApi.optionalCur(Number(id))
const res = await ManageApi.optionalCur(Number(id), page, 10)
if (res.length) {
setData(res)
}
} catch (e) {
}
}
}, [page])
useEffect(() => {
getData()

@ -119,7 +119,7 @@ const DepAdmin: FC = () => {
useEffect(() => {
getData()
Taro.setNavigationBarTitle({
title: decodeURI(router.params.name!) || '部门管理'
title: router.params.name ? decodeURI(router.params.name!) : '部门管理'
})
}, [])

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Loading…
Cancel
Save