Commit 136034ff by yuananting

feat:新建培训任务相关接口联调

parent 11f4ee76
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-08-06 17:35:35
* @LastEditors: yuananting
* @LastEditTime: 2021-08-09 14:23:07
* @LastEditTime: 2021-08-10 15:28:07
* @Description: 任务中心接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -13,6 +13,10 @@ export function getTrainingTaskPage(params: object) {
return Service.Hades('public/hades/getTrainingTaskPage', params);
}
export function getStoreTaskNum(params: object) {
return Service.Hades('public/hades/getStoreTaskNum', params);
}
export function createTrainingExam(params: object) {
return Service.Hades('public/hades/createTrainingExam', params);
}
......@@ -20,3 +24,19 @@ export function createTrainingExam(params: object) {
export function createTrainingTask(params: object) {
return Service.Hades('public/hades/createTrainingTask', params);
}
export function updateIssueStateTraining(params: object) {
return Service.Hades('public/hades/updateIssueStateTraining', params);
}
export function deleteTrainingTask(params: object) {
return Service.Hades('public/hades/deleteTrainingTask', params);
}
export function getTrainingTaskDetail(params: object) {
return Service.Hades('public/hades/getTrainingTaskDetail', params);
}
export function updateTrainingTask(params: object) {
return Service.Hades('public/hades/updateTrainingTask', params);
}
......@@ -2,12 +2,21 @@
* @Author: yuananting
* @Date: 2021-08-06 17:32:41
* @LastEditors: yuananting
* @LastEditTime: 2021-08-09 14:23:33
* @LastEditTime: 2021-08-10 15:28:39
* @Description: 任务中心-培训任务接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import { getTrainingTaskPage, createTrainingExam, createTrainingTask } from '@/data-source/taskCenter/request-apis';
import {
getTrainingTaskPage,
getStoreTaskNum,
createTrainingExam,
createTrainingTask,
updateIssueStateTraining,
deleteTrainingTask,
getTrainingTaskDetail,
updateTrainingTask,
} from '@/data-source/taskCenter/request-apis';
export default class TaskCenterService {
// 获取培训任务列表
......@@ -15,6 +24,11 @@ export default class TaskCenterService {
return getTrainingTaskPage(params);
}
// 获取学院任务数量
static getStoreTaskNum(params: any) {
return getStoreTaskNum(params);
}
// 培训任务创建考试
static createTrainingExam(params: any) {
return createTrainingExam(params);
......@@ -24,4 +38,24 @@ export default class TaskCenterService {
static createTrainingTask(params: any) {
return createTrainingTask(params);
}
// 发布/取消发布培训任务
static updateIssueStateTraining(params: any) {
return updateIssueStateTraining(params);
}
// 删除培训任务
static deleteTrainingTask(params: any) {
return deleteTrainingTask(params);
}
// 获取培训任务详情
static getTrainingTaskDetail(params: any) {
return getTrainingTaskDetail(params);
}
// 修改培训任务
static updateTrainingTask(params: any) {
return updateTrainingTask(params);
}
}
......@@ -278,18 +278,19 @@
}
.circle-tip {
position: absolute;
left: 70%;
padding-left: 16px;
&.unfinished {
top: 152px;
bottom: 2%;
left: 37%;
.spot {
background: #2966ff;
}
}
&.finished {
top: 232px;
bottom: 2%;
left: 14%;
.spot {
background: #ffbb54;
background: #14cca7;
}
}
.spot {
......@@ -297,7 +298,7 @@
width: 8px;
height: 8px;
border-radius: 4px;
top: 20px;
top: 8px;
left: 0;
}
.number {
......
......@@ -6,66 +6,66 @@
* @Description: 大班直播分享弹窗
*/
import React from 'react'
import { Modal, Button, message } from 'antd'
import domtoimage from 'dom-to-image'
import qrcode from '@/libs/qrcode/qrcode.js'
import User from '@/common/js/user'
import $ from 'jquery'
import CourseService from '@/domains/course-domain/CourseService'
import React from 'react';
import { Modal, Button, message } from 'antd';
import domtoimage from 'dom-to-image';
import qrcode from '@/libs/qrcode/qrcode.js';
import User from '@/common/js/user';
import $ from 'jquery';
import CourseService from '@/domains/course-domain/CourseService';
import './SharePlanModal.less'
import './SharePlanModal.less';
const DEFAULT_COVER = 'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png'
const DEFAULT_COVER = 'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png';
class ShareLiveModal extends React.Component {
constructor(props) {
super(props)
super(props);
this.state = {
shareUrl: '',
}
};
}
componentDidMount() {
// 获取短链接
this.handleConvertShortUrl()
this.handleConvertShortUrl();
}
handleConvertShortUrl = () => {
const { longUrl } = this.props.data
const { longUrl } = this.props.data;
// 发请求
CourseService.getQrcode({
urls: [longUrl],
}).then((res) => {
const { result = [] } = res
const { result = [] } = res;
this.setState(
{
shareUrl: result[0].shortUrl,
},
() => {
const qrcodeWrapDom = document.querySelector('#qrcodeWrap')
const qrcodeWrapDom = document.querySelector('#qrcodeWrap');
const qrcodeNode = new qrcode({
text: this.state.shareUrl,
size: 98,
})
qrcodeWrapDom.appendChild(qrcodeNode)
});
qrcodeWrapDom.appendChild(qrcodeNode);
const qrcodeWrapDomDownload = document.querySelector('#qrcodeWrap-dowload')
const qrcodeWrapDomDownload = document.querySelector('#qrcodeWrap-dowload');
const qrcodeNodeDownLoad = new qrcode({
text: this.state.shareUrl,
size: 196,
})
qrcodeWrapDomDownload.appendChild(qrcodeNodeDownLoad)
}
)
})
});
qrcodeWrapDomDownload.appendChild(qrcodeNodeDownLoad);
}
);
});
};
componentWillUnmount() {
// 页面销毁之前清空定时器
clearTimeout(this.timer)
clearTimeout(this.timer);
}
// 下载海报
......@@ -77,29 +77,29 @@ class ShareLiveModal extends React.Component {
},
() => {
this.setState({ time: new Date().valueOf() }, () => {
let node = document.getElementById('poster-dowload')
let node = document.getElementById('poster-dowload');
domtoimage.toPng(node).then((imgData) => {
const download = document.createElement('a')
const { planName } = this.props.data
$(download).attr('href', imgData).attr('download', `${planName}.png`).get(0).click()
})
})
}
)
const download = document.createElement('a');
const { planName } = this.props.data;
$(download).attr('href', imgData).attr('download', `${planName}.png`).get(0).click();
});
});
}
);
};
// 复制分享链接
handleCopy = () => {
const textContent = document.getElementById('shareUrl').innerText
const textContent = document.getElementById('shareUrl').innerText;
window.copyText(textContent)
message.success('复制成功!')
}
window.copyText(textContent);
message.success('复制成功!');
};
render() {
const { data } = this.props
const { planName, coverUrl = DEFAULT_COVER } = data
const { shareUrl, showImg, time } = this.state
const { data } = this.props;
const { planName, coverUrl = DEFAULT_COVER } = data;
const { shareUrl, showImg, time } = this.state;
return (
<Modal
title={'分享培训计划'}
......@@ -185,8 +185,8 @@ class ShareLiveModal extends React.Component {
</div>
</div>
</Modal>
)
);
}
}
export default ShareLiveModal
export default ShareLiveModal;
......@@ -2,12 +2,12 @@
* @Author: yuananting
* @Date: 2021-07-29 13:57:03
* @LastEditors: yuananting
* @LastEditTime: 2021-08-09 17:39:56
* @LastEditTime: 2021-08-11 12:46:17
* @Description: 任务中心-培训任务-新建页面
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, useRef } from 'react';
import { Button, message, Modal, Space } from 'antd';
import ShowTips from '@/components/ShowTips';
import Breadcrumbs from '@/components/Breadcrumbs';
......@@ -18,14 +18,15 @@ import _ from 'underscore';
import './AddTrainTask.less';
import Upload from '@/core/upload';
import { randomString } from '@/domains/basic-domain/utils';
import TaskCenterService from '@/domains/task-center-domain/TaskCenterService';
import Bus from '@/core/bus';
const defaultCover = 'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png';
const DEFAULT_BASIC_INFO = {
taskName: '1', // 培训任务名称
taskName: '', // 培训任务名称
coverUrl: defaultCover,
coverId: null,
trainingStageList: [], // 培训内容
helpStoreUserIds: [], // 指定协同者id
timeType: 'FOREVER', // 培训时间,默认永久有效
startTime: null, // 固定时间段-开始时间
......@@ -51,17 +52,85 @@ const DEFAULT_FINISH_STANDARD = {
function AddTrainTask() {
const type = getParameterByName('type');
const taskId = getParameterByName('taskId');
const taskState = getParameterByName('taskState');
const [activeStep, setActiveStep] = useState('BASIC_INFO');
const [basicInfo, setBasicInfo] = useState(DEFAULT_BASIC_INFO);
const [stageList, setStageList] = useState(DEFAULT_STAGE_LIST);
const [finishStandard, setFinishStandard] = useState(DEFAULT_FINISH_STANDARD); // 完成百分比
const [startCheck, setStartCheck] = useState(false); // 是否启动校验
const basicInfoRef = useRef(null);
useEffect(() => {
basicInfoRef.current = basicInfo;
}, [basicInfo]);
useEffect(() => {
if (type === 'edit') {
TaskCenterService.getTrainingTaskDetail({
taskId,
}).then((res) => {
const {
result: {
taskName,
courseMediaVOS,
helpStoreUsers,
timeType,
startTime,
endTime,
learnType,
assignList,
percentCompleteLive,
percentCompletePicture,
percentCompleteVideo,
trainingStageList,
},
} = res;
const _helpStoreUserIds = helpStoreUsers.map((item) => {
item.nickName = item.storeUserName;
item.userId = item.storeUserId;
return item;
});
// useEffect(() => {
const coverInfo = courseMediaVOS.filter((item) => item.contentType === 'COVER')[0];
const coverUrl = coverInfo ? coverInfo.mediaUrl : defaultCover;
const coverId = coverInfo ? coverInfo.mediaContent : null;
// }, [basicInfo]);
console.log('basicInfo=====>', basicInfo);
const ITEM_BASIC_INFO = {
taskName,
coverUrl,
coverId,
helpStoreUserIds: _helpStoreUserIds,
timeType,
startTime,
endTime,
learnType,
assignList,
// introduce: null, // 培训目的
};
const ITEM_FINISH_STANDARD = {
percentCompleteLive,
percentCompletePicture,
percentCompleteVideo,
};
const _stageList = trainingStageList.map((item) => {
item.contentList = item.contentVOList;
item.type = 'text';
return item;
});
setBasicInfo(ITEM_BASIC_INFO);
setFinishStandard(ITEM_FINISH_STANDARD);
setStageList(_stageList);
});
}
}, []);
// 渲染底部操作按钮
function renderFooter() {
return (
<Choose>
......@@ -90,34 +159,55 @@ function AddTrainTask() {
);
}
// 确认保存新建
function submitRemote(introduceId, issue) {
const { endTime, helpStoreUserIds, learnType, startTime, taskName, timeType, coverId, coverUrl } = basicInfo;
const { percentCompleteLive, percentCompletePicture, percentCompleteVideo } = finishStandard;
const commonParams = {
assignList: [
// 指派对象
const _stageList = stageList.map((item, index) => {
delete item.contentVOList;
delete item.check;
delete item.type;
delete item.liveFailure;
item.sequence = index + 1;
return item;
});
const _helpStoreUserIds = helpStoreUserIds.map((item) => {
return item.userId;
});
const assignList = [
{
assignId: '',
assignName: '',
assignType: '',
assignId: '1379762403510968321',
assignType: 'CUSTOM',
},
],
];
// const _assignList = assignList((item) => {
// if (item.depType === 'DEP_CUSTOM') {
// // item.
// }
// });
// console.log(assignList);
createId: User.getUserId(),
const commonParams = {
assignList,
createId: User.getStoreUserId(),
endTime,
helpStoreUserIds, // 协同者集合
helpStoreUserIds: _helpStoreUserIds, // 协同者集合
issueState: issue, // 是否发布
learnType, // 学习模式
scheduleMediaRequests: [
scheduleMediaRequests: coverId
? [
{
contentType: 'COVER',
mediaContent: coverId,
mediaType: 'PICTURE',
mediaUrl: coverUrl,
},
],
]
: [],
startTime,
storeId: User.getStoreId(),
taskName,
......@@ -126,17 +216,60 @@ function AddTrainTask() {
percentCompletePicture,
percentCompleteVideo,
introduceId,
trainingStageList: _stageList,
};
console.log('commonParams:', commonParams);
// if (type === 'edit' && timeType === 'FOREVER') {
// delete commonParams.startTime;
// delete commonParams.endTime;
// }
if (type === 'edit') {
TaskCenterService.updateTrainingTask({ ...commonParams, id: taskId }).then((res) => {
message.success('保存成功');
RCHistory.goBack();
});
} else {
TaskCenterService.createTrainingTask(commonParams).then((res) => {
message.success('保存成功');
RCHistory.goBack();
});
}
Bus.trigger('getTrainingTaskPage');
Bus.trigger('getStoreTaskNum');
}
// 保存
function handleSubmit(issue) {
setStartCheck(true);
const { taskName, assignList } = basicInfo;
const { percentCompleteLive, percentCompleteVideo, percentCompletePicture } = finishStandard;
console.log(percentCompleteLive, percentCompleteVideo, percentCompletePicture);
if (!taskName) {
return message.warning('请输入培训任务名称');
}
// if (assignList.length === 0) {
// return message.warning('请选择指派对象');
// }
if (stageList.length === 0) {
return message.warning('请添加阶段');
}
const stageNameEmpty = stageList.filter((item) => !item.stageName);
if (stageNameEmpty.length > 0) {
return message.warning('请输入阶段名称');
}
const stageNameArr = stageList.map((item) => item.stageName);
const stageNameSet = new Set(stageNameArr);
if (stageNameSet.size !== stageNameArr.length) {
return message.warning('阶段名称不能重复');
}
if (percentCompleteLive === '' || percentCompleteVideo === '' || percentCompletePicture === '') {
return message.warning('请输入完成标准');
}
Upload.uploadTextToOSS(
basicInfo.introduce,
`${randomString()}.txt`,
......@@ -147,39 +280,37 @@ function AddTrainTask() {
);
}
// 返回、取消
function handleGoBack() {
window.RCHistory.goBack();
}
function handleChangeBasicInfo(field, value) {
console.log('handleChangeBasicInfo====>', basicInfo, field, value);
if (field === 'coverUrl') {
setBasicInfo({
...basicInfo,
...basicInfoRef.current,
coverUrl: value.fileUrl,
coverId: value.resourceId,
});
} else if (field === 'trainDate') {
// 固定培训时间,设置起始
setBasicInfo({
...basicInfo,
...basicInfoRef.current,
startTime: value && value[0]?.valueOf(),
endTime: value && value[1]?.valueOf(),
});
} else if (field === 'timeType' && value === 'FOREVER') {
setBasicInfo({
...basicInfo,
...basicInfoRef.current,
[field]: value,
startTime: null,
endTime: null,
});
} else {
let a = {
...basicInfo,
setBasicInfo({
...basicInfoRef.current,
[field]: value,
};
console.log('a====>', a);
setBasicInfo(a);
});
}
}
......@@ -187,10 +318,7 @@ function AddTrainTask() {
if (field === 'stageList') {
setStageList(value);
} else {
setFinishStandard({
...finishStandard,
[field]: value,
});
setFinishStandard(value);
}
}
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-07-28 11:25:58
* @LastEditors: yuananting
* @LastEditTime: 2021-08-09 11:41:40
* @LastEditTime: 2021-08-10 15:10:44
* @Description: 任务中心-培训任务
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -13,6 +13,8 @@ import TrainList from './components/TrainList';
import TaskCenterService from '@/domains/task-center-domain/TaskCenterService';
import DataCenter from '../data-center/Index';
import User from '@/common/js/user';
import Bus from '@/core/bus';
function TrainTaskPage(props) {
const [trainListData, setTrainListData] = useState([]); // 培训任务列表
const [query, setQuery] = useState({
......@@ -28,12 +30,33 @@ function TrainTaskPage(props) {
taskName: '',
});
const [totalCount, setTotalCount] = useState(0); // 总数
const [storeTaskNum, setStoreTaskNum] = useState({});
const { match } = props;
useEffect(() => {
getTrainingTaskPage();
}, [query]);
useEffect(() => {
getStoreTaskNum();
initPageData();
return () => {
removePageData();
};
}, []);
useEffect(() => {}, []);
const initPageData = () => {
Bus.bind('getTrainingTaskPage', getTrainingTaskPage);
Bus.bind('getStoreTaskNum', getStoreTaskNum);
};
const removePageData = () => {
Bus.unbind('getTrainingTaskPage', getTrainingTaskPage);
Bus.unbind('getStoreTaskNum', getStoreTaskNum);
};
// 获取计划列表
function getTrainingTaskPage() {
let _query = _.clone(query);
......@@ -49,6 +72,13 @@ function TrainTaskPage(props) {
});
}
// 获取学院任务数量
function getStoreTaskNum() {
TaskCenterService.getStoreTaskNum({ storeId: User.getStoreId() }).then((res) => {
setStoreTaskNum(res.result);
});
}
// 搜索条件修改
function queryChange(_query) {
setQuery({ ...query, ..._query });
......@@ -59,7 +89,7 @@ function TrainTaskPage(props) {
<div className='content-header'>培训任务</div>
<div className='box'>
<TrainFilter onChange={queryChange} />
<TrainList trainListData={trainListData} query={query} totalCount={totalCount} onChange={queryChange} />
<TrainList trainListData={trainListData} storeTaskNum={storeTaskNum} query={query} totalCount={totalCount} onChange={queryChange} />
</div>
<Route path={`${match.url}/data`} component={DataCenter} />
</div>
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-07-29 14:32:24
* @LastEditors: yuananting
* @LastEditTime: 2021-08-09 17:46:08
* @LastEditTime: 2021-08-11 10:20:33
* @Description: 任务中心-培训任务-新建-基本信息
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -24,6 +24,9 @@ const { RangePicker } = DatePicker;
const FormItem = Form.Item;
function BasicInfo(props) {
const taskState = getParameterByName('taskState');
const type = getParameterByName('type');
const { basicInfo, startCheck } = props;
const { taskName, coverUrl, helpStoreUserIds, timeType, startTime, endTime, learnType, assignList, introduce } = basicInfo;
const [imageFile, setImageFile] = useState(null); // 需要被截取的图片
......@@ -94,18 +97,21 @@ function BasicInfo(props) {
}
function confirmAddCollaborator(data) {
const helpStoreUserIds = data.map((item) => item.userId);
props.onChange('helpStoreUserIds', helpStoreUserIds);
props.onChange('helpStoreUserIds', data);
}
function confirmAddAssignor(data) {
props.onChange('assignList', data);
}
function removeSelectedCollaborator(tag, index) {
const _helpStoreUserIds = helpStoreUserIds.filter((item) => item !== tag);
function removeSelectedCollaborator(tag) {
const _helpStoreUserIds = helpStoreUserIds.filter((item) => item.userId !== tag);
props.onChange('helpStoreUserIds', _helpStoreUserIds);
}
function test(data) {
console.log(data);
props.onChange('introduce', data);
// props.onChange('introduce', data);
function removeCheckedAssignor(tag) {
const _assignList = assignList.filter((item) => item.id !== tag.id);
props.onChange('assignList', _assignList);
}
return (
......@@ -148,6 +154,7 @@ function BasicInfo(props) {
<div className='duration__wrap'>
<Radio.Group
value={timeType}
disabled={taskState === 'STARTING'}
onChange={(e) => {
props.onChange('timeType', e.target.value);
}}>
......@@ -172,6 +179,7 @@ function BasicInfo(props) {
}}
disabledDate={disabledDate}
disabledTime={disabledRangeTime}
disabled={[type === 'edit' && taskState === 'STARTING', false]}
value={[startTime ? moment(Number(startTime)) : null, endTime ? moment(Number(endTime)) : null]}
format='YYYY-MM-DD HH:mm'
onChange={(date) => {
......@@ -188,7 +196,7 @@ function BasicInfo(props) {
</FormItem>
<FormItem label='学习模式' required extra={<div className='learning-model-tips'>提示:任务开始后学习模式将不允许更换</div>}>
<div className='learning-model__wrap'>
<Radio.Group value={learnType} onChange={(e) => props.onChange('learnType', e.target.value)}>
<Radio.Group value={learnType} disabled={taskState === 'STARTING'} onChange={(e) => props.onChange('learnType', e.target.value)}>
<Space direction='vertical' size={16}>
<Radio value='FREEDOM'>自由学习</Radio>
<Radio value='BREAKTHROUGH_LEARNING'>
......@@ -214,7 +222,7 @@ function BasicInfo(props) {
<FormItem
label={
<span>
闯关学习
指派对象
<Tooltip title='选择员工协同完成任务指派和督学工作'>
<i
className='icon iconfont'
......@@ -230,7 +238,10 @@ function BasicInfo(props) {
</Tooltip>
</span>
}
required>
required
// validateStatus={startCheck && assignList.length === 0 ? 'error' : ''}
// help={startCheck && assignList.length === 0 && '请选择培训时间'}>
>
<Button
style={{ display: 'block' }}
onClick={() => {
......@@ -238,14 +249,18 @@ function BasicInfo(props) {
}}>
添加指派对象
</Button>
{assignList > 0 && (
{/* {assignList.length > 0 && (
<Space size={'12'} direction={'vertical'} className='select-obj'>
{assignList.length > 0 && (
<div className='obj-type-container'>
<div className='type-title'>已选组织:</div>
<div className='tag-box'>
{_.map(assignList, (item) => {
return <Tag closable>{item.name}</Tag>;
{_.map(assignList, (tag) => {
return (
<Tag key={tag.id} onClose={() => removeCheckedAssignor(tag)} closable>
{tag.name}
</Tag>
);
})}
</div>
</div>
......@@ -254,14 +269,18 @@ function BasicInfo(props) {
<div className='obj-type-container'>
<div className='type-title'>已选学员:</div>
<div className='tag-box'>
{_.map(assignList, (item) => {
return <Tag closable>{item.name}</Tag>;
{_.map(assignList, (tag) => {
return (
<Tag key={tag.id} onClose={() => removeCheckedAssignor(tag)} closable>
{tag.name}
</Tag>
);
})}
</div>
</div>
)}
</Space>
)}
)} */}
</FormItem>
<FormItem
label={
......@@ -291,9 +310,9 @@ function BasicInfo(props) {
</Button>
{helpStoreUserIds.length > 0 && (
<div className='select-obj'>
{_.map(helpStoreUserIds, (tag, index) => {
{_.map(helpStoreUserIds, (tag) => {
return (
<Tag key={tag.id} onClose={() => removeSelectedCollaborator(tag, index)} closable>
<Tag key={tag.userId} onClose={() => removeSelectedCollaborator(tag)} closable>
<WWOpenDataCom type='userName' openid={tag.nickName} />
</Tag>
);
......@@ -310,8 +329,8 @@ function BasicInfo(props) {
detail={{
content: introduce,
}}
onChange={(val, length) => {
test(val);
onChange={(val) => {
props.onChange('introduce', val);
}}
/>
</FormItem>
......@@ -343,14 +362,13 @@ function BasicInfo(props) {
)}
{assignorModalVisible && (
<ChooseAssignorModal
currentAssignorList={assignList}
visible={assignorModalVisible}
type='CUSTOMER'
treeDepType={'DEP_CHAT'}
close={() => {
// closeChooseMembersModal();
onClose={() => {
setAssignorModalVisible(false);
}}
onConfirm={() => {
// confirmAddCustomer();
onConfirm={(data) => {
confirmAddAssignor(data);
}}
/>
)}
......
......@@ -125,12 +125,11 @@
position: fixed;
right: 0;
bottom: 0;
height: 50px;
width: 720px;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 24px;
padding: 16px 24px;
background: #fff;
border-top: 1px solid #e8e8e8;
z-index: 9999;
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-08-03 17:05:32
* @LastEditors: yuananting
* @LastEditTime: 2021-08-09 14:36:05
* @LastEditTime: 2021-08-11 11:49:11
* @Description: 新建培训任务-关联考试抽屉
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -20,7 +20,6 @@ import Bus from '@/core/bus';
function RelatedExamDrawer(props) {
const [showPaperModal, setShowPaperModal] = useState(false);
const [paperInfo, setPaperInfo] = useState({});
const [basicInfo, setBasicInfo] = useState(props.basicInfo);
const [answerAnalysis, setAnswerAnalysis] = useState('RIGHT_OR_WRONG'); // 答案与解析-默认仅显示对错
const [examDesc, setExamDesc] = useState(''); // 考试说明
const [examDuration, setExamDuration] = useState(null); // 考试时长
......@@ -36,6 +35,8 @@ function RelatedExamDrawer(props) {
const [check, setCheck] = useState(false);
const [examTotal, setExamTotal] = useState(0);
const [samePaper, setSamePaper] = useState(false);
const request = useRef(false);
useEffect(() => {
......@@ -55,11 +56,6 @@ function RelatedExamDrawer(props) {
setExamTotal(paperInfo.singleChoiceCnt + paperInfo.multiChoiceCnt + paperInfo.judgeCnt + paperInfo.gapFillingCnt + paperInfo.indefiniteChoiceCnt || 0);
}, [paperInfo.paperId, passRate]);
function disabledDate(current) {
// Can not select days before today and today
return current && current < moment().startOf('day');
}
function handleSave() {
if (request.current) {
return;
......@@ -75,23 +71,28 @@ function RelatedExamDrawer(props) {
resultShow,
resultContent,
answerAnalysis,
examEndTime: basicInfo.endTime,
examStartTime: basicInfo.startTime || new Date().valueOf(), // 新建(永久)取当前时间,固定取培训开始,编辑取培训创建的时间
examEndTime: props.basicInfo.endTime || null,
examStartTime: props.basicInfo.startTime || new Date().valueOf(),
passScore,
source: 0,
tenantId: User.getStoreId(),
userId: User.getStoreUserId(),
};
console.log('sfkajsdfiohasiudfhaiusdfhiaus', params);
console.log('新建入参==============>', params);
if (
!paperId ||
samePaper ||
!examName ||
examName.length > 40 ||
!passRate ||
!examDuration ||
editorTextLength > 1000 ||
(basicInfo.timeType === 'VALIDITY' && basicInfo.startTime && basicInfo.endTime && basicInfo.startTime + examDuration * 60 * 1000 > basicInfo.endTime)
(props.basicInfo.timeType === 'VALIDITY' &&
props.basicInfo.startTime &&
props.basicInfo.endTime &&
props.basicInfo.startTime + examDuration * 60 * 1000 > props.basicInfo.endTime)
) {
return;
}
......@@ -102,7 +103,7 @@ function RelatedExamDrawer(props) {
}, 2000);
TaskCenterService.createTrainingExam(params).then((res) => {
console.log(res);
props.onSave(res.result);
});
}
......@@ -110,7 +111,11 @@ function RelatedExamDrawer(props) {
<Drawer title='添加考试' width={720} maskClosable={false} closable={true} onClose={props.onClose} visible={true} mask className='related-exam-drawer'>
<Form labelCol={{ span: 4 }} wrapperCol={{ span: 20 }} layout='horizontal'>
<div className='module-title'>基本信息</div>
<Form.Item label='选择试卷' validateStatus={check && !paperId ? 'error' : ''} help={check && !paperId && '请选择试卷'} required>
<Form.Item
label='选择试卷'
validateStatus={(check && !paperId) || samePaper ? 'error' : ''}
help={(check && !paperId && '请选择试卷') || (samePaper && '已存在相同试卷')}
required>
<Button
onClick={() => {
setShowPaperModal(true);
......@@ -199,20 +204,20 @@ function RelatedExamDrawer(props) {
validateStatus={
check &&
(!examDuration ||
(basicInfo.timeType === 'VALIDITY' &&
basicInfo.startTime &&
basicInfo.endTime &&
basicInfo.startTime + examDuration * 60 * 1000 > basicInfo.endTime))
(props.basicInfo.timeType === 'VALIDITY' &&
props.basicInfo.startTime &&
props.basicInfo.endTime &&
props.basicInfo.startTime + examDuration * 60 * 1000 > props.basicInfo.endTime))
? 'error'
: ''
}
help={
check &&
((!examDuration && '请输入考试时长') ||
(basicInfo.timeType === 'VALIDITY' &&
basicInfo.startTime &&
basicInfo.endTime &&
basicInfo.startTime + examDuration * 60 * 1000 > basicInfo.endTime &&
(props.basicInfo.timeType === 'VALIDITY' &&
props.basicInfo.startTime &&
props.basicInfo.endTime &&
props.basicInfo.startTime + examDuration * 60 * 1000 > props.basicInfo.endTime &&
'考试时长不得超过培训有效期时长'))
}
required>
......@@ -300,6 +305,17 @@ function RelatedExamDrawer(props) {
{showPaperModal && (
<SelectPaperModal
onSelect={(info) => {
const contentList = props.stageList.map((item) => {
return item.contentList;
});
const existedPaperId = contentList.flat().filter((item) => {
return item.paperId === info.paperId;
});
if (existedPaperId.length > 0) {
setSamePaper(true);
} else {
setSamePaper(false);
}
setPaperInfo(info);
}}
paperInfo={paperInfo}
......
......@@ -23,18 +23,19 @@
}
.finish-standard__warp {
margin-top: 24px;
.module-title {
height: 22px;
font-size: 16px;
color: #333333;
line-height: 22px;
cursor: pointer;
.icon {
font-size: 12px;
margin-left: 8px;
color: #5e606a;
display: inline-block;
vertical-align: middle;
cursor: pointer;
}
.rotate-arrow {
transform: (rotate(180deg));
......
......@@ -2,17 +2,21 @@
* @Author: yuananting
* @Date: 2021-07-28 14:56:52
* @LastEditors: yuananting
* @LastEditTime: 2021-08-09 11:13:14
* @LastEditTime: 2021-08-11 11:01:49
* @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { useState, useEffect } from 'react';
import { Route, withRouter } from 'react-router-dom';
import { Tooltip, Checkbox, Dropdown, Radio, Button, Space, Badge } from 'antd';
import { Tooltip, Checkbox, Dropdown, Radio, Button, Space, Modal, message } from 'antd';
import './TrainList.less';
import { XMTable, PageControl } from '@/components';
import User from '@/common/js/user';
import ENUM from '../../enum';
import TaskCenterService from '@/domains/task-center-domain/TaskCenterService';
import ShareTrainTaskModal from '../modal/ShareTrainTaskModal';
import { LIVE_SHARE } from '@/domains/course-domain/constants';
import Bus from '@/core/bus';
function TrainList(props) {
const {
......@@ -21,14 +25,110 @@ function TrainList(props) {
match,
} = props;
const [shareTrainTaskModal, setShareTrainTaskModal] = useState(null);
// 发布或取消发布培训任务
function updateIssueStateTrain(taskId, issueState) {
Modal.confirm({
title: '提示',
content:
issueState === 'YES'
? '发布后,被指派学员将任务列表中看到该任务,确定要发布?'
: '取消发布后,任务对学员暂不可见,可能会影响正在学习学员,确定要取消?',
okText: '确定',
cancelText: '取消',
icon: <span className='icon iconfont default-confirm-icon'>&#xe6f4;</span>,
onOk: () => {
TaskCenterService.updateIssueStateTraining({
taskId,
issueState,
}).then((res) => {
message.success(issueState === 'YES' ? '发布成功' : '取消发布成功');
Bus.trigger('getTrainingTaskPage');
Bus.trigger('getStoreTaskNum');
});
},
});
}
// 删除培训任务
function deleteTrainTask(taskId) {
Modal.confirm({
title: '你确定要删除吗?',
content: '删除后,此培训任务的用户将无法继续学习,所有学习数据将同步删除不可恢复',
okText: '确定',
cancelText: '取消',
icon: <span className='icon iconfont default-confirm-icon'>&#xe6f4;</span>,
onOk: () => {
TaskCenterService.deleteTrainingTask({
taskId,
}).then((res) => {
message.success('删除成功');
Bus.trigger('getTrainingTaskPage');
Bus.trigger('getStoreTaskNum');
});
},
});
}
// 编辑培训任务-跳转新建/编辑页
function editTrainingTask(item) {
window.RCHistory.push({
pathname: `/create-train-task?type=edit&taskId=${item.taskId}&taskState=${item.taskState}`,
});
}
// 显示分享弹窗
function handleShowShareModal(item) {
const htmlUrl = `${LIVE_SHARE}training_task_detail/${item.taskId}?id=${User.getStoreId()}&storeUserId=${User.getStoreUserId()}`;
const longUrl = htmlUrl;
const shareData = { ...item, longUrl };
const shareTrainTaskModal = (
<ShareTrainTaskModal
data={shareData}
type='liveClass'
close={() => {
setShareTrainTaskModal(null);
}}
/>
);
setShareTrainTaskModal(shareTrainTaskModal);
}
function renderMoreOperate(item) {
const isUnableIssue = item.issueState === 'YES'; // 已发布
const isUnableAbleEdit = item.issueState === 'YES' || item.taskState === 'FINISH'; // 已发布或已结束
const isUnableShare = item.issueState === 'NO' || item.taskState === 'FINISH'; //未发布或已结束
return (
<div className='live-course-more-menu'>
<div className='operate__item'>取消发布</div>
<div className='operate__item'>编辑</div>
<div className='operate__item'>分享</div>
<div className='operate__item'>审批作业</div>
<div className='operate__item'>删除 </div>
{!isUnableIssue && (
<div className='operate__item' onClick={() => updateIssueStateTrain(item.taskId, 'YES')}>
发布
</div>
)}
{isUnableIssue && (
<div className='operate__item' onClick={() => updateIssueStateTrain(item.taskId, 'NO')}>
取消发布
</div>
)}
<div
className={`operate__item ${isUnableAbleEdit && 'disabled'} `}
onClick={() => {
editTrainingTask(item);
}}>
编辑
</div>
<div className={`operate__item ${isUnableShare && 'disabled'} `} onClick={() => handleShowShareModal(item)}>
分享
</div>
{/* <div className='operate__item'>审批作业</div> */}
<div
className='operate__item'
onClick={() => {
deleteTrainTask(item.taskId);
}}>
删除
</div>
</div>
);
}
......@@ -132,7 +232,7 @@ function TrainList(props) {
},
{
title: '培训时间',
width: '14%',
width: '12.5%',
key: 'trainTime',
dataIndex: 'trainTime',
render: (val, record) => {
......@@ -140,7 +240,7 @@ function TrainList(props) {
return <span>不限时</span>;
}
return (
<span style={{ whiteSpace: 'nowrap' }}>
<span>
{window.formatDate('YYYY-MM-DD H:i', record.startTime)}~{window.formatDate('YYYY-MM-DD H:i', record.endTime)}
</span>
);
......@@ -194,9 +294,9 @@ function TrainList(props) {
</div>
<span className='split'> | </span>
<div
className='operate__item'
className={`operate__item ${record.taskState === 'FINISH' && 'disabled'} `}
onClick={() => {
handleShowShareModal(record);
// handleShowShareModal(record);
}}>
指派
</div>
......@@ -305,12 +405,12 @@ function TrainList(props) {
onChange={(e) => {
handleChangeQuery('issueState', e.target.value);
}}>
<Radio.Button value='ALL'>全部(2)</Radio.Button>
<Radio.Button value='YES'>已发布(2)</Radio.Button>
<Radio.Button value='NO'>未发布(10)</Radio.Button>
<Radio.Button value='ALL'>全部({props.storeTaskNum.allNum})</Radio.Button>
<Radio.Button value='YES'>已发布({props.storeTaskNum.issueNum})</Radio.Button>
<Radio.Button value='NO'>未发布({props.storeTaskNum.notIssueNum})</Radio.Button>
</Radio.Group>
<Checkbox style={{ lineHeight: '32px' }} value={myAssist} onChange={(e) => handleChangeQuery('myAssist', e.target.checked)}>
只看我协同的 ({10})
只看我协同的 ({props.storeTaskNum.myAssistNum})
</Checkbox>
</Space>
</div>
......@@ -342,6 +442,7 @@ function TrainList(props) {
/>
</div>
</div>
{shareTrainTaskModal}
</div>
);
}
......
......@@ -109,3 +109,9 @@
}
}
}
.disabled {
color: #ccc !important;
cursor: not-allowed !important;
pointer-events: none !important;
}
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-08-05 17:09:36
* @LastEditors: yuananting
* @LastEditTime: 2021-08-06 17:23:31
* @LastEditTime: 2021-08-10 20:21:36
* @Description: 新建培训任务-选择指派对象
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -21,6 +21,7 @@ import StoreService from '@/domains/store-domain/storeService';
// import SearchUser from '../components/SearchUser';
import WWOpenDataCom from '@/components/WWOpenDataCom';
import './ChooseAssignorModal.less';
import Item from 'antd/lib/list/Item';
// import _ from 'underscore';
const { Search } = Input;
......@@ -30,6 +31,8 @@ const { DirectoryTree } = Tree;
function ChooseAssignorModal(props) {
const [structureData, setStructureData] = useState([]);
const [activeKey, setActiveKey] = useState('departMentTab');
const [checkedAssignorList, setCheckedAssignorList] = useState(props.currentAssignorList || []); // 勾选的指派对象
const [checkedAssignorKeys, setCheckedAssignorKeys] = useState(props.currentAssignorList.map((item) => item.id) || []);
useEffect(() => {
getStructureData();
......@@ -53,6 +56,9 @@ function ChooseAssignorModal(props) {
function handleStructureData(dataArray) {
const _dataArray = dataArray.map((item, index) => {
item.key = item.id;
if (item.depLevel === 0) {
item.disableCheckbox = true;
}
if (item.sonDepartmentVOList) {
item.children = item.sonDepartmentVOList;
handleStructureData(item.sonDepartmentVOList);
......@@ -62,17 +68,40 @@ function ChooseAssignorModal(props) {
return _dataArray;
}
function onSelectAssignor(value) {}
function onCheckAssignor(key, e) {
const { node, checked } = e;
let _checkedAssignorList = [...checkedAssignorList];
if (checked) {
_checkedAssignorList.push(node);
} else {
_checkedAssignorList = checkedAssignorList.filter((item) => item.id !== node.id);
}
const _checkedAssignorKeys = _checkedAssignorList.map((item) => item.id);
setCheckedAssignorKeys(_checkedAssignorKeys);
setCheckedAssignorList(_checkedAssignorList);
}
function removeCheckedAssignor(item) {
const _checkedAssignorList = checkedAssignorList.filter((innerItem) => innerItem.id !== item.id);
const _checkedAssignorKeys = _checkedAssignorList.map((item) => item.id);
setCheckedAssignorKeys(_checkedAssignorKeys);
setCheckedAssignorList(_checkedAssignorList);
}
function clearCheckedAssignor() {
setCheckedAssignorKeys([]);
setCheckedAssignorList([]);
}
return (
<Modal
className='choose-assignor-modal'
title='添加指派对象'
visible={true}
// onCancel={props.onClose}
onCancel={props.onClose}
onOk={() => {
// props.onConfirm(seletedAssignorList);
// props.onClose();
props.onConfirm(checkedAssignorList);
props.onClose();
}}
width={680}
maskClosable={false}>
......@@ -97,8 +126,8 @@ function ChooseAssignorModal(props) {
checkable
showIcon={false}
treeData={structureData}
// selectedKeys={selectedKeys}
onSelect={onSelectAssignor}
checkedKeys={checkedAssignorKeys}
onCheck={(key, e) => onCheckAssignor(key, e)}
titleRender={(nodeData) => {
return (
<div className='node-title-div'>
......@@ -124,11 +153,27 @@ function ChooseAssignorModal(props) {
<div className='right-list'>
<div className='header-line'>
<span className='tip-text'>已选择</span>
<span className='clear-btn' onClick={() => {}}>
<span className='clear-btn' onClick={clearCheckedAssignor}>
清空
</span>
</div>
<div className='data-body'></div>
<div className='data-body'>
{checkedAssignorList.map((item, index) => {
return (
<div className='selected-item'>
<span className='item-name'>
<span className='icon iconfont avatar-icon'>&#xe84a;</span>
<Tooltip title={item.name}>
<span className='name-text'>{item.name}</span>
</Tooltip>
</span>
<span className='icon iconfont clear-icon' onClick={() => removeCheckedAssignor(item)}>
&#xe717;
</span>
</div>
);
})}
</div>
</div>
</div>
</Modal>
......
......@@ -89,7 +89,7 @@
padding: 12px 12px 12px 16px;
display: flex;
justify-content: space-between;
.user-name {
.item-name {
width: 80%;
overflow: hidden;
text-overflow: ellipsis;
......
......@@ -207,10 +207,10 @@ function ChooseCollaboratorModal(props) {
{seletedCollaboratorList.map((item, index) => {
return (
<div className='selected-item'>
<span className='user-name'>
<span className='item-name'>
<span className='icon iconfont avatar-icon'>&#xe84a;</span>
<Tooltip title={<WWOpenDataCom type='userName' openid={item.nickName} />}>
<span className='user-name'>
<span className='name-text'>
<WWOpenDataCom type='userName' openid={item.nickName} />
</span>
</Tooltip>
......
......@@ -64,7 +64,7 @@
padding: 12px 12px 12px 16px;
display: flex;
justify-content: space-between;
.user-name {
.item-name {
width: 80%;
overflow: hidden;
text-overflow: ellipsis;
......
/*
* @Author: 吴文洁
* @Date: 2020-07-20 19:12:49
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-07-20 20:25:13
* @Description: 大班直播分享弹窗
*/
import React from 'react';
import { Modal, Button, message } from 'antd';
import domtoimage from 'dom-to-image';
import qrcode from '@/libs/qrcode/qrcode.js';
import User from '@/common/js/user';
import $ from 'jquery';
import CourseService from '@/domains/course-domain/CourseService';
import './ShareTrainTaskModal.less';
const DEFAULT_COVER = 'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png';
class ShareTrainTaskModal extends React.Component {
constructor(props) {
super(props);
this.state = {
shareUrl: '',
};
}
componentDidMount() {
// 获取短链接
this.handleConvertShortUrl();
}
handleConvertShortUrl = () => {
const { longUrl } = this.props.data;
// 发请求
CourseService.getQrcode({
urls: [longUrl],
}).then((res) => {
const { result = [] } = res;
this.setState(
{
shareUrl: result[0].shortUrl,
},
() => {
const qrcodeWrapDom = document.querySelector('#qrcodeWrap');
const qrcodeNode = new qrcode({
text: this.state.shareUrl,
size: 98,
});
qrcodeWrapDom.appendChild(qrcodeNode);
const qrcodeWrapDomDownload = document.querySelector('#qrcodeWrap-dowload');
const qrcodeNodeDownLoad = new qrcode({
text: this.state.shareUrl,
size: 196,
});
qrcodeWrapDomDownload.appendChild(qrcodeNodeDownLoad);
}
);
});
};
componentWillUnmount() {
// 页面销毁之前清空定时器
clearTimeout(this.timer);
}
// 下载海报
handleDownloadPoster = () => {
this.setState(
{
showImg: true,
time: new Date().valueOf(),
},
() => {
this.setState({ time: new Date().valueOf() }, () => {
let node = document.getElementById('poster-dowload');
domtoimage.toPng(node).then((imgData) => {
const download = document.createElement('a');
const { planName } = this.props.data;
$(download).attr('href', imgData).attr('download', `${planName}.png`).get(0).click();
});
});
}
);
};
// 复制分享链接
handleCopy = () => {
const textContent = document.getElementById('shareUrl').innerText;
window.copyText(textContent);
message.success('复制成功!');
};
render() {
const { data } = this.props;
const { planName, coverUrl = DEFAULT_COVER } = data;
const { shareUrl, showImg, time } = this.state;
return (
<Modal
title={'分享培训任务'}
width={680}
visible={true}
footer={null}
maskClosable={false}
closeIcon={<span className='icon iconfont modal-close-icon'>&#xe6ef;</span>}
className='share-task-modal'
onCancel={this.props.close}>
<div className='left'>
<div id='poster'>
<div className='store-name'>
<span className='text'>{User.getStoreName()}</span>
</div>
<div className='course-name-title'>邀请你参与培训:</div>
<div className='live-couse-name'>{planName}</div>
<Choose>
<When condition={showImg}>
<img crossOrigin='*' src={coverUrl + `?=${time}`} className='course-cover' alt='' />
</When>
<Otherwise>
<img src={coverUrl + `?=${time}`} className='course-cover' alt='' />
</Otherwise>
</Choose>
<div className='qrcode-wrap'>
<div className='qrcode-wrap__left'>
<div className='text'>长按识别二维码进入观看</div>
<img className='finger' src='https://image.xiaomaiketang.com/xm/thpkWDwJsC.png' alt='' />
</div>
<div className='qrcode-wrap__right' id='qrcodeWrap'></div>
</div>
</div>
<div id='poster-dowload'>
<div className='store-name'>
<span className='text'>{User.getStoreName()}</span>
</div>
<div className='course-name-title'>邀请你参与培训:</div>
<div className='live-couse-name'>{planName}</div>
<Choose>
<When condition={showImg}>
<img crossOrigin='*' src={coverUrl + `?=${time}`} className='course-cover' alt='' />
</When>
<Otherwise>
<img src={coverUrl + `?=${time}`} className='course-cover' alt='' />
</Otherwise>
</Choose>
<div className='qrcode-wrap'>
<div className='qrcode-wrap__left'>
<div className='text'>长按识别二维码进入观看</div>
<img className='finger' src='https://image.xiaomaiketang.com/xm/thpkWDwJsC.png' alt='' />
</div>
<div className='qrcode-wrap__right' id='qrcodeWrap-dowload'></div>
</div>
</div>
</div>
<div className='right'>
<div className='share-poster right__item'>
<div className='title'>① 海报分享</div>
<div className='sub-title'>学员可通过微信扫描海报二维码,查看培训计划</div>
<div className='content' onClick={this.handleDownloadPoster}>
下载海报
</div>
</div>
<div className='share-url right__item'>
<div className='title'>② 链接分享</div>
<div className='sub-title'>学员可通过微信或浏览器打开以下链接,查看培训计划</div>
<div className='content url-content'>
<div className='share-url' id='shareUrl'>
{shareUrl}
</div>
<Button type='primary' onClick={this.handleCopy}>
复制
</Button>
</div>
</div>
</div>
</Modal>
);
}
}
export default ShareTrainTaskModal;
.share-task-modal {
.ant-modal-body {
display: flex;
height: 510px !important;
overflow: hidden !important;
.left {
width: 303px;
margin: 0 32px 0 16px;
box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.05);
border-radius: 12px;
#poster {
background: #fff;
margin: 0;
padding: 20px;
margin-bottom: 140px;
.course-name-title {
font-size: 14px;
color: #333;
line-height: 20px;
margin-bottom: 4px;
}
.live-couse-name {
font-size: 16px;
color: #333333;
font-weight: 600;
}
.course-name {
color: #333;
font-size: 16px;
font-weight: 600;
line-height: 20px;
}
.course-cover {
width: 263px;
height: 143px;
border-radius: 6px;
margin-top: 8px;
}
.qrcode-wrap {
padding: 0 16px;
display: flex;
align-items: center;
margin: 24px 0 16px 0;
&__left {
width: 98px;
text-align: center;
margin-right: 22px;
.text {
line-height: 20px;
}
.finger {
width: 40px;
height: 40px;
margin-top: 8px;
}
}
&__right {
width: 110px;
height: 110px;
padding: 6px;
}
}
.store-name {
// padding: 8px 16px;
display: flex;
align-items: center;
margin-bottom: 8px;
.text {
font-size: 12px;
color: #999;
font-size: 14px;
line-height: 20px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 100%;
}
}
}
#poster-dowload {
background: #fff;
margin: 0;
padding: 40px;
width: 606px;
.course-name-title {
font-size: 28px;
color: #333;
line-height: 40px;
margin-bottom: 8px;
}
.live-couse-name {
font-size: 32px;
color: #333333;
font-weight: 600;
}
.course-name {
color: #333;
font-size: 32px;
font-weight: 600;
line-height: 40px;
}
.course-cover {
width: 526px;
height: 286px;
border-radius: 6px;
margin-top: 16px;
}
.qrcode-wrap {
padding: 0 32px;
display: flex;
align-items: center;
margin: 48px 0 32px 0;
&__left {
width: 196px;
text-align: center;
margin-right: 44px;
.text {
line-height: 40px;
}
.finger {
width: 80px;
height: 80px;
margin-top: 16px;
}
}
&__right {
width: 220px;
height: 220px;
padding: 12px;
}
}
.store-name {
// padding: 8px 16px;
display: flex;
align-items: center;
margin-bottom: 16px;
.text {
font-size: 12px;
color: #999;
font-size: 28px;
line-height: 40px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 100%;
}
}
}
}
.right {
.title {
color: #333;
font-weight: 500;
}
.sub-title {
color: #999;
margin-top: 16px;
}
.content {
display: flex;
align-items: center;
margin-top: 8px;
.share-url {
width: 212px;
overflow: hidden;
height: 28px;
line-height: 28px;
border-radius: 4px 0 0 4px;
padding-left: 12px;
white-space: nowrap;
color: #999999;
background: #efefef;
}
.ant-btn {
margin-left: -2px;
}
}
.url-content {
position: relative;
&:after {
content: '';
width: 12px;
height: 22px;
background: #efefef;
position: absolute;
right: 71px;
}
}
.share-poster {
margin-bottom: 40px;
.content {
color: #2966ff;
cursor: pointer;
}
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment