Commit c59d9d6e by guomingpang

Merge branch 'dev' of…

Merge branch 'dev' of ssh://xmgit.ixm5.cn:10022/xiaomai-cloud-class/xiaomai-cloud-class-web into dev
parents ed917f83 df3a31a5
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
$(document).ready(function () { $(document).ready(function () {
var BASIC_HOST_MAP = { var BASIC_HOST_MAP = {
dev: 'https://dev-heimdall.xiaomai5.com/', dev: 'https://dev-heimdall.xiaomai5.com/',
dev1: 'https://dev1-heimdall.xiaomai5.com/', dev1: 'https://dev-heimdall.xiaomai5.com/',
rc: 'https://rc-heimdall.xiaomai5.com/', rc: 'https://rc-heimdall.xiaomai5.com/',
gray: 'https://gray-heimdall.xiaomai5.com/', gray: 'https://gray-heimdall.xiaomai5.com/',
prod: 'https://gateway.xiaomai5.com/' prod: 'https://gateway.xiaomai5.com/'
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
.container-left-body-table{ .container-left-body-table{
width: 300px; width: 300px;
height: 330px; height: 330px;
overflow: scroll;
.ant-table { .ant-table {
border: none; border: none;
min-height: 250px !important; min-height: 250px !important;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: wufan * @Author: wufan
* @Date: 2021-05-11 10:21:37 * @Date: 2021-05-11 10:21:37
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-07-19 15:24:27 * @LastEditTime: 2021-07-21 14:25:37
* @Description: 企业微信api * @Description: 企业微信api
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* *
...@@ -14,56 +14,57 @@ import Service from '@/common/js/service'; ...@@ -14,56 +14,57 @@ import Service from '@/common/js/service';
export default class WechatApi { export default class WechatApi {
static async initConfig(params = { isAgentConfig: false, url: '' }) { static async initConfig(params = { isAgentConfig: false, url: '' }) {
if(Platform.isWorkWx()){ if (Platform.isWorkWx()) {
return Service.Hades('anon/hades/getWxCorpJSAPISignature', {
storeId: User.getStoreId(), return new Promise(async (resolve, reject) => {
url: params.url, Service.Hades('anon/hades/getWxCorpJSAPISignature', {
}).then((result) => { storeId: User.getStoreId(),
const res = result.result; url: params.url,
this.config({ }).then((result) => {
beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题 const res = result.result;
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 this.config({
appId: res.appId, // 必填,企业微信的corpID beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
timestamp: res.timestamp, // 必填,生成签名的时间戳 debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
nonceStr: res.nonceStr, // 必填,生成签名的随机串 appId: res.appId, // 必填,企业微信的corpID
signature: res.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法 timestamp: res.timestamp, // 必填,生成签名的时间戳
jsApiList: ['chooseImage', 'shareToExternalContact', 'selectExternalContact', 'selectEnterpriseContact'], nonceStr: res.nonceStr, // 必填,生成签名的随机串
}).then(() => { signature: res.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
if (params.isAgentConfig) { jsApiList: ['chooseImage', 'shareToExternalContact', 'selectExternalContact', 'selectEnterpriseContact'],
return new Promise(async (resolve, reject) => { }).then(() => {
Service.Hades('anon/hades/getWxWorkJSAPISignature', { Service.Hades('anon/hades/getWxWorkJSAPISignature', {
storeId: User.getStoreId(), storeId: User.getStoreId(),
url: params.url, url: params.url,
}).then((result2) => { }).then((result2) => {
const res2 = result2.result; const res2 = result2.result;
this.agentConfig({ this.agentConfig({
corpid: res2.corpid, // 必填,企业微信的corpid,必须与当前登录的企业一致 corpid: res2.corpid, // 必填,企业微信的corpid,必须与当前登录的企业一致
agentid: res2.agentid, // 必填,企业微信的应用id (e.g. 1000247) agentid: res2.agentid, // 必填,企业微信的应用id (e.g. 1000247)
timestamp: res2.timestamp, // 必填,生成签名的时间戳 timestamp: res2.timestamp, // 必填,生成签名的时间戳
nonceStr: res2.nonceStr, // 必填,生成签名的随机串 nonceStr: res2.nonceStr, // 必填,生成签名的随机串
signature: res2.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法 signature: res2.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
jsApiList: ['selectExternalContact', 'getCurExternalContact', 'getContext', 'shareToExternalContact', 'sendChatMessage', 'shareToExternalChat'], jsApiList: ['selectExternalContact', 'getCurExternalContact', 'getContext', 'shareToExternalContact', 'sendChatMessage', 'shareToExternalChat', 'startLiving', 'replayLiving'],
success: (res) => { success: (res) => {
console.log(res, 'res-agentconfig'); console.log(res, 'res-agentconfig');
console.info('window.WWOpenData', window.WWOpenData); console.info('window.WWOpenData', window.WWOpenData);
resolve(res); resolve(res);
}, },
fail: (err) => { fail: (err) => {
console.log(1213545344545) console.log(1213545344545)
console.log(err, 'err-agentconfig'); console.log(err, 'err-agentconfig');
reject(err); reject(err);
}, },
});
}); });
}); });
}
}) })
}); });
}else{ })
} else {
if (params.isAgentConfig) { if (params.isAgentConfig) {
console.log(32132132,'cesgu') console.log(32132132, 'cesgu')
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
Service.Hades('anon/hades/getWxWorkJSAPISignature', { Service.Hades('anon/hades/getWxWorkJSAPISignature', {
storeId: User.getStoreId(), storeId: User.getStoreId(),
...@@ -76,7 +77,7 @@ export default class WechatApi { ...@@ -76,7 +77,7 @@ export default class WechatApi {
timestamp: res2.timestamp, // 必填,生成签名的时间戳 timestamp: res2.timestamp, // 必填,生成签名的时间戳
nonceStr: res2.nonceStr, // 必填,生成签名的随机串 nonceStr: res2.nonceStr, // 必填,生成签名的随机串
signature: res2.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法 signature: res2.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
jsApiList: ['selectExternalContact', 'getCurExternalContact', 'getContext', 'shareToExternalContact', 'sendChatMessage', 'shareToExternalChat'], jsApiList: ['selectExternalContact', 'getCurExternalContact', 'getContext', 'shareToExternalContact', 'sendChatMessage', 'shareToExternalChat', 'startLiving', 'replayLiving'],
success: (res) => { success: (res) => {
console.log(res, 'res-agentconfig'); console.log(res, 'res-agentconfig');
console.info('window.WWOpenData', window.WWOpenData); console.info('window.WWOpenData', window.WWOpenData);
...@@ -92,7 +93,7 @@ export default class WechatApi { ...@@ -92,7 +93,7 @@ export default class WechatApi {
}); });
} }
} }
} }
static async config(config) { static async config(config) {
...@@ -113,19 +114,7 @@ export default class WechatApi { ...@@ -113,19 +114,7 @@ export default class WechatApi {
} }
static async agentConfig(config) { static async agentConfig(config) {
return new Promise((success, fail) => { wx.agentConfig({ ...config });
console.info('wx.agentConfig', config);
wx.agentConfig({ ...config, success, fail });
}).then(
(res) => {
console.info('wx.agentConfig success', res);
return res;
},
(error) => {
console.error('wx.agentConfig fail', error);
throw error;
}
);
} }
static getCurExternalContact() { static getCurExternalContact() {
...@@ -168,7 +157,39 @@ export default class WechatApi { ...@@ -168,7 +157,39 @@ export default class WechatApi {
reject(res.err_msg); //错误处理 reject(res.err_msg); //错误处理
} }
}); });
});
})
}
static replayLiving(id) {
return new Promise((resolve, reject) => {
wx.ready(() => {
wx.invoke('replayLiving', {
"livingId": id,
}, function(res) {
console.log("WorkWXAPI 进入直播间",res)
if (res.err_msg === "replayLiving:ok") {
resolve(true)
} else {
let err = "进入回放失败"
console.log(res.err_msg);
if (res.err_msg === "replayLiving:fail_invalid living id") {
err = "不合法的直播ID"
} else if (res.err_msg === "replayLiving:fail_not allow to cross corp") {
err = "不可跨企业使用直播ID"
} else if (res.err_msg === "replayLiving:fail_not allow to cross app") {
err = "不可跨应用使用直播ID"
} else if (res.err_msg === "replayLiving:fail_living has no replay") {
err = "直播回放已失效或不存在"
} else if (res.err_msg === "replayLiving:fail_replay is beging creating") {
err = "回放生成中,请耐心等待"
} else if (res.err_msg === "replayLiving:fail_create replay failed") {
err = "回放创建失败"
} else if (res.err_msg === "replayLiving:fail_invalid parameter") {
err = "参数不合法"
}
reject(err); //错误处理
}
});
}); });
}) })
} }
......
import React, { ReactElement } from "react"; import React, { ReactElement } from "react";
import { Popover } from "antd"; import { Popover } from "antd";
import { TooltipPlacement } from "antd/lib/tooltip"; import { TooltipPlacement } from "antd/lib/tooltip";
import { brandLogo,xfrwm } from '@/domains/brand/constants'
import "./ContactWidget.less" import "./ContactWidget.less"
interface ContactWidgetProps { interface ContactWidgetProps {
...@@ -14,7 +15,7 @@ function Content() { ...@@ -14,7 +15,7 @@ function Content() {
return ( return (
<div className="contact-widget"> <div className="contact-widget">
<div className="qrcode"> <div className="qrcode">
<img src="https://cdn.xiaomai5.com/qixueyuankehu.png" alt=""></img> <img src={xfrwm} alt=""></img>
<div className="des">微信/企业微信扫码咨询</div> <div className="des">微信/企业微信扫码咨询</div>
</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> <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>
......
...@@ -23,6 +23,7 @@ class routeHook { ...@@ -23,6 +23,7 @@ class routeHook {
} }
cancel() { //取消跳转 cancel() { //取消跳转
console.log('jhgjh')
this.routeFun.pop() this.routeFun.pop()
} }
...@@ -42,7 +43,10 @@ class routeHook { ...@@ -42,7 +43,10 @@ class routeHook {
// ** // **
addSaveCase() { //离开保存校验时将方法注入 addSaveCase() { //离开保存校验时将方法注入
this.add(this.saveBeforeLeave.bind(this)) setTimeout(()=>{
this.add(this.saveBeforeLeave.bind(this))
},100)
} }
saveBeforeLeave() { //离开保存时触发的方法 saveBeforeLeave() { //离开保存时触发的方法
......
...@@ -27,7 +27,7 @@ const PATH_MAP: any = { ...@@ -27,7 +27,7 @@ const PATH_MAP: any = {
} }
const LIVE_SHARE_MAP: any = { const LIVE_SHARE_MAP: any = {
xiaomai: 'https://res.xiaomai0.com/store-live/index.html#/', xiaomai: process.env.DEPLOY_ENV === 'dev' ? 'https://dev.xiaomai5.com/store-live/index.html#/' : 'https://res.xiaomai0.com/store-live/index.html#/',
syoo: 'https://dev.xiaomai5.com/dev1/store-live/index.html#/', syoo: 'https://dev.xiaomai5.com/dev1/store-live/index.html#/',
} }
...@@ -38,6 +38,12 @@ const CorpType_MAP: any = { ...@@ -38,6 +38,12 @@ const CorpType_MAP: any = {
} }
const XF_RWM_MAP: any = {
xiaomai: 'https://cdn.xiaomai5.com/qixueyuankehu.png',
syoo: 'https://image.xiaomaiketang.com/xm/Z2X2GTmKdj.png'
}
export const brandName: string = BrandNameMap[BRAND]; export const brandName: string = BrandNameMap[BRAND];
...@@ -47,5 +53,6 @@ export const brandBanner: string = BrandBannerMap[BRAND]; ...@@ -47,5 +53,6 @@ export const brandBanner: string = BrandBannerMap[BRAND];
export const path: string = PATH_MAP[BRAND]; export const path: string = PATH_MAP[BRAND];
export const live: string = LIVE_SHARE_MAP[BRAND]; export const live: string = LIVE_SHARE_MAP[BRAND];
export const corpType: string = CorpType_MAP[BRAND]; export const corpType: string = CorpType_MAP[BRAND];
export const xfrwm: string = XF_RWM_MAP[BRAND]
window.brandName = BrandNameMap[BRAND]; window.brandName = BrandNameMap[BRAND];
...@@ -69,6 +69,7 @@ window.RCHistory = _.extend({}, history, { ...@@ -69,6 +69,7 @@ window.RCHistory = _.extend({}, history, {
}); });
window.onhashchange = () => { window.onhashchange = () => {
console.log(132121)
routeHook.cancel() routeHook.cancel()
} }
......
...@@ -17,4 +17,10 @@ ...@@ -17,4 +17,10 @@
font-size:14px; font-size:14px;
color:#5289FA; color:#5289FA;
} }
.post-name{
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
} }
\ No newline at end of file
...@@ -9,7 +9,7 @@ import React, { useEffect, useState } from "react"; ...@@ -9,7 +9,7 @@ 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 { CheckBox, PageControl } from "@/components"; import { CheckBox, PageControl } from "@/components";
import { Button, Table, Modal, message, Input } from "antd"; import { Button, Table, Modal, message, Input,Tooltip} from "antd";
import { XMTable } from '@/components'; import { XMTable } from '@/components';
import college from '@/common/lottie/college.json'; import college from '@/common/lottie/college.json';
import StoreService from "@/domains/store-domain/storeService"; import StoreService from "@/domains/store-domain/storeService";
...@@ -182,10 +182,17 @@ function EmployeeManage() { ...@@ -182,10 +182,17 @@ function EmployeeManage() {
if(!record.depNameList){ if(!record.depNameList){
return <span>-</span> return <span>-</span>
} }
return record.depNameList.map((item,index)=>{ if(record.depNameList.length === 0){
return <span><WWOpenDataCom type="departmentName" openid={item}/>{index<(record.depNameList.length -1)?'、':''}</span>; return <span>-</span>
}) }
// return record.depNameList.map((item,index)=>{
// return <span><WWOpenDataCom type="departmentName" openid={item}/>{index<(record.depNameList.length -1)?';':''}</span>;
// })
return <Tooltip title={<div>{handleDepName(record.depNameList)}</div>} placement='top' arrowPointAtCenter><div className="post-name"> {record.depNameList.map((item, index) => {
return <span><WWOpenDataCom type="departmentName" openid={item}/>{index<(record.depNameList.length -1)?';':''}</span>
})}
</div>
</Tooltip>
}, },
}, },
{ {
...@@ -237,6 +244,13 @@ function EmployeeManage() { ...@@ -237,6 +244,13 @@ function EmployeeManage() {
return columns; return columns;
} }
function handleDepName(depArray:any):any{
const depArrayDom = depArray.map((item:any, index:any) => {
return <span><WWOpenDataCom type="departmentName" openid={item}/></span>
});
return depArrayDom;
};
function handleEditEmployee(record: RecordTypes) { function handleEditEmployee(record: RecordTypes) {
const { nickName, phone, roleCodes, avatar, id, weChatAccount } = record; const { nickName, phone, roleCodes, avatar, id, weChatAccount } = record;
const _choosesItem = { const _choosesItem = {
...@@ -342,10 +356,10 @@ function EmployeeManage() { ...@@ -342,10 +356,10 @@ function EmployeeManage() {
userType:'USER' userType:'USER'
} }
StoreService.syncWorkWeChatDepartment(params).then((res) => { StoreService.syncWorkWeChatDepartment(params).then((res) => {
getEmployeeList();
message.success('已更新'); message.success('已更新');
}); });
} }
return ( return (
<div className="page employee-manage-page"> <div className="page employee-manage-page">
<div className="content-header">角色管理</div> <div className="content-header">角色管理</div>
...@@ -493,7 +507,7 @@ function EmployeeManage() { ...@@ -493,7 +507,7 @@ function EmployeeManage() {
type="USER" type="USER"
close={()=>{setEmployeeModal(false)}} close={()=>{setEmployeeModal(false)}}
onConfirm={() => { onConfirm={() => {
setEmployeeModal(false) setEmployeeModal(false)
message.success('添加成功') message.success('添加成功')
getEmployeeList(); getEmployeeList();
}} }}
......
/* /*
* @Author: your name * @Author: your name
* @Date: 2021-08-04 15:21:36 * @Date: 2021-08-04 15:21:36
* @LastEditTime: 2021-08-04 15:27:16 * @LastEditTime: 2021-08-04 15:23:37
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @Description: In User Settings Edit * @Description: In User Settings Edit
* @FilePath: /xiaomai-cloud-class-web/src/modules/college-manage/LimitTip.tsx * @FilePath: /xiaomai-cloud-class-web/src/modules/college-manage/LimitTip.tsx
...@@ -34,7 +34,7 @@ export default function LimitTip(props:{total:number,type:string,tip:() => React ...@@ -34,7 +34,7 @@ export default function LimitTip(props:{total:number,type:string,tip:() => React
{ {
isOver ? ( isOver ? (
<> <>
<div style={{marginLeft:"14px",display:"inline-block"}}>当前企业使用人数已达到上限 (<span style={{color:"#333333",fontWeight:"bold"}}>{limitUser}</span>人),将无法添加新员工、新学员,如需增加人数限制,请联系{window.brandName}服务平台。</div> <div style={{marginLeft:"14px",display:"inline-block"}}>当前企业使用人数已达到上限 <span style={{color:"#333333",fontWeight:"bold"}}>{limitUser}</span>,将无法添加新员工、新学员,如需增加人数限制,请联系{window.brandName}服务平台。</div>
<ContactWidget trigger="hover" placement="bottom"> <ContactWidget trigger="hover" placement="bottom">
<div className="renew-text">立即续费<span className="icon iconfont" style={{fontSize:"10px"}}>&#59291;</span></div> <div className="renew-text">立即续费<span className="icon iconfont" style={{fontSize:"10px"}}>&#59291;</span></div>
</ContactWidget> </ContactWidget>
......
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 { Button, Input, message,Modal} from "antd"; import { Button, Input, message,Modal,Tooltip} from "antd";
import NewChooseMembersModal from "@/modules/college-manage/modal/NewChooseMembersModal"; import NewChooseMembersModal from "@/modules/college-manage/modal/NewChooseMembersModal";
import LeftStructureTree from "./LeftStructureTree"; import LeftStructureTree from "./LeftStructureTree";
import { XMTable, PageControl } from "@/components"; import { XMTable, PageControl } from "@/components";
...@@ -17,7 +17,7 @@ const { Search } = Input; ...@@ -17,7 +17,7 @@ const { Search } = Input;
const { confirm } = Modal; const { confirm } = Modal;
const DefaultQuery = { const DefaultQuery = {
size: 10, size: 10,
current: 1, current:1,
}; };
function DepartMentTabCon(props) { function DepartMentTabCon(props) {
const [chooseMembersModalVisible, setChooseMembersModalVisible] = useState( const [chooseMembersModalVisible, setChooseMembersModalVisible] = useState(
...@@ -73,23 +73,31 @@ function DepartMentTabCon(props) { ...@@ -73,23 +73,31 @@ function DepartMentTabCon(props) {
title: "岗位", title: "岗位",
dataIndex: "depNameList", dataIndex: "depNameList",
render: (val, record) => { render: (val, record) => {
if(!record.depNameList){ if(!record.depNameList){
return <span>-</span> return <span>-</span>
}else{ }else{
if(record.depNameList.length === 0){ if(record.depNameList.length === 0){
return <span>-</span> return <span>-</span>
} }
return record.depNameList.map((item, index) => { return <Tooltip title={handleDepName(record.depNameList)} placement='top' arrowPointAtCenter><div className="post-name"> {record.depNameList.map((item, index) => {
return <span>{item}{index!==record.depNameList.length-1 && <span></span>}</span>; return <span>{item}{index!==record.depNameList.length-1 && <span></span>}</span>
}) })}
</div>
</Tooltip>
} }
} }
}, },
{ {
title: "手机号", title: "手机号",
dataIndex: "phone", dataIndex: "phone",
render: (val, item) => { render: (val, item) => {
return <span>{val}</span>; if(!val){
return <span>-</span>
}else{
return <span>{item.phone}</span>
}
}, },
}, },
{ {
...@@ -116,6 +124,17 @@ function DepartMentTabCon(props) { ...@@ -116,6 +124,17 @@ function DepartMentTabCon(props) {
}, },
}, },
]; ];
function handleDepName(depArray){
let depStr = '';
depArray.forEach((item, index) => {
if (index < depArray.length - 1) {
depStr = depStr + item + ';';
} else {
depStr = depStr + item;
}
});
return depStr;
};
function closeChooseMembersModal() { function closeChooseMembersModal() {
setChooseMembersModalVisible(false); setChooseMembersModalVisible(false);
} }
...@@ -202,8 +221,8 @@ function DepartMentTabCon(props) { ...@@ -202,8 +221,8 @@ function DepartMentTabCon(props) {
StoreService.delDepartmentUser(params).then((res) => { StoreService.delDepartmentUser(params).then((res) => {
message.success(`删除成功`); message.success(`删除成功`);
getUserList(); getUserList();
Bus.trigger("changeTreeData",{treeType:props.currentTab});
}); });
} }
function handleSelectUserList(record, selected){ function handleSelectUserList(record, selected){
let _list = []; let _list = [];
...@@ -360,12 +379,12 @@ function DepartMentTabCon(props) { ...@@ -360,12 +379,12 @@ function DepartMentTabCon(props) {
/> />
<div className="box-footer"> <div className="box-footer">
<PageControl <PageControl
current={query.current} current={query.current - 1}
pageSize={query.size} pageSize={query.size}
total={total} total={total}
toPage={(page) => { toPage={(page) => {
const queryStates = _.clone(query); const queryStates = _.clone(query);
queryStates.current = page; queryStates.current = page + 1;
setQuery(queryStates); setQuery(queryStates);
getUserList(null,null,queryStates.current); getUserList(null,null,queryStates.current);
}} }}
......
...@@ -3,6 +3,12 @@ ...@@ -3,6 +3,12 @@
.table-con{ .table-con{
margin-left:16px; margin-left:16px;
flex:1; flex:1;
.post-name{
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.operate-area{ .operate-area{
margin-bottom:16px; margin-bottom:16px;
.add-user-btn{ .add-user-btn{
......
.left-structure-tree { .left-structure-tree {
margin-right: 24px; margin-right: 24px;
width:250px; width:260px;
height: calc(~'100vh - 260px'); height: calc(~'100vh - 260px');
overflow-y: scroll;
.organization{ .organization{
overflow: scroll; overflow: scroll;
.search-con{ .search-con{
......
...@@ -38,6 +38,7 @@ function MemberTree(props) { ...@@ -38,6 +38,7 @@ function MemberTree(props) {
} }
function handleData(dataArray){ function handleData(dataArray){
const _dataArray = dataArray.map((item,index)=>{ const _dataArray = dataArray.map((item,index)=>{
item.title = "";
item.key=item.id; item.key=item.id;
item.children = [] item.children = []
if(item.departmentUserVOList){ if(item.departmentUserVOList){
......
...@@ -52,7 +52,7 @@ function SearchUser(props) { ...@@ -52,7 +52,7 @@ function SearchUser(props) {
// onBlur={()=>{onBlur()}} // onBlur={()=>{onBlur()}}
/> />
{dropDownVisible && {dropDownVisible &&
<div className="drop-down" style={{width:'100%'}}> <div className="drop-down">
<div className="drop-down__list"> <div className="drop-down__list">
{props.data.departmentUserVOList && {props.data.departmentUserVOList &&
<div> <div>
...@@ -66,6 +66,7 @@ function SearchUser(props) { ...@@ -66,6 +66,7 @@ function SearchUser(props) {
<Checkbox onChange={(e)=>{selectuser(e,item)}} > <Checkbox onChange={(e)=>{selectuser(e,item)}} >
<div className="drop-down__item__con__item"> <div className="drop-down__item__con__item">
<div className="drop-down__item__con__item__left"> <div className="drop-down__item__con__item__left">
<span className="icon iconfont title-icon">&#xe603;</span>
<WWOpenDataCom type="userName" openid={item.userName}/> <WWOpenDataCom type="userName" openid={item.userName}/>
</div> </div>
<div className="drop-down__item__con__item__right"> <div className="drop-down__item__con__item__right">
......
.search-user{ .search-user{
position: relative; position: relative;
padding:12px 16px;
.drop-down{ .drop-down{
padding:18px; padding:18px;
position: absolute; position: absolute;
...@@ -8,11 +9,12 @@ ...@@ -8,11 +9,12 @@
background: #FFFFFF; background: #FFFFFF;
box-shadow: 0px 2px 15px 6px rgba(0, 0, 0, 0.05); box-shadow: 0px 2px 15px 6px rgba(0, 0, 0, 0.05);
border-radius:2px; border-radius:2px;
width:270px;
.ant-checkbox-wrapper{ .ant-checkbox-wrapper{
width:100%; width:100%;
.drop-down__item__con__item{ .drop-down__item__con__item{
display:flex; display:flex;
width:240px; width:220px;
justify-content:space-between; justify-content:space-between;
color:#333; color:#333;
font-size:14px; font-size:14px;
......
...@@ -41,7 +41,7 @@ function UserTable() { ...@@ -41,7 +41,7 @@ function UserTable() {
title: '岗位', title: '岗位',
dataIndex: 'post', dataIndex: 'post',
render: (val, record) => { render: (val, record) => {
return <span>{val}</span> return <span className="post-name">{val}</span>
} }
}, },
{ {
......
.user-table{ .user-table{
.post-name{
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
} }
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: wufan * @Author: wufan
* @Date: 2020-11-27 16:21:49 * @Date: 2020-11-27 16:21:49
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-08-03 17:23:40 * @LastEditTime: 2021-08-06 17:10:50
* @Description: Description * @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -16,24 +16,28 @@ function AddOrEditPostGroupModal(props) { ...@@ -16,24 +16,28 @@ function AddOrEditPostGroupModal(props) {
const [nameErrorMsg,setNameErrorMsg] = useState(''); const [nameErrorMsg,setNameErrorMsg] = useState('');
const [validateStatus,setValidateStatus] = useState('success'); const [validateStatus,setValidateStatus] = useState('success');
const [postGroupName,setPostGroupName] = useState(''); const [postGroupName,setPostGroupName] = useState('');
const [isError,setIsError] = useState(false)
useEffect(() => { useEffect(() => {
},[]); },[]);
function changePostGroupName(e){ function changePostGroupName(e){
let isError = false; setIsError(false)
setValidateStatus('success'); setValidateStatus('success');
setNameErrorMsg(''); setNameErrorMsg('');
if((!e.target.value) || /^\s+$/.test(e.target.value)){
setValidateStatus('error');
setNameErrorMsg(`${props.label}不能为空`);
setIsError(true)
}
props.postGroupTreeData.map((item,index)=>{ props.postGroupTreeData.map((item,index)=>{
if(item.name === e.target.value){ if(item.name === e.target.value){
setValidateStatus('error'); setValidateStatus('error');
setNameErrorMsg(`该${props.label}已存在`); setNameErrorMsg(`该${props.label}已存在`);
isError = true; setIsError(true)
} }
return item; return item;
}) })
if(!isError){ setPostGroupName(e.target.value);
setPostGroupName(e.target.value);
}
} }
function handleConfirm(){ function handleConfirm(){
...@@ -44,10 +48,11 @@ function AddOrEditPostGroupModal(props) { ...@@ -44,10 +48,11 @@ function AddOrEditPostGroupModal(props) {
} }
} }
function addGroup(){ function addGroup(){
if(!postGroupName){ if(isError){
return; return;
} }
const { postGroupModalLevel,currentTab,currentGroupData,label} = props const { postGroupModalLevel,currentTab,currentGroupData,label} = props
let parmas={ let parmas={
depLevel:postGroupModalLevel, depLevel:postGroupModalLevel,
depType:DepType[currentTab], depType:DepType[currentTab],
...@@ -68,7 +73,7 @@ function AddOrEditPostGroupModal(props) { ...@@ -68,7 +73,7 @@ function AddOrEditPostGroupModal(props) {
}); });
} }
function editGroup(){ function editGroup(){
if(!postGroupName){ if(isError){
return; return;
} }
const {postGroupModalLevel,currentTab,currentGroupData,label} = props const {postGroupModalLevel,currentTab,currentGroupData,label} = props
......
...@@ -18,7 +18,6 @@ import WechatApi from '@/common/js/wechatApi'; ...@@ -18,7 +18,6 @@ import WechatApi from '@/common/js/wechatApi';
import WWOpenDataCom from '@/components/WWOpenDataCom'; import WWOpenDataCom from '@/components/WWOpenDataCom';
const { Search } = Input; const { Search } = Input;
class ChooseMembersModal extends React.Component { class ChooseMembersModal extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
...@@ -204,6 +203,7 @@ class ChooseMembersModal extends React.Component { ...@@ -204,6 +203,7 @@ class ChooseMembersModal extends React.Component {
}) })
} }
}) })
} }
addCustomer = () => { addCustomer = () => {
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
.container-left-body-table{ .container-left-body-table{
width: 300px; width: 300px;
height: 330px; height: 330px;
overflow: scroll;
.ant-table { .ant-table {
border: none; border: none;
min-height: 250px !important; min-height: 250px !important;
......
...@@ -56,7 +56,7 @@ class NewChooseMembersModal extends React.Component { ...@@ -56,7 +56,7 @@ class NewChooseMembersModal extends React.Component {
return ( return (
<div className='avatar'> <div className='avatar'>
<span className="icon iconfont avatar-icon">&#xe84a;</span> <span className="icon iconfont avatar-icon">&#xe84a;</span>
<Tooltip title={userName}> <Tooltip title={<WWOpenDataCom type="userName" openid={userName}/>}>
<span className='userImg'> <span className='userImg'>
<WWOpenDataCom type="userName" openid={userName}/> <WWOpenDataCom type="userName" openid={userName}/>
{/* {userName} */} {/* {userName} */}
...@@ -348,7 +348,7 @@ class NewChooseMembersModal extends React.Component { ...@@ -348,7 +348,7 @@ class NewChooseMembersModal extends React.Component {
this.setState({ selectObject }); this.setState({ selectObject });
}} }}
onClose={() => { onClose={() => {
this.setState({ openSetModal: true},()=>{this.handleClose()}) // this.setState({ openSetModal: true},()=>{this.handleClose()})
this.setState({ openSetModal: false, visible: true }) this.setState({ openSetModal: false, visible: true })
}} }}
onCancel={() => { onCancel={() => {
......
...@@ -19,12 +19,27 @@ export default class SetEmployeeModal extends React.Component { ...@@ -19,12 +19,27 @@ export default class SetEmployeeModal extends React.Component {
}) })
const selectedData = list[0] || {}; const selectedData = list[0] || {};
this.state = { this.state = {
list, list:this.uniqArr([...list]),
selected: selectedData.userId, selected: selectedData.userId,
roleCode: selectedData.roleCode, roleCode: selectedData.roleCode,
submit:false
} }
} }
uniqArr(arr){
let obj={};
arr.map((item,index)=>{
// 若重复则删除该项
if(obj.hasOwnProperty(item.userId)){
arr.splice(index,1);
// 不重复则存入obj
}else{
obj[item.userId]=item.userName;
}
});
return arr;
}
handleChangeValues(value) { handleChangeValues(value) {
const { list, selected } = this.state; const { list, selected } = this.state;
list.map((item) => { list.map((item) => {
...@@ -33,7 +48,7 @@ export default class SetEmployeeModal extends React.Component { ...@@ -33,7 +48,7 @@ export default class SetEmployeeModal extends React.Component {
} }
}) })
this.props.onChange(selected, value); this.props.onChange(selected, value);
this.setState({ roleCode: value, list }); this.setState({ roleCode: value, list});
} }
render() { render() {
...@@ -41,6 +56,7 @@ export default class SetEmployeeModal extends React.Component { ...@@ -41,6 +56,7 @@ export default class SetEmployeeModal extends React.Component {
list, list,
roleCode, roleCode,
selected, selected,
submit
} = this.state; } = this.state;
return ( return (
<Modal <Modal
...@@ -55,7 +71,7 @@ export default class SetEmployeeModal extends React.Component { ...@@ -55,7 +71,7 @@ export default class SetEmployeeModal extends React.Component {
<div className="modal-footer"> <div className="modal-footer">
<Button style={{ float: 'left' }} onClick={() => this.props.onClose()}>上一步</Button> <Button style={{ float: 'left' }} onClick={() => this.props.onClose()}>上一步</Button>
<Button onClick={() => this.props.onCancel()}>取消</Button> <Button onClick={() => this.props.onCancel()}>取消</Button>
<Button onClick={() => this.props.onOk(list)} type="primary">确定</Button> <Button onClick={() =>{this.setState({submit:true},()=>this.props.onOk(list))}} type="primary" disabled={submit}>确定</Button>
</div> </div>
} }
> >
......
...@@ -362,6 +362,8 @@ class AddLive extends React.Component { ...@@ -362,6 +362,8 @@ class AddLive extends React.Component {
scheduleMediaRequests, scheduleMediaRequests,
}; };
routeHook.cancel()
if (type === 'add') { if (type === 'add') {
const params = { const params = {
...commonParams, ...commonParams,
......
...@@ -93,6 +93,18 @@ class DataList extends React.Component { ...@@ -93,6 +93,18 @@ class DataList extends React.Component {
}; };
studentTypeEnum = (type)=> {
if (type === "STUDENT") {
return "学员"
}
if (type === "NON_STUDENT") {
return "待加入"
}
if (type === "GUEST") {
return "游客"
}
}
// 进入直播次数列表 // 进入直播次数列表
getVisiterColumns() { getVisiterColumns() {
const columns = [ const columns = [
...@@ -190,7 +202,7 @@ class DataList extends React.Component { ...@@ -190,7 +202,7 @@ class DataList extends React.Component {
const columnsWorkWX = [ const columnsWorkWX = [
{ {
title: '学员姓名', title: '学员姓名',
dataIndex: 'userName', dataIndex: 'name',
}, },
{ {
title: ()=> { title: ()=> {
...@@ -210,43 +222,16 @@ class DataList extends React.Component { ...@@ -210,43 +222,16 @@ class DataList extends React.Component {
</div> </div>
) )
}, },
dataIndex: 'phone', dataIndex: 'studentTypeEnum',
render: (text, record) => { render: (text, record) => {
const { phone = '', bindingWeChat } = record; return <div>{this.studentTypeEnum(record.studentTypeEnum)}</div>;
return <div>{phone}</div>;
}, },
}, },
{ {
title: '账号类型', title: '账号类型',
dataIndex: 'entryNum', dataIndex: 'accountTypeEnum',
render: (text, record) => { render: (text, record) => {
if (text > 0) { return record.accountTypeEnum === "ENTERPRISE_WECHAT" ? <span style={{color:"#5289FA"}}>企业微信</span> : <span style={{color:"#1DCC65"}}>微信</span>
if (record.visitorInfoVOList && record.visitorInfoVOList.length > 0) {
const table = (
<XMTable
renderEmpty={{
image: college,
description: '暂无数据',
}}
columns={this.getVisiterColumns()}
dataSource={record.visitorInfoVOList}
scroll={{ y: 75 }}
size={'small'}
style={{ width: 450 }}
pagination={false}
/>
);
return (
<Popover content={table} trigger='click'>
<span className='handel-btn'>{text}</span>
</Popover>
);
} else {
return <div className='live-table--empty'>暂无观看数据</div>;
}
} else {
return <span>{text}</span>;
}
}, },
}, },
{ {
......
...@@ -15,8 +15,6 @@ import Breadcrumbs from '@/components/Breadcrumbs'; ...@@ -15,8 +15,6 @@ import Breadcrumbs from '@/components/Breadcrumbs';
import Bus from '@/core/tbus'; import Bus from '@/core/tbus';
import AddLiveBasic from './AddLiveBasic'; import AddLiveBasic from './AddLiveBasic';
import AddLiveClass from './AddLiveClass';
import AddLiveIntro from './AddLiveIntro';
import AddLiveClassInfoWorkWX from './AddLiveClassInfoWorkWX'; import AddLiveClassInfoWorkWX from './AddLiveClassInfoWorkWX';
import { randomString } from '@/domains/basic-domain/utils'; import { randomString } from '@/domains/basic-domain/utils';
import Upload from '@/core/upload'; import Upload from '@/core/upload';
...@@ -41,10 +39,10 @@ const defaultBasicInfo = { ...@@ -41,10 +39,10 @@ const defaultBasicInfo = {
const defaultClassInfo = { const defaultClassInfo = {
teacherId: '', //讲师的Id teacherId: null, //讲师的Id
courseName: '', //课程名称 courseName: '', //课程名称
duration: 3600000, //直播时长默认1小时 duration: 3600, //直播时长默认1小时
remindTime: 0, //提醒时间 remindTime: 900, //提醒时间
startTime: new Date().getTime() + 300000, startTime: new Date().getTime() + 300000,
}; };
...@@ -60,12 +58,15 @@ function CreateWorkWXCourse() { ...@@ -60,12 +58,15 @@ function CreateWorkWXCourse() {
const [classInfo, setClassInfo] = useState(defaultClassInfo) const [classInfo, setClassInfo] = useState(defaultClassInfo)
const [endTime, setEndTime] = useState(0) const [endTime, setEndTime] = useState(0)
const [introduce, setIntroduce] = useState('') const [introduce, setIntroduce] = useState('')
const [getInfo, setGetInfo] = useState(false)
const [previewLiveCourseModal, setPreviewLiveCourseModal] = useState() const [previewLiveCourseModal, setPreviewLiveCourseModal] = useState()
useEffect(()=> { useEffect(()=> {
routeHook.addSaveCase(); routeHook.addSaveCase();
if (type === 'edit') { if (type === 'edit') {
getCourseDetail(); getCourseDetail();
}else{
setGetInfo(true)
} }
Bus.bind('editorLimit', (editorTextLength) => { Bus.bind('editorLimit', (editorTextLength) => {
setEditorTextLength(editorTextLength) setEditorTextLength(editorTextLength)
...@@ -104,9 +105,11 @@ function CreateWorkWXCourse() { ...@@ -104,9 +105,11 @@ function CreateWorkWXCourse() {
default: default:
break; break;
} }
return item; return item;
}); });
if (!hasIntro) {
setGetInfo(true)
}
const _basicInfo = { const _basicInfo = {
courseName, courseName,
...@@ -133,6 +136,7 @@ function CreateWorkWXCourse() { ...@@ -133,6 +136,7 @@ function CreateWorkWXCourse() {
setBasicInfo(_basicInfo) setBasicInfo(_basicInfo)
setClassInfo(_classInfo) setClassInfo(_classInfo)
setCourseState(courseState) setCourseState(courseState)
}); });
}; };
...@@ -146,6 +150,7 @@ function CreateWorkWXCourse() { ...@@ -146,6 +150,7 @@ function CreateWorkWXCourse() {
success: (res) => { success: (res) => {
setLoadintroduce(true) setLoadintroduce(true)
setIntroduce(res) setIntroduce(res)
setGetInfo(true)
}, },
error: () => { error: () => {
message.warning('获取简介失败'); message.warning('获取简介失败');
...@@ -193,11 +198,6 @@ function CreateWorkWXCourse() { ...@@ -193,11 +198,6 @@ function CreateWorkWXCourse() {
} }
} }
// 修改简介
function handleChangeIntroInfo(field, value) {
};
// 完成创建/编辑 // 完成创建/编辑
function handleSubmit() { function handleSubmit() {
//过期判断 //过期判断
...@@ -221,8 +221,8 @@ function CreateWorkWXCourse() { ...@@ -221,8 +221,8 @@ function CreateWorkWXCourse() {
}); });
return; return;
} }
// this.handleValidate(addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo, isEdit, editorTextLength).then((res) => { handleValidate().then((res) => {
// if (!res) return; if (!res) return;
//上传简介 //上传简介
Upload.uploadTextToOSS( Upload.uploadTextToOSS(
introduce, introduce,
...@@ -232,7 +232,7 @@ function CreateWorkWXCourse() { ...@@ -232,7 +232,7 @@ function CreateWorkWXCourse() {
}, },
() => message.warning('上传课程简介失败') () => message.warning('上传课程简介失败')
); );
// }); });
}; };
function submitRemote({ introduceId, id }) { function submitRemote({ introduceId, id }) {
...@@ -240,10 +240,12 @@ function CreateWorkWXCourse() { ...@@ -240,10 +240,12 @@ function CreateWorkWXCourse() {
} else { } else {
} }
console.log('取消')
routeHook.cancel()
if (type === 'add') { if (type === 'add') {
if (endTime !== 0) { if (endTime !== 0) {
classInfo.duration = String(endTime - classInfo.startTime) classInfo.duration = String((endTime - classInfo.startTime)/1000)
} }
const params = { const params = {
...classInfo, ...classInfo,
...@@ -255,6 +257,7 @@ function CreateWorkWXCourse() { ...@@ -255,6 +257,7 @@ function CreateWorkWXCourse() {
CourseService.createWorkWXLiveCourse(params).then((res) => { CourseService.createWorkWXLiveCourse(params).then((res) => {
if (res.success) { if (res.success) {
message.success('新建成功'); message.success('新建成功');
Bus.trigger('freshCourseList')
window.RCHistory.push({ window.RCHistory.push({
pathname: `/live-course`, pathname: `/live-course`,
}); });
...@@ -262,7 +265,7 @@ function CreateWorkWXCourse() { ...@@ -262,7 +265,7 @@ function CreateWorkWXCourse() {
}); });
} else { } else {
if (endTime !== 0) { if (endTime !== 0) {
classInfo.duration = String(endTime - classInfo.startTime) classInfo.duration = String((endTime - classInfo.startTime)/1000)
} }
const params = { const params = {
...classInfo, ...classInfo,
...@@ -274,6 +277,7 @@ function CreateWorkWXCourse() { ...@@ -274,6 +277,7 @@ function CreateWorkWXCourse() {
}; };
CourseService.updateWorkWXLiveCourse(params).then((res) => { CourseService.updateWorkWXLiveCourse(params).then((res) => {
if (res.success) { if (res.success) {
Bus.trigger('freshCourseList')
message.success('更新成功'); message.success('更新成功');
window.RCHistory.push({ window.RCHistory.push({
pathname: `/live-course`, pathname: `/live-course`,
...@@ -282,103 +286,33 @@ function CreateWorkWXCourse() { ...@@ -282,103 +286,33 @@ function CreateWorkWXCourse() {
}); });
} }
}; };
/*
handleValidate = (addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo, isEdit, editorTextLength) => {
return new Promise((resolve) => {
const { type } = this.state;
const { courseName, categoryId } = addLiveBasicInfo;
const { liveDate, timeHorizonStart, timeHorizonEnd, teacherId, calendarTime } = addLiveClassInfo;
const { liveCourseMediaRequests } = addLiveIntroInfo;
const currentTime = +new Date();
if (!courseName) {
message.warning('请输入课程名称');
resolve(false);
return;
}
if (!categoryId) { function handleValidate() {
message.warning('请选择课程分类'); return new Promise((resolve) => {
resolve(false); if (_.isEmpty(basicInfo.courseName)) {
return; message.warning("课程名称不能为空")
resolve(false)
return
} }
if (_.isEmpty(basicInfo.categoryId)) {
if (type === 'add') { message.warning("课程分类未选择")
const { startTime, endTime } = addLiveClassInfo; resolve(false)
if (calendarTime.length === 0) { return
message.warning('请选择上课日期');
resolve(false);
return;
} else if (startTime === endTime || startTime > endTime) {
message.warning('结束时间必须晚于开始时间');
resolve(false);
return;
}
// 若有今日排课 校验当前时间
const currentDay = moment(currentTime).format('YYYY-MM-DD');
const itemToday = _.find(calendarTime, (item) => {
const itemDay = moment(item).format('YYYY-MM-DD');
return itemDay === currentDay;
});
if (itemToday) {
const itemDay = moment(itemToday).format('YYYY-MM-DD');
const itemHour = moment(startTime).format('HH:mm');
if (itemDay === currentDay) {
if (moment(itemDay + ' ' + itemHour).format('x') < currentTime) {
message.warning('开始时间不能早于现在');
resolve(false);
return;
}
}
}
} else {
const _liveDate = moment(liveDate).format('YYYY-MM-DD');
const _timeHorizonStart = moment(timeHorizonStart).format('HH:mm');
const _timeHorizonEnd = moment(timeHorizonEnd).format('HH:mm');
const startTime = moment(_liveDate + ' ' + _timeHorizonStart).format('x');
const endTime = moment(_liveDate + ' ' + _timeHorizonEnd).format('x');
if (!startTime || !endTime) {
message.warning('日期不能为空');
resolve(false);
return;
} else if (!timeHorizonStart) {
message.warning('开始时间不能为空');
resolve(false);
return;
} else if (!timeHorizonEnd) {
message.warning('结束时间不能为空');
resolve(false);
return;
} else if (isEdit && startTime < currentTime) {
message.warning('开始时间不能早于当前时间');
resolve(false);
return;
} else if (isEdit && endTime < currentTime) {
message.warning('结束时间不能早于当前时间');
resolve(false);
return;
} else if (isEdit && endTime <= startTime) {
message.warning('结束时间不能早于开始时间');
resolve(false);
return;
}
} }
if (!teacherId) { if (!classInfo.startTime) {
message.warning('请选择讲师'); message.warning("未设置开始时间")
resolve(false); resolve(false)
return; return
} }
if (_.isEmpty(classInfo.teacherId)) {
if (editorTextLength > 1000) { message.warning("课程分类未选择")
message.warning('课程简介超过字数限定'); resolve(false)
resolve(false); return
return;
} }
resolve(true); resolve(true)
}); });
}; };
*/
// 显示预览课程弹窗 // 显示预览课程弹窗
function handleShowPreviewModal() { function handleShowPreviewModal() {
...@@ -427,14 +361,17 @@ function CreateWorkWXCourse() { ...@@ -427,14 +361,17 @@ function CreateWorkWXCourse() {
</div> </div>
<div className='add-live-page__form'> <div className='add-live-page__form'>
<div className='basic-info__wrap'> <div className='basic-info__wrap'>
<div className='title'>基本信息</div> <div className='title'>基本信息<span style={{marginLeft:"24px",color:"#2966FF",fontSize:"14px"}}>温馨提示:在直播间可控制回放录制功能。</span></div>
<AddLiveBasic isEdit={isEdit} pageType={type} data={basicInfo} onChange={handleChangeBasicInfo} /> <AddLiveBasic isEdit={isEdit} pageType={type} data={basicInfo} onChange={handleChangeBasicInfo} />
</div> </div>
<div className='class-info__wrap'> <div className='class-info__wrap'>
<div className='title'>上课信息</div> <div className='title'>上课信息</div>
{/* <AddLiveClass isEdit={isEdit} pageType={type} data={{ ...addLiveClassInfo, id }} onChange={handleChangeClassInfo} /> */} {/* <AddLiveClass isEdit={isEdit} pageType={type} data={{ ...addLiveClassInfo, id }} onChange={handleChangeClassInfo} /> */}
<AddLiveClassInfoWorkWX type={type} data={classInfo} introduce={introduce} onChange={onClassInfoChange}/> {
getInfo && <AddLiveClassInfoWorkWX type={type} data={classInfo} isEdit={isEdit} introduce={introduce} onChange={onClassInfoChange}/>
}
</div> </div>
</div> </div>
......
...@@ -151,6 +151,7 @@ class LiveCourseFilter extends React.Component { ...@@ -151,6 +151,7 @@ class LiveCourseFilter extends React.Component {
courseState: undefined, courseState: undefined,
current: 1, current: 1,
shelfState: null, shelfState: null,
thirdPartType: null
}, },
}, },
() => { () => {
...@@ -303,6 +304,16 @@ class LiveCourseFilter extends React.Component { ...@@ -303,6 +304,16 @@ class LiveCourseFilter extends React.Component {
style={{ width: 'calc(100% - 70px)' }} style={{ width: 'calc(100% - 70px)' }}
placeholder='请选择' placeholder='请选择'
allowClear={true} allowClear={true}
onClear={(value) => {
this.setState(
{
query: {...this.state.query,thirdPartType:null}
},
() => {
this.props.onChange(this.state.query)
}
)
}}
value={thirdPartType} value={thirdPartType}
onChange={(value) => { onChange={(value) => {
this.handleChangeQuery('thirdPartType', value) this.handleChangeQuery('thirdPartType', value)
......
...@@ -24,6 +24,7 @@ import DataList from '../DataList/DataList'; ...@@ -24,6 +24,7 @@ import DataList from '../DataList/DataList';
import ManageCoursewareModal from '../modal/ManageCoursewareModal'; import ManageCoursewareModal from '../modal/ManageCoursewareModal';
import RelatedPlanModal from '../modal/RelatedPlanModal'; import RelatedPlanModal from '../modal/RelatedPlanModal';
import ShareLiveModal from '../modal/ShareLiveModal'; import ShareLiveModal from '../modal/ShareLiveModal';
import Bus from '@/core/bus';
import './LiveCourseList.less'; import './LiveCourseList.less';
const { confirm } = Modal const { confirm } = Modal
...@@ -65,6 +66,9 @@ class LiveCourseList extends React.Component { ...@@ -65,6 +66,9 @@ class LiveCourseList extends React.Component {
} }
componentDidMount() { componentDidMount() {
this.getDownloadVersion() this.getDownloadVersion()
Bus.bind('freshCourseList',()=>{
this.refreshCourseList()
})
} }
// 显示分享弹窗 // 显示分享弹窗
handleShowShareModal = (item, needStr = false) => { handleShowShareModal = (item, needStr = false) => {
...@@ -629,6 +633,7 @@ class LiveCourseList extends React.Component { ...@@ -629,6 +633,7 @@ class LiveCourseList extends React.Component {
} }
renderMoreOperate = (item) => { renderMoreOperate = (item) => {
let now = new Date().getTime()
return ( return (
<Menu <Menu
onClick={({key})=> { onClick={({key})=> {
...@@ -641,15 +646,48 @@ class LiveCourseList extends React.Component { ...@@ -641,15 +646,48 @@ class LiveCourseList extends React.Component {
} }
}} }}
> >
<Menu.Item disabled={!(User.getUserRole() === 'CloudManager' || User.getUserRole() === 'StoreManager')} key="link"> {
关联培训计划 item.thirdPartType === "WECHAT" &&
</Menu.Item> <Tooltip placement="left" title="企微直播,暂不支持关联培训任务">
<Menu.Item disabled={item.courseState === "STARTING" || item.courseState === "FINISH"} key="edit"> <Menu.Item style={{color:"#999999"}}>
编辑 关联培训计划
</Menu.Item> </Menu.Item>
<Menu.Item disabled={item.courseState === "STARTING"} key="del"> </Tooltip>
删除 }
</Menu.Item> {
item.thirdPartType !== "WECHAT" &&
<Menu.Item disabled={!(User.getUserRole() === 'CloudManager' || User.getUserRole() === 'StoreManager')} key="link">
关联培训计划
</Menu.Item>
}
{
(item.courseState === "STARTING" || item.courseState === "FINISH") &&
<Tooltip placement="left" title={`${item.courseState === "STARTING"?"直播已开始,不能编辑":"直播已结束,不能编辑"}`}>
<Menu.Item style={{color:"#999999"}}>
编辑
</Menu.Item>
</Tooltip>
}
{
item.courseState !== "STARTING" && item.courseState !== "FINISH" &&
<Menu.Item key="edit">
编辑
</Menu.Item>
}
{
(item.courseState === "STARTING" || (now > item.startTime && now < item.endTime)) &&
<Tooltip placement="left" title="直播进行中,不能删除">
<Menu.Item style={{color:"#999999"}}>
删除
</Menu.Item>
</Tooltip>
}
{
(item.courseState !== "STARTING" && (now < item.startTime || now > item.endTime)) &&
<Menu.Item key="del">
删除
</Menu.Item>
}
</Menu> </Menu>
) )
// return ( // return (
...@@ -734,9 +772,12 @@ class LiveCourseList extends React.Component { ...@@ -734,9 +772,12 @@ class LiveCourseList extends React.Component {
return return
} }
WechatApi.enterLiveRoom(item.livingId).then((res)=> { WechatApi.enterLiveRoom(item.livingId).then((res)=> {
console.log(res) console.log("进入企微直播间",res)
}).catch((err)=> { }).catch((err)=> {
console.log(err) Modal.warning({
title:"提示",
content: err
})
}) })
return return
} }
...@@ -794,7 +835,34 @@ class LiveCourseList extends React.Component { ...@@ -794,7 +835,34 @@ class LiveCourseList extends React.Component {
}) })
} }
handleViewPlayBack = (item) => { handleViewPlayBack = (item) => {
let htmlUrl if (item.thirdPartType === "WECHAT") {
if (!isWorkWx()) {
Modal.warning({
title:"提示",
content:"请使用企业微信进入回放"
})
return
}
if (item.startTime + 60*60*1000 < new Date().getTime()) {
Modal.warning({
title: '提示',
content: "该直播课的回放视频已失效",
});
return
}
WechatApi.replayLiving(item.livingId)
.then((res)=> {
console.log("进入企微回放")
})
.catch((err)=> {
Modal.warning({
title: '提示',
content: err,
});
})
return
}
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())) {
......
...@@ -91,7 +91,7 @@ class LiveCourseOpt extends React.Component { ...@@ -91,7 +91,7 @@ class LiveCourseOpt extends React.Component {
<Button type="primary" onClick={this.handleCreateLiveCouese}>新建直播课</Button> <Button type="primary" onClick={this.handleCreateLiveCouese}>新建直播课</Button>
} }
{/* <Button type="primary" onClick={this.handleCreateQWCouese}>新建企微直播课</Button> */} {/* <Button type="primary" onClick={this.handleCreateQWCouese}>新建企微直播课</Button> */}
{!this.state.isMac && <Button onClick={this.handleDownloadClient}>下载直播客户端</Button>} <Button onClick={this.handleDownloadClient}>下载直播客户端</Button>
</div> </div>
<Route path={`${match.url}/createqwcourse`} component={CreateWorkWXCourse} /> <Route path={`${match.url}/createqwcourse`} component={CreateWorkWXCourse} />
</div> </div>
......
...@@ -333,6 +333,7 @@ class ManageCoursewareModal extends React.Component { ...@@ -333,6 +333,7 @@ class ManageCoursewareModal extends React.Component {
]; ];
const { list, scanFileModal, editData, cancelObject, showSelectFileModal, selectedFileList, diskList, showPreviewModal, previewStatus, url } = this.state; const { list, scanFileModal, editData, cancelObject, showSelectFileModal, selectedFileList, diskList, showPreviewModal, previewStatus, url } = this.state;
const _list = _.reject(list, (item) => cancelObject[item.id]); const _list = _.reject(list, (item) => cancelObject[item.id]);
const { thirdPartType } = this.props.data
return ( return (
<Modal <Modal
visible={true} visible={true}
...@@ -348,10 +349,17 @@ class ManageCoursewareModal extends React.Component { ...@@ -348,10 +349,17 @@ class ManageCoursewareModal extends React.Component {
{_.isEmpty(_list) ? ( {_.isEmpty(_list) ? (
<div className='empty-body'> <div className='empty-body'>
<div id='lottie-box' className='empty-image'></div> <div id='lottie-box' className='empty-image'></div>
<Button className='empty-button' type='primary' onClick={() => this.addFile()}> { thirdPartType === "WECHAT" && <div className="qiwei-tip">企微直播<br/>Mac暂不支持上传课件,Windows可在直播间添加课件</div>}
<Button className='empty-button' type='primary'
disabled={thirdPartType === "WECHAT"}
onClick={() => {
if (thirdPartType !== "WECHAT") {
this.addFile()
}
}}>
上传课件 上传课件
</Button> </Button>
<p className='empty-tip'>提前上传直播需要的课件和素材,直播将会变得更便捷!</p> { thirdPartType !== "WECHAT" && <p className='empty-tip'>提前上传直播需要的课件和素材,直播将会变得更便捷!</p>}
</div> </div>
) : ( ) : (
<div className='manage-body'> <div className='manage-body'>
......
...@@ -11,6 +11,14 @@ ...@@ -11,6 +11,14 @@
width:150px; width:150px;
height:150px; height:150px;
} }
.qiwei-tip {
font-size: 14px;
font-weight: 400;
color: #999;
text-align: center;
margin-top: 12px;
margin-bottom: 12px;
}
.empty-button { .empty-button {
display: block; display: block;
margin: 0 auto 8px; margin: 0 auto 8px;
......
...@@ -48,7 +48,6 @@ class PreviewCourseModal extends React.Component { ...@@ -48,7 +48,6 @@ class PreviewCourseModal extends React.Component {
return hours + ":" + mins + ":" + seconds; return hours + ":" + mins + ":" + seconds;
}; };
dealWithTime = (startTime, endTime) => { dealWithTime = (startTime, endTime) => {
debugger
const startDate = new Date(Number(startTime)); const startDate = new Date(Number(startTime));
const endDate = new Date(Number(endTime)); const endDate = new Date(Number(endTime));
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: zhangleyuan * @Author: zhangleyuan
* @Date: 2020-11-27 15:06:31 * @Date: 2020-11-27 15:06:31
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-08-02 16:35:20 * @LastEditTime: 2021-08-05 10:26:25
* @Description: 描述一下 * @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -178,7 +178,7 @@ function PersonalInfoPage() { ...@@ -178,7 +178,7 @@ function PersonalInfoPage() {
<div> <div>
<span className="label">所在部门:</span> <span className="label">所在部门:</span>
{departmentList.map((item,index)=>{ {departmentList.map((item,index)=>{
return <span>{item}{index<departmentList.length-1?'、':''}</span> return <span><WWOpenDataCom type="departmentName" openid={item}/>{index<departmentList.length-1?'、':''}</span>
})} })}
</div> </div>
<div className="save-btn"> <div className="save-btn">
......
...@@ -353,17 +353,6 @@ class SelectOperatorModal extends React.Component { ...@@ -353,17 +353,6 @@ class SelectOperatorModal extends React.Component {
}, },
}, },
{ {
title: '直播方式',
key: 'thirdPartType',
dataIndex: 'thirdPartType',
width: 120,
render: (val, record) => {
return (
<div>{record.thirdPartType === "WECHAT" ? "企微直播":"小麦直播"}</div>
);
},
},
{
title: '学院展示', title: '学院展示',
key: 'shelfState', key: 'shelfState',
dataIndex: 'shelfState', dataIndex: 'shelfState',
......
...@@ -2,24 +2,24 @@ ...@@ -2,24 +2,24 @@
* @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-07-21 14:33:49 * @LastEditTime: 2021-07-19 16:21:07
* @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, Layout, DatePicker } 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/lib/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 moment from 'moment'; import moment from 'moment';
import WechatApi from '@/common/js/wechatApi';
import { VersionContext, VersionInfo, XMContext } from '@/store/context'; import { VersionContext, VersionInfo, XMContext } from '@/store/context';
import { setStoreGroupPermission, setStorePermission, setStoreGroupList, setStoreList, setWechatLogin } from '@/store/actions/index'; import { setStoreGroupPermission, setStorePermission, setStoreGroupList, setStoreList, setWechatLogin } 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 WechatApi from '@/common/js/wechatApi';
const { Footer, Sider, Content } = Layout; const { Footer, Sider, Content } = Layout;
...@@ -52,12 +52,7 @@ const App: React.FC = (props: any) => { ...@@ -52,12 +52,7 @@ const App: React.FC = (props: any) => {
}) })
async function initWechatConfig() {
WechatApi.initConfig({ isAgentConfig: true, url: window.location.href.split('#')[0] })
} }
}
useEffect(() => { useEffect(() => {
getStorePermission(); getStorePermission();
}, [window.location.hash]) }, [window.location.hash])
...@@ -173,6 +168,15 @@ const App: React.FC = (props: any) => { ...@@ -173,6 +168,15 @@ 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}> <VersionContext.Provider value={versionInfo}>
<ConfigProvider locale={zhCN} autoInsertSpaceInButton={false}> <ConfigProvider locale={zhCN} autoInsertSpaceInButton={false}>
......
...@@ -6,8 +6,8 @@ import User from "@/common/js/user"; ...@@ -6,8 +6,8 @@ import User from "@/common/js/user";
import { LIVE_SHARE } from "@/domains/course-domain/constants"; import { LIVE_SHARE } from "@/domains/course-domain/constants";
import { Modal, message } from 'antd'; import { Modal, message } from 'antd';
import WechatApi from '@/common/js/wechatApi'; import WechatApi from '@/common/js/wechatApi';
import { brandLogo } from '@/domains/brand/constants'
import WWOpenDataCom from '@/components/WWOpenData'; import WWOpenDataCom from '@/components/WWOpenData';
import { brandLogo,xfrwm } from '@/domains/brand/constants'
import './CollegeManagePage.less'; import './CollegeManagePage.less';
import storage from '@/common/js/storage'; import storage from '@/common/js/storage';
...@@ -94,7 +94,7 @@ function ExpirationPopover(props) { ...@@ -94,7 +94,7 @@ function ExpirationPopover(props) {
} }
<div className="qrcode"> <div className="qrcode">
<img src="https://cdn.xiaomai5.com/qixueyuankehu.png" alt=""></img> <img src={xfrwm} alt=""></img>
<div className="des">微信/企业微信扫码咨询</div> <div className="des">微信/企业微信扫码咨询</div>
</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> <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>
......
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