Commit ba7900dc by maolipeng

Merge branch 'master' into feature/maolipeng/20210610/zuhuyouhua

# Conflicts:
#	src/common/js/user.ts
#	src/modules/root/Menu.tsx
parents 8120a9da 9e611ef6
......@@ -105,6 +105,10 @@
},
"scripts": {
"start": "node scripts/start.js",
"start:dev": "cross-env DEPLOY_ENV=dev node scripts/start.js",
"start:dev1": "cross-env DEPLOY_ENV=dev node scripts/start.js",
"start:rc": "cross-env DEPLOY_ENV=rc node scripts/start.js",
"start:gray": "cross-env DEPLOY_ENV=gray node scripts/start.js",
"build:dev": "cross-env DEPLOY_ENV=dev node scripts/build.js",
"build:dev1": "cross-env DEPLOY_ENV=dev node scripts/build.js",
"build:rc": "cross-env DEPLOY_ENV=rc node scripts/build.js",
......
......@@ -10,6 +10,8 @@ import Service from '@/common/js/service';
// import _ from 'underscore';
import './ChooseMembersModal.less';
import User from '@/common/js/user'
import { XMTable } from '@/components';
import college from '@/common/lottie/college';
const { Search } = Input;
......@@ -155,7 +157,7 @@ class ChooseMembersModal extends React.Component {
let rightsList = []; // 保存新加进去的成员
selectUserList.map((item) => {
rightsList.push({
rights: "LOOK_DOWNLOAD",
rights: "LOOK",
userId: item.userId
})
return rightsList
......@@ -203,10 +205,8 @@ class ChooseMembersModal extends React.Component {
title: '全选', // 实际为头像,但在表格上这行要求显示为全选
key: 'avatar',
dataIndex: 'avatar',
width: '40%',
render: (value, record) => {
const { adminName } = record;
return (
<div className='avatar'>
{
......@@ -232,7 +232,7 @@ class ChooseMembersModal extends React.Component {
title: '学员名',
key: 'adminNameRight',
dataIndex: 'adminName',
width: '70%',
width: '65%',
render: (value, record) => {
const { adminName = '', avatar } = record;
return (
......@@ -293,16 +293,19 @@ class ChooseMembersModal extends React.Component {
enterButton={<span className="icon iconfont">&#xe832;</span>}
/>
<div className='container-left-body-table'>
<Table
<XMTable
renderEmpty={{
image: college,
description: '暂无数据'
}}
rowKey={(record) => record.userId}
dataSource={allUserList}
columns={this.selectedColumnsLeft()}
pagination={false}
scroll={{ y: 290}}
// bordered={true}
size={'small'}
rowSelection={{
columnWidth : 24,
columnWidth : 63,
selectedRowKeys,
onChange : this.onChangeRow,
getCheckboxProps : this.getCheckboxProps,
......@@ -326,7 +329,11 @@ class ChooseMembersModal extends React.Component {
<span className={ (selectUserList.length > 0) ? 'span-right-l' : null }>清空</span>
</div>
<div className='container-right-body'>
<Table
<XMTable
renderEmpty={{
image: college,
description: '暂无数据'
}}
rowKey={(record) => record.userId}
dataSource={selectUserList}
columns={this.selectedColumnsRight()}
......
......@@ -37,7 +37,7 @@
>tr >td {
border-bottom: none;
background-color: #fff !important;
padding:8px 8px !important;
}
}
}
......@@ -45,6 +45,14 @@
.ant-empty-normal {
margin: 100px 0 !important;
}
.ant-empty {
margin-top: 60px;
}
.ant-empty-description {
color: #999;
}
.avatar{
display: flex;
align-items: center;
......@@ -119,6 +127,13 @@
margin: 144px 0 !important;
}
.ant-empty {
margin-top: 60px;
}
.ant-empty-description {
color: #999;
}
.avatar{
display: flex;
align-items: center;
......
......@@ -8,7 +8,7 @@ import React from 'react';
import { Modal, Button, Breadcrumb, Radio, message } from 'antd';
import Service from '@/common/js/service';
import { FILE_TYPE_ICON_MAP, DEFAULT_SIZE_UNIT } from "@/domains/resource-disk/constants";
import { LottieIcon } from 'xiaomai-b-components';
import LottieIcon from '@/components/LottieIcon';
import _ from 'underscore';
import { getEllipsText } from "@/domains/basic-domain/utils";
import * as lodash from 'lodash';
......@@ -80,7 +80,7 @@ class CopyFileModal extends React.Component {
// const { folderPathList, folderList } = this.state;
const { folderPathList, disk } = this.state;
const { dataInfo } = this.props;
const { id, createId, folderName } = dataInfo;
const { id, createId, folderName,folderType} = dataInfo;
const newParentId = folderPathList[folderPathList.length-1].id;
const _params = {
copyIds : [id], // 复制文件的ID
......@@ -99,7 +99,10 @@ class CopyFileModal extends React.Component {
}
return allowCopy;
})
if(folderPathList.length > 9 && folderType === 'FOLDER'){
allowCopy = 1;
message.warning('不能将文件夹复制到10级目录下');
}
if (allowCopy === 0) {
Service.Hades('public/hadesStore/copyFolder', _params).then((res) => {
if (res.success) {
......@@ -331,6 +334,8 @@ class CopyFileModal extends React.Component {
<div className="lottie-box">
<LottieIcon
title={<span className="desc">这个文件夹是空的</span>}
type="college"
size={150}
/>
</div>
}
......
......@@ -57,12 +57,17 @@
}
}
.lottie-box {
border:1px solid #E8E8E8;
border-radius:4px;
height: 320px;
.copy-body {
.lottie-box {
border:1px solid #E8E8E8;
border-radius:4px;
height: 320px;
}
.lottie-icon{
margin: 70px 0 !important;
.lottie-icon__title {
color: #999;
}
}
}
.lottie-icon{
margin: 100px 0;
}
\ No newline at end of file
......@@ -19,7 +19,7 @@ class ManagingMembersModal extends React.Component {
addManagingMember: false, // 是否点击了添加成员
storeId :User.getStoreId() , // 学院Id
iconRotateList: [],
userAuthority : ['可编辑', '可查看/下载', '仅可查看', '', '创建者', '学院管理员'] , // 空 代表删除
userAuthority : ['可编辑', '可下载', '可查看', '', '创建者', '学院管理员'] , // 空 代表删除
}
}
componentDidMount() {
......@@ -64,7 +64,7 @@ class ManagingMembersModal extends React.Component {
// 修改成员权限
updateFileUserAuthority = (params, newRights = 1) => {
const rightList = ['EDIT', 'LOOK_DOWNLOAD', ''];
const rightList = ['EDIT', 'LOOK_DOWNLOAD', 'LOOK'];
let { iconRotateList } = this.state;
let _params = params;
_params.rights = rightList[newRights];
......@@ -173,10 +173,10 @@ class ManagingMembersModal extends React.Component {
<span className='menu-bottom'>下载、复制</span>
</div>
</Menu.Item>
{/* <Menu.Item key="LOOK" >
<div onClick={() => this.updateFileUserAuthority(params, 2)}>仅可查看</div>
<span className='menu-bottom'>{userAuthority[2]}</span>
</Menu.Item> */}
<Menu.Item key="LOOK" >
<div onClick={() => this.updateFileUserAuthority(params, 2)}>{userAuthority[2]}</div>
<span className='menu-bottom'>查看</span>
</Menu.Item>
<Menu.Divider key='LINE'/>
<Menu.Item key="REMOVE" >
<div className='remove' onClick={() => this.removeUser(params, userAuthority[3])}>移除</div>
......@@ -247,6 +247,8 @@ class ManagingMembersModal extends React.Component {
num = 1;
} else if (record.rights === "EDIT") {
num = 0;
}else if(record.rights=="LOOK"){
num = 2;
}
}
return (
......
......@@ -35,6 +35,9 @@
.ant-table-row{
background-color: #fff !important;
}
tr:first-child{
display: none;
}
.ant-table-row:hover{
background-color: #E9E9E9;
}
......
......@@ -10,7 +10,7 @@ import React from 'react';
import { Modal, Button, Radio, Checkbox, message, Tooltip } from 'antd';
import _ from 'underscore';
import * as lodash from 'lodash';
import { LottieIcon } from 'xiaomai-b-components';
import LottieIcon from '@/components/LottieIcon';
import Service from '@/common/js/service';
import { getEllipsText } from "@/domains/basic-domain/utils";
......@@ -647,6 +647,8 @@ class SelectPrepareFileModal extends React.Component {
<Otherwise>
<LottieIcon
title={<span className="desc">这个文件夹是空的</span>}
type="college"
size={150}
/>
</Otherwise>
</Choose>
......
......@@ -4,10 +4,10 @@
}
.lottie-icon {
margin: 12px 0 0 0;
margin: 0;
border: 1px solid #E8E8E8;
border-radius: 4px;
padding: 100px 0;
padding: 69px 0 59px 0;
.desc {
color: #999;
......
......@@ -3,7 +3,7 @@
* @Date: 2020-08-31 09:34:25
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-05-12 17:27:08
* @Description:
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -21,26 +21,29 @@ class User {
}
getEnterpriseId() {
return Storage.get(`${PREFIX}_enterpriseId`)
return Storage.get(`${PREFIX}_enterpriseId`);
}
getStoreName(){
return Storage.get(`${PREFIX}_storeName`)
getStoreName() {
return Storage.get(`${PREFIX}_storeName`);
}
getStoreType(){
return Storage.get(`${PREFIX}_storeType`)
getStoreType() {
return Storage.get(`${PREFIX}_storeType`);
}
getStoreUserId(){
return Storage.get(`${PREFIX}_storeUserId`)
getStoreUserId() {
return Storage.get(`${PREFIX}_storeUserId`);
}
getUserId(){
return Storage.get(`${PREFIX}_userId`)
getCustomerId() {
return Storage.get(`${PREFIX}_customerId`);
}
getUserRole(){
return Storage.get(`${PREFIX}_userRole`)
getUserId() {
return Storage.get(`${PREFIX}_userId`);
}
getUserRole() {
return Storage.get(`${PREFIX}_userRole`);
}
getToken() {
......@@ -60,62 +63,66 @@ class User {
}
setEnterpriseId(value: any) {
return Storage.set(`${PREFIX}_enterpriseId`,value)
return Storage.set(`${PREFIX}_enterpriseId`, value);
}
setStoreName(value: any) {
return Storage.set(`${PREFIX}_storeName`, value);
}
setStoreName(value:any){
return Storage.set(`${PREFIX}_storeName`,value)
setStoreType(value: any) {
return Storage.set(`${PREFIX}_storeType`, value);
}
setStoreType(value:any){
return Storage.set(`${PREFIX}_storeType`,value)
setStoreUserId(value: any) {
return Storage.set(`${PREFIX}_storeUserId`, value);
}
setStoreUserId(value:any){
return Storage.set(`${PREFIX}_storeUserId`,value)
setCustomerId(value: any) {
return Storage.set(`${PREFIX}_customerId`, value);
}
setUserId(value:any){
return Storage.set(`${PREFIX}_userId`,value)
setUserId(value: any) {
return Storage.set(`${PREFIX}_userId`, value);
}
setUserRole(value:any){
return Storage.set(`${PREFIX}_userRole`,value)
setUserRole(value: any) {
return Storage.set(`${PREFIX}_userRole`, value);
}
setToken(value:any) {
return Storage.set(`${PREFIX}_token`,value);
setToken(value: any) {
return Storage.set(`${PREFIX}_token`, value);
}
setIsAdmin(value: any) {
return Storage.set(`${PREFIX}_isAdmin`, value);
}
removeToken(){
removeToken() {
return Storage.remove(`${PREFIX}_token`);
}
removeUserId(){
removeUserId() {
return Storage.remove(`${PREFIX}_userId`);
}
removeEnterpriseId() {
return Storage.remove(`${PREFIX}_enterpriseId`)
return Storage.remove(`${PREFIX}_enterpriseId`);
}
getCustomerStoreId(){
getCustomerStoreId() {
return Storage.get(`${PREFIX}_customerStoreId`);
}
setCustomerStoreId(value:any) {
return Storage.set(`${PREFIX}_customerStoreId`,value);
setCustomerStoreId(value: any) {
return Storage.set(`${PREFIX}_customerStoreId`, value);
}
setIdentifier(value:any){
return Storage.set(`${PREFIX}_identifier`,value);
setIdentifier(value: any) {
return Storage.set(`${PREFIX}_identifier`, value);
}
getIdentifier(){
getIdentifier() {
return Storage.get(`${PREFIX}_identifier`);
}
clearUserInfo(){
clearUserInfo() {
Storage.remove(`${USER_PREFIX}_token`);
Storage.remove(`${USER_PREFIX}_userId`);
Storage.remove(`${USER_PREFIX}_userPhone`);
......@@ -127,4 +134,4 @@ class User {
}
}
export default new User();
\ No newline at end of file
export default new User();
.lottie-icon{
text-align: center;
margin-top: 200px;
margin-bottom: 50px;
&__title{
font-size:14px;
font-family:PingFangSC-Regular;
font-weight:400;
color:#999;
line-height:20px;
margin-top: 20px;
}
}
\ No newline at end of file
/*
* @Author: wufan
* @Date: 2021-06-15 13:48:35
* @LastEditors: wufan
* @LastEditTime: 2021-06-15 14:24:57
* @Description: Description
*/
import React from 'react';
import Lottie from 'react-lottie';
import student from '@/common/lottie/student.json';
import activity from '@/common/lottie/activity.json';
import teacher from '@/common/lottie/teacher.json';
import college from '@/common/lottie/college.json';
import './LottieIcon.less';
interface LottieIconInterface {
size: number,
type: string,
title: string,
isStopped: boolean,
isPaused: boolean,
}
const ANIMATION_DATA_MAP: {
[key: string]: any,
} = {
student,
activity,
teacher,
college
}
function LottieIcon(props: LottieIconInterface) {
const {
title,
size = 90,
type = 'student',
isPaused = true,
isStopped = true,
} = props;
const options = {
loop: true,
autoplay: true,
animationData: ANIMATION_DATA_MAP[type],
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice'
}
}
return (
<div className="lottie-icon">
<Lottie
options={options}
width={size}
height={size}
isPaused={isPaused}
isStopped={isStopped}
/>
<div className="lottie-icon__title">{title}</div>
</div>
)
}
export default LottieIcon;
\ No newline at end of file
/*
* @Author: wufan
* @Date: 2021-05-26 10:29:56
* @LastEditors: wufan
* @LastEditTime: 2021-06-17 14:15:00
* @Description: Description
*/
import React from "react";
import { Tag } from 'antd'
import "./WatchDataHeader.less";
interface WatchDataHeaderProps {
......
import React, { useEffect, useState } from 'react';
import { Empty, ConfigProvider, Table } from 'antd';
import Lottie from 'react-lottie';
import * as nodata from '../modules/lottie/nodata/data.json';
function XMTable(props) {
const [empty, setEmpty] = useState(props.renderEmpty || {});
......@@ -12,9 +14,25 @@ function XMTable(props) {
// 自定义表格空状态
function customizeRenderEmpty() {
const defaultOptions = {
loop: true,
autoplay: true,
animationData: empty.image || nodata,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice'
}
}
return (
<Empty
image={empty.image || Empty.PRESENTED_IMAGE_SIMPLE}
image={<div style={{ marginTop: 24 }}>
<Lottie
options={defaultOptions}
height={150}
width={150}
isStopped={false}
isPaused={false}
/>
</div>}
imageStyle={{
height: 150,
}}
......
......@@ -7,7 +7,7 @@
left: 0px;
right: 0;
bottom: 0;
z-index:3;
z-index: 3;
background-color: #fff;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
......@@ -20,12 +20,12 @@
bottom: 0;
z-index: 102;
overflow: auto;
margin:0 16px;
.box{
&:first-child{
margin: 0 16px;
.box {
&:first-child {
margin-bottom: 8px;
}
&:last-child{
&:last-child {
margin-bottom: 16px;
}
}
......@@ -48,10 +48,10 @@
.content-header {
padding: 16px 16px 8px 16px;
line-height: 30px;
font-size:24px;
color:#333;
font-weight:bold;
background: #FFF;
font-size: 24px;
color: #333;
font-weight: bold;
background: #fff;
h1 {
font-weight: normal;
display: inline-block;
......
......@@ -2,89 +2,89 @@
* @Author: yuananting
* @Date: 2021-03-03 15:13:12
* @LastEditors: fusanqiasng
* @LastEditTime: 2021-05-25 10:07:03
* @LastEditTime: 2021-06-16 09:57:18
* @Description: 助学工具接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import Service from '@/common/js/service'
import Service from '@/common/js/service';
export function queryExternalCategoryTree(params: object) {
return Service.Hades('public/externalHades/queryCategoryTree', params)
return Service.Hades('public/externalHades/queryCategoryTree', params);
}
export function queryCategoryTree(params: object) {
return Service.Hades('public/hades/queryCategoryTree', params)
return Service.Hades('public/hades/queryCategoryTree', params);
}
export function addCategory(params: object) {
return Service.Hades('public/hades/addCategory', params)
return Service.Hades('public/hades/addCategory', params);
}
export function delCategory(params: object) {
return Service.Hades('public/hades/delCategory', params)
return Service.Hades('public/hades/delCategory', params);
}
export function editCategory(params: object) {
return Service.Hades('public/hades/editCategory', params)
return Service.Hades('public/hades/editCategory', params);
}
export function editCategoryTree(params: object) {
return Service.Hades('public/hades/editCategoryTree', params)
export function moveCategory(params: object) {
return Service.Hades('public/hades/moveCategory', params);
}
export function queryQuestionPageList(params: object) {
return Service.Hades('public/hades/queryQuestionPageList', params)
return Service.Hades('public/hades/queryQuestionPageList', params);
}
export function addQuestion(params: object) {
return Service.Hades('public/hades/addQuestion', params)
return Service.Hades('public/hades/addQuestion', params);
}
export function deleteQuestion(params: object) {
return Service.Hades('public/hades/deleteQuestion', params)
return Service.Hades('public/hades/deleteQuestion', params);
}
export function queryQuestionDetails(params: object) {
return Service.Hades('public/hades/queryQuestionDetails', params)
return Service.Hades('public/hades/queryQuestionDetails', params);
}
export function editQuestion(params: object) {
return Service.Hades('public/hades/editQuestion', params)
return Service.Hades('public/hades/editQuestion', params);
}
export function batchImport(params: object) {
return Service.Hades('public/hades/batchImport', params)
return Service.Hades('public/hades/batchImport', params);
}
export function createPaper(params: object) {
return Service.Hades('public/hades/createPaper', params)
return Service.Hades('public/hades/createPaper', params);
}
export function queryPaperPageList(params: object) {
return Service.Hades('public/hades/queryPaperPageList', params)
return Service.Hades('public/hades/queryPaperPageList', params);
}
export function deletePaper(params: object) {
return Service.Hades('public/hades/deletePaper', params)
return Service.Hades('public/hades/deletePaper', params);
}
export function queryPaperDetail(params: object) {
return Service.Hades('public/hades/queryPaperDetail', params)
return Service.Hades('public/hades/queryPaperDetail', params);
}
export function viewPaper(params: object) {
return Service.Hades('public/hades/viewPaper', params)
return Service.Hades('public/hades/viewPaper', params);
}
export function editPaper(params: object) {
return Service.Hades('public/hades/editPaper', params)
return Service.Hades('public/hades/editPaper', params);
}
export function batchQueryQuestionDetails(params: object) {
return Service.Hades('public/hades/batchQueryQuestionDetails', params)
return Service.Hades('public/hades/batchQueryQuestionDetails', params);
}
export function queryQuestionPageListWithContent(params: object) {
return Service.Hades('public/hades/queryQuestionPageListWithContent', params)
return Service.Hades('public/hades/queryQuestionPageListWithContent', params);
}
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-03-11 11:34:37
* @LastEditors: fusanqiasng
* @LastEditTime: 2021-05-24 23:44:39
* @LastEditTime: 2021-06-16 09:56:46
* @Description: 助学工具接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -12,7 +12,7 @@ import {
addCategory,
delCategory,
editCategory,
editCategoryTree,
moveCategory,
addQuestion,
queryQuestionPageList,
deleteQuestion,
......@@ -26,8 +26,8 @@ import {
viewPaper,
editPaper,
batchQueryQuestionDetails,
queryQuestionPageListWithContent
} from '@/data-source/aidTool/request-apis'
queryQuestionPageListWithContent,
} from '@/data-source/aidTool/request-apis';
export default class AidToolService {
/**
* 查询运营端分类书
......@@ -35,101 +35,101 @@ export default class AidToolService {
* @returns
*/
static queryExternalCategoryTree(parmas: any) {
return queryExternalCategoryTree(parmas)
return queryExternalCategoryTree(parmas);
}
// 获取题目分类树
static queryCategoryTree(params: any) {
return queryCategoryTree(params)
return queryCategoryTree(params);
}
// 新增题目分类
static addCategory(params: any) {
return addCategory(params)
return addCategory(params);
}
// 删除分类
static delCategory(params: any) {
return delCategory(params)
return delCategory(params);
}
// 编辑分类
static editCategory(params: any) {
return editCategory(params)
return editCategory(params);
}
// 编辑分类树(拖拽)
static editCategoryTree(params: any) {
return editCategoryTree(params)
// 拖拽移动分类树
static moveCategory(params: any) {
return moveCategory(params);
}
// 查询题目列表
static queryQuestionPageList(params: any) {
return queryQuestionPageList(params)
return queryQuestionPageList(params);
}
// 添加题目
static addQuestion(params: any) {
return addQuestion(params)
return addQuestion(params);
}
// 删除题目
static deleteQuestion(params: any) {
return deleteQuestion(params)
return deleteQuestion(params);
}
// 预览题目
static queryQuestionDetails(params: any) {
return queryQuestionDetails(params)
return queryQuestionDetails(params);
}
// 编辑题目
static editQuestion(params: any) {
return editQuestion(params)
return editQuestion(params);
}
// 批量导入
static batchImport(params: any) {
return batchImport(params)
return batchImport(params);
}
// 创建试卷
static createPaper(params: any) {
return createPaper(params)
return createPaper(params);
}
// 查询试卷列表
static queryPaperPageList(params: any) {
return queryPaperPageList(params)
return queryPaperPageList(params);
}
// 删除试卷
static deletePaper(params: any) {
return deletePaper(params)
return deletePaper(params);
}
// 编辑前查询试卷信息
static queryPaperDetail(params: any) {
return queryPaperDetail(params)
return queryPaperDetail(params);
}
// 预览试卷
static viewPaper(params: any) {
return viewPaper(params)
return viewPaper(params);
}
// 编辑试卷
static editPaper(params: any) {
return editPaper(params)
return editPaper(params);
}
// 操作试卷-预览查询多题目信息
static batchQueryQuestionDetails(params: any) {
return batchQueryQuestionDetails(params)
return batchQueryQuestionDetails(params);
}
// 操作试卷-选择题目列表带题目详情
static queryQuestionPageListWithContent(params: any) {
return queryQuestionPageListWithContent(params)
return queryQuestionPageListWithContent(params);
}
}
/*
* @Author: 陈剑宇
* @Date: 2020-05-07 14:43:01
* @LastEditTime: 2021-05-28 15:20:40
* @LastEditors: fusanqiasng
* @LastEditTime: 2021-06-11 16:44:17
* @LastEditors: Please set LastEditors
* @Description:
* @FilePath: /wheat-web-demo/src/domains/basic-domain/constants.ts
*/
......
/*
* @Author: 吴文洁
* @Date: 2020-08-20 09:21:40
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-02-20 17:08:58
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-11 15:17:56
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......
......@@ -6,9 +6,11 @@
import React from 'react';
import { Modal, Input, Table, message, Tooltip, Empty } from 'antd';
import { XMTable } from '@/components';
import Service from '@/common/js/service';
import User from '@/common/js/user'
import SetEmployeeModal from "./SetEmployeeModal";
import search from '../../lottie/search/data.json';
import './ChooseMembersModal.less';
import _ from 'underscore';
......@@ -208,7 +210,6 @@ class ChooseMembersModal extends React.Component {
title: '全选', // 实际为头像,但在表格上这行要求显示为全选
key: 'avatar',
dataIndex: 'avatar',
width: '40%',
render: (value, record) => {
const { name } = record;
......@@ -311,23 +312,22 @@ class ChooseMembersModal extends React.Component {
enterButton={<span className="icon iconfont">&#xe832;</span>}
/>
<div className='container-left-body-table'>
<Table
<XMTable
rowKey={(record) => record.enterpriseVisibleUserId}
dataSource={allUserList}
columns={this.selectedColumnsLeft()}
pagination={false}
scroll={{ y: 290}}
// bordered={true}
locale={{
emptyText: <div>
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={false} />
<div style={{ color: '#333', marginTop: -70 }}>暂无数据</div>
renderEmpty={{
image: searchKey ? search : '',
description: <div>
<div style={{ color: '#333' }}>暂无数据</div>
<div style={{ color: '#666', padding: '0 32px', fontSize: '12px' }}>需要先将员工添加到企微可见范围后,员工才会出现在这里</div>
</div>,
</div>
}}
size={'small'}
rowSelection={{
columnWidth : 24,
columnWidth : 63,
selectedRowKeys,
onChange : this.onChangeRow,
getCheckboxProps : this.getCheckboxProps,
......
......@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-08-05 10:12:45
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-05-27 20:13:53
* @LastEditTime: 2021-06-15 20:01:05
* @Description: 视频课-列表模块
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -364,7 +364,7 @@ class GraphicsCourseList extends React.Component {
<ShareLiveModal
needStr={needStr}
data={shareData}
type="videoClass"
type="graphicsClass"
title="图文课"
close={() => {
this.setState({
......
/*
* @Author: 吴文洁
* @Date: 2020-06-22 14:26:37
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-07-23 09:33:02
* @Last Modified by: chenshu
* @Last Modified time: 2021-06-08 18:18:46
*/
import React, { useEffect, useState } from 'react';
import { Modal, Button, Table, Progress, message, Tooltip, Spin, Popconfirm } from 'antd';
import React from 'react';
import { Modal, Button, Table, message, Tooltip, Spin, Popconfirm } from 'antd';
import { QuestionCircleOutlined,LoadingOutlined} from "@ant-design/icons";
import _ from 'underscore';
import moment from 'moment';
import Lottie from "lottie-web";
import User from '@/common/js/user';
import { suffixType, DEFAULT_SIZE_UNIT, SupportFileType } from '@/common/constants/academic/liveEnum';
import { FileVerifyMap, FileTypeIcon, DISK_MAP } from '@/common/constants/academic/lessonEnum';
import { suffixType, DEFAULT_SIZE_UNIT } from '@/common/constants/academic/liveEnum';
import { FileVerifyMap, FileTypeIcon } from '@/common/constants/academic/lessonEnum';
import ScanFileModal from '@/modules/prepare-lesson/modal/ScanFileModal'
import SelectPrepareFileModal from '@/modules/prepare-lesson/modal/SelectPrepareFileModal';
import Service from '@/common/js/service';
......@@ -40,7 +40,7 @@ class ManageCoursewareModal extends React.Component {
componentDidMount() {
this.getCoursewareList();
var animation = Lottie.loadAnimation({
path: "https://image.xiaomaiketang.com/xm/MQwp2aJaxf.json",
path: "https://image.xiaomaiketang.com/xm/SDBkP7mbJX.json",
name: "test",
renderer: "svg",
loop: true,
......@@ -229,14 +229,18 @@ class ManageCoursewareModal extends React.Component {
const antIcon = <LoadingOutlined/>;
const type = FileVerifyMap[fileType].type;
return <div className="courseware-name" onClick={() => this.handleScanFile(item)}>
{(type === 'JPG' || type === 'PNG') && item.progress ?
<Spin indicator={antIcon} />
:<img
src={FileTypeIcon[FileVerifyMap[fileType].type] || (item.docUrls[0] || {}).conversionFileUrl}
alt=""
className="item-img"
/>
}
<Choose>
<When condition={(type === 'JPG' || type === 'PNG') && item.progress}>
<Spin indicator={antIcon} />
</When>
<Otherwise>
<img
src={FileTypeIcon[FileVerifyMap[fileType].type] || (item.docUrls[0] || {}).conversionFileUrl}
alt=""
className="item-img"
/>
</Otherwise>
</Choose>
<Tooltip title={item.fileName}><span className="name">{item.fileName}</span></Tooltip>
</div>
},
......@@ -270,7 +274,7 @@ class ManageCoursewareModal extends React.Component {
width: "16%",
dataIndex: "control",
render: (_value, item) => {
const { uploadObject, failObject, cancelObject } = this.state;
const { failObject } = this.state;
const uploadFail = failObject[item.id];
// 上课前45分钟/上课中/已结束的情况下都不可操作
......@@ -295,7 +299,7 @@ class ManageCoursewareModal extends React.Component {
const {
list, scanFileModal, editData, cancelObject,
showSelectFileModal, selectedFileList,
diskList, currentRootDisk, isLessonPermission
diskList
} = this.state;
const _list = _.reject(list, (item) => cancelObject[item.id]);
return (
......
......@@ -8,8 +8,8 @@
.empty-image {
display: block;
margin: 24px auto 12px;
width:100px;
height:100px;
width:150px;
height:150px;
}
.empty-button {
display: block;
......
......@@ -18,8 +18,6 @@ import CourseService from '@/domains/course-domain/CourseService'
import './ShareLiveModal.less'
const DEFAULT_COVER = 'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png'
class ShareLiveModal extends React.Component {
constructor(props) {
super(props)
......@@ -54,6 +52,13 @@ class ShareLiveModal extends React.Component {
size: 98,
})
qrcodeWrapDom.appendChild(qrcodeNode)
const qrcodeWrapDomDownload = document.querySelector('#qrcodeWrap-dowload')
const qrcodeNodeDownLoad = new qrcode({
text: this.state.shareUrl,
size: 196,
})
qrcodeWrapDomDownload.appendChild(qrcodeNodeDownLoad)
}
)
})
......@@ -74,13 +79,12 @@ class ShareLiveModal extends React.Component {
() => {
this.setState({ time: new Date().valueOf() }, () => {
setTimeout(() => {
let node = document.getElementById('poster')
let node = document.getElementById('poster-dowload')
domtoimage.toPng(node).then((imgData) => {
console.log(imgData)
const download = document.createElement('a')
const { courseName } = this.props.data
$(download).attr('href', imgData).attr('download', `${courseName}.png`).get(0).click()
// this.props.close()
})
}, 1000)
})
......@@ -98,27 +102,31 @@ class ShareLiveModal extends React.Component {
render() {
const { courseDivision, data, type, title } = this.props
const { courseName, coverUrl = DEFAULT_COVER, scheduleVideoUrl } = data
const { courseName, scheduleVideoUrl, courseMediaVOS, coverUrl } = data
const { shareUrl, showImg, time } = this.state
// 判断是否是默认图, 默认图不需要在URL后面增加字符串
const isDefaultCover = coverUrl === DEFAULT_COVER
let coverImgSrc = coverUrl
if (type === 'videoClass') {
if ((!coverUrl || isDefaultCover) && title !== '图文课' && title !== '线下课') {
if (courseDivision === 'external') {
coverImgSrc = 'https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png'
let coverImgSrc = '';
switch (type) {
case 'liveClass': // 直播课
if (courseMediaVOS && courseMediaVOS.length > 0) {
data.courseMediaVOS.map((item, index) => {
if (item.contentType === 'COVER') {
coverImgSrc = item.mediaUrl
}
})
} else {
coverImgSrc = `${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast&anystring=anystring`
}
}
} else {
data.courseMediaVOS.map((item, index) => {
if (item.contentType === 'COVER') {
coverImgSrc = item.mediaUrl
coverImgSrc = 'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png';
}
})
break;
case 'videoClass': // 视频课
coverImgSrc = coverUrl || (courseDivision === 'internal' ? `${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast&anystring=anystring` : 'https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png')
break;
case 'graphicsClass': // 图文课
coverImgSrc = coverUrl || 'https://image.xiaomaiketang.com/xm/wFnpZtp2yB.png';
break;
case 'offlineClass': // 线下课
coverImgSrc = coverUrl || 'https://image.xiaomaiketang.com/xm/pxbWKsYA87.png';
break;
}
return (
......@@ -137,7 +145,7 @@ class ShareLiveModal extends React.Component {
<span className='text'>{User.getStoreName()}</span>
</div>
<div className='course-name-title'>{type === 'videoClass' ? `${courseName}开课啦` : `邀请你观看直播:`}</div>
<div className='course-name-title'>{type === 'liveClass' ? `邀请你观看直播:` : `${courseName}开课啦`}</div>
{type === 'liveClass' && <div class='live-couse-name'>{courseName}</div>}
<Choose>
<When condition={showImg}>
......@@ -156,6 +164,29 @@ class ShareLiveModal extends React.Component {
<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'>{type === 'videoClass' ? `${courseName}开课啦` : `邀请你观看直播:`}</div>
{type === 'liveClass' && <div class='live-couse-name'>{courseName}</div>}
<Choose>
<When condition={showImg}>
<img crossOrigin='*' src={coverImgSrc + `?=${time}`} className='course-cover' alt='' />
</When>
<Otherwise>
<img src={coverImgSrc + `?=${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'>
......
.share-live-modal {
.ant-modal-body {
display: flex;
#poster{
background: #FFF;
margin:0;
padding: 20px;
}
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;
.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 {
#poster{
background: #FFF;
margin:0;
padding: 20px;
margin-bottom:140px;
.course-name-title {
font-size: 14px;
color: #333;
font-size: 16px;
font-weight: 600;
line-height: 20px;
}
.course-cover {
width: 263px;
height: 143px;
border-radius: 6px;
margin-top: 8px;
}
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;
.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;
&__left {
width: 98px;
text-align: center;
margin-right: 22px;
.text {
line-height: 20px;
}
.finger {
width: 40px;
height: 40px;
margin-top: 8px;
}
}
.finger {
width: 40px;
height: 40px;
margin-top: 8px;
&__right {
width: 110px;
height: 110px;
padding: 6px
}
}
&__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%;
}
}
}
.store-name {
// padding: 8px 16px;
display: flex;
align-items: center;
#poster-dowload{
background: #FFF;
margin:0;
padding: 40px;
width:606px;
.course-name-title {
font-size: 28px;
color: #333;
line-height: 40px;
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%;
}
.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: 24px;
color: #999;
font-size: 28px;
line-height: 40px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 100%;
}
}
}
}
.right {
.title {
color: #333;
......
/*
* @Author: 吴文洁
* @Date: 2020-08-05 10:07:47
* @LastEditors: wufan
* @LastEditTime: 2021-05-27 19:25:48
* @LastEditors: yuananting
* @LastEditTime: 2021-06-07 15:06:26
* @Description: 线下课新增/编辑页
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -518,6 +518,11 @@ class AddOfflineCourse extends React.Component {
if(coverId){
scheduleMediaRequests = [coverObj]
}
// 编辑且使用默认图时不传
if (pageType === 'edit' && coverUrl === defaultCoverUrl) {
scheduleMediaRequests = []
}
const commonParams = {
categoryId,
courseName,
......
......@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-08-05 10:12:45
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-05-27 20:14:01
* @LastEditTime: 2021-06-11 16:44:42
* @Description: 视频课-列表模块
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -25,7 +25,7 @@ import QRCodeModal from '../modal/QRCodeModal';
import './OfflineCourseList.less';
const ENV = process.env.DEPLOY_ENV || 'dev';
const defaultCoverUrl = 'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png';
const defaultCoverUrl = 'https://image.xiaomaiketang.com/xm/pxbWKsYA87.png';
class OfflineCourseList extends React.Component {
......@@ -358,7 +358,7 @@ class OfflineCourseList extends React.Component {
<ShareLiveModal
needStr={needStr}
data={shareData}
type="videoClass"
type="offlineClass"
title="线下课"
close={() => {
this.setState({
......
......@@ -6,7 +6,7 @@ import Service from "@/common/js/service";
import './PreviewOfflineModal.less';
import ENUM from '@/modules/knowledge-base/ENUM';
const defaultCoverUrl = 'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png';
const defaultCoverUrl = 'https://image.xiaomaiketang.com/xm/pxbWKsYA87.png';
class PreviewOfflineModal extends React.Component {
......
import React from 'react'
import { Tabs } from 'antd'
import VideoCourseFilter from './components/VideoCourseFilter'
import VideoCourseOpt from './components/VieoCourseOpt'
import VideoCourseList from './components/VideoCourseList'
import CourseService from '@/domains/course-domain/CourseService'
import User from '@/common/js/user'
const { TabPane } = Tabs
import React from 'react';
import { Tabs } from 'antd';
import VideoCourseFilter from './components/VideoCourseFilter';
import VideoCourseOpt from './components/VieoCourseOpt';
import VideoCourseList from './components/VideoCourseList';
import CourseService from '@/domains/course-domain/CourseService';
import User from '@/common/js/user';
const { TabPane } = Tabs;
class VideoCourse extends React.Component {
constructor(props) {
super(props)
super(props);
this.state = {
query: {
size: 10,
......@@ -18,45 +18,43 @@ class VideoCourse extends React.Component {
dataSource: [], // 视频课列表
totalCount: 0, // 视频课数据总条数
currentTabKey: 'internal',
}
};
}
componentWillMount() {
// 获取视频课列表
this.handleFetchScheduleList()
this.handleFetchScheduleList();
}
// 获取视频课列表
handleFetchScheduleList = (_query = {}) => {
const { currentTabKey } = this.state
const { currentTabKey } = this.state;
const query = {
...this.state.query,
..._query,
courseDivision: currentTabKey === 'external' ? 1 : null,
}
// 更新请求参数
this.setState({ query })
};
CourseService.videoSchedulePage(query).then((res) => {
const { result = {} } = res || {}
const { records = [], total = 0 } = result
const { result = {} } = res || {};
const { records = [], total = 0 } = result;
if (Number(total) && query.size * (query.current - 1) >= Number(total)) {
this.handleFetchScheduleList({
...query,
current: 1,
})
return
});
return;
}
this.setState({
query,
dataSource: records,
totalCount: Number(total),
})
})
}
});
});
};
currenTabChange = (currentTabKey) => {
const { query } = this.state
const { query } = this.state;
this.setState(
{
currentTabKey,
......@@ -66,20 +64,21 @@ class VideoCourse extends React.Component {
},
},
() => {
this.handleFetchScheduleList()
console.log('this.state.query===>', this.state.query);
// this.handleFetchScheduleList()
}
)
}
);
};
changeShelfState = (index, shelfState) => {
const { dataSource } = this.state
dataSource[index].shelfState = shelfState
const { dataSource } = this.state;
dataSource[index].shelfState = shelfState;
this.setState({
dataSource,
})
}
});
};
render() {
const { dataSource, totalCount, query, currentTabKey } = this.state
const { dataSource, totalCount, query, currentTabKey } = this.state;
return (
<div className='page video-course-page'>
<div className='content-header'>视频课</div>
......@@ -107,8 +106,8 @@ class VideoCourse extends React.Component {
/>
</div>
</div>
)
);
}
}
export default VideoCourse
export default VideoCourse;
......@@ -2,17 +2,17 @@
* @Description:
* @Author: zangsuyun
* @Date: 2021-03-19 18:05:23
* @LastEditors: wufan
* @LastEditTime: 2021-05-30 16:48:46
* @LastEditors: fusanqiasng
* @LastEditTime: 2021-06-15 11:20:24
* @Copyright: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { Component } from "react";
import { Input, Button, Tree } from "antd";
import "./Classification.less";
import User from "@/common/js/user";
import KnowledgeAPI from "@/data-source/knowledge/request-api";
import Bus from "@/core/bus";
import React, { Component } from 'react';
import { Input, Button, Tree } from 'antd';
import './Classification.less';
import User from '@/common/js/user';
import KnowledgeAPI from '@/data-source/knowledge/request-api';
import Bus from '@/core/bus';
const { Search } = Input;
const { DirectoryTree } = Tree;
......@@ -21,7 +21,7 @@ class Classification extends Component {
constructor(props) {
super(props);
this.state = {
selectedKeys: props.selectedKeys ? [props.selectedKeys] : ["0"],
selectedKeys: props.selectedKeys ? [props.selectedKeys] : ['0'],
searchValue: null,
NewEditQuestionBankCategory: null, //新增或编辑分类模态框
ImportCourseCategory: null, // 引用课程分类模态框
......@@ -32,11 +32,11 @@ class Classification extends Component {
componentDidMount() {
this.queryCategoryTree();
Bus.bind('knowledgeCategoryTree', this.queryCategoryTree)
Bus.bind('knowledgeCategoryTree', this.queryCategoryTree);
}
componentWillUnmount() {
Bus.unbind('knowledgeCategoryTree', this.queryCategoryTree)
Bus.unbind('knowledgeCategoryTree', this.queryCategoryTree);
}
shouldComponentUpdate = (nextProps, nextState) => {
......@@ -79,7 +79,7 @@ class Classification extends Component {
};
KnowledgeAPI.getCategoryTree(query).then((res) => {
const { categoryList = [], noCategoryCnt = 0 } = res.result;
let str = "未分类";
let str = '未分类';
if (categoryName) {
this.setState({ autoExpandParent: true });
if (str.indexOf(categoryName) < 0) {
......@@ -93,8 +93,8 @@ class Classification extends Component {
this.setState({ expandedKeys: nodeId });
} else {
const defaultNode = {
id: "0",
categoryName: "未分类",
id: '0',
categoryName: '未分类',
categoryCount: noCategoryCnt,
};
categoryList.unshift(defaultNode);
......@@ -110,8 +110,8 @@ class Classification extends Component {
} else {
this.setState({ autoExpandParent: false });
const defaultNode = {
id: "0",
categoryName: "未分类",
id: '0',
categoryName: '未分类',
categoryCount: noCategoryCnt,
};
categoryList.unshift(defaultNode);
......@@ -140,39 +140,35 @@ class Classification extends Component {
item.title =
!value || (value && item.categoryName.indexOf(value) > -1) ? (
<span>
{item.categoryName}{item.categoryCount}
{item.categoryName}
{item.categoryCount > 0 && <span>{item.categoryCount}</span>}
</span>
) : (
<span style={{ opacity: 0.5 }}>
{item.categoryName}{item.categoryCount}
{item.categoryName}
{item.categoryCount > 0 && <span>{item.categoryCount}</span>}
</span>
);
item.icon =
item.categoryName === "未分类" ? (
item.categoryName === '未分类' ? (
<img
style={{
width: "24px",
height: "24px",
opacity:
!value || (value && item.categoryName.indexOf(value) > -1)
? 1
: 0.5,
width: '24px',
height: '24px',
opacity: !value || (value && item.categoryName.indexOf(value) > -1) ? 1 : 0.5,
}}
src="https://image.xiaomaiketang.com/xm/defaultCategory.png"
alt=""
src='https://image.xiaomaiketang.com/xm/defaultCategory.png'
alt=''
/>
) : (
<img
style={{
width: "24px",
height: "24px",
opacity:
!value || (value && item.categoryName.indexOf(value) > -1)
? 1
: 0.5,
width: '24px',
height: '24px',
opacity: !value || (value && item.categoryName.indexOf(value) > -1) ? 1 : 0.5,
}}
src="https://image.xiaomaiketang.com/xm/hasCategory.png"
alt=""
src='https://image.xiaomaiketang.com/xm/hasCategory.png'
alt=''
/>
);
if (item.sonCategoryList) {
......@@ -186,36 +182,30 @@ class Classification extends Component {
};
render() {
const {
treeData,
expandedKeys,
selectedKeys,
autoExpandParent,
} = this.state;
const { treeData, expandedKeys, selectedKeys, autoExpandParent } = this.state;
return (
<div className="question-bank-sider">
<div className="sider-title">知识分类</div>
<div className='question-bank-sider'>
<div className='sider-title'>知识分类</div>
<Search
className="sider-search"
placeholder="搜索名称分类"
className='sider-search'
placeholder='搜索名称分类'
onSearch={(value) => {
this.queryCategoryTree(value);
}}
enterButton={<span className="icon iconfont">&#xe832;</span>}
style={{width: 230}}
enterButton={<span className='icon iconfont'>&#xe832;</span>}
style={{ width: 230 }}
/>
<div className="sider-btn">
<div className='sider-btn'>
<Button
onClick={() => {
window.RCHistory.push({
pathname: "/course-category-manage?from=knowledge",
pathname: '/course-category-manage?from=knowledge',
});
}}
>
}}>
分类管理
</Button>
</div>
<div className="sider-tree">
<div className='sider-tree'>
<DirectoryTree
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
......
......@@ -2,15 +2,14 @@
* @Description:
* @Author: zangsuyun
* @Date: 2021-03-12 14:49:40
* @LastEditors: wufan
* @LastEditTime: 2021-05-30 20:37:42
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-11 16:44:59
* @Copyright: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React from "react";
import { Modal, message, Tooltip, Switch, Dropdown, Button } from "antd";
import { Route, withRouter } from "react-router-dom";
import Lottie from 'react-lottie';
import { PageControl, XMTable } from "@/components";
import { LIVE_SHARE_MAP } from "@/common/constants/academic/cloudClass";
import { appId, shareUrl, LIVE_SHARE } from "@/domains/course-domain/constants";
......@@ -18,7 +17,6 @@ import ScanFileModal from "../../resource-disk/modal/ScanFileModal";
import WatchData from "./WatchData";
import KnowledgeAPI from "@/data-source/knowledge/request-api";
import ENUM from "../ENUM.js";
import * as nodata from '../../lottie/nodata/data.json';
import "./KnowledgeBaseList.less";
const DEFAULT_SIZE_UNIT = 1000 * 1000 // 将B转换成M
......@@ -494,14 +492,6 @@ class KnowledgeBaseList extends React.Component {
preserveSelectedRowKeys: true,
onChange: onSelectChange,
}
const defaultOptions = {
loop: true,
autoplay: true,
animationData: nodata,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice'
}
}
return (
<div className="knowledge-base-list">
<XMTable
......@@ -515,15 +505,6 @@ class KnowledgeBaseList extends React.Component {
bordered
className="knowledge-list-table"
renderEmpty={{
image: <div style={{ marginTop: 24 }}>
<Lottie
options={defaultOptions}
height={150}
width={150}
isStopped={false}
isPaused={false}
/>
</div>,
description: <span style={{ display: 'block', paddingBottom: 24 }}>暂无数据</span>
}}
/>
......
......@@ -2,8 +2,8 @@
* @Description:
* @Author: zangsuyun
* @Date: 2021-03-13 09:54:26
* @LastEditors: fusanqiasng
* @LastEditTime: 2021-06-01 10:26:46
* @LastEditors: yuananting
* @LastEditTime: 2021-06-10 19:55:24
* @Copyright: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -324,7 +324,7 @@ class AddCourse extends React.Component {
return <img className='course-cover' src={item.mediaUrl} alt='' />;
}
})}
{!hasCover && <img className='course-cover' src={'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png'} alt='' />}
{!hasCover && <img className='course-cover' src={'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'} alt='' />}
<div>
<Choose>
<When condition={record.courseName.length > 17}>
......@@ -501,8 +501,7 @@ class AddCourse extends React.Component {
const { coverUrl } = record;
return (
<div className='record__item'>
{/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */}
<img className='course-cover' src={coverUrl || 'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png'} alt='' />
<img className='course-cover' src={coverUrl || 'https://image.xiaomaiketang.com/xm/wFnpZtp2yB.png'} alt='' />
<Choose>
<When condition={record.courseName.length > 25}>
<Tooltip title={record.courseName}>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
import React from 'react';
import { Button } from 'antd';
import { withRouter } from 'react-router-dom';
import User from '@/common/js/user';
import './ExpiredCourseList.less';
function ExpiredCourseList(props) {
......
......@@ -10,7 +10,7 @@
import React, { useState } from 'react';
import { Table, Modal, message, Tooltip, Switch, Dropdown } from 'antd';
import { withRouter } from 'react-router-dom';
import { PageControl } from '@/components';
import { PageControl, XMTable } from "@/components";
import PlanService from '@/domains/plan-domain/planService';
import SharePlanModal from '../modal/SharePlanModal';
import { LIVE_SHARE } from '@/domains/course-domain/constants';
......@@ -305,7 +305,7 @@ function PlanList(props) {
}
return (
<div className='plan-list'>
<Table
<XMTable
rowKey={(record) => record.id}
showSorterTooltip={false}
dataSource={props.planListData}
......@@ -316,6 +316,9 @@ function PlanList(props) {
size='middle'
scroll={{ x: 1400 }}
className='plan-list-table'
renderEmpty={{
description: <span style={{ display: 'block', paddingBottom: 24 }}>暂无数据</span>
}}
/>
<div className='box-footer'>
<PageControl
......
......@@ -16,7 +16,7 @@ import CourseService from '@/domains/course-domain/CourseService'
import './SharePlanModal.less'
const DEFAULT_COVER = 'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png'
const DEFAULT_COVER = 'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png'
class ShareLiveModal extends React.Component {
constructor(props) {
......@@ -51,6 +51,13 @@ class ShareLiveModal extends React.Component {
size: 98,
})
qrcodeWrapDom.appendChild(qrcodeNode)
const qrcodeWrapDomDownload = document.querySelector('#qrcodeWrap-dowload')
const qrcodeNodeDownLoad = new qrcode({
text: this.state.shareUrl,
size: 196,
})
qrcodeWrapDomDownload.appendChild(qrcodeNodeDownLoad)
}
)
})
......@@ -70,9 +77,8 @@ class ShareLiveModal extends React.Component {
},
() => {
this.setState({ time: new Date().valueOf() }, () => {
let node = document.getElementById('poster')
let node = document.getElementById('poster-dowload')
domtoimage.toPng(node).then((imgData) => {
console.log(imgData)
const download = document.createElement('a')
const { planName } = this.props.data
$(download).attr('href', imgData).attr('download', `${planName}.png`).get(0).click()
......@@ -112,7 +118,7 @@ class ShareLiveModal extends React.Component {
<div className='course-name-title'>邀请你参与培训:</div>
<div class='live-couse-name'>{planName}</div>
<div className='live-couse-name'>{planName}</div>
<Choose>
<When condition={showImg}>
<img crossOrigin='*' src={coverUrl + `?=${time}`} className='course-cover' alt='' />
......@@ -130,6 +136,31 @@ class ShareLiveModal extends React.Component {
<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'>
......
.share-live-modal {
.ant-modal-body {
display: flex;
#poster{
background: #FFF;
margin:0;
padding: 20px;
}
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;
.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;
}
#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;
.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;
&__left {
width: 98px;
text-align: center;
margin-right: 22px;
.text {
line-height: 20px;
}
.finger {
width: 40px;
height: 40px;
margin-top: 8px;
}
}
.finger {
width: 40px;
height: 40px;
margin-top: 8px;
&__right {
width: 110px;
height: 110px;
padding: 6px
}
}
&__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;
}
.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%;
.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%;
}
}
}
}
......
......@@ -304,7 +304,7 @@ class SelectOperatorModal extends React.Component {
return null
})}
<If condition={!hasCover}>
<img className='course-cover' src={"https://image.xiaomaiketang.com/xm/YNfi45JwFA.png"} alt='' />
<img className='course-cover' src={"https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png"} alt='' />
</If>
<div>
......@@ -432,8 +432,7 @@ class SelectOperatorModal extends React.Component {
const { coverUrl } = record
return (
<div className='course-info'>
{/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */}
<img className='course-cover' src={coverUrl || "https://image.xiaomaiketang.com/xm/YNfi45JwFA.png"} alt='' />
<img className='course-cover' src={coverUrl || "https://image.xiaomaiketang.com/xm/wFnpZtp2yB.png"} alt='' />
<div className='course-name'>{record.courseName}</div>
</div>
)
......
......@@ -7,23 +7,20 @@
*/
import React from 'react';
import { Modal, Button, Radio, Checkbox, Spin, Upload, message, Tooltip } from 'antd';
import InfiniteScroll from 'react-infinite-scroller';
import { Modal, Button, Radio, Checkbox, message, Tooltip } from 'antd';
import User from '@/common/js/user';
import { getEllipsText } from "@/core/util";
import DefaultIcon from '@/modules/common/DefaultIcon';
import UploadProgressModal from './UploadProgressModal';
import NonCompliantFileModal from './NonCompliantFileModal';
import Service from '@/common/js/service';
import _ from 'underscore';
import {
DEFAULT_SIZE_UNIT, FileTypeIcon, NonCompliantFileMap,
DISK_LIST, SupportFileType, LocalFileType,FileVerifyMap
DEFAULT_SIZE_UNIT, FileTypeIcon,
SupportFileType, FileVerifyMap
} from "@/common/constants/academic/lessonEnum";
import { getFileTypeByName } from '../components/FolderManage';
import LottieIcon from '@/components/LottieIcon';
import './SelectPrepareFileModal.less';
const defaultQuery = {
......@@ -660,9 +657,10 @@ class SelectPrepareFileModal extends React.Component {
}
</div>
</div> :
<DefaultIcon
type='student'
<LottieIcon
title={<span className="desc">这个文件夹是空的</span>}
type="college"
size={150}
/>
}
......
......@@ -47,6 +47,7 @@ class FolderManage extends React.Component {
folderPathList: [props.currentRootDisk],
selectedFileIds: [], // 已被选择的文件
selectedFileRights: [], // 已被选择的文件对应权限
selectedFileType:[], // 已选择的文件的类型
folderList: [], // 当前目录下的文件
searchKey: null, // 搜索关键字
totalCount: 0, // 该磁盘总共有的文件个数
......@@ -200,10 +201,12 @@ class FolderManage extends React.Component {
handleChangeRow = (selectedRowKeys) => {
const { folderList } = this.state;
let _selectedFileRights = [];
let _selectedFileType = [];
selectedRowKeys.map(folderId => {
folderList.map(item => {
if (item.id === folderId) {
_selectedFileRights.push(item.rights);
_selectedFileType.push(item.folderType);
}
return _selectedFileRights;
})
......@@ -211,7 +214,8 @@ class FolderManage extends React.Component {
})
this.setState({
selectedFileIds: selectedRowKeys,
selectedFileRights: _selectedFileRights
selectedFileRights: _selectedFileRights,
selectedFileType:_selectedFileType
})
}
......@@ -255,12 +259,13 @@ class FolderManage extends React.Component {
}
// 移动文件
handleMove = (query, sourceFileIds = this.state.selectedFileIds) => {
handleMove = (query, sourceFileIds = this.state.selectedFileIds,selectedFileTypes=this.state.selectedFileType) => {
const { targetFolder, selectFolderPathList } = query;
const { currentRootDisk: { disk} } = this.props;
const { folderPathList } = this.state;
const currentFolder = folderPathList[folderPathList.length - 1];
const { id } = targetFolder;
let canRemove = true;
// 将selectedFileIds移动到targetFolder
let params = {
disk,
......@@ -271,28 +276,38 @@ class FolderManage extends React.Component {
if (selectFolderPathList.length > 1) {
params.newParentId = id
}
Service.Hades('public/hadesStore/moveFolder', params).then((res) => {
// 判断是否将文件移动到了自身或者子目录
const { result = {} } = res;
const { code, message: _message } = result;
if (code === 'PARAM_ERROR') {
message.warning(_message);
return;
}
if (id == null) {
Modal.success({
title: '文件移动成功',
content: '移动到一级目录的文件仅自己可以查看,如需其他成员查看请设置权限'
})
} else {
message.success('文件移动成功');
}
if(selectFolderPathList.length > 9){
selectedFileTypes.map((item)=>{
//判定是否存在文件夹
if(item==="FOLDER"){
canRemove = false;
message.warning('不能将文件夹移动到10级目录下');
}
})
}
if(canRemove){
Service.Hades('public/hadesStore/moveFolder', params).then((res) => {
// 判断是否将文件移动到了自身或者子目录
const { result = {} } = res;
const { code, message: _message } = result;
if (code === 'PARAM_ERROR') {
message.warning(_message);
return;
}
if (id == null) {
Modal.success({
title: '文件移动成功',
content: '移动到一级目录的文件仅自己可以查看,如需其他成员查看请设置权限'
})
} else {
message.success('文件移动成功');
}
// 移动成功之后需要将selectedFileIds置为空
this.setState({ selectedFileIds: [] });
this.handleFetchFolderList({ parentId: currentFolder.id, current: 1});
})
// 移动成功之后需要将selectedFileIds置为空
this.setState({ selectedFileIds: [] });
this.handleFetchFolderList({ parentId: currentFolder.id, current: 1});
})
}
}
// 修改文件路径
......
......@@ -13,7 +13,7 @@ import _ from 'underscore';
import Service from '@/common/js/service';
import { getEllipsText } from '@/domains/basic-domain/utils';
import { DEFAULT_SIZE_UNIT, LOCAL_FILE_TYPE_MAP,FILR_VERIFY_MAP,SUPPORT_FILE_TYPE_MAP} from '@/domains/resource-disk/constants';
import { DEFAULT_SIZE_UNIT,FILR_VERIFY_MAP,SUPPORT_FILE_TYPE_MAP} from '@/domains/resource-disk/constants';
import { getFileTypeByName } from '@/domains/resource-disk/utils';
import UploadProgressModal from '@/bu-components/UploadProgressModal';
......@@ -70,7 +70,7 @@ class OperateArea extends React.Component {
// 判断当前目录是否在第10层,如果是的话提示最多只能创建10层文件夹
const { folderPathList } = this.props;
if (folderPathList.length > 10) {
if (folderPathList.length > 9) {
message.warning('最多只能创建10层文件夹');
return;
}
......
......@@ -29,25 +29,6 @@ class PrepareLessonPage extends React.Component {
}
}
componentWillMount() {
// this.handleFetchDiskList();
}
handleFetchDiskList = async () => {
const res = await Service.Hades('public/apollo/getUserDisk', {});
const { result = [] } = res;
const diskList = result.map((item) => {
return {
...item,
folderName: DISK_MAP[item.disk]
}
});
this.setState({
diskList,
currentRootDisk: diskList[0] || defaultRootDisk
});
}
handleChangeDisk = (disk) => {
this.setState({
currentRootDisk: disk
......
......@@ -215,14 +215,12 @@
cursor: pointer;
}
.lottie-icon {
&__title {
color: #999;
.upload-btn {
color: #5A8EFA;
margin: 0 4px;
cursor: pointer;
}
.lottie-icon-title {
color: #999;
.upload-btn {
color: #5A8EFA;
margin: 0 4px;
cursor: pointer;
}
}
// td.ant-table-column-sort{
......@@ -230,6 +228,11 @@
// }
}
}
.add-empty {
.ant-table-cell {
border: none;
}
}
}
......
import React from 'react';
import { Modal, Input, Form, message } from 'antd';
import ShowTips from '@/bu-components/ShowTip';
import { Modal, Input, Form } from 'antd';
import './CreateFolderModal.less';
class CreateFolderModal extends React.Component {
......@@ -107,5 +106,4 @@ class CreateFolderModal extends React.Component {
}
}
// export default Form.create()(CreateFolderModal);
export default CreateFolderModal;
\ No newline at end of file
import React from 'react';
import "./PreviewFileModal.less";
import { Spin } from 'antd'
class PreviewFileModal extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
cancelPreView = ()=>{
this.props.onCancel();
}
toPreView = (url)=>{
const a = document.createElement('a');
document.body.appendChild(a);
a.setAttribute('href', url);
a.setAttribute('target', '_blank');
a.click();
document.body.removeChild(a);
this.props.onCancel();
}
render() {
const { previewStatus,url} = this.props
return (
<div className="preview-modal">
<div className="preview-modal-content">
<div className="load-img-box">
{previewStatus === "UPLOAD" &&
<Spin size="large"/>
}
{previewStatus === "UPLOAD_SUCCESS" &&
<img className="load-img" src="https://image.xiaomaiketang.com/xm/jJRK3bTEdc.png"></img>
}
</div>
<div className="load-text-box">
{previewStatus === "UPLOAD" &&
<div className="load-text-box-title">预览生成中</div>
}
{previewStatus === "UPLOAD_SUCCESS" &&
<div className="load-text-box-title">预览生成成功</div>
}
</div>
<div className="operate">
<span className="btn cancel-preview-btn" onClick={()=>this.cancelPreView()}>取消预览</span>
{previewStatus === "UPLOAD" &&
<span className="btn to-preview-btn__disabled to-preview-btn">去查看</span>
}
{previewStatus === "UPLOAD_SUCCESS" &&
<span className="btn to-preview-btn" onClick={()=>this.toPreView(url)}>去查看</span>
}
</div>
</div>
</div>
);
}
}
export default PreviewFileModal;
.preview-modal{
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 102;
height: 100%;
background: rgba(0, 0, 0, 0.7);
.preview-modal-content{
position:absolute;
left:calc(50% - 133px);
top:calc(50% - 87px);
color:#FFF;
text-align:center;
width:266px;
height:174px;
.ant-spin-dot-item{
background-color: #FFF;
}
.load-img-box{
.load-img{
width:44px;
height:44px;
}
}
.load-text-box{
margin-top:23px;
font-size:16px;
color:#FFF;
.load-text-box-title{
margin-bottom:8px;
}
}
.operate{
margin-top:24px;
.btn {
padding:5px 12px;
border:1px solid #E8E8E8;
border-radius:2px;
}
.cancel-preview-btn{
margin-right:8px;
}
.to-preview-btn__disabled{
border:1px solid #E8E8E8;
opacity: 0.4;
}
}
}
}
\ No newline at end of file
......@@ -116,7 +116,6 @@ const App: React.FC = (props: any) => {
setMenuType(!menuType);
}
if (!storeUserId) {
return <div></div>
}
......@@ -127,7 +126,7 @@ const App: React.FC = (props: any) => {
<ConfigProvider locale={zhCN} autoInsertSpaceInButton={false}>
<Main menuType={menuType} />
</ConfigProvider>
<Menu menuType={menuType} handleMenuType={handleMenuType}/>
<Menu menuType={menuType} handleMenuType={handleMenuType} />
</div>
)
}
......
import User from '@/common/js/user';
import React from 'react';
import Header from './Header'
import Lottie from "lottie-web";
import { Modal } from "antd";
import Service from "@/common/js/service";
import { LIVE_SHARE } from "@/domains/course-domain/constants";
import BaseService from "@/domains/basic-domain/baseService";
import './ErrorCollege.less';
export default class ErrorCollege extends React.Component {
constructor(props) {
super(props);
this.state = {
menuType: true,
nickName: '',
}
}
componentDidMount() {
this.getUserInfo();
this.getStorePermission();
var animation = Lottie.loadAnimation({
path: "https://image.xiaomaiketang.com/xm/AhcJZHdMZf.json",
name: "test",
renderer: "svg",
loop: true,
autoplay: true,
container: document.getElementById("lottie-box")
});
}
getStorePermission() {
......@@ -29,17 +41,62 @@ export default class ErrorCollege extends React.Component {
});
}
handleMenuType() {
this.setState({ menuType: !menuType });
getUserInfo() {
const param = {
storeUserId: User.getStoreUserId(),
};
BaseService.getStoreUser(param).then((res) => {
const { nickName } = res.result;
this.setState({ nickName });
});
}
handleLogoutConfirm() {
return Modal.confirm({
title: "你确定要退出登录吗?",
content: "退出后,需重新登录",
icon: (
<span className="icon iconfont default-confirm-icon">&#xe839; </span>
),
okText: "退出登录",
cancelText: "点错了",
onOk: () => {
this.handleLogout();
},
});
}
handleLogout() {
BaseService.logout({identifier:User.getIdentifier()}).then((res) => {
User.removeUserId();
User.removeToken();
User.removeEnterpriseId();
User.clearUserInfo();
const url = `${LIVE_SHARE}store/index?id=${User.getCustomerStoreId()||User.getStoreId()}&userId=${User.getUserId()}&from=work_weixin`;
window.location.href = url;
});
}
render() {
const { menuType } = this.state;
const { nickName } = this.state;
return (
<div className="error-college-page">
<Header id="error" handleMenuType={this.handleMenuType} menuType={menuType} />
<div className="header">
<img src='https://image.xiaomaiketang.com/xm/FEdG7BMwKr.png' className="logo" alt="" />
<div className="name-box">
<img src='https://image.xiaomaiketang.com/xm/hcp6zs5HTn.png' className="avatar" alt="" />
<span className="name">{nickName}</span>
<span
className="control"
onClick={() => {
this.handleLogoutConfirm();
}}
>退出登录</span>
</div>
</div>
<div className="error-college-box">
<img src="https://image.xiaomaiketang.com/xm/MQRaYkbr6J.png" className="error-college-image" />
<div id="lottie-box" className="error-college-image"></div>
<span className="error-college-tip">{User.getStoreName()}已停用</span>
</div>
</div>
......
......@@ -2,6 +2,36 @@
position: relative;
width: 100vw;
height: 100vh;
.header {
display: flex;
align-items: center;
height: 60px;
padding: 0 344px;
justify-content: space-between;
.logo {
width: 117px;
height: 30px;
}
.name-box {
display: flex;
align-items: center;
.avatar {
width: 24px;
height: 24px;
border-radius: 50%;
margin-right: 6px;
}
.name {
color: #666;
font-size: 16px;
margin-right: 8px;
}
.control {
color: #2966FF;
cursor: pointer;
}
}
}
.error-college-box {
position: absolute;
top: 50px;
......@@ -10,20 +40,20 @@
bottom: 0;
.error-college-image {
position: absolute;
top: 246px;
top: 266px;
left: 50%;
transform: translateX(-50%);
width: 246px;
height: 132px;
width: 200px;
height: 200px;
display: block;
}
.error-college-tip {
position: absolute;
top: 404px;
top: 482px;
left: 50%;
transform: translateX(-50%);
color: #8C8E93;
font-size: 13px;
color: #000;
font-size: 18px;
}
}
}
\ No newline at end of file
......@@ -11,6 +11,7 @@ import { Radio, Button, Dropdown, Modal, Tooltip, message } from "antd";
import { LIVE_SHARE } from "@/domains/course-domain/constants";
import User from "@/common/js/user";
import Service from "@/common/js/service";
import StoreService from "@/domains/store-domain/storeService";
import BaseService from "@/domains/basic-domain/baseService";
import { XMContext } from "@/store/context";
import logoImg from "@/common/images/logo.png";
......@@ -18,6 +19,7 @@ import CourseService from "@/domains/course-domain/CourseService";
import qrcode from "@/libs/qrcode/qrcode.js";
import Bus from '@/core/tbus';
import ClickOutside from '../../components/ClickOutside';
import _ from "underscore";
const baseImg = "https://image.xiaomaiketang.com/xm/rJeQaZxtc7.png";
const { confirm } = Modal;
......@@ -38,6 +40,8 @@ function Header(props) {
const storeUserId = User.getStoreUserId();
const enterpriseId = User.getEnterpriseId();
const messageHelpRef = useRef(null)
const domRef = useRef(null);
const listRef = useRef(list);
......@@ -53,6 +57,17 @@ function Header(props) {
storeUserId && getUserInfo();
enterpriseId ? getEnterpriseUser() : User.setIsAdmin(false);
}, [storeUserId]);
useEffect(()=> {
if (!messageHelpRef.current) {
return
}
if (menuType) {
messageHelpRef.current.style.marginLeft = "194px"
} else {
messageHelpRef.current.style.marginLeft = "76px"
}
},[menuType])
function getUserInfo() {
const param = {
......@@ -218,10 +233,10 @@ function Header(props) {
return (
<div id="top-container" className="top-container">
<div className="top top-nav">
<div>
<img src='https://image.xiaomaiketang.com/xm/WEsMPAYxAs.png' className="logo" alt="" />
</div>
<div className="message-help">
{/* <div>
<img src={topLeftLogo} className="logo" alt="" />
</div> */}
<div className="message-help" ref={messageHelpRef}>
{list.length ? (
<ClickOutside
onClickOutside={() => {
......
@import '../../core/variables.less';
@top-height: 60px;
@top-height: 0px;
@menu-bakg: #FFF;
@active-color: #2966FF;
.left-container {
......@@ -12,6 +12,23 @@
width: @xm-left-width;
background: @menu-bakg;
color: #333;
.topLogo {
height: 62px;
background: rgba(255, 255, 255, 0.5);
.img1 {
width: 138px;
height: 35px;
margin-left: 19px;
margin-top: 13px;
}
.img0 {
display: none;
width: 35px;
height: 35px;
margin-left: 10px;
margin-top: 13px;
}
}
.menu-type-icon{
margin:4px 0 0px 150px;
cursor: pointer;
......@@ -48,8 +65,8 @@
margin-right: 20px
}
.icon-img{
width:16px;
height:16px;
width:18px;
height:18px;
margin-right:16px;
}
.listType {
......
import React, { useContext, useEffect, useState, version } from 'react';
import React, { useContext, useEffect, useRef, useState } from 'react';
import {
withRouter,
} from 'react-router-dom';
......@@ -128,6 +128,9 @@ function Aside(props: any) {
const ctx: any = useContext(XMContext);
const [selectKey, setSelectKey] = useState();
const [openKeys, setOpenKeys] = useState(['']);
const [topLogoUrl, setTopLogoUrl] = useState("")
const logoImg0Ref = useRef<any>()
const logoImg1Ref = useRef<any>()
const rootSubmenuKeys = _.pluck(menuList, 'groupCode');
useEffect(() => {
const link = props.location.pathname;
......@@ -145,6 +148,22 @@ function Aside(props: any) {
return item;
})
}, [props.location.pathname])
useEffect(()=> {
getTopLeftLogo()
})
function getTopLeftLogo() {
if (User.getToken()) {
StoreService.getStoreDetail({storeId:User.getStoreId()})
.then(res=> {
if (_.isEmpty(res.result.logo)) {
setTopLogoUrl("https://image.xiaomaiketang.com/xm/fe4NCjr7XF.png")
} else {
setTopLogoUrl(res.result.logo)
}
})
}
}
function toggleMenu(item: any) {
window.RCHistory.push(item.link)
}
......@@ -158,6 +177,23 @@ function Aside(props: any) {
function handleMenu() {
handleMenuType();
}
useEffect(()=> {
if (!logoImg0Ref.current || !logoImg1Ref.current) {
return
}
if (!menuType) {
if (topLogoUrl.indexOf("xiaomaiketang.com") < 0) {
logoImg0Ref.current.style.display = "none"
logoImg1Ref.current.style.display = "none"
} else {
logoImg0Ref.current.style.display = "inline"
logoImg1Ref.current.style.display = "none"
}
} else {
logoImg0Ref.current.style.display = "none"
logoImg1Ref.current.style.display = "inline"
}
},[menuType])
return (
<div
......@@ -168,6 +204,10 @@ function Aside(props: any) {
: "left-container left-container-vertical"
}
>
<div className="topLogo">
<img ref={logoImg0Ref} src="https://image.xiaomaiketang.com/xm/c4KiP2epBP.png" alt="" className="img0"></img>
<img ref={logoImg1Ref} src={topLogoUrl} alt="" className="img1"></img>
</div>
<div className="menu-type-icon" onClick={handleMenu}>
{menuType ? (
<span
......
/*
* @Author: yuananting
* @Date: 2021-02-22 10:59:43
* @LastEditors: yuananting
* @LastEditTime: 2021-04-13 13:55:37
* @LastEditors: fusanqiasng
* @LastEditTime: 2021-06-15 11:20:48
* @Description: 助学工具-侧边课程分类树
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { Component } from "react";
import { Input, Button, Tree } from "antd";
import "./CourseCategorySiderTree.less";
import User from "@/common/js/user";
import AidToolService from "@/domains/aid-tool-domain/AidToolService";
import Bus from "@/core/bus";
import React, { Component } from 'react';
import { Input, Button, Tree } from 'antd';
import './CourseCategorySiderTree.less';
import User from '@/common/js/user';
import AidToolService from '@/domains/aid-tool-domain/AidToolService';
import Bus from '@/core/bus';
const { Search } = Input;
const { DirectoryTree } = Tree;
......@@ -20,31 +20,25 @@ class CourseCategorySiderTree extends Component {
constructor(props) {
super(props);
this.state = {
selectedKeys: ["QUESTION_INDEX", "PAPER_INDEX"].includes(props.fromModule)
? [getParameterByName("categoryId") || "null"]
: ["null"],
selectedKeys: ['QUESTION_INDEX', 'PAPER_INDEX'].includes(props.fromModule) ? [getParameterByName('categoryId') || 'null'] : ['null'],
treeData: props.treeData || [],
autoExpandParent: false,
};
}
componentDidMount() {
this.queryCategoryTree("init");
Bus.bind("queryCategoryTree", this.queryCategoryTree);
this.queryCategoryTree('init');
Bus.bind('queryCategoryTree', this.queryCategoryTree);
}
componentWillUnmount() {
Bus.unbind("queryCategoryTree", this.queryCategoryTree);
Bus.unbind('queryCategoryTree', this.queryCategoryTree);
}
// 查询分类树
queryCategoryTree = (type = "init", categoryName) => {
queryCategoryTree = (type = 'init', categoryName) => {
let query = {
bizType: ["QUESTION_INDEX", "QUESTION_MODAL"].includes(
this.props.fromModule
)
? "QUESTION"
: "PAPER",
bizType: ['QUESTION_INDEX', 'QUESTION_MODAL'].includes(this.props.fromModule) ? 'QUESTION' : 'PAPER',
categoryName,
count: true,
source: 0,
......@@ -53,7 +47,7 @@ class CourseCategorySiderTree extends Component {
};
AidToolService.queryCategoryTree(query).then((res) => {
const { categoryList = [], noCategoryCnt = 0 } = res.result;
let str = "未分类";
let str = '未分类';
if (categoryName) {
this.setState({ autoExpandParent: true });
if (str.indexOf(categoryName) < 0) {
......@@ -64,15 +58,15 @@ class CourseCategorySiderTree extends Component {
Object.keys(this.state.treeMap).forEach((item) => {
nodeId.push(item);
});
if (type === "init") {
if (type === 'init') {
this.setState({ expandedKeys: nodeId });
}
} else {
const defaultNode = {
id: "null",
categoryName: "未分类",
id: 'null',
categoryName: '未分类',
categoryCount: noCategoryCnt,
parentId: "0",
parentId: '0',
categoryLevel: 0,
};
categoryList.unshift(defaultNode);
......@@ -83,24 +77,24 @@ class CourseCategorySiderTree extends Component {
Object.keys(this.state.treeMap).forEach((item) => {
nodeId.push(item);
});
if (type === "init") {
if (type === 'init') {
this.setState({ expandedKeys: nodeId });
}
}
} else {
this.setState({ autoExpandParent: false });
const defaultNode = {
id: "null",
categoryName: "未分类",
id: 'null',
categoryName: '未分类',
categoryCount: noCategoryCnt,
parentId: "0",
parentId: '0',
categoryLevel: 0,
};
categoryList.unshift(defaultNode);
this.setState({
treeData: this.renderTreeNodes(categoryList, categoryName),
});
if (type === "init") {
if (type === 'init') {
this.setState({ expandedKeys: [] });
}
}
......@@ -126,12 +120,12 @@ class CourseCategorySiderTree extends Component {
// 树状选中事件
onSelect = (selectedKeys) => {
this.setState({ selectedKeys }, () => {
if (this.props.fromModule === "QUESTION_INDEX") {
Bus.trigger("queryQuestionPageList", selectedKeys[0]);
} else if (this.props.fromModule === "QUESTION_MODAL") {
Bus.trigger("queryQuestionPageListWithContent", selectedKeys[0]);
if (this.props.fromModule === 'QUESTION_INDEX') {
Bus.trigger('queryQuestionPageList', selectedKeys[0]);
} else if (this.props.fromModule === 'QUESTION_MODAL') {
Bus.trigger('queryQuestionPageListWithContent', selectedKeys[0]);
} else {
Bus.trigger("queryPaperPageList", selectedKeys[0], 0);
Bus.trigger('queryPaperPageList', selectedKeys[0], 0);
}
});
};
......@@ -144,39 +138,35 @@ class CourseCategorySiderTree extends Component {
item.title =
!value || (value && item.categoryName.indexOf(value) > -1) ? (
<span>
{item.categoryName}{item.categoryCount}
{item.categoryName}
{item.categoryCount > 0 && <span>{item.categoryCount}</span>}
</span>
) : (
<span style={{ opacity: 0.5 }}>
{item.categoryName}{item.categoryCount}
{item.categoryName}
{item.categoryCount > 0 && <span>{item.categoryCount}</span>}
</span>
);
item.icon =
item.categoryName === "未分类" ? (
item.categoryName === '未分类' ? (
<img
style={{
width: "24px",
height: "24px",
opacity:
!value || (value && item.categoryName.indexOf(value) > -1)
? 1
: 0.5,
width: '24px',
height: '24px',
opacity: !value || (value && item.categoryName.indexOf(value) > -1) ? 1 : 0.5,
}}
src="https://image.xiaomaiketang.com/xm/defaultCategory.png"
alt=""
src='https://image.xiaomaiketang.com/xm/defaultCategory.png'
alt=''
/>
) : (
<img
style={{
width: "24px",
height: "24px",
opacity:
!value || (value && item.categoryName.indexOf(value) > -1)
? 1
: 0.5,
width: '24px',
height: '24px',
opacity: !value || (value && item.categoryName.indexOf(value) > -1) ? 1 : 0.5,
}}
src="https://image.xiaomaiketang.com/xm/hasCategory.png"
alt=""
src='https://image.xiaomaiketang.com/xm/hasCategory.png'
alt=''
/>
);
if (item.sonCategoryList) {
......@@ -190,46 +180,34 @@ class CourseCategorySiderTree extends Component {
};
render() {
const {
treeData,
expandedKeys,
selectedKeys,
autoExpandParent,
} = this.state;
const { treeData, expandedKeys, selectedKeys, autoExpandParent } = this.state;
return (
<div className="category-tree-sider">
{["QUESTION_INDEX", "PAPER_INDEX"].includes(this.props.fromModule) && (
<div className="sider-title">
{this.props.fromModule === "QUESTION_INDEX"
? "题目分类"
: "试卷分类"}
</div>
<div className='category-tree-sider'>
{['QUESTION_INDEX', 'PAPER_INDEX'].includes(this.props.fromModule) && (
<div className='sider-title'>{this.props.fromModule === 'QUESTION_INDEX' ? '题目分类' : '试卷分类'}</div>
)}
<Search
className="sider-search"
placeholder="搜索名称分类"
className='sider-search'
placeholder='搜索名称分类'
onSearch={(value) => {
this.queryCategoryTree("init", value);
this.queryCategoryTree('init', value);
}}
enterButton={<span className="icon iconfont">&#xe832;</span>}
enterButton={<span className='icon iconfont'>&#xe832;</span>}
/>
{["QUESTION_INDEX", "PAPER_INDEX"].includes(this.props.fromModule) &&
User.getUserRole() !== "CloudLecturer" &&
this.props.type !== "modal-select" && (
<div className="sider-btn">
<Button
onClick={() => {
window.RCHistory.push({
pathname: "/course-category-manage?from=aid",
});
}}
>
分类管理
</Button>
</div>
)}
<div className="sider-tree">
{['QUESTION_INDEX', 'PAPER_INDEX'].includes(this.props.fromModule) && User.getUserRole() !== 'CloudLecturer' && this.props.type !== 'modal-select' && (
<div className='sider-btn'>
<Button
onClick={() => {
window.RCHistory.push({
pathname: '/course-category-manage?from=aid',
});
}}>
分类管理
</Button>
</div>
)}
<div className='sider-tree'>
<DirectoryTree
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
......
......@@ -5,15 +5,15 @@
* @Last Modified time: 2020-04-18 10:54:32
*/
import React, { useState, useEffect, useRef } from "react";
import "./XMAudio.less";
import VideoUpload from "@/core/upload";
import React, { useState, useEffect, useRef } from 'react';
import './XMAudio.less';
import VideoUpload from '@/core/upload';
let timerInterval;
const XMAudio = (props) => {
const ref = useRef();
const { style, size, getDuration } = props;
const { style, size, getDuration } = props;
const [url, setUrl] = useState(props.url);
const [playing, setPlaying] = useState(false);
const [timer, setTimer] = useState(null);
......@@ -22,7 +22,7 @@ const XMAudio = (props) => {
const [totalTime, setTotalTime] = useState(Math.round(Number(size)));
const prevTimeRef = useRef();
useEffect(() => {
if(!props.forbidParse){
if (!props.forbidParse) {
VideoUpload.getVideoParseRoute(props.url).then((newUrl) => {
setUrl(newUrl);
});
......@@ -30,7 +30,7 @@ const XMAudio = (props) => {
setLeftTime(Math.round(Number(size)));
setTotalTime(Math.round(Number(size)));
ref.current.addEventListener("pause", () => {
ref.current.addEventListener('pause', () => {
clearInterval(timer);
setPlaying(false);
setTimer(null);
......@@ -42,7 +42,6 @@ const XMAudio = (props) => {
}, [props.url]);
useEffect(() => {
if (playing) {
timerInterval = setInterval(() => {
setPlayedTime((preTime) => {
......@@ -53,18 +52,18 @@ const XMAudio = (props) => {
if ((prevTimeRef.current + 20) % 1000 === 0) {
setLeftTime(totalTime - (prevTimeRef.current + 20));
}
if ((prevTimeRef.current + 30) >= totalTime) {
if (prevTimeRef.current + 30 >= totalTime) {
clearInterval(timerInterval);
setPlayedTime(0);
setLeftTime(totalTime);
setPlaying(false);
}
}, 20);
const audioDomList = document.querySelectorAll("audio");
const audioDomList = document.querySelectorAll('audio');
for (let i = 0; i < Array.from(audioDomList).length; i++) {
if (audioDomList[i] === ref.current) {
ref.current.play();
setTimer(timerInterval)
setTimer(timerInterval);
} else {
audioDomList[i].pause();
}
......@@ -75,9 +74,7 @@ const XMAudio = (props) => {
}
}, [playing]);
const audioImg = `https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/${
playing ? 1584514990496 : 1584514999661
}.png`;
const audioImg = `https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/${playing ? 1584514990496 : 1584514999661}.png`;
function _togglePlay() {
playing ? pausePlay() : startPlay();
......@@ -112,78 +109,74 @@ const XMAudio = (props) => {
}
}
function _startTime() {
let time = Math.floor(playedTime / 1000);
let second = 0
let second = 0;
let minute = 0;
let result = 0
let result = 0;
if (time > 0) {
minute = Math.floor(time % 3600 / 60);
minute = Math.floor((time % 3600) / 60);
second = Math.floor((time - 60 * minute) % 60);
if (minute < 10) {
minute = "0" + minute;
minute = '0' + minute;
}
if (second < 10) {
second = "0" + second;
second = '0' + second;
}
result = minute + ':' + second
}else{
result = "00:00"
result = minute + ':' + second;
} else {
result = '00:00';
}
return result;
}
function _endTime() {
let time = Math.floor(totalTime / 1000);
let second = 0
let second = 0;
let minute = 0;
let result = 0
let result = 0;
if (time > 0) {
minute = Math.floor(time % 3600 / 60);
minute = Math.floor((time % 3600) / 60);
second = Math.floor((time - 60 * minute) % 60);
if (minute < 10) {
minute = "0" + minute;
minute = '0' + minute;
}
if (second < 10) {
second = "0" + second;
second = '0' + second;
}
result = minute + ':' + second
result = minute + ':' + second;
}
if(time === 0){
result = "00:00"
if (time === 0) {
result = '00:00';
}
return result;
}
function putDownFlag(event) {
let dragDiv = event.target;
dragDiv.style.cursor = "pointer";
dragDiv.style.cursor = 'pointer';
let offsetX = parseInt(dragDiv.style.left); // 获取当前的x轴距离
let innerX = event.clientX - offsetX; // 获取鼠标在方块内的x轴距
// 按住鼠标时为div修改样式
dragDiv.style.width = "16px";
dragDiv.style.height = "16px";
dragDiv.style.top = "-7px";
dragDiv.style.backGround = "linear-gradient(180deg, #FFB467 0%, #FF9143 100%)"
dragDiv.style.width = '16px';
dragDiv.style.height = '16px';
dragDiv.style.top = '-7px';
dragDiv.style.backGround = 'linear-gradient(180deg, #FFB467 0%, #FF9143 100%)';
// 鼠标移动的时候不停的修改div的left和top值
document.onmousemove = function (event) {
dragDiv.style.left = event.clientX - innerX + "px";
dragDiv.style.left = event.clientX - innerX + 'px';
// 边界判断
if (parseInt(dragDiv.style.left) <= 0) {
dragDiv.style.left = "0px";
dragDiv.style.left = '0px';
}
if (parseInt(dragDiv.style.left) >= 154) {
dragDiv.style.left = "149px";
dragDiv.style.left = '149px';
}
setPlayedTime(parseInt(dragDiv.style.left) / 150 * totalTime)
}
setPlayedTime((parseInt(dragDiv.style.left) / 150) * totalTime);
};
// 鼠标抬起时,清除绑定在文档上的mousemove和mouseup事件
// 否则鼠标抬起后还可以继续拖拽方块
document.onmouseup = function () {
......@@ -191,50 +184,43 @@ const XMAudio = (props) => {
document.onmouseup = null;
// 清除border
dragDiv.style.top = "-4px";
dragDiv.style.width = "10px";
dragDiv.style.height = "10px";
}
dragDiv.style.top = '-4px';
dragDiv.style.width = '10px';
dragDiv.style.height = '10px';
};
}
function mouseOver(event){
function mouseOver(event) {
let dragDiv = event.target;
dragDiv.style.cursor = "pointer";
dragDiv.style.width = "16px";
dragDiv.style.height = "16px";
dragDiv.style.top = "-7px";
dragDiv.style.backGround = "linear-gradient(180deg, #FFB467 0%, #FF9143 100%)"
dragDiv.style.cursor = 'pointer';
dragDiv.style.width = '16px';
dragDiv.style.height = '16px';
dragDiv.style.top = '-7px';
dragDiv.style.backGround = 'linear-gradient(180deg, #FFB467 0%, #FF9143 100%)';
}
function mouseLeave (event){
function mouseLeave(event) {
let dragDiv = event.target;
dragDiv.style.top = "-4px";
dragDiv.style.width = "10px";
dragDiv.style.height = "10px";
dragDiv.style.top = '-4px';
dragDiv.style.width = '10px';
dragDiv.style.height = '10px';
ref.current.currentTime = playedTime / 1000;
}
return (
<div className="xm-audio" style={style}>
<img src={audioImg} onClick={_togglePlay} className="audio-image" />
<div className="process-area">
<div
className="complete-area"
style={{ width: `${(playedTime / totalTime) * 150}px ` }}
/>
<div className='xm-audio' style={style}>
<img src={audioImg} onClick={_togglePlay} className='audio-image' />
<div className='process-area'>
<div className='complete-area' style={{ width: `${(playedTime / totalTime) * 150}px ` }} />
<div
className="flag"
className='flag'
style={{ left: `${(playedTime / totalTime) * 150}px ` }}
onMouseDown={(e) => putDownFlag(e)}
onMouseOver={(e)=> mouseOver(e)}
onMouseLeave={(e)=>mouseLeave(e)}
onMouseOver={(e) => mouseOver(e)}
onMouseLeave={(e) => mouseLeave(e)}
/>
</div>
<span className="sec-time">
{`${_startTime()}`}/{`${_endTime()}`}
</span>
<audio
src={url}
ref={ref}
autoPlay={false}
onCanPlayThrough={_getDuration}
/>
<span className='sec-time'>
{`${_startTime()}`}/{`${_endTime()}`}
</span>
<audio src={url} ref={ref} autoPlay={false} onCanPlayThrough={_getDuration} />
</div>
);
};
......
......@@ -5,10 +5,11 @@
* @Last Modified time: 2020-03-24 10:18:43
*/
.xm-audio {
.xm-audio {
display: flex;
align-items: center;
width: 280px;
padding: 10px 20px;
border-radius: 5px;
background-color: #ffffff;
.audio-image {
......@@ -24,11 +25,11 @@
cursor: pointer;
}
.play-icon {
color: #FC8540;
color: #fc8540;
}
.sec-time{
.sec-time {
white-space: nowrap;
color: #FF8534;
color: #ff8534;
margin-left: 12px;
font-size: 13px;
}
......@@ -38,11 +39,11 @@
border-radius: 3px;
margin-left: 12px;
position: relative;
background:rgba(255,133,52,0.2);
background: rgba(255, 133, 52, 0.2);
.complete-area {
height: 100%;
background-color: #FF8534;
background-color: #ff8534;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
......@@ -52,7 +53,7 @@
width: 10px;
height: 10px;
border-radius: 50%;
background:linear-gradient(180deg,rgba(255,180,103,1) 0%,rgba(255,145,67,1) 100%);
background: linear-gradient(180deg, rgba(255, 180, 103, 1) 0%, rgba(255, 145, 67, 1) 100%);
}
}
}
import React from 'react';
import { Modal, Button, message } from 'antd';
import { Modal, message } from 'antd';
import html2canvas from 'html2canvas';
import User from "../../../common/js/user";
import QRCode from '../../../libs/qrcode/qrcode';
......@@ -27,7 +27,6 @@ class ExamShareModal extends React.Component {
handleConvertShortUrl = () => {
const longUrl = `${LIVE_SHARE}test_detail/${this.props.data.examId}?id=${User.getStoreId()}`
console.log(longUrl)
// 发请求
Service.Sales('public/businessShow/convertShortUrls', {
urls: [longUrl]
......
/*
* @Author: yuananting
* @Date: 2021-04-07 16:10:21
* @LastEditors: wufan
* @LastEditTime: 2021-04-26 10:21:19
* @Description: 助学工具-考试-考试结果
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { useState, useEffect } from 'react';
import { withRouter } from 'react-router-dom';
import User from '@/common/js/user';
import './TestDetailPage.less';
import Service from '@/common/js/service';
import { message } from 'antd';
import AnswerDescPage from '../components/AnswerDescPage';
import Breadcrumbs from '@/components/Breadcrumbs';
function TestDetailPage(props) {
const examId = props.match.params.testId.replace(/\?.+/, '');
const paperId = window.getParameterByName('paperId');
const userId = window.getParameterByName('userId');
const [examDetail, setExamDetail] = useState({
answerAnalysis: '',
resultShow: '',
examDesc: '',
examDuration: 0,
examEndTime: '',
examName: '',
examStartTime: '',
paperId: 0,
passRate: 0,
passScore: 0,
resultContent: '',
totalQuestionCount: 0,
totalScore: 0,
userCorrectQuestion: 0,
userExamDuration: 0,
userScore: 0,
}); // 考试详情
const [paperDetail, setPaperDetail] = useState({}); // 试卷详情
const [questionList, setQuestionList] = useState([]); // 试卷题目列表
const [userAnswerList, setUserAnswerList] = useState([]); // 用户答案列表
const [isScrollShow, setIsScrollShow] = useState(false); // 是否展示回到顶部按钮
const { answerAnalysis, resultContent, examName, totalScore, totalQuestionCount, passScore, examDuration, userExamDuration, userScore, userCorrectQuestion } =
examDetail;
useEffect(() => {
bindScroll();
getPaperDetail();
getExamDetail();
}, []);
function bindScroll() {
window.addEventListener('scroll', handleScroll, true);
}
function getExamDetail() {
const params = {
examId,
source: 0,
tenantId: User.getStoreId() || window.getParameterByName('id'),
userId,
};
Service.Hades('public/customerHades/queryUserExamResult', params, {
reject: true,
})
.then((res) => {
const data = { ...res.result };
setExamDetail(data);
})
.catch((res) => {
if (res.code === 'EXAM_IS_NOT_EXIST') {
handleChangeShowErrorPage();
} else {
message.error(res.message);
}
});
}
function getPaperDetail() {
Service.Hades('public/customerHades/queryUserExamAnswer', {
examId,
paperId,
source: 0,
readAnswer: true,
tenantId: User.getStoreId() || window.getParameterByName('id'),
userId,
}).then((res) => {
if (res.success) {
const { paperDetailVO, userExamAnswerVO } = res.result;
const userAnswerList = [...userExamAnswerVO];
const { questionList } = paperDetailVO;
setPaperDetail(paperDetail);
setUserAnswerList(userAnswerList);
setQuestionList(questionList || []);
}
});
}
function handleChangeShowErrorPage() {
setIsShowErrorPage(true);
}
// 用户时长转换
function formatTime(msTime) {
let time = msTime / 1000;
let hour = Math.floor(time / 60 / 60) % 24 > 9 ? Math.floor(time / 60 / 60) % 24 : '0' + (Math.floor(time / 60 / 60) % 24);
let minute = Math.floor(time / 60) % 60 > 9 ? Math.floor(time / 60) % 60 : '0' + (Math.floor(time / 60) % 60);
let second = time % 60 > 9 ? Math.round(time % 60) : '0' + Math.round(time % 60);
return `${hour}:${minute}:${second}`;
}
// 快速跳转题目
function handleQuickActiveQuestion(questionId) {
let selectDom = document.getElementById(`${questionId}`);
selectDom.scrollIntoView({
block: 'center',
});
}
// 回到顶部
function handleGoTop() {
window.scrollTo(0, 0);
}
// 监听滚动,200以后出现回到顶部按钮
function handleScroll() {
if (window.pageYOffset > 200) {
setIsScrollShow(true);
} else {
setIsScrollShow(false);
}
}
function renderResultInfo() {
return (
<div>
<div className='exam-info'>
<div className='info-score item'>
<div className='current-score'>
{userScore}
<img src='https://image.xiaomaiketang.com/xm/TsaApiPyxA.png' />
</div>
<div className='origin-data'>总分{totalScore}</div>
</div>
<div className='info-level item'>
<div className='current-level'>{userScore < passScore ? '不及格' : '及格'}</div>
<div className='origin-data'>及格分{passScore}</div>
</div>
<div className='info-correct item'>
<div className='current-correct'>
{userCorrectQuestion}
<div className='text'>答对题数</div>
</div>
<div className='origin-data'>{totalQuestionCount}</div>
</div>
<div className='info-time item'>
<div className='current-time'>
{formatTime(Number(userExamDuration > examDuration ? examDuration : userExamDuration || 0))}
<div className='text'>用时</div>
</div>
<div className='origin-data'>考试时长{(examDuration || 0) / 60 / 1000}分钟</div>
</div>
</div>
<div className='exam-result'>
<div className='result-title'>
<div className='left-title'>答题情况</div>
<div className='right-tip'>
<span className='correct-num'>{userCorrectQuestion}</span>
<span className='incorrect-num'>/{totalQuestionCount} </span>
道正确
</div>
</div>
<div className='result-content'>
{sortedAnswerList.map((item, index) => {
return (
<div
className='result-content__item'
onClick={() => {
console.log('item', item);
handleQuickActiveQuestion(item.questionId);
}}>
<img
className='icon'
src={item.isCorrect === 1 ? 'https://image.xiaomaiketang.com/xm/FwZa2Kaypc.png' : 'https://image.xiaomaiketang.com/xm/7tRHDf6ysA.png'}
/>
<div className='result-content-box'>{index + 1}</div>
</div>
);
})}
</div>
</div>
<AnswerDescPage userId={userId} />
</div>
);
}
let sortedAnswerList = [];
questionList.map((item) => {
userAnswerList &&
userAnswerList.map((answerItem) => {
if (item.questionId === answerItem.questionId) {
sortedAnswerList.push(answerItem);
}
});
});
return (
<div className='exam-result-page page'>
<Breadcrumbs navList={'答题详情'} goBack={props.history.goBack} />
<div className='center'>
<div className='box'>
<div className='box-content'>
<div
className='exam-head'
style={{
padding: examName.length > 20 ? '8px 0 14px' : '16px 0 29px',
}}>
<div className={`exam-name ${examName.length > 20 ? 'many' : 'few'}`}>{examName}</div>
</div>
{renderResultInfo()}
</div>
</div>
</div>
{isScrollShow && <div className='go-top' onClick={handleGoTop}></div>}
</div>
);
}
export default withRouter(TestDetailPage);
.exam-result-page {
margin: 0 auto;
.go-top {
cursor: pointer;
position: fixed;
width: 48px;
height: 48px;
background-image: url('https://image.xiaomaiketang.com/xm/jWix2xDm4t.png');
background-size: 100%;
box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.08);
border-radius: 4px;
bottom: 125px;
right: calc(~'(100vw - 1232px)/2');
display: flex;
justify-content: center;
align-items: center;
&:hover {
background-image: url('https://image.xiaomaiketang.com/xm/GHBBNDtTDd.png');
}
}
.box {
.box-content {
position: relative;
width: 840px;
margin: 0 auto;
.exam-head {
color: #333;
text-align: center;
.exam-name {
width: 600px;
font-weight: 500;
margin: 0 auto;
font-size: 24px;
line-height: 33px;
}
.many {
font-size: 21px;
line-height: 29px;
}
.few {
font-size: 25px;
line-height: 36px;
}
}
.empty-result {
box-sizing: border-box;
margin: 0 16px;
background: #ffffff;
box-shadow: 0 -15px 10px 0 rgba(0, 34, 121, 0.1);
border-radius: 4px 4px 0 0;
padding-top: 56px;
.lack-desc {
margin-top: 16px;
.title {
font-size: 17px;
font-weight: 500;
color: #333333;
line-height: 24px;
margin-bottom: 4px;
}
.content {
font-size: 15px;
color: #999999;
line-height: 21px;
}
}
.after-desc {
margin-top: 16px;
.title {
font-size: 17px;
font-weight: 500;
color: #333333;
line-height: 24px;
margin-bottom: 20px;
}
.after-show-box {
// margin: 0 37px;
padding: 11px 21px;
background: #f4f6fa;
border-radius: 4px;
font-size: 15px;
color: #999999;
line-height: 21px;
text-align: center;
}
}
}
.exam-info {
width: 840px;
box-sizing: border-box;
margin: 0 auto;
padding: 24px 0 12px;
height: 130px;
background: #ffffff;
box-shadow: 0px 5px 30px 0px rgba(12, 54, 158, 0.08);
border-radius: 4px;
display: flex;
justify-content: center;
.item {
flex: 1 25%;
display: flex;
flex-direction: column;
// height: 130px;
align-items: center;
justify-content: space-between;
position: relative;
.origin-data {
text-align: center;
font-size: 14px;
color: #999999;
line-height: 20px;
}
.line {
&::before {
width: 1px;
height: 40px;
content: '';
position: absolute;
right: 0;
top: 0;
background-color: rgba(232, 232, 232, 1);
}
}
&.info-score {
.current-score {
font-size: 40px;
font-weight: 500;
color: #ff4f4f;
text-align: center;
line-height: 42px;
img {
display: block;
margin: 0 auto;
width: 27px;
height: 12px;
padding-left: 4px;
}
}
}
&.info-level {
.current-level {
font-size: 24px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 33px;
text-align: center;
}
}
&.info-correct {
.current-correct {
display: flex;
flex-direction: column;
padding-bottom: 20px;
justify-content: space-between;
align-items: center;
font-size: 20px;
font-weight: 500;
color: #333333;
line-height: 28px;
.text {
margin-top: 4px;
width: 48px;
height: 17px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #9b9b9b;
line-height: 17px;
text-align: center;
}
}
}
&.info-time {
.current-time {
display: flex;
flex-direction: column;
padding-bottom: 20px;
justify-content: space-between;
align-items: center;
font-size: 20px;
font-weight: 500;
color: #333333;
line-height: 28px;
}
.text {
margin-top: 4px;
width: 48px;
height: 17px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #9b9b9b;
line-height: 17px;
text-align: center;
}
}
}
}
.left-title {
font-size: 20px;
font-weight: 500;
color: #333333;
position: relative;
margin-left: 8px;
line-height: 28px;
&::before {
position: absolute;
content: '';
left: -8px;
top: 50%;
transform: translateY(-50%);
width: 4px;
height: 16px;
background-image: linear-gradient(#2966ff 83.5%, #0acca4 16.5%);
}
}
.exam-result {
padding: 44px 0 24px 0;
vertical-align: middle;
.result-title {
display: flex;
justify-content: space-between;
margin-bottom: 30px;
line-height: 24px;
.right-tip {
font-size: 15px;
font-weight: 500;
color: #999999;
.correct-num {
color: #16e0b7;
}
.incorrect-num {
font-size: 11px;
}
}
}
.result-content {
display: flex;
flex-wrap: wrap;
&__item {
position: relative;
margin: 0 16px 16px 0;
width: 36px;
height: 36px;
background: #f4f6fa;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:nth-child(5n) {
margin-right: 50px;
}
&:nth-child(15n) {
margin-right: 0px;
}
.icon {
width: 16px;
height: 16px;
position: absolute;
left: 50%;
top: 0;
transform: translate(-50%, -50%);
}
.result-content-box {
width: 36px;
height: 36px;
font-size: 15px;
line-height: 36px;
background: #f4f6fa;
border-radius: 4px;
text-align: center;
}
}
}
}
}
}
.footer-btn {
width: 100%;
position: fixed;
bottom: 0;
left: 0;
height: 64px;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
border-top: 1px solid rgba(238, 238, 238, 1);
box-sizing: border-box;
.text {
cursor: pointer;
background: #ffb714;
border-radius: 5px;
width: 342px;
font-size: 15px;
color: #ffffff;
line-height: 44px;
text-align: center;
&.disabled {
background-color: #ccc;
}
}
}
}
.dataAnalysic{
.titleBox{
position: relative;
padding-left: 28px;
font-size: 19px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 26px;
background: #FFFFFF;
&::before{
width:4px;
height:12px;
content:'';
background-image: linear-gradient(#2966FF 83.5%, #0ACCA4 16.5%);
display:inline-block;
position: absolute;
left:16px;
top:7px;
}
.dataAnalysic {
.titleBox {
position: relative;
font-size: 19px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 26px;
background: #ffffff;
&::before {
width: 4px;
height: 12px;
content: '';
background-image: linear-gradient(#2966ff 83.5%, #0acca4 16.5%);
display: inline-block;
margin-right: 8px;
}
.ant-tabs-content-holder {
margin-top: 8px;
}
}
\ No newline at end of file
}
.ant-tabs-content-holder {
margin-top: 8px;
}
}
.examination-manager{
.status{
display: inline-block;
margin-left: 4px;
border: 1px solid #999;
padding: 2px 4px;
line-height: 16px;
}
.ant-table-column-sorters {
justify-content: flex-end;
}
.examination-manager {
.status {
display: inline-block;
margin-left: 4px;
border: 1px solid #999;
padding: 2px 4px;
line-height: 16px;
}
.ant-table-column-sorter {
margin-top: 0px !important;
.ant-table-column-sorter {
margin-top: 0px !important;
}
.ant-table tbody tr {
&:nth-child(even) {
background: #fff;
}
.ant-table tbody tr {
&:nth-child(even) {
background: #fff;
}
&:nth-child(odd) {
background: #fafafa;
}
&:nth-child(odd) {
background: #fafafa;
}
}
\ No newline at end of file
}
}
.dataPanal{
border-radius: 4px;
border: 1px solid #E8E8E8;
display: flex;
.item{
text-align: center;
// width: 29.9%;
.dataPanal {
border-radius: 4px;
border: 1px solid #e8e8e8;
display: flex;
.item {
text-align: center;
// width: 29.9%;
position: relative;
flex: 1;
.num {
font-size: 26px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 26px;
margin-top: 12px;
}
.percent {
margin-top: 6px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
line-height: 17px;
height: 20px;
margin-bottom: 18px;
}
.subTitle {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
line-height: 20px;
margin-bottom: 12px;
}
.type {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
line-height: 20px;
span {
color: rgba(153, 153, 153, 1);
}
.icon {
color: rgba(204, 204, 204, 1);
font-size: 16px;
margin-right: 4px;
position: relative;
flex: 1;
.num{
font-size: 26px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 26px;
margin-top: 12px;
}
.percent{
margin-top: 6px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
line-height: 17px;
height: 20px;
margin-bottom: 18px;
}
.subTitle{
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
line-height: 20px;
margin-bottom: 12px;
}
.type{
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
line-height: 20px;
span{
color: rgba(153, 153, 153, 1);
}
.icon{
color: rgba(204, 204, 204, 1);
font-size: 16px;
margin-right: 4px;
position: relative;
top: 1px;
}
}
&:after{
content: '';
width: 0px;
height: 40px;
position: absolute;
width: 1px;
background-color: rgba(232, 232, 232, 1);
top: 40px;
right: 0px;
}
top: 1px;
}
}
&:last-child{
&:after{
display: none;
}
}
&:after {
content: '';
width: 0px;
height: 40px;
position: absolute;
width: 1px;
background-color: rgba(232, 232, 232, 1);
top: 40px;
right: 0px;
}
&:last-child {
&:after {
display: none;
}
}
.exstatus{
width: 4px;
height: 4px;
background: rgb(35, 143, 255);
display: inline-block;
border-radius: 50%;
position: relative;
top: -4px;
}
.exstatus {
width: 4px;
height: 4px;
background: rgb(35, 143, 255);
display: inline-block;
border-radius: 50%;
position: relative;
top: -4px;
}
}
.answer-detail {
color: rgb(35, 143, 255);
}
.analysic-content {
.ant-table-bordered .ant-table-tbody tr {
&.analysic-content-row {
height: 50px;
}
}
\ No newline at end of file
}
}
......@@ -88,4 +88,23 @@
.ant-dropdown-menu-item-selected > span {
color: #333333;
}
\ No newline at end of file
}
.type-order-modal {
.type-order-table {
tr {
background: #F7F8F9 !important;
display: flex;
margin-bottom: 8px;
width: 521px;
justify-content: space-between;
td {
border: none !important;
}
}
.ant-table-tbody > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td {
background: #F7F8F9 !important;
}
}
}
......@@ -19,7 +19,6 @@ import {
ConfigProvider,
Empty,
} from "antd";
import Lottie from 'react-lottie';
import { PageControl, XMTable } from "@/components";
import "./PaperList.less";
import { Route, withRouter } from "react-router-dom";
......@@ -31,7 +30,6 @@ import Service from "@/common/js/service";
import _ from "underscore";
import PaperPreviewModal from "../modal/PreviewPaperModal";
import MoveModal from '../../modal/MoveModal';
import * as nodata from '../../../lottie/nodata/data.json';
import Bus from "@/core/bus";
const { Search } = Input;
......@@ -547,14 +545,6 @@ class PaperList extends Component {
User.getUserRole()
);
const { match } = this.props;
const defaultOptions = {
loop: true,
autoplay: true,
animationData: nodata,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice'
}
}
return (
<div className={"paper-list " + this.props.type}>
<div className="paper-list-filter">
......@@ -635,15 +625,6 @@ class PaperList extends Component {
bordered
loading={loading}
renderEmpty={{
image: <div style={{ marginTop: 24 }}>
<Lottie
options={defaultOptions}
height={150}
width={150}
isStopped={false}
isPaused={false}
/>
</div>,
description: <span style={{ display: 'block', paddingBottom: 24 }}>还没有试卷</span>
}}
/>
......@@ -660,16 +641,7 @@ class PaperList extends Component {
pagination={false}
bordered
renderEmpty={{
image: <div style={{ marginTop: 24 }}>
<Lottie
options={defaultOptions}
height={150}
width={150}
isStopped={false}
isPaused={false}
/>
</div>,
description: <span style={{ display: 'block', paddingBottom: 24 }}>暂无数据</span>
description: <span style={{ display: 'block', paddingBottom: 24 }}>还没有试卷</span>
}}
/>
)}
......
......@@ -8,6 +8,7 @@
*/
import React, { Component } from "react";
import { Modal, ConfigProvider, Empty } from "antd";
import Lottie from 'react-lottie';
import User from "@/common/js/user";
import AidToolService from "@/domains/aid-tool-domain/AidToolService";
import "./PreviewPaperModal.less";
......@@ -15,6 +16,7 @@ import ScanFileModal from "@/modules/resource-disk/modal/ScanFileModal";
import _ from "underscore";
import XMAudio from "../../components/XMAudio";
import { NUM_TO_WORD_MAP } from "@/common/constants/punchClock/punchClock";
import previewEmpty from '../../../lottie/previewEmpty/data.json';
const questionTypeList = {
SINGLE_CHOICE: "单选题",
MULTI_CHOICE: "多选题",
......@@ -254,13 +256,28 @@ class PreviewPaperModal extends Component {
// 自定义空状态
customizeRenderEmpty = () => {
const defaultOptions = {
loop: true,
autoplay: true,
animationData: previewEmpty,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice'
}
}
return (
<Empty
image="https://image.xiaomaiketang.com/xm/emptyTable.png"
imageStyle={{
height: 100,
}}
description={"暂无内容"}
image={
<div style={{ marginTop: 24 }}>
<Lottie
options={defaultOptions}
height={150}
width={150}
isStopped={false}
isPaused={false}
/>
</div>
}
description={<span style={{ display: 'block', paddingBottom: 24, marginTop: 50 }}>暂无内容</span>}
></Empty>
);
};
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-03-29 10:52:26
* @LastEditors: yuananting
* @LastEditTime: 2021-05-08 16:11:27
* @LastEditTime: 2021-06-07 14:45:02
* @Description: 助学工具-试卷-新建选择题目弹窗
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -42,7 +42,8 @@ class SelectQuestionModal extends Component {
width={1080}
onOk={() => {
this.props.setSelectedQuestion(
this.listRef.current.state.selectQuestionKeys.map((item) => {
this.listRef.current.state.selectQuestionKeys.map((item, index) => {
item.sorterIndex = index;
item.questionId = item.id || item.questionId;
item.questionType = item.questionTypeEnum || item.questionType;
item.score = item.score || 2;
......
/*
* @Author: yuananting
* @Date: 2021-02-25 14:34:29
* @LastEditors: wufan
* @LastEditTime: 2021-05-14 18:17:08
* @LastEditors: yuananting
* @LastEditTime: 2021-06-09 12:00:12
* @Description: 助学工具-题库-操作题目Tab
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -66,23 +66,25 @@ class OperateQuestionTab extends Component {
}
componentDidMount() {
const { chooseOptions } = this.state;
const { questionTypeKey } = this.props;
const isEditCurrent =
getParameterByName("id") &&
getParameterByName("type") === questionTypeKey;
const optionSize = isEditCurrent ? 20 : 4;
if (
["INDEFINITE_CHOICE", "MULTI_CHOICE", "SINGLE_CHOICE"].includes(
this.props.questionTypeKey
questionTypeKey
)
) {
if (chooseOptions.length === 0) {
// 选择题(单选 多选 不定项)-插入4条默认选项
for (var i = 0; i < 4; i++) {
this.handleAddOption();
this.setState({
[`optionsValidate_${i}`]: "success",
[`optionsText_${i}`]: "",
});
}
// 选择题(单选 多选 不定项)-插入4条默认选项
for (var i = 0; i < optionSize; i++) {
this.handleAddOption();
this.setState({
[`optionsValidate_${i}`]: "success",
[`optionsText_${i}`]: "",
});
}
} else if (this.props.questionTypeKey === "JUDGE") {
} else if (questionTypeKey === "JUDGE") {
this.initJudgeOption("正确");
this.initJudgeOption("错误");
}
......@@ -634,9 +636,9 @@ class OperateQuestionTab extends Component {
this.state.stemContent,
(contentItem) => contentItem.type === "RICH_TEXT"
);
if(stemContent.textLength > 1000) {
if (stemContent.textLength > 1000) {
validateError++;
}
}
let stem = stemContent.content.replace(/<[^>]+>/g, "");
stem = stem.replace(/\&nbsp\;/gi, "");
stem = stem.replace(/\s+/g, "");
......@@ -694,7 +696,7 @@ class OperateQuestionTab extends Component {
optionUnChecked = item.isCorrectAnswer
? optionUnChecked
: optionUnChecked + 1;
if(optionContent[0].textLength > 1000) {
if (optionContent[0].textLength > 1000) {
validateError++;
}
let optionInput = optionContent[0].content.replace(/<[^>]+>/g, "");
......@@ -1040,11 +1042,11 @@ class OperateQuestionTab extends Component {
return dom ? (
<div
className="question-item_question-content"
style={{
display: ["PICTURE", "VIDEO"].includes(type)
? "inline-grid"
: "flex",
}}
style={
!["PICTURE", "VIDEO"].includes(type)
? { display: "flex" }
: { float: "left" }
}
key={index}
>
{dom}
......@@ -1194,10 +1196,8 @@ class OperateQuestionTab extends Component {
data-label="正确答案"
>
{_.map(chooseOptions, (optionItem, optionIndex) => {
const {
questionOptionContentList,
isCorrectAnswer,
} = optionItem;
const { questionOptionContentList, isCorrectAnswer } =
optionItem;
optionItem.optionSort = optionIndex;
const mediaBtn = ["VOICE", "AUDIO", "PICTURE"];
const placeHold =
......
......@@ -2,7 +2,7 @@
border-radius: 2px;
padding: 16px;
position: relative;
margin-bottom: 35px;
margin-bottom: 70px;
.editor-fill-box_single {
border-radius: 4px;
......@@ -24,7 +24,7 @@
color: #999999;
margin-top: 8px;
.fill-info_icon {
color: #2966FF;
color: #2966ff;
font-size: 14px;
padding-left: 9px;
cursor: pointer;
......@@ -72,7 +72,6 @@
}
.audio-box {
box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.1);
padding: 10px 20px;
}
.img-box {
max-width: 88px;
......@@ -229,7 +228,7 @@
line-height: 33px;
align-self: stretch;
.option-operate_item__icon:hover {
color: #2966FF;
color: #2966ff;
}
.icon {
color: #bfbfbf;
......@@ -252,7 +251,7 @@
border-radius: 4px;
border: 1px dashed #e8e8e8;
font-size: 14px;
color: #2966FF;
color: #2966ff;
line-height: 44px;
text-align: center;
cursor: pointer;
......
......@@ -32,7 +32,7 @@
color: #666666;
.input-box {
margin-bottom: 8px;
display: inline-block;
// display: inline-block;
*:not(p) {
font-weight: normal !important;
font-size: 14px !important;
......
......@@ -14,13 +14,13 @@ import UserManage from '@/modules/college-manage/UserManagePage';
import StoreDecorationPage from '@/modules/store-manage/StoreDecorationPage';
import CourseCatalogPage from '@/modules/store-manage/CourseCatalogPage';
import LiveCoursePage from '@/modules/course-manage/LiveCoursePage';
import AddLivePage from '@/modules/course-manage/AddLive'
import VideoCoursePage from '@/modules/course-manage/video-course'
import GraphicsCoursePage from '@/modules/course-manage/graphics-course'
import OfflineCoursePage from '@/modules/course-manage/offline-course'
import AddVideoCoursePage from '@/modules/course-manage/video-course/AddVideoCourse'
import AddGraphicsCoursePage from '@/modules/course-manage/graphics-course/AddGraphicsCourse'
import AddOfflineCoursePage from '@/modules/course-manage/offline-course/AddOfflineCourse'
import AddLivePage from '@/modules/course-manage/AddLive';
import VideoCoursePage from '@/modules/course-manage/video-course';
import GraphicsCoursePage from '@/modules/course-manage/graphics-course';
import OfflineCoursePage from '@/modules/course-manage/offline-course';
import AddVideoCoursePage from '@/modules/course-manage/video-course/AddVideoCourse';
import AddGraphicsCoursePage from '@/modules/course-manage/graphics-course/AddGraphicsCourse';
import AddOfflineCoursePage from '@/modules/course-manage/offline-course/AddOfflineCourse';
// import DataList from '@/modules/course-manage/DataList/DataList';
// import ClassBook from '@/modules/resource-disk';
import ResourceDisk from '@/modules/resource-disk';
......@@ -33,145 +33,152 @@ import CourseCategoryManage from '@/modules/teach-tool/components/CourseCategory
import QuestionManageIndex from '@/modules/teach-tool/question-manage/Index';
import PaperManageIndex from '@/modules/teach-tool/paper-manage/Index';
import ExaminationManagerIndex from '@/modules/teach-tool/examination-manager/Index';
import KnowledgeBase from "@/modules/knowledge-base/index";
import ExaminationManagerTestDetail from '@/modules/teach-tool/examination-manager/TestDetailPage';
import KnowledgeBase from '@/modules/knowledge-base/index';
import CollegeInfoPage from '@/modules/college-manage/CollegeInfoPage';
const mainRoutes = [
{
path: "/home",
path: '/home',
component: Home,
name: "中心首页",
name: '中心首页',
},
{
path: "/employees-manage",
path: '/employees-manage',
component: EmployeesManagePage,
name: "员工管理",
name: '员工管理',
},
{
path: '/college-employee',
component: EmployeeManage,
name: '员工管理'
component: EmployeeManage,
name: '员工管理',
},
{
path: '/personal-info',
component: personalInfoPage,
name: '个人信息'
component: personalInfoPage,
name: '个人信息',
},
{
path: "/user-manage",
path: '/user-manage',
component: UserManagePage,
name: "学员管理",
name: '学员管理',
},
{
path: '/college-user',
component: UserManage,
name: '学员管理'
component: UserManage,
name: '学员管理',
},
{
path: '/store-decoration',
component: StoreDecorationPage,
name: '学院装修'
component: StoreDecorationPage,
name: '学院装修',
},
{
path: "/live-course",
path: '/live-course',
component: LiveCoursePage,
name: "直播课",
name: '直播课',
},
{
path: "/video-course",
path: '/video-course',
component: VideoCoursePage,
name: "视频课",
name: '视频课',
},
{
path: "/graphics-course",
path: '/graphics-course',
component: GraphicsCoursePage,
name: "图文课",
name: '图文课',
},
{
path: "/offline-course",
path: '/offline-course',
component: OfflineCoursePage,
name: "线下课",
name: '线下课',
},
{
path: "/create-live-course",
path: '/create-live-course',
component: AddLivePage,
name: "创建直播课",
name: '创建直播课',
},
{
path: "/create-video-course",
path: '/create-video-course',
component: AddVideoCoursePage,
name: "创建视频课",
name: '创建视频课',
},
{
path: "/knowledge-base",
path: '/knowledge-base',
// component:ResourceDisk,
component: KnowledgeBase,
name: "知识库",
name: '知识库',
},
{
path: "/create-graphics-course",
path: '/create-graphics-course',
component: AddGraphicsCoursePage,
name: "创建图文课",
name: '创建图文课',
},
{
path: "/create-offline-course",
path: '/create-offline-course',
component: AddOfflineCoursePage,
name: "创建线下课",
name: '创建线下课',
},
{
path: "/resource-disk",
path: '/resource-disk',
component: ResourceDisk,
name: "资料云盘",
name: '资料云盘',
},
{
path: '/question-manage-index',
component:QuestionManageIndex,
name: '题库'
component: QuestionManageIndex,
name: '题库',
},
{
path: '/paper-manage-index',
component:PaperManageIndex,
name: '试卷'
component: PaperManageIndex,
name: '试卷',
},
{
path: '/examination-manage-index',
component:ExaminationManagerIndex,
name: '考试'
component: ExaminationManagerIndex,
name: '考试',
},
{
path: '/test-detail/:testId',
component: ExaminationManagerTestDetail,
// () => import('@/modules/teach-tool/examination-manager/TestDetailPage'),
name: '答题详情',
},
{
path: '/course-category-manage',
component:CourseCategoryManage,
name: '分类管理'
component: CourseCategoryManage,
name: '分类管理',
},
{
path: "/switch-route",
path: '/switch-route',
component: SwitchRoute,
name: "登录后跳转承载页",
name: '登录后跳转承载页',
},
{
path: "/plan",
path: '/plan',
component: PlanPage,
name: "培训计划",
name: '培训计划',
},
{
path: "/create-plan",
path: '/create-plan',
component: AddPlanPage,
name: "创建视频课",
name: '创建视频课',
},
{
path: '/store-info',
component:StoreInfoPage,
name: '学院信息'
component: StoreInfoPage,
name: '学院信息',
},
{
path: '/college-info',
component: CollegeInfoPage,
name: '学院信息'
component: CollegeInfoPage,
name: '学院信息',
},
{
path: "/learning-data",
path: '/learning-data',
component: LearningDataPage,
name: "学习数据",
name: '学习数据',
},
];
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-02-21 15:53:31
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-05-30 11:00:09
* @LastEditTime: 2021-06-08 16:46:15
* @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -44,22 +44,6 @@ export const menuList: any = [
]
},
{
groupName: "知识库",
groupCode: "CloudKnowledge",
icon: '&#xe8a8;',
link: '/knowledge-base',
img:'https://image.xiaomaiketang.com/xm/8sbP5rGQWh.png',
selectImg:'https://image.xiaomaiketang.com/xm/hJKCfibC22.png'
},
{
groupName: "资料云盘",
groupCode: "CloudDisk",
icon: '&#xe8aa;',
link: '/resource-disk',
img:'https://image.xiaomaiketang.com/xm/zGKbXJPzXx.png',
selectImg:'https://image.xiaomaiketang.com/xm/5sN4MzjxYc.png',
},
{
groupName: "培训管理",
groupCode: "TrainManage",
icon: '&#xe8a6;',
......@@ -96,17 +80,28 @@ export const menuList: any = [
]
},
{
groupName: "学院管理",
groupCode: "CloudShop",
groupName: "知识库",
groupCode: "CloudKnowledge",
icon: '&#xe8a8;',
link: '/knowledge-base',
img:'https://image.xiaomaiketang.com/xm/8sbP5rGQWh.png',
selectImg:'https://image.xiaomaiketang.com/xm/hJKCfibC22.png'
},
{
groupName: "资料云盘",
groupCode: "CloudDisk",
icon: '&#xe8aa;',
link: '/resource-disk',
img:'https://image.xiaomaiketang.com/xm/zGKbXJPzXx.png',
selectImg:'https://image.xiaomaiketang.com/xm/5sN4MzjxYc.png',
},
{
groupName: "人员管理",
groupCode: "PersonManage",
icon: '&#xe8a4;',
img:'https://image.xiaomaiketang.com/xm/Q8i5RSMKNc.png',
img:'https://image.xiaomaiketang.com/xm/PRCnrt35y8.png',
children: [
{
groupName: "学院信息",
groupCode: "ShopInfo",
link: '/college-info'
},
{
groupName: "员工管理",
groupCode: "ShopStaff",
link: '/college-employee'
......@@ -115,11 +110,19 @@ export const menuList: any = [
groupName: "学员管理",
groupCode: "ShopUser",
link: '/college-user'
},
}
]
},
{
groupName: "学院管理",
groupCode: "CloudShop",
icon: '&#xe8a4;',
img:'https://image.xiaomaiketang.com/xm/Q8i5RSMKNc.png',
children: [
{
groupName: "课程分类",
groupCode: "CourseCategory",
link: '/course-category-manage'
groupName: "学院信息",
groupCode: "ShopInfo",
link: '/college-info'
},
{
groupName: "学院装修",
......@@ -127,6 +130,11 @@ export const menuList: any = [
link: '/store-decoration'
},
{
groupName: "分类管理",
groupCode: "CourseCategory",
link: '/course-category-manage'
},
{
groupName: "H5学院",
groupCode: "ShopDecorationH5",
link: '/store-decoration/h5'
......@@ -138,5 +146,4 @@ export const menuList: any = [
}
]
},
]
\ No newline at end of file
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