Commit 937c309d by guomingpang
parents 2525f78b 8270c55e
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
"@typescript-eslint/eslint-plugin": "^2.10.0", "@typescript-eslint/eslint-plugin": "^2.10.0",
"@typescript-eslint/parser": "^2.10.0", "@typescript-eslint/parser": "^2.10.0",
"ali-oss": "^6.12.0", "ali-oss": "^6.12.0",
"antd": "^4.9.4", "antd": "^4.16.3",
"array-move": "^3.0.1", "array-move": "^3.0.1",
"axios": "^0.20.0", "axios": "^0.20.0",
"babel-eslint": "10.1.0", "babel-eslint": "10.1.0",
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
"bizcharts": "^3.3.0", "bizcharts": "^3.3.0",
"camelcase": "^5.3.1", "camelcase": "^5.3.1",
"case-sensitive-paths-webpack-plugin": "2.3.0", "case-sensitive-paths-webpack-plugin": "2.3.0",
"classnames": "^2.2.6", "classnames": "^2.3.1",
"cropper": "^3.1.4", "cropper": "^3.1.4",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"css-loader": "3.4.2", "css-loader": "3.4.2",
......
...@@ -5,9 +5,8 @@ ...@@ -5,9 +5,8 @@
*/ */
import React from 'react'; import React from 'react';
import { Modal, Input, Table } from 'antd'; import { Modal, Input } from 'antd';
import Service from '@/common/js/service'; import Service from '@/common/js/service';
// import _ from 'underscore';
import './ChooseMembersModal.less'; import './ChooseMembersModal.less';
import User from '@/common/js/user' import User from '@/common/js/user'
import { XMTable } from '@/components'; import { XMTable } from '@/components';
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*/ */
import React from 'react'; import React from 'react';
import { Modal, Button, Breadcrumb, Radio, message } from 'antd'; import { Modal, Button, Breadcrumb, message } from 'antd';
import Service from '@/common/js/service'; import Service from '@/common/js/service';
import { FILE_TYPE_ICON_MAP, DEFAULT_SIZE_UNIT } from "@/domains/resource-disk/constants"; import { FILE_TYPE_ICON_MAP, DEFAULT_SIZE_UNIT } from "@/domains/resource-disk/constants";
import LottieIcon from '@/components/LottieIcon'; import LottieIcon from '@/components/LottieIcon';
......
/* /*
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-31 09:34:31 * @Date: 2020-08-31 09:34:31
* @LastEditors: wufan * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-05-27 10:42:12 * @LastEditTime: 2021-06-24 19:34:21
* @Description: * @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
*/ */
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosPromise, AxiosError } from 'axios'; import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosPromise, AxiosError } from 'axios';
import { message } from 'antd'; import { message, Modal } from 'antd';
import { BASIC_HOST, TIME_OUT, USER_TYPE, VERSION, PROJECT } from '@/domains/basic-domain/constants'; import { BASIC_HOST, TIME_OUT, USER_TYPE, VERSION, PROJECT } from '@/domains/basic-domain/constants';
import User from './user'; import User from './user';
import { content } from 'html2canvas/dist/types/css/property-descriptors/content';
interface FetchParams { interface FetchParams {
url: string, url: string,
...@@ -27,7 +28,8 @@ interface HeadersType{ ...@@ -27,7 +28,8 @@ interface HeadersType{
storeId?:any, storeId?:any,
storeUserId?:any, storeUserId?:any,
userId?:any, userId?:any,
xmtoken?:any xmtoken?:any,
enterpriseId?:string|null
} }
class Axios { class Axios {
static post( static post(
...@@ -51,6 +53,9 @@ class Axios { ...@@ -51,6 +53,9 @@ class Axios {
if(User.getToken()){ if(User.getToken()){
headerObject.xmtoken = User.getToken(); headerObject.xmtoken = User.getToken();
} }
if (User.getEnterpriseId()) {
headerObject.enterpriseId = User.getEnterpriseId();
}
const instance: AxiosInstance = axios.create({ const instance: AxiosInstance = axios.create({
timeout: TIME_OUT, timeout: TIME_OUT,
responseType: 'json', responseType: 'json',
...@@ -84,8 +89,14 @@ class Axios { ...@@ -84,8 +89,14 @@ class Axios {
}) })
instance.interceptors.response.use((response: AxiosResponse): AxiosResponse | AxiosPromise => { instance.interceptors.response.use((response: AxiosResponse): AxiosResponse | AxiosPromise => {
const { message: ResMessage, success, resultMsg, resultCode } = response.data; const { message: ResMessage, success, resultMsg, code: resultCode } = response.data;
if (success || resultCode === 0) { if (resultCode === "CROP_DEPLOY_PAST_BETTER") {
Modal.warning({
title:"服务已到期",
content: "当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买",
okText: "我知道了"
})
} else if (success || resultCode === 0) {
return response; return response;
} else if (!options.reject) { } else if (!options.reject) {
message.error(ResMessage || resultMsg); message.error(ResMessage || resultMsg);
......
...@@ -2,21 +2,30 @@ ...@@ -2,21 +2,30 @@
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-31 09:34:25 * @Date: 2020-08-31 09:34:25
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-05-12 17:27:08 * @LastEditTime: 2021-06-23 16:08:50
* @Description: * @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
*/ */
import Storage from './storage'; import Storage from './storage';
import { PREFIX, USER_PREFIX } from '@/domains/basic-domain/constants'; import { PREFIX, USER_PREFIX } from '@/domains/basic-domain/constants';
declare var window:any;
class User { class User {
getStoreId() {
return Storage.get(`${PREFIX}_storeId`); getExpirationTime() {
return Storage.get(`${PREFIX}_expiration_time`)
}
getVersion() {
return Storage.getObj(`${PREFIX}_version`)
}
getStoreId(){
return window.currentStoreUserInfo.storeId || Storage.get(`${PREFIX}_storeId`)
} }
getEnterpriseId() { getEnterpriseId() {
return Storage.get(`${PREFIX}_enterpriseId`); return window.currentStoreUserInfo.enterpriseId || Storage.get(`${PREFIX}_enterpriseId`);
} }
getStoreName() { getStoreName() {
...@@ -28,29 +37,39 @@ class User { ...@@ -28,29 +37,39 @@ class User {
} }
getStoreUserId() { getStoreUserId() {
return Storage.get(`${PREFIX}_storeUserId`); return window.currentStoreUserInfo.storeUserId || Storage.get(`${PREFIX}_storeUserId`);
} }
getCustomerId() { getCustomerId() {
return Storage.get(`${PREFIX}_customerId`); return Storage.get(`${PREFIX}_customerId`);
} }
getUserId() { getUserId() {
return Storage.get(`${PREFIX}_userId`); return window.currentStoreUserInfo.userId || Storage.get(`${PREFIX}_userId`);
} }
getUserRole() { getUserRole() {
return Storage.get(`${PREFIX}_userRole`); return Storage.get(`${PREFIX}_userRole`);
} }
getToken() { getToken() {
return Storage.get(`${PREFIX}_token`); return window.currentStoreUserInfo.token || Storage.get(`${PREFIX}_token`);
} }
getIsAdmin() { getIsAdmin() {
return Storage.get(`${PREFIX}_isAdmin`); return Storage.get(`${PREFIX}_isAdmin`);
} }
setStoreId(value: any) { setExpirationTime(value:number) {
return Storage.set(`${PREFIX}_storeId`, value); return Storage.set(`${PREFIX}_expiration_time`,value)
}
setVersion(value:any) {
return Storage.setObj(`${PREFIX}_version`,value)
}
setStoreId(value:any){
return Storage.set(`${PREFIX}_storeId`,value)
} }
setEnterpriseId(value: any) { setEnterpriseId(value: any) {
......
...@@ -11,3 +11,6 @@ ...@@ -11,3 +11,6 @@
padding: 16px; padding: 16px;
background-color: #F0F2F5; background-color: #F0F2F5;
} }
.ant-tooltip-inner {
max-width: 1000px;
}
\ No newline at end of file
{"v":"5.6.10","fr":25,"ip":0,"op":25,"w":150,"h":150,"nm":"搜索无结果","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"“ͼ²ã 3”轮廓","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,74,0],"ix":2},"a":{"a":0,"k":[70,63.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-70,0.5],[40,0.5],[40,-0.5],[-70,-0.5]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[52.1,0.5],[70,0.5],[70,-0.5],[52.1,-0.5]],"c":true},"ix":2},"nm":"路径 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"合并路径 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.627450980392,0.670587995941,0.792156982422,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[70,126],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"“ͼ²ã 4”轮廓","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[5]},{"t":20,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[53.25,58.75,0],"to":[0,-0.292,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":10,"s":[53.25,57,0],"to":[0,0,0],"ti":[0,-0.292,0]},{"t":20,"s":[53.25,58.75,0]}],"ix":2},"a":{"a":0,"k":[48.25,48.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.3,0.4],[1.1,-0.6],[0.5,-1.4],[0,0],[-0.5,0.3],[-0.8,-0.3],[-0.3,-0.5],[0.2,-0.7],[0.4,-0.3],[0,0],[0.4,-0.4],[0.3,-0.8],[0,0],[0,0],[0,0],[-0.3,0.3],[-0.5,0.2],[0,0],[-0.1,0.1],[-0.3,0.9],[0.6,0.9]],"o":[[-1.4,-0.4],[-1.1,0.5],[0,0],[0.3,-0.8],[0.5,-0.4],[0.7,0.2],[0.2,0.5],[-0.1,0.5],[0,0],[-1.6,0.7],[-0.4,0.4],[0,0],[0,0],[0,0],[0.1,-0.5],[0.3,-0.3],[0,0],[0.5,-0.2],[0.6,-0.5],[0.4,-1.2],[-0.6,-0.9]],"v":[[1.25,-6.75],[-2.45,-6.55],[-4.75,-3.65],[-2.55,-2.95],[-1.45,-4.65],[0.55,-4.85],[1.95,-3.85],[2.05,-2.15],[1.15,-0.95],[0.85,-0.75],[-2.15,0.95],[-3.15,2.75],[-3.25,2.85],[-1.05,3.55],[-0.95,3.25],[-0.25,2.05],[0.85,1.35],[2.05,0.85],[2.95,0.35],[4.35,-1.75],[4.05,-4.85]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-0.4,-0.1],[-0.2,-0.3],[0.1,-0.5],[0.3,-0.2],[0.4,0.1],[0.2,0.3],[-0.2,0.5],[-0.4,0.2]],"o":[[0.4,0.1],[0.2,0.3],[-0.1,0.4],[-0.4,0.2],[-0.4,-0.1],[-0.2,-0.4],[0.1,-0.4],[0.3,-0.2]],"v":[[-2.45,4.15],[-1.55,4.85],[-1.45,6.05],[-2.15,6.95],[-3.35,7.05],[-4.25,6.35],[-4.35,5.15],[-3.55,4.25]],"c":true},"ix":2},"nm":"路径 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"合并路径 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.160783999574,0.4,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.65,41.15],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"形状图层 1","sr":1,"ks":{"o":{"a":0,"k":19,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[22.695,22.109],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.87450986376,0.901960844152,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-14.777,8.93],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"“ͼ²ã 5”轮廓","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[-7]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[-9]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[-9]},{"t":25,"s":[-7]}],"ix":10},"p":{"a":0,"k":[106.125,131.5,0],"ix":2},"a":{"a":0,"k":[114.75,123.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.099,0.014],[0,0],[-0.051,-1.117],[0,0],[-1.116,0.05],[-0.112,0.086],[0,0],[-0.121,0.892],[0,0],[1.09,0.148]],"o":[[0,0],[-1.104,-0.049],[0,0],[-0.05,1.104],[0.1,0.013],[0,0],[0.833,-0.189],[0,0],[0.147,-1.09],[-0.198,-0.027]],"v":[[3.861,-4.084],[-3.904,-4.131],[-5.884,-2.18],[-5.968,2.148],[-4.018,4.13],[-3.608,4.084],[3.85,2.677],[5.493,0.982],[5.871,-1.792],[4.158,-4.043]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.862744978362,0.886274988511,0.945097979377,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[101.329,76.27],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.109,-3.648],[0,0],[-0.135,0.99],[-1.527,0.096],[-1.086,-1.661]],"o":[[0,0],[-4.167,-3.493],[0.089,-1.401],[1.229,-0.135],[1.158,1.873]],"v":[[6.657,2.541],[-0.354,7.339],[-6.522,0.749],[-3.642,-6.329],[4.847,-5.678]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901961023667,0.917646998985,0.956862984452,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[102.189,79.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.292,-8.52],[-8.486,-2.197],[-2.86,7.558],[0,0],[0,0],[0,0],[7.656,1.972]],"o":[[-2.198,8.486],[7.913,2.09],[0,0],[0,0],[0,0],[0.613,-7.581],[-8.392,-2.232]],"v":[[-17.808,-3.965],[-6.498,15.418],[12.397,5.674],[18.779,7.37],[20.006,3.185],[13.402,1.466],[1.575,-15.275]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.577,6.124],[-6.159,-1.671],[1.671,-6.16],[6.159,1.671]],"o":[[1.577,-6.125],[6.159,1.671],[-1.671,6.159],[-6.16,-1.671]],"v":[[-13.565,-2.865],[0.476,-11.032],[8.642,3.01],[-5.399,11.176]],"c":true},"ix":2},"nm":"路径 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"合并路径 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.160783999574,0.4,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[77.396,70.77],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 3","np":4,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.198,-8.485],[-8.485,-2.197],[-2.697,7.711],[0,0],[0,0],[0,0],[7.562,2.006]],"o":[[-2.198,8.486],[8.007,2.056],[0,0],[0,0],[0,0],[0.648,-7.487],[-8.452,-2.104]],"v":[[-17.786,-3.965],[-6.476,15.417],[12.444,5.452],[18.884,7.019],[19.984,2.776],[13.355,1.278],[1.563,-15.369]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.671,6.159],[-6.16,-1.671],[1.671,-6.16],[6.16,1.671]],"o":[[1.577,-6.125],[6.159,1.671],[-1.671,6.159],[-6.124,-1.577]],"v":[[-13.543,-2.866],[0.499,-11.032],[8.664,3.009],[-5.377,11.175]],"c":true},"ix":2},"nm":"路径 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"合并路径 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.64313695571,0.839215985466,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[75.467,70.514],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 4","np":4,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.983,1.086],[0,0],[-1.807,-0.492]],"o":[[-1.513,-0.414],[0,0],[1.182,1.312],[0,0]],"v":[[2.478,0.351],[-1.259,-1.934],[-2.478,-0.834],[2.046,1.934]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[69.921,76.684],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.786,-12.74],[0.791,12.84],[1.786,12.74],[-0.791,-12.84]],"c":false},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.627450980392,0.670587995941,0.792156982422,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[103.092,100.967],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.842,0.995],[6.633,20.985],[1.849,5.701],[0,0],[-0.597,-6.742],[-2.239,-2.827]],"o":[[2.805,-3.555],[-1.704,-5.278],[0,0],[0.61,6.643],[0.859,10.007],[4.38,5.642]],"v":[[5.275,20.19],[3.067,-7.358],[-2.262,-23.827],[-9.7,-19.591],[-7.896,0.536],[-5.755,18.186]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901961023667,0.917646998985,0.956862984452,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[110.976,102.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"“ͼ²ã 6”轮廓","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[-2]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[0]},{"t":25,"s":[-2]}],"ix":10},"p":{"a":0,"k":[46.75,103.75,0],"ix":2},"a":{"a":0,"k":[41.75,93.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.208,0.425],[0.18,0.149],[0.231,0.035],[0.096,0],[0.16,-0.072],[0.089,-0.227],[0.005,-0.268],[0,0],[-0.011,0.006],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.082,-0.247],[-0.038,-0.437]],"o":[[-0.059,-0.648],[-0.105,-0.212],[-0.179,-0.15],[-0.098,-0.015],[-0.162,0],[-0.244,0.106],[-0.093,0.229],[0,0],[0.001,-0.262],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.069,0.056],[0.082,0.245],[0,0]],"v":[[1.424,1.184],[1.055,-0.411],[0.634,-0.962],[0.002,-1.247],[-0.288,-1.271],[-0.778,-1.174],[-1.297,-0.619],[-1.424,0.117],[-0.424,0.132],[-0.358,-0.268],[-0.364,-0.272],[-0.36,-0.267],[-0.358,-0.268],[-0.364,-0.272],[-0.36,-0.267],[-0.382,-0.294],[-0.366,-0.262],[-0.36,-0.267],[-0.382,-0.294],[-0.366,-0.262],[-0.354,-0.266],[-0.288,-0.271],[-0.155,-0.259],[-0.004,-0.192],[0.243,0.242],[0.428,1.271]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.627450980392,0.670587995941,0.792156982422,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[26.311,80.461],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.227,-0.717],[0.951,1.669],[-1.523,0.67],[-0.935,-1.767]],"o":[[-1.228,0.717],[-0.951,-1.669],[1.523,-0.67],[0.935,1.769]],"v":[[1.99,3.052],[-2.205,0.768],[-1.693,-3.099],[2.153,-1.174]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901961023667,0.917646998985,0.956862984452,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[26.551,81.273],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[11.126,-0.566],[-0.675,-2.132],[0.655,-0.302],[-0.723,0.089],[-0.51,1.944],[0.119,0.524],[-0.636,2.734],[-6.57,-3.268],[-0.597,-0.702],[3.643,-7.017]],"o":[[0.083,0.114],[0.135,0.427],[-0.983,0.451],[-4.375,-4.338],[0.719,-2.619],[-0.441,-1.69],[1.432,-5.848],[1.403,0.728],[0.764,0.931],[-2.378,4.787]],"v":[[-7.743,8.907],[-6.663,12.317],[-9.621,12.457],[-9.897,12.919],[-15.694,3.496],[-13.562,0.898],[-13.601,-3.968],[6.854,-9.74],[11.71,-10.995],[12.562,0.884]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.345097979377,0.388234994926,0.509803981407,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[35.072,65.811],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.87,0.778],[1.153,0.181],[0.87,-0.778],[-1.153,-0.181]],"c":false},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.356862984452,0.4,0.521568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[40.506,84.78],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.16,-0.257],[0,-0.148],[0.091,-0.129],[0.244,-0.14],[0,0],[-0.201,0.276],[0.002,0.343],[0.23,0.367],[0.425,0.377],[0,0]],"o":[[0.375,0.333],[0.162,0.258],[-0.002,0.131],[-0.092,0.127],[0,0],[0.33,-0.191],[0.201,-0.275],[0,-0.39],[-0.232,-0.369],[0,0],[0,0]],"v":[[-1.009,-1.199],[-0.209,-0.305],[0.007,0.303],[-0.119,0.668],[-0.615,1.08],[-0.115,1.947],[0.691,1.255],[1.007,0.303],[0.639,-0.836],[-0.345,-1.947],[-1.009,-1.198]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.356862984452,0.4,0.521568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.695,78.259],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.829,-0.803],[-0.11,1.149],[0.829,0.803],[0.109,-1.149]],"c":false},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.356862984452,0.4,0.521568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[35.411,79.067],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.416,-0.979],[-0.466,1.657],[1.416,0.979],[0.466,-1.657]],"c":false},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.356862984452,0.4,0.521568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[44.491,75.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.114,-0.083],[-2.035,-5.689],[0,0],[-5.689,2.035],[1.9,5.263],[0.067,0.214],[1.012,3.197],[5.641,-1.739]],"o":[[-5.689,2.036],[0,0],[2.035,5.689],[5.262,-1.9],[-0.052,-0.311],[-0.337,-1.065],[-1.754,-5.543],[-0.083,-0.114]],"v":[[-4.55,-13.548],[-11.144,0.595],[-8.973,6.709],[5.169,13.303],[11.279,0.298],[10.993,-0.456],[9.051,-6.736],[-4.238,-13.6]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901961023667,0.917646998985,0.956862984452,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[37.427,76.893],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 8","np":2,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.9,0.107],[-2.644,1.14],[0,0],[0,0]],"o":[[2.423,2.276],[3.014,-0.111],[0,0],[0,0],[0,0]],"v":[[-7.198,1.043],[0.51,4.246],[7.198,2.492],[5.017,-4.353],[-5.794,-2.735]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.345097979377,0.388234994926,0.509803981407,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[40.326,87.963],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 9","np":2,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-3.737,1.298],[0.971,3.253],[0.105,0.095],[0.1,-0.005]],"o":[[0,0],[0,0],[1.271,3.238],[3.842,-1.202],[-0.005,-0.101],[-0.005,-0.1],[0,0]],"v":[[5.027,-9.962],[-9.249,-5.309],[-5.898,5.13],[3.099,8.664],[8.278,0.482],[8.162,0.188],[8.052,-0.007]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.890196018593,0.909803981407,0.960784014534,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[39.246,89.973],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 10","np":2,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"“ͼ²ã 7”轮廓","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,74,0],"ix":2},"a":{"a":0,"k":[70,63.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.854,0.007],[0.007,0.854],[0.854,-0.006],[-0.007,-0.854]],"o":[[0.854,-0.007],[-0.006,-0.854],[-0.854,0.007],[0.006,0.855]],"v":[[0.035,1.486],[1.486,-0.035],[-0.035,-1.487],[-1.486,0.035]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901961023667,0.917646998985,0.956862984452,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[28.197,124.349],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.049,1.802],[4.401,0.025],[0.009,-3.324],[-3.898,-0.11]],"o":[[0.009,-3.324],[-4.401,-0.024],[-0.022,1.615],[4.121,0.132]],"v":[[7.981,2.129],[-0.013,-3.907],[-8.008,2.054],[-0.449,3.33]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901961023667,0.917646998985,0.956862984452,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[19.727,122.622],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.503,-2.959],[-1.367,-4.04],[0,0],[2.631,3.121],[4.447,0.017]],"o":[[4.236,0.032],[2.554,3.03],[0,0],[-1.406,-4.157],[-2.681,-3.193],[0,0]],"v":[[-8.442,-6.963],[1.557,-2.6],[7.495,7.963],[8.442,7.643],[2.322,-3.245],[-8.436,-7.963]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.627450980392,0.670587995941,0.792156982422,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[29.966,115.441],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.013,-2.877],[0.546,-9.378],[0,0],[0,0],[5.511,2.615]],"o":[[-2.91,4.293],[0,0],[0,0],[0.658,-5.932],[-5.15,-2.415]],"v":[[-6.812,-6.491],[-12.009,14.064],[5.068,14.085],[11.351,1.067],[3.997,-11.67]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.803921987496,0.83529399797,0.917646998985,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[24.722,111.739],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.3,-5.601],[-3.1,-17.601],[0,0],[0,0],[-5,1.2]],"o":[[0.9,3.699],[0,0],[0,0],[13,-8],[6.9,-1.5]],"v":[[17.1,-11.35],[23.1,20.65],[-17.6,20.65],[-23.1,-5.45],[3.9,-19.15]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.803921987496,0.83529399797,0.917646998985,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[46.9,105.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"“ͼ²ã 8”轮廓","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,74,0],"ix":2},"a":{"a":0,"k":[70,63.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.3,4.9],[-6.9,-1.3],[-10.3,-4.601],[0,0],[0,0]],"o":[[1,-1.5],[3.7,0.7],[0,0],[0,0],[-8.2,-5]],"v":[[-16.65,-10.15],[-0.95,-12.95],[19.95,-4.95],[11.85,14.25],[-9.35,4.75]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752940996955,0.788234994926,0.882353001015,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[62.523,98.47],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.4,-3.9],[0,0],[-3.9,-2.399],[-0.1,-0.101],[0,0],[-1.199,1.9],[0,0],[3.7,2.5],[0.2,0.1],[0,0]],"o":[[0,0],[-2.4,3.8],[0.1,0.101],[0,0],[2,1.1],[0,0],[2.5,-3.7],[-0.199,-0.1],[0,0],[-4.1,-2.2]],"v":[[-16.2,-9.85],[-16.5,-9.45],[-13.9,1.85],[-13.5,2.15],[8,13.95],[13.7,12.55],[16.4,8.65],[14.2,-2.45],[13.6,-2.85],[-4.6,-12.85]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901961023667,0.917646998985,0.956862984452,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[84.373,106.569],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"“ͼ²ã 9”轮廓","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,74,0],"ix":2},"a":{"a":0,"k":[70,63.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.6,0],[0,0],[0,-0.6],[0,0],[-0.6,0],[0,0],[0,0.6],[0,0]],"o":[[0,0],[-0.6,0],[0,0],[0,0.6],[0,0],[0.6,0],[0,0],[0,-0.6]],"v":[[12.5,-2.5],[-12.5,-2.5],[-13.5,-1.5],[-13.5,1.5],[-12.5,2.5],[12.5,2.5],[13.5,1.5],[13.5,-1.5]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.96470600203,0.968626972273,0.984314024682,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[67.5,29.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.6,0],[0,0],[0,-0.6],[0,0],[-0.6,0],[0,0],[0,0.6],[0,0]],"o":[[0,0],[-0.6,0],[0,0],[0,0.6],[0,0],[0.6,0],[0,0],[0,-0.6]],"v":[[12.5,-2.5],[-12.5,-2.5],[-13.5,-1.5],[-13.5,1.5],[-12.5,2.5],[12.5,2.5],[13.5,1.5],[13.5,-1.5]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.96470600203,0.968626972273,0.984314024682,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[67.5,20.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.6,0],[0,0],[0,-0.6],[0,0],[-0.6,0],[0,0],[0,0.6],[0,0]],"o":[[0,0],[-0.6,0],[0,0],[0,0.6],[0,0],[0.6,0],[0,0],[0,-0.6]],"v":[[6.5,-2.5],[-6.5,-2.5],[-7.5,-1.5],[-7.5,1.5],[-6.5,2.5],[6.5,2.5],[7.5,1.5],[7.5,-1.5]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.96470600203,0.968626972273,0.984314024682,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[61.5,11.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.6,0],[0,0],[0,-0.6],[0,0],[-0.6,0],[0,0],[0,0.6],[0,0]],"o":[[0,0],[-0.6,0],[0,0],[0,0.6],[0,0],[0.6,0],[0,0],[0,-0.6]],"v":[[17,-2.5],[-17,-2.5],[-18,-1.5],[-18,1.5],[-17,2.5],[17,2.5],[18,1.5],[18,-1.5]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.96470600203,0.968626972273,0.984314024682,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[72,2.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"“ͼ²ã 10”轮廓","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,74,0],"ix":2},"a":{"a":0,"k":[70,63.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.1,0],[0,0],[0,-1.1],[0,0],[-1.1,0],[0,0],[0,1.1],[0,0]],"o":[[0,0],[-1.1,0],[0,0],[0,1.1],[0,0],[1.1,0],[0,0],[0,-1.1]],"v":[[18.5,-25],[-18.5,-25],[-20.5,-23],[-20.5,23],[-18.5,25],[18.5,25],[20.5,23],[20.5,-23]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.960784014534,0.968626972273,0.984314024682,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[23.5,52],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"“ͼ²ã 11”轮廓","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,74,0],"ix":2},"a":{"a":0,"k":[70,63.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.6,0],[0,0],[0,-0.6],[0,0],[-0.6,0],[0,0],[0,0.6],[0,0]],"o":[[0,0],[-0.6,0],[0,0],[0,0.6],[0,0],[0.6,0],[0,0],[0,-0.6]],"v":[[12.5,-2.5],[-12.5,-2.5],[-13.5,-1.5],[-13.5,1.5],[-12.5,2.5],[12.5,2.5],[13.5,1.5],[13.5,-1.5]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.87450986376,0.901960844152,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[117.5,44.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.5,5.5],[-5.5,-5.5],[5.5,-5.5],[5.5,5.5]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.875903739181,0.902435601926,0.955499387255,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[109.5,30.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.2,0],[0,0],[0,3.3],[0,0]],"o":[[0,0],[0,2.2],[0,0],[-3.3,0],[0,0],[0,0]],"v":[[14.6,-6],[14.6,2],[18.6,6],[-12.6,6],[-18.6,0],[-18.6,-6]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901961023667,0.917646998985,0.956862984452,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[112.6,64],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0.6],[0,0],[-0.6,0],[0,0],[0,-0.6],[0,0],[0.6,0]],"o":[[-0.6,0],[0,0],[0,-0.6],[0,0],[0.6,0],[0,0],[0,0.6],[0,0]],"v":[[-13.5,4],[-14.5,3],[-14.5,0],[-13.5,-1],[11.5,-1],[12.5,0],[12.5,3],[11.5,4]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-14.5,-7],[-14.5,-18],[-3.5,-18],[-3.5,-7]],"c":true},"ix":2},"nm":"路径 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0.6,0],[0,0],[0,-0.6],[0,0],[-0.6,0],[0,0],[0,2.8],[0,0]],"o":[[0,0],[-0.6,0],[0,0],[0,0.6],[0,0],[2.8,0],[0,0],[0,-0.6]],"v":[[19.5,-27],[-19.5,-27],[-20.5,-26],[-20.5,26],[-19.5,27],[15.5,27],[20.5,22],[20.5,-26]],"c":true},"ix":2},"nm":"路径 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"合并路径 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.960784014534,0.968626972273,0.984314024682,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[118.5,43],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"组 4","np":5,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":25,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
.ant-popover .ant-popover-content .ant-popover-inner {
box-shadow: 0px 2px 20px 0px rgba(0, 0, 0, 0.06);
.ant-popover-inner-content {
padding: 0;
}
}
.contact-widget {
width: 276px;
height: 294px;
overflow: hidden;
background-color: white;
background-image: url(https://image.xiaomaiketang.com/xm/CZ4a752jzi.png);
background-repeat: no-repeat;
background-size: cover;
text-align: center;
font-size: 14px;
font-weight: 400;
color: #333333;
line-height: 22px;
.qrcode {
width: 182px;
height: 204px;
background-color: white;
margin: 28px auto 16px auto;
img {
width: 150px;
height: 150px;
margin: 16px 16px 8px 16px;
}
}
}
\ No newline at end of file
import React, { ReactElement } from "react";
import { Popover } from "antd";
import { TooltipPlacement } from "antd/lib/tooltip";
import { ActionType } from "rc-trigger/lib/interface";
import "./ContactWidget.less"
interface ContactWidgetProps {
placement: TooltipPlacement
children: React.ReactElement
visible?: boolean
trigger: ActionType | ActionType[]
}
function Content() {
return (
<div className="contact-widget">
<div className="qrcode">
<img src="https://cdn.xiaomai5.com/qixueyuankehu.png" alt=""></img>
<div className="des">微信/企业微信扫码咨询</div>
</div>
<div className="phone"><svg style={{position:"relative",top:"2px",marginRight:"4px"}} viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M512.651 3.78c-281.433 0-509.21 228.324-509.21 509.209 0 281.43 228.325 509.203 509.21 509.203 281.427 0 509.202-228.317 509.202-509.203 0.55-280.885-227.775-509.21-509.202-509.21z m198.205 743.553c-36.14 36.136-169.737 1.641-302.24-130.312-131.953-131.959-165.902-266.104-129.768-301.695 31.211-31.21 68.99-85.417 125.939-14.782 56.943 70.629 29.016 90.34-3.291 122.647-22.449 22.448 24.642 79.392 73.37 128.125 49.283 48.73 105.678 95.818 128.126 73.368 32.306-32.305 52.017-60.23 122.646-3.288 71.182 56.949 16.426 95.276-14.782 125.937z" p-id="4409" fill="#999999"></path></svg>
咨询电话:19157875632</div>
</div>
)
}
export default function ContactWidget(props:ContactWidgetProps) {
return <Popover
placement={props.placement}
arrowPointAtCenter
content={Content}
visible={props.visible}
trigger={props.trigger}
>
{props.children}
</Popover>
}
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: wufan * @Author: wufan
* @Date: 2021-06-15 13:48:35 * @Date: 2021-06-15 13:48:35
* @LastEditors: wufan * @LastEditors: wufan
* @LastEditTime: 2021-06-15 14:24:57 * @LastEditTime: 2021-06-24 11:10:45
* @Description: Description * @Description: Description
*/ */
import React from 'react'; import React from 'react';
...@@ -12,6 +12,7 @@ import student from '@/common/lottie/student.json'; ...@@ -12,6 +12,7 @@ import student from '@/common/lottie/student.json';
import activity from '@/common/lottie/activity.json'; import activity from '@/common/lottie/activity.json';
import teacher from '@/common/lottie/teacher.json'; import teacher from '@/common/lottie/teacher.json';
import college from '@/common/lottie/college.json'; import college from '@/common/lottie/college.json';
import search from '@/common/lottie/search.json';
import './LottieIcon.less'; import './LottieIcon.less';
...@@ -29,7 +30,8 @@ const ANIMATION_DATA_MAP: { ...@@ -29,7 +30,8 @@ const ANIMATION_DATA_MAP: {
student, student,
activity, activity,
teacher, teacher,
college college,
search
} }
function LottieIcon(props: LottieIconInterface) { function LottieIcon(props: LottieIconInterface) {
......
/* /*
* @Author: yuananting * @Author: yuananting
* @Date: 2021-03-03 15:13:12 * @Date: 2021-03-03 15:13:12
* @LastEditors: fusanqiasng * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-16 09:57:18 * @LastEditTime: 2021-06-22 14:31:46
* @Description: 助学工具接口 * @Description: 助学工具接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
......
/* /*
* @Author: wufan * @Author: wufan
* @Date: 2020-12-01 17:21:21 * @Date: 2020-12-01 17:21:21
* @LastEditors: zhangleyuan * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-04-09 14:28:09 * @LastEditTime: 2021-06-22 14:56:34
* @Description: Description * @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import Service from "@/common/js/service"; import Service from "@/common/js/service";
import axios from 'axios';
import User from "@/common/js/user";
export function sendLoginAuthCode(params: object) { export function sendLoginAuthCode(params: object) {
return Service.Hades("anon/hades/sendLoginAuthCode", params); return Service.Hades("anon/hades/sendLoginAuthCode", params);
...@@ -47,6 +49,19 @@ export function getEnterpriseUser(params: object) { ...@@ -47,6 +49,19 @@ export function getEnterpriseUser(params: object) {
export function getWXWorkLoginNoCheck(params: object) { export function getWXWorkLoginNoCheck(params: object) {
return Service.Hades('anon/hades/getWXWorkLoginNoCheck', params); return Service.Hades('anon/hades/getWXWorkLoginNoCheck', params);
} }
export function getYoZoSign(params: object) {
return Service.Apollo('public/apollo/getYoZoSign', params);
}
export function saveYoZoFileVersionId(params: object) {
return Service.Apollo('public/apollo/saveYoZoFileVersionId', params);
}
export function yoZoUpload(ossUrl:String,appId:String,uploadSign:String){
return axios.post(`https://dmc.yozocloud.cn/api/file/http?fileUrl=${ossUrl}&appId=${appId}&sign=${uploadSign}`)
}
export function getLesseeVersionMsg() {
return Service.Hades("public/customerHades/getLesseeVersionMsg",{enterpriseId:User.getEnterpriseId()})
}
export const getOssClient = ( export const getOssClient = (
data: object, data: object,
instId: string, instId: string,
...@@ -63,3 +78,4 @@ export const getOssClient = ( ...@@ -63,3 +78,4 @@ export const getOssClient = (
}); });
} }
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import Service from "@/common/js/service"; import Service from "@/common/js/service";
import User from "@/common/js/user"
export function getEmployeeList(params: object) { export function getEmployeeList(params: object) {
return Service.Hades("public/hades/getStoreUserPage", params); return Service.Hades("public/hades/getStoreUserPage", params);
...@@ -76,3 +77,4 @@ export function getStoreDetail(params: object) { ...@@ -76,3 +77,4 @@ export function getStoreDetail(params: object) {
} }
/* /*
* @Author: wufan * @Author: wufan
* @Date: 2020-12-01 17:20:49 * @Date: 2020-12-01 17:20:49
* @LastEditors: zhangleyuan * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-04-09 14:28:59 * @LastEditTime: 2021-06-22 14:57:01
* @Description: Description * @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import { getUserStore, getUserPermission ,logout,getStoreUser,sendBizAuthCode,editUserPhone,checkBizAuthCode,sendNewPhoneAuthCode,sendLoginAuthCode,login,getLastedVersion, getEnterpriseUser,getWXWorkLoginNoCheck} from '@/data-source/base/request-apis'; import { getUserStore, getUserPermission ,logout,getStoreUser,sendBizAuthCode,editUserPhone,checkBizAuthCode,sendNewPhoneAuthCode,sendLoginAuthCode,login,getLastedVersion, getEnterpriseUser,getWXWorkLoginNoCheck,getLesseeVersionMsg,getYoZoSign,saveYoZoFileVersionId,yoZoUpload} from '@/data-source/base/request-apis';
export default class StoreService { export default class StoreService {
// 获取员工列表 // 获取员工列表
...@@ -55,5 +55,22 @@ export default class StoreService { ...@@ -55,5 +55,22 @@ export default class StoreService {
static getWXWorkLoginNoCheck(params: any){ static getWXWorkLoginNoCheck(params: any){
return getWXWorkLoginNoCheck(params); return getWXWorkLoginNoCheck(params);
} }
static getYoZoSign(params:any){
return new Promise((resolve) => {
getYoZoSign(params).then(res => {
const { result = [] } = res;
resolve(result)
});
})
}
static saveYoZoFileVersionId(params: any){
return saveYoZoFileVersionId(params);
}
static yoZoUpload(ossUrl:String,appId:String,uploadSign:String){
return yoZoUpload(ossUrl,appId,uploadSign);
}
//获取企业配置的版本信息
static getLesseeVersionMsg() {
return getLesseeVersionMsg();
}
} }
\ No newline at end of file
/* /*
* @Author: 陈剑宇 * @Author: 陈剑宇
* @Date: 2020-05-07 14:43:01 * @Date: 2020-05-07 14:43:01
* @LastEditTime: 2021-06-11 16:44:17 * @LastEditTime: 2021-06-22 16:49:06
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @Description: * @Description:
* @FilePath: /wheat-web-demo/src/domains/basic-domain/constants.ts * @FilePath: /wheat-web-demo/src/domains/basic-domain/constants.ts
...@@ -26,6 +26,10 @@ const PATH_MAP: MapInterface = { ...@@ -26,6 +26,10 @@ const PATH_MAP: MapInterface = {
prod: 'https://res.xiaomai0.com/xiaomai-cloud-class-web/h5.html', prod: 'https://res.xiaomai0.com/xiaomai-cloud-class-web/h5.html',
} }
export const YZ_APPId = "yozoqvpO2Hvz8346";
export const YZ_PREVIEW_URL: string = 'http://eic.yozocloud.cn/api/view/file'
export const OFFICE_PREVIEW_URL: string = 'https://view.officeapps.live.com/op/view.aspx'
// axios headers config // axios headers config
export const TIME_OUT: number = 20000 export const TIME_OUT: number = 20000
export const USER_TYPE: string = 'B' export const USER_TYPE: string = 'B'
...@@ -37,3 +41,4 @@ export const USER_PREFIX = 'store-live' ...@@ -37,3 +41,4 @@ export const USER_PREFIX = 'store-live'
// host // host
export const BASIC_HOST: string = BASIC_HOST_MAP[ENV] export const BASIC_HOST: string = BASIC_HOST_MAP[ENV]
export const PATH: string = PATH_MAP[ENV] export const PATH: string = PATH_MAP[ENV]
/* /*
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-04-27 20:35:34 * @Date: 2020-04-27 20:35:34
* @LastEditors: wufan * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-03-26 16:14:09 * @LastEditTime: 2021-06-23 14:14:20
* @Description: * @Description:
*/ */
...@@ -23,8 +23,8 @@ import User from '@/common/js/user'; ...@@ -23,8 +23,8 @@ import User from '@/common/js/user';
import Service from "@/common/js/service"; import Service from "@/common/js/service";
declare var getParameterByName: any; declare var getParameterByName: any;
declare var window: any;
window.currentStoreUserInfo = {}
const history = createHashHistory(); const history = createHashHistory();
window.RCHistory = _.extend({}, history, { window.RCHistory = _.extend({}, history, {
...@@ -65,6 +65,10 @@ if (getParameterByName('code') && isWeiXin()) { ...@@ -65,6 +65,10 @@ if (getParameterByName('code') && isWeiXin()) {
User.setUserId(res.result.loginInfo.userId); User.setUserId(res.result.loginInfo.userId);
User.setToken(res.result.loginInfo.xmToken); User.setToken(res.result.loginInfo.xmToken);
User.setEnterpriseId(res.result.enterpriseId); User.setEnterpriseId(res.result.enterpriseId);
window.currentStoreUserInfo = {}
window.currentStoreUserInfo.userId = res.result.loginInfo.userId;
window.currentStoreUserInfo.token = res.result.loginInfo.xmToken;
window.currentStoreUserInfo.enterpriseId = res.result.enterpriseId;
mount() mount()
}) })
} else { } else {
......
...@@ -8,17 +8,17 @@ ...@@ -8,17 +8,17 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { withRouter } from "react-router-dom"; import { withRouter } from "react-router-dom";
import _ from "underscore"; import _ from "underscore";
import PageControl from "@/components/PageControl"; import { CheckBox, PageControl } from "@/components";
import { CheckBox } from "@/components";
import { Button, Table, Modal, message, Input } from "antd"; import { Button, Table, Modal, message, Input } from "antd";
import Service from '@/common/js/service'; import { XMTable } from '@/components';
import college from '@/common/lottie/college.json';
import StoreService from "@/domains/store-domain/storeService"; import StoreService from "@/domains/store-domain/storeService";
import EmployeeAddOrEditModal from "../store-manage/EmployeeAddOrEditModal"; import EmployeeAddOrEditModal from "../store-manage/EmployeeAddOrEditModal";
import User from "@/common/js/user"; import User from "@/common/js/user";
import LimitTip from "./LimitTip";
import "./EmployeeManage.less"; import "./EmployeeManage.less";
import ChooseMembersModal from "./modal/ChooseMembersModal"; import ChooseMembersModal from "./modal/ChooseMembersModal";
import SetEmployeeModal from "./modal/SetEmployeeModal";
const { confirm } = Modal; const { confirm } = Modal;
const { Search } = Input; const { Search } = Input;
...@@ -69,6 +69,7 @@ function EmployeeManage() { ...@@ -69,6 +69,7 @@ function EmployeeManage() {
}); });
const [total, setTotal] = useState(0); const [total, setTotal] = useState(0);
const [realTotal, setRealTotal] = useState(0)
const [model, setModel] = useState<React.ReactNode>(null); const [model, setModel] = useState<React.ReactNode>(null);
const [employeeModal, setEmployeeModal] = useState(false); const [employeeModal, setEmployeeModal] = useState(false);
const [choosedItem, setChooseItem] = useState<ChoosedItemType>({ const [choosedItem, setChooseItem] = useState<ChoosedItemType>({
...@@ -86,6 +87,17 @@ function EmployeeManage() { ...@@ -86,6 +87,17 @@ function EmployeeManage() {
if (!User.getEnterpriseId()) { if (!User.getEnterpriseId()) {
window.RCHistory.replace('/employees-manage'); window.RCHistory.replace('/employees-manage');
} }
//获取员工数
const _query = {
current: 0,
size: 10,
nickName: "",
phone: "",
roleCodes: [],
}
StoreService.getEmployeeList(_query).then((res: any) => {
setRealTotal(res.result.total);
});
}, []) }, [])
useEffect(() => { useEffect(() => {
...@@ -363,8 +375,13 @@ function EmployeeManage() { ...@@ -363,8 +375,13 @@ function EmployeeManage() {
</Button> </Button>
} }
</div> </div>
<LimitTip type="员工" total={realTotal} tip={()=>{return (<div>数据为当前学院的员工数,若员工存在多个学院,企业人数只统计为1人</div>)}}/>
<div className="box-body"> <div className="box-body">
<Table <XMTable
renderEmpty={{
image: college,
description: '暂无数据'
}}
size={"middle"} size={"middle"}
pagination={false} pagination={false}
dataSource={employeeList} dataSource={employeeList}
......
.limit-tip {
background: #E9EFFF;
border-radius: 2px;
margin-bottom: 13px;
.always {
display: inline-block;
font-size: 14px;
line-height: 32px;
font-weight: 400;
color: #666666;
margin-left: 16px;
.renew-text {
display: inline-block;
color: #2966FF;
cursor: pointer;
}
}
}
\ No newline at end of file
import React, { useContext, useEffect, useState } from "react";
import { Tooltip } from "antd"
import { VersionContext } from "@/store/context";
import ContactWidget from "@/components/ContactWidget";
import "./LimitTip.less"
export default function LimitTip(props:{total:number,type:string,tip:() => React.ReactNode}) {
const [isOver, setIsOver] = useState(false)
const [limitUser, setLimitUser] = useState("0")
const versionInfo = useContext(VersionContext)
useEffect(()=> {
if (versionInfo) {
setIsOver(versionInfo.userNum === -1 ? false : versionInfo.whetherReachUserNum)
setLimitUser(versionInfo.userNum === -1 ? "不限人数" : String(versionInfo.userNum))
}
},[versionInfo])
return (
<div className="limit-tip">
<div className="always">本学院{props.type}<span style={{color:"#333333",fontWeight:"bold"}}>{props.total}</span>
<Tooltip overlayStyle={{maxWidth:"587px",width:"fit-content"}} placement="topLeft" arrowPointAtCenter title={props.tip}>
<span className="icon iconfont" style={{cursor:"pointer",marginLeft:"4px",color:"#bfbfbf"}}>&#59449;</span>
</Tooltip>
{
isOver ? (
<>
<div style={{marginLeft:"14px",display:"inline-block"}}>当前企业使用人数已达到上限 (<span style={{color:"#333333",fontWeight:"bold"}}>{limitUser}</span>人),将无法添加新员工、新学员,如需增加人数限制,请联系小麦企学院服务平台。</div>
<ContactWidget trigger="hover" placement="bottom">
<div className="renew-text">立即续费<span className="icon iconfont" style={{fontSize:"10px"}}>&#59291;</span></div>
</ContactWidget>
</>
) : ("")
}
</div>
</div>
)
}
\ No newline at end of file
...@@ -17,4 +17,5 @@ ...@@ -17,4 +17,5 @@
margin-left: 4px; margin-left: 4px;
} }
} }
} }
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: wufan * @Author: wufan
* @Date: 2020-11-30 10:47:38 * @Date: 2020-11-30 10:47:38
* @LastEditors: wufan * @LastEditors: wufan
* @LastEditTime: 2021-05-30 15:57:40 * @LastEditTime: 2021-06-21 11:13:15
* @Description: 学员管理页面 * @Description: 学员管理页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -11,19 +11,25 @@ import React, { useEffect, useState } from "react"; ...@@ -11,19 +11,25 @@ import React, { useEffect, useState } from "react";
import { withRouter } from "react-router-dom"; import { withRouter } from "react-router-dom";
import _ from "underscore"; import _ from "underscore";
import { PageControl } from "@/components"; import { PageControl } from "@/components";
import { Table, Input, DatePicker, Select, Button, message } from "antd"; import { Input, DatePicker, Select, Button, message } from "antd";
import StoreService from "@/domains/store-domain/storeService"; import StoreService from "@/domains/store-domain/storeService";
import User from "@/common/js/user"; import User from "@/common/js/user";
import ChooseMembersModal from "./modal/ChooseMembersModal"; import ChooseMembersModal from "./modal/ChooseMembersModal";
import LimitTip from "./LimitTip"
import { XMTable } from '@/components';
import college from '@/common/lottie/college.json';
import "./UserManagePage.less"; import "./UserManagePage.less";
import moment from "moment"; import moment from "moment";
const { Option } = Select; const { Option } = Select;
const { Search } = Input; const { Search } = Input;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
declare var window: any; declare var window: any;
function UserManagePage() { function UserManagePage() {
const [userList, setUserList] = useState([]); const [userList, setUserList] = useState([]);
const [model, setModel] = useState<React.ReactNode>(null); const [model, setModel] = useState<React.ReactNode>(null);
...@@ -37,11 +43,25 @@ function UserManagePage() { ...@@ -37,11 +43,25 @@ function UserManagePage() {
sourceEnum: undefined, sourceEnum: undefined,
}); });
const [total, setTotal] = useState(0); const [total, setTotal] = useState(0);
const [realTotal, setRealTotal] = useState(0)
useEffect(() => { useEffect(() => {
if (!User.getEnterpriseId()) { if (!User.getEnterpriseId()) {
window.RCHistory.replace('/user-manage'); window.RCHistory.replace('/user-manage');
} }
//获取学员数
const _query = {
current: 0,
size: 10,
nickName: "",
phone: "",
registerBegin: null,
registerEnd: null,
sourceEnum: undefined,
}
StoreService.getUserList(_query).then((res: any) => {
setRealTotal(res.result.total);
});
}, []) }, [])
useEffect(() => { useEffect(() => {
...@@ -197,8 +217,13 @@ function UserManagePage() { ...@@ -197,8 +217,13 @@ function UserManagePage() {
}} }}
>添加学员</Button> >添加学员</Button>
} }
<LimitTip type="学员" total={realTotal} tip={()=>{ return (<div><div>1、数据为当前学院的员工数,若学员存在多个学院,企业人数只统计为1人;</div><div>2、若一个学员既用「企业微信」登录学习又用「微信」登录学习,企业人数将统计为2人。</div></div>)}}/>
<div className="box-body"> <div className="box-body">
<Table <XMTable
renderEmpty={{
image: college,
description: '暂无数据'
}}
size={"middle"} size={"middle"}
pagination={false} pagination={false}
dataSource={userList} dataSource={userList}
......
...@@ -5,8 +5,9 @@ ...@@ -5,8 +5,9 @@
*/ */
import React from 'react'; import React from 'react';
import { Modal, Input, Table, message, Tooltip, Empty } from 'antd'; import { Modal, Input, message, Tooltip } from 'antd';
import { XMTable } from '@/components'; import { XMTable } from '@/components';
import college from '@/common/lottie/college.json';
import Service from '@/common/js/service'; import Service from '@/common/js/service';
import User from '@/common/js/user' import User from '@/common/js/user'
import SetEmployeeModal from "./SetEmployeeModal"; import SetEmployeeModal from "./SetEmployeeModal";
...@@ -319,7 +320,7 @@ class ChooseMembersModal extends React.Component { ...@@ -319,7 +320,7 @@ class ChooseMembersModal extends React.Component {
pagination={false} pagination={false}
scroll={{ y: 290}} scroll={{ y: 290}}
renderEmpty={{ renderEmpty={{
image: searchKey ? search : '', image: searchKey ? search : college,
description: <div> description: <div>
<div style={{ color: '#333' }}>暂无数据</div> <div style={{ color: '#333' }}>暂无数据</div>
<div style={{ color: '#666', padding: '0 32px', fontSize: '12px' }}>需要先将员工添加到企微可见范围后,员工才会出现在这里</div> <div style={{ color: '#666', padding: '0 32px', fontSize: '12px' }}>需要先将员工添加到企微可见范围后,员工才会出现在这里</div>
...@@ -346,7 +347,11 @@ class ChooseMembersModal extends React.Component { ...@@ -346,7 +347,11 @@ class ChooseMembersModal extends React.Component {
<span className={ (selectUserList.length > 0) ? 'span-right-l' : null }>清空</span> <span className={ (selectUserList.length > 0) ? 'span-right-l' : null }>清空</span>
</div> </div>
<div className='container-right-body'> <div className='container-right-body'>
<Table <XMTable
renderEmpty={{
image: college,
description: '暂无数据'
}}
rowKey={(record) => record.enterpriseVisibleUserId} rowKey={(record) => record.enterpriseVisibleUserId}
dataSource={selectUserList} dataSource={selectUserList}
columns={this.selectedColumnsRight()} columns={this.selectedColumnsRight()}
......
...@@ -125,7 +125,9 @@ ...@@ -125,7 +125,9 @@
.ant-empty-normal { .ant-empty-normal {
margin: 120px 0 !important; margin: 120px 0 !important;
} }
.ant-empty {
margin-top: 76px;
}
.avatar{ .avatar{
display: flex; display: flex;
align-items: center; align-items: center;
......
...@@ -269,6 +269,15 @@ handleChangeBasicInfo = (field, value) => { ...@@ -269,6 +269,15 @@ handleChangeBasicInfo = (field, value) => {
// 完成创建/编辑 // 完成创建/编辑
handleSubmit = () => { handleSubmit = () => {
//过期判断
if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) {
Modal.warning({
title:"服务已到期",
content: "当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买",
okText: "我知道了"
})
return
}
const { addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo, id, isEdit, type } = this.state; const { addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo, id, isEdit, type } = this.state;
const {liveDate, timeHorizonStart} = addLiveClassInfo; const {liveDate, timeHorizonStart} = addLiveClassInfo;
const _liveDate = moment(liveDate).format("YYYY-MM-DD"); const _liveDate = moment(liveDate).format("YYYY-MM-DD");
......
...@@ -22,6 +22,13 @@ class LiveCoursePage extends React.Component { ...@@ -22,6 +22,13 @@ class LiveCoursePage extends React.Component {
componentWillMount() { componentWillMount() {
this.handleFetchLiveList(this.state.query); this.handleFetchLiveList(this.state.query);
} }
changeShelfState = (index, shelfState) => {
const { courseList } = this.state;
courseList[index].shelfState = shelfState;
this.setState({
courseList,
});
};
// 获取直播课列表 // 获取直播课列表
handleFetchLiveList = (_query) => { handleFetchLiveList = (_query) => {
const { query } = this.state; const { query } = this.state;
...@@ -54,6 +61,7 @@ class LiveCoursePage extends React.Component { ...@@ -54,6 +61,7 @@ class LiveCoursePage extends React.Component {
total={total} total={total}
courseList={courseList} courseList={courseList}
onChange={this.handleFetchLiveList} onChange={this.handleFetchLiveList}
changeShelfState={this.changeShelfState}
/> />
</div> </div>
</div> </div>
......
...@@ -7,47 +7,45 @@ ...@@ -7,47 +7,45 @@
*/ */
import React from 'react'; import React from 'react';
import { Table, Modal, message, Dropdown, Button,Switch,Tooltip} from 'antd'; import { Table, Modal, message, Dropdown, Switch, Tooltip } from 'antd';
import { Route, withRouter } from 'react-router-dom'; import { Route, withRouter } from 'react-router-dom';
import { PageControl } from "@/components"; import { PageControl } from '@/components';
import DownloadLiveModal from '@/components/DownloadLiveModal'; import DownloadLiveModal from '@/components/DownloadLiveModal';
import ManageCoursewareModal from '../modal/ManageCoursewareModal'; import ManageCoursewareModal from '../modal/ManageCoursewareModal';
import ShareLiveModal from '../modal/ShareLiveModal'; import ShareLiveModal from '../modal/ShareLiveModal';
import RelatedPlanModal from '../modal/RelatedPlanModal'; import RelatedPlanModal from '../modal/RelatedPlanModal';
import './LiveCourseList.less'; import './LiveCourseList.less';
import { QuestionCircleOutlined } from '@ant-design/icons'; import { QuestionCircleOutlined } from '@ant-design/icons';
import { appId, shareUrl, LIVE_SHARE,LIVE_REPLAY_MAP} from '@/domains/course-domain/constants'; import { appId, LIVE_SHARE } from '@/domains/course-domain/constants';
import CourseService from "@/domains/course-domain/CourseService"; import CourseService from '@/domains/course-domain/CourseService';
import BaseService from "@/domains/basic-domain/baseService"; import BaseService from '@/domains/basic-domain/baseService';
import DataList from '../DataList/DataList'; import DataList from '../DataList/DataList';
import User from '@/common/js/user'; import User from '@/common/js/user';
import _ from "underscore"; import _ from 'underscore';
const { confirm } = Modal; const { confirm } = Modal;
const courseStateShow = { const courseStateShow = {
UN_START: { UN_START: {
code: 1, code: 1,
title: "待开课", title: '待开课',
color: "#FFB129", color: '#FFB129',
}, },
STARTING: { STARTING: {
code: 2, code: 2,
title: "上课中", title: '上课中',
color: "#238FFF", color: '#238FFF',
}, },
FINISH: { FINISH: {
code: 3, code: 3,
title: "已完成", title: '已完成',
color: "#3BBDAA", color: '#3BBDAA',
}, },
EXPIRED: { EXPIRED: {
code: 4, code: 4,
title: "未成功开课", title: '未成功开课',
color: "#999", color: '#999',
}, },
}; };
class LiveCourseList extends React.Component { class LiveCourseList extends React.Component {
...@@ -55,18 +53,17 @@ class LiveCourseList extends React.Component { ...@@ -55,18 +53,17 @@ class LiveCourseList extends React.Component {
super(props); super(props);
this.state = { this.state = {
columns: [], columns: [],
openDownloadModal:false, openDownloadModal: false,
url:'', url: '',
RelatedPlanModalVisible:false, RelatedPlanModalVisible: false,
selectPlanList:{} selectPlanList: {},
} };
} }
componentWillMount(){ componentWillMount() {
this.parseColumns(); this.parseColumns();
} }
componentDidMount() { componentDidMount() {
this.getDownloadVersion() this.getDownloadVersion();
} }
// 显示分享弹窗 // 显示分享弹窗
handleShowShareModal = (item, needStr = false) => { handleShowShareModal = (item, needStr = false) => {
...@@ -74,555 +71,597 @@ class LiveCourseList extends React.Component { ...@@ -74,555 +71,597 @@ class LiveCourseList extends React.Component {
const { liveCourseId } = item; const { liveCourseId } = item;
const htmlUrl = `${LIVE_SHARE}live_detail/${liveCourseId}?id=${User.getStoreId()}`; const htmlUrl = `${LIVE_SHARE}live_detail/${liveCourseId}?id=${User.getStoreId()}`;
const longUrl = htmlUrl const longUrl = htmlUrl;
console.log('htmlUrl',htmlUrl,longUrl); console.log('htmlUrl', htmlUrl, longUrl);
const shareData = { ...item, longUrl }; const shareData = { ...item, longUrl };
const shareLiveModal = ( const shareLiveModal = (
<ShareLiveModal <ShareLiveModal
needStr={needStr} needStr={needStr}
data={shareData} data={shareData}
type="liveClass" type='liveClass'
title="直播课" title='直播课'
close={() => { close={() => {
this.setState({ this.setState({
shareLiveModal: null shareLiveModal: null,
}); });
localStorage.setItem('largeLiveCourseItem', ''); localStorage.setItem('largeLiveCourseItem', '');
}} }}
/> />
) );
this.setState({ shareLiveModal }) this.setState({ shareLiveModal });
} };
//改变上架状态 //改变上架状态
changeShelfState = (item) =>{ changeShelfState = (index,item,checked) => {
let _shelfState = item.shelfState let _shelfState = checked ? "YES" : "NO"
if(_shelfState==='NO'){ // if (_shelfState === 'NO') {
_shelfState = "YES"; // _shelfState = 'YES';
item.shelfState = "YES" // } else {
}else{ // _shelfState = 'NO';
_shelfState = "NO" // }
item.shelfState = "NO" const params = {
} liveCourseId: item.liveCourseId,
const params={ shelfState: _shelfState,
"liveCourseId": item.liveCourseId, };
"shelfState":_shelfState CourseService.turnOnOrOffLiveCloudCourse(params).then((res) => {
} if (res.success) {
CourseService.turnOnOrOffLiveCloudCourse(params).then((res)=>{ if (_shelfState === 'YES') {
if(res.success){ message.success('已开启展示');
if(_shelfState === "YES"){ } else {
message.success("已开启展示"); message.success('已取消展示');
}else{
message.success("已取消展示");
}
} }
}) this.props.changeShelfState(index,_shelfState)
} }
});
};
// 前往上课数据页面 // 前往上课数据页面
handleLinkToClassData = (item) => { handleLinkToClassData = (item) => {
const { match } = this.props; const { match } = this.props;
window.RCHistory.push({ window.RCHistory.push({
pathname: `${match.url}/live-course-data?type=large&id=${item.liveCourseId}` pathname: `${match.url}/live-course-data?type=large&id=${item.liveCourseId}`,
}); });
} };
parseColumns = () => { parseColumns = () => {
const menu = (item) => ( const menu = (item) => (
<div className="live-course-more-menu"> <div className='live-course-more-menu'>
<div> <div>上课记录</div>
上课记录
</div>
<div <div
onClick={() => { onClick={() => {
this.handleShowRepeatModal(item); this.handleShowRepeatModal(item);
}} }}>
>
回放记录 回放记录
</div> </div>
</div> </div>
); );
let columns let columns;
const userRole = User.getUserRole(); const userRole = User.getUserRole();
if(userRole !=="CloudLecturer"){ if (userRole !== 'CloudLecturer') {
columns = [ columns = [
{ {
title: "直播课", title: '直播课',
width: "23%", width: '23%',
key: "course", key: 'course',
dataIndex: "courseName", dataIndex: 'courseName',
render: (val, record) => { render: (val, record) => {
let hasCover = false; let hasCover = false;
return ( return (
<div className="record__item"> <div className='record__item'>
{ {record.courseMediaVOS.map((item, index) => {
record.courseMediaVOS.map((item,index)=>{ if (item.contentType === 'COVER') {
if( item.contentType === "COVER"){
hasCover = true; hasCover = true;
return <img className="course-cover" src={item.mediaUrl} /> return <img className='course-cover' src={item.mediaUrl} />;
}
})
}
{ !hasCover &&
<img className="course-cover" src={'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'} />
} }
})}
{!hasCover && <img className='course-cover' src={'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'} />}
<div> <div>
{ record.courseName.length > 17? {record.courseName.length > 17 ? (
<Tooltip title={record.courseName}> <Tooltip title={record.courseName}>
<div className="course-name">{record.courseName}</div> <div className='course-name'>{record.courseName}</div>
</Tooltip> </Tooltip>
: ) : (
<div className="course-name">{record.courseName}</div> <div className='course-name'>{record.courseName}</div>
} )}
<div> <div>
<span className="course-time">{formatDate("YYYY-MM-DD H:i",parseInt(record.startTime))}~{formatDate("H:i", parseInt(record.endTime))}</span> <span className='course-time'>
<span className="course-status" style={{color:courseStateShow[record.courseState].color,border:`1px solid ${courseStateShow[record.courseState].color}`}}>{courseStateShow[record.courseState].title}</span> {formatDate('YYYY-MM-DD H:i', parseInt(record.startTime))}~{formatDate('H:i', parseInt(record.endTime))}
</span>
<span
className='course-status'
style={{ color: courseStateShow[record.courseState].color, border: `1px solid ${courseStateShow[record.courseState].color}` }}>
{courseStateShow[record.courseState].title}
</span>
</div> </div>
<div className="teacher-assistant"> <div className='teacher-assistant'>
{ record.teacherName.length > 4 ? {record.teacherName?.length > 4 ? (
<Tooltip title={record.teacherName}> <Tooltip title={record.teacherName}>
<span className="teacher">讲师:{record.teacherName}</span> <span className='teacher'>讲师:{record.teacherName}</span>
</Tooltip> </Tooltip>
: ) : (
<span className="teacher">讲师:{record.teacherName}</span> <span className='teacher'>讲师:{record.teacherName}</span>
} )}
{ record.admins.length >0 && {record.admins.length > 0 && (
<> <>
<span className="split"> | </span> <span className='split'> | </span>
{ this.handleAdminName(record.admins).length > 4? {this.handleAdminName(record.admins).length > 4 ? (
<Tooltip title={this.handleAdminName(record.admins)}> <Tooltip title={this.handleAdminName(record.admins)}>
<span className="assistant">助教: <span className='assistant'>
{ record.admins.map((item,index)=>{ 助教:
return <span>{item.adminName} { (index < record.admins.length-1)&&(<span></span>)} </span> {record.admins.map((item, index) => {
}) return (
} <span>
{item.adminName} {index < record.admins.length - 1 && <span></span>}{' '}
</span>
);
})}
</span> </span>
</Tooltip> </Tooltip>
: ) : (
<span className="assistant">助教: <span className='assistant'>
{ record.admins.map((item,index)=>{ 助教:
return <span>{item.adminName} { (index < record.admins.length-1)&&(<span></span>)} </span> {record.admins.map((item, index) => {
}) return (
} <span>
{item.adminName} {index < record.admins.length - 1 && <span></span>}{' '}
</span> </span>
} );
})}
</span>
)}
</> </>
} )}
</div> </div>
</div> </div>
</div> </div>
) );
} },
}, },
{ {
title: "课程分类", title: '课程分类',
width: "10%", width: '10%',
key: "couseCatalog", key: 'couseCatalog',
dataIndex: "couseCatalog", dataIndex: 'couseCatalog',
render: (val, item) => { render: (val, item) => {
return ( return <div className='categoryName'>{item.categoryName}</div>;
<div className="categoryName">{item.categoryName}</div>
)
}, },
}, },
{ {
title: "课件管理", title: '课件管理',
width: "8%", width: '8%',
key: "courseware", key: 'courseware',
dataIndex: "courseware", dataIndex: 'courseware',
render: (val, item) => { render: (val, item) => {
return ( return (
<span className="courseware" <span
className='courseware'
onClick={() => { onClick={() => {
this.setState({ this.setState({
editData: item, editData: item,
openCoursewareModal: true, openCoursewareModal: true,
}); });
}}>{item.courseDocumentCount}</span> }}>
{item.courseDocumentCount}
</span>
); );
}, },
}, },
{ {
title: '上课数据', title: '上课数据',
width: "9%", width: '9%',
key: "quota", key: 'quota',
dataIndex: "quota", dataIndex: 'quota',
render: (val, item) => { render: (val, item) => {
return ( return (
<span className="iconfont icon quota-icon" onClick={() => { <span
this.handleLinkToClassData(item) className='iconfont icon quota-icon'
}}>&#xe7d6;</span> onClick={() => {
this.handleLinkToClassData(item);
}}>
&#xe7d6;
</span>
); );
}, },
}, },
{ {
title: <span> title: (
<span>
<span>学院展示</span> <span>学院展示</span>
<Tooltip title={<div>开启后,学员可在学院内查看到此课程。若课程“未成功开课”,则系统会自动“关闭”学院展示。<br/>关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。</div>}><i className="icon iconfont" style={{ marginLeft: '5px',cursor:'pointer',color:'#bfbfbf',fontSize:'14px',fontWeight:'normal'}}>&#xe61d;</i></Tooltip> <Tooltip
</span>, title={
width: "9%", <div>
key: "shelfState", 开启后,学员可在学院内查看到此课程。若课程“未成功开课”,则系统会自动“关闭”学院展示。
dataIndex: "shelfState", <br />
关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。
</div>
}>
<i className='icon iconfont' style={{ marginLeft: '5px', cursor: 'pointer', color: '#bfbfbf', fontSize: '14px', fontWeight: 'normal' }}>
&#xe61d;
</i>
</Tooltip>
</span>
),
width: '9%',
key: 'shelfState',
dataIndex: 'shelfState',
render: (val, item, index) => { render: (val, item, index) => {
return ( return <Switch
<Switch defaultChecked={item.shelfState==="YES"?true:false} onChange={()=>this.changeShelfState(item)}/> checked={item.shelfState === "YES"}
) defaultChecked={item.shelfState === 'YES' ? true : false}
onChange={(checked) => this.changeShelfState(index,item,checked)} />;
}, },
}, },
{ {
title: '创建时间', title: '创建时间',
width: "9%", width: '9%',
key: "created", key: 'created',
dataIndex: "created", dataIndex: 'created',
sorter: true, sorter: true,
render: (val, item) => { render: (val, item) => {
return ( return <span>{val === -29000 ? '-' : formatDate('YYYY-MM-DD H:i', val)}</span>;
<span>{formatDate('YYYY-MM-DD H:i', val)}</span>
);
}, },
}, },
{ {
title: '关联项', title: '关联项',
width: "15%", width: '15%',
key: "planList", key: 'planList',
dataIndex: "planList", dataIndex: 'planList',
render: (val, record) => { render: (val, record) => {
return ( return (
<div className="related-task"> <div className='related-task'>
{ record.relatedPlanList ? {record.relatedPlanList ? (
<Tooltip title={this.handlePlanName(record.relatedPlanList)} placement="top" arrowPointAtCenter> <Tooltip title={this.handlePlanName(record.relatedPlanList)} placement='top' arrowPointAtCenter>
{ record.relatedPlanList.map((item,index)=>{ {record.relatedPlanList.map((item, index) => {
return <span>{item.planName} { (index < record.relatedPlanList.length-1)&&(<span></span>)} </span> return (
}) <span>
} {item.planName} {index < record.relatedPlanList.length - 1 && <span></span>}{' '}
</span>
);
})}
</Tooltip> </Tooltip>
: ) : (
<span></span> <span></span>
} )}
</div> </div>
) );
}, },
}, },
{ {
title: "操作", title: '操作',
width: "15%", width: '15%',
key: "operate", key: 'operate',
dataIndex: "operate", dataIndex: 'operate',
render: (val, item) => { render: (val, item) => {
return ( return (
<div className='operate'>
<div className="operate"> {(item.courseState === 'UN_START' || item.courseState === 'STARTING') &&
{ ((item.courseState==="UN_START" || item.courseState==="STARTING") && (item.teacherId === User.getUserId() || _.pluck(item.admins, "adminId").includes(User.getUserId()))) && (item.teacherId === User.getUserId() || _.pluck(item.admins, 'adminId').includes(User.getUserId())) && (
<> <>
<div <div
key="enter_live_room1" key='enter_live_room1'
className="operate__item" className='operate__item'
onClick={() => { this.handleEnterLiveRoom(item) }} onClick={() => {
>进入直播间 this.handleEnterLiveRoom(item);
}}>
进入直播间
</div> </div>
<span className="operate__item split" key="view_play_back_split"> | </span> <span className='operate__item split' key='view_play_back_split'>
{' '}
|{' '}
</span>
</> </>
} )}
{ (item.courseState==="FINISH" && item.haveRecord==="YES") && {item.courseState === 'FINISH' && item.haveRecord === 'YES' && (
<> <>
<div <div
key="view_play_back" key='view_play_back'
className="operate__item" className='operate__item'
onClick={()=>{this.handleViewPlayBack(item)}} onClick={() => {
>查看回放</div> this.handleViewPlayBack(item);
<span className="operate__item split" key="view_play_back_split"> | </span> }}>
查看回放
</div>
<span className='operate__item split' key='view_play_back_split'>
{' '}
|{' '}
</span>
</> </>
)}
} {item.courseState !== 'EXPIRED' && (
{ item.courseState!=="EXPIRED" &&
<> <>
<div <div
key="share" key='share'
className="operate__item" className='operate__item'
onClick={() => { this.handleShowShareModal(item); }} onClick={() => {
> this.handleShowShareModal(item);
}}>
分享 分享
</div> </div>
</> </>
} )}
{ item.courseState!=="EXPIRED" && {item.courseState !== 'EXPIRED' && (
<> <>
<span key="split1" className="operate__item split"> | </span> <span key='split1' className='operate__item split'>
<div className="big-live"> {' '}
|{' '}
</span>
<div className='big-live'>
<Dropdown overlay={this.renderMoreOperate(item)}> <Dropdown overlay={this.renderMoreOperate(item)}>
<span className="more-operate"> <span className='more-operate'>
<span className="operate-text">更多</span> <span className='operate-text'>更多</span>
<span <span className='iconfont icon' style={{ color: '#2966FF' }}>
className="iconfont icon"
style={{ color: "#2966FF" }}
>
&#xe824; &#xe824;
</span> </span>
</span> </span>
</Dropdown> </Dropdown>
</div> </div>
</> </>
} )}
{ item.courseState==="EXPIRED" && {item.courseState === 'EXPIRED' && (
<div <div className='operate__item' onClick={() => this.handleDelete(item)}>
className="operate__item" 删除
onClick={()=>this.handleDelete(item)}
>删除</div>
}
</div> </div>
) )}
} </div>
} );
},
},
]; ];
}else{ } else {
columns = [ columns = [
{ {
title: "直播课", title: '直播课',
width: "25%", width: '25%',
key: "course", key: 'course',
dataIndex: "courseName", dataIndex: 'courseName',
render: (val, record) => { render: (val, record) => {
let hasCover = false; let hasCover = false;
return ( return (
<div className="record__item"> <div className='record__item'>
{ {record.courseMediaVOS.map((item, index) => {
record.courseMediaVOS.map((item,index)=>{ if (item.contentType === 'COVER') {
if( item.contentType === "COVER"){
hasCover = true; hasCover = true;
return <img className="course-cover" src={item.mediaUrl} /> return <img className='course-cover' src={item.mediaUrl} />;
}
})
}
{ !hasCover &&
<img className="course-cover" src={'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'} />
} }
})}
{!hasCover && <img className='course-cover' src={'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'} />}
<div> <div>
{ record.courseName.length > 17? {record.courseName.length > 17 ? (
<Tooltip title={record.courseName}> <Tooltip title={record.courseName}>
<div className="course-name">{record.courseName}</div> <div className='course-name'>{record.courseName}</div>
</Tooltip> </Tooltip>
: ) : (
<div className="course-name">{record.courseName}</div> <div className='course-name'>{record.courseName}</div>
} )}
<div> <div>
<span className="course-time">{formatDate("YYYY-MM-DD H:i",parseInt(record.startTime))}~{formatDate("H:i", parseInt(record.endTime))}</span> <span className='course-time'>
<span className="course-status" style={{color:courseStateShow[record.courseState].color,border:`1px solid ${courseStateShow[record.courseState].color}`}}>{courseStateShow[record.courseState].title}</span> {formatDate('YYYY-MM-DD H:i', parseInt(record.startTime))}~{formatDate('H:i', parseInt(record.endTime))}
</span>
<span
className='course-status'
style={{ color: courseStateShow[record.courseState].color, border: `1px solid ${courseStateShow[record.courseState].color}` }}>
{courseStateShow[record.courseState].title}
</span>
</div> </div>
<div className="teacher-assistant"> <div className='teacher-assistant'>
{ record.teacherName.length > 4 ? {record.teacherName.length > 4 ? (
<Tooltip title={record.teacherName}> <Tooltip title={record.teacherName}>
<span className="teacher">讲师:{record.teacherName}</span> <span className='teacher'>讲师:{record.teacherName}</span>
</Tooltip> </Tooltip>
: ) : (
<span className="teacher">讲师:{record.teacherName}</span> <span className='teacher'>讲师:{record.teacherName}</span>
} )}
{ record.admins.length >0 && {record.admins.length > 0 && (
<> <>
<span className="split"> | </span> <span className='split'> | </span>
{ this.handleAdminName(record.admins).length > 4? {this.handleAdminName(record.admins).length > 4 ? (
<Tooltip title={this.handleAdminName(record.admins)}> <Tooltip title={this.handleAdminName(record.admins)}>
<span className="assistant">助教: <span className='assistant'>
{ record.admins.map((item,index)=>{ 助教:
return <span>{item.adminName} { (index < record.admins.length-1)&&(<span></span>)} </span> {record.admins.map((item, index) => {
}) return (
} <span>
{item.adminName} {index < record.admins.length - 1 && <span></span>}{' '}
</span>
);
})}
</span> </span>
</Tooltip> </Tooltip>
: ) : (
<span className="assistant">助教: <span className='assistant'>
{ record.admins.map((item,index)=>{ 助教:
return <span>{item.adminName} { (index < record.admins.length-1)&&(<span></span>)} </span> {record.admins.map((item, index) => {
}) return (
} <span>
{item.adminName} {index < record.admins.length - 1 && <span></span>}{' '}
</span> </span>
} );
})}
</span>
)}
</> </>
} )}
</div> </div>
</div> </div>
</div> </div>
) );
} },
}, },
{ {
title: "课程分类", title: '课程分类',
width: "10%", width: '10%',
key: "couseCatalog", key: 'couseCatalog',
dataIndex: "couseCatalog", dataIndex: 'couseCatalog',
render: (val, item) => { render: (val, item) => {
return ( return <div className='categoryName'>{item.categoryName}</div>;
<div className="categoryName">{item.categoryName}</div>
)
}, },
}, },
{ {
title: "课件管理", title: '课件管理',
width: "8%", width: '8%',
key: "courseware", key: 'courseware',
dataIndex: "courseware", dataIndex: 'courseware',
render: (val, item) => { render: (val, item) => {
return ( return (
<span className="courseware" <span
className='courseware'
onClick={() => { onClick={() => {
this.setState({ this.setState({
editData: item, editData: item,
openCoursewareModal: true, openCoursewareModal: true,
}); });
}}>{item.courseDocumentCount}</span> }}>
{item.courseDocumentCount}
</span>
); );
}, },
}, },
{ {
title: '上课数据', title: '上课数据',
width: "9%", width: '9%',
key: "quota", key: 'quota',
dataIndex: "quota", dataIndex: 'quota',
render: (val, item) => { render: (val, item) => {
return ( return (
<span className="iconfont icon quota-icon" onClick={() => { <span
this.handleLinkToClassData(item) className='iconfont icon quota-icon'
}}>&#xe7d6;</span> onClick={() => {
this.handleLinkToClassData(item);
}}>
&#xe7d6;
</span>
); );
}, },
}, },
{ {
title: '创建时间', title: '创建时间',
width: "9%", width: '9%',
key: "created", key: 'created',
dataIndex: "created", dataIndex: 'created',
sorter: true, sorter: true,
render: (val, item) => { render: (val, item) => {
return ( return <span>{formatDate('YYYY-MM-DD H:i', val)}</span>;
<span>{formatDate('YYYY-MM-DD H:i', val)}</span>
);
}, },
}, },
{ {
title: '关联项', title: '关联项',
width: "15%", width: '15%',
key: "planList", key: 'planList',
dataIndex: "planList", dataIndex: 'planList',
render: (val, record) => { render: (val, record) => {
return ( return (
<div className="related-task"> <div className='related-task'>
{ record.relatedPlanList ? {record.relatedPlanList ? (
<Tooltip title={this.handlePlanName(record.relatedPlanList)} placement="top" arrowPointAtCenter> <Tooltip title={this.handlePlanName(record.relatedPlanList)} placement='top' arrowPointAtCenter>
{ record.relatedPlanList.map((item,index)=>{ {record.relatedPlanList.map((item, index) => {
return <span>{item.planName} { (index < record.relatedPlanList.length-1)&&(<span></span>)} </span> return (
}) <span>
} {item.planName} {index < record.relatedPlanList.length - 1 && <span></span>}{' '}
</span>
);
})}
</Tooltip> </Tooltip>
: ) : (
<span></span> <span></span>
} )}
</div> </div>
) );
}, },
}, },
]; ];
} }
this.setState({ columns }) this.setState({ columns });
} };
handleAdminName = (adminArray)=>{ handleAdminName = (adminArray) => {
let adminStr = ""; let adminStr = '';
adminArray.map((item,index)=>{ adminArray.map((item, index) => {
if(index < adminArray.length-1){ if (index < adminArray.length - 1) {
adminStr = adminStr + item.adminName + '、'; adminStr = adminStr + item.adminName + '、';
}else{ } else {
adminStr = adminStr + item.adminName adminStr = adminStr + item.adminName;
}
})
return adminStr
} }
});
return adminStr;
};
handlePlanName = (planArray)=>{ handlePlanName = (planArray) => {
let planStr = ""; let planStr = '';
planArray.map((item,index)=>{ planArray.map((item, index) => {
if(index < planArray.length-1){ if (index < planArray.length - 1) {
planStr = planStr + item.planName + '、'; planStr = planStr + item.planName + '、';
}else{ } else {
planStr = planStr + item.planName planStr = planStr + item.planName;
}
})
return planStr
} }
});
return planStr;
};
renderMoreOperate = (item) => { renderMoreOperate = (item) => {
return ( return (
<div className="live-course-more-menu"> <div className='live-course-more-menu'>
{ (User.getUserRole() === "CloudManager" || User.getUserRole() === "StoreManager") && {(User.getUserRole() === 'CloudManager' || User.getUserRole() === 'StoreManager') && (
<div <div className='operate__item' onClick={() => this.handleRelatedModalShow(item)}>
className="operate__item" 关联培训计划
onClick={()=>this.handleRelatedModalShow(item)}
>关联培训计划</div>
}
<div
className="operate__item"
onClick={()=>this.toEditCoursePage(item)}
>编辑</div>
{ item.courseState !=="STARTING" &&
<div
className="operate__item"
onClick={()=>this.handleDelete(item)}
>删除</div>
}
</div> </div>
) )}
} <div className='operate__item' onClick={() => this.toEditCoursePage(item)}>
handleDelete = (record)=>{ 编辑
</div>
{item.courseState !== 'STARTING' && (
<div className='operate__item' onClick={() => this.handleDelete(item)}>
删除
</div>
)}
</div>
);
};
handleDelete = (record) => {
return confirm({ return confirm({
title: '你确定要删除直播课?', title: '你确定要删除直播课?',
content: '删除后,学员将不能观看直播课/回放', content: '删除后,学员将不能观看直播课/回放',
icon: <span className="icon iconfont default-confirm-icon">&#xe839; </span>, icon: <span className='icon iconfont default-confirm-icon'>&#xe839; </span>,
okText: '删除', okText: '删除',
okType: 'danger', okType: 'danger',
cancelText: '取消', cancelText: '取消',
width:440, width: 440,
height:188, height: 188,
onOk: () => { onOk: () => {
this.deleteConfirm(record); this.deleteConfirm(record);
} },
}) });
} };
deleteConfirm = (item)=>{ deleteConfirm = (item) => {
const params={ const params = {
"liveCourseId": item.liveCourseId, liveCourseId: item.liveCourseId,
} };
CourseService.delLiveCloudCourse(params).then((res)=>{ CourseService.delLiveCloudCourse(params).then((res) => {
if(res.success){ if (res.success) {
message.success("已删除"); message.success('已删除');
this.props.onChange(); this.props.onChange();
} }
}) });
} };
toEditCoursePage =(item)=>{ toEditCoursePage = (item) => {
window.RCHistory.push({ window.RCHistory.push({
pathname: `/create-live-course?type=edit&id=${item.liveCourseId}`, pathname: `/create-live-course?type=edit&id=${item.liveCourseId}`,
}) });
} };
refreshCourseList = ()=>{ refreshCourseList = () => {
this.props.onChange(this.props.query); this.props.onChange(this.props.query);
} };
//进入直播间 //进入直播间
handleEnterLiveRoom = (item) => { handleEnterLiveRoom = (item) => {
if (item.startTime - Date.now() > 1800000) { if (item.startTime - Date.now() > 1800000) {
Modal.warning({ Modal.warning({
title: "你来得太早了", title: '你来得太早了',
okText: '我知道了', okText: '我知道了',
content: "请于开始上课前30分钟来直播上课。", content: '请于开始上课前30分钟来直播上课。',
icon: ( icon: (
<span <span className='icon iconfont default-confirm-icon' style={{ color: '#FFBB54 !important' }}>
className="icon iconfont default-confirm-icon"
style={{ color: "#FFBB54 !important" }}
>
&#xe834; &#xe834;
</span> </span>
), ),
...@@ -630,127 +669,126 @@ class LiveCourseList extends React.Component { ...@@ -630,127 +669,126 @@ class LiveCourseList extends React.Component {
} else { } else {
CourseService.getLiveCloudCourseDetail({ CourseService.getLiveCloudCourseDetail({
liveCourseId: item.liveCourseId, liveCourseId: item.liveCourseId,
}) }).then((res) => {
.then((res) => {
const url = `xmqx://liveCourseId=${item.liveCourseId}`; const url = `xmqx://liveCourseId=${item.liveCourseId}`;
if (res.result.courseState === "FINISH") { if (res.result.courseState === 'FINISH') {
Modal.warning({ Modal.warning({
title: "刷新页面", title: '刷新页面',
icon: <QuestionCircleOutlined />, icon: <QuestionCircleOutlined />,
content: "课次已结束,请刷新一下", content: '课次已结束,请刷新一下',
onOk: () => { onOk: () => {
this.refreshCourseList(); this.refreshCourseList();
} },
}); });
} else { } else {
this.setState({ url, openDownloadModal: true }); this.setState({ url, openDownloadModal: true });
} }
}); });
} }
} };
onShowSizeChange = (current, size) => { onShowSizeChange = (current, size) => {
if (current == size) { if (current == size) {
return return;
} }
let _query = this.props.query let _query = this.props.query;
_query.size = size; _query.size = size;
this.props.onChange(_query) this.props.onChange(_query);
} };
getDownloadVersion() { getDownloadVersion() {
const isMac = /macintosh|mac os x/i.test(navigator.userAgent); const isMac = /macintosh|mac os x/i.test(navigator.userAgent);
// 判断学员系统 // 判断学员系统
let platform; let platform;
if(!isMac){ if (!isMac) {
platform = 1 platform = 1;
}else{ } else {
platform = 4 platform = 4;
} }
BaseService BaseService.getLastedVersion({ model: 5, platform }).then((res) => {
.getLastedVersion({ model: 5, platform})
.then((res) => {
const { result = {} } = res; const { result = {} } = res;
this.setState({ downloadUrl: result.releaseUrl }); this.setState({ downloadUrl: result.releaseUrl });
}) });
} }
handleViewPlayBack = (item) => { handleViewPlayBack = (item) => {
let htmlUrl; let htmlUrl;
if(item.teacherId === User.getUserId()){ if (item.teacherId === User.getUserId()) {
htmlUrl = `${LIVE_SHARE}replay/${item.liveCourseId}?teacherId=${User.getUserId()}&id=${User.getStoreId()}`; htmlUrl = `${LIVE_SHARE}replay/${item.liveCourseId}?teacherId=${User.getUserId()}&id=${User.getStoreId()}`;
}else if(_.pluck(item.admins, "adminId").includes(User.getUserId())){ } else if (_.pluck(item.admins, 'adminId').includes(User.getUserId())) {
htmlUrl = `${LIVE_SHARE}replay/${item.liveCourseId}?userId=${User.getUserId()}&id=${User.getStoreId()}`; htmlUrl = `${LIVE_SHARE}replay/${item.liveCourseId}?userId=${User.getUserId()}&id=${User.getStoreId()}`;
}else{ } else {
htmlUrl = `${LIVE_SHARE}replay/${item.liveCourseId}?id=${User.getStoreId()}`; htmlUrl = `${LIVE_SHARE}replay/${item.liveCourseId}?id=${User.getStoreId()}`;
} }
window.open(htmlUrl); window.open(htmlUrl);
} };
handleRelatedModalShow = (item)=>{ handleRelatedModalShow = (item) => {
const selectPlanList = {}; const selectPlanList = {};
if(item.relatedPlanList){ if (item.relatedPlanList) {
item.relatedPlanList.map((item,index)=>{ item.relatedPlanList.map((item, index) => {
selectPlanList[item.planId] = {} selectPlanList[item.planId] = {};
selectPlanList[item.planId].planId = item.planId; selectPlanList[item.planId].planId = item.planId;
selectPlanList[item.planId].taskBaseVOList = [{taskId:item.taskId}]; selectPlanList[item.planId].taskBaseVOList = [{ taskId: item.taskId }];
return item return item;
}) });
} }
this.setState({ this.setState({
RelatedPlanModalVisible:true, RelatedPlanModalVisible: true,
selectCourseId:item.liveCourseId, selectCourseId: item.liveCourseId,
selectPlanList:selectPlanList selectPlanList: selectPlanList,
}) });
} };
closeRelatedPlanModalVisible = ()=>{ closeRelatedPlanModalVisible = () => {
this.setState({
RelatedPlanModalVisible:false
})
}
onChangeSelectPlanList = (selectPlanList)=>{
this.setState({ this.setState({
selectPlanList:selectPlanList RelatedPlanModalVisible: false,
}) });
} };
onConfirmSelectPlanList = ()=>{ onChangeSelectPlanList = (selectPlanList) => {
this.setState({ this.setState({
RelatedPlanModalVisible:false selectPlanList: selectPlanList,
},()=>{this.props.onChange();}) });
};
onConfirmSelectPlanList = () => {
this.setState(
{
RelatedPlanModalVisible: false,
},
() => {
this.props.onChange();
} }
);
};
handleChangeTable = (pagination, filters, sorter) => { handleChangeTable = (pagination, filters, sorter) => {
const { columnKey, order } = sorter; const { columnKey, order } = sorter;
const { query } = this.props; const { query } = this.props;
let _columnKey; let _columnKey;
let _order; let _order;
// 按创建时间升序排序 // 按创建时间升序排序
if (columnKey === 'created' && order === 'ascend') {_columnKey="CREATED"; _order = 'SORT_ASC'; } if (columnKey === 'created' && order === 'ascend') {
_columnKey = 'CREATED';
_order = 'SORT_ASC';
}
// 按创建时间降序排序 // 按创建时间降序排序
if (columnKey === 'created' && order === 'descend') { _columnKey="CREATED"; _order = 'SORT_DESC';} if (columnKey === 'created' && order === 'descend') {
_columnKey = 'CREATED';
_order = 'SORT_DESC';
}
const _query = { const _query = {
...query, ...query,
sortMap:{} sortMap: {},
}; };
_query.sortMap[_columnKey]=_order; _query.sortMap[_columnKey] = _order;
this.props.onChange(_query); this.props.onChange(_query);
} };
render() { render() {
const { total, query, courseList, loading} = this.props; const { total, query, courseList, loading } = this.props;
const { current, size } = query; const { current, size } = query;
const { openDownloadModal, const { openDownloadModal, downloadUrl, url, columns, openCoursewareModal, editData, RelatedPlanModalVisible, selectCourseId, selectPlanList } = this.state;
downloadUrl, url, columns,
openCoursewareModal,
editData,
RelatedPlanModalVisible,
selectCourseId,
selectPlanList
} = this.state;
const { match } = this.props; const { match } = this.props;
return ( return (
<div className="live-course-list"> <div className='live-course-list'>
<Table <Table
bordered bordered
size="middle" size='middle'
pagination={false} pagination={false}
columns={columns} columns={columns}
loading={loading} loading={loading}
...@@ -758,21 +796,21 @@ class LiveCourseList extends React.Component { ...@@ -758,21 +796,21 @@ class LiveCourseList extends React.Component {
onChange={this.handleChangeTable} onChange={this.handleChangeTable}
rowKey={(row) => row.liveCourseId} rowKey={(row) => row.liveCourseId}
/> />
{ total>0 && {total > 0 && (
<div className="box-footer"> <div className='box-footer'>
<PageControl <PageControl
current={current - 1} current={current - 1}
pageSize={size} pageSize={size}
total={parseInt(total)} total={parseInt(total)}
toPage={(page) => { toPage={(page) => {
const _query = {...query, current: page + 1}; const _query = { ...query, current: page + 1 };
this.props.onChange(_query) this.props.onChange(_query);
}} }}
onShowSizeChange={this.onShowSizeChange} onShowSizeChange={this.onShowSizeChange}
/> />
</div> </div>
} )}
{ this.state.shareLiveModal } {this.state.shareLiveModal}
{openCoursewareModal && ( {openCoursewareModal && (
<ManageCoursewareModal <ManageCoursewareModal
data={editData} data={editData}
...@@ -789,12 +827,12 @@ class LiveCourseList extends React.Component { ...@@ -789,12 +827,12 @@ class LiveCourseList extends React.Component {
onCancel={() => { onCancel={() => {
this.setState({ this.setState({
url: '', url: '',
openDownloadModal: openDownloadModal: false,
false }); });
}} }}
/> />
)} )}
{ RelatedPlanModalVisible && {RelatedPlanModalVisible && (
<RelatedPlanModal <RelatedPlanModal
onClose={this.closeRelatedPlanModalVisible} onClose={this.closeRelatedPlanModalVisible}
visible={RelatedPlanModalVisible} visible={RelatedPlanModalVisible}
...@@ -803,11 +841,11 @@ class LiveCourseList extends React.Component { ...@@ -803,11 +841,11 @@ class LiveCourseList extends React.Component {
onChange={this.onChangeSelectPlanList} onChange={this.onChangeSelectPlanList}
onConfirm={this.onConfirmSelectPlanList} onConfirm={this.onConfirmSelectPlanList}
/> />
} )}
<iframe src={url} style={{ display: "none" }} /> <iframe src={url} style={{ display: 'none' }} />
<Route path={`${match.url}/live-course-data`} component={DataList} /> <Route path={`${match.url}/live-course-data`} component={DataList} />
</div> </div>
) );
} }
} }
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
import React from 'react'; import React from 'react';
import { Button, Input, Radio, message, Modal, Cascader } from 'antd'; import { Button, Input, Radio, message, Modal, Cascader } from 'antd';
import $ from 'jquery'; import $ from 'jquery';
import moment from 'moment';
import { DISK_MAP, FileTypeIcon, FileVerifyMap } from '@/common/constants/academic/lessonEnum'; import { DISK_MAP, FileTypeIcon, FileVerifyMap } from '@/common/constants/academic/lessonEnum';
import { ImgCutModalNew } from '@/components'; import { ImgCutModalNew } from '@/components';
import ShowTips from '@/components/ShowTips'; import ShowTips from '@/components/ShowTips';
...@@ -390,6 +390,15 @@ class AddGraphicsCourse extends React.Component { ...@@ -390,6 +390,15 @@ class AddGraphicsCourse extends React.Component {
// 保存 // 保存
handleSubmit = () => { handleSubmit = () => {
//过期判断
if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) {
Modal.warning({
title:"服务已到期",
content: "当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买",
okText: "我知道了"
})
return
}
const { id, coverId, pageType, courseName, courseMedia, introduce, categoryId, shelfState, whetherVisitorsJoin } = this.state; const { id, coverId, pageType, courseName, courseMedia, introduce, categoryId, shelfState, whetherVisitorsJoin } = this.state;
const commonParams = { const commonParams = {
......
...@@ -143,7 +143,10 @@ class GraphicsCourseList extends React.Component { ...@@ -143,7 +143,10 @@ class GraphicsCourseList extends React.Component {
dataIndex: "courseware", dataIndex: "courseware",
render: (val, item, index) => { render: (val, item, index) => {
return ( return (
<Switch defaultChecked={item.shelfState==="YES"?true:false} onChange={()=>this.changeShelfState(item)}/> <Switch
checked={item.shelfState === "YES"}
defaultChecked={item.shelfState==="YES"?true:false}
onChange={(checked)=>this.changeShelfState(index,item,checked)}/>
) )
}, },
}, },
...@@ -296,15 +299,13 @@ class GraphicsCourseList extends React.Component { ...@@ -296,15 +299,13 @@ class GraphicsCourseList extends React.Component {
) )
} }
//改变上架状态 //改变上架状态
changeShelfState = (item) =>{ changeShelfState = (index,item,checked) =>{
let _shelfState = item.shelfState let _shelfState = checked ? "YES" : "NO"
if(_shelfState==='NO'){ // if(_shelfState==='NO'){
_shelfState = "YES"; // _shelfState = "YES";
item.shelfState = "YES" // }else{
}else{ // _shelfState = "NO"
_shelfState = "NO" // }
item.shelfState = "NO"
}
const params={ const params={
courseId: item.id, courseId: item.id,
shelfState:_shelfState shelfState:_shelfState
...@@ -316,6 +317,7 @@ class GraphicsCourseList extends React.Component { ...@@ -316,6 +317,7 @@ class GraphicsCourseList extends React.Component {
}else{ }else{
message.success("已取消展示"); message.success("已取消展示");
} }
this.props.changeShelfState(index,_shelfState)
} }
}) })
} }
......
...@@ -27,6 +27,13 @@ class GraphicsCourse extends React.Component { ...@@ -27,6 +27,13 @@ class GraphicsCourse extends React.Component {
this.handleFetchScheduleList(); this.handleFetchScheduleList();
} }
changeShelfState = (index, shelfState) => {
const { dataSource } = this.state;
dataSource[index].shelfState = shelfState;
this.setState({
dataSource,
});
};
// 获取视频课列表 // 获取视频课列表
handleFetchScheduleList = (_query = {}) => { handleFetchScheduleList = (_query = {}) => {
const query = { const query = {
...@@ -75,6 +82,7 @@ class GraphicsCourse extends React.Component { ...@@ -75,6 +82,7 @@ class GraphicsCourse extends React.Component {
dataSource={dataSource} dataSource={dataSource}
totalCount={totalCount} totalCount={totalCount}
onChange={this.handleFetchScheduleList} onChange={this.handleFetchScheduleList}
changeShelfState={this.changeShelfState}
/> />
</div> </div>
</div> </div>
......
...@@ -16,6 +16,9 @@ import { FileVerifyMap, FileTypeIcon } from '@/common/constants/academic/lessonE ...@@ -16,6 +16,9 @@ import { FileVerifyMap, FileTypeIcon } from '@/common/constants/academic/lessonE
import ScanFileModal from '@/modules/prepare-lesson/modal/ScanFileModal' import ScanFileModal from '@/modules/prepare-lesson/modal/ScanFileModal'
import SelectPrepareFileModal from '@/modules/prepare-lesson/modal/SelectPrepareFileModal'; import SelectPrepareFileModal from '@/modules/prepare-lesson/modal/SelectPrepareFileModal';
import Service from '@/common/js/service'; import Service from '@/common/js/service';
import BaseService from "@/domains/basic-domain/baseService";
import PreviewFileModal from '@/bu-components/PreviewFileModal';
import {YZ_APPId,YZ_PREVIEW_URL,OFFICE_PREVIEW_URL} from '@/domains/basic-domain/constants';
import './ManageCoursewareModal.less'; import './ManageCoursewareModal.less';
...@@ -33,7 +36,10 @@ class ManageCoursewareModal extends React.Component { ...@@ -33,7 +36,10 @@ class ManageCoursewareModal extends React.Component {
scanFileModal: false, scanFileModal: false,
isLessonPermission: false, isLessonPermission: false,
diskList: [], // 机构可见的磁盘目录 diskList: [], // 机构可见的磁盘目录
selectedFileList: [] selectedFileList: [],
showPreviewModal:false, //是否显示loading
previewing:false, //是否正在预览
previewStatus:'UPLOAD' //预览文件的生成状态
} }
} }
...@@ -164,17 +170,17 @@ class ManageCoursewareModal extends React.Component { ...@@ -164,17 +170,17 @@ class ManageCoursewareModal extends React.Component {
} }
// 预览文件 // 预览文件
handleScanFile(item) { handleScanFile = async (item)=>{
if (!item.srcDocUrl) return null; if (!item.srcDocUrl) return null;
const suffix = _.last(item.fileName.split('.')).toLowerCase(); const suffix = _.last(item.fileName.split('.')).toLowerCase();
const type = suffixType[suffix] const type = suffixType[suffix]
const fileType = FileVerifyMap[type].type; const fileType = FileVerifyMap[type].type;
const that = this;
switch (fileType) { switch (fileType) {
case "PDF": case "PDF":
window.open(item.srcDocUrl, "_blank"); // window.open(item.srcDocUrl, "_blank");
break; // break;
case "Excel": case "Excel":
case "EXCEL": case "EXCEL":
case "PPT": case "PPT":
...@@ -183,25 +189,78 @@ class ManageCoursewareModal extends React.Component { ...@@ -183,25 +189,78 @@ class ManageCoursewareModal extends React.Component {
case "WORD": case "WORD":
case "DOCX": case "DOCX":
case "DOC": case "DOC":
let size = parseFloat(item.fileSize.replace(/M$|KB$/g, '')); // let size = parseFloat(item.fileSize.replace(/M$|KB$/g, ''));
if (item.fileSize.includes('KB')) { // if (item.fileSize.includes('KB')) {
size = 0; // size = 0;
// }
// if (((fileType == 'word' || fileType == 'PPT') && size > 10) || ((fileType == 'Excel') && size > 5)) {
// Modal.confirm({
// title: '抱歉,不能在线预览',
// content: '由于文件较大,不支持在线预览,请下载后再查看',
// icon: <QuestionCircleOutlined />,
// okText:"下载",
// onOk:() => {
// const a = document.createElement('a');
// a.href = item.srcDocUrl;
// a.click();
// }
// });
// } else {
// const scanUrl = "https://view.officeapps.live.com/op/view.aspx?src=" + encodeURIComponent(item.srcDocUrl);
// window.open(scanUrl, "_blank");
// }
if(!item.fileVersionId){
this.setState({
previewing:true,
showPreviewModal:true,
previewStatus:'UPLOAD'
},async ()=>{
const uploadParams ={
fileUrl:item.srcDocUrl,
instId:User.getStoreId(),
yoZoTypeEnum:'UPLOAD'
}
const uploadSign = await BaseService.getYoZoSign(uploadParams);
BaseService.yoZoUpload(item.srcDocUrl,YZ_APPId,uploadSign).then(async function (response){
const saveParams ={
fileVersionId:response.data.data.fileVersionId,
folderId:item.folderId,
instId:User.getStoreId(),
}
BaseService.saveYoZoFileVersionId(saveParams);
const { previewing } = that.state;
if(previewing){
const previewParams ={
fileVersionId:response.data.data.fileVersionId,
instId:User.getStoreId(),
yoZoTypeEnum:'VIEW',
htmlTitle:item.fileName
}
const previewSign = await BaseService.getYoZoSign(previewParams);
const url = `${YZ_PREVIEW_URL}?fileVersionId=${response.data.data.fileVersionId}&appId=${YZ_APPId}&sign=${previewSign}&htmlTitle=${item.fileName}`
that.setState({
previewStatus:'UPLOAD_SUCCESS',
url
})
}
})
})
}else{
const previewParams ={
fileVersionId:item.fileVersionId,
instId:User.getStoreId(),
yoZoTypeEnum:'VIEW',
htmlTitle:item.fileName
} }
if (((fileType == 'word' || fileType == 'PPT') && size > 10) || ((fileType == 'Excel') && size > 5)) { const previewSign = await BaseService.getYoZoSign(previewParams);
Modal.confirm({ const url = `${YZ_PREVIEW_URL}?fileVersionId=${item.fileVersionId}&appId=${YZ_APPId}&sign=${previewSign}&htmlTitle=${item.fileName}`
title: '抱歉,不能在线预览',
content: '由于文件较大,不支持在线预览,请下载后再查看',
icon: <QuestionCircleOutlined />,
okText:"下载",
onOk:() => {
const a = document.createElement('a'); const a = document.createElement('a');
a.href = item.srcDocUrl; document.body.appendChild(a);
a.setAttribute('href', url);
a.setAttribute('target', '_blank');
a.click(); a.click();
} document.body.removeChild(a)
});
} else {
const scanUrl = "https://view.officeapps.live.com/op/view.aspx?src=" + encodeURIComponent(item.srcDocUrl);
window.open(scanUrl, "_blank");
} }
break; break;
case "JPG": case "JPG":
...@@ -214,8 +273,13 @@ class ManageCoursewareModal extends React.Component { ...@@ -214,8 +273,13 @@ class ManageCoursewareModal extends React.Component {
break; break;
} }
}; };
cancelPreview = ()=>{
this.setState({
previewing:false,
showPreviewModal:false,
previewStatus:'UPLOAD'
})
}
render() { render() {
const columns = [ const columns = [
{ {
...@@ -299,7 +363,7 @@ class ManageCoursewareModal extends React.Component { ...@@ -299,7 +363,7 @@ class ManageCoursewareModal extends React.Component {
const { const {
list, scanFileModal, editData, cancelObject, list, scanFileModal, editData, cancelObject,
showSelectFileModal, selectedFileList, showSelectFileModal, selectedFileList,
diskList diskList,showPreviewModal, previewStatus,url
} = this.state; } = this.state;
const _list = _.reject(list, (item) => cancelObject[item.id]); const _list = _.reject(list, (item) => cancelObject[item.id]);
return ( return (
...@@ -365,6 +429,9 @@ class ManageCoursewareModal extends React.Component { ...@@ -365,6 +429,9 @@ class ManageCoursewareModal extends React.Component {
}} }}
onSelect={this.handleAddFile} onSelect={this.handleAddFile}
/> />
{ showPreviewModal &&
<PreviewFileModal onCancel={()=>this.cancelPreview()} previewStatus={previewStatus} url={url}/>
}
</Modal> </Modal>
) )
} }
......
...@@ -466,6 +466,15 @@ class AddOfflineCourse extends React.Component { ...@@ -466,6 +466,15 @@ class AddOfflineCourse extends React.Component {
}; };
preSubmit = () => { preSubmit = () => {
//过期判断
if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) {
Modal.warning({
title:"服务已到期",
content: "当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买",
okText: "我知道了"
})
return
}
const { courseId } = this.state; const { courseId } = this.state;
if (courseId) { if (courseId) {
this.checkDetail(courseId).then(bool => bool ? this.handleSubmit() : message.warning('课程已开始,无法继续编辑')) this.checkDetail(courseId).then(bool => bool ? this.handleSubmit() : message.warning('课程已开始,无法继续编辑'))
......
...@@ -14,7 +14,7 @@ import { DISK_MAP, FileTypeIcon, FileVerifyMap } from '@/common/constants/academ ...@@ -14,7 +14,7 @@ import { DISK_MAP, FileTypeIcon, FileVerifyMap } from '@/common/constants/academ
import { ImgCutModalNew } from '@/components' import { ImgCutModalNew } from '@/components'
import ShowTips from '@/components/ShowTips' import ShowTips from '@/components/ShowTips'
import Breadcrumbs from '@/components/Breadcrumbs' import Breadcrumbs from '@/components/Breadcrumbs'
import moment from 'moment'
import AddVideoIntro from './components/AddVideoIntro' import AddVideoIntro from './components/AddVideoIntro'
import SelectStudent from '../modal/select-student' import SelectStudent from '../modal/select-student'
import SelectPrepareFileModal from '../../prepare-lesson/modal/SelectPrepareFileModal' import SelectPrepareFileModal from '../../prepare-lesson/modal/SelectPrepareFileModal'
...@@ -321,6 +321,15 @@ class AddVideoCourse extends React.Component { ...@@ -321,6 +321,15 @@ class AddVideoCourse extends React.Component {
// 保存 // 保存
handleSubmit = () => { handleSubmit = () => {
//过期判断
if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) {
Modal.warning({
title:"服务已到期",
content: "当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买",
okText: "我知道了"
})
return
}
const { instId, adminId } = window.currentUserInstInfo const { instId, adminId } = window.currentUserInstInfo
const { const {
......
import React from 'react'; import React, { useEffect, useState } from 'react';
import { Select, Tooltip } from 'antd'; import { Select, Tooltip, Carousel, Popover } from 'antd';
import DataSet from "@antv/data-set"; import DataSet from "@antv/data-set";
import { Chart as G2Chart } from '@antv/g2'; import { Chart as G2Chart } from '@antv/g2';
import { import {
...@@ -20,6 +20,8 @@ import { ...@@ -20,6 +20,8 @@ import {
import moment from 'moment' import moment from 'moment'
import Service from "@/common/js/service"; import Service from "@/common/js/service";
import User from '@/common/js/user'; import User from '@/common/js/user';
import HomeTip from './HomeTip';
import './Home.less'; import './Home.less';
const Option = Select.Option; const Option = Select.Option;
...@@ -265,6 +267,7 @@ class Home extends React.Component { ...@@ -265,6 +267,7 @@ class Home extends React.Component {
}; };
return ( return (
<div className="home-page"> <div className="home-page">
<HomeTip />
<div className="data-wrap"> <div className="data-wrap">
<div className="home-title">数据概况</div> <div className="home-title">数据概况</div>
<div className="data-box"> <div className="data-box">
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
font-family: 'number'; font-family: 'number';
src: url('https://image.xiaomaiketang.com/xm/n2sADd2jY6.TTF'); src: url('https://image.xiaomaiketang.com/xm/n2sADd2jY6.TTF');
} }
.data-wrap{ .data-wrap{
background: #FFF; background: #FFF;
.data-box { .data-box {
......
.home-tip {
.tip {
height: 40px;
background: #FFE7E7;
margin-bottom: 16px;
.content {
font-size: 14px;
color: #666666;
font-weight: 400;
line-height: 40px;
padding-left: 16px;
.renew-btn {
display: inline-block;
width: 80px;
height: 28px;
background: #FF4F4F;
border-radius: 2px;
color: #ffffff;
font-size: 14px;
font-weight: 400;
line-height: 28px;
text-align: center;
cursor: pointer;
margin-left: 8px;
}
}
}
}
\ No newline at end of file
import React, { useContext, useEffect, useState, version } from "react";
import "./HomeTip.less"
import { VersionContext } from "@/store/context";
import ContactWidget from '@/components/ContactWidget';
import { Carousel } from "antd";
export default function HomeTip() {
const [isOverNum, setIsOverNum] = useState<boolean>(false)
const [tipType, setTipType] = useState(0) //0不显示1即将过期2已过期
const [expirationTime, setExpirationTime] = useState("")
const [surplusDay, setSurplusDay] = useState(0)
const versionInfo = useContext(VersionContext)
useEffect(()=> {
if (versionInfo) {
setIsOverNum(versionInfo.userNum === -1 ? false : versionInfo.whetherReachUserNum)
setSurplusDay(versionInfo.surplusDayTime)
setExpirationTime(versionInfo.validEndTime)
if (versionInfo.stateEnum === "NO") {
setTipType(2)
} else if (versionInfo.surplusDayTime === 30 || versionInfo.surplusDayTime <= 7) {
setTipType(1)
}
}
},[versionInfo])
return (
<div className="home-tip">
{
(isOverNum || tipType !== 0) &&
<div className="tip">
<Carousel dotPosition="left" dots={false} autoplay={true} autoplaySpeed={5000}>
{
isOverNum && (
<div className="content">
<span className="icon iconfont" style={{color:"#FF4F4F",marginRight:"8px"}}>&#xe61d;</span>温馨提示:企业使用人数已达上限,将无法新增员工、学员,如需增加人数限制,请联系小麦企学院服务平台。
<ContactWidget placement="bottom" trigger="hover"><div className="renew-btn">立即续费</div></ContactWidget>
</div>
)
}
{
tipType === 2 && (
<div className="content">
<span className="icon iconfont" style={{color:"#FF4F4F",marginRight:"8px"}}>&#xe61d;</span>版本到期提醒:当前企业购买的小麦企学院服务已于{expirationTime}到期,到期后仍可访问,但功能不可使用,建议尽快续费购买哦~
<ContactWidget placement="bottom" trigger="hover"><div className="renew-btn">立即续费</div></ContactWidget>
</div>
)
}
{
tipType === 1 && (
<div className="content">
<span className="icon iconfont" style={{color:"#FF4F4F",marginRight:"8px"}}>&#xe61d;</span>当前企业购买的小麦企学院服务仅剩{surplusDay}天(于{expirationTime}到期),为了不影响使用,建议尽快续费购买哦~
<ContactWidget placement="bottom" trigger="hover"><div className="renew-btn">立即续费</div></ContactWidget>
</div>
)
}
</Carousel>
</div>
}
</div>
)
}
\ No newline at end of file
import React from 'react'; import React from 'react';
import { withRouter } from "react-router-dom"; import { withRouter } from 'react-router-dom';
import {Table, Modal,Input,message} from 'antd'; import { Input } from 'antd';
import { PageControl } from "@/components"; import { PageControl, XMTable } from '@/components';
import PlanService from '@/domains/plan-domain/planService' import college from '@/common/lottie/college';
import PlanService from '@/domains/plan-domain/planService';
import User from '@/common/js/user'; import User from '@/common/js/user';
import Bus from '@/core/bus'; import Bus from '@/core/bus';
import './EmployeeShareData.less'; import './EmployeeShareData.less';
...@@ -10,103 +11,129 @@ import './EmployeeShareData.less'; ...@@ -10,103 +11,129 @@ import './EmployeeShareData.less';
const { Search } = Input; const { Search } = Input;
const UserRole = { const UserRole = {
Store_Manager: { Store_Manager: {
text: "学院管理员" text: '学院管理员',
}, },
Cloud_Manager: { Cloud_Manager: {
text:"管理员" text: '管理员',
}, },
Cloud_Operator: { Cloud_Operator: {
text:'运营师' text: '运营师',
}, },
Cloud_Lecture: { Cloud_Lecture: {
text:"讲师" text: '讲师',
}, },
}; };
class EmployeeShareData extends React.Component { class EmployeeShareData extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
const id = getParameterByName("id"); const id = getParameterByName('id');
this.state = { this.state = {
id, id,
dataSource:[], dataSource: [],
size:10, size: 10,
query: { query: {
current: 1, current: 1,
}, },
totalCount:0, totalCount: 0,
} };
} }
componentDidMount(){ componentDidMount() {
this.handleFetchDataList(); this.handleFetchDataList();
} }
handleFetchDataList = ()=>{ handleFetchDataList = () => {
const { query ,size,id} = this.state; const { query, size, id } = this.state;
const params ={ const params = {
...query, ...query,
size, size,
planId:id, planId: id,
storeId:User.getStoreId(), storeId: User.getStoreId(),
} };
PlanService.getPlanUserRecordPage(params).then((res) => { PlanService.getPlanUserRecordPage(params).then((res) => {
const { result = {} } = res ; const { result = {} } = res;
const { records = [], total = 0 } = result; const { records = [], total = 0 } = result;
this.setState({ this.setState({
dataSource: records, dataSource: records,
totalCount: Number(total) totalCount: Number(total),
}); });
}); });
} };
onShowSizeChange = (current, size) => { onShowSizeChange = (current, size) => {
if (current == size) { if (current == size) {
return return;
} }
this.setState({ this.setState(
size {
},()=>{this.handleFetchDataList()}) size,
},
() => {
this.handleFetchDataList();
} }
handleChangeTable = (pagination, filters, sorter)=> { );
};
handleChangeTable = (pagination, filters, sorter) => {
const { columnKey, order } = sorter; const { columnKey, order } = sorter;
const { query } = this.state; const { query } = this.state;
let _columnKey; let _columnKey;
let _order; let _order;
if (columnKey === 'learnNum' && order === 'ascend') { _columnKey="LEARN_NUM"; _order = 'SORT_ASC'; } if (columnKey === 'learnNum' && order === 'ascend') {
if (columnKey === 'learnNum' && order === 'descend') { _columnKey="LEARN_NUM"; _order = 'SORT_DESC'; } _columnKey = 'LEARN_NUM';
_order = 'SORT_ASC';
}
if (columnKey === 'learnNum' && order === 'descend') {
_columnKey = 'LEARN_NUM';
_order = 'SORT_DESC';
}
if (columnKey === 'learnFinishNum' && order === 'ascend') { _columnKey="FINISH_NUM"; _order = 'SORT_ASC'; } if (columnKey === 'learnFinishNum' && order === 'ascend') {
if (columnKey === 'learnFinishNum' && order === 'descend') { _columnKey="FINISH_NUM"; _order = 'SORT_DESC'; } _columnKey = 'FINISH_NUM';
_order = 'SORT_ASC';
}
if (columnKey === 'learnFinishNum' && order === 'descend') {
_columnKey = 'FINISH_NUM';
_order = 'SORT_DESC';
}
if (columnKey === 'learnNoFinishNum' && order === 'ascend') { _columnKey="NOT_NUM"; _order = 'SORT_ASC'; } if (columnKey === 'learnNoFinishNum' && order === 'ascend') {
if (columnKey === 'learnNoFinishNum' && order === 'descend') { _columnKey="NOT_NUM"; _order = 'SORT_DESC'; } _columnKey = 'NOT_NUM';
_order = 'SORT_ASC';
}
if (columnKey === 'learnNoFinishNum' && order === 'descend') {
_columnKey = 'NOT_NUM';
_order = 'SORT_DESC';
}
const _query = { const _query = {
...query, ...query,
sortMap:{} sortMap: {},
}; };
_query.sortMap[_columnKey]=_order; _query.sortMap[_columnKey] = _order;
this.setState({ this.setState(
query:_query {
},()=>this.handleFetchDataList()) query: _query,
} },
handleChangNickname = (value)=>{ () => this.handleFetchDataList()
);
};
handleChangNickname = (value) => {
const isPhone = (value || '').match(/^\d+$/); const isPhone = (value || '').match(/^\d+$/);
const { query } = this.state; const { query } = this.state;
if(isPhone){ if (isPhone) {
query.userPhone = value; query.userPhone = value;
query.userName = null; query.userName = null;
}else{ } else {
query.userName = value; query.userName = value;
query.userPhone = null; query.userPhone = null;
} }
query.current = 1; query.current = 1;
this.setState({ this.setState({
query query,
}) });
} };
watchDataView = (record)=>{ watchDataView = (record) => {
Bus.trigger('watchDataView',record); Bus.trigger('watchDataView', record);
} };
// 请求表头 // 请求表头
parselumns = () => { parselumns = () => {
const columns = [ const columns = [
...@@ -115,24 +142,16 @@ class EmployeeShareData extends React.Component { ...@@ -115,24 +142,16 @@ class EmployeeShareData extends React.Component {
key: 'storeUserName', key: 'storeUserName',
dataIndex: 'storeUserName', dataIndex: 'storeUserName',
render: (val, record) => { render: (val, record) => {
return ( return <div>{val}</div>;
<div> },
{val}
</div>
)
}
}, },
{ {
title: '角色', title: '角色',
key: 'roleEnum', key: 'roleEnum',
dataIndex: 'roleEnum', dataIndex: 'roleEnum',
render: (val, record) => { render: (val, record) => {
return ( return <div>{UserRole[record.roleEnum].text}</div>;
<div> },
{UserRole[record.roleEnum].text}
</div>
)
}
}, },
//产品暂时性隐藏 //产品暂时性隐藏
// { // {
...@@ -151,28 +170,20 @@ class EmployeeShareData extends React.Component { ...@@ -151,28 +170,20 @@ class EmployeeShareData extends React.Component {
title: '最近分享成功时间', title: '最近分享成功时间',
key: 'recentlyForwardTime', key: 'recentlyForwardTime',
dataIndex: 'recentlyForwardTime', dataIndex: 'recentlyForwardTime',
width:240, width: 240,
render: (val, record) => { render: (val, record) => {
return ( return <div>{formatDate('YYYY-MM-DD H:i', val)}</div>;
<div> },
{formatDate('YYYY-MM-DD H:i', val)}
</div>
)
}
}, },
{ {
title: '学习人数', title: '学习人数',
key: 'learnNum', key: 'learnNum',
dataIndex: 'learnNum', dataIndex: 'learnNum',
width:110, width: 110,
sorter:true, sorter: true,
render: (val, record) => { render: (val, record) => {
return ( return <div className='learn-num'>{val}</div>;
<div className="learn-num"> },
{val}
</div>
)
}
}, },
// { // {
// title: '已学完', // title: '已学完',
...@@ -208,24 +219,39 @@ class EmployeeShareData extends React.Component { ...@@ -208,24 +219,39 @@ class EmployeeShareData extends React.Component {
dataIndex: 'operate', dataIndex: 'operate',
render: (val, record) => { render: (val, record) => {
return ( return (
<span className="operate-item" onClick={()=>this.watchDataView(record)}>数据详情</span> <span className='operate-item' onClick={() => this.watchDataView(record)}>
) 数据详情
} </span>
} );
},
},
]; ];
return columns; return columns;
} };
render() { render() {
const { dataSource,query,size,totalCount} = this.state; const { dataSource, query, size, totalCount } = this.state;
return ( return (
<div className="employee-share-data"> <div className='employee-share-data'>
<div className="search-container"> <div className='search-container'>
<Search placeholder="搜索员工姓名或手机号" onChange={(e) => { this.handleChangNickname(e.target.value)}} onSearch={ () => { this.handleFetchDataList()}} style={{ width: 200 }} enterButton={<span className="icon iconfont">&#xe832;</span>}/> <Search
placeholder='搜索员工姓名或手机号'
onChange={(e) => {
this.handleChangNickname(e.target.value);
}}
onSearch={() => {
this.handleFetchDataList();
}}
style={{ width: 200 }}
enterButton={<span className='icon iconfont'>&#xe832;</span>}
/>
</div> </div>
<div> <div>
<Table <XMTable
rowKey={record => record.id} renderEmpty={{
image: college,
description: '暂无数据',
}}
rowKey={(record) => record.id}
dataSource={dataSource} dataSource={dataSource}
columns={this.parselumns()} columns={this.parselumns()}
pagination={false} pagination={false}
...@@ -233,25 +259,30 @@ class EmployeeShareData extends React.Component { ...@@ -233,25 +259,30 @@ class EmployeeShareData extends React.Component {
showSorterTooltip={false} showSorterTooltip={false}
bordered bordered
/> />
{dataSource.length >0 && {dataSource.length > 0 && (
<div className="box-footer"> <div className='box-footer'>
<PageControl <PageControl
current={query.current - 1} current={query.current - 1}
pageSize={size} pageSize={size}
total={totalCount} total={totalCount}
toPage={(page) => { toPage={(page) => {
const _query = {...query, current: page + 1}; const _query = { ...query, current: page + 1 };
this.setState({ this.setState(
query:_query {
},()=>{ this.handleFetchDataList()}) query: _query,
},
() => {
this.handleFetchDataList();
}
);
}} }}
onShowSizeChange={this.onShowSizeChange} onShowSizeChange={this.onShowSizeChange}
/> />
</div> </div>
} )}
</div> </div>
</div> </div>
) );
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* @Description: 大班直播、互动班课列表的筛选组件 * @Description: 大班直播、互动班课列表的筛选组件
*/ */
import React, { useState, useRef, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { Row, Input, Select ,Tooltip} from 'antd'; import { Row, Input, Select ,Tooltip} from 'antd';
import RangePicker from "@/modules/common/DateRangePicker"; import RangePicker from "@/modules/common/DateRangePicker";
...@@ -86,7 +86,7 @@ function PlanFilter(props) { ...@@ -86,7 +86,7 @@ function PlanFilter(props) {
}; };
StoreService.getStoreUserBasicPage( _query).then((res) => { StoreService.getStoreUserBasicPage( _query).then((res) => {
const { result = {} } = res; const { result = {} } = res;
const { records = [], total = 0, hasNext } = result; const { records = [], hasNext } = result;
const list = current > 1 ? creatorList.concat(records) : records; const list = current > 1 ? creatorList.concat(records) : records;
setHasNext(hasNext); setHasNext(hasNext);
setCreatorList(list); setCreatorList(list);
......
import React from 'react' import React from 'react';
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom';
import { Table, Modal, message, Tooltip } from 'antd' import { Modal, message, Tooltip } from 'antd';
import { PageControl } from '@/components' import { PageControl, XMTable } from '@/components';
import UserLearningDataFilter from './UserLearningDataFilter' import college from '@/common/lottie/college';
import PlanService from '@/domains/plan-domain/planService' import UserLearningDataFilter from './UserLearningDataFilter';
import UserLearnDetailModal from '../modal/UserLearnDetailModal' import PlanService from '@/domains/plan-domain/planService';
import UnbundEmployeeModal from '../modal/UnbundEmployeeModal' import UserLearnDetailModal from '../modal/UserLearnDetailModal';
import User from '@/common/js/user' import UnbundEmployeeModal from '../modal/UnbundEmployeeModal';
import './UserLearningData.less' import User from '@/common/js/user';
const { confirm } = Modal import './UserLearningData.less';
const { confirm } = Modal;
const LearnState = { const LearnState = {
UN_PLAY: { UN_PLAY: {
text: '未开始', text: '未开始',
...@@ -19,12 +20,12 @@ const LearnState = { ...@@ -19,12 +20,12 @@ const LearnState = {
FINISH: { FINISH: {
text: '已完成', text: '已完成',
}, },
} };
class UserLearningData extends React.Component { class UserLearningData extends React.Component {
constructor(props) { constructor(props) {
super(props) super(props);
const id = getParameterByName('id') const id = getParameterByName('id');
this.state = { this.state = {
id, id,
dataSource: [], dataSource: [],
...@@ -35,13 +36,13 @@ class UserLearningData extends React.Component { ...@@ -35,13 +36,13 @@ class UserLearningData extends React.Component {
totalCount: 0, totalCount: 0,
userLearnDetailModalSHow: false, userLearnDetailModalSHow: false,
unbundEmployeeModalVisible: false, unbundEmployeeModalVisible: false,
} };
} }
componentDidMount() { componentDidMount() {
this.handleFetchDataList() this.handleFetchDataList();
} }
handleFetchDataList = (_query) => { handleFetchDataList = (_query) => {
const { query, size, id } = this.state const { query, size, id } = this.state;
const params = { const params = {
...query, ...query,
..._query, ..._query,
...@@ -49,88 +50,88 @@ class UserLearningData extends React.Component { ...@@ -49,88 +50,88 @@ class UserLearningData extends React.Component {
planId: id, planId: id,
storeId: User.getStoreId(), storeId: User.getStoreId(),
storeUserId: User.getStoreUserId(), storeUserId: User.getStoreUserId(),
} };
this.setState({ query: params }) this.setState({ query: params });
PlanService.getPlanCustomerRecordPage(params).then((res) => { PlanService.getPlanCustomerRecordPage(params).then((res) => {
const { result = {} } = res const { result = {} } = res;
const { records = [], total = 0 } = result const { records = [], total = 0 } = result;
this.setState({ this.setState({
dataSource: records, dataSource: records,
totalCount: Number(total), totalCount: Number(total),
}) });
}) });
} };
onShowSizeChange = (current, size) => { onShowSizeChange = (current, size) => {
if (current == size) { if (current == size) {
return return;
} }
this.setState( this.setState(
{ {
size, size,
}, },
() => { () => {
this.handleFetchDataList() this.handleFetchDataList();
}
)
} }
);
};
handleChangeTable = (pagination, filters, sorter) => { handleChangeTable = (pagination, filters, sorter) => {
const { columnKey, order } = sorter const { columnKey, order } = sorter;
const { query } = this.state const { query } = this.state;
let _columnKey let _columnKey;
let _order let _order;
if (columnKey === 'latelyLearnTime' && order === 'ascend') { if (columnKey === 'latelyLearnTime' && order === 'ascend') {
_columnKey = 'LATE_LEARN_TIME' _columnKey = 'LATE_LEARN_TIME';
_order = 'SORT_ASC' _order = 'SORT_ASC';
} }
if (columnKey === 'latelyLearnTime' && order === 'descend') { if (columnKey === 'latelyLearnTime' && order === 'descend') {
_columnKey = 'LATE_LEARN_TIME' _columnKey = 'LATE_LEARN_TIME';
_order = 'SORT_DESC' _order = 'SORT_DESC';
} }
if (columnKey === 'startLearnTime' && order === 'ascend') { if (columnKey === 'startLearnTime' && order === 'ascend') {
_columnKey = 'START_LEARN_TIME' _columnKey = 'START_LEARN_TIME';
_order = 'SORT_ASC' _order = 'SORT_ASC';
} }
if (columnKey === 'startLearnTime' && order === 'descend') { if (columnKey === 'startLearnTime' && order === 'descend') {
_columnKey = 'START_LEARN_TIME' _columnKey = 'START_LEARN_TIME';
_order = 'SORT_DESC' _order = 'SORT_DESC';
} }
if (columnKey === 'learnNum' && order === 'ascend') { if (columnKey === 'learnNum' && order === 'ascend') {
_columnKey = 'LEARN_NUM' _columnKey = 'LEARN_NUM';
_order = 'SORT_ASC' _order = 'SORT_ASC';
} }
if (columnKey === 'learnNum' && order === 'descend') { if (columnKey === 'learnNum' && order === 'descend') {
_columnKey = 'LEARN_NUM' _columnKey = 'LEARN_NUM';
_order = 'SORT_DESC' _order = 'SORT_DESC';
} }
const _query = { const _query = {
...query, ...query,
sortMap: {}, sortMap: {},
} };
_query.sortMap[_columnKey] = _order _query.sortMap[_columnKey] = _order;
this.setState( this.setState(
{ {
query: _query, query: _query,
}, },
() => this.handleFetchDataList() () => this.handleFetchDataList()
) );
} };
watchDetail = (record) => { watchDetail = (record) => {
this.setState({ this.setState({
userLearnDetailModalSHow: true, userLearnDetailModalSHow: true,
storeCustomerId: record.storeCustomerId, storeCustomerId: record.storeCustomerId,
planId: record.planId, planId: record.planId,
}) });
} };
closeUserLearnDetailModal = () => { closeUserLearnDetailModal = () => {
this.setState({ this.setState({
userLearnDetailModalSHow: false, userLearnDetailModalSHow: false,
}) });
} };
UnbundEmployee = (record) => { UnbundEmployee = (record) => {
if (User.getUserRole() === 'CloudOperator') { if (User.getUserRole() === 'CloudOperator') {
return confirm({ return confirm({
...@@ -141,40 +142,40 @@ class UserLearningData extends React.Component { ...@@ -141,40 +142,40 @@ class UserLearningData extends React.Component {
okType: 'danger', okType: 'danger',
cancelText: '取消', cancelText: '取消',
onOk: () => { onOk: () => {
this.handleConfirmUnbundEmployee(record.storeCustomerId) this.handleConfirmUnbundEmployee(record.storeCustomerId);
}, },
}) });
} else { } else {
this.setState({ this.setState({
unbundEmployeeModalVisible: true, unbundEmployeeModalVisible: true,
storeCustomerId: record.storeCustomerId, storeCustomerId: record.storeCustomerId,
}) });
}
} }
};
handleConfirmUnbundEmployee = (storeCustomerId) => { handleConfirmUnbundEmployee = (storeCustomerId) => {
let removeUserIds = [] let removeUserIds = [];
removeUserIds.push(storeCustomerId) removeUserIds.push(storeCustomerId);
const params = { const params = {
planId: getParameterByName('id'), planId: getParameterByName('id'),
removeUserIds, removeUserIds,
storeCustomerId: storeCustomerId, storeCustomerId: storeCustomerId,
storeId: User.getStoreId(), storeId: User.getStoreId(),
storeUserId: User.getStoreUserId(), storeUserId: User.getStoreUserId(),
} };
PlanService.removePlanCustomer(params).then((res) => { PlanService.removePlanCustomer(params).then((res) => {
this.handleFetchDataList() this.handleFetchDataList();
message.success('解绑成功') message.success('解绑成功');
}) });
} };
handleCloseUnbundEmployeeModal = () => { handleCloseUnbundEmployeeModal = () => {
this.setState({ this.setState({
unbundEmployeeModalVisible: false, unbundEmployeeModalVisible: false,
}) });
} };
// 请求表头 // 请求表头
parselumns = () => { parselumns = () => {
let columns let columns;
if (User.getUserRole() === 'CloudManager' || User.getUserRole() === 'StoreManager') { if (User.getUserRole() === 'CloudManager' || User.getUserRole() === 'StoreManager') {
columns = [ columns = [
{ {
...@@ -182,7 +183,7 @@ class UserLearningData extends React.Component { ...@@ -182,7 +183,7 @@ class UserLearningData extends React.Component {
key: 'storeCustomerName', key: 'storeCustomerName',
dataIndex: 'storeCustomerName', dataIndex: 'storeCustomerName',
render: (val, record) => { render: (val, record) => {
return <div>{val}</div> return <div>{val}</div>;
}, },
}, },
{ {
...@@ -190,14 +191,20 @@ class UserLearningData extends React.Component { ...@@ -190,14 +191,20 @@ class UserLearningData extends React.Component {
key: 'learnState', key: 'learnState',
dataIndex: 'learnState', dataIndex: 'learnState',
render: (val, record) => { render: (val, record) => {
return <div>{LearnState[val].text}</div> return <div>{LearnState[val].text}</div>;
}, },
}, },
{ {
title: <span> title: (
<span>
<span>负责人</span> <span>负责人</span>
<Tooltip title="培训计划的分享者/跟进人"><i className="icon iconfont" style={{ marginLeft: '5px',cursor:'pointer',color:'#bfbfbf',fontSize:'14px',fontWeight:"400"}}>&#xe61d;</i></Tooltip> <Tooltip title='培训计划的分享者/跟进人'>
</span>, <i className='icon iconfont' style={{ marginLeft: '5px', cursor: 'pointer', color: '#bfbfbf', fontSize: '14px', fontWeight: '400' }}>
&#xe61d;
</i>
</Tooltip>
</span>
),
key: 'userNameList', key: 'userNameList',
dataIndex: 'userNameList', dataIndex: 'userNameList',
render: (val, record) => { render: (val, record) => {
...@@ -208,10 +215,10 @@ class UserLearningData extends React.Component { ...@@ -208,10 +215,10 @@ class UserLearningData extends React.Component {
<span> <span>
{item} {index < record.userNameList.length - 1 && <span></span>}{' '} {item} {index < record.userNameList.length - 1 && <span></span>}{' '}
</span> </span>
) );
})} })}
</div> </div>
) );
}, },
}, },
{ {
...@@ -221,7 +228,7 @@ class UserLearningData extends React.Component { ...@@ -221,7 +228,7 @@ class UserLearningData extends React.Component {
sorter: true, sorter: true,
width: 240, width: 240,
render: (val, record) => { render: (val, record) => {
return `${formatDate('YYYY-MM-DD H:i', parseInt(record.latelyLearnTime))}` return `${formatDate('YYYY-MM-DD H:i', parseInt(record.latelyLearnTime))}`;
}, },
}, },
{ {
...@@ -231,14 +238,20 @@ class UserLearningData extends React.Component { ...@@ -231,14 +238,20 @@ class UserLearningData extends React.Component {
width: 240, width: 240,
sorter: true, sorter: true,
render: (val, record) => { render: (val, record) => {
return <div>{formatDate('YYYY-MM-DD H:i', val)}</div> return <div>{formatDate('YYYY-MM-DD H:i', val)}</div>;
}, },
}, },
{ {
title: <span> title: (
<span>
<span>学习进度</span> <span>学习进度</span>
<Tooltip title="学员培训计划中达到“已完成”状态的课程数/总课程数"><i className="icon iconfont" style={{ marginLeft: '5px',cursor:'pointer',color:'#bfbfbf',fontSize:'14px', fontWeight:"400"}}>&#xe61d;</i></Tooltip> <Tooltip title='学员培训计划中达到“已完成”状态的课程数/总课程数'>
</span>, <i className='icon iconfont' style={{ marginLeft: '5px', cursor: 'pointer', color: '#bfbfbf', fontSize: '14px', fontWeight: '400' }}>
&#xe61d;
</i>
</Tooltip>
</span>
),
key: 'learnNum', key: 'learnNum',
dataIndex: 'learnNum', dataIndex: 'learnNum',
width: 130, width: 130,
...@@ -250,7 +263,7 @@ class UserLearningData extends React.Component { ...@@ -250,7 +263,7 @@ class UserLearningData extends React.Component {
<span>/</span> <span>/</span>
<span>{record.courseNum}</span> <span>{record.courseNum}</span>
</div> </div>
) );
}, },
}, },
{ {
...@@ -267,15 +280,15 @@ class UserLearningData extends React.Component { ...@@ -267,15 +280,15 @@ class UserLearningData extends React.Component {
<span <span
className='operate-item' className='operate-item'
onClick={() => { onClick={() => {
this.UnbundEmployee(record) this.UnbundEmployee(record);
}}> }}>
解绑 解绑
</span> </span>
</div> </div>
) );
}, },
}, },
] ];
} else { } else {
columns = [ columns = [
{ {
...@@ -283,7 +296,7 @@ class UserLearningData extends React.Component { ...@@ -283,7 +296,7 @@ class UserLearningData extends React.Component {
key: 'storeCustomerName', key: 'storeCustomerName',
dataIndex: 'storeCustomerName', dataIndex: 'storeCustomerName',
render: (val, record) => { render: (val, record) => {
return <div>{val}</div> return <div>{val}</div>;
}, },
}, },
{ {
...@@ -291,7 +304,7 @@ class UserLearningData extends React.Component { ...@@ -291,7 +304,7 @@ class UserLearningData extends React.Component {
key: 'learnState', key: 'learnState',
dataIndex: 'learnState', dataIndex: 'learnState',
render: (val, record) => { render: (val, record) => {
return <div>{LearnState[val].text}</div> return <div>{LearnState[val].text}</div>;
}, },
}, },
{ {
...@@ -300,7 +313,7 @@ class UserLearningData extends React.Component { ...@@ -300,7 +313,7 @@ class UserLearningData extends React.Component {
dataIndex: 'latelyLearnTime', dataIndex: 'latelyLearnTime',
sorter: true, sorter: true,
render: (val, record) => { render: (val, record) => {
return <div>{formatDate('YYYY-MM-DD H:i', val)}</div> return <div>{formatDate('YYYY-MM-DD H:i', val)}</div>;
}, },
}, },
{ {
...@@ -309,7 +322,7 @@ class UserLearningData extends React.Component { ...@@ -309,7 +322,7 @@ class UserLearningData extends React.Component {
dataIndex: 'startLearnTime', dataIndex: 'startLearnTime',
sorter: true, sorter: true,
render: (val, record) => { render: (val, record) => {
return <div>{formatDate('YYYY-MM-DD H:i', val)}</div> return <div>{formatDate('YYYY-MM-DD H:i', val)}</div>;
}, },
}, },
{ {
...@@ -333,7 +346,7 @@ class UserLearningData extends React.Component { ...@@ -333,7 +346,7 @@ class UserLearningData extends React.Component {
<span>/</span> <span>/</span>
<span>{record.courseNum}</span> <span>{record.courseNum}</span>
</div> </div>
) );
}, },
}, },
{ {
...@@ -350,28 +363,32 @@ class UserLearningData extends React.Component { ...@@ -350,28 +363,32 @@ class UserLearningData extends React.Component {
<span <span
className='operate-item' className='operate-item'
onClick={() => { onClick={() => {
this.UnbundEmployee(record) this.UnbundEmployee(record);
}}> }}>
解绑 解绑
</span> </span>
</div> </div>
) );
}, },
}, },
] ];
} }
return columns return columns;
} };
render() { render() {
const { dataSource, query, size, totalCount, userLearnDetailModalSHow, storeCustomerId, planId, unbundEmployeeModalVisible } = this.state const { dataSource, query, size, totalCount, userLearnDetailModalSHow, storeCustomerId, planId, unbundEmployeeModalVisible } = this.state;
return ( return (
<div className='user-learning-data'> <div className='user-learning-data'>
<div className='search-container'> <div className='search-container'>
<UserLearningDataFilter onChange={this.handleFetchDataList} /> <UserLearningDataFilter onChange={this.handleFetchDataList} />
</div> </div>
<div> <div>
<Table <XMTable
renderEmpty={{
image: college,
description: '暂无数据',
}}
rowKey={(record) => record.storeCustomerId} rowKey={(record) => record.storeCustomerId}
dataSource={dataSource} dataSource={dataSource}
columns={this.parselumns()} columns={this.parselumns()}
...@@ -388,15 +405,15 @@ class UserLearningData extends React.Component { ...@@ -388,15 +405,15 @@ class UserLearningData extends React.Component {
pageSize={size} pageSize={size}
total={totalCount} total={totalCount}
toPage={(page) => { toPage={(page) => {
const _query = { ...query, current: page + 1 } const _query = { ...query, current: page + 1 };
this.setState( this.setState(
{ {
query: _query, query: _query,
}, },
() => { () => {
this.handleFetchDataList() this.handleFetchDataList();
} }
) );
}} }}
onShowSizeChange={this.onShowSizeChange} onShowSizeChange={this.onShowSizeChange}
/> />
...@@ -412,14 +429,14 @@ class UserLearningData extends React.Component { ...@@ -412,14 +429,14 @@ class UserLearningData extends React.Component {
onClose={this.handleCloseUnbundEmployeeModal} onClose={this.handleCloseUnbundEmployeeModal}
storeCustomerId={storeCustomerId} storeCustomerId={storeCustomerId}
onConfirm={() => { onConfirm={() => {
this.handleFetchDataList() this.handleFetchDataList();
this.handleCloseUnbundEmployeeModal() this.handleCloseUnbundEmployeeModal();
}} }}
/> />
)} )}
</div> </div>
) );
} }
} }
export default withRouter(UserLearningData) export default withRouter(UserLearningData);
import React from "react" import React from 'react';
import _ from "underscore" import _ from 'underscore';
import { Table, Radio, Tabs, Modal, Input, message, Button, Tooltip } from "antd" import { Table, Radio, Tabs, Modal, Input, message, Button, Tooltip } from 'antd';
import { PageControl } from "@/components" import { PageControl, XMTable } from '@/components';
import college from '@/common/lottie/college';
import CourseService from "@/domains/course-domain/CourseService" import CourseService from '@/domains/course-domain/CourseService';
import User from "@/common/js/user" import User from '@/common/js/user';
import Service from "@/common/js/service" import Service from '@/common/js/service';
import dealTimeDuration from "../../course-manage/utils/dealTimeDuration" import dealTimeDuration from '../../course-manage/utils/dealTimeDuration';
import "./relatedCourseModal.less" import './relatedCourseModal.less';
const { Search } = Input const { Search } = Input;
const { TabPane } = Tabs const { TabPane } = Tabs;
const courseStateShow = { const courseStateShow = {
UN_START: { UN_START: {
code: 1, code: 1,
title: "待开课", title: '待开课',
color: "#FFB129", color: '#FFB129',
}, },
STARTING: { STARTING: {
code: 2, code: 2,
title: "上课中", title: '上课中',
color: "#238FFF" color: '#238FFF',
}, },
FINISH: { FINISH: {
code: 3, code: 3,
title: "已完成", title: '已完成',
color: "#3BBDAA" color: '#3BBDAA',
}, },
EXPIRED: { EXPIRED: {
code: 4, code: 4,
title: "未成功开课", title: '未成功开课',
color: "#999" color: '#999',
} },
} };
class SelectOperatorModal extends React.Component { class SelectOperatorModal extends React.Component {
constructor(props) { constructor(props) {
super(props) super(props);
this.state = { this.state = {
liveDataSource: [], liveDataSource: [],
liveSize: 10, liveSize: 10,
liveQuery: { liveQuery: {
current: 1 current: 1,
}, },
liveTotalCount: 0, liveTotalCount: 0,
selectLive: [], //弹窗内已选择的直播课程 selectLive: [], //弹窗内已选择的直播课程
currentCourseListData: [], currentCourseListData: [],
currentLiveCourseListData: [], //页面中已关联的直播课程 currentLiveCourseListData: [], //页面中已关联的直播课程
videoCourseDivision: "internal", videoCourseDivision: 'internal',
videoDataSource: { videoDataSource: {
external: [], external: [],
internal: [] internal: [],
}, },
videoSize: { videoSize: {
external: 10, external: 10,
internal: 10 internal: 10,
}, },
videoSearchName: { videoSearchName: {
external: "", external: '',
internal: "" internal: '',
}, },
videoSearchDefalt: "", videoSearchDefalt: '',
videoQuery: { videoQuery: {
external: { external: {
current: 1 current: 1,
}, },
internal: { internal: {
current: 1 current: 1,
} },
}, },
videoTotalCount: { videoTotalCount: {
external: 0, external: 0,
internal: 0 internal: 0,
}, },
selectVideo: { selectVideo: {
external: [], external: [],
internal: [] internal: [],
}, //弹窗内已选择的视频课程 }, //弹窗内已选择的视频课程
currentVideoCourseListData: { currentVideoCourseListData: {
external: [], external: [],
internal: [] internal: [],
}, //页面中已关联的视频课程 }, //页面中已关联的视频课程
pictureDataSource: [], pictureDataSource: [],
pictureSize: 10, pictureSize: 10,
pictureQuery: { pictureQuery: {
current: 1 current: 1,
}, },
pictureTotalCount: 0, pictureTotalCount: 0,
selectPicture: [], //弹窗内已选择的视频课程 selectPicture: [], //弹窗内已选择的视频课程
currentPictureCourseListData: [], //页面中已关联的视频课程 currentPictureCourseListData: [], //页面中已关联的视频课程
activeKey: "video", activeKey: 'video',
currentTaskCourseData: this.props.data[this.props.selectedTaskIndex].courseList || [] currentTaskCourseData: this.props.data[this.props.selectedTaskIndex].courseList || [],
} };
} }
componentDidMount() { componentDidMount() {
this.handleFetchLiveDataList() this.handleFetchLiveDataList();
this.handleFetchVideoDataList() this.handleFetchVideoDataList();
this.handleFetchPictureDataList() this.handleFetchPictureDataList();
} }
// 获取直播课列表 // 获取直播课列表
handleFetchLiveDataList = () => { handleFetchLiveDataList = () => {
const { liveQuery, liveSize } = this.state const { liveQuery, liveSize } = this.state;
const _data = [...this.props.data] const _data = [...this.props.data];
let currentLiveCourseListData = [] let currentLiveCourseListData = [];
_data.map((item) => { _data.map((item) => {
item.courseList.map((childItem, childIndex) => { item.courseList.map((childItem, childIndex) => {
if (childItem.courseType === "LIVE") { if (childItem.courseType === 'LIVE') {
currentLiveCourseListData.push(childItem.courseId) currentLiveCourseListData.push(childItem.courseId);
} }
return childItem return childItem;
}) });
return item return item;
}) });
const params = { const params = {
...liveQuery, ...liveQuery,
size: liveSize, size: liveSize,
excludeCourseIdList: currentLiveCourseListData excludeCourseIdList: currentLiveCourseListData,
} };
CourseService.getLiveCloudCourseBasePage(params).then((res) => { CourseService.getLiveCloudCourseBasePage(params).then((res) => {
const { result = {} } = res const { result = {} } = res;
const { records = [], total = 0 } = result const { records = [], total = 0 } = result;
this.setState({ this.setState({
liveDataSource: records, liveDataSource: records,
liveTotalCount: Number(total), liveTotalCount: Number(total),
currentLiveCourseListData currentLiveCourseListData,
}) });
}) });
} };
// 获取视频课列表 // 获取视频课列表
handleFetchVideoDataList = () => { handleFetchVideoDataList = () => {
const { videoQuery, videoSize, videoDataSource, videoTotalCount, videoCourseDivision } = this.state const { videoQuery, videoSize, videoDataSource, videoTotalCount, videoCourseDivision } = this.state;
const _data = [...this.props.data] const _data = [...this.props.data];
let currentVideoCourseListData = [] let currentVideoCourseListData = [];
_data.map((item, index) => { _data.map((item, index) => {
item.courseList.map((childItem, childIndex) => { item.courseList.map((childItem, childIndex) => {
if (childItem.courseType === "VOICE") { if (childItem.courseType === 'VOICE') {
currentVideoCourseListData.push(childItem.courseId) currentVideoCourseListData.push(childItem.courseId);
} }
return childItem return childItem;
}) });
return item return item;
}) });
const params = { const params = {
...videoQuery[videoCourseDivision], ...videoQuery[videoCourseDivision],
size: videoSize[videoCourseDivision], size: videoSize[videoCourseDivision],
courseDivision: videoCourseDivision === "internal" ? "INTERNAL" : "EXTERNAL", courseDivision: videoCourseDivision === 'internal' ? 'INTERNAL' : 'EXTERNAL',
excludeCourseIdList: currentVideoCourseListData excludeCourseIdList: currentVideoCourseListData,
} };
CourseService.videoScheduleBasePage(params).then((res) => { CourseService.videoScheduleBasePage(params).then((res) => {
const { result = {} } = res const { result = {} } = res;
console.log("result", result) console.log('result', result);
const { records = [], total = 0 } = result const { records = [], total = 0 } = result;
this.setState({ this.setState({
videoDataSource: { videoDataSource: {
...videoDataSource, ...videoDataSource,
[videoCourseDivision]: records [videoCourseDivision]: records,
}, },
videoTotalCount: { videoTotalCount: {
...videoTotalCount, ...videoTotalCount,
[videoCourseDivision]: Number(total) [videoCourseDivision]: Number(total),
}, },
currentVideoCourseListData currentVideoCourseListData,
}) });
}) });
} };
// 获取图文课列表 // 获取图文课列表
handleFetchPictureDataList = () => { handleFetchPictureDataList = () => {
const { pictureQuery, pictureSize } = this.state const { pictureQuery, pictureSize } = this.state;
const _data = [...this.props.data] const _data = [...this.props.data];
let currentPictureCourseListData = [] let currentPictureCourseListData = [];
_data.map((item, index) => { _data.map((item, index) => {
item.courseList.map((childItem, childIndex) => { item.courseList.map((childItem, childIndex) => {
if (childItem.courseType === "PICTURE") { if (childItem.courseType === 'PICTURE') {
currentPictureCourseListData.push(childItem.courseId) currentPictureCourseListData.push(childItem.courseId);
} }
return childItem return childItem;
}) });
return item return item;
}) });
const params = { const params = {
...pictureQuery, ...pictureQuery,
size: pictureSize, size: pictureSize,
courseType: "PICTURE", courseType: 'PICTURE',
storeId: User.getStoreId(), storeId: User.getStoreId(),
excludeCourseIdList: currentPictureCourseListData excludeCourseIdList: currentPictureCourseListData,
} };
Service.Hades("public/hades/mediaCoursePage", params).then((res) => { Service.Hades('public/hades/mediaCoursePage', params).then((res) => {
const { result = {} } = res const { result = {} } = res;
const { records = [], total = 0 } = result const { records = [], total = 0 } = result;
this.setState({ this.setState({
pictureDataSource: records, pictureDataSource: records,
pictureTotalCount: Number(total), pictureTotalCount: Number(total),
currentPictureCourseListData currentPictureCourseListData,
}) });
}) });
} };
handleChangVideoCourseName = (value) => { handleChangVideoCourseName = (value) => {
const { videoQuery, videoCourseDivision, videoSearchName } = this.state const { videoQuery, videoCourseDivision, videoSearchName } = this.state;
videoQuery[videoCourseDivision].courseName = value videoQuery[videoCourseDivision].courseName = value;
videoQuery[videoCourseDivision].current = 1 videoQuery[videoCourseDivision].current = 1;
this.setState({ this.setState({
...videoQuery, ...videoQuery,
videoSearchDefalt: value, videoSearchDefalt: value,
videoSearchName: { videoSearchName: {
...videoSearchName, ...videoSearchName,
[videoCourseDivision]: value [videoCourseDivision]: value,
} },
}) });
} };
handleChangLiveCourseName = (value) => { handleChangLiveCourseName = (value) => {
const { liveQuery } = this.state const { liveQuery } = this.state;
liveQuery.courseName = value liveQuery.courseName = value;
liveQuery.current = 1 liveQuery.current = 1;
this.setState({ this.setState({
liveQuery liveQuery,
}) });
} };
handleChangPictureCourseName = (value) => { handleChangPictureCourseName = (value) => {
const { pictureQuery } = this.state const { pictureQuery } = this.state;
pictureQuery.courseName = value pictureQuery.courseName = value;
pictureQuery.current = 1 pictureQuery.current = 1;
this.setState({ this.setState({
pictureQuery pictureQuery,
}) });
} };
onShowLiveSizeChange = (current, size) => { onShowLiveSizeChange = (current, size) => {
if (current === size) { if (current === size) {
return return;
} }
this.setState( this.setState(
{ {
liveSize: size liveSize: size,
}, },
() => { () => {
this.handleFetchLiveDataList() this.handleFetchLiveDataList();
}
)
} }
);
};
onShowVideoSizeChange = (current, size) => { onShowVideoSizeChange = (current, size) => {
if (current === size) { if (current === size) {
return return;
} }
this.setState( this.setState(
{ {
videoSize: size videoSize: size,
}, },
() => { () => {
this.handleFetchLiveDataList() this.handleFetchLiveDataList();
}
)
} }
);
};
onShowPictureSizeChange = (current, size) => { onShowPictureSizeChange = (current, size) => {
if (current === size) { if (current === size) {
return return;
} }
this.setState( this.setState(
{ {
pictureSize: size pictureSize: size,
}, },
() => { () => {
this.handleFetchPictureDataList() this.handleFetchPictureDataList();
}
)
} }
);
};
// 请求表头 // 请求表头
parseLiveColumns = () => { parseLiveColumns = () => {
const columns = [ const columns = [
{ {
title: <span><span>课程信息</span><Tooltip title="仅显示未关联课程,已关联课程不支持重复选择"><i className="icon iconfont" style={{ marginLeft: '5px',cursor:'pointer',color:'#bfbfbf',fontSize:'14px',fontWeight:"400" title: (
}}>&#xe61d;</i></Tooltip></span>, <span>
<span>课程信息</span>
<Tooltip title='仅显示未关联课程,已关联课程不支持重复选择'>
<i className='icon iconfont' style={{ marginLeft: '5px', cursor: 'pointer', color: '#bfbfbf', fontSize: '14px', fontWeight: '400' }}>
&#xe61d;
</i>
</Tooltip>
</span>
),
key: 'course', key: 'course',
dataIndex: 'course', dataIndex: 'course',
width:'40%', width: '40%',
render: (val, record) => { render: (val, record) => {
let hasCover = false let hasCover = false;
return ( return (
<div className='course-info'> <div className='course-info'>
{record.courseMediaVOS.map((item) => { {record.courseMediaVOS.map((item) => {
if (item.contentType === "COVER") { if (item.contentType === 'COVER') {
hasCover = true hasCover = true;
return <img className='course-cover' src={item.mediaUrl} alt='' /> return <img className='course-cover' src={item.mediaUrl} alt='' />;
} }
return null return null;
})} })}
<If condition={!hasCover}> <If condition={!hasCover}>
<img className='course-cover' src={"https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png"} alt='' /> <img className='course-cover' src={'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'} alt='' />
</If> </If>
<div> <div>
...@@ -316,35 +325,35 @@ class SelectOperatorModal extends React.Component { ...@@ -316,35 +325,35 @@ class SelectOperatorModal extends React.Component {
</span> </span>
</div> </div>
</div> </div>
) );
} },
}, },
{ {
title: "上课时间", title: '上课时间',
key: "courseTime", key: 'courseTime',
dataIndex: "courseTime", dataIndex: 'courseTime',
width: "40%", width: '40%',
render: (val, record) => { render: (val, record) => {
return ( return (
<div> <div>
<div>{formatDate("YYYY-MM-DD", record.startTime)}</div> <div>{formatDate('YYYY-MM-DD', record.startTime)}</div>
<div> <div>
{formatDate("H:i", record.startTime)}~{formatDate("H:i", record.endTime)} {formatDate('H:i', record.startTime)}~{formatDate('H:i', record.endTime)}
</div> </div>
</div> </div>
) );
} },
}, },
{ {
title: "学院展示", title: '学院展示',
key: "shelfState", key: 'shelfState',
dataIndex: "shelfState", dataIndex: 'shelfState',
width: "20%", width: '20%',
render: (val, record) => { render: (val, record) => {
return ( return (
<span> <span>
<Choose> <Choose>
<When condition={record.shelfState === "YES"}> <When condition={record.shelfState === 'YES'}>
<span>开启</span> <span>开启</span>
</When> </When>
<Otherwise> <Otherwise>
...@@ -352,24 +361,33 @@ class SelectOperatorModal extends React.Component { ...@@ -352,24 +361,33 @@ class SelectOperatorModal extends React.Component {
</Otherwise> </Otherwise>
</Choose> </Choose>
</span> </span>
) );
} },
} },
] ];
return columns return columns;
} };
// 请求表头 // 请求表头
parseVideoColumns = () => { parseVideoColumns = () => {
const { videoCourseDivision } = this.state const { videoCourseDivision } = this.state;
const columns = [ const columns = [
{ {
title: <span><span>课程信息</span><Tooltip title="仅显示未关联课程,已关联课程不支持重复选择"><i className="icon iconfont" style={{ marginLeft: '5px',cursor:'pointer',color:'#bfbfbf',fontSize:'14px',fontWeight:"400"}}>&#xe61d;</i></Tooltip></span>, title: (
<span>
<span>课程信息</span>
<Tooltip title='仅显示未关联课程,已关联课程不支持重复选择'>
<i className='icon iconfont' style={{ marginLeft: '5px', cursor: 'pointer', color: '#bfbfbf', fontSize: '14px', fontWeight: '400' }}>
&#xe61d;
</i>
</Tooltip>
</span>
),
key: 'course', key: 'course',
dataIndex: 'course', dataIndex: 'course',
width:'60%', width: '60%',
render: (val, record) => { render: (val, record) => {
const { coverUrl, scheduleVideoUrl } = record const { coverUrl, scheduleVideoUrl } = record;
return ( return (
<div className='course-info'> <div className='course-info'>
{/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */} {/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */}
...@@ -377,242 +395,251 @@ class SelectOperatorModal extends React.Component { ...@@ -377,242 +395,251 @@ class SelectOperatorModal extends React.Component {
className='course-cover' className='course-cover'
src={ src={
coverUrl || coverUrl ||
(videoCourseDivision === "internal" (videoCourseDivision === 'internal'
? `${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast` ? `${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast`
: "https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png") : 'https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png')
} }
alt='' alt=''
/> />
<div className='course-name'>{record.courseName}</div> <div className='course-name'>{record.courseName}</div>
</div> </div>
) );
} },
}, },
{ {
title: "课程时长", title: '课程时长',
key: "courseTime", key: 'courseTime',
dataIndex: "courseTime", dataIndex: 'courseTime',
width: "20%", width: '20%',
render: (val, record) => { render: (val, record) => {
return <span className='course-status'>{dealTimeDuration(record.videoDuration)}</span> return <span className='course-status'>{dealTimeDuration(record.videoDuration)}</span>;
} },
}, },
{ {
title: "学院展示", title: '学院展示',
key: "shelfState", key: 'shelfState',
dataIndex: "shelfState", dataIndex: 'shelfState',
width: "20%", width: '20%',
render: (val, record) => { render: (val, record) => {
return ( return (
<Choose> <Choose>
<When condition={record.shelfState === "YES"}> <When condition={record.shelfState === 'YES'}>
<span>开启</span> <span>开启</span>
</When> </When>
<Otherwise> <Otherwise>
<span>关闭</span> <span>关闭</span>
</Otherwise> </Otherwise>
</Choose> </Choose>
) );
} },
} },
] ];
return columns return columns;
} };
// 请求表头 // 请求表头
parsePictureColumns = () => { parsePictureColumns = () => {
const columns = [ const columns = [
{ {
title: <span><span>课程信息</span><Tooltip title="仅显示未关联课程,已关联课程不支持重复选择"><i className="icon iconfont" style={{ marginLeft: '5px',cursor:'pointer',color:'#bfbfbf',fontSize:'14px',fontWeight:"400"}}>&#xe61d;</i></Tooltip></span>, title: (
<span>
<span>课程信息</span>
<Tooltip title='仅显示未关联课程,已关联课程不支持重复选择'>
<i className='icon iconfont' style={{ marginLeft: '5px', cursor: 'pointer', color: '#bfbfbf', fontSize: '14px', fontWeight: '400' }}>
&#xe61d;
</i>
</Tooltip>
</span>
),
key: 'course', key: 'course',
dataIndex: 'course', dataIndex: 'course',
width:'55%', width: '55%',
render: (val, record) => { render: (val, record) => {
const { coverUrl } = record const { coverUrl } = record;
return ( return (
<div className='course-info'> <div className='course-info'>
<img className='course-cover' src={coverUrl || "https://image.xiaomaiketang.com/xm/wFnpZtp2yB.png"} alt='' /> <img className='course-cover' src={coverUrl || 'https://image.xiaomaiketang.com/xm/wFnpZtp2yB.png'} alt='' />
<div className='course-name'>{record.courseName}</div> <div className='course-name'>{record.courseName}</div>
</div> </div>
) );
} },
}, },
{ {
title: "更新时间", title: '更新时间',
key: "updated", key: 'updated',
dataIndex: "updated", dataIndex: 'updated',
width: "25%", width: '25%',
render: (val, record) => { render: (val, record) => {
return <span className='course-status'>{formatDate("YYYY-MM-DD", record.updated)}</span> return <span className='course-status'>{formatDate('YYYY-MM-DD', record.updated)}</span>;
} },
}, },
{ {
title: "学院展示", title: '学院展示',
key: "shelfState", key: 'shelfState',
dataIndex: "shelfState", dataIndex: 'shelfState',
width: "20%", width: '20%',
render: (val, record) => { render: (val, record) => {
return <span>{record.shelfState === "YES" ? "开启" : "关闭"}</span> return <span>{record.shelfState === 'YES' ? '开启' : '关闭'}</span>;
} },
} },
] ];
return columns return columns;
} };
selectLiveList = (record, selected) => { selectLiveList = (record, selected) => {
const { selectVideo, currentTaskCourseData, selectLive, selectPicture } = this.state const { selectVideo, currentTaskCourseData, selectLive, selectPicture } = this.state;
let _list = [] let _list = [];
if (selected || !_.find(selectLive, (item) => item.liveCourseId === record.liveCourseId)) { if (selected || !_.find(selectLive, (item) => item.liveCourseId === record.liveCourseId)) {
_list = _.uniq(selectLive.concat([record]), false, (item) => item.liveCourseId) _list = _.uniq(selectLive.concat([record]), false, (item) => item.liveCourseId);
} else { } else {
_list = _.reject(selectLive, (item) => item.liveCourseId === record.liveCourseId) _list = _.reject(selectLive, (item) => item.liveCourseId === record.liveCourseId);
} }
if (_list.length + currentTaskCourseData.length + selectVideo.length + selectPicture.length > 20) { if (_list.length + currentTaskCourseData.length + selectVideo.length + selectPicture.length > 20) {
message.warning("无法继续选择,一个任务最多关联20个课程") message.warning('无法继续选择,一个任务最多关联20个课程');
return return;
}
this.setState({ selectLive: _list })
} }
this.setState({ selectLive: _list });
};
selectVideoList = (record, selected) => { selectVideoList = (record, selected) => {
const { selectVideo, currentTaskCourseData, selectLive, selectPicture, videoCourseDivision } = this.state const { selectVideo, currentTaskCourseData, selectLive, selectPicture, videoCourseDivision } = this.state;
let { [videoCourseDivision]: selectList } = selectVideo let { [videoCourseDivision]: selectList } = selectVideo;
let _list = [] let _list = [];
if (selected || !_.find(selectList, (item) => item.id === record.id)) { if (selected || !_.find(selectList, (item) => item.id === record.id)) {
_list = _.uniq(selectList.concat([record]), false, (item) => item.id) _list = _.uniq(selectList.concat([record]), false, (item) => item.id);
} else { } else {
_list = _.reject(selectList, (item) => item.id === record.id) _list = _.reject(selectList, (item) => item.id === record.id);
} }
if (_list.length + currentTaskCourseData.length + selectLive.length + selectPicture.length > 20) { if (_list.length + currentTaskCourseData.length + selectLive.length + selectPicture.length > 20) {
message.warning("无法继续选择,一个任务最多关联20个课程") message.warning('无法继续选择,一个任务最多关联20个课程');
return return;
} }
this.setState({ this.setState({
selectVideo: { selectVideo: {
...selectVideo, ...selectVideo,
[videoCourseDivision]: _list [videoCourseDivision]: _list,
} },
}) });
} };
selectPictureList = (record, selected) => { selectPictureList = (record, selected) => {
const { selectVideo, currentTaskCourseData, selectLive, selectPicture } = this.state const { selectVideo, currentTaskCourseData, selectLive, selectPicture } = this.state;
let _list = [] let _list = [];
if (selected || !_.find(selectPicture, (item) => item.id === record.id)) { if (selected || !_.find(selectPicture, (item) => item.id === record.id)) {
_list = _.uniq(selectPicture.concat([record]), false, (item) => item.id) _list = _.uniq(selectPicture.concat([record]), false, (item) => item.id);
} else { } else {
_list = _.reject(selectPicture, (item) => item.id === record.id) _list = _.reject(selectPicture, (item) => item.id === record.id);
} }
if (_list.length + currentTaskCourseData.length + selectLive.length + selectVideo.length > 20) { if (_list.length + currentTaskCourseData.length + selectLive.length + selectVideo.length > 20) {
message.warning("无法继续选择,一个任务最多关联20个课程") message.warning('无法继续选择,一个任务最多关联20个课程');
return return;
}
this.setState({ selectPicture: _list })
} }
this.setState({ selectPicture: _list });
};
clearSelectCourse = () => { clearSelectCourse = () => {
this.setState({ this.setState({
selectLive: [], selectLive: [],
selectVideo: { selectVideo: {
internal: [], internal: [],
external: [] external: [],
}, },
selectPicture: [] selectPicture: [],
}) });
} };
handleSelectVideo = (selectVideo) => { handleSelectVideo = (selectVideo) => {
return selectVideo.map((item) => { return selectVideo.map((item) => {
let _item = {} let _item = {};
_item.courseId = item.id _item.courseId = item.id;
_item.courseType = "VOICE" _item.courseType = 'VOICE';
_item.courseName = item.courseName _item.courseName = item.courseName;
return _item return _item;
}) });
} };
handleSelectLive = (selectLive) => { handleSelectLive = (selectLive) => {
return selectLive.map((item, index) => { return selectLive.map((item, index) => {
let _item = {} let _item = {};
_item.courseId = item.liveCourseId _item.courseId = item.liveCourseId;
_item.courseType = "LIVE" _item.courseType = 'LIVE';
_item.courseName = item.courseName _item.courseName = item.courseName;
_item.courseState = item.courseState _item.courseState = item.courseState;
return _item return _item;
}) });
} };
videoCourseDivisionChange = (e) => { videoCourseDivisionChange = (e) => {
const { videoSearchName } = this.state const { videoSearchName } = this.state;
this.setState( this.setState(
{ {
videoCourseDivision: e.target.value, videoCourseDivision: e.target.value,
videoSearchDefalt: videoSearchName[e.target.value] videoSearchDefalt: videoSearchName[e.target.value],
}, },
() => { () => {
this.handleFetchVideoDataList() this.handleFetchVideoDataList();
}
)
} }
);
};
handleSelectPicture = (selectPicture) => { handleSelectPicture = (selectPicture) => {
return selectPicture.map((item, index) => { return selectPicture.map((item, index) => {
let _item = {} let _item = {};
_item.courseId = item.id _item.courseId = item.id;
_item.courseType = "PICTURE" _item.courseType = 'PICTURE';
_item.courseName = item.courseName _item.courseName = item.courseName;
return _item return _item;
}) });
} };
renderFooter = () => { renderFooter = () => {
const { activeKey } = this.state const { activeKey } = this.state;
let href = "" let href = '';
switch (activeKey) { switch (activeKey) {
case "live": case 'live':
href = ( href = (
<a <a
target='_blank' target='_blank'
rel='noopener noreferrer' rel='noopener noreferrer'
className='link-create-course' className='link-create-course'
href={window.location.origin + window.location.pathname + "#/create-live-course?type=add"} href={window.location.origin + window.location.pathname + '#/create-live-course?type=add'}
onClick={this.props.onClose}> onClick={this.props.onClose}>
没有找到需要的直播课?<span>去创建</span> 没有找到需要的直播课?<span>去创建</span>
</a> </a>
) );
break break;
case "video": case 'video':
href = ( href = (
<a <a
target='_blank' target='_blank'
rel='noopener noreferrer' rel='noopener noreferrer'
className='link-create-course' className='link-create-course'
href={window.location.origin + window.location.pathname + "#/create-video-course?type=add"} href={window.location.origin + window.location.pathname + '#/create-video-course?type=add'}
onClick={this.props.onClose}> onClick={this.props.onClose}>
没有找到需要的视频课?<span>去创建</span> 没有找到需要的视频课?<span>去创建</span>
</a> </a>
) );
break break;
case "picture": case 'picture':
href = ( href = (
<a <a
target='_blank' target='_blank'
rel='noopener noreferrer' rel='noopener noreferrer'
className='link-create-course' className='link-create-course'
href={window.location.origin + window.location.pathname + "#/create-graphics-course?type=add"} href={window.location.origin + window.location.pathname + '#/create-graphics-course?type=add'}
onClick={this.props.onClose}> onClick={this.props.onClose}>
没有找到需要的图文课?<span>去创建</span> 没有找到需要的图文课?<span>去创建</span>
</a> </a>
) );
break break;
default: default:
break break;
}
return href
} }
return href;
};
render() { render() {
const { visible } = this.props const { visible } = this.props;
const { const {
liveDataSource, liveDataSource,
liveSize, liveSize,
...@@ -632,8 +659,8 @@ class SelectOperatorModal extends React.Component { ...@@ -632,8 +659,8 @@ class SelectOperatorModal extends React.Component {
pictureQuery, pictureQuery,
pictureTotalCount, pictureTotalCount,
videoCourseDivision videoCourseDivision,
} = this.state } = this.state;
return ( return (
<Modal <Modal
title='关联课程' title='关联课程'
...@@ -649,7 +676,7 @@ class SelectOperatorModal extends React.Component { ...@@ -649,7 +676,7 @@ class SelectOperatorModal extends React.Component {
this.renderFooter(), this.renderFooter(),
<Button <Button
onClick={() => { onClick={() => {
this.props.onClose() this.props.onClose();
}}> }}>
取消 取消
</Button>, </Button>,
...@@ -660,18 +687,18 @@ class SelectOperatorModal extends React.Component { ...@@ -660,18 +687,18 @@ class SelectOperatorModal extends React.Component {
...this.handleSelectVideo(selectVideo.internal), ...this.handleSelectVideo(selectVideo.internal),
...this.handleSelectVideo(selectVideo.external), ...this.handleSelectVideo(selectVideo.external),
...this.handleSelectLive(selectLive), ...this.handleSelectLive(selectLive),
...this.handleSelectPicture(selectPicture) ...this.handleSelectPicture(selectPicture),
]) ])
}> }>
确定 确定
</Button> </Button>,
]}> ]}>
<div> <div>
<Tabs <Tabs
type='line' type='line'
defaultActiveKey='live' defaultActiveKey='live'
onChange={(activeKey) => { onChange={(activeKey) => {
this.setState({ activeKey: activeKey }) this.setState({ activeKey: activeKey });
}}> }}>
<TabPane tab='直播课' key='live'> <TabPane tab='直播课' key='live'>
<div className='search-container'> <div className='search-container'>
...@@ -680,10 +707,10 @@ class SelectOperatorModal extends React.Component { ...@@ -680,10 +707,10 @@ class SelectOperatorModal extends React.Component {
placeholder='搜索课程名称' placeholder='搜索课程名称'
style={{ width: 200 }} style={{ width: 200 }}
onChange={(e) => { onChange={(e) => {
this.handleChangLiveCourseName(e.target.value) this.handleChangLiveCourseName(e.target.value);
}} }}
onSearch={() => { onSearch={() => {
this.handleFetchLiveDataList() this.handleFetchLiveDataList();
}} }}
/> />
</div> </div>
...@@ -707,32 +734,36 @@ class SelectOperatorModal extends React.Component { ...@@ -707,32 +734,36 @@ class SelectOperatorModal extends React.Component {
</div> </div>
</div> </div>
<div> <div>
<Table <XMTable
renderEmpty={{
image: college,
description: '暂无数据',
}}
rowKey={(record) => record.liveCourseId} rowKey={(record) => record.liveCourseId}
dataSource={liveDataSource} dataSource={liveDataSource}
columns={this.parseLiveColumns()} columns={this.parseLiveColumns()}
pagination={false} pagination={false}
bordered bordered
rowSelection={{ rowSelection={{
type: "checkbox", type: 'checkbox',
selectedRowKeys: _.pluck(selectLive, "liveCourseId"), selectedRowKeys: _.pluck(selectLive, 'liveCourseId'),
onSelect: (record, selected) => { onSelect: (record, selected) => {
this.selectLiveList(record, selected) this.selectLiveList(record, selected);
}, },
onSelectAll: (selected, _selectedRows, changeRows) => { onSelectAll: (selected, _selectedRows, changeRows) => {
let _list = [] let _list = [];
if (selected) { if (selected) {
_list = _.uniq(selectLive.concat(changeRows), false, (item) => item.liveCourseId) _list = _.uniq(selectLive.concat(changeRows), false, (item) => item.liveCourseId);
} else { } else {
_list = _.reject(selectLive, (item) => _.find(changeRows, (data) => data.liveCourseId === item.liveCourseId)) _list = _.reject(selectLive, (item) => _.find(changeRows, (data) => data.liveCourseId === item.liveCourseId));
} }
if (_list.length + currentTaskCourseData.length + selectVideo.length + selectPicture.length > 20) { if (_list.length + currentTaskCourseData.length + selectVideo.length + selectPicture.length > 20) {
message.warning("无法继续选择,一个任务最多关联20个课程") message.warning('无法继续选择,一个任务最多关联20个课程');
const extraLength = _list.length + currentTaskCourseData.length + selectVideo.length + selectPicture.length - 20 const extraLength = _list.length + currentTaskCourseData.length + selectVideo.length + selectPicture.length - 20;
_list.splice(_list.length - extraLength, extraLength) _list.splice(_list.length - extraLength, extraLength);
}
this.setState({ selectLive: _list })
} }
this.setState({ selectLive: _list });
},
}} }}
/> />
{liveDataSource.length > 0 && ( {liveDataSource.length > 0 && (
...@@ -743,15 +774,15 @@ class SelectOperatorModal extends React.Component { ...@@ -743,15 +774,15 @@ class SelectOperatorModal extends React.Component {
size='small' size='small'
total={liveTotalCount} total={liveTotalCount}
toPage={(page) => { toPage={(page) => {
const _query = { ...liveQuery, current: page + 1 } const _query = { ...liveQuery, current: page + 1 };
this.setState( this.setState(
{ {
liveQuery: _query liveQuery: _query,
}, },
() => { () => {
this.handleFetchLiveDataList() this.handleFetchLiveDataList();
} }
) );
}} }}
onShowSizeChange={this.onShowLiveSizeChange} onShowSizeChange={this.onShowLiveSizeChange}
/> />
...@@ -772,10 +803,10 @@ class SelectOperatorModal extends React.Component { ...@@ -772,10 +803,10 @@ class SelectOperatorModal extends React.Component {
placeholder='搜索课程名称' placeholder='搜索课程名称'
style={{ width: 200 }} style={{ width: 200 }}
onChange={(e) => { onChange={(e) => {
this.handleChangVideoCourseName(e.target.value) this.handleChangVideoCourseName(e.target.value);
}} }}
onSearch={() => { onSearch={() => {
this.handleFetchVideoDataList() this.handleFetchVideoDataList();
}} }}
/> />
</div> </div>
...@@ -798,37 +829,41 @@ class SelectOperatorModal extends React.Component { ...@@ -798,37 +829,41 @@ class SelectOperatorModal extends React.Component {
</div> </div>
</div> </div>
<div> <div>
<Table <XMTable
renderEmpty={{
image: college,
description: '暂无数据',
}}
rowKey={(record) => record.id} rowKey={(record) => record.id}
dataSource={videoDataSource[videoCourseDivision]} dataSource={videoDataSource[videoCourseDivision]}
columns={this.parseVideoColumns()} columns={this.parseVideoColumns()}
pagination={false} pagination={false}
bordered bordered
rowSelection={{ rowSelection={{
type: "checkbox", type: 'checkbox',
selectedRowKeys: _.pluck(selectVideo[videoCourseDivision], "id"), selectedRowKeys: _.pluck(selectVideo[videoCourseDivision], 'id'),
onSelect: (record, selected) => { onSelect: (record, selected) => {
this.selectVideoList(record, selected) this.selectVideoList(record, selected);
}, },
onSelectAll: (selected, _selectedRows, changeRows) => { onSelectAll: (selected, _selectedRows, changeRows) => {
let _list = [] let _list = [];
if (selected) { if (selected) {
_list = _.uniq(selectVideo[videoCourseDivision].concat(changeRows), false, (item) => item.id) _list = _.uniq(selectVideo[videoCourseDivision].concat(changeRows), false, (item) => item.id);
} else { } else {
_list = _.reject(selectVideo[videoCourseDivision], (item) => _.find(changeRows, (data) => data.id === item.id)) _list = _.reject(selectVideo[videoCourseDivision], (item) => _.find(changeRows, (data) => data.id === item.id));
} }
if (_list.length + currentTaskCourseData.length + selectLive.length + selectPicture.length > 20) { if (_list.length + currentTaskCourseData.length + selectLive.length + selectPicture.length > 20) {
message.warning("无法继续选择,一个任务最多关联20个课程") message.warning('无法继续选择,一个任务最多关联20个课程');
const extraLength = _list.length + currentTaskCourseData.length + selectLive.length + selectPicture.length - 20 const extraLength = _list.length + currentTaskCourseData.length + selectLive.length + selectPicture.length - 20;
_list.splice(_list.length - extraLength, extraLength) _list.splice(_list.length - extraLength, extraLength);
} }
this.setState({ this.setState({
selectVideo: { selectVideo: {
...selectVideo, ...selectVideo,
[videoCourseDivision]: _list [videoCourseDivision]: _list,
} },
}) });
} },
}} }}
/> />
{videoDataSource[videoCourseDivision].length > 0 && ( {videoDataSource[videoCourseDivision].length > 0 && (
...@@ -839,19 +874,19 @@ class SelectOperatorModal extends React.Component { ...@@ -839,19 +874,19 @@ class SelectOperatorModal extends React.Component {
size='small' size='small'
total={videoTotalCount[videoCourseDivision]} total={videoTotalCount[videoCourseDivision]}
toPage={(page) => { toPage={(page) => {
const _query = { ...videoQuery[videoCourseDivision], current: page + 1 } const _query = { ...videoQuery[videoCourseDivision], current: page + 1 };
this.setState( this.setState(
{ {
videoQuery: { videoQuery: {
...videoQuery, ...videoQuery,
[videoCourseDivision]: _query [videoCourseDivision]: _query,
} },
}, },
() => { () => {
this.handleFetchVideoDataList() this.handleFetchVideoDataList();
} }
) );
}} }}
onShowSizeChange={this.onShowVideoSizeChange} onShowSizeChange={this.onShowVideoSizeChange}
/> />
...@@ -866,10 +901,10 @@ class SelectOperatorModal extends React.Component { ...@@ -866,10 +901,10 @@ class SelectOperatorModal extends React.Component {
placeholder='搜索课程名称' placeholder='搜索课程名称'
style={{ width: 200 }} style={{ width: 200 }}
onChange={(e) => { onChange={(e) => {
this.handleChangPictureCourseName(e.target.value) this.handleChangPictureCourseName(e.target.value);
}} }}
onSearch={() => { onSearch={() => {
this.handleFetchPictureDataList() this.handleFetchPictureDataList();
}} }}
/> />
</div> </div>
...@@ -893,32 +928,36 @@ class SelectOperatorModal extends React.Component { ...@@ -893,32 +928,36 @@ class SelectOperatorModal extends React.Component {
</div> </div>
</div> </div>
<div> <div>
<Table <XMTable
renderEmpty={{
image: college,
description: '暂无数据',
}}
rowKey={(record) => record.id} rowKey={(record) => record.id}
dataSource={pictureDataSource} dataSource={pictureDataSource}
columns={this.parsePictureColumns()} columns={this.parsePictureColumns()}
pagination={false} pagination={false}
bordered bordered
rowSelection={{ rowSelection={{
type: "checkbox", type: 'checkbox',
selectedRowKeys: _.pluck(selectPicture, "id"), selectedRowKeys: _.pluck(selectPicture, 'id'),
onSelect: (record, selected) => { onSelect: (record, selected) => {
this.selectPictureList(record, selected) this.selectPictureList(record, selected);
}, },
onSelectAll: (selected, _selectedRows, changeRows) => { onSelectAll: (selected, _selectedRows, changeRows) => {
let _list = [] let _list = [];
if (selected) { if (selected) {
_list = _.uniq(selectPicture.concat(changeRows), false, (item) => item.id) _list = _.uniq(selectPicture.concat(changeRows), false, (item) => item.id);
} else { } else {
_list = _.reject(selectPicture, (item) => _.find(changeRows, (data) => data.id === item.id)) _list = _.reject(selectPicture, (item) => _.find(changeRows, (data) => data.id === item.id));
} }
if (_list.length + currentTaskCourseData.length + selectVideo.length + selectLive.length > 20) { if (_list.length + currentTaskCourseData.length + selectVideo.length + selectLive.length > 20) {
message.warning("无法继续选择,一个任务最多关联20个课程") message.warning('无法继续选择,一个任务最多关联20个课程');
const extraLength = _list.length + currentTaskCourseData.length + selectVideo.length + selectLive.length - 20 const extraLength = _list.length + currentTaskCourseData.length + selectVideo.length + selectLive.length - 20;
_list.splice(_list.length - extraLength, extraLength) _list.splice(_list.length - extraLength, extraLength);
}
this.setState({ selectPicture: _list })
} }
this.setState({ selectPicture: _list });
},
}} }}
/> />
{pictureDataSource.length > 0 && ( {pictureDataSource.length > 0 && (
...@@ -929,15 +968,15 @@ class SelectOperatorModal extends React.Component { ...@@ -929,15 +968,15 @@ class SelectOperatorModal extends React.Component {
size='small' size='small'
total={pictureTotalCount} total={pictureTotalCount}
toPage={(page) => { toPage={(page) => {
const _query = { ...pictureQuery, current: page + 1 } const _query = { ...pictureQuery, current: page + 1 };
this.setState( this.setState(
{ {
pictureQuery: _query pictureQuery: _query,
}, },
() => { () => {
this.handleFetchPictureDataList() this.handleFetchPictureDataList();
} }
) );
}} }}
onShowSizeChange={this.onShowPictureSizeChange} onShowSizeChange={this.onShowPictureSizeChange}
/> />
...@@ -948,8 +987,8 @@ class SelectOperatorModal extends React.Component { ...@@ -948,8 +987,8 @@ class SelectOperatorModal extends React.Component {
</Tabs> </Tabs>
</div> </div>
</Modal> </Modal>
) );
} }
} }
export default SelectOperatorModal export default SelectOperatorModal;
/*
* @Author: 吴文洁
* @Date: 2020-06-09 10:47:51
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-07-23 09:33:09
* @Description: 文件夹列表
*/
import React from 'react';
import { Table, Menu, Dropdown, Upload, Modal, message, Tooltip, Icon } from 'antd';
import { PageControl } from '@/components';
import DefaultIcon from '@/modules/common/DefaultIcon';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { FileTypeIcon, SupportFileType, DEFAULT_SIZE_UNIT } from "@/common/constants/academic/lessonEnum";
import ScanFileModal from '../modal/ScanFileModal';
import CreateFolderModal from '../modal/CreateFolderModal';
import UploadProgressModal from '../modal/UploadProgressModal';
import SelectPrepareFileModal from '../modal/SelectPrepareFileModal';
const DEL_FOLDER_URL_MAP = {
'MYSELF': 'public/apollo/delFolder',
'COMMON': 'public/apollo/delCommonFolder'
}
let count = 0;
class FolderList extends React.Component {
constructor(props) {
super(props);
this.state = {
localFileList: [], // 本地文件列表(待上传)
currentFolder: {}, // 当前文件/文件夹(操作列表中的文件/文件夹的时候需要用到)
uploadFolderPath: {}, // 上传文件的目录,防止中途切换文件夹
renameModalData: {}, // 重命名弹窗
scanFileModal: null, // 预览文件弹窗
showUploadModal: false, // 上传进度弹窗,
nonCompliantFileList: []
}
}
componentWillReceiveProps(nextProps) {
const { folderPathList } = nextProps
const currentFolder = folderPathList[folderPathList.length - 1];
this.setState({
currentFolder
})
}
//预览文件
handleSelect = (folder) => {
// 只有文件才有预览功能
if (folder.folderType === 'FOLDER') {
this.handleSelectFolder(folder);
} else {
this.handleScanFile(folder);
}
}
// 埋点
handleDataDot = (folderFormat) => {
switch (folderFormat) {
case 'PDF':
window.WEBTRACING('resource_disk_file_preview_pdf', '资料云盘_点击预览_pdf');
break;
case 'WORD':
case 'DOCX':
case 'DOC':
window.WEBTRACING('resource_disk_file_preview_word', '资料云盘_点击预览_word');
break;
case 'EXCEL':
window.WEBTRACING('resource_disk_file_preview_excel', '资料云盘_点击预览_excel');
break;
case 'PPT':
case 'PPTX':
window.WEBTRACING('resource_disk_file_preview_ppt', '资料云盘_点击预览_ppt');
break;
default:
break;
}
}
// 预览文件
handleScanFile = (folder) => {
const { folderFormat, folderSize, ossUrl } = folder;
switch (folderFormat) {
case 'PDF':
window.open(ossUrl, "_blank");
break;
case "WORD":
case "DOCX":
case "DOC":
case "EXCEL":
case "PPT":
case "PPTX":
case "PDF":
if ((folderFormat === 'PPT' || folderFormat === 'PPTX' ||
folderFormat === 'DOCX' || folderFormat === 'WORD' ||
folderFormat === 'DOC') && folderSize > 10 * DEFAULT_SIZE_UNIT) {
Modal.confirm({
title: '抱歉,不能在线预览',
content: '由于文件较大,不支持在线预览,请下载后再查看',
icon: <QuestionCircleOutlined />,
okText:"下载",
onOk:() => {
const a = document.createElement('a');
a.href = ossUrl;
a.click();
}
});
break;
}
if (folderFormat === 'EXCEL' && folderSize > 5 * DEFAULT_SIZE_UNIT) {
Modal.confirm({
title: '抱歉,不能在线预览',
content: '由于文件较大,不支持在线预览,请下载后再查看',
icon: <QuestionCircleOutlined />,
okText:"下载",
onOk:() => {
const a = document.createElement('a');
a.href = ossUrl;
a.click();
}
});
break;
}
const prefixUrl = "https://view.officeapps.live.com/op/view.aspx?src=";
const scanUrl = `${prefixUrl}${encodeURIComponent(ossUrl)}`
window.open(scanUrl, "_blank");
break;
default:
const scanFileModal = <ScanFileModal
fileType={folderFormat}
item={folder}
close={() => {
this.setState({ scanFileModal: null })
}}
/>
this.setState({ scanFileModal });
break;
}
// 预览文件埋点
this.handleDataDot(folderFormat);
}
// 选择文件夹
handleSelectFolder = (folder) => {
const { folderPathList, showResultPage, currentRootDisk } = this.props;
// 判断是否是员工文件的根目录
const employeeDisk = currentRootDisk.disk === 'EMPLOYEE' && folderPathList.length === 1;
if (showResultPage) {
folderPathList.pop();
}
folderPathList.push({
id: folder.id,
folderName: folder.folderName
});
this.props.onChangeFolderPath(folderPathList);
this.props.onRefresh({
parentId: folder.id,
folderIdType: employeeDisk ? 'USER' : 'FOLDER'
});
}
// 修改文件路径
handleChangeFolderPath = (folder) => {
const { instId } = window.currentUserInstInfo;
const { id } = folder;
const { currentRootDisk } = this.props;
const params = {
id,
instId: instId || LS.get('instId'),
disk: currentRootDisk.disk,
}
axios.Apollo('public/apollo/folderPath', params).then((res) => {
const { result = [] } = res;
this.props.onChangeFolderPath(result, false);
})
}
parseColumns = () => {
const { currentRootDisk, showResultPage, folderPathList } = this.props;
const hasManagementAuthority = currentRootDisk.uploadPower;
// 判断是否是员工文件的根目录
const employeeDisk = currentRootDisk.disk === 'EMPLOYEE' && folderPathList.length === 1;
const columns = [
{
title: '名称',
key: 'folderName',
dataIndex: 'folderName',
width: '28%',
sorter: (employeeDisk || !hasManagementAuthority) ? false : true,
render: (value, record) => {
const { folderType, folderFormat } = record;
const isFolder = folderType === 'FOLDER';
let imgSrc = !isFolder ?
FileTypeIcon[folderFormat] :
'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1594871430788.png';
if (employeeDisk) {
imgSrc = 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1594871440736.png'
}
return (
<div
className="file-name"
onClick={() => this.handleSelect(record)}
>
{
<img
alt="img-src"
className="file-name__icon"
src={imgSrc}
/>
}
<span
className={`file-name__text ${!isFolder ? 'highlight' : ''}`}
>
{value}
</span>
</div>
)
}
},
{
title: '更新时间',
key: 'updated',
dataIndex: 'updated',
sorter: (employeeDisk || !hasManagementAuthority) ? false : true,
render: (value) => {
return <span>{formatDate('YYYY-MM-DD H:i', value)}</span>
}
},
{
title: '大小',
key: 'folderSize',
dataIndex: 'folderSize',
width: '10%',
sorter: (employeeDisk || !hasManagementAuthority) ? false : true,
render: (value, record) => {
const { folderType } = record;
const _fileSize = Number(value);
let _size = `${(_fileSize / DEFAULT_SIZE_UNIT).toFixed(1)}M`;
if (_fileSize < 0.1 * DEFAULT_SIZE_UNIT) {
_size = `${(_fileSize / 1024).toFixed(1)}kb`;
}
return (
<span>{folderType === 'FILE' ? _size : '-'}</span>
)
}
},
{
title: '操作',
key: 'operate',
render: (value, record) => {
if (!(currentRootDisk.disk === 'EMPLOYEE' && (folderPathList.length === 1 || record.folderType === 'FOLDER')) ||
hasManagementAuthority) {
return (
<Dropdown overlay={this.renderMenu(record)} trigger={['hover']}>
<span className="icon iconfont">&#xe756;</span>
</Dropdown>
)
}
return <span>-</span>
}
}
]
// 公共文件需要显示创建者
if (currentRootDisk.disk === 'COMMON') {
columns.splice(1, 0, {
title: '创建者',
key: 'createName',
dataIndex: 'createName'
});
}
// 搜索结果需要显示所在目录
if (showResultPage) {
columns.push({
title: '所在目录',
key: 'parentName',
dataIndex: 'parentName',
render: (value, record) => {
return <span
className="file-path"
onClick={() => this.handleChangeFolderPath(record)}
>
{value || currentRootDisk.folderName}
</span>
}
})
}
return columns;
}
// 删除文件
handleDeleteFolder = (folder) => {
const { currentRootDisk: { disk } } = this.props;
const { instId } = window.currentUserInstInfo;
// 判断此文件是否有关联的课次
axios.Apollo('public/apollo/judgeRelation', {
folderIds: [folder.id],
instId: instId || LS.get('instId')
}).then((res) => {
// 如果有关联的文件,二次弹窗确认
const hasRelative = !!res.result;
Modal.confirm({
title: '确认删除所选的文件吗?',
content: hasRelative ? '此文件已关联了课次,删除后,学员将不能查看到此文件。' : '删除后,数据将无法恢复。',
icon:<span className="icon iconfont default-confirm-icon">&#xe839; </span>,
okType: 'danger',
onOk: () => {
const { currentFolder } = this.state;
axios.Apollo(DEL_FOLDER_URL_MAP[disk], {
ids: [folder.id],
instId: instId || LS.get('instId')
}).then(() => {
message.success('删除成功');
this.props.onRefresh({ parentId: currentFolder.id || null });
})
}
});
})
}
// 重命名
handleRename = (folder) => {
this.setState({
renameModalData: {
visible: true,
id: folder.id,
folderName: folder.folderName,
}
});
}
// 重命名完成或者取消重命名之后隐藏重命名弹窗
handleRenameDone = (folderName) => {
const { renameModalData, currentFolder } = this.state;
// 名称未修改不发送请求
if (folderName === renameModalData.folderName) {
this.setState({ renameModalData: {} });
return;
}
// 判断是否有同名文件
this.handleGetSameNameFiles(folderName).then((res) => {
if (res) {
message.warning('此目录下已存在同名文件');
return;
}
axios.Apollo('public/apollo/renameFolder', {
id: renameModalData.id,
name: folderName
}).then(() => {
message.success('重命名成功');
this.setState({ renameModalData: {} });
this.props.onRefresh({ parentId: currentFolder.id || null });
})
});
}
// 获取同名文件
handleGetSameNameFiles = async (folderName) => {
const { currentRootDisk, folderPathList } = this.props;
const currentFolder = folderPathList[folderPathList.length - 1];
const { instId } = window.currentUserInstInfo;
const params = {
name: folderName,
disk: currentRootDisk.disk,
parentId: currentFolder.id,
folderType: 'FOLDER',
instId: instId || LS.get('instId')
}
const res = await axios.Apollo('public/apollo/sameNameFile', params);
const { result } = res;
return !!result || result && Object.keys(result).length;
}
// 显示移动文件弹窗
handleShowSelectFileModal = (file) => {
this.setState({
currentFile: file,
showSelectFileModal: true
});
}
getBlob = (url) => {
return new Promise((resolve) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.responseType = 'blob'
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.response)
}
}
xhr.send()
})
}
saveAs = (blob, filename) => {
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, filename)
} else {
const link = document.createElement('a')
const body = document.querySelector('body')
// 创建对象url
link.href = window.URL.createObjectURL(blob)
link.download = filename
body.appendChild(link)
link.click()
body.removeChild(link)
// 通过调用 URL.createObjectURL() 创建的 URL 对象
window.URL.revokeObjectURL(link.href)
}
}
// 下载文件
handleDownload = (folder) => {
this.getBlob(folder.ossUrl).then((blob) => {
this.saveAs(blob, folder.folderName)
})
}
handleChooseFile = async () => {
// 判断是否欠费,旗舰版用户不需要校验余额
const { instId } = window.currentUserInstInfo;
const ultimateRes = await axios.Business('public/inst/checkInstProduct', {
instId: instId || LS.get("instId"),
productCodeList: ['ULTIMATESELL', 'PIP_TO_ULTIMATE', 'HIGH_TO_ULTIMATE']
});
const { balance } = this.props;
if (balance <= 0 && !ultimateRes.result) {
this.handleShowNoticeModal();
return;
}
const dom = document.querySelector('#detailFileInput');
dom.click();
}
// 准备上传
handleUpload = (event) => {
const fileList = event.target.files;
// 判断文件的大小是否超出了限制
const nonCompliantFileList = [];
const _fileList = [...fileList];
_fileList.map((file, index) => {
let { size, type, name } = file;
if (!type) {
type = getFileTypeByName(name);
}
if (type.indexOf('image') > -1 && size > 50 * DEFAULT_SIZE_UNIT) {
nonCompliantFileList.push(file);
_fileList.splice(index, 1);
}
if (type.indexOf('audio') > -1 && size > 50 * DEFAULT_SIZE_UNIT) {
nonCompliantFileList.push(file);
_fileList.splice(index, 1);
}
if (type.indexOf('video') > -1 && size > 2000 * DEFAULT_SIZE_UNIT) {
nonCompliantFileList.push(file);
_fileList.splice(index, 1);
}
if (localFileType.indexOf(type) > -1 && size > 100 * DEFAULT_SIZE_UNIT) {
nonCompliantFileList.push(file);
_fileList.splice(index, 1);
}
file.key = count++;
});
// 不符合规则的文件列表
if (nonCompliantFileList.length > 0) {
this.setState({
nonCompliantFileList,
showNonCompliantFileModal: true,
})
} else {
this.handleShowUploadModal(_fileList);
}
// 清空文件,防止第二次无法上传同一个文件
const dom = document.querySelector('#detailFileInput');
dom.value = '';
}
// 显示上传进度弹窗
handleShowUploadModal = (fileList) => {
// 保存当前路径
const { folderPathList } = this.props;
if (fileList.length) {
this.setState({
showUploadModal: true,
localFileList: fileList,
uploadFolderPath: folderPathList[folderPathList.length - 1]
});
}
}
// 上传成功
handleUploadDone = (file, resourceId) => {
this.props.onCreate(file, resourceId);
}
// 取消上传
handleHiddenUploadModal = () => {
this.setState({
showUploadModal: false,
localFileList: []
});
}
// 余额欠费提示弹窗
handleShowNoticeModal = () => {
const { balance } = this.props;
Modal.info({
title: '无法继续操作',
content: '直播服务已升级,请联系运营老师。',
icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>
})
}
// 排序
handleChangeTable = (pagination, filters, sorter) => {
const { columnKey, order } = sorter;
let sort = null;
if (columnKey === 'folderName' && order === 'ascend') { sort = 'NAME_ASC'; }
if (columnKey === 'folderName' && order === 'descend') { sort = 'NAME_DESC'; }
if (columnKey === 'folderSize' && order === 'ascend') { sort = 'SIZE_ASC'; }
if (columnKey === 'folderSize' && order === 'descend') { sort = 'SIZE_DESC'; }
if (columnKey === 'updated' && order === 'ascend') { sort = 'UPDATE_ASC'; }
if (columnKey === 'updated' && order === 'descend') { sort = 'UPDATE_DESC'; }
const { currentFolder } = this.state;
this.props.onRefresh({
sort,
parentId: currentFolder.id || null
});
}
renderMenu = (record) => {
const { currentRootDisk } = this.props;
// 是否有编辑权限
const hasManagementAuthority = currentRootDisk.uploadPower;
const { folderType } = record;
const menu = (
<Menu>
{
folderType === 'FILE' &&
<Menu.Item key="download">
<span onClick={() => { this.handleDownload(record) }}>下载</span>
</Menu.Item>
}
{
hasManagementAuthority &&
[
<Menu.Item key="move">
<span onClick={() => this.handleShowSelectFileModal(record)}>移动</span>
</Menu.Item>,
<Menu.Item key="rename">
<span onClick={() => this.handleRename(record)}>重命名</span>
</Menu.Item>,
<Menu.Item key="delete">
<span onClick={() => this.handleDeleteFolder(record)}>删除</span>
</Menu.Item>
]
}
</Menu>
);
return menu;
}
render() {
const {
currentFolder, showScanFileModal, currentFile, renameModalData,
showSelectFileModal, showUploadModal, localFileList, currentFolderName
} = this.state;
const {
selectedFileIds, folderList, showResultPage, folderPathList,
currentRootDisk, balance, query, totalCount
} = this.props;
// 是否有编辑权限
const hasManagementAuthority = currentRootDisk.uploadPower;
// 是否已经欠费
const hasOwnedFee = balance <= 0;
return (
<div className="file-list">
{
!_.isEmpty(folderList) ?
[<Table
key="table"
rowKey={(record) => record.id}
columns={this.parseColumns()}
dataSource={folderList}
rowSelection={
hasManagementAuthority ? {
selectedRowKeys: selectedFileIds,
onChange: this.props.onChangeRow
} : null
}
pagination={false}
onChange={this.handleChangeTable}
/>,
<div className="box-footer" key="pagination">
<PageControl
current={query.current - 1}
pageSize={query.size}
total={totalCount}
showSizeChanger={true}
toPage={(page) => this.props.onChangePage('current', page + 1)}
onShowSizeChange={(current, size) => this.props.onChangePage('size', size)}
/>
</div>] :
<DefaultIcon
type='student'
title={
!showResultPage ?
<div className="desc">
<input
multiple
type="file"
style={{ display: 'none' }}
id="detailFileInput"
accept=".ppt,.pptx,.doc,.docx,.pdf,.jpg,.jpeg,.png,.mp3,.mp4,.xlsx,.xls"
onChange={(e) => this.handleUpload(e)}
/>
{
hasManagementAuthority ?
<div>你还没有上传文件,点击
<Tooltip title="支持文件类型:ppt、word、excel、pdf、jpg、mp3、mp4">
<span
className="upload-btn"
onClick={this.handleChooseFile}
>上传文件</span>
</Tooltip>
按钮
</div> :
<span>这个文件夹是空的</span>
}
</div> :
<div className="desc">搜索无结果</div>
}
/>
}
<CreateFolderModal
title="重命名"
folderName={renameModalData.folderName}
isOpen={renameModalData.visible}
onClose={() => { this.setState({ renameModalData: {} })}}
onOk={this.handleRenameDone}
/>
<UploadProgressModal
isOpen={showUploadModal}
currentFolder={currentFolder}
fileList={localFileList}
onUpload={this.handleUploadDone}
onCancel={this.handleHiddenUploadModal}
/>
<SelectPrepareFileModal
multiple={true}
isOpen={showSelectFileModal}
currentRootDisk={currentRootDisk}
onClose={() => {
this.setState({ showSelectFileModal: false });
}}
onMove={(targetFolder) => {
this.setState({ showSelectFileModal: false });
this.props.onMove(targetFolder, [currentFile.id]);
}}
/>
{ this.state.scanFileModal }
{ this.state.chargeModal }
</div>
)
}
}
export default FolderList;
\ No newline at end of file
...@@ -13,7 +13,6 @@ import { Spin, message } from 'antd'; ...@@ -13,7 +13,6 @@ import { Spin, message } from 'antd';
import User from '@/common/js/user'; import User from '@/common/js/user';
import OperateArea from './OperateArea'; import OperateArea from './OperateArea';
import FolderList from './FolderList';
import { DISK_MAP, suffixMap } from "@/common/constants/academic/lessonEnum"; import { DISK_MAP, suffixMap } from "@/common/constants/academic/lessonEnum";
...@@ -301,27 +300,6 @@ class FolderManage extends React.Component { ...@@ -301,27 +300,6 @@ class FolderManage extends React.Component {
onChangeFolderPath={this.handleChangeFolderPath} onChangeFolderPath={this.handleChangeFolderPath}
onRefresh={this.handleFetchFolderList} onRefresh={this.handleFetchFolderList}
/> />
{/* 文件夹列表 */}
<FolderList
query={query}
totalCount={totalCount}
balance={balance}
showResultPage={showResultPage}
currentRootDisk={currentRootDisk}
hasManagementAuthority={hasManagementAuthority}
folderList={folderList}
folderPathList={folderPathList}
selectedFileIds={selectedFileIds}
onChangeRow={this.handleChangeRow}
onChangeFolderPath={this.handleChangeFolderPath}
onMove={this.handleMove}
onUpload={this.handleUploadDone}
onChangePage={this.handleChangePage}
onRefresh={this.handleFetchFolderList}
/>
</div> </div>
</Spin> </Spin>
......
...@@ -21,9 +21,9 @@ import UploadProgressModal from '@/bu-components/UploadProgressModal'; ...@@ -21,9 +21,9 @@ import UploadProgressModal from '@/bu-components/UploadProgressModal';
import SelectPrepareFileModal from '@/bu-components/SelectPrepareFileModal'; import SelectPrepareFileModal from '@/bu-components/SelectPrepareFileModal';
import CopyFileModal from '@/bu-components/CopyFileModal'; import CopyFileModal from '@/bu-components/CopyFileModal';
import ManagingMembersModal from '@/bu-components/ManagingMembersModal'; import ManagingMembersModal from '@/bu-components/ManagingMembersModal';
import PreviewFileModal from '../modal/PreviewFileModal' import PreviewFileModal from '@/bu-components/PreviewFileModal';
import {YZ_APPId,YZ_PREVIEW_URL,OFFICE_PREVIEW_URL} from '@/domains/basic-domain/constants';
import BaseService from "@/domains/basic-domain/baseService";
import ScanFileModal from '../modal/ScanFileModal'; import ScanFileModal from '../modal/ScanFileModal';
import CreateFolderModal from '../modal/CreateFolderModal'; import CreateFolderModal from '../modal/CreateFolderModal';
import User from '@/common/js/user'; import User from '@/common/js/user';
...@@ -121,40 +121,40 @@ class FolderList extends React.Component { ...@@ -121,40 +121,40 @@ class FolderList extends React.Component {
break; break;
} }
} }
getYoZoSign = (data,type,folderName)=>{ // getYoZoSign = (data,type,folderName)=>{
return new Promise((resolve) => { // return new Promise((resolve) => {
let uploadParams; // let uploadParams;
if(type==="UPLOAD"){ // if(type==="UPLOAD"){
uploadParams ={ // uploadParams ={
fileUrl:data, // fileUrl:data,
instId:window.currentUserInstInfo.instId, // instId:window.currentUserInstInfo.instId,
yoZoTypeEnum:'UPLOAD' // yoZoTypeEnum:'UPLOAD'
} // }
}else{ // }else{
uploadParams ={ // uploadParams ={
fileVersionId:data, // fileVersionId:data,
instId:window.currentUserInstInfo.instId, // instId:window.currentUserInstInfo.instId,
yoZoTypeEnum:'VIEW', // yoZoTypeEnum:'VIEW',
htmlTitle:folderName // htmlTitle:folderName
} // }
} // }
Service.Apollo('public/apollo/getYoZoSign', uploadParams).then(res => { // Service.Apollo('public/apollo/getYoZoSign', uploadParams).then(res => {
const { result = [] } = res; // const { result = [] } = res;
resolve(result) // resolve(result)
}); // });
}) // })
} // }
saveYoZoFileVersionId = (fileVersionId,folderId)=>{ // saveYoZoFileVersionId = (fileVersionId,folderId)=>{
const params ={ // const params ={
fileVersionId, // fileVersionId,
folderId, // folderId,
instId: window.currentUserInstInfo.instId, // instId: window.currentUserInstInfo.instId,
} // }
Service.Apollo('public/apollo/saveYoZoFileVersionId', params).then(res => { // Service.Apollo('public/apollo/saveYoZoFileVersionId', params).then(res => {
}); // });
} // }
// 预览文件 // 预览文件
handleScanFile = async (folder) => { handleScanFile = async (folder) => {
const { folderFormat, folderSize, ossUrl,rights,fileVersionId,id,folderName} = folder; const { folderFormat, folderSize, ossUrl,rights,fileVersionId,id,folderName} = folder;
...@@ -177,24 +177,46 @@ class FolderList extends React.Component { ...@@ -177,24 +177,46 @@ class FolderList extends React.Component {
showPreviewModal:true, showPreviewModal:true,
previewStatus:'UPLOAD' previewStatus:'UPLOAD'
},async ()=>{ },async ()=>{
const uploadSign = await that.getYoZoSign(ossUrl,"UPLOAD"); const uploadParams ={
axios.post(`https://dmc.yozocloud.cn/api/file/http?fileUrl=${ossUrl}&appId=${appId}&sign=${uploadSign}`) fileUrl:ossUrl,
.then(async function (response){ instId:User.getStoreId(),
that.saveYoZoFileVersionId(response.data.data.fileVersionId,id); yoZoTypeEnum:'UPLOAD'
}
const uploadSign = await BaseService.getYoZoSign(uploadParams);
BaseService.yoZoUpload(ossUrl,YZ_APPId,uploadSign).then(async function (response){
const saveParams ={
fileVersionId:response.data.data.fileVersionId,
folderId:id,
instId:User.getStoreId(),
}
BaseService.saveYoZoFileVersionId(saveParams);
const { previewing } = that.state; const { previewing } = that.state;
if(previewing){ if(previewing){
const previewSign = await that.getYoZoSign(response.data.data.fileVersionId,"VIEW",folderName); const previewParams ={
const url = `https://eic.yozocloud.cn/api/view/file?fileVersionId=${response.data.data.fileVersionId}&appId=${appId}&sign=${previewSign}&htmlTitle=${folderName}` fileVersionId:response.data.data.fileVersionId,
instId:User.getStoreId(),
yoZoTypeEnum:'VIEW',
htmlTitle:folderName
}
const previewSign = await BaseService.getYoZoSign(previewParams);
const url = `${YZ_PREVIEW_URL}?fileVersionId=${response.data.data.fileVersionId}&appId=${YZ_APPId}&sign=${previewSign}&htmlTitle=${folderName}`
that.setState({ that.setState({
previewStatus:'UPLOAD_SUCCESS', previewStatus:'UPLOAD_SUCCESS',
url url
}) })
} }
}) })
}) })
}else{ }else{
const previewSign = await that.getYoZoSign(fileVersionId,"VIEW",folderName); const previewParams ={
const url = `http://eic.yozocloud.cn/api/view/file?fileVersionId=${fileVersionId}&appId=${appId}&sign=${previewSign}&htmlTitle=${folderName}` fileVersionId,
instId:User.getStoreId(),
yoZoTypeEnum:'VIEW',
htmlTitle:folderName
}
const previewSign = await BaseService.getYoZoSign(previewParams);
const url = `${YZ_PREVIEW_URL}?fileVersionId=${fileVersionId}&appId=${YZ_APPId}&sign=${previewSign}&htmlTitle=${folderName}`
const a = document.createElement('a'); const a = document.createElement('a');
document.body.appendChild(a); document.body.appendChild(a);
a.setAttribute('href', url); a.setAttribute('href', url);
...@@ -234,7 +256,6 @@ class FolderList extends React.Component { ...@@ -234,7 +256,6 @@ class FolderList extends React.Component {
Modal.confirm({ Modal.confirm({
title: '抱歉,不能在线预览', title: '抱歉,不能在线预览',
content: '由于文件较大,不支持在线预览,请下载后再查看', content: '由于文件较大,不支持在线预览,请下载后再查看',
// icon: <Icon type="question-circle" theme="filled" style={{ color: '#FF8534' }}></Icon>,
okText: "下载", okText: "下载",
onOk: () => { onOk: () => {
const a = document.createElement('a'); const a = document.createElement('a');
...@@ -244,21 +265,7 @@ class FolderList extends React.Component { ...@@ -244,21 +265,7 @@ class FolderList extends React.Component {
}); });
break; break;
} }
// if (folderFormat === 'EXCEL') { const prefixUrl = `${OFFICE_PREVIEW_URL}?src=`;
// Modal.confirm({
// title: '抱歉,不能在线预览',
// content: ' 该文件类型不支持在线预览,请下载后再查看',
// // icon: <Icon type="question-circle" theme="filled" style={{ color: '#FF8534' }}></Icon>,
// okText: "下载",
// onOk: () => {
// const a = document.createElement('a');
// a.href = ossUrl;
// a.click();
// }
// });
// break;
// }
const prefixUrl = "https://view.officeapps.live.com/op/view.aspx?src=";
const scanUrl = `${prefixUrl}${encodeURIComponent(ossUrl)}` const scanUrl = `${prefixUrl}${encodeURIComponent(ossUrl)}`
window.open(scanUrl, "_blank"); window.open(scanUrl, "_blank");
break; break;
......
...@@ -2,29 +2,33 @@ ...@@ -2,29 +2,33 @@
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2019-07-10 10:30:49 * @Date: 2019-07-10 10:30:49
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-05-24 16:29:05 * @LastEditTime: 2021-06-22 17:47:02
* @Description: * @Description:
*/ */
import React, { useContext, useEffect, useState } from 'react'; import React, { useContext, useEffect, useState } from 'react';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { ConfigProvider, message } from 'antd'; import { ConfigProvider, message, Layout } from 'antd';
import Header from './Header' import Header from './Header'
import Menu from './Menu' import Menu from './Menu'
import Main from './Main' import Main from './Main'
import zhCN from 'antd/es/locale/zh_CN' import zhCN from 'antd/es/locale/zh_CN'
import User from '@/common/js/user'; import User from '@/common/js/user';
import BaseService from "@/domains/basic-domain/baseService"; import BaseService from "@/domains/basic-domain/baseService";
import { XMContext } from '@/store/context'; import moment from 'moment';
import { VersionContext, VersionInfo, XMContext } from '@/store/context';
import { setStoreGroupPermission, setStorePermission, setStoreGroupList, setStoreList } from '@/store/actions/index'; import { setStoreGroupPermission, setStorePermission, setStoreGroupList, setStoreList } from '@/store/actions/index';
import Service from "@/common/js/service"; import Service from "@/common/js/service";
import Bus from '@/core/tbus'; import Bus from '@/core/tbus';
import { func } from 'prop-types'; import { func } from 'prop-types';
const { Footer, Sider, Content } = Layout;
declare var window: any; declare var window: any;
const App: React.FC = (props: any) => { const App: React.FC = (props: any) => {
const [storeUserId, setStoreUserId] = useState('') const [storeUserId, setStoreUserId] = useState('')
const ctx: any = useContext(XMContext); const ctx: any = useContext(XMContext);
const [versionInfo, setVersionInfo] = useState<VersionInfo|null>(null)
const userId = User.getUserId(); const userId = User.getUserId();
const [menuType, setMenuType] = useState(true); const [menuType, setMenuType] = useState(true);
const enterpriseId = User.getEnterpriseId(); const enterpriseId = User.getEnterpriseId();
...@@ -33,6 +37,7 @@ const App: React.FC = (props: any) => { ...@@ -33,6 +37,7 @@ const App: React.FC = (props: any) => {
useEffect(() => { useEffect(() => {
getStoreAndUserInfo(); getStoreAndUserInfo();
getVersion();
if (window.location.hash === "#/") { if (window.location.hash === "#/") {
window.RCHistory.replace({ window.RCHistory.replace({
pathname: '/home', pathname: '/home',
...@@ -56,17 +61,37 @@ const App: React.FC = (props: any) => { ...@@ -56,17 +61,37 @@ const App: React.FC = (props: any) => {
} }
}); });
} }
function getVersion() {
BaseService.getLesseeVersionMsg().then((res) => {
let version = res.result;
User.setVersion(version);
User.setExpirationTime(res.result.validEndTime)
let versioninfo:VersionInfo = {
dayTime: version.dayTime,
stateEnum: version.stateEnum,
userNum: version.userNum === -1 ? '不限人数' : version.userNum,
surplusUserNum: version.userNum === -1 ? '不限人数' : version.surplusUserNum,
surplusDayTime: version.surplusDayTime,
validEndTime: moment(version.validEndTime).format('YYYY-MM-DD'),
validStartTime: moment(version.validStartTime).format('YYYY-MM-DD'),
whetherReachUserNum: version.whetherReachUserNum,
};
setVersionInfo(versioninfo)
});
}
async function getStoreAndUserInfo() { async function getStoreAndUserInfo() {
await (enterpriseId ? getStoreInfo() : getStoreGroupAndStoreList()); await (enterpriseId ? getStoreInfo() : getStoreGroupAndStoreList());
} }
function getStoreInfo() { function getStoreInfo() {
console.log("currentStoreUserInfo",window.currentStoreUserInfo);
const params = { const params = {
storeId: User.getStoreId(), storeId: User.getStoreId(),
userId: User.getUserId(), userId: User.getUserId(),
}; };
Service.Hades('public/customerHades/getStoreAndUserMsg', params).then((res) => { Service.Hades('public/customerHades/getStoreAndUserMsg', params).then((res) => {
if(res.success){
const { id, storeUserId, storeName, userRole, storeType } = res.result; const { id, storeUserId, storeName, userRole, storeType } = res.result;
User.setStoreId(id); User.setStoreId(id);
User.setStoreUserId(storeUserId); User.setStoreUserId(storeUserId);
...@@ -74,11 +99,21 @@ const App: React.FC = (props: any) => { ...@@ -74,11 +99,21 @@ const App: React.FC = (props: any) => {
Bus.trigger('storeNameChange',storeName); Bus.trigger('storeNameChange',storeName);
User.setUserRole(userRole); User.setUserRole(userRole);
User.setStoreType(storeType); User.setStoreType(storeType);
setStoreUserId(storeUserId) setCurrentStoreUserInfo(id,storeUserId)
setStoreUserId(storeUserId);
getUserPermission(); getUserPermission();
}
}) })
} }
function setCurrentStoreUserInfo(storeId:any,storeUserId:any){
window.currentStoreUserInfo.storeId = storeId;
window.currentStoreUserInfo.storeUserId = storeUserId;
window.currentStoreUserInfo.userId = User.getUserId();
window.currentStoreUserInfo.token = User.getToken();
window.currentStoreUserInfo.enterpriseId = User.getEnterpriseId();
}
function getStoreGroupAndStoreList() { function getStoreGroupAndStoreList() {
BaseService.getUserStore({ userId }).then((res) => { BaseService.getUserStore({ userId }).then((res) => {
...@@ -97,6 +132,7 @@ const App: React.FC = (props: any) => { ...@@ -97,6 +132,7 @@ const App: React.FC = (props: any) => {
Bus.trigger('storeNameChange', storeName); Bus.trigger('storeNameChange', storeName);
User.setUserRole(userRole); User.setUserRole(userRole);
User.setStoreType(storeType); User.setStoreType(storeType);
setCurrentStoreUserInfo(id,storeUserId);
ctx.dispatch(setStoreGroupList(storeGroupVOS)) ctx.dispatch(setStoreGroupList(storeGroupVOS))
ctx.dispatch(setStoreList(storeVOS)); ctx.dispatch(setStoreList(storeVOS));
setStoreUserId(storeUserId) setStoreUserId(storeUserId)
...@@ -122,11 +158,23 @@ const App: React.FC = (props: any) => { ...@@ -122,11 +158,23 @@ const App: React.FC = (props: any) => {
return ( return (
<div id="home"> <div id="home">
{/* <Layout>
<Sider><Menu menuType={menuType} handleMenuType={handleMenuType} /></Sider>
<Layout>
<Header id="app" handleMenuType={handleMenuType} menuType={menuType} />
<ConfigProvider locale={zhCN} autoInsertSpaceInButton={false}>
<Main menuType={menuType} />
</ConfigProvider>
</Layout>
</Layout> */}
<Header id="app" handleMenuType={handleMenuType} menuType={menuType} /> <Header id="app" handleMenuType={handleMenuType} menuType={menuType} />
<VersionContext.Provider value={versionInfo}>
<ConfigProvider locale={zhCN} autoInsertSpaceInButton={false}> <ConfigProvider locale={zhCN} autoInsertSpaceInButton={false}>
<Main menuType={menuType} /> <Main menuType={menuType} />
</ConfigProvider> </ConfigProvider>
<Menu menuType={menuType} handleMenuType={handleMenuType} /> <Menu menuType={menuType} handleMenuType={handleMenuType} />
</VersionContext.Provider>
</div> </div>
) )
} }
......
import React from 'react'; import React, { useEffect, useState } from 'react';
import moment from "moment"
import Service from "@/common/js/service"; import Service from "@/common/js/service";
import BaseService from "@/domains/basic-domain/baseService"; import BaseService from "@/domains/basic-domain/baseService";
import User from "@/common/js/user"; import User from "@/common/js/user";
import { LIVE_SHARE } from "@/domains/course-domain/constants"; import { LIVE_SHARE } from "@/domains/course-domain/constants";
import moment from 'moment';
import { Modal, message } from 'antd'; import { Modal, message } from 'antd';
import './CollegeManagePage.less'; import './CollegeManagePage.less';
import storage from '@/common/js/storage';
const roleMap = { const roleMap = {
CloudManager: "管理员", CloudManager: "管理员",
...@@ -14,6 +15,97 @@ const roleMap = { ...@@ -14,6 +15,97 @@ const roleMap = {
CloudOperator: '运营师', CloudOperator: '运营师',
}; };
function ExpirationPopover(props) {
const [showType, setShowType] = useState(0); //0不显示,1剩余30天,2小于等于7天,3已过期
useEffect(()=> {
if (props.surplusDayTime === 0 ) {
//已过期
let loginflag = storage.get("expiration_tip_login")
if (loginflag === null || loginflag === "true") {
//只有登陆进来的时候提示一次
setShowType(3)
}
return
}
//即将过期
if (props.surplusDayTime === 30 || props.surplusDayTime <= 7) {
let daysflag = storage.get("expiration_tip"+User.getUserId()+"_days")
if (daysflag === null || daysflag !== moment().format("YYYYMMDD")) {
setShowType(2)
}
}
// if (props.surplusDayTime === 30) {
// if (storage.get("expiration_tip"+User.getUserId()+"_thirty") == null || storage.get("expiration_tip"+User.getUserId()+"_thirty") === "true") {
// setShowType(1)
// }
// return
// }
// if (props.surplusDayTime <= 7) {
// let daysflag = storage.getObj("expiration_tip"+User.getUserId()+"_7day");
// if (!daysflag) {
// setShowType(2)
// return
// }
// if (daysflag[props.surplusDayTime - 1] === 0) {
// setShowType(2)
// }
// }
},[props.endTime,props.surplusDayTime])
function iknow() {
storage.set("expiration_tip_login",false)
storage.set("expiration_tip"+User.getUserId()+"_days",moment().format("YYYYMMDD"))
/*
if (props.surplusDayTime === 0 ) {
//已过期
storage.set("expiration_tip_login",false)
} else if (props.surplusDayTime === 30) {
storage.set("expiration_tip"+User.getUserId()+"_thirty",false)
} else if (props.surplusDayTime <= 7) {
let daysflag = [0,0,0,0,0,0,0]
daysflag[props.surplusDayTime - 1] = 1
storage.setObj("expiration_tip"+User.getUserId()+"_7day",daysflag)
}
*/
setShowType(0)
}
if (props.surplusDayTime > 30) {
return ("")
}
return (
<>
{
showType === 0 ? ("") :(
<div className="expirationpopover">
<div className="dialog">
<div className="title">{props.surplusDayTime === 0 ? "服务已到期":"服务到期提醒"}</div>
{
showType === 3 ? (
<div className="tip-text">当前企业购买的小麦企学院服务已于<span style={{color:"#FF4F4F"}}>{moment(props.endTime).format("YYYY-MM-DD")}</span>到期,到期后仍可访问,但功能不可使用,建议尽快续费购买哦~</div>
) : (
<div className="tip-text">当前企业购买的小麦企学院服务 <span style={{color:"#FF4F4F"}}>仅剩{props.surplusDayTime}</span>(于<span>{moment(props.endTime).format("YYYY-MM-DD")}</span>到期),为了不影响使用,建议尽快续费购买哦~</div>
)
}
<div className="qrcode">
<img src="https://cdn.xiaomai5.com/qixueyuankehu.png" alt=""></img>
<div className="des">微信/企业微信扫码咨询</div>
</div>
<div className="phone"><svg style={{position:"relative",top:"2px",marginRight:"4px"}} viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M512.651 3.78c-281.433 0-509.21 228.324-509.21 509.209 0 281.43 228.325 509.203 509.21 509.203 281.427 0 509.202-228.317 509.202-509.203 0.55-280.885-227.775-509.21-509.202-509.21z m198.205 743.553c-36.14 36.136-169.737 1.641-302.24-130.312-131.953-131.959-165.902-266.104-129.768-301.695 31.211-31.21 68.99-85.417 125.939-14.782 56.943 70.629 29.016 90.34-3.291 122.647-22.449 22.448 24.642 79.392 73.37 128.125 49.283 48.73 105.678 95.818 128.126 73.368 32.306-32.305 52.017-60.23 122.646-3.288 71.182 56.949 16.426 95.276-14.782 125.937z" p-id="4409" fill="#999999"></path></svg>
咨询电话:19157875632</div>
<div className="button" onClick={iknow}>我知道了</div>
</div>
</div>
)
}
</>
)
}
export default class CollegeManagePage extends React.Component { export default class CollegeManagePage extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
...@@ -24,13 +116,16 @@ export default class CollegeManagePage extends React.Component { ...@@ -24,13 +116,16 @@ export default class CollegeManagePage extends React.Component {
enterpriseId: User.getEnterpriseId(), enterpriseId: User.getEnterpriseId(),
isAdmin: false, isAdmin: false,
createStoreList:[], createStoreList:[],
joinStoreList:[] joinStoreList:[],
surplusDayTime:365, //剩余天数
endTime: 0, //有效截至时间
}; };
} }
componentDidMount() { componentDidMount() {
this.getStoreList(); this.getStoreList();
this.getEnterpriseUser(); this.getEnterpriseUser();
this.getVersion()
} }
getEnterpriseUser() { getEnterpriseUser() {
...@@ -45,6 +140,18 @@ export default class CollegeManagePage extends React.Component { ...@@ -45,6 +140,18 @@ export default class CollegeManagePage extends React.Component {
}); });
} }
getVersion() {
BaseService.getLesseeVersionMsg()
.then(res=> {
User.setVersion(res.result)
User.setExpirationTime(res.result.validEndTime)
this.setState({
surplusDayTime: res.result.stateEnum === "NO" ? 0 : res.result.surplusDayTime,
endTime: res.result.validEndTime
})
})
}
getStoreList() { getStoreList() {
const { enterpriseId } = this.state; const { enterpriseId } = this.state;
if (!enterpriseId) return null; if (!enterpriseId) return null;
...@@ -132,6 +239,7 @@ export default class CollegeManagePage extends React.Component { ...@@ -132,6 +239,7 @@ export default class CollegeManagePage extends React.Component {
} = this.state; } = this.state;
return ( return (
<div className="college-manage-page"> <div className="college-manage-page">
<ExpirationPopover surplusDayTime={this.state.surplusDayTime} endTime={this.state.endTime}/>
<div className="college-header"> <div className="college-header">
<div className="box"> <div className="box">
<img className="box-image" src="https://image.xiaomaiketang.com/xm/fe4NCjr7XF.png" /> <img className="box-image" src="https://image.xiaomaiketang.com/xm/fe4NCjr7XF.png" />
...@@ -180,6 +288,8 @@ export default class CollegeManagePage extends React.Component { ...@@ -180,6 +288,8 @@ export default class CollegeManagePage extends React.Component {
}; };
User.setStoreId(item.id); User.setStoreId(item.id);
User.setStoreUserId(item.storeUserId); User.setStoreUserId(item.storeUserId);
window.currentStoreUserInfo.storeId = item.id;
window.currentStoreUserInfo.storeUserId = item.storeUserId;
window.RCHistory.push('/home') window.RCHistory.push('/home')
}} }}
> >
...@@ -198,6 +308,8 @@ export default class CollegeManagePage extends React.Component { ...@@ -198,6 +308,8 @@ export default class CollegeManagePage extends React.Component {
e.stopPropagation(); e.stopPropagation();
User.setStoreId(item.id); User.setStoreId(item.id);
User.setStoreUserId(item.storeUserId); User.setStoreUserId(item.storeUserId);
window.currentStoreUserInfo.storeId = item.id;
window.currentStoreUserInfo.storeUserId = item.storeUserId;
window.RCHistory.push('/college-info') window.RCHistory.push('/college-info')
}} }}
>编辑</span> >编辑</span>
...@@ -253,6 +365,8 @@ export default class CollegeManagePage extends React.Component { ...@@ -253,6 +365,8 @@ export default class CollegeManagePage extends React.Component {
}; };
User.setStoreId(item.id); User.setStoreId(item.id);
User.setStoreUserId(item.storeUserId); User.setStoreUserId(item.storeUserId);
window.currentStoreUserInfo.storeId = item.id;
window.currentStoreUserInfo.storeUserId = item.storeUserId;
window.RCHistory.push('/home') window.RCHistory.push('/home')
}} }}
> >
...@@ -271,6 +385,8 @@ export default class CollegeManagePage extends React.Component { ...@@ -271,6 +385,8 @@ export default class CollegeManagePage extends React.Component {
e.stopPropagation(); e.stopPropagation();
User.setStoreId(item.id); User.setStoreId(item.id);
User.setStoreUserId(item.storeUserId); User.setStoreUserId(item.storeUserId);
window.currentStoreUserInfo.storeId = item.id;
window.currentStoreUserInfo.storeUserId = item.storeUserId;
window.RCHistory.push('/college-info') window.RCHistory.push('/college-info')
}} }}
>编辑</span> >编辑</span>
......
...@@ -183,4 +183,78 @@ ...@@ -183,4 +183,78 @@
} }
} }
} }
.expirationpopover {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0,0,0,0.7);
z-index: 1000;
.dialog {
width: 560px;
height: 486px;
background: #FFFFFF;
border-radius: 4px;
.title {
text-align: center;
font-size: 20px;
color: #333333;
font-weight: 500;
margin-top: 40px;
}
.tip-text {
font-size: 16px;
color: #666666;
font-weight: 400;
margin-top: 16px;
margin-right: 40px;
margin-left: 40px;
}
.qrcode {
width: 182px;
height: 204px;
background: #F1F3F6;
border-radius: 2px;
margin-top: 16px;
margin-left: auto;
margin-right: auto;
img {
width: 150px;
height: 150px;
margin: 16px 16px 8px 16px;
}
.des {
text-align: center;
font-size: 14px;
color: #333333;
font-weight: 400;
}
}
.phone {
text-align: center;
font-size: 14px;
color: #333333;
font-weight: 400;
margin-top: 16px;
}
.button {
width: 80px;
height: 32px;
background: #2966FF;
cursor: pointer;
margin-left: auto;
margin-right: auto;
margin-top: 24px;
font-size: 14px;
font-weight: 400;
color: #ffffff;
line-height: 32px;
text-align: center;
}
}
}
} }
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2019-09-10 18:26:03 * @Date: 2019-09-10 18:26:03
* @LastEditors: fusanqiasng * @LastEditors: fusanqiasng
* @LastEditTime: 2021-06-22 15:00:53 * @LastEditTime: 2021-06-25 14:33:49
* @Description: * @Description:
*/ */
import React, { useRef, useContext, useEffect, useState } from 'react'; import React, { useRef, useContext, useEffect, useState } from 'react';
...@@ -271,6 +271,14 @@ function Header(props) { ...@@ -271,6 +271,14 @@ function Header(props) {
onChange={(e) => { onChange={(e) => {
setStoreId(e.target.value); setStoreId(e.target.value);
User.setStoreId(e.target.value); User.setStoreId(e.target.value);
list.map((item) => {
if (item.id === e.target.value) {
User.setStoreUserId(item.storeUserId);
}
});
User.setUserId(User.getUserId());
User.setToken(User.getToken());
User.setEnterpriseId(User.getEnterpriseId());
window.RCHistory.push('/home'); window.RCHistory.push('/home');
window.location.reload(); window.location.reload();
}} }}
......
...@@ -7,11 +7,16 @@ import User from '@/common/js/user'; ...@@ -7,11 +7,16 @@ import User from '@/common/js/user';
import WechatLogin from './WechatLogin'; import WechatLogin from './WechatLogin';
import BaseService from '@/domains/basic-domain/baseService'; import BaseService from '@/domains/basic-domain/baseService';
import axios from 'axios'; import axios from 'axios';
import storage from '@/common/js/storage';
import _ from 'underscore'; import _ from 'underscore';
import user from '@/common/js/user'; import user from '@/common/js/user';
const { TabPane } = Tabs; const { TabPane } = Tabs;
function Login(props) { function Login(props) {
/**
* 手机登陆入口,暂时隐藏,此页注释代码勿删
*/
// const [phone, setPhone] = useState(''); // 登录手机号 // const [phone, setPhone] = useState(''); // 登录手机号
// const [phoneverify, setPhoneverify] = useState(''); // 密码登录验证码 // const [phoneverify, setPhoneverify] = useState(''); // 密码登录验证码
// const [openCheck1, setOpenCheck1] = useState(false); // const [openCheck1, setOpenCheck1] = useState(false);
...@@ -22,6 +27,10 @@ function Login(props) { ...@@ -22,6 +27,10 @@ function Login(props) {
// const [phoneError, setPhoneError] = useState(false); // const [phoneError, setPhoneError] = useState(false);
// const [checkObject1, setCheckObject1] = useState({}); // const [checkObject1, setCheckObject1] = useState({});
/**
* 手机登陆入口,暂时隐藏,此页注释代码勿删
*/
useEffect(() => { useEffect(() => {
const enterpriseId = getParameterByName('enterpriseId'); const enterpriseId = getParameterByName('enterpriseId');
const userId = getParameterByName('userId'); const userId = getParameterByName('userId');
...@@ -43,7 +52,8 @@ function Login(props) { ...@@ -43,7 +52,8 @@ function Login(props) {
User.removeToken(); User.removeToken();
User.removeEnterpriseId(); User.removeEnterpriseId();
} }
}, []); storage.set("expiration_tip_login",true)
}, [])
function getWXWorkLoginNoCheck(enterpriseId, userId) { function getWXWorkLoginNoCheck(enterpriseId, userId) {
const params = { const params = {
appTermEnum: 'XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN', appTermEnum: 'XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN',
...@@ -54,12 +64,21 @@ function Login(props) { ...@@ -54,12 +64,21 @@ function Login(props) {
User.setUserId(res.result.loginInfo.userId); User.setUserId(res.result.loginInfo.userId);
User.setToken(res.result.loginInfo.xmToken); User.setToken(res.result.loginInfo.xmToken);
User.setEnterpriseId(res.result.enterpriseId); User.setEnterpriseId(res.result.enterpriseId);
window.currentStoreUserInfo = {};
window.currentStoreUserInfo.userId = res.result.loginInfo.userId;
window.currentStoreUserInfo.token = res.result.loginInfo.xmToken;
window.currentStoreUserInfo.enterpriseId = res.result.enterpriseId;
User.setIdentifier(res.result.identifier); User.setIdentifier(res.result.identifier);
window.RCHistory.push({ window.RCHistory.push({
pathname: `/switch-route`, pathname: `/switch-route`,
}); });
}); });
} }
/**
* 手机登陆入口,暂时隐藏,此页注释代码勿删
*/
// async function checkAccount(code, callback = () => {}) { // async function checkAccount(code, callback = () => {}) {
// callback(); // callback();
// } // }
...@@ -147,6 +166,10 @@ function Login(props) { ...@@ -147,6 +166,10 @@ function Login(props) {
// }); // });
// } // }
/**
* 手机登陆入口,暂时隐藏,此页注释代码勿删
*/
return ( return (
<div className='login-page'> <div className='login-page'>
<div className='logo-img-box'> <div className='logo-img-box'>
...@@ -167,6 +190,91 @@ function Login(props) { ...@@ -167,6 +190,91 @@ function Login(props) {
<TabPane tab='企业微信登录' key='1'> <TabPane tab='企业微信登录' key='1'>
<WechatLogin></WechatLogin> <WechatLogin></WechatLogin>
</TabPane> </TabPane>
{/* 手机登陆入口,暂时隐藏,此页注释代码勿删 */}
{/* <TabPane tab='手机号登录' key='2'>
<div className='login-form'>
<div className='form'>
<div className='username' style={{ marginBottom: 16 }}>
<Input
type='phone'
autoComplete='off'
name='account'
maxLength={11}
placeholder="请输入手机号"
value={phone}
onChange={(e) => {
setPhone(e.target.value)
}}
/>
</div>
<div className='error-message'></div>
<div className='phoneverify'>
<Input
type="text"
id="phoneverify"
name="phoneverify"
placeholder="请输入验证码"
autoComplete="off"
value={phoneverify}
maxLength={4}
onChange={(e) => {
setPhoneverify(e.target.value)
}}
/>
<Popover
visible={openCheck1}
trigger='click'
title=''
content={
<div>
<span style={{ fontSize: '12px', color: '#999', marginBottom: 8, display: 'block' }}>请完成安全验证</span>
<CheckBeforeSendCode
callback={(data, nc) => {
setCheckObject1(nc)
checkAccount(1, (userType) => {
handleSendSMSCode(data, userType)
setTimeout(() => {
setOpenCheck1(false)
}, 500)
})
}}
/>
</div>
}
onVisibleChange={(value) => {
if (!value) {
setOpenCheck1(false)
}
}}
placement='bottomRight'>
<div
className='btn'
id='sendVerifyCode'
onClick={() => {
if (checking1) return
checkSend(1)
}}>
{codeText}
</div>
</Popover>
</div>
<div className='error-message'>{errorMessage}</div>
<div className='submit'>
<div className='btn'>
<span
id='loginIn'
onClick={() => {
handleSubmit()
}}>
登录
</span>
</div>
</div>
</div>
</div>
</TabPane> */}
{/* 手机登陆入口,暂时隐藏,此页注释代码勿删 */}
</Tabs> </Tabs>
</div> </div>
</div> </div>
......
...@@ -5,38 +5,35 @@ ...@@ -5,38 +5,35 @@
@active-color: #2966FF; @active-color: #2966FF;
.left-container { .left-container {
position: absolute; position: absolute;
z-index: 2; z-index: 10;
top: @top-height; top: @top-height;
left: 0; left: 0;
bottom: 0; bottom: 0;
width: @xm-left-width; width: @xm-left-width;
background: @menu-bakg; background: @menu-bakg;
color: #333; color: #333;
.top-ctrl {
display: flex;
align-items: center;
.topLogo { .topLogo {
height: 62px; height: 60px;
background: rgba(255, 255, 255, 0.5); background: rgba(255, 255, 255, 0.5);
.img1 { .img1 {
width: 138px; width: 138px;
height: 35px; height: 35px;
margin-left: 19px; margin: 15px 0 15px 8px;
margin-top: 13px;
}
.img0 {
display: none;
width: 35px;
height: 35px;
margin-left: 10px;
margin-top: 13px;
} }
} }
.menu-type-icon{ .menu-type-icon{
margin:4px 0 0px 150px; margin: 8px 14px 0px 4px;
cursor: pointer; cursor: pointer;
.icon{ .icon{
font-size:14px; font-size:14px;
color:#5E606A; color:#5E606A;
} }
} }
}
.ant-menu { .ant-menu {
padding-left: 0 !important; padding-left: 0 !important;
color: #333; color: #333;
...@@ -67,7 +64,7 @@ ...@@ -67,7 +64,7 @@
.icon-img{ .icon-img{
width:18px; width:18px;
height:18px; height:18px;
margin-right:16px; margin-right:6px;
} }
.listType { .listType {
width: 5px; width: 5px;
...@@ -145,7 +142,119 @@ ...@@ -145,7 +142,119 @@
// display:inline-block; // display:inline-block;
// } // }
// } // }
.version-info {
position: absolute;
height: 74px;
bottom: 0;
width: 100%;
cursor: pointer;
z-index: -1;
.row-1 {
width: fit-content;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
line-height: 20px;
margin: 0 auto;
.version-name {
display: inline-block;
width: 58px;
text-align: center;
margin: 0 auto;
border-radius: 2px;
border: 1px solid #E8E8E8;
}
.renew {
display: inline-block;
width: 58px;
color: #2966FF;
margin-left: 8px;
}
}
.expiration-time {
height: 24px;
text-align: center;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
line-height: 22px;
margin: 6px auto 0 auto;
}
.popover {
display: none;
position: absolute;
z-index: 100;
padding: 16px 22px;
bottom: 22px;
width: 352px;
height: 198px;
right: -342px;
background: #FFFFFF;
box-shadow: 0px 2px 15px 0px rgba(0, 0, 0, 0.06);
.title {
display: inline-block;
width: 68px;
height: 22px;
font-size: 16px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 22px;
margin-right: 8px;
}
.expiration-tag {
display: inline-block;
width: 52px;
height: 18px;
background: #EEEEEE;
border-radius: 2px;
text-align: center;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
line-height: 17px;
}
&::before {
position: absolute;
content: "";
width: 16px;
height: 16px;
left: -8px;
top: 80%;
border: 8px solid transparent;
box-shadow: 0px 2px 15px 0px rgba(0, 0, 0, 0.06);
}
.content {
margin-top: 24px;
.widget {
display: inline-block;
}
.lable {
font-size: 14px;
font-weight: 400;
color: #999999;
line-height: 22px;
}
.lable-text {
margin-top: 4px;
font-size: 16px;
font-weight: 500;
color: #333333;
line-height: 22px;
}
}
}
.popover-show {
display: block;
}
}
} }
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected { .ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
background:@active-color !important; background:@active-color !important;
} }
......
import React, { useContext, useEffect, useRef, useState } from 'react'; import React, { Key, useContext, useEffect, useRef, useState, useMemo } from 'react';
import { import {
withRouter, withRouter,
} from 'react-router-dom'; } from 'react-router-dom';
import { Menu} from 'antd'; import { Menu, Popover, Tooltip } from 'antd';
import { menuList } from '../../routes//config/menuList' import { RightOutlined } from '@ant-design/icons';
import { XMContext } from '../../store/context'; import { menuList } from '../../routes//config/menuList';
import Service from "@/common/js/service"; import { XMContext, VersionContext } from '../../store/context';
import StoreService from "@/domains/store-domain/storeService"; import BaseService from '@/domains/basic-domain/baseService';
import User from "@/common/js/user"; import StoreService from '@/domains/store-domain/storeService';
import classNames from 'classnames';
import User from "@/common/js/user"
import _ from 'underscore'; import _ from 'underscore';
import "./Menu.less"; import "./Menu.less";
console.log('2021-06-17') import { display } from 'html2canvas/dist/types/css/property-descriptors/display';
import ContactWidget from '@/components/ContactWidget';
const { SubMenu } = Menu; const { SubMenu } = Menu;
function VersionPanel(props: any) {
const [versionName, setVersionName] = useState('标准版');
const [showVersionPopover, setShowVersionPopover] = useState(false);
const [showRenewPopover, setShowRenewPopover] = useState(false);
const versionInfo = useContext(VersionContext);
function onVersionEnter() {
setShowVersionPopover(true)
}
function onVersionLeave() {
setShowVersionPopover(false)
setShowRenewPopover(false)
}
function onRenewClick() {
setShowRenewPopover(true)
setShowVersionPopover(false)
}
const versionPopoverClass = classNames({
'popover':true,
'popover-show':showVersionPopover
})
return (
<div className='version-info' onMouseEnter={onVersionEnter} onMouseLeave={onVersionLeave}>
<div className='row-1'>
<div className='version-name'>{versionName}</div>
<ContactWidget trigger='click' placement='rightBottom' visible={showRenewPopover}>
<div className='renew' onClick={onRenewClick}>
去续费
<span className='icon iconfont' style={{ fontSize: '10px' }}>
&#59291;
</span>
</div>
</ContactWidget>
</div>
<div className='expiration-time'>
有效期至{versionInfo?.validEndTime}
{versionInfo?.stateEnum === "NO" ? '(已过期)' : ''}
</div>
<div className={versionPopoverClass}>
<div className='title'>版本信息</div>
{versionInfo?.stateEnum === "NO" ? <div className='expiration-tag'>已过期</div> : ''}
<div className='content'>
<div className='widget' style={{ marginRight: '26px', marginBottom: '16px', width: '70px' }}>
<div className='lable'>剩余天数</div>
<div className='lable-text'>{versionInfo?.surplusDayTime}</div>
</div>
<div className='widget' style={{ marginBottom: '16px', width:"212px"}}>
<div className='lable'>有效起止日期</div>
<div className='lable-text'>
{versionInfo?.validStartTime}~{versionInfo?.validEndTime}
</div>
</div>
<div className='widget' style={{ marginRight: '26px', marginBottom: '8px', width: '70px' }}>
<div className='lable'>剩余人数</div>
<div className='lable-text'>{versionInfo?.surplusUserNum}</div>
</div>
<div className='widget' style={{ marginBottom: '8px' }}>
<div className='lable' style={{ display: 'inline-block' }}>
人数限制
</div>
<Tooltip
overlayStyle={{ maxWidth: '587px', width: '587px' }}
placement='topLeft'
arrowPointAtCenter
title={() => {
return (
<div>
<div>1、若员工/学员存在多个学院,企业人数只统计为1人;</div>
<div>2、若一个学员既用「企业微信」登录学习又用「微信」登录学习,企业人数将统计为2人。</div>
</div>
);
}}>
<div style={{ display: 'inline-block', position: 'relative', top: '2px', marginLeft: '4px' }}>
<span>
<svg viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='1026' width='14' height='14'>
<path
d='M512 68.266667c245.111467 0 443.733333 198.656 443.733333 443.733333s-198.621867 443.733333-443.733333 443.733333C266.922667 955.733333 68.266667 757.077333 68.266667 512S266.922667 68.266667 512 68.266667z m29.320533 596.548266c0.477867-27.989333 2.4576-48.196267 5.802667-60.654933 3.413333-12.458667 8.567467-23.4496 15.633067-33.0752 6.997333-9.557333 21.9136-24.507733 44.714666-44.714667 33.928533-30.037333 56.797867-55.637333 68.437334-76.5952a139.1616 139.1616 0 0 0 17.5104-68.846933c0-43.008-16.5888-79.701333-49.800534-110.011733-33.1776-30.378667-77.6192-45.533867-133.358933-45.533867-52.6336 0-94.958933 14.1312-126.976 42.3936-31.9488 28.2624-51.268267 68.949333-57.685333 122.094933l71.8848 8.533334c6.212267-39.6288 19.3536-68.778667 39.3216-87.483734 19.933867-18.6368 44.817067-27.989333 74.6496-27.989333 30.788267 0 56.900267 10.308267 78.165333 30.9248 21.265067 20.5824 31.880533 44.544 31.880533 71.748267 0 15.018667-3.618133 28.910933-10.922666 41.608533-7.168 12.731733-22.971733 29.764267-47.240534 51.131733-24.200533 21.367467-41.028267 37.649067-50.346666 48.810667-12.6976 15.291733-21.9136 30.481067-27.613867 45.533867-7.748267 19.933867-11.639467 43.690667-11.639467 71.133866 0 4.676267 0.1024 11.707733 0.341334 21.026134h67.242666z m8.192 140.3904v-79.735466h-79.701333v79.735466h79.701333z'
fill='#bfbfbf'
p-id='1027'></path>
</svg>
</span>
</div>
</Tooltip>
<div className='lable-text'>{versionInfo?.userNum}</div>
</div>
</div>
</div>
</div>
)
}
function Aside(props: any) { function Aside(props: any) {
const {menuType,handleMenuType}= props const { menuType, handleMenuType } = props
const ctx: any = useContext(XMContext); const ctx: any = useContext(XMContext);
const [selectKey, setSelectKey] = useState(); const [selectKey, setSelectKey] = useState();
const [openKeys, setOpenKeys] = useState(['']); const [openKeys, setOpenKeys] = useState(['']);
const [topLogoUrl, setTopLogoUrl] = useState("") const [topLogoUrl, setTopLogoUrl] = useState("")
const logoImg0Ref = useRef<any>() const [collapsed, setCollapsed] = useState(false)
const logoImg1Ref = useRef<any>()
const rootSubmenuKeys = _.pluck(menuList, 'groupCode'); const rootSubmenuKeys = _.pluck(menuList, 'groupCode');
useEffect(() => { useEffect(() => {
const link = props.location.pathname; const link = props.location.pathname;
menuList.map((item: any, index: any) => { menuList.map((item: any, index: any) => {
...@@ -38,13 +137,14 @@ function Aside(props: any) { ...@@ -38,13 +137,14 @@ function Aside(props: any) {
return item; return item;
}) })
}, [props.location.pathname]) }, [props.location.pathname])
useEffect(()=> { useEffect(() => {
getTopLeftLogo() getTopLeftLogo()
}) }, [])
function getTopLeftLogo() { function getTopLeftLogo() {
if (User.getToken()) { if (User.getToken()) {
StoreService.getStoreDetail({storeId:User.getStoreId()}) StoreService.getStoreDetail({ storeId: User.getStoreId() })
.then(res=> { .then(res => {
if (_.isEmpty(res.result.logo)) { if (_.isEmpty(res.result.logo)) {
setTopLogoUrl("https://image.xiaomaiketang.com/xm/fe4NCjr7XF.png") setTopLogoUrl("https://image.xiaomaiketang.com/xm/fe4NCjr7XF.png")
} else { } else {
...@@ -54,36 +154,48 @@ function Aside(props: any) { ...@@ -54,36 +154,48 @@ function Aside(props: any) {
}) })
} }
} }
function toggleMenu(item: any) { function toggleMenu(item: any) {
window.RCHistory.push(item.link) window.RCHistory.push(item.link)
if (!menuType) {
setOpenKeys([])
}
} }
function onOpenChange(key: any) {
function onOpenChange(key: Key[]) {
if (typeof key === "string") {
if (openKeys.includes(key)) { if (openKeys.includes(key)) {
setOpenKeys([]); setOpenKeys([]);
} else { } else {
setOpenKeys([key]); setOpenKeys([key]);
} }
} }
function handleMenu() {
handleMenuType();
} }
useEffect(()=> {
if (!logoImg0Ref.current || !logoImg1Ref.current) { function onOpenChangeForHover(key: Key[]) {
if (menuType) {
return return
} }
if (!menuType) { if (typeof key === "string") {
if (topLogoUrl.indexOf("xiaomaiketang.com") < 0) { if (openKeys.includes(key)) {
logoImg0Ref.current.style.display = "none" setOpenKeys([]);
logoImg1Ref.current.style.display = "none"
} else { } else {
logoImg0Ref.current.style.display = "inline" setOpenKeys([key]);
logoImg1Ref.current.style.display = "none"
} }
} else {
logoImg0Ref.current.style.display = "none"
logoImg1Ref.current.style.display = "inline"
} }
},[menuType]) }
function handleMenu() {
handleMenuType();
setCollapsed(!collapsed)
}
const openKeysConstrol = useMemo(() => {
return {
[menuType ? 'openKeys' : 'defaultOpenKeys']: openKeys
};
}, [menuType, openKeys])
return ( return (
<div <div
...@@ -94,9 +206,9 @@ function Aside(props: any) { ...@@ -94,9 +206,9 @@ function Aside(props: any) {
: "left-container left-container-vertical" : "left-container left-container-vertical"
} }
> >
<div className="top-ctrl">
<div className="topLogo"> <div className="topLogo">
<img ref={logoImg0Ref} src="https://image.xiaomaiketang.com/xm/c4KiP2epBP.png" alt="" className="img0"></img> {menuType && <img src={topLogoUrl} alt="" className="img1"></img>}
<img ref={logoImg1Ref} src={topLogoUrl} alt="" className="img1"></img>
</div> </div>
<div className="menu-type-icon" onClick={handleMenu}> <div className="menu-type-icon" onClick={handleMenu}>
{menuType ? ( {menuType ? (
...@@ -113,14 +225,18 @@ function Aside(props: any) { ...@@ -113,14 +225,18 @@ function Aside(props: any) {
</span> </span>
)} )}
</div> </div>
</div>
<div className="left"> <div className="left">
<div className="nav"> <div className="nav">
<Menu <Menu
style={{ minHeight: "100%", background: '#0E1935' }} {...openKeysConstrol}
style={menuType ? { minHeight: "100%", background: '#0E1935' } : { minHeight: "100%", background: '#0E1935', width: "56px" }}
selectedKeys={selectKey} selectedKeys={selectKey}
openKeys={openKeys}
inlineCollapsed={false} onOpenChange={onOpenChange}
inlineCollapsed={collapsed}
mode={menuType ? "inline" : "vertical"} mode={menuType ? "inline" : "vertical"}
> >
{ {
...@@ -129,19 +245,19 @@ function Aside(props: any) { ...@@ -129,19 +245,19 @@ function Aside(props: any) {
return null; return null;
} }
if (item.children) { if (item.children) {
return <SubMenu key={item.groupCode} style={{ marginTop: 0 }} className="first-menu-item" title={<div > return <SubMenu
{/* <span style={{ marginRight: 16 }} className="iconfont icon" dangerouslySetInnerHTML={{ __html:item.icon}}></span> */} key={item.groupCode}
<img src={item.img} className="icon-img"></img> style={{ marginTop: 0 }}
{menuType && icon={<img src={item.img} className="icon-img"></img>}
<span>{item.groupName}</span> title={menuType ? <span>{item.groupName}</span> : ""}
}</div> onTitleClick={() => onOpenChange(item.groupCode)}
} onTitleClick={() => onOpenChange(item.groupCode)}> >
{ {
item.children.map((_item: any, _index: any) => { item.children.map((_item: any, _index: any) => {
if (ctx.xmState.storeUserPermissionList.indexOf(_item.groupCode) === -1) { if (ctx.xmState.storeUserPermissionList.indexOf(_item.groupCode) === -1) {
return null; return null;
} }
return <Menu.Item onClick={() => { toggleMenu(_item) }} style={{ marginTop: 0 }} key={_item.groupCode + index + _index}> return <Menu.Item onClick={() => { toggleMenu(_item) }} style={{ marginTop: 0 }} key={_item.groupCode + index + _index} >
<span className="name">{_item.groupName}</span> <span className="name">{_item.groupName}</span>
</Menu.Item> </Menu.Item>
...@@ -149,18 +265,12 @@ function Aside(props: any) { ...@@ -149,18 +265,12 @@ function Aside(props: any) {
} }
</SubMenu> </SubMenu>
} else { } else {
return <Menu.Item onClick={() => { toggleMenu(item) }} key={item.groupCode} className="first-menu-item"> return <Menu.Item
{/* <span style={{ marginRight: 16 }} className="iconfont icon" dangerouslySetInnerHTML={{ __html:item.icon}}></span> */} onClick={() => { toggleMenu(item) }}
{selectKey === item.groupCode ? key={item.groupCode}
<img src={item.selectImg} className="icon-img"></img> icon={<img src={selectKey === item.groupCode ? item.selectImg : item.img} className="icon-img"></img>}
: >
<img src={item.img} className="icon-img"></img> {menuType ? item.groupName : ""}
}
{menuType &&
<span>{item.groupName}</span>
}
</Menu.Item> </Menu.Item>
} }
}) })
...@@ -168,6 +278,11 @@ function Aside(props: any) { ...@@ -168,6 +278,11 @@ function Aside(props: any) {
</Menu> </Menu>
</div> </div>
</div> </div>
{
menuType ? <VersionPanel /> : ""
}
</div> </div>
); );
} }
......
...@@ -6,6 +6,7 @@ import { PATH } from '@/domains/basic-domain/constants'; ...@@ -6,6 +6,7 @@ import { PATH } from '@/domains/basic-domain/constants';
import './WechatLogin.less'; import './WechatLogin.less';
const Logo = require('@/common/images/logo.png'); const Logo = require('@/common/images/logo.png');
declare var location: any; declare var location: any;
declare var window: any;
export default function WechatLogin(props: any) { export default function WechatLogin(props: any) {
const freshTime = 60; const freshTime = 60;
...@@ -27,15 +28,11 @@ export default function WechatLogin(props: any) { ...@@ -27,15 +28,11 @@ export default function WechatLogin(props: any) {
Service.Hades('anon/hades/getTicket', {}).then((res: any) => { Service.Hades('anon/hades/getTicket', {}).then((res: any) => {
setTicket(res.result); setTicket(res.result);
const redirect = `${PATH}?ticket=${res.result}&appTermEnum=XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN&env=${process.env.DEPLOY_ENV || 'dev'}`; const redirect = `${PATH}?ticket=${res.result}&appTermEnum=XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN&env=${process.env.DEPLOY_ENV || 'dev'}`;
// console.log(redirect)
// const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=ww409ccf9c6e31f19e&redirect_uri=${encodeURIComponent(redirect)}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
// console.log(url)
const qrcodeWrapDom: any = document.querySelector('#qrcode'); const qrcodeWrapDom: any = document.querySelector('#qrcode');
let qrnode = new qrcode({ let qrnode = new qrcode({
text: redirect, text: redirect,
correctLevel: 2, correctLevel: 2,
size: 180, size: 180,
// image: 'https://image.xiaomaiketang.com/xm/Newk4NrxKC.png',
image: 'https://image.xiaomaiketang.com/xm/bFkRBz7teA.png', image: 'https://image.xiaomaiketang.com/xm/bFkRBz7teA.png',
imageSize: 50, imageSize: 50,
}); });
...@@ -75,7 +72,15 @@ export default function WechatLogin(props: any) { ...@@ -75,7 +72,15 @@ export default function WechatLogin(props: any) {
User.setUserId(_res.result.loginInfo.userId); User.setUserId(_res.result.loginInfo.userId);
User.setToken(_res.result.loginInfo.xmToken); User.setToken(_res.result.loginInfo.xmToken);
User.setEnterpriseId(_res.result.enterpriseId); User.setEnterpriseId(_res.result.enterpriseId);
window.currentStoreUserInfo = {}
window.currentStoreUserInfo.userId = _res.result.loginInfo.userId;
window.currentStoreUserInfo.token = _res.result.loginInfo.xmToken;
window.currentStoreUserInfo.enterpriseId = _res.result.enterpriseId;
User.setIdentifier(_res.result.identifier); User.setIdentifier(_res.result.identifier);
window.currentStoreUserInfo = {}
window.currentStoreUserInfo.userId = _res.result.loginInfo.userId;
window.currentStoreUserInfo.token = _res.result.loginInfo.xmToken;
window.currentStoreUserInfo.enterpriseId = _res.result.enterpriseId;
window.RCHistory.push({ window.RCHistory.push({
pathname: `/switch-route`, pathname: `/switch-route`,
}); });
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
* @Author: wufan * @Author: wufan
* @Date: 2020-11-30 10:47:38 * @Date: 2020-11-30 10:47:38
* @LastEditors: wufan * @LastEditors: wufan
* @LastEditTime: 2021-02-01 14:12:38 * @LastEditTime: 2021-06-21 11:17:44
* @Description: 学院装修页面 * @Description: 学院装修页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React, { useEffect, useState } from "react"; import React, { useState } from "react";
import { withRouter, Switch, Route } from "react-router-dom"; import { withRouter } from "react-router-dom";
import _ from "underscore"; import _ from "underscore";
import { Tabs } from "antd"; import { Tabs } from "antd";
import "./StoreDecorationPage.less"; import "./StoreDecorationPage.less";
...@@ -16,9 +16,6 @@ import StoreH5DecorationTab from "./StoreH5DecorationTab"; ...@@ -16,9 +16,6 @@ import StoreH5DecorationTab from "./StoreH5DecorationTab";
import StoreWebDecorationTab from "./StoreWebDecorationTab"; import StoreWebDecorationTab from "./StoreWebDecorationTab";
const { TabPane } = Tabs; const { TabPane } = Tabs;
declare var window: any;
interface StoreDecoprationProps { interface StoreDecoprationProps {
match: { match: {
url: string; url: string;
...@@ -27,7 +24,6 @@ interface StoreDecoprationProps { ...@@ -27,7 +24,6 @@ interface StoreDecoprationProps {
function StoreDecorationPage(props: StoreDecoprationProps) { function StoreDecorationPage(props: StoreDecoprationProps) {
const [currentTab, setCurrentTab] = useState("h5"); const [currentTab, setCurrentTab] = useState("h5");
const { match } = props;
return ( return (
<div className="page store-decoration-page"> <div className="page store-decoration-page">
...@@ -36,7 +32,6 @@ function StoreDecorationPage(props: StoreDecoprationProps) { ...@@ -36,7 +32,6 @@ function StoreDecorationPage(props: StoreDecoprationProps) {
<Tabs <Tabs
onChange={(key) => { onChange={(key) => {
setCurrentTab(key); setCurrentTab(key);
// window.RCHistory.push(`${match.url}/store-decoration/${key}`);
}} }}
activeKey={currentTab} activeKey={currentTab}
> >
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: wufan * @Author: wufan
* @Date: 2020-11-30 10:47:38 * @Date: 2020-11-30 10:47:38
* @LastEditors: wufan * @LastEditors: wufan
* @LastEditTime: 2021-05-28 16:20:26 * @LastEditTime: 2021-06-21 11:16:21
* @Description: web学院banner页面 * @Description: web学院banner页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -10,8 +10,7 @@ ...@@ -10,8 +10,7 @@
import React from "react"; import React from "react";
import { withRouter } from "react-router-dom"; import { withRouter } from "react-router-dom";
import _ from "underscore"; import _ from "underscore";
// import PhotoClip from 'photoclip' import { Modal, message, Button } from "antd";
import { Table, Modal, message, Button } from "antd";
import StoreService from "@/domains/store-domain/storeService"; import StoreService from "@/domains/store-domain/storeService";
import { import {
sortableContainer, sortableContainer,
...@@ -24,6 +23,8 @@ import User from "@/common/js/user"; ...@@ -24,6 +23,8 @@ import User from "@/common/js/user";
import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal"; import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal";
import "./StoreDecorationPage.less"; import "./StoreDecorationPage.less";
import Upload from "@/core/upload"; import Upload from "@/core/upload";
import { XMTable } from '@/components';
import college from '@/common/lottie/college';
const { confirm } = Modal; const { confirm } = Modal;
const DragHandle = sortableHandle(() => ( const DragHandle = sortableHandle(() => (
...@@ -391,7 +392,11 @@ class StoreH5Decoration extends React.Component { ...@@ -391,7 +392,11 @@ class StoreH5Decoration extends React.Component {
</Button> </Button>
</div> </div>
<div className="box-body"> <div className="box-body">
<Table <XMTable
renderEmpty={{
image: college,
description: '暂无数据'
}}
size={"middle"} size={"middle"}
pagination={false} pagination={false}
dataSource={storeDecorationlist} dataSource={storeDecorationlist}
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: wufan * @Author: wufan
* @Date: 2020-11-30 10:47:38 * @Date: 2020-11-30 10:47:38
* @LastEditors: wufan * @LastEditors: wufan
* @LastEditTime: 2021-05-28 16:21:04 * @LastEditTime: 2021-06-21 11:16:31
* @Description: web学院banner页面 * @Description: web学院banner页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -10,8 +10,7 @@ ...@@ -10,8 +10,7 @@
import React from "react"; import React from "react";
import { withRouter } from "react-router-dom"; import { withRouter } from "react-router-dom";
import _ from "underscore"; import _ from "underscore";
// import PhotoClip from 'photoclip' import { Modal, message, Button } from "antd";
import { Table, Modal, message, Button } from "antd";
import StoreService from "@/domains/store-domain/storeService"; import StoreService from "@/domains/store-domain/storeService";
import { import {
sortableContainer, sortableContainer,
...@@ -24,6 +23,8 @@ import User from "@/common/js/user"; ...@@ -24,6 +23,8 @@ import User from "@/common/js/user";
import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal"; import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal";
import "./StoreDecorationPage.less"; import "./StoreDecorationPage.less";
import Upload from "@/core/upload"; import Upload from "@/core/upload";
import { XMTable } from '@/components';
import college from '@/common/lottie/college';
const { confirm } = Modal; const { confirm } = Modal;
const DragHandle = sortableHandle(() => ( const DragHandle = sortableHandle(() => (
...@@ -389,7 +390,11 @@ class StoreWebDecoration extends React.Component { ...@@ -389,7 +390,11 @@ class StoreWebDecoration extends React.Component {
</Button> </Button>
</div> </div>
<div className="box-body"> <div className="box-body">
<Table <XMTable
renderEmpty={{
image: college,
description: '暂无数据'
}}
size={"middle"} size={"middle"}
pagination={false} pagination={false}
dataSource={storeDecorationlist} dataSource={storeDecorationlist}
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-04-08 15:50:52 * @Date: 2021-04-08 15:50:52
* @LastEditors: wufan * @LastEditors: wufan
* @LastEditTime: 2021-04-24 15:55:19 * @LastEditTime: 2021-06-21 11:24:48
* @Description: 助学工具-考试-答案详情 * @Description: 助学工具-考试-答案详情
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect} from 'react';
import { Route, withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import User from '@/common/js/user'; import User from '@/common/js/user';
import Service from '@/common/js/service'; import Service from '@/common/js/service';
import Lottie from 'lottie-web'; import Lottie from 'lottie-web';
...@@ -20,7 +20,6 @@ const NUM_TO_WORD_MAP = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', ...@@ -20,7 +20,6 @@ const NUM_TO_WORD_MAP = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
function AnswerDescPage(props) { function AnswerDescPage(props) {
const examId = props.match.params.testId.replace(/\?.+/, ''); const examId = props.match.params.testId.replace(/\?.+/, '');
const paperId = window.getParameterByName('paperId'); const paperId = window.getParameterByName('paperId');
const [customerId, setCustomerId] = useState('');
const [examDetail, setExamDetail] = useState({ const [examDetail, setExamDetail] = useState({
examDesc: '', examDesc: '',
examDuration: 0, examDuration: 0,
...@@ -155,68 +154,10 @@ function AnswerDescPage(props) { ...@@ -155,68 +154,10 @@ function AnswerDescPage(props) {
setIsShowErrorPage(true); setIsShowErrorPage(true);
} }
function handleChangeActiveIndex(isPre) {
if (onlyError) {
if (isPre && activeOrderIndex !== errorQuestionList[0].orderIndex) {
setActiveOrderIndex(errorQuestionList[activeIndex - 1].orderIndex);
setActiveIndex(activeIndex - 1);
} else if (!isPre && activeOrderIndex !== errorQuestionList[errorCount - 1].orderIndex) {
setActiveOrderIndex(errorQuestionList[activeIndex + 1].orderIndex);
setActiveIndex(activeIndex + 1);
}
} else {
if (isPre && activeOrderIndex !== 0) {
setActiveOrderIndex(activeIndex - 1);
setActiveIndex(activeIndex - 1);
} else if (!isPre && activeOrderIndex !== questionList.length - 1) {
setActiveOrderIndex(activeIndex + 1);
setActiveIndex(activeIndex + 1);
}
}
}
function renderFooterText() {
if (onlyError && errorCount > 0) {
// 只看错题
return (
<div className='footer-btn'>
<div className='pre-next'>
<div
className={`${activeOrderIndex === (errorQuestionList.length > 0 ? errorQuestionList[0].orderIndex : 0) ? 'disabled' : ''} pre`}
onClick={() => handleChangeActiveIndex(true)}>
<span className='icon iconfont'>&#xe79c;</span>
<div className='text'>上一题</div>
</div>
<div
className={`${activeOrderIndex === (errorQuestionList.length > 0 ? errorQuestionList[errorCount - 1].orderIndex : 0) ? 'disabled' : ''} next`}
onClick={() => handleChangeActiveIndex(false)}>
<div className='text'>下一题</div>
<span className='icon iconfont'>&#xe79b;</span>
</div>
</div>
</div>
);
} else if (!onlyError) {
return (
<div className='footer-btn'>
<div className='pre-next'>
<div className={`${activeOrderIndex === 0 ? 'disabled' : ''} pre`} onClick={() => handleChangeActiveIndex(true)}>
<span className='icon iconfont'>&#xe79c;</span>
<div className='text'>上一题</div>
</div>
<div className={`${activeOrderIndex === questionList.length - 1 ? 'disabled' : ''} next`} onClick={() => handleChangeActiveIndex(false)}>
<div className='text'>下一题</div>
<span className='icon iconfont'>&#xe79b;</span>
</div>
</div>
</div>
);
}
}
function handleRenderQuestionItem() { function handleRenderQuestionItem() {
return _.map(questionList, (questionItem, questionIndex) => { return _.map(questionList, (questionItem, questionIndex) => {
const { questionStemList, optionList, gapFillingAnswerList, questionAnswerDescList, questionType, score, questionId, orderIndex } = questionItem; const { questionStemList, optionList, gapFillingAnswerList, questionType, score, questionId, orderIndex } = questionItem;
return ( return (
<div className={`question-info-item`}> <div className={`question-info-item`}>
{renderStem(questionItem, questionStemList, questionType, score, orderIndex, questionId, gapFillingAnswerList)} {renderStem(questionItem, questionStemList, questionType, score, orderIndex, questionId, gapFillingAnswerList)}
...@@ -225,7 +166,6 @@ function AnswerDescPage(props) { ...@@ -225,7 +166,6 @@ function AnswerDescPage(props) {
return renderOption(optionItem, optionIndex, questionId); return renderOption(optionItem, optionIndex, questionId);
})} })}
{renderAnswerCompare(questionId, questionType, optionList, gapFillingAnswerList)} {renderAnswerCompare(questionId, questionType, optionList, gapFillingAnswerList)}
{/* {renderAnswerDesc(questionAnswerDescList)} */}
</div> </div>
); );
}); });
...@@ -503,133 +443,6 @@ function AnswerDescPage(props) { ...@@ -503,133 +443,6 @@ function AnswerDescPage(props) {
} }
} }
// 渲染答案解析
function renderAnswerDesc(questionAnswerDescList) {
const textContent = _.filter(questionAnswerDescList, (item) => {
return item.type === 'RICH_TEXT';
});
const mediaContent = _.filter(questionAnswerDescList, (item) => {
return item.type !== 'RICH_TEXT';
});
let content = textContent.length > 0 ? `${textContent[0].content}:` : '';
let textDom = (
<div
key={0}
className='text-dom'
dangerouslySetInnerHTML={{
__html: content,
}}
/>
);
return (
<div className='desc-line__item'>
{textDom}
{renderAnswerDescMedia(mediaContent)}
</div>
);
}
// 渲染答案解析的多媒体
function renderAnswerDescMedia(mediaContent) {
const pictureMediaList = _.filter(mediaContent, (mediaItem) => {
return mediaItem.type === 'PICTURE';
});
const voiceMediaList = _.filter(mediaContent, (mediaItem) => {
return mediaItem.type === 'VOICE';
});
const audioMediaList = _.filter(mediaContent, (mediaItem) => {
return mediaItem.type === 'AUDIO';
});
const videoMediaList = _.filter(mediaContent, (mediaItem) => {
return mediaItem.type === 'VIDEO';
});
return (
<div className='desc-media-container'>
{pictureMediaList.length > 0 && (
<div className='desc-picture-box'>
{_.map(pictureMediaList, (pictureItem, pictureIndex) => {
let { content } = pictureItem;
return (
<div className='picture-box' key={pictureIndex}>
<img className='img-box' src={content} onClick={() => handleScanFile('JPG', content)} />
</div>
);
})}
</div>
)}
{audioMediaList.length > 0 && (
<div className='desc-audio-box'>
{_.map(audioMediaList, (audioItem, audioIndex) => {
let { content, size } = audioItem;
return (
<div className='audio-box' key={audioIndex}>
<XMAudio
forbidParse
url={content}
getDuration={(durationSize) => {
size = durationSize;
}}
index={audioIndex}
size={size || 1000}
/>
</div>
);
})}
</div>
)}
{voiceMediaList.length > 0 && (
<div className='desc-audio-box'>
{_.map(voiceMediaList, (voiceItem, voiceIndex) => {
let { content, size } = voiceItem;
return (
<div className='audio-box' key={voiceIndex}>
<XMAudio
forbidParse
url={content}
getDuration={(durationSize) => {
size = durationSize;
}}
index={voiceIndex}
size={size || 1000}
/>
</div>
);
})}
</div>
)}
{videoMediaList.length > 0 && (
<div className='desc-video-box'>
{_.map(videoMediaList, (videoItem, videoIndex) => {
let { content } = videoItem;
return (
<div className='video-box' key={videoIndex}>
<img className='video-box_content' src={`${content}?x-oss-process=video/snapshot,t_0,m_fast`} />
<img className='video-box_btn' src='https://image.xiaomaiketang.com/xm/r5H8cYm4ch.png' onClick={() => handleScanFile('MP4', content)} />
</div>
);
})}
</div>
)}
</div>
);
}
// 答题卡展开和收起
function handleToggleQuestionCardShow() {
setIsShowQuestionCard(!isShowQuestionCard);
}
// 快速跳转题目
function handleQuickActiveQuestion(orderIndex, answerIndex) {
setActiveOrderIndex(orderIndex);
setActiveIndex(answerIndex);
setIsShowQuestionCard(false);
}
// 只选错题 // 只选错题
function chooseErrorAnswer() { function chooseErrorAnswer() {
...@@ -640,8 +453,6 @@ function AnswerDescPage(props) { ...@@ -640,8 +453,6 @@ function AnswerDescPage(props) {
setQuestionList(!onlyError ? errorQuestionList : allQuestionList); setQuestionList(!onlyError ? errorQuestionList : allQuestionList);
} }
const { totalQuestionCount, userCorrectQuestion } = examDetail;
let sortedAnswerList = []; let sortedAnswerList = [];
let userAnswerMap = {}; let userAnswerMap = {};
userAnswerList.forEach((item) => { userAnswerList.forEach((item) => {
...@@ -689,7 +500,6 @@ function AnswerDescPage(props) { ...@@ -689,7 +500,6 @@ function AnswerDescPage(props) {
<div className='question-list-box'>{handleRenderQuestionItem()}</div> <div className='question-list-box'>{handleRenderQuestionItem()}</div>
</div> </div>
</If> </If>
{/* {renderFooterText()} */}
</div> </div>
{showScanFile && ( {showScanFile && (
<ScanFileModal <ScanFileModal
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-23 18:28:50 * @Date: 2021-02-23 18:28:50
* @LastEditors: fusanqiasng * @LastEditors: fusanqiasng
* @LastEditTime: 2021-06-16 17:35:55 * @LastEditTime: 2021-06-25 14:35:20
* @Description: 助学工具-课程分类 * @Description: 助学工具-课程分类
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -14,9 +14,11 @@ import AidToolService from '@/domains/aid-tool-domain/AidToolService'; ...@@ -14,9 +14,11 @@ import AidToolService from '@/domains/aid-tool-domain/AidToolService';
import User from '@/common/js/user'; import User from '@/common/js/user';
import { Tree, Input, Space, Button, Menu, Dropdown, message, Modal } from 'antd'; import { Tree, Input, Space, Button, Menu, Dropdown, message, Modal } from 'antd';
import ShowTips from '@/components/ShowTips'; import ShowTips from '@/components/ShowTips';
import LottieIcon from '@/components/LottieIcon';
const { DirectoryTree } = Tree; const { DirectoryTree } = Tree;
const { Search } = Input; const { Search } = Input;
const { confirm } = Modal; const { confirm } = Modal;
class CourseCategoryManage extends Component { class CourseCategoryManage extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
...@@ -567,6 +569,9 @@ class CourseCategoryManage extends Component { ...@@ -567,6 +569,9 @@ class CourseCategoryManage extends Component {
<ShowTips message='为方便管理,该分类用于课程、培训计划、题库、知识库等模块,改动将同步各模块更新' /> <ShowTips message='为方便管理,该分类用于课程、培训计划、题库、知识库等模块,改动将同步各模块更新' />
</div> </div>
<div className='course-category-tree'> <div className='course-category-tree'>
{
<Choose>
<When condition={treeData.length !== 0}>
<DirectoryTree <DirectoryTree
expandedKeys={expandedKeys} expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent} autoExpandParent={autoExpandParent}
...@@ -577,6 +582,12 @@ class CourseCategoryManage extends Component { ...@@ -577,6 +582,12 @@ class CourseCategoryManage extends Component {
blockNode blockNode
onDrop={this.onDrop} onDrop={this.onDrop}
treeData={treeData}></DirectoryTree> treeData={treeData}></DirectoryTree>
</When>
<Otherwise>
<LottieIcon title={<span className='desc'>搜索无结果</span>} type='search' size={150} />
</Otherwise>
</Choose>
}
</div> </div>
</div> </div>
{operateCourseCategoryModal} {operateCourseCategoryModal}
......
...@@ -14,6 +14,12 @@ ...@@ -14,6 +14,12 @@
margin-top: 12px; margin-top: 12px;
width: 900px; width: 900px;
border: 1px solid #e8e8e8; border: 1px solid #e8e8e8;
.lottie-icon {
margin-top: 100px!important;
.desc {
color: #999!important;
}
}
.ant-tree.ant-tree-directory { .ant-tree.ant-tree-directory {
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
......
import React, { useState, useRef, useEffect, useContext } from 'react' import React, { useState, useRef, useEffect, useContext } from 'react';
import Service from "@/common/js/service"; import Service from '@/common/js/service';
import { PageControl } from "@/components"; import { PageControl } from '@/components';
import { Input, Select, Tooltip, Button, Table } from 'antd'; import { Input, Select, Tooltip, Button, Table } from 'antd';
import User from "@/common/js/user"; import User from '@/common/js/user';
import moment from 'moment'; import moment from 'moment';
import './userData.less' import './userData.less';
const { Search } = Input; const { Search } = Input;
const { Option } = Select; const { Option } = Select;
interface sortType { interface sortType {
type: "ascend" | "descend" | null | undefined type: 'ascend' | 'descend' | null | undefined;
} }
function ExamData(props: any) { function ExamData(props: any) {
const sortStatus: sortType = { const sortStatus: sortType = {
type: undefined type: undefined,
} };
const examDataInit: any = {}; const examDataInit: any = {};
const queryInit: any = { current: 1, size: 10, order: 'SORT_ASC' }; const queryInit: any = { current: 1, size: 10, order: 'SORT_ASC' };
...@@ -28,165 +27,152 @@ function ExamData(props: any) { ...@@ -28,165 +27,152 @@ function ExamData(props: any) {
const [allData, setAllData] = useState(0); const [allData, setAllData] = useState(0);
const [order, setOrder] = useState(sortStatus.type); const [order, setOrder] = useState(sortStatus.type);
const questionTypeList = { const questionTypeList = {
SINGLE_CHOICE: "单选题", SINGLE_CHOICE: '单选题',
MULTI_CHOICE: "多选题", MULTI_CHOICE: '多选题',
JUDGE: "判断题", JUDGE: '判断题',
GAP_FILLING: "填空题", GAP_FILLING: '填空题',
INDEFINITE_CHOICE: "不定项选择题", INDEFINITE_CHOICE: '不定项选择题',
}; };
const userTypeEnum = { const userTypeEnum = {
WORK_WE_CHAT: '企业微信', WORK_WE_CHAT: '企业微信',
WE_CHAT: '微信' WE_CHAT: '微信',
} };
const userExamStateEnum = { const userExamStateEnum = {
EXAM: '进行中', EXAM: '进行中',
LACK_EXAM: '缺考', LACK_EXAM: '缺考',
FINISH_EXAM: '已考试' FINISH_EXAM: '已考试',
} };
const orderEnum = { const orderEnum = {
currentAccuracy: { currentAccuracy: {
ascend: 'ACCURACY_ASC', ascend: 'ACCURACY_ASC',
descend: 'ACCURACY_DESC' descend: 'ACCURACY_DESC',
}, },
};
}
const queryRef = useRef({}); const queryRef = useRef({});
useEffect(() => { useEffect(() => {
queryExamUserData(); queryExamUserData();
}, []) }, []);
useEffect(() => { useEffect(() => {
queryRef.current = query; queryRef.current = query;
queryExamUserDataList(); queryExamUserDataList();
}, [query]) }, [query]);
function queryExamUserData() { function queryExamUserData() {
Service.Hades('public/hades/queryExamQuestionData', { Service.Hades('public/hades/queryExamQuestionData', {
examId: props.examId, examId: props.examId,
tenantId: User.getStoreId(), tenantId: User.getStoreId(),
userId: User.getStoreUserId(), userId: User.getStoreUserId(),
source: 0 source: 0,
}).then((res) => { }).then((res) => {
setUserData(res.result) setUserData(res.result);
});
})
} }
function queryExamUserDataList() { function queryExamUserDataList() {
Service.Hades('public/hades/queryExamQuestionDataList', { Service.Hades('public/hades/queryExamQuestionDataList', {
...query, ...query,
examId: props.examId, examId: props.examId,
tenantId: User.getStoreId(), tenantId: User.getStoreId(),
userId: User.getStoreUserId(), userId: User.getStoreUserId(),
source: 0 source: 0,
}).then((res) => { }).then((res) => {
setList(res.result.records); setList(res.result.records);
setTotal(parseInt(res.result.total)) setTotal(parseInt(res.result.total));
if (!allData) { if (!allData) {
setAllData(parseInt(res.result.total)) setAllData(parseInt(res.result.total));
} }
}) });
} }
const columns = [ const columns = [
{ {
title: "序号", title: '序号',
dataIndex: "sort", dataIndex: 'sort',
width: 60, width: 60,
render: (text: any) => <span>{text + 1}</span>, render: (text: any, record: any, index: any) => <span>{index + 1}</span>,
}, },
{ {
title: "题目", title: '题目',
dataIndex: "questionStem", dataIndex: 'questionStem',
ellipsis: true, ellipsis: true,
width: 350, width: 350,
render: (val: any) => { render: (val: any) => {
var handleVal = val; var handleVal = val;
handleVal = handleVal.replace(/<(?!img|input).*?>/g, ""); handleVal = handleVal.replace(/<(?!img|input).*?>/g, '');
handleVal = handleVal.replace(/<\s?input[^>]*>/gi, "_、"); handleVal = handleVal.replace(/<\s?input[^>]*>/gi, '_、');
handleVal = handleVal.replace(/\&nbsp\;/gi, " "); handleVal = handleVal.replace(/\&nbsp\;/gi, ' ');
return ( return (
<Tooltip <Tooltip
overlayClassName="aid-tool-list" overlayClassName='aid-tool-list'
title={ title={<div style={{ maxWidth: 700, width: 'auto' }}>{handleVal}</div>}
<div style={{ maxWidth: 700, width: "auto" }}>{handleVal}</div> placement='topLeft'
} overlayStyle={{ maxWidth: 700 }}>
placement="topLeft"
overlayStyle={{ maxWidth: 700 }}
>
{handleVal} {handleVal}
</Tooltip> </Tooltip>
); );
}, },
}, },
{ {
title: "题型", title: '题型',
dataIndex: "questionType", dataIndex: 'questionType',
render: (text: any) => <span>{(questionTypeList as any)[text]}</span>, render: (text: any) => <span>{(questionTypeList as any)[text]}</span>,
filters: Object.keys(questionTypeList).map((key) => { filters: Object.keys(questionTypeList).map((key) => {
return { return {
text: (questionTypeList as any)[key], text: (questionTypeList as any)[key],
value: key value: key,
} };
}), }),
}, },
{ {
title: "本次正确率", title: '本次正确率',
dataIndex: "currentAccuracy", dataIndex: 'currentAccuracy',
sorter: true, sorter: true,
sortOrder: field === "currentAccuracy" ? order : sortStatus.type, sortOrder: field === 'currentAccuracy' ? order : sortStatus.type,
render: (text: any) => <span>{parseInt(text * 100 as any)}%</span>, render: (text: any) => <span>{parseInt((text * 100) as any)}%</span>,
}, },
{ {
title: <div>历史正确率 <Tooltip title: (
overlayClassName="tool-list" <div>
title='包含本次考试正确率' 历史正确率{' '}
placement="top" <Tooltip overlayClassName='tool-list' title='包含本次考试正确率' placement='top' overlayStyle={{ maxWidth: 700 }}>
overlayStyle={{ maxWidth: 700 }} {' '}
> <span style={{ color: 'rgba(191, 191, 191, 1)' }} className="icon iconfont">&#xe61d;</span> <span style={{ color: 'rgba(191, 191, 191, 1)' }} className='icon iconfont'>
&#xe61d;
</span>
</Tooltip> </Tooltip>
</div>, </div>
dataIndex: "totalAccuracy", ),
render: (text: any) => <span>{parseInt(text * 100 as any)}%</span>, dataIndex: 'totalAccuracy',
render: (text: any) => <span>{parseInt((text * 100) as any)}%</span>,
}, },
]; ];
function onChange(pagination: any, filters: any, sorter: any, extra: any) { function onChange(pagination: any, filters: any, sorter: any, extra: any) {
console.log(filters, sorter); console.log(filters, sorter);
setfield(sorter.field); setfield(sorter.field);
setOrder(sorter.order) setOrder(sorter.order);
console.log(sorter.field, sorter.order, (orderEnum as any)[sorter.field]) console.log(sorter.field, sorter.order, (orderEnum as any)[sorter.field]);
let _query: any = { ...queryRef.current }; let _query: any = { ...queryRef.current };
console.log(filters.questionType) console.log(filters.questionType);
if (filters.questionType) { if (filters.questionType) {
console.log(233232) console.log(233232);
_query.questionType = filters.questionType; _query.questionType = filters.questionType;
_query.current = 1; _query.current = 1;
} else { } else {
delete _query.questionType delete _query.questionType;
} }
_query.order = (orderEnum as any)[sorter.field][sorter.order] _query.order = (orderEnum as any)[sorter.field][sorter.order];
setQuery(_query) setQuery(_query);
} }
function download() { function download() {
Service.Hades('public/hades/exportExamData', { Service.Hades('public/hades/exportExamData', {
// ...query, // ...query,
...@@ -194,103 +180,102 @@ function ExamData(props: any) { ...@@ -194,103 +180,102 @@ function ExamData(props: any) {
exportDataType: 'EXAM_QUESTION_DATA', exportDataType: 'EXAM_QUESTION_DATA',
tenantId: User.getStoreId(), tenantId: User.getStoreId(),
userId: User.getStoreUserId(), userId: User.getStoreUserId(),
source: 0 source: 0,
}).then((res) => { }).then((res) => {
const dom = (document as any).getElementById("load-play-back-excel") const dom = (document as any).getElementById('load-play-back-excel');
dom.setAttribute('href', res.result); dom.setAttribute('href', res.result);
dom.click(); dom.click();
});
})
} }
return (
<div className='rr'>
return <div className="rr"> <a download id='load-play-back-excel' style={{ position: 'absolute', left: '-10000px' }}></a>
<a <div className='dataPanal'>
download {!!examData.singleChoiceCnt && (
id="load-play-back-excel" <div className='item'>
style={{ position: "absolute", left: "-10000px" }} <div className='num'>{Math.round((examData.singleChoiceAccuracy || 0) * 100)}%</div>
></a> <div className='percent'>正确率</div>
<div className="dataPanal"> <div className='subTitle'>
{ <div className='type'>
!!examData.singleChoiceCnt && <div className="item"> <span className='icon iconfont'>&#xe7fa;</span>单选题 <span>(共{examData.singleChoiceCnt}题)</span>
<div className="num">{Math.round((examData.singleChoiceAccuracy || 0) * 100)}%</div>
<div className="percent">正确率</div>
<div className="subTitle"><div className="type"><span className="icon iconfont">&#xe7fa;</span>单选题 <span>(共{examData.singleChoiceCnt}题)</span></div></div>
</div> </div>
}
{
!!examData.multiChoiceCnt && <div className="item">
<div className="num">{Math.round((examData.multiChoiceAccuracy || 0) * 100)}%</div>
<div className="percent">正确率</div>
<div className="subTitle"><div className="type"><span className="icon iconfont">&#xe7fb;</span>多选题<span>(共{examData.multiChoiceCnt}题)</span></div></div>
</div> </div>
}
{
!!examData.judgeCnt && <div className="item">
<div className="num">{Math.round((examData.judgeAccuracy || 0) * 100)}%</div>
<div className="percent">正确率</div>
<div className="subTitle"><div className="type"><span className="icon iconfont">&#xe7fc;</span>判断题<span>(共{examData.judgeCnt}题)</span></div></div>
</div> </div>
} )}
{!!examData.multiChoiceCnt && (
{ <div className='item'>
!!examData.gapFillingCnt && <div className="item"> <div className='num'>{Math.round((examData.multiChoiceAccuracy || 0) * 100)}%</div>
<div className="num">{Math.round((examData.gapFillingAccuracy || 0) * 100)}%</div> <div className='percent'>正确率</div>
<div className="percent">正确率</div> <div className='subTitle'>
<div className="subTitle"><div className="type"><span className="icon iconfont">&#xe7fd;</span>填空题<span>(共{examData.gapFillingCnt}题)</span></div></div> <div className='type'>
<span className='icon iconfont'>&#xe7fb;</span>多选题<span>(共{examData.multiChoiceCnt}题)</span>
</div> </div>
}
{
!!examData.indefiniteChoiceCnt && <div className="item">
<div className="num">{Math.round((examData.indefiniteChoiceAccuracy || 0) * 100)}%</div>
<div className="percent">正确率</div>
<div className="subTitle"><div className="type"><span className="icon iconfont">&#xe7fe;</span>不定项选择题 <span>(共{examData.indefiniteChoiceCnt}题)</span></div></div>
</div> </div>
}
</div> </div>
{ )}
!!allData && <Button style={{ marginBottom: 12, marginTop: 12 }} onClick={download} >导出</Button>
} {!!examData.judgeCnt && (
<div className='item'>
<div className='num'>{Math.round((examData.judgeAccuracy || 0) * 100)}%</div>
<div className="content"> <div className='percent'>正确率</div>
<Table <div className='subTitle'>
bordered <div className='type'>
size="small" <span className='icon iconfont'>&#xe7fc;</span>判断题<span>(共{examData.judgeCnt}题)</span>
columns={columns} </div>
dataSource={list} </div>
onChange={onChange} </div>
pagination={false} )}
> {!!examData.gapFillingCnt && (
</Table> <div className='item'>
{total > 0 && <div className='num'>{Math.round((examData.gapFillingAccuracy || 0) * 100)}%</div>
<div className='percent'>正确率</div>
<div className='subTitle'>
<div className='type'>
<span className='icon iconfont'>&#xe7fd;</span>填空题<span>(共{examData.gapFillingCnt}题)</span>
</div>
</div>
</div>
)}
{!!examData.indefiniteChoiceCnt && (
<div className='item'>
<div className='num'>{Math.round((examData.indefiniteChoiceAccuracy || 0) * 100)}%</div>
<div className='percent'>正确率</div>
<div className='subTitle'>
<div className='type'>
<span className='icon iconfont'>&#xe7fe;</span>不定项选择题 <span>(共{examData.indefiniteChoiceCnt}题)</span>
</div>
</div>
</div>
)}
</div>
{!!allData && (
<Button style={{ marginBottom: 12, marginTop: 12 }} onClick={download}>
导出
</Button>
)}
<div className='content'>
<Table bordered size='small' columns={columns} dataSource={list} onChange={onChange} pagination={false}></Table>
{total > 0 && (
<PageControl <PageControl
size="small" size='small'
current={query.current - 1} current={query.current - 1}
pageSize={query.size} pageSize={query.size}
total={total} total={total}
toPage={(page: any) => { toPage={(page: any) => {
console.log(page) console.log(page);
let _query: any = { ...queryRef.current }; let _query: any = { ...queryRef.current };
_query.current = page + 1; _query.current = page + 1;
setQuery(_query) setQuery(_query);
}} }}
/> />
} )}
</div> </div>
</div> </div>
);
} }
export default ExamData; export default ExamData;
import React, { useState, useRef, useEffect, useContext } from 'react'; import React, { useState, useRef, useEffect, useContext } from 'react';
import { Input, Select, DatePicker, Tooltip, Button, Table, Dropdown, Menu, Modal } from 'antd'; import { Input, Select, DatePicker, Tooltip, Button, Dropdown, Menu, Modal } from 'antd';
import TeacherSelect from '@/modules/common/TeacherSelect'; import TeacherSelect from '@/modules/common/TeacherSelect';
import { Route, withRouter } from 'react-router-dom'; import { Route, withRouter } from 'react-router-dom';
import Service from '@/common/js/service'; import Service from '@/common/js/service';
...@@ -14,8 +14,6 @@ import PreviewModal from './PreviewModal'; ...@@ -14,8 +14,6 @@ import PreviewModal from './PreviewModal';
import './index.less'; import './index.less';
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
const { Search } = Input; const { Search } = Input;
const { Option } = Select;
interface sortType { interface sortType {
type: 'ascend' | 'descend' | null | undefined; type: 'ascend' | 'descend' | null | undefined;
} }
...@@ -42,9 +40,7 @@ function ExaminationManager(props: any) { ...@@ -42,9 +40,7 @@ function ExaminationManager(props: any) {
type: undefined, type: undefined,
}; };
const sortEnum = {};
const { match } = props; const { match } = props;
const sortState: any = false;
const ctx: any = useContext(XMContext); const ctx: any = useContext(XMContext);
const [query, setQuery] = useState(queryInit); const [query, setQuery] = useState(queryInit);
const [expandFilter, setExpandFilter] = useState(false); const [expandFilter, setExpandFilter] = useState(false);
...@@ -53,7 +49,6 @@ function ExaminationManager(props: any) { ...@@ -53,7 +49,6 @@ function ExaminationManager(props: any) {
const [field, setfield] = useState(''); const [field, setfield] = useState('');
const [order, setOrder] = useState(sortStatus.type); const [order, setOrder] = useState(sortStatus.type);
const [modal, setModal] = useState(null); const [modal, setModal] = useState(null);
const [questionCntSort, setQuestionCntSort] = useState(sortState);
const [openPreviewModal, setOpenPreviewModal] = useState(false); const [openPreviewModal, setOpenPreviewModal] = useState(false);
const [info, setInfo] = useState({ examDuration: 0 }); const [info, setInfo] = useState({ examDuration: 0 });
const queryRef = useRef({}); const queryRef = useRef({});
...@@ -76,7 +71,6 @@ function ExaminationManager(props: any) { ...@@ -76,7 +71,6 @@ function ExaminationManager(props: any) {
const columns = [ const columns = [
{ {
title: '考试', title: '考试',
// fixed:fixStr.left,
width: 320, width: 320,
dataIndex: 'examName', dataIndex: 'examName',
render: (text: any, record: any) => { render: (text: any, record: any) => {
...@@ -279,9 +273,6 @@ function ExaminationManager(props: any) { ...@@ -279,9 +273,6 @@ function ExaminationManager(props: any) {
function getList() { function getList() {
const _query = { ...queryRef.current }; const _query = { ...queryRef.current };
// if(_query.examCreator){
// _query.examCreator =parseInt(_query.examCreator)
// }
Service.Hades('public/hades/queryExamPageList', { Service.Hades('public/hades/queryExamPageList', {
..._query, ..._query,
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
} }
.table-style { .table-style {
border: 1px solid #f0f0f0 !important; border: 1px solid #f0f0f0 !important;
margin-bottom: 70px;
} }
.ant-tabs { .ant-tabs {
color: #666666; color: #666666;
......
...@@ -11,6 +11,7 @@ import { Modal, Button, message, Spin } from "antd"; ...@@ -11,6 +11,7 @@ import { Modal, Button, message, Spin } from "antd";
import "./BatchImportQuestionModal.less"; import "./BatchImportQuestionModal.less";
import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal"; import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal";
import User from "@/common/js/user"; import User from "@/common/js/user";
import moment from "moment";
import AidToolService from "@/domains/aid-tool-domain/AidToolService"; import AidToolService from "@/domains/aid-tool-domain/AidToolService";
import { LoadingOutlined } from "@ant-design/icons"; import { LoadingOutlined } from "@ant-design/icons";
class BatchImportQuestionModal extends Component { class BatchImportQuestionModal extends Component {
...@@ -48,6 +49,15 @@ class BatchImportQuestionModal extends Component { ...@@ -48,6 +49,15 @@ class BatchImportQuestionModal extends Component {
// 导入 // 导入
handleImport = async () => { handleImport = async () => {
//过期判断
if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) {
Modal.warning({
title:"服务已到期",
content: "当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买",
okText: "我知道了"
})
return
}
const { uploadFile } = this.state; const { uploadFile } = this.state;
if (!uploadFile) { if (!uploadFile) {
message.warning("请选择要导入的文件"); message.warning("请选择要导入的文件");
......
...@@ -7,4 +7,17 @@ ...@@ -7,4 +7,17 @@
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React from 'react'; import React from 'react';
export interface VersionInfo {
dayTime: number; //有效时长
stateEnum: string; //"NO"已过期,"YES"未过期
surplusDayTime: number; //剩余有效天数
surplusUserNum: number; //剩余限制人数
userNum: number; //限制人数
validEndTime: string;
validStartTime: string;
whetherReachUserNum: boolean;
}
export const XMContext: any = React.createContext(null); export const XMContext: any = React.createContext(null);
export const VersionContext = React.createContext<VersionInfo|null>(null)
\ No newline at end of file
...@@ -2451,10 +2451,10 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: ...@@ -2451,10 +2451,10 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
"@types/color-name" "^1.1.1" "@types/color-name" "^1.1.1"
color-convert "^2.0.1" color-convert "^2.0.1"
antd@^4.9.4: antd@4.16.5:
version "4.15.6" version "4.16.5"
resolved "https://registry.yarnpkg.com/antd/-/antd-4.15.6.tgz#bc4359b8f232c8bbb073d7236446edc9aa658d38" resolved "https://registry.nlark.com/antd/download/antd-4.16.5.tgz#6105bd848fb2e468e0d1d3ec024c82d2516587ef"
integrity sha512-uXn1uRFlPLrAmjfkyxKc3avMVO5N30o3YoSMSJPRw5OLNjOfWsnZDPKvZwinn+QQE9N7dRXylcMfNvl11LH2gA== integrity sha1-YQW9hI+y5Gjg0dPsAkyC0lFlh+8=
dependencies: dependencies:
"@ant-design/colors" "^6.0.0" "@ant-design/colors" "^6.0.0"
"@ant-design/icons" "^4.6.2" "@ant-design/icons" "^4.6.2"
...@@ -2474,10 +2474,10 @@ antd@^4.9.4: ...@@ -2474,10 +2474,10 @@ antd@^4.9.4:
rc-field-form "~1.20.0" rc-field-form "~1.20.0"
rc-image "~5.2.4" rc-image "~5.2.4"
rc-input-number "~7.1.0" rc-input-number "~7.1.0"
rc-mentions "~1.5.0" rc-mentions "~1.6.1"
rc-menu "~8.10.0" rc-menu "~9.0.12"
rc-motion "^2.4.0" rc-motion "^2.4.0"
rc-notification "~4.5.2" rc-notification "~4.5.7"
rc-pagination "~3.1.6" rc-pagination "~3.1.6"
rc-picker "~2.5.10" rc-picker "~2.5.10"
rc-progress "~3.1.0" rc-progress "~3.1.0"
...@@ -2487,15 +2487,15 @@ antd@^4.9.4: ...@@ -2487,15 +2487,15 @@ antd@^4.9.4:
rc-slider "~9.7.1" rc-slider "~9.7.1"
rc-steps "~4.1.0" rc-steps "~4.1.0"
rc-switch "~3.2.0" rc-switch "~3.2.0"
rc-table "~7.13.0" rc-table "~7.15.1"
rc-tabs "~11.7.0" rc-tabs "~11.9.1"
rc-textarea "~0.3.0" rc-textarea "~0.3.0"
rc-tooltip "~5.1.1" rc-tooltip "~5.1.1"
rc-tree "~4.1.0" rc-tree "~4.1.0"
rc-tree-select "~4.3.0" rc-tree-select "~4.3.0"
rc-trigger "^5.2.1" rc-trigger "^5.2.1"
rc-upload "~4.3.0" rc-upload "~4.3.0"
rc-util "^5.9.4" rc-util "^5.13.1"
scroll-into-view-if-needed "^2.2.25" scroll-into-view-if-needed "^2.2.25"
warning "^4.0.3" warning "^4.0.3"
...@@ -3552,6 +3552,11 @@ classnames@2.x, classnames@^2.2.1, classnames@^2.2.3, classnames@^2.2.5, classna ...@@ -3552,6 +3552,11 @@ classnames@2.x, classnames@^2.2.1, classnames@^2.2.3, classnames@^2.2.5, classna
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
classnames@^2.3.1:
version "2.3.1"
resolved "https://registry.npm.taobao.org/classnames/download/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
integrity sha1-38+jiR4wbsHa0QXQ6I9EF7hTXo4=
clean-css@^4.2.3: clean-css@^4.2.3:
version "4.2.3" version "4.2.3"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
...@@ -3927,6 +3932,17 @@ cosmiconfig@^6.0.0: ...@@ -3927,6 +3932,17 @@ cosmiconfig@^6.0.0:
path-type "^4.0.0" path-type "^4.0.0"
yaml "^1.7.2" yaml "^1.7.2"
cosmiconfig@^7.0.0:
version "7.0.0"
resolved "https://registry.npm.taobao.org/cosmiconfig/download/cosmiconfig-7.0.0.tgz?cache=0&sync_timestamp=1596310773001&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcosmiconfig%2Fdownload%2Fcosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3"
integrity sha1-75tE13OVnK5j3ezRIt4jhTtg+NM=
dependencies:
"@types/parse-json" "^4.0.0"
import-fresh "^3.2.1"
parse-json "^5.0.0"
path-type "^4.0.0"
yaml "^1.10.0"
create-ecdh@^4.0.0: create-ecdh@^4.0.0:
version "4.0.3" version "4.0.3"
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff"
...@@ -5750,12 +5766,20 @@ find-up@^3.0.0: ...@@ -5750,12 +5766,20 @@ find-up@^3.0.0:
dependencies: dependencies:
locate-path "^3.0.0" locate-path "^3.0.0"
find-versions@^3.2.0: find-up@^5.0.0:
version "3.2.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e" resolved "https://registry.npm.taobao.org/find-up/download/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww== integrity sha1-TJKBnstwg1YeT0okCoa+UZj1Nvw=
dependencies: dependencies:
semver-regex "^2.0.0" locate-path "^6.0.0"
path-exists "^4.0.0"
find-versions@^4.0.0:
version "4.0.0"
resolved "https://registry.nlark.com/find-versions/download/find-versions-4.0.0.tgz?cache=0&sync_timestamp=1619599444272&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ffind-versions%2Fdownload%2Ffind-versions-4.0.0.tgz#3c57e573bf97769b8cb8df16934b627915da4965"
integrity sha1-PFflc7+XdpuMuN8Wk0tieRXaSWU=
dependencies:
semver-regex "^3.1.2"
flat-cache@^2.0.1: flat-cache@^2.0.1:
version "2.0.1" version "2.0.1"
...@@ -6352,7 +6376,7 @@ hmac-drbg@^1.0.0: ...@@ -6352,7 +6376,7 @@ hmac-drbg@^1.0.0:
minimalistic-assert "^1.0.0" minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1" minimalistic-crypto-utils "^1.0.1"
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.2: hoist-non-react-statics@^3.1.0:
version "3.3.2" version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
...@@ -6554,18 +6578,18 @@ humanize-ms@^1.2.0, humanize-ms@^1.2.1: ...@@ -6554,18 +6578,18 @@ humanize-ms@^1.2.0, humanize-ms@^1.2.1:
dependencies: dependencies:
ms "^2.0.0" ms "^2.0.0"
husky@^4.2.5: husky@^4.3.0:
version "4.2.5" version "4.3.8"
resolved "https://registry.yarnpkg.com/husky/-/husky-4.2.5.tgz#2b4f7622673a71579f901d9885ed448394b5fa36" resolved "https://registry.npm.taobao.org/husky/download/husky-4.3.8.tgz?cache=0&sync_timestamp=1617004245593&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhusky%2Fdownload%2Fhusky-4.3.8.tgz#31144060be963fd6850e5cc8f019a1dfe194296d"
integrity sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ== integrity sha1-MRRAYL6WP9aFDlzI8Bmh3+GUKW0=
dependencies: dependencies:
chalk "^4.0.0" chalk "^4.0.0"
ci-info "^2.0.0" ci-info "^2.0.0"
compare-versions "^3.6.0" compare-versions "^3.6.0"
cosmiconfig "^6.0.0" cosmiconfig "^7.0.0"
find-versions "^3.2.0" find-versions "^4.0.0"
opencollective-postinstall "^2.0.2" opencollective-postinstall "^2.0.2"
pkg-dir "^4.2.0" pkg-dir "^5.0.0"
please-upgrade-node "^3.2.0" please-upgrade-node "^3.2.0"
slash "^3.0.0" slash "^3.0.0"
which-pm-runs "^1.0.0" which-pm-runs "^1.0.0"
...@@ -6649,6 +6673,14 @@ import-fresh@^3.0.0, import-fresh@^3.1.0: ...@@ -6649,6 +6673,14 @@ import-fresh@^3.0.0, import-fresh@^3.1.0:
parent-module "^1.0.0" parent-module "^1.0.0"
resolve-from "^4.0.0" resolve-from "^4.0.0"
import-fresh@^3.2.1:
version "3.3.0"
resolved "https://registry.npm.taobao.org/import-fresh/download/import-fresh-3.3.0.tgz?cache=0&sync_timestamp=1608469579940&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimport-fresh%2Fdownload%2Fimport-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
integrity sha1-NxYsJfy566oublPVtNiM4X2eDCs=
dependencies:
parent-module "^1.0.0"
resolve-from "^4.0.0"
import-from@^2.1.0: import-from@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1"
...@@ -8088,6 +8120,13 @@ locate-path@^5.0.0: ...@@ -8088,6 +8120,13 @@ locate-path@^5.0.0:
dependencies: dependencies:
p-locate "^4.1.0" p-locate "^4.1.0"
locate-path@^6.0.0:
version "6.0.0"
resolved "https://registry.npm.taobao.org/locate-path/download/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
integrity sha1-VTIeswn+u8WcSAHZMackUqaB0oY=
dependencies:
p-locate "^5.0.0"
lodash._reinterpolate@^3.0.0: lodash._reinterpolate@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
...@@ -8406,14 +8445,6 @@ mini-css-extract-plugin@0.9.0: ...@@ -8406,14 +8445,6 @@ mini-css-extract-plugin@0.9.0:
schema-utils "^1.0.0" schema-utils "^1.0.0"
webpack-sources "^1.1.0" webpack-sources "^1.1.0"
mini-store@^3.0.1:
version "3.0.6"
resolved "https://registry.yarnpkg.com/mini-store/-/mini-store-3.0.6.tgz#44b86be5b2877271224ce0689b3a35a2dffb1ca9"
integrity sha512-YzffKHbYsMQGUWQRKdsearR79QsMzzJcDDmZKlJBqt5JNkqpyJHYlK6gP61O36X+sLf76sO9G6mhKBe83gIZIQ==
dependencies:
hoist-non-react-statics "^3.3.2"
shallowequal "^1.0.2"
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
...@@ -9083,6 +9114,13 @@ p-limit@^2.3.0: ...@@ -9083,6 +9114,13 @@ p-limit@^2.3.0:
dependencies: dependencies:
p-try "^2.0.0" p-try "^2.0.0"
p-limit@^3.0.2:
version "3.1.0"
resolved "https://registry.nlark.com/p-limit/download/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
integrity sha1-4drMvnjQ0TiMoYxk/qOOPlfjcGs=
dependencies:
yocto-queue "^0.1.0"
p-locate@^2.0.0: p-locate@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
...@@ -9104,6 +9142,13 @@ p-locate@^4.1.0: ...@@ -9104,6 +9142,13 @@ p-locate@^4.1.0:
dependencies: dependencies:
p-limit "^2.2.0" p-limit "^2.2.0"
p-locate@^5.0.0:
version "5.0.0"
resolved "https://registry.nlark.com/p-locate/download/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
integrity sha1-g8gxXGeFAF470CGDlBHJ4RDm2DQ=
dependencies:
p-limit "^3.0.2"
p-map@^2.0.0: p-map@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
...@@ -9439,13 +9484,20 @@ pkg-dir@^3.0.0: ...@@ -9439,13 +9484,20 @@ pkg-dir@^3.0.0:
dependencies: dependencies:
find-up "^3.0.0" find-up "^3.0.0"
pkg-dir@^4.1.0, pkg-dir@^4.2.0: pkg-dir@^4.1.0:
version "4.2.0" version "4.2.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
dependencies: dependencies:
find-up "^4.0.0" find-up "^4.0.0"
pkg-dir@^5.0.0:
version "5.0.0"
resolved "https://registry.nlark.com/pkg-dir/download/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760"
integrity sha1-oC1q6+a6EzqSj3Suwguv3+a452A=
dependencies:
find-up "^5.0.0"
pkg-up@3.1.0, pkg-up@^3.1.0: pkg-up@3.1.0, pkg-up@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5"
...@@ -10518,7 +10570,7 @@ rc-drawer@~4.3.0: ...@@ -10518,7 +10570,7 @@ rc-drawer@~4.3.0:
classnames "^2.2.6" classnames "^2.2.6"
rc-util "^5.7.0" rc-util "^5.7.0"
rc-dropdown@^3.1.3, rc-dropdown@~3.2.0: rc-dropdown@^3.2.0, rc-dropdown@~3.2.0:
version "3.2.0" version "3.2.0"
resolved "https://registry.yarnpkg.com/rc-dropdown/-/rc-dropdown-3.2.0.tgz#da6c2ada403842baee3a9e909a0b1a91ba3e1090" resolved "https://registry.yarnpkg.com/rc-dropdown/-/rc-dropdown-3.2.0.tgz#da6c2ada403842baee3a9e909a0b1a91ba3e1090"
integrity sha512-j1HSw+/QqlhxyTEF6BArVZnTmezw2LnSmRk6I9W7BCqNCKaRwleRmMMs1PHbuaG8dKHVqP6e21RQ7vPBLVnnNw== integrity sha512-j1HSw+/QqlhxyTEF6BArVZnTmezw2LnSmRk6I9W7BCqNCKaRwleRmMMs1PHbuaG8dKHVqP6e21RQ7vPBLVnnNw==
...@@ -10555,30 +10607,29 @@ rc-input-number@~7.1.0: ...@@ -10555,30 +10607,29 @@ rc-input-number@~7.1.0:
classnames "^2.2.5" classnames "^2.2.5"
rc-util "^5.9.8" rc-util "^5.9.8"
rc-mentions@~1.5.0: rc-mentions@~1.6.1:
version "1.5.3" version "1.6.1"
resolved "https://registry.yarnpkg.com/rc-mentions/-/rc-mentions-1.5.3.tgz#b92bebadf8ad9fb3586ba1af922d63b49d991c67" resolved "https://registry.nlark.com/rc-mentions/download/rc-mentions-1.6.1.tgz?cache=0&sync_timestamp=1621867143484&other_urls=https%3A%2F%2Fregistry.nlark.com%2Frc-mentions%2Fdownload%2Frc-mentions-1.6.1.tgz#46035027d64aa33ef840ba0fbd411871e34617ae"
integrity sha512-NG/KB8YiKBCJPHHvr/QapAb4f9YzLJn7kDHtmI1K6t7ZMM5YgrjIxNNhoRKKP9zJvb9PdPts69Hbg4ZMvLVIFQ== integrity sha1-RgNQJ9ZKoz74QLoPvUEYceNGF64=
dependencies: dependencies:
"@babel/runtime" "^7.10.1" "@babel/runtime" "^7.10.1"
classnames "^2.2.6" classnames "^2.2.6"
rc-menu "^8.0.1" rc-menu "^9.0.0"
rc-textarea "^0.3.0" rc-textarea "^0.3.0"
rc-trigger "^5.0.4" rc-trigger "^5.0.4"
rc-util "^5.0.1" rc-util "^5.0.1"
rc-menu@^8.0.1, rc-menu@^8.6.1, rc-menu@~8.10.0: rc-menu@^9.0.0, rc-menu@~9.0.12:
version "8.10.8" version "9.0.12"
resolved "https://registry.yarnpkg.com/rc-menu/-/rc-menu-8.10.8.tgz#c3eb2158b3983e42a67192babad9c8128755d26a" resolved "https://registry.nlark.com/rc-menu/download/rc-menu-9.0.12.tgz#492c4bb07a596e2ce07587c669b27ee28c3810c5"
integrity sha512-0gnSR0nmR/60NnK+72EGd+QheHyPSQ3wYg1TwX1zl0JJ9Gm0purFFykCXVv/G0Jynpt0QySPAos+bpHpjMZdoQ== integrity sha1-SSxLsHpZbizgdYfGabJ+4ow4EMU=
dependencies: dependencies:
"@babel/runtime" "^7.10.1" "@babel/runtime" "^7.10.1"
classnames "2.x" classnames "2.x"
mini-store "^3.0.1" rc-motion "^2.4.3"
rc-motion "^2.0.1" rc-overflow "^1.2.0"
rc-trigger "^5.1.2" rc-trigger "^5.1.2"
rc-util "^5.7.0" rc-util "^5.12.0"
resize-observer-polyfill "^1.5.0"
shallowequal "^1.1.0" shallowequal "^1.1.0"
rc-motion@^2.0.0, rc-motion@^2.0.1, rc-motion@^2.2.0, rc-motion@^2.3.0, rc-motion@^2.3.4, rc-motion@^2.4.0: rc-motion@^2.0.0, rc-motion@^2.0.1, rc-motion@^2.2.0, rc-motion@^2.3.0, rc-motion@^2.3.4, rc-motion@^2.4.0:
...@@ -10590,10 +10641,19 @@ rc-motion@^2.0.0, rc-motion@^2.0.1, rc-motion@^2.2.0, rc-motion@^2.3.0, rc-motio ...@@ -10590,10 +10641,19 @@ rc-motion@^2.0.0, rc-motion@^2.0.1, rc-motion@^2.2.0, rc-motion@^2.3.0, rc-motio
classnames "^2.2.1" classnames "^2.2.1"
rc-util "^5.2.1" rc-util "^5.2.1"
rc-notification@~4.5.2: rc-motion@^2.4.3:
version "4.5.5" version "2.4.4"
resolved "https://registry.yarnpkg.com/rc-notification/-/rc-notification-4.5.5.tgz#9660a495d5f20bd677686e4f7fc00e4f0c1a3849" resolved "https://registry.nlark.com/rc-motion/download/rc-motion-2.4.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Frc-motion%2Fdownload%2Frc-motion-2.4.4.tgz#e995d5fa24fc93065c24f714857cf2677d655bb0"
integrity sha512-YIfhTSw+h5GsSdgMnuMx24wqiPlg3FeamuOlkh9RkyHx+SeZVAKzQ0juy2NGvPEF2hDWi5xTqxUqLdo0L2AmGg== integrity sha1-6ZXV+iT8kwZcJPcUhXzyZ31lW7A=
dependencies:
"@babel/runtime" "^7.11.1"
classnames "^2.2.1"
rc-util "^5.2.1"
rc-notification@~4.5.7:
version "4.5.7"
resolved "https://registry.nlark.com/rc-notification/download/rc-notification-4.5.7.tgz#265e6e6a0c1a0fac63d6abd4d832eb8ff31522f1"
integrity sha1-Jl5uagwaD6xj1qvU2DLrj/MVIvE=
dependencies: dependencies:
"@babel/runtime" "^7.10.1" "@babel/runtime" "^7.10.1"
classnames "2.x" classnames "2.x"
...@@ -10610,6 +10670,16 @@ rc-overflow@^1.0.0: ...@@ -10610,6 +10670,16 @@ rc-overflow@^1.0.0:
rc-resize-observer "^1.0.0" rc-resize-observer "^1.0.0"
rc-util "^5.5.1" rc-util "^5.5.1"
rc-overflow@^1.2.0:
version "1.2.2"
resolved "https://registry.nlark.com/rc-overflow/download/rc-overflow-1.2.2.tgz#95b0222016c0cdbdc0db85f569c262e7706a5f22"
integrity sha1-lbAiIBbAzb3A24X1acJi53BqXyI=
dependencies:
"@babel/runtime" "^7.11.1"
classnames "^2.2.1"
rc-resize-observer "^1.0.0"
rc-util "^5.5.1"
rc-pagination@~3.1.6: rc-pagination@~3.1.6:
version "3.1.6" version "3.1.6"
resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-3.1.6.tgz#db3c06e50270b52fe272ac527c1fdc2c8d28af1f" resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-3.1.6.tgz#db3c06e50270b52fe272ac527c1fdc2c8d28af1f"
...@@ -10700,26 +10770,26 @@ rc-switch@~3.2.0: ...@@ -10700,26 +10770,26 @@ rc-switch@~3.2.0:
classnames "^2.2.1" classnames "^2.2.1"
rc-util "^5.0.1" rc-util "^5.0.1"
rc-table@~7.13.0: rc-table@~7.15.1:
version "7.13.3" version "7.15.2"
resolved "https://registry.yarnpkg.com/rc-table/-/rc-table-7.13.3.tgz#25d5f5ec47ee2d8a293aff18c4c4b8876f78c22b" resolved "https://registry.nlark.com/rc-table/download/rc-table-7.15.2.tgz#f6ab73b2cfb1c76f3cf9682c855561423c6b5b22"
integrity sha512-oP4fknjvKCZAaiDnvj+yzBaWcg+JYjkASbeWonU1BbrLcomkpKvMUgPODNEzg0QdXA9OGW0PO86h4goDSW06Kg== integrity sha1-9qtzss+xx288+WgshVVhQjxrWyI=
dependencies: dependencies:
"@babel/runtime" "^7.10.1" "@babel/runtime" "^7.10.1"
classnames "^2.2.5" classnames "^2.2.5"
rc-resize-observer "^1.0.0" rc-resize-observer "^1.0.0"
rc-util "^5.4.0" rc-util "^5.13.0"
shallowequal "^1.1.0" shallowequal "^1.1.0"
rc-tabs@~11.7.0: rc-tabs@~11.9.1:
version "11.7.3" version "11.9.1"
resolved "https://registry.yarnpkg.com/rc-tabs/-/rc-tabs-11.7.3.tgz#32a30e59c6992d60fb58115ba0bf2652b337ed43" resolved "https://registry.nlark.com/rc-tabs/download/rc-tabs-11.9.1.tgz?cache=0&sync_timestamp=1621867452307&other_urls=https%3A%2F%2Fregistry.nlark.com%2Frc-tabs%2Fdownload%2Frc-tabs-11.9.1.tgz#5b2e74da9a276978c2172ef9a05ae8af14da74cb"
integrity sha512-5nd2NVss9TprPRV9r8N05SjQyAE7zDrLejxFLcbJ+BdLxSwnGnk3ws/Iq0smqKZUnPQC0XEvnpF3+zlllUUT2w== integrity sha1-Wy502ponaXjCFy75oFrorxTadMs=
dependencies: dependencies:
"@babel/runtime" "^7.11.2" "@babel/runtime" "^7.11.2"
classnames "2.x" classnames "2.x"
rc-dropdown "^3.1.3" rc-dropdown "^3.2.0"
rc-menu "^8.6.1" rc-menu "^9.0.0"
rc-resize-observer "^1.0.0" rc-resize-observer "^1.0.0"
rc-util "^5.5.0" rc-util "^5.5.0"
...@@ -10800,6 +10870,15 @@ rc-util@^5.0.1: ...@@ -10800,6 +10870,15 @@ rc-util@^5.0.1:
react-is "^16.12.0" react-is "^16.12.0"
shallowequal "^1.1.0" shallowequal "^1.1.0"
rc-util@^5.12.0, rc-util@^5.13.0, rc-util@^5.13.1:
version "5.13.1"
resolved "https://registry.nlark.com/rc-util/download/rc-util-5.13.1.tgz#03e74955b5c46a58cbc6236e4d30dd462c755290"
integrity sha1-A+dJVbXEaljLxiNuTTDdRix1UpA=
dependencies:
"@babel/runtime" "^7.12.5"
react-is "^16.12.0"
shallowequal "^1.1.0"
rc-virtual-list@^3.0.1, rc-virtual-list@^3.2.0: rc-virtual-list@^3.0.1, rc-virtual-list@^3.2.0:
version "3.2.6" version "3.2.6"
resolved "https://registry.yarnpkg.com/rc-virtual-list/-/rc-virtual-list-3.2.6.tgz#2c92a40f4425e19881b38134d6bd286a11137d2d" resolved "https://registry.yarnpkg.com/rc-virtual-list/-/rc-virtual-list-3.2.6.tgz#2c92a40f4425e19881b38134d6bd286a11137d2d"
...@@ -11551,10 +11630,10 @@ semver-compare@^1.0.0: ...@@ -11551,10 +11630,10 @@ semver-compare@^1.0.0:
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
semver-regex@^2.0.0: semver-regex@^3.1.2:
version "2.0.0" version "3.1.2"
resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" resolved "https://registry.nlark.com/semver-regex/download/semver-regex-3.1.2.tgz#34b4c0d361eef262e07199dbef316d0f2ab11807"
integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== integrity sha1-NLTA02Hu8mLgcZnb7zFtDyqxGAc=
"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: "semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
version "5.7.1" version "5.7.1"
...@@ -11673,7 +11752,7 @@ shallow-clone@^0.1.2: ...@@ -11673,7 +11752,7 @@ shallow-clone@^0.1.2:
lazy-cache "^0.2.3" lazy-cache "^0.2.3"
mixin-object "^2.0.1" mixin-object "^2.0.1"
shallowequal@^1.0.2, shallowequal@^1.1.0: shallowequal@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
...@@ -13026,17 +13105,17 @@ vary@~1.1.2: ...@@ -13026,17 +13105,17 @@ vary@~1.1.2:
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
vconsole-webpack-plugin@^1.5.2: vconsole-webpack-plugin@^1.6.1:
version "1.5.2" version "1.6.1"
resolved "https://registry.yarnpkg.com/vconsole-webpack-plugin/-/vconsole-webpack-plugin-1.5.2.tgz#4c25b6cc51add03bb4e1562c4d3653431c89af60" resolved "https://registry.nlark.com/vconsole-webpack-plugin/download/vconsole-webpack-plugin-1.6.1.tgz#7a9ee82c0a90d58964034f6d6bd349242ce65a70"
integrity sha512-v3goAnjsurFUy+qUmJCGjW+tzeKzlkrlbY8YnctSbhbrKiyC40hDeVFdGJvv7Drvd+w4xCQ1hJFZa5ESadmljQ== integrity sha1-ep7oLAqQ1YlkA09ta9NJJCzmWnA=
dependencies: dependencies:
vconsole "^3.3.4" vconsole "^3.6"
vconsole@^3.3.4: vconsole@^3.6:
version "3.6.0" version "3.7.0"
resolved "https://registry.yarnpkg.com/vconsole/-/vconsole-3.6.0.tgz#3affe6082271014f8a169ea429b85c148c2cc796" resolved "https://registry.nlark.com/vconsole/download/vconsole-3.7.0.tgz#7b347fc635eb09646bb50f0ce0cbfba1852af1b1"
integrity sha512-vNyB9AwO0gqGub3BLbj4FtwQjlQ8EwhrD1zfcaAwToP/wKcfAoozJiD+6kAzL85FIklgptERcM+c621IEPuItQ== integrity sha1-ezR/xjXrCWRrtQ8M4Mv7oYUq8bE=
dependencies: dependencies:
copy-text-to-clipboard "^3.0.1" copy-text-to-clipboard "^3.0.1"
core-js "^3.11.0" core-js "^3.11.0"
...@@ -13650,6 +13729,11 @@ yallist@^4.0.0: ...@@ -13650,6 +13729,11 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yaml@^1.10.0:
version "1.10.2"
resolved "https://registry.nlark.com/yaml/download/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha1-IwHF/78StGfejaIzOkWeKeeSDks=
yaml@^1.7.2: yaml@^1.7.2:
version "1.8.2" version "1.8.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.8.2.tgz#a29c03f578faafd57dcb27055f9a5d569cb0c3d9" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.8.2.tgz#a29c03f578faafd57dcb27055f9a5d569cb0c3d9"
...@@ -13698,3 +13782,8 @@ yauzl@^2.4.2: ...@@ -13698,3 +13782,8 @@ yauzl@^2.4.2:
dependencies: dependencies:
buffer-crc32 "~0.2.3" buffer-crc32 "~0.2.3"
fd-slicer "~1.1.0" fd-slicer "~1.1.0"
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.nlark.com/yocto-queue/download/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha1-ApTrPe4FAo0x7hpfosVWpqrxChs=
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