1.修改现场会部门和公司

2.新增现场修改
3.新增现场邀请登录 短信
main
king 1 year ago
parent f10af4f1cc
commit 400d00546d
  1. 3
      src/api/login.ts
  2. 16
      src/api/meeting.ts
  3. 4
      src/api/user.ts
  4. 9
      src/components/button/MyButton.tsx
  5. 4
      src/config.ts
  6. 95
      src/pages/manage/spotMeeting/spotMeeting.tsx
  7. 118
      src/pages/meeting/meeting.tsx

@ -15,8 +15,5 @@ export const loginApi = {
},
testLogin() {
return request('/token/18708100736', "GET")
},
meetingInfo(id: string) {
return request(`/api/v1/meetings/meeting/${id}/info`, "GET")
}
}

@ -3,7 +3,10 @@ import {request} from "@/api/request";
export interface Meeting {
id: number
/** 部门ID */
department_id: number;
dep_id: number | null;
department_id: number | null;
company_id: number,
companyId: number,
/** 现场会描述 */
description: string;
/** 预计结束时间 */
@ -18,10 +21,18 @@ export interface Meeting {
| 3 // 结束中
}
interface MeetingInfo {
type: number
data: Meeting
}
export const meetingAPi = {
setMeetings(data: Meeting) {
return request<{ id: number }>('/api/v1/meetings/meeting', "POST", data)
},
putMeeting(id: number, data: Partial<Meeting>) {
return request(`/api/v1/meetings/meeting/${id}`, "PUT", data)
},
setMeeting(id: string) {
return request<Meeting>(`/api/v1/meetings/meeting/${id}`, "GET")
},
@ -43,4 +54,7 @@ export const meetingAPi = {
end(id: number) {
return request(`/api/v1/meetings/meeting/${id}/end`, "PUT")
},
meetingInfo(id: string) {
return request<MeetingInfo>(`/api/v1/meetings/meeting/info?id=${id}`, "GET")
}
}

@ -76,7 +76,7 @@ export const userApi = {
return request<HourCourse>(`/api/v1/course/${course_id}/info/${unique_ident}`, "GET")
},
meetingSave(data: any) {
return request<LoginData>(`/api/v1/user/meeting/save`, "POST", data)
return request<LoginData>(`/api/v1/auth/login/meeting/save`, "POST", data)
},
info(user_id: string) {
return request<User>(`/api/v1/statistics/${user_id}`, "GET")
@ -88,6 +88,6 @@ export const userApi = {
}>(`/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")
return request('/api/v1/sms/send?phone_number=' + phone_number, "GET")
}
}

@ -42,22 +42,27 @@ const MyButton: FC<Props> = (props) => {
}
}
if (props.disabled) {
style.background = '#f5f8f7'
style.color = '#ddd'
style.boxShadow = 'none'
}
return style
}
return (
<Button
hoverClass='none'
plain
{...props}
style={buttonStyle()}
onClick={(event) => !props.disabled && props.onClick?.(event)}
className={`${styles.Mybutton} ${props.className}`}>
{
props.loading && <View className='mr-1'>
<Loading/>
</View>
}
<View>{props.children}</View>
</Button>
)

@ -4,4 +4,8 @@ export const whiteList: string[] = [
'/pages/login/login',
'/pages/meeting/meeting',
'/pages/preview/preview',
'pages/check/check',
'pages/login/login',
'pages/meeting/meeting',
'pages/preview/preview',
]

@ -9,6 +9,7 @@ import styles from './spotMeeting.module.scss'
import code from '@/static/img/code.png'
import Icon from "@/components/icon";
import failure from "@/static/img/failure.png"
import {Profile} from "@/store";
const SpotMeeting: FC = () => {
const path = encodeURIComponent("/pages/meeting/meeting")
@ -23,6 +24,7 @@ const SpotMeeting: FC = () => {
const [loading, setLoading] = useState(false)
const [status, setStatus] = useState(0) // 状态
const [id, setId] = useState<number | undefined>(params.id ? Number(params.id) : undefined)
const {company} = Profile.useContainer()
function setData(res: Meeting | null) {
/**
@ -31,13 +33,13 @@ const SpotMeeting: FC = () => {
*/
if (params.id || id !== res?.id) {
setImgUrl('')
setDepid(res?.department_id || null)
setDepid(res?.dep_id || null)
setName(res?.name || '')
setDescription(res?.description || '')
setStatus(res?.status || 0)
setId(res?.id || 0)
if (!Array.isArray(res) && res) {
if (res) {
downUrl(res.id, false)
setEnd(formatDate(new Date(res.estimate_end_time), "YY-MM-dd 18:00:00"))
setStart(formatDate(new Date(res.estimate_start_time), "YY-MM-dd 08:00:00"))
@ -120,6 +122,8 @@ const SpotMeeting: FC = () => {
}
},
});
} else {
Taro.showToast({title: '请截图保存', icon: 'none'})
}
}, [imgUrl]);
@ -166,10 +170,6 @@ const SpotMeeting: FC = () => {
Taro.showToast({title: '请填写会议名称', icon: 'error'})
return
}
if (!depid) {
Taro.showToast({title: '请选择部门', icon: 'error'})
return
}
setLoading(true)
try {
@ -177,7 +177,8 @@ const SpotMeeting: FC = () => {
...values,
estimate_end_time: new Date(end).getTime(),
estimate_start_time: new Date(start).getTime(),
department_id: depid
dep_id: depid,
company_id: company?.id!
})
downUrl(res.id)
setStatus(0)
@ -192,14 +193,6 @@ const SpotMeeting: FC = () => {
setLoading(false)
}
useEffect(() => {
if (imgUrl) {
setImgUrl('')
setStatus(0)
setId(undefined)
}
}, [start, end, name, depid, description])
/** 开始 */
async function onStart() {
try {
@ -222,6 +215,20 @@ const SpotMeeting: FC = () => {
}
}
async function putMeeting() {
Taro.showLoading()
await meetingAPi.putMeeting(id!, {
name,
dep_id: depid,
company_id: company?.id!,
description,
estimate_end_time: new Date(end).getTime(),
estimate_start_time: new Date(start).getTime(),
})
Taro.hideLoading()
Taro.showToast({title: '修改成功'})
}
return (
<View className={styles.page}>
@ -251,13 +258,13 @@ const SpotMeeting: FC = () => {
<View className={styles.choice}>
<Form onSubmit={submit}>
<PopPut
title='会议标题'
title='会议名称'
chevron
content={<Input
className='input'
name='name'
value={name}
disabled={!!params.id || status > 0}
disabled={status > 0}
placeholder='请输入会议标题'
onInput={(e) => setName(e.detail.value)}
/>}
@ -265,7 +272,7 @@ const SpotMeeting: FC = () => {
<Picker
mode="date"
value={start}
disabled={!!params.id || status === 1}
disabled={status === 1}
onChange={(e) => change_start(e.detail.value + ' 8:00:00')}
name='estimate_start_time'>
<PopPut title='开始时间' content={start}/>
@ -273,7 +280,7 @@ const SpotMeeting: FC = () => {
<Picker
mode="date"
value={end}
disabled={!!params.id || status === 1}
disabled={status === 1}
onChange={(e) => change_end(e.detail.value + ' 18:00:00')}
name='estimate_end_time'>
<PopPut title='结束时间' content={end}/>
@ -282,9 +289,9 @@ const SpotMeeting: FC = () => {
mode='selector'
range={manages}
onChange={depChange}
disabled={!!params.id || status === 1}
disabled={status === 1}
rangeKey='name'
name='department_id'>
name='dep_id'>
<PopPut title='选择部门' content={manages?.find(x => x.id == depid)?.name}/>
</Picker>
@ -299,20 +306,39 @@ const SpotMeeting: FC = () => {
{/* style={{height: '60px'}}>*/}
{/*</Textarea>*/}
{
id !== undefined && <>
{
status === 0 &&
<MyButton fillet type='warn' width={200} className={styles.buttonDel} onClick={onStart}></MyButton>
}
<View className='flex justify-between'>
{
status === 1 &&
<MyButton fillet type='warn' width={200} className={styles.buttonDel} onClick={onEnd}></MyButton>
}
</>
}
{
id !== undefined && <>
{
status === 0 && <MyButton
fillet
type='warn'
width={150}
className={styles.buttonDel}
onClick={onStart}>
</MyButton>
}
{
status === 1 &&
<MyButton fillet type='warn' width={150} className={styles.buttonDel} onClick={onEnd}></MyButton>
}
</>
}
{
imgUrl && <MyButton
fillet
disabled={!imgUrl || status === 1}
width={150}
onClick={putMeeting}
className={styles.button}>
</MyButton>
}
</View>
<MyButton
formType='submit'
@ -320,9 +346,8 @@ const SpotMeeting: FC = () => {
width={200}
className={styles.button}
loading={loading}>
{imgUrl ? "保存二维码" : "新建现场会"}
</MyButton>
</Form>
</View>

@ -1,40 +1,66 @@
import {FC, useEffect, useState} from "react";
import {Button, Form, Input, View} from "@tarojs/components";
import {FC, useCallback, useEffect, useState} from "react";
import {Form, Input, View} from "@tarojs/components";
import Taro, {useRouter} from "@tarojs/taro";
import {userApi, loginApi, LoginParams} from "@/api";
import {userApi, loginApi, LoginParams, meetingAPi, Meeting} from "@/api";
import {Profile} from '@/store'
import {getCurrentInstance} from "@tarojs/runtime";
import {regexTel} from "@/utils/regu";
import MyButton from "@/components/button/MyButton";
const Meeting: FC = () => {
const {meeting_id} = getCurrentInstance()?.router?.params as unknown as { meeting_id: string }
interface Params {
meeting_id: string
phone_number?: string
user_name?: string
}
const MeetingLogin: FC = () => {
const {setUser, setToken, setCompany} = Profile.useContainer()
const [codeTime, setCodeTime] = useState(0)
const [phone_number, setPhone_number] = useState<number | null>()
const [userName, setUserName] = useState('')
const [code, setCode] = useState('')
const [h5params, setH5Params] = useState<LoginParams | null>(null)
const router = useRouter()
const [meeting, setMeeting] = useState<Meeting | null>(null)
const params = useRouter().params as unknown as Params
useEffect(() => {
loginApi.getMeetingParams().then((res) => {
setH5Params(res)
})
if (params.user_name && params.phone_number) {
setPhone_number(Number(params.phone_number))
setUserName(params.user_name)
Taro.showToast({title: '验证码错误', icon: 'error'})
}
}, [])
useEffect(() => {
if (codeTime > 0) {
setTimeout(() => {
setCodeTime(codeTime - 1)
}, 1000)
}
}, [codeTime])
Taro.useLoad(() => {
loginApi.meetingInfo(meeting_id).then(res => {
if (res !== 1) {
meetingAPi.meetingInfo(params.meeting_id).then(res => {
if (res.type !== 1) {
Taro.showModal({
title: '二维码已过期',
title: res.type === 0 ? '暂未开始' : '二维码已过期',
success() {
Taro.reLaunch({url: '/pages/login/login'})
}
})
return
}
setMeeting(res.data)
})
})
function submit(e) {
const value = e.detail.value
if (!value.user_name || !value.phone_number) {
Taro.showToast({title: '请认真填写', icon: "error"})
if (!value.user_name) {
Taro.showToast({title: '请写用户名', icon: "error"})
return
}
@ -43,6 +69,11 @@ const Meeting: FC = () => {
return
}
if (!value.phone_code) {
Taro.showToast({title: '请获取手机验证码', icon: 'error'})
return;
}
if (process.env.TARO_ENV === 'h5') {
if (h5params == null) {
Taro.showToast({title: '页面参数错误,请刷新页面!', icon: 'error'})
@ -50,18 +81,21 @@ const Meeting: FC = () => {
}
location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
"appid=" + h5params!.appid +
"&redirect_uri=" + encodeURIComponent(h5params!.route + `?depid=1&phone_number=${value.phone_number}&user_name=${value.user_name}&meeting_id=${meeting_id}`) +
"&redirect_uri=" +
encodeURIComponent(
h5params!.route +
`?dep_id=${meeting?.dep_id}&company_id=${meeting?.companyId}&phone_number=${value.phone_number}&user_name=${value.user_name}&meeting_id=${params.meeting_id}&phone_code=${value.phone_code}`
) +
"&response_type=code" +
"&scope=snsapi_userinfo" +
"#wechat_redirect";
} else {
Taro.login({
success: async (res) => {
const data = await userApi.meetingSave({
...value,
code: res.code,
ticket: router.params.ticket,
meeting_id: params.meeting_id
})
setCompany(data.company)
setUser(data.user)
@ -72,29 +106,71 @@ const Meeting: FC = () => {
Taro.showToast({title: '获取微信登录失败', icon: "error"})
}
})
}
}
const getCode = useCallback(async () => {
if (codeTime > 0) return;
if (!phone_number || !regexTel.exec(String(phone_number))) {
Taro.showToast({title: '请输入正确的手机号', icon: 'error'})
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 bg-white px-2'>
<View style={{position: 'fixed', top: 0, left: 0, bottom: 0, right: 0, padding: "0 15px", background: '#fff'}}>
<Form className='form' onSubmit={submit}>
<View className='item'>
<View></View>
<Input placeholder='请输入用户名' focus name='user_name'/>
<Input
placeholder='请输入用户名'
focus
name='user_name'
value={userName}
onInput={(e) => setUserName(e.detail.value)}/>
</View>
<View className='item'>
<View></View>
<Input type='number' placeholder='请输入手机号' name='phone_number'/>
<Input
type='number'
name='phone_number'
placeholder={'请输入手机号'}
value={phone_number as unknown as string}
onInput={(e) => setPhone_number(Number(e.detail.value))}/>
</View>
<View className='item'>
<View></View>
<View className='flex flex-1'>
<Input
type='number'
name='phone_code'
className='flex-1 mr-2'
value={code}
onInput={(e) => setCode(e.detail.value)}
placeholder='输入验证码'/>
<View onClick={getCode}>
{codeTime > 0 ? `${codeTime}` : '获取验证码'}
</View>
</View>
</View>
<Button className='button mt-3' formType='submit'></Button>
<MyButton className='mt-3' formType='submit'></MyButton>
</Form>
</View>
)
}
export default Meeting
export default MeetingLogin

Loading…
Cancel
Save