Commit 1e7dbc37 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 c59d9d6e 8e4ae974
...@@ -113,11 +113,12 @@ ...@@ -113,11 +113,12 @@
"start:gray": "cross-env DEPLOY_ENV=gray node scripts/start.js", "start:gray": "cross-env DEPLOY_ENV=gray node scripts/start.js",
"start:prod": "cross-env DEPLOY_ENV=prod node scripts/start.js", "start:prod": "cross-env DEPLOY_ENV=prod node scripts/start.js",
"start:syoo": "better-npm-run start:syoo", "start:syoo": "better-npm-run start:syoo",
"build:dev": "cross-env DEPLOY_ENV=dev node scripts/build.js", "build:dev": "cross-env DEPLOY_ENV=dev node --max_old_space_size=4096 scripts/build.js",
"build:dev1": "better-npm-run build:dev1", "build:dev1": "better-npm-run build:dev1",
"build:rc": "cross-env DEPLOY_ENV=rc node scripts/build.js", "build:rc": "cross-env DEPLOY_ENV=rc node scripts/build.js",
"build:gray": "cross-env DEPLOY_ENV=gray node scripts/build.js", "build:gray": "cross-env DEPLOY_ENV=gray node scripts/build.js",
"build:syoo": "better-npm-run build:syoo", "build:gray-syoo": "better-npm-run build:gray-syoo",
"build:prod-syoo": "better-npm-run build:prod-syoo",
"build:prod": "cross-env DEPLOY_ENV=prod node scripts/build.js" "build:prod": "cross-env DEPLOY_ENV=prod node scripts/build.js"
}, },
"betterScripts": { "betterScripts": {
...@@ -128,7 +129,14 @@ ...@@ -128,7 +129,14 @@
"BRAND": "syoo" "BRAND": "syoo"
} }
}, },
"build:syoo": { "build:gray-syoo": {
"command": "node scripts/build.js",
"env": {
"DEPLOY_ENV": "gray",
"BRAND": "syoo"
}
},
"build:prod-syoo": {
"command": "node scripts/build.js", "command": "node scripts/build.js",
"env": { "env": {
"DEPLOY_ENV": "prod", "DEPLOY_ENV": "prod",
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
<!-- <link rel="apple-touch-icon" href="../src/common/images/logo.png" /> --> <!-- <link rel="apple-touch-icon" href="../src/common/images/logo.png" /> -->
<link rel="shortcut icon" href="https://image.xiaomaiketang.com/xm/KGSYFEpcHT.png"> <link rel="shortcut icon" href="https://image.xiaomaiketang.com/xm/KGSYFEpcHT.png">
<title>小麦企学院</title> <title>扫码登陆</title>
<script type="text/javascript" charset="utf-8" src="./jquery.min.js"></script> <script type="text/javascript" charset="utf-8" src="./jquery.min.js"></script>
<style type="text/css"> <style type="text/css">
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
} }
.container-left-body-table{ .container-left-body-table{
width: 300px; width: 300px;
height: 330px; height: 360px;
overflow: scroll; overflow: scroll;
.ant-table { .ant-table {
border: none; border: none;
......
...@@ -96,6 +96,12 @@ class Axios { ...@@ -96,6 +96,12 @@ class Axios {
content: `当前企业购买的${window.brandName}服务已到期,如需继续使用学院功能,请尽快续费购买`, content: `当前企业购买的${window.brandName}服务已到期,如需继续使用学院功能,请尽快续费购买`,
okText: "我知道了" okText: "我知道了"
}) })
} else if (resultCode === "LIVE_START_FORBID_DEL") {
Modal.warning({
title:"提示",
content: "直播进行中,无法删除直播",
okText: "我知道了"
})
} else if (success || resultCode === 0) { } else if (success || resultCode === 0) {
return response; return response;
} else if (!options.reject) { } else if (!options.reject) {
......
module.exports = { module.exports = {
isWeiXin() { isWeiXin() {
const ua = navigator.userAgent.toLowerCase(); const ua = navigator.userAgent.toLowerCase();
return ua.indexOf('micromessenger') > 0; return (ua.indexOf('micromessenger') > 0) && !(/wxwork/i.test(navigator.userAgent));
}, },
isWorkWx (){ isWorkWx (){
return /wxwork/i.test(navigator.userAgent) return /wxwork/i.test(navigator.userAgent)
}, },
isAlipay() { isAlipay() {
const ua = navigator.userAgent.toLowerCase(); const ua = navigator.userAgent.toLowerCase();
return ua.indexOf('aliapp') > 0 || ua.indexOf('alipay') > 0; return ua.indexOf('aliapp') > 0 || ua.indexOf('alipay') > 0;
}, },
isXiaoMaiApp() { isXiaoMaiApp() {
const ua = navigator.userAgent.toLowerCase(); const ua = navigator.userAgent.toLowerCase();
return ua.match(/xiaomai_ios/i) === 'xiaomai_ios' || ua.match(/xiaomai_android/i) === 'xiaomai_android'; return ua.match(/xiaomai_ios/i) === 'xiaomai_ios' || ua.match(/xiaomai_android/i) === 'xiaomai_android';
}, },
isXiaoMaiIOSApp() { isXiaoMaiIOSApp() {
const ua = navigator.userAgent.toLowerCase(); const ua = navigator.userAgent.toLowerCase();
return ua.match(/xiaomai_ios/i) === 'xiaomai_ios'; return ua.match(/xiaomai_ios/i) === 'xiaomai_ios';
}, },
isXiaoMaiAndroidApp() { isXiaoMaiAndroidApp() {
const ua = navigator.userAgent.toLowerCase(); const ua = navigator.userAgent.toLowerCase();
return ua.match(/xiaomai_android/i) === 'xiaomai_android'; return ua.match(/xiaomai_android/i) === 'xiaomai_android';
}, },
isAndroid() { isAndroid() {
const ua = navigator.userAgent.toLowerCase(); const ua = navigator.userAgent.toLowerCase();
return /android/i.test(ua); return /android/i.test(ua);
}, },
isIOS() { isIOS() {
const ua = navigator.userAgent.toLowerCase(); const ua = navigator.userAgent.toLowerCase();
return /iphone|ipad|ipod/i.test(ua); return /iphone|ipad|ipod/i.test(ua);
}, },
isMeiKe() { isMeiKe() {
const ua = navigator.userAgent.toLowerCase(); const ua = navigator.userAgent.toLowerCase();
return /xmappc/i.test(ua); return /xmappc/i.test(ua);
}, },
}; isMac() {
const ua = navigator.platform.toLowerCase();
return ua.indexOf("mac") > 0
}
};
...@@ -12,66 +12,34 @@ import Platform from '@/common/js/platform'; ...@@ -12,66 +12,34 @@ import Platform from '@/common/js/platform';
import User from '@/common/js/user'; import User from '@/common/js/user';
import Service from '@/common/js/service'; import Service from '@/common/js/service';
console.log(wx.agentConfig,' console.log(wx.agentConfig) ')
export default class WechatApi { export default class WechatApi {
static async initConfig(params = { isAgentConfig: false, url: '' }) { static initConfig(params = { isAgentConfig: false, url: '' }) {
if (Platform.isWorkWx()) { if (Platform.isWorkWx()) {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
Service.Hades('anon/hades/getWxCorpJSAPISignature', { Service.Hades('anon/hades/getWxCorpJSAPISignature', {
storeId: User.getStoreId(), storeId: User.getStoreId(),
url: params.url, url: window.location.href.split('#')[0],
}).then((result) => { }).then((result) => {
const res = result.result; const res = result.result;
this.config({ wx.config({
beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题 beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: res.appId, // 必填,企业微信的corpID appId: res.appId, // 必填,企业微信的corpID
timestamp: res.timestamp, // 必填,生成签名的时间戳 timestamp: res.timestamp, // 必填,生成签名的时间戳
nonceStr: res.nonceStr, // 必填,生成签名的随机串 nonceStr: res.nonceStr, // 必填,生成签名的随机串
signature: res.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法 signature: res.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
jsApiList: ['chooseImage', 'shareToExternalContact', 'selectExternalContact', 'selectEnterpriseContact'], jsApiList: ['scanQRCode'],
}).then(() => { });
Service.Hades('anon/hades/getWxWorkJSAPISignature', { })
storeId: User.getStoreId(), wx.ready(() => {
url: params.url,
}).then((result2) => {
const res2 = result2.result;
this.agentConfig({
corpid: res2.corpid, // 必填,企业微信的corpid,必须与当前登录的企业一致
agentid: res2.agentid, // 必填,企业微信的应用id (e.g. 1000247)
timestamp: res2.timestamp, // 必填,生成签名的时间戳
nonceStr: res2.nonceStr, // 必填,生成签名的随机串
signature: res2.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
jsApiList: ['selectExternalContact', 'getCurExternalContact', 'getContext', 'shareToExternalContact', 'sendChatMessage', 'shareToExternalChat', 'startLiving', 'replayLiving'],
success: (res) => {
console.log(res, 'res-agentconfig');
console.info('window.WWOpenData', window.WWOpenData);
resolve(res);
},
fail: (err) => {
console.log(1213545344545)
console.log(err, 'err-agentconfig');
reject(err);
},
});
});
})
});
})
} else {
if (params.isAgentConfig) {
console.log(32132132, 'cesgu')
return new Promise(async (resolve, reject) => {
Service.Hades('anon/hades/getWxWorkJSAPISignature', { Service.Hades('anon/hades/getWxWorkJSAPISignature', {
storeId: User.getStoreId(), storeId: User.getStoreId(),
url: params.url, url: window.location.href.split('#')[0],
}).then((result2) => { }).then((result2) => {
const res2 = result2.result; const res2 = result2.result;
this.agentConfig({ wx.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, // 必填,生成签名的时间戳
...@@ -79,58 +47,55 @@ export default class WechatApi { ...@@ -79,58 +47,55 @@ export default class WechatApi {
signature: res2.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法 signature: res2.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
jsApiList: ['selectExternalContact', 'getCurExternalContact', 'getContext', 'shareToExternalContact', 'sendChatMessage', 'shareToExternalChat', 'startLiving', 'replayLiving'], jsApiList: ['selectExternalContact', 'getCurExternalContact', 'getContext', 'shareToExternalContact', 'sendChatMessage', 'shareToExternalChat', 'startLiving', 'replayLiving'],
success: (res) => { success: (res) => {
console.log(res, 'res-agentconfig'); console.log(res, 'agentConfig 成功', 'res-agentconfig');
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);
}, },
}); });
}); });
}); });
} wx.error((err) => {
} console.log('getWxCorpJSAPISignature', err)
});
} })
static async config(config) {
return new Promise((resolve, reject) => {
console.info('wx.config', config);
wx.config(config);
wx.ready(resolve);
wx.error(reject);
}).then(
() => {
console.info('wx.ready');
},
(error) => {
console.error('wx.error', error);
throw error;
}
);
}
static async agentConfig(config) { } else {
wx.agentConfig({ ...config });
}
static getCurExternalContact() { return new Promise(async (resolve, reject) => {
return new Promise((resolve, reject) => { Service.Hades('anon/hades/getWxWorkJSAPISignature', {
wx.ready(() => { storeId: User.getStoreId(),
wx.invoke('getCurExternalContact', {}, function (res) { url: window.location.href.split('#')[0],
if (res.err_msg == 'getCurExternalContact:ok') { }).then((result2) => {
resolve(res.userId); //返回当前外部联系人userId const res2 = result2.result;
} else { wx.agentConfig({
reject(res.err_msg); //错误处理 corpid: res2.corpid, // 必填,企业微信的corpid,必须与当前登录的企业一致
} agentid: res2.agentid, // 必填,企业微信的应用id (e.g. 1000247)
timestamp: res2.timestamp, // 必填,生成签名的时间戳
nonceStr: res2.nonceStr, // 必填,生成签名的随机串
signature: res2.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
jsApiList: ['selectExternalContact', 'getCurExternalContact', 'getContext', 'shareToExternalContact', 'sendChatMessage', 'shareToExternalChat', 'startLiving', 'replayLiving'],
success: (res) => {
console.log(res, 'agentConfig 成功', 'res-agentconfig');
resolve(res);
},
fail: (err) => {
console.log(1213545344545)
console.log(err, 'err-agentconfig');
},
});
}); });
}); });
}); }
} }
static getContext() { static getContext() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
wx.ready(() => { wx.ready(() => {
...@@ -150,13 +115,13 @@ export default class WechatApi { ...@@ -150,13 +115,13 @@ export default class WechatApi {
wx.ready(() => { wx.ready(() => {
wx.invoke('startLiving', { wx.invoke('startLiving', {
"livingId": id, "livingId": id,
}, function(res) { }, function (res) {
if (res.err_msg === "startLiving:ok") { if (res.err_msg === "startLiving:ok") {
resolve(true) resolve(true)
} else { } else {
reject(res.err_msg); //错误处理 reject(res.err_msg); //错误处理
} }
}); });
}); });
}) })
} }
...@@ -179,7 +144,8 @@ export default class WechatApi { ...@@ -179,7 +144,8 @@ export default class WechatApi {
} else if (res.err_msg === "replayLiving:fail_not allow to cross app") { } else if (res.err_msg === "replayLiving:fail_not allow to cross app") {
err = "不可跨应用使用直播ID" err = "不可跨应用使用直播ID"
} else if (res.err_msg === "replayLiving:fail_living has no replay") { } else if (res.err_msg === "replayLiving:fail_living has no replay") {
err = "直播回放已失效或不存在" // err = "直播回放已失效或不存在"
err = "该直播课未录制回放"
} else if (res.err_msg === "replayLiving:fail_replay is beging creating") { } else if (res.err_msg === "replayLiving:fail_replay is beging creating") {
err = "回放生成中,请耐心等待" err = "回放生成中,请耐心等待"
} else if (res.err_msg === "replayLiving:fail_create replay failed") { } else if (res.err_msg === "replayLiving:fail_create replay failed") {
...@@ -189,7 +155,7 @@ export default class WechatApi { ...@@ -189,7 +155,7 @@ export default class WechatApi {
} }
reject(err); //错误处理 reject(err); //错误处理
} }
}); });
}); });
}) })
} }
......
@font-face { @font-face {
font-family: 'iconfont'; /* Project id 2223403 */ font-family: 'iconfont'; /* Project id 2223403 */
src: url('//at.alicdn.com/t/font_2223403_6hd3qwwrou2.woff2?t=1627033726611') format('woff2'), src: url('//at.alicdn.com/t/font_2223403_7261tsts1dc.woff2?t=1628475376853') format('woff2'),
url('//at.alicdn.com/t/font_2223403_6hd3qwwrou2.woff?t=1627033726611') format('woff'), url('//at.alicdn.com/t/font_2223403_7261tsts1dc.woff?t=1628475376853') format('woff'),
url('//at.alicdn.com/t/font_2223403_6hd3qwwrou2.ttf?t=1627033726611') format('truetype'); url('//at.alicdn.com/t/font_2223403_7261tsts1dc.ttf?t=1628475376853') format('truetype');
} }
.iconfont { .iconfont {
font-family: 'iconfont' !important; font-family: 'iconfont' !important;
......
...@@ -1605,7 +1605,13 @@ input:focus { ...@@ -1605,7 +1605,13 @@ input:focus {
color: #2966FF !important; color: #2966FF !important;
margin-right: 16px !important; margin-right: 16px !important;
} }
.default-warning-icon {
font-size: 22px !important;
line-height: 22px !important;
float: left !important;
color: #FF4F4F !important;
margin-right: 16px !important;
}
.m-content { .m-content {
position: absolute; position: absolute;
top: 0; top: 0;
......
...@@ -39,5 +39,9 @@ module.exports = { ...@@ -39,5 +39,9 @@ module.exports = {
const ua = navigator.userAgent.toLowerCase(); const ua = navigator.userAgent.toLowerCase();
return /xmappc/i.test(ua); return /xmappc/i.test(ua);
}, },
isMac() {
const ua = navigator.platform.toLowerCase();
return ua.indexOf("mac") >= 0
}
}; };
\ No newline at end of file
import Platform from './platform';
import Service from "@/common/js/service";
import User from '@/common/js/user';
export default class WechatApi {
static initShareConfig() {
// if (Platform.isWeiXin()) {
const data = { url: window.location.href.split('#')[0], storeId: User.getStoreId(), }
Service.Hades('anon/hades/getWxWorkJSAPISignature', data).then((result) => {
const res = result.result;
const conf ={
corpid: res.corpid, // 必填,企业微信的corpid,必须与当前登录的企业一致
agentid: res.agentid, // 必填,企业微信的应用id (e.g. 1000247)
timestamp: res.timestamp, // 必填,生成签名的时间戳
nonceStr: res.nonceStr,// 必填,生成签名的随机串
signature: res.signature,
jsApiList: ['startLiving','downloadLivingReplay'],
success: function(res) {
console.log('agentConfig注册成功')
console.log(res,'agentConfig')
},
fail: function(res) {
console.log(res,' agentConfig1 错误')
if(res.errMsg.indexOf('function not exist') > -1){
alert('版本过低请升级')
}
},
complete:(res)=>{
console.log(res,' agentConfig2 错误')
}
}
console.log(conf)
wx.agentConfig(conf);
});
// }
}
}
\ No newline at end of file
...@@ -42,6 +42,10 @@ export function exportStudentCourseData(params: object) { ...@@ -42,6 +42,10 @@ export function exportStudentCourseData(params: object) {
return Service.Hades("public/courseCloud/exportCourseCloudVisitorAsync", params); return Service.Hades("public/courseCloud/exportCourseCloudVisitorAsync", params);
} }
export function exportWorkWXStudentCourseData(params: object) {
return Service.Hades("public/courseCloud/exportWechatLiveStudentData", params);
}
export function exportPlayBackCourseData(params: object) { export function exportPlayBackCourseData(params: object) {
return Service.Hades("public/courseCloud/exportCourseCloudPlayBackSync", params); return Service.Hades("public/courseCloud/exportCourseCloudPlayBackSync", params);
} }
......
/* /*
* @Author: 陈剑宇 * @Author: 陈剑宇
* @Date: 2020-05-07 14:43:01 * @Date: 2020-05-07 14:43:01
* @LastEditTime: 2021-06-22 16:49:06 * @LastEditTime: 2021-08-11 22:52:04
* @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
...@@ -23,8 +23,8 @@ const PATH_MAP: MapInterface = { ...@@ -23,8 +23,8 @@ const PATH_MAP: MapInterface = {
dev: 'https://dev.xiaomai5.com/xiaomai-cloud-class-web/h5.html', dev: 'https://dev.xiaomai5.com/xiaomai-cloud-class-web/h5.html',
dev1: 'https://dev.xiaomai5.com/dev1/xiaomai-cloud-class-web/h5.html', dev1: 'https://dev.xiaomai5.com/dev1/xiaomai-cloud-class-web/h5.html',
rc: 'https://rc.xiaomai5.com/xiaomai-cloud-class-web/h5.html', rc: 'https://rc.xiaomai5.com/xiaomai-cloud-class-web/h5.html',
gray: 'https://res.xiaomai0.com/xiaomai-cloud-class-web/gray/h5.html', gray: path + '/gray/h5.html',
prod: path, prod: path + '/h5.html',
} }
export const YZ_APPId = "yozoqvpO2Hvz8346"; export const YZ_APPId = "yozoqvpO2Hvz8346";
......
...@@ -3,7 +3,7 @@ export const BRAND: any = process.env.BRAND; ...@@ -3,7 +3,7 @@ export const BRAND: any = process.env.BRAND;
const BrandNameMap: any = { const BrandNameMap: any = {
xiaomai: '小麦企学院', xiaomai: '小麦企学院',
syoo: '云课堂' syoo: '商有云课堂'
} }
const BrandIconMap: any = { const BrandIconMap: any = {
...@@ -22,13 +22,13 @@ const BrandBannerMap: any = { ...@@ -22,13 +22,13 @@ const BrandBannerMap: any = {
} }
const PATH_MAP: any = { const PATH_MAP: any = {
prod: 'https://res.xiaomai0.com/xiaomai-cloud-class-web/h5.html', xiaomai: 'https://res.xiaomai0.com/xiaomai-cloud-class-web',
syoo: 'https://res.xiaomai0.com/xiaomai-cloud-class-web/h5.html', syoo: 'https://study.syoo.cn/syoo-cloud-class-web',
} }
const LIVE_SHARE_MAP: any = { const LIVE_SHARE_MAP: any = {
xiaomai: process.env.DEPLOY_ENV === 'dev' ? 'https://dev.xiaomai5.com/store-live/index.html#/' : 'https://res.xiaomai0.com/store-live/index.html#/', xiaomai: 'https://res.xiaomai0.com/store-live',
syoo: 'https://dev.xiaomai5.com/dev1/store-live/index.html#/', syoo: 'https://study.syoo.cn/syoo-store-live',
} }
...@@ -43,7 +43,10 @@ const XF_RWM_MAP: any = { ...@@ -43,7 +43,10 @@ const XF_RWM_MAP: any = {
syoo: 'https://image.xiaomaiketang.com/xm/Z2X2GTmKdj.png' syoo: 'https://image.xiaomaiketang.com/xm/Z2X2GTmKdj.png'
} }
const LiveNameMap: any = {
xiaomai: '小麦直播',
syoo: '商有直播'
}
export const brandName: string = BrandNameMap[BRAND]; export const brandName: string = BrandNameMap[BRAND];
...@@ -54,5 +57,6 @@ export const path: string = PATH_MAP[BRAND]; ...@@ -54,5 +57,6 @@ 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] export const xfrwm: string = XF_RWM_MAP[BRAND]
export const brandLiveName: string = LiveNameMap[BRAND]
window.brandName = BrandNameMap[BRAND]; window.brandName = BrandNameMap[BRAND];
...@@ -10,7 +10,7 @@ import { ...@@ -10,7 +10,7 @@ import {
fetchLecturerData, getCategoryTree, knowledgeMediaCoursePage, fetchUserData, exportStudentCourseData, exportPlayBackCourseData, fetchPlaybackList, createLiveCloudCourse, getLiveCloudCoursePage, fetchLecturerData, getCategoryTree, knowledgeMediaCoursePage, fetchUserData, exportStudentCourseData, exportPlayBackCourseData, fetchPlaybackList, createLiveCloudCourse, getLiveCloudCoursePage,
getLiveCloudCourseDetail, updateLiveCloudCourse, turnOnOrOffLiveCloudCourse, delLiveCloudCourse, changeVideoShelfState, createVideoSchedule, delVideoSchedule, getLiveCloudCourseDetail, updateLiveCloudCourse, turnOnOrOffLiveCloudCourse, delLiveCloudCourse, changeVideoShelfState, createVideoSchedule, delVideoSchedule,
editVideoSchedule, userWatchInfo, videoSchedulePage, videoScheduleDetail, videoWatchInfo, getQrcode, getLiveCloudCourseBasePage, videoScheduleBasePage, relatedCourseToPlan, editVideoSchedule, userWatchInfo, videoSchedulePage, videoScheduleDetail, videoWatchInfo, getQrcode, getLiveCloudCourseBasePage, videoScheduleBasePage, relatedCourseToPlan,
lineDetailWatchInfo, createWorkWXLiveCourse, fetchWorkWXLecturerData, fetchWorkWXUserData, getWorkWXLiveCourseDetail, updateWorkWXLiveCourse, delWorkWXLiveCourse lineDetailWatchInfo, createWorkWXLiveCourse, fetchWorkWXLecturerData, fetchWorkWXUserData, getWorkWXLiveCourseDetail, updateWorkWXLiveCourse, delWorkWXLiveCourse, exportWorkWXStudentCourseData
} from '@/data-source/course/request-api'; } from '@/data-source/course/request-api';
export default class courseService { export default class courseService {
...@@ -44,13 +44,17 @@ export default class courseService { ...@@ -44,13 +44,17 @@ export default class courseService {
return createWorkWXLiveCourse(params) return createWorkWXLiveCourse(params)
} }
static getLiveCloudCoursePage(params: any) { static getLiveCloudCoursePage(params: any) {
return getLiveCloudCoursePage(params); return getLiveCloudCoursePage({...params,terminalTypeEnum:"B_WEB"});
} }
// 导出学生上课数据 // 导出学生上课数据
static exportStudentCourseData(params: any) { static exportStudentCourseData(params: any) {
return exportStudentCourseData(params); return exportStudentCourseData(params);
} }
// 导出企微学生上课数据
static exportWorkWXStudentCourseData(params: any) {
return exportWorkWXStudentCourseData(params);
}
// 导出回放数据 // 导出回放数据
static exportPlayBackCourseData(params: any) { static exportPlayBackCourseData(params: any) {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-20 09:21:40 * @Date: 2020-08-20 09:21:40
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-11 15:17:56 * @LastEditTime: 2021-08-11 22:50:48
* @Description: * @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -30,8 +30,8 @@ const LIVE_SHARE_MAP: MapInterface = { ...@@ -30,8 +30,8 @@ const LIVE_SHARE_MAP: MapInterface = {
dev: 'https://dev.xiaomai5.com/store-live/index.html#/', dev: 'https://dev.xiaomai5.com/store-live/index.html#/',
dev1: 'https://dev.xiaomai5.com/dev1/store-live/index.html#/', dev1: 'https://dev.xiaomai5.com/dev1/store-live/index.html#/',
rc: 'https://rc.xiaomai5.com/store-live/index.html#/', rc: 'https://rc.xiaomai5.com/store-live/index.html#/',
gray: 'https://res.xiaomai0.com/store-live/gray/index.html#/', gray: live+'/gray/index.html#/',
prod: live, prod: live+'/index.html#/',
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-24 12:20:57 * @Date: 2020-08-24 12:20:57
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-08-03 14:27:49 * @LastEditTime: 2021-08-12 15:58:30
* @Description: * @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
--> -->
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
--> -->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="stylesheet" href="//at.alicdn.com/t/font_2223403_6hd3qwwrou2.css" /> <link rel="stylesheet" href="//at.alicdn.com/t/font_2223403_7261tsts1dc.css" />
<!-- <!--
Notice the use of %PUBLIC_URL% in the tags above. Notice the use of %PUBLIC_URL% in the tags above.
...@@ -41,21 +41,29 @@ ...@@ -41,21 +41,29 @@
work correctly both with client-side routing and a non-root public URL. work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
<title>小麦企学院</title> <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
<script type="text/javascript" src="https://image.xiaomaiketang.com/xm/iscroll-zoom-min.js"></script> <script type="text/javascript" src="https://image.xiaomaiketang.com/xm/iscroll-zoom-min.js"></script>
<script type="text/javascript" src="https://image.xiaomaiketang.com/xm/hammer.min.js"></script> <script type="text/javascript" src="https://image.xiaomaiketang.com/xm/hammer.min.js"></script>
<script type="text/javascript" src="https://image.xiaomaiketang.com/xm/lrz.all.bundle.js"></script> <script type="text/javascript" src="https://image.xiaomaiketang.com/xm/lrz.all.bundle.js"></script>
<script type="text/javascript" src="https://image.xiaomaiketang.com/xm/PhotoClip.js"></script> <script type="text/javascript" src="https://image.xiaomaiketang.com/xm/PhotoClip.js"></script>
<script type="text/javascript" charset="utf-8" src="//g.alicdn.com/sd/ncpc/nc.js?t=2015052012"></script> <script type="text/javascript" charset="utf-8" src="//g.alicdn.com/sd/ncpc/nc.js?t=2015052012"></script>
<script type="text/javascript" src="https://xiaomai-js.oss-cn-hangzhou.aliyuncs.com/loghub-xm-0.0.1-beta.js"></script> <script type="text/javascript" src="https://xiaomai-js.oss-cn-hangzhou.aliyuncs.com/loghub-xm-0.0.1-beta.js"></script>
<script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script type="text/javascript" src="//open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
</head> </head>
<body> <body>
<script>
setTimeout(()=>{
if(!wx.agentConfig){
window.location.reload()
}
},100)
</script>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root"></div>
<!-- <!--
This HTML file is a template. This HTML file is a template.
If you open it directly in the browser, you will see an empty page. If you open it directly in the browser, you will see an empty page.
......
...@@ -23,4 +23,7 @@ ...@@ -23,4 +23,7 @@
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.edit-disable{
color:#CCC !important;
}
} }
\ No newline at end of file
...@@ -34,7 +34,7 @@ interface RecordTypes { ...@@ -34,7 +34,7 @@ interface RecordTypes {
phone: string; phone: string;
avatar?: string; avatar?: string;
weChatAccount?: string; weChatAccount?: string;
depNameList:Array<string> depNameList:any
} }
interface RoleItemType { interface RoleItemType {
...@@ -59,6 +59,7 @@ interface ChoosedItemType { ...@@ -59,6 +59,7 @@ interface ChoosedItemType {
avatar?: string; avatar?: string;
storeUserId?: string; storeUserId?: string;
weChatAccount?: string; weChatAccount?: string;
depNameList?:any;
} }
function EmployeeManage() { function EmployeeManage() {
...@@ -144,7 +145,7 @@ function EmployeeManage() { ...@@ -144,7 +145,7 @@ function EmployeeManage() {
const columns = [ const columns = [
{ {
title: "员工", title: "员工",
dataIndex: "nickName", dataIndex: "weChatAccount",
render: (val: string, record: RecordTypes) => { render: (val: string, record: RecordTypes) => {
return ( return (
<div className="employee-info"> <div className="employee-info">
...@@ -185,10 +186,7 @@ function EmployeeManage() { ...@@ -185,10 +186,7 @@ function EmployeeManage() {
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={<div>{handleDepName(record.depNameList)}</div>} placement='top' arrowPointAtCenter><div className="post-name"> {record.depNameList.map((item:any, index:any) => {
// 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> return <span><WWOpenDataCom type="departmentName" openid={item}/>{index<(record.depNameList.length -1)?';':''}</span>
})} })}
</div> </div>
...@@ -212,9 +210,22 @@ function EmployeeManage() { ...@@ -212,9 +210,22 @@ function EmployeeManage() {
<div className="no-operate">-</div> <div className="no-operate">-</div>
) : ( ) : (
<div className="operation"> <div className="operation">
<span className="edit" onClick={() => handleEditEmployee(record)}> {!record.depNameList &&
编辑 <span className="edit edit-disable">
</span> 编辑
</span>
}
{record.depNameList &&
(record.depNameList.length > 0 ?
<span className="edit" onClick={() => handleEditEmployee(record)}>
编辑
</span>
:
<span className="edit edit-disable">
编辑
</span>
)
}
<span className="divider-line">{" | "}</span> <span className="divider-line">{" | "}</span>
<span <span
className="delete" className="delete"
...@@ -252,14 +263,15 @@ function EmployeeManage() { ...@@ -252,14 +263,15 @@ function EmployeeManage() {
}; };
function handleEditEmployee(record: RecordTypes) { function handleEditEmployee(record: RecordTypes) {
const { nickName, phone, roleCodes, avatar, id, weChatAccount } = record; const { nickName, phone, roleCodes, avatar, id, weChatAccount,depNameList} = record;
const _choosesItem = { const _choosesItem = {
nickName: nickName, nickName: nickName,
phone: phone, phone: phone,
role: roleCodes, role: roleCodes,
avatar: avatar, avatar: avatar,
storeUserId: id, storeUserId: id,
weChatAccount weChatAccount,
depNameList:depNameList
}; };
setChooseItem(_choosesItem); setChooseItem(_choosesItem);
const model: React.ReactNode = ( const model: React.ReactNode = (
...@@ -274,7 +286,8 @@ function EmployeeManage() { ...@@ -274,7 +286,8 @@ function EmployeeManage() {
role: [], role: [],
avatar: "", avatar: "",
storeUserId: "", storeUserId: "",
weChatAccount: "" weChatAccount:"",
depNameList:[]
}); });
}} }}
isWorkWechat={isWorkWechat} isWorkWechat={isWorkWechat}
...@@ -322,7 +335,7 @@ function EmployeeManage() { ...@@ -322,7 +335,7 @@ function EmployeeManage() {
if(num<3){ if(num<3){
return confirm({ return confirm({
title: "确定更新列表数据吗?", title: "确定更新列表数据吗?",
content: `员工数据来源企微通讯录,一天只能更新3次,今日还能更新${3-num}次。`, content: <span>员工数据来源企微通讯录,一天只能更新3次,今日还能更新<span style={{color:'#2966FF'}}>{3-num}</span>次。</span>,
icon: ( icon: (
<span className="icon iconfont default-confirm-icon">&#xe839; </span> <span className="icon iconfont default-confirm-icon">&#xe839; </span>
), ),
...@@ -336,7 +349,7 @@ function EmployeeManage() { ...@@ -336,7 +349,7 @@ function EmployeeManage() {
Modal.warning({ Modal.warning({
title: '提示', title: '提示',
okText: '我知道了', okText: '我知道了',
content: '员工数据今日更新次数已达上限(3次),无法继续更新。', content: <span>员工数据今日更新次数已达上限<span style={{color:'#2966FF'}}>(3次)</span>,无法继续更新。</span>,
icon: ( icon: (
<span className='icon iconfont default-confirm-icon' style={{ color: '#FFBB54 !important' }}> <span className='icon iconfont default-confirm-icon' style={{ color: '#FFBB54 !important' }}>
&#xe834; &#xe834;
...@@ -463,7 +476,7 @@ function EmployeeManage() { ...@@ -463,7 +476,7 @@ function EmployeeManage() {
<Button className="update-user-btn" onClick={()=>{updateListData()}}>更新列表数据</Button> <Button className="update-user-btn" onClick={()=>{updateListData()}}>更新列表数据</Button>
<span className="origin-text">数据来源企业微信通讯录</span> <span className="origin-text">数据来源企业微信通讯录</span>
<a <a
href="https://www.yuque.com/wangzhong-zkqw0/qixue" href="https://www.yuque.com/docs/share/8c66333f-ed62-469d-909e-b36389a115ea?#"
target="_blank" target="_blank"
> >
<span className="view-text">查看数据更新说明</span> <span className="view-text">查看数据更新说明</span>
......
/* /*
* @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:23:37 * @LastEditTime: 2021-08-11 20:25:26
* @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
......
...@@ -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: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-08-03 16:04:30 * @LastEditTime: 2021-08-11 20:31:26
* @Description: 学员管理页面 * @Description: 学员管理页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -11,9 +11,7 @@ import React, { useEffect, useState } from "react"; ...@@ -11,9 +11,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 {Tabs,Input,Tree,Button} from "antd"; import {Tabs,Input,Tree,Button} from "antd";
import CustomGroupTabCon from './components/CustomGroupTabCon';
import DepartMentTabCon from './components/DepartMentTabCon'; import DepartMentTabCon from './components/DepartMentTabCon';
import PostGroupTabCon from './components/PostGroupTabCon';
import "./NewUsersManagePage.less"; import "./NewUsersManagePage.less";
const { TabPane } = Tabs; const { TabPane } = Tabs;
......
.new-user-manage-page{
.ant-tabs-tab + .ant-tabs-tab{
margin:0;
}
}
\ No newline at end of file
import React, { useEffect, useState } from "react";
import { withRouter } from "react-router-dom";
import { Button, Input, message } from "antd";
import LeftStructureTree from "./LeftStructureTree";
import AddOrEditPostGroupModal from "../modal/AddOrEditPostGroupModal";
import UserTable from "./UserTable";
import "./PostGroupTabCon.less";
const { Search } = Input;
function CustomGroupTabCon() {
const [postGroupTreeData, setPostGroupTreeData] = useState([]);
return (
<div className="post-group-tab-con">
<LeftStructureTree
treeData={postGroupTreeData}
treeType={"customGroupTab"}
editPostGroup={(record)=>editPostGroup(record)}
addPostGroup={(record)=>addPostGroup(record)}
/>
<div className="table-con">
<div className="operate-area">
<Button type="primary" className="add-user-btn">
添加学员
</Button>
<Button className="del-user-btn">移出学员</Button>
</div>
<UserTable />
</div>
</div>
);
}
export default withRouter(CustomGroupTabCon);
...@@ -28,6 +28,9 @@ function DepartMentTabCon(props) { ...@@ -28,6 +28,9 @@ function DepartMentTabCon(props) {
const [userListdata, setUserListData] = useState([]); const [userListdata, setUserListData] = useState([]);
const [selectUser,setSelectUser] = useState([]); // 设置选中的用户 const [selectUser,setSelectUser] = useState([]); // 设置选中的用户
const [selectDep,setSelectDep] = useState({}); const [selectDep,setSelectDep] = useState({});
useEffect(()=>{
setSelectUser([]);
},[selectDep]);
const columns = [ const columns = [
{ {
title: "学员", title: "学员",
...@@ -37,8 +40,8 @@ function DepartMentTabCon(props) { ...@@ -37,8 +40,8 @@ function DepartMentTabCon(props) {
return ( return (
<div> <div>
{item.sourceEnum === "WORK_WE_CHAT" ? {item.sourceEnum === "WORK_WE_CHAT" ?
<span> <WWOpenDataCom type="userName" openid={val}/></span>: <Tooltip title={<div><WWOpenDataCom type="userName" openid={val}/></div>}><span className="student-name"><WWOpenDataCom type="userName" openid={val}/></span></Tooltip>:
<span>{val}</span> <Tooltip title={val}><span className="student-name">{val}</span></Tooltip>
} }
<span <span
className="tag" className="tag"
...@@ -56,9 +59,9 @@ function DepartMentTabCon(props) { ...@@ -56,9 +59,9 @@ function DepartMentTabCon(props) {
{ {
title: "真实姓名", title: "真实姓名",
dataIndex: "realName", dataIndex: "realName",
width: "15%", width: 180,
render: (val, record) => { render: (val, record) => {
return <span>{val}</span>; return <span>{val}</span>
}, },
}, },
{ {
...@@ -71,6 +74,7 @@ function DepartMentTabCon(props) { ...@@ -71,6 +74,7 @@ function DepartMentTabCon(props) {
}, },
{ {
title: "岗位", title: "岗位",
width: "15%",
dataIndex: "depNameList", dataIndex: "depNameList",
render: (val, record) => { render: (val, record) => {
...@@ -92,6 +96,7 @@ function DepartMentTabCon(props) { ...@@ -92,6 +96,7 @@ function DepartMentTabCon(props) {
{ {
title: "手机号", title: "手机号",
dataIndex: "phone", dataIndex: "phone",
width: "15%",
render: (val, item) => { render: (val, item) => {
if(!val){ if(!val){
return <span>-</span> return <span>-</span>
...@@ -103,6 +108,7 @@ function DepartMentTabCon(props) { ...@@ -103,6 +108,7 @@ function DepartMentTabCon(props) {
{ {
title: "注册时间", title: "注册时间",
dataIndex: "created", dataIndex: "created",
width: "15%",
render: (val, item) => { render: (val, item) => {
return <div>{moment(val).format("YYYY-MM-DD HH:mm:ss")}</div>; return <div>{moment(val).format("YYYY-MM-DD HH:mm:ss")}</div>;
}, },
...@@ -111,13 +117,19 @@ function DepartMentTabCon(props) { ...@@ -111,13 +117,19 @@ function DepartMentTabCon(props) {
title: "操作", title: "操作",
key: "operate", key: "operate",
dataIndex: "operate", dataIndex: "operate",
width: 60,
fixed: 'right',
render: (val, item) => { render: (val, item) => {
return ( return (
<div className="operate"> <div className="operate">
{props.currentTab==='departMentTab'? {props.currentTab==='departMentTab'?
<div className="operate__item" onClick={()=>delUser('single',item.userId)}>删除</div> <span>-</span>
: :
<div className="operate__item" onClick={()=>delUser('single',item.userId)}>移出</div> (selectDep.depLevel > 0 ?
<div className="operate__item" onClick={()=>delUser('single',item.userId)}>移出</div>
:
<span>-</span>
)
} }
</div> </div>
); );
...@@ -181,6 +193,9 @@ function DepartMentTabCon(props) { ...@@ -181,6 +193,9 @@ function DepartMentTabCon(props) {
function delUser(type,userId){ function delUser(type,userId){
let idList = []; let idList = [];
let title = '';
let content = '';
let okText = '';
if(type === 'single'){ if(type === 'single'){
idList.push(userId); idList.push(userId);
} }
...@@ -188,16 +203,38 @@ function DepartMentTabCon(props) { ...@@ -188,16 +203,38 @@ function DepartMentTabCon(props) {
idList = _.pluck(selectUser,'userId'); idList = _.pluck(selectUser,'userId');
} }
if(idList.length===0){ if(idList.length===0){
message.warning('请先选择要删除的学员') message.warning('请先选择要移出的学员')
return; return;
} }
switch (props.currentTab){
case 'departMentTab':
title = '确定要删除学员吗?';
content = '删除后,该学员将从员工列表中删除,且看不到该学院用户端。';
okText = '删除';
break;
case 'postGrouptab':
title = '确定要移出该学员吗?';
content = '移出后,该学员将从岗位列表中移出。';
okText = '移出';
break;
case 'customGroupTab':
title = '确定要移出该学员吗?';
content = '移出后,该学员将从分组列表中移出。';
okText = '移出';
break;
default:
title = '确定要删除学员吗?';
content = '删除后,该学员将从员工列表中删除,且看不到该学院用户端。';
okText = '删除';
break;
}
return confirm({ return confirm({
title: "确定要删除学员吗?", title,
content: "删除后,该学员将从员工列表中删除,且看不到该学院用户端。", content,
icon: ( icon: (
<span className="icon iconfont default-confirm-icon">&#xe839; </span> <span className="icon iconfont default-confirm-icon">&#xe839; </span>
), ),
okText: "删除", okText,
okType: "danger", okType: "danger",
cancelText: "取消", cancelText: "取消",
onOk: () => { onOk: () => {
...@@ -213,13 +250,18 @@ function DepartMentTabCon(props) { ...@@ -213,13 +250,18 @@ function DepartMentTabCon(props) {
storeId:User.getStoreId() storeId:User.getStoreId()
} }
console.log('selectDep',selectDep) console.log('selectDep',selectDep)
if(selectDep.id==='100'){ if(selectDep.depId==='10000'){
params.userType='WE_CHAT'; params.userType='WE_CHAT';
}else{ }else{
params.userType='WORK_WE_CHAT'; params.userType='WORK_WE_CHAT';
} }
params.departmentId = selectDep.id;
StoreService.delDepartmentUser(params).then((res) => { StoreService.delDepartmentUser(params).then((res) => {
message.success(`删除成功`); if(props.currentTab === "departMentTab"){
message.success(`删除成功`);
}else{
message.success(`移出成功`);
}
getUserList(); getUserList();
Bus.trigger("changeTreeData",{treeType:props.currentTab}); Bus.trigger("changeTreeData",{treeType:props.currentTab});
}); });
...@@ -251,7 +293,7 @@ function DepartMentTabCon(props) { ...@@ -251,7 +293,7 @@ function DepartMentTabCon(props) {
if(num<3){ if(num<3){
return confirm({ return confirm({
title: "确定更新列表数据吗?", title: "确定更新列表数据吗?",
content: `学员数据来源企微通讯录,一天只能更新3次,今日还能更新${3-num}次。`, content: <span>学员数据来源企微通讯录,一天只能更新3次,今日还能更新<span style={{color:'#2966FF'}}>{3-num}</span>次。</span>,
icon: ( icon: (
<span className="icon iconfont default-confirm-icon">&#xe839; </span> <span className="icon iconfont default-confirm-icon">&#xe839; </span>
), ),
...@@ -265,7 +307,7 @@ function DepartMentTabCon(props) { ...@@ -265,7 +307,7 @@ function DepartMentTabCon(props) {
Modal.warning({ Modal.warning({
title: '提示', title: '提示',
okText: '我知道了', okText: '我知道了',
content: '学员数据今日更新次数已达上限(3次),无法继续更新。', content: <span>学员数据今日更新次数已达上限<span style={{color:'#2966FF'}}>(3次)</span>,无法继续更新。</span>,
icon: ( icon: (
<span className='icon iconfont default-confirm-icon' style={{ color: '#FFBB54 !important' }}> <span className='icon iconfont default-confirm-icon' style={{ color: '#FFBB54 !important' }}>
&#xe834; &#xe834;
...@@ -289,15 +331,15 @@ function DepartMentTabCon(props) { ...@@ -289,15 +331,15 @@ function DepartMentTabCon(props) {
return ( return (
<div className="department-tab-con"> <div className="department-tab-con">
<LeftStructureTree <LeftStructureTree
treeType={props.currentTab} treeType={props.currentTab}
searchUserList={(params,treeType) => getUserList(params,treeType,1)} searchUserList={(params,treeType) => getUserList(params,treeType,1)}
onChangeSelectDep={(record)=>{setSelectDep(record);}} onChangeSelectDep={(record)=>{setSelectDep(record);}}
/> />
<div className="table-con"> <div className="table-con">
{props.currentTab === "departMentTab" && ( {props.currentTab === "departMentTab" && (
<div className="operate-area"> <div className="operate-area">
{ selectDep.id !== '100' && { selectDep.depId !== '10000' &&
<Button <Button
type="primary" type="primary"
className="add-user-btn" className="add-user-btn"
...@@ -308,13 +350,15 @@ function DepartMentTabCon(props) { ...@@ -308,13 +350,15 @@ function DepartMentTabCon(props) {
添加学员 添加学员
</Button> </Button>
} }
<Button className="del-user-btn" onClick={()=>delUser('multiple')}>删除学员</Button> {(props.currentTab === "postGrouptab" || props.currentTab === "customGroupTab") &&
{ selectDep.id !== '100' && <Button className="del-user-btn" onClick={()=>delUser('multiple')}>删除学员</Button>
}
{ selectDep.depId !== '10000' &&
<> <>
<Button className="update-user-btn" onClick={()=>{updateListData()}}>更新列表数据</Button> <Button className="update-user-btn" onClick={()=>{updateListData()}}>更新列表数据</Button>
<span className="origin-text">数据来源企业微信通讯录</span> <span className="origin-text">数据来源企业微信通讯录</span>
<a <a
href="https://www.yuque.com/wangzhong-zkqw0/qixue" href="https://www.yuque.com/docs/share/8c66333f-ed62-469d-909e-b36389a115ea?#"
target="_blank" target="_blank"
> >
<span className="view-text">查看数据更新说明</span> <span className="view-text">查看数据更新说明</span>
...@@ -338,7 +382,9 @@ function DepartMentTabCon(props) { ...@@ -338,7 +382,9 @@ function DepartMentTabCon(props) {
添加学员 添加学员
</Button> </Button>
} }
<Button className="del-user-btn" onClick={()=>delUser('multiple')}>移出学员</Button> {selectDep.depLevel > 0 &&
<Button className="del-user-btn" onClick={()=>delUser('multiple')}>移出学员</Button>
}
</div> </div>
)} )}
<div className="user-table"> <div className="user-table">
...@@ -347,11 +393,11 @@ function DepartMentTabCon(props) { ...@@ -347,11 +393,11 @@ function DepartMentTabCon(props) {
image: college, image: college,
description: "暂无数据", description: "暂无数据",
}} }}
scroll={{ x: 1200 }}
bordered bordered
size="middle" size="middle"
pagination={false} pagination={false}
columns={columns} columns={columns}
scroll={{ x: 800 }}
dataSource={userListdata} dataSource={userListdata}
rowKey={(record) => record.userId} rowKey={(record) => record.userId}
rowSelection={{ rowSelection={{
...@@ -369,7 +415,7 @@ function DepartMentTabCon(props) { ...@@ -369,7 +415,7 @@ function DepartMentTabCon(props) {
_list = _.reject(selectUser, (item) => _.find(changeRows, (data) => data.userId === item.userId)); _list = _.reject(selectUser, (item) => _.find(changeRows, (data) => data.userId === item.userId));
} }
if (_list.length > 50) { if (_list.length > 50) {
message.warning('无法继续选择,一个任务最多关联50个课程'); message.warning('无法继续选择,最多选择50个');
const extraLength = _list.length - 50; const extraLength = _list.length - 50;
_list.splice(_list.length - extraLength, extraLength); _list.splice(_list.length - extraLength, extraLength);
} }
......
.department-tab-con{ .department-tab-con{
display: flex; display: flex;
.table-con{ .table-con{
margin-left:16px;
flex:1; flex:1;
max-width: calc(100% - 290px);
.post-name{ .post-name{
max-width: 200px; max-width: 200px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.student-name{
max-width: 120px;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
vertical-align: middle;
display: inline-block;
}
.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: 17px;
width:260px; width:260px;
flex-shrink: 0;
height: calc(~'100vh - 260px'); height: calc(~'100vh - 260px');
overflow-y: scroll; overflow: scroll;
border-right:1px solid #eee;
.organization{ .organization{
overflow: scroll;
.search-con{ .search-con{
margin-bottom: 10px; margin-bottom: 10px;
} }
...@@ -69,7 +70,45 @@ ...@@ -69,7 +70,45 @@
color: #666666; color: #666666;
} }
} }
} }
} }
.certain-category-search-dropdown{
.catalog-title{
font-size:14px;
color:#666;
margin-bottom:14px;
}
.search-result-item{
padding:14px 0;
color:#333;
.title-icon{
color:#999;
margin-right:3px;
}
.search-result-item__left{
font-size:14px;
}
.search-result-item__right{
font-size:14px;
width:84px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color:#999;
text-align:right;
}
}
.empty-con{
text-align:center;
.empty-img{
width:150px;
height:150px;
}
.empty-text{
color:#666;
}
}
}
\ No newline at end of file
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 { Tree} from "antd"; import { Tree,Tooltip} 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 WWOpenDataCom from '@/components/WWOpenDataCom'; import WWOpenDataCom from '@/components/WWOpenDataCom';
...@@ -40,7 +40,7 @@ function MemberTree(props) { ...@@ -40,7 +40,7 @@ function MemberTree(props) {
const _dataArray = dataArray.map((item,index)=>{ const _dataArray = dataArray.map((item,index)=>{
item.title = ""; item.title = "";
item.key=item.id; item.key=item.id;
item.children = [] item.children = [];
if(item.departmentUserVOList){ if(item.departmentUserVOList){
item.children = item.departmentUserVOList; item.children = item.departmentUserVOList;
} }
...@@ -60,11 +60,10 @@ function MemberTree(props) { ...@@ -60,11 +60,10 @@ function MemberTree(props) {
const _checkedNodes = e.checkedNodes; const _checkedNodes = e.checkedNodes;
const _selectNodes = []; const _selectNodes = [];
_checkedNodes.map((item,index)=>{ _checkedNodes.map((item,index)=>{
if(item.userId){ // if(item.userId){
_selectNodes.push(item); _selectNodes.push(item);
} // }
}) })
console.log('_selectNodes',_selectNodes);
props.onSelect(_selectNodes); props.onSelect(_selectNodes);
} }
return ( return (
...@@ -75,7 +74,7 @@ function MemberTree(props) { ...@@ -75,7 +74,7 @@ function MemberTree(props) {
checkable checkable
showIcon={false} showIcon={false}
treeData={treeData} treeData={treeData}
checkedKeys={_.pluck(props.selectUserList, 'id')} checkedKeys={_.pluck(props.selectList, 'id')}
onCheck={(selectedKeys,e)=>treeSelected(selectedKeys,e)} onCheck={(selectedKeys,e)=>treeSelected(selectedKeys,e)}
titleRender={(nodeData) => { titleRender={(nodeData) => {
return ( return (
...@@ -83,15 +82,20 @@ function MemberTree(props) { ...@@ -83,15 +82,20 @@ function MemberTree(props) {
className="node-title-con" className="node-title-con"
> >
{nodeData.userId ? {nodeData.userId ?
<div> <>
<span className="icon iconfont title-icon">&#xe603;</span> <span className="icon iconfont title-icon">&#xe603;</span>
<span><WWOpenDataCom type="userName" openid={nodeData.userName}/></span> <Tooltip title={<WWOpenDataCom type="userName" openid={nodeData.userName}/>}>
</div> <span className="name"><WWOpenDataCom type="userName" openid={nodeData.userName}/></span>
</Tooltip>
</>
: :
<div> <>
<span className="icon iconfont title-icon">&#xe604;</span> <span className="icon iconfont title-icon">&#xe604;</span>
<span><WWOpenDataCom type="departmentName" openid={nodeData.name}/></span> <Tooltip title={<WWOpenDataCom type="departmentName" openid={nodeData.name}/>}>
</div> <span className="name"><WWOpenDataCom type="departmentName" openid={nodeData.name}/></span>
</Tooltip>
<span>({nodeData.departmentCount || 0})</span>
</>
} }
</div> </div>
); );
......
...@@ -2,8 +2,29 @@ ...@@ -2,8 +2,29 @@
.node-title-con{ .node-title-con{
color:#666; color:#666;
font-size:14px; font-size:14px;
display: flex;
.name{
display: inline-block;
vertical-align: middle;
max-width:190px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.title-icon{ .title-icon{
font-size:14px;
color:#999;
margin-right:8px; margin-right:8px;
} }
} }
.ant-tree .ant-tree-treenode {
padding: 8px 0 14px 0;
}
.ant-tree.ant-tree-directory .ant-tree-treenode-selected:hover::before, .ant-tree.ant-tree-directory .ant-tree-treenode-selected::before{
background:transparent;
}
.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-switcher{
color:#000;
}
} }
\ No newline at end of file
import React, { useEffect, useState } from "react";
import { withRouter } from "react-router-dom";
import { Button, Input, message,Modal} from "antd";
import LeftStructureTree from "./LeftStructureTree";
import UserTable from "./UserTable";
import "./PostGroupTabCon.less";
const { Search } = Input;
function PostGroupTabCon() {
// const [addOrEditPostGroupShow, setAddOrEditPostGroupShow] = useState(false);
// const [postGroupModalType, setPostGroupModalType] = useState("");
// const [operatePostGroupModalType,setOperatePostGroupModalType] = useState("");
// const [postGroupModalTitle,setPostGroupModalTitle] = useState("");
// const [postGroupModalLable,setPostGroupModalLable] = useState("");
const [postGroupTreeData, setPostGroupTreeData] = useState([]);
// function closeAddOrEditPostGroupModal() {
// setAddOrEditPostGroupShow(false);
// }
// //添加岗位组/岗位
// function addPostGroup(type) {
// if (postGroupTreeData.length === 10) {
// message.error("岗位组数量已达10个上限");
// return;
// }
// setAddOrEditPostGroupShow(true);
// setOperatePostGroupModalType("add");
// if(type==='parentGroup'){
// setPostGroupModalType('parentGroup'); //parentGroup 代表岗位组
// setPostGroupModalTitle('添加岗位组');
// setPostGroupModalLable('岗位组');
// }else{
// setPostGroupModalType('sub');
// setPostGroupModalTitle('添加岗位'); // sub代表岗位
// setPostGroupModalLable('岗位');
// }
// }
// //编辑岗位组/岗位
// function editPostGroup(record){
// setAddOrEditPostGroupShow(true);
// setOperatePostGroupModalType("edit");
// //level为0的时候编辑的是岗位组 大于0的时候
// if(record.level===0){
// setPostGroupModalType('parentGroup');
// setPostGroupModalTitle('编辑岗位组');
// setPostGroupModalLable('岗位组');
// }else{
// setPostGroupModalType('sub');
// setPostGroupModalTitle('编辑岗位');
// setPostGroupModalLable('岗位');
// }
// }
// function delPostGroup(record){
// let title = '确认删除该岗位组吗?';
// let content= '删除后,该岗位组下的岗位及也将全部删除。';
// if(record.level>0){
// title = '确认删除该岗位吗?';
// content = '删除后,不可恢复';
// }
// Modal.confirm({
// title,
// content,
// icon: <span className='icon iconfont default-confirm-icon'>&#xe6f4;</span>,
// okText: '确定',
// okType: 'danger',
// cancelText: '取消',
// onOk: () => {
// },
// });
// }
// function confirmAddOrEditPostGroup() {
// getPostGroupTreeData()
// }
return (
<div className="post-group-tab-con">
{/* <div className="organization">
<div className="search-con">
<Search
placeholder="搜索部门/学员姓名"
className="search search-input"
style={{ width: 245 }}
enterButton={<span className="icon iconfont">&#xe832;</span>}
/>
</div>
<div className="operate">
<Button
className="add-btn"
onClick={() => {
addPostGroup('postGroup');
}}
>
添加岗位组
</Button>
</div>
</div> */}
<LeftStructureTree
treeData={postGroupTreeData}
treeType={"postGrouptab"}
editPostGroup={(record)=>editPostGroup(record)}
addPostGroup={(record)=>addPostGroup(record)}
delPostGroup={(record)=>delPostGroup('record')}
/>
<div className="table-con">
<div className="operate-area">
<Button type="primary" className="add-user-btn">
添加学员
</Button>
<Button className="del-user-btn">移出学员</Button>
</div>
<UserTable />
</div>
{/* {addOrEditPostGroupShow && (
<AddOrEditPostGroupModal
onClose={() => {
closeAddOrEditPostGroupModal();
}}
onConfirm={() => {
confirmAddOrEditPostGroup();
}}
title={postGroupModalTitle}
modalType={postGroupModalType}
modalOperateType={operatePostGroupModalType}
postGroupName={postGroupName}
postGroupTreeData={postGroupTreeData}
label={postGroupModalLable}
/>
)} */}
</div>
);
}
export default withRouter(PostGroupTabCon);
.post-group-tab-con {
display: flex;
.table-con {
margin-left: 16px;
flex: 1;
.operate-area {
margin-bottom: 16px;
.add-user-btn {
margin-right: 8px;
}
.del-user-btn {
margin-right: 8px;
}
.update-user-btn {
margin-right: 8px;
}
.origin-text {
font-size: 14px;
color: #999;
}
.view-text {
font-size: 14px;
color: #5289fa;
}
}
}
}
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 { Input,Checkbox} from "antd"; import { Input,Checkbox,Tooltip} 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 WWOpenDataCom from '@/components/WWOpenDataCom'; import WWOpenDataCom from '@/components/WWOpenDataCom';
import $ from 'jquery'; import $ from 'jquery';
import _ from 'underscore';
import './SearchUser.less' import './SearchUser.less'
const { Search } = Input; const { Search } = Input;
function SearchUser(props) { function SearchUser(props) {
...@@ -17,19 +18,53 @@ function SearchUser(props) { ...@@ -17,19 +18,53 @@ function SearchUser(props) {
} }
function onChange(e){ function onChange(e){
setDropDownVisible(true);
props.onChange(e.target.value) props.onChange(e.target.value)
} }
function selectuser(e,item){ function selectuser(e,item){
if(e.target.checked){ if(e.target.checked){
let _record = [] let _record = props.selectList
_record.push(item) _record.push(item)
props.onSelect(_record,'user') props.onSelect(_record,'user')
}else{
let _record = props.selectList
_record.map((_item,index)=>{
if(_item.userId === item.userId){
_record.splice(index,1)
}
})
props.onSelect(_record,'user')
} }
} }
function selectDep(e,item){ function selectDep(e,item){
console.log('item',item);
if(e.target.checked){ if(e.target.checked){
console.log('item',item); let _record = props.selectList;
props.onSelect(item,'department'); let _userList = [];
_record.push(item); // 将当前选中的部门塞进来
if(item.departmentUserVOList){
_userList = item.departmentUserVOList; //获取当前选中的人
}
_record = [..._record,..._userList];
props.onSelect(_record,'department');
}else{
let _record = [];
let _userList = [];
props.selectList.map((_item,index)=>{
if(_item.id !== item.id){ //取消选择后将当前的部门移除也要将父部门也移除
_record.push(_item);
}
})
if(item.departmentUserVOList){
_userList = item.departmentUserVOList; //获取当前选中的人
}
const new_arr = _record.filter((x) => {return !_userList.some((item) => x.id === item.id)});
// _userList.map((_item,index)=>{
// if(_item.id === item.id){
// _record.splice(_item,index);
// }
// })
props.onSelect(new_arr,'department');
} }
} }
function documentClick(){ function documentClick(){
...@@ -41,6 +76,12 @@ function SearchUser(props) { ...@@ -41,6 +76,12 @@ function SearchUser(props) {
}; };
} }
function handleDepName(depArray){
const depArrayDom = depArray.map((item, index) => {
return <span><WWOpenDataCom type="departmentName" openid={item}/></span>
});
return depArrayDom;
};
return ( return (
<div className="search-user" style={{width:'300px'}} id="search-user"> <div className="search-user" style={{width:'300px'}} id="search-user">
<Search <Search
...@@ -49,13 +90,12 @@ function SearchUser(props) { ...@@ -49,13 +90,12 @@ function SearchUser(props) {
onFocus={(e)=>{onFocus(e)}} onFocus={(e)=>{onFocus(e)}}
onChange={(e)=>{onChange(e)}} onChange={(e)=>{onChange(e)}}
className="search-input-item" className="search-input-item"
// onBlur={()=>{onBlur()}}
/> />
{dropDownVisible && {dropDownVisible &&
<div className="drop-down"> <div className="drop-down">
<div className="drop-down__list"> <div className="drop-down__list">
{props.data.departmentUserVOList && {props.data.departmentUserVOList &&
<div> ( props.data.departmentUserVOList.length>0 && <div className="drop-down__item-user">
<div className="drop-down__item__title"> <div className="drop-down__item__title">
员工 员工
</div> </div>
...@@ -63,17 +103,19 @@ function SearchUser(props) { ...@@ -63,17 +103,19 @@ function SearchUser(props) {
<div> <div>
{props.data.departmentUserVOList.map((item,index)=>{ {props.data.departmentUserVOList.map((item,index)=>{
return <div> return <div>
<Checkbox onChange={(e)=>{selectuser(e,item)}} > <Checkbox onChange={(e)=>{selectuser(e,item)}} checked={_.pluck(props.selectList, 'userId').indexOf(item.userId)=== -1?false:true}>
<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> <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">
{item.depNamesList.map((_item,index)=>{ <Tooltip title={<div>{handleDepName(item.depNamesList)}</div>} placement='top' arrowPointAtCenter>
return <span> <WWOpenDataCom type="departmentName" openid={_item}/>{index<(item.depNamesList.length -1)?';':''}</span> {item.depNamesList.map((_item,index)=>{
}) return <span> <WWOpenDataCom type="departmentName" openid={_item}/>{index<(item.depNamesList.length -1)?';':''}</span>
} })
}
</Tooltip>
</div> </div>
</div> </div>
</Checkbox> </Checkbox>
...@@ -82,20 +124,24 @@ function SearchUser(props) { ...@@ -82,20 +124,24 @@ function SearchUser(props) {
} }
</div> </div>
</div> </div>
</div> </div>)
} }
{props.data.departmentVOList && {props.data.departmentVOList &&
<div> (props.data.departmentVOList.length>0 && <div>
<div className="drop-down__item__title"> <div className="drop-down__item__title drop-down__item__title-dep">
部门 部门
</div> </div>
<div className="drop-down__item__con"> <div className="drop-down__item__con">
<div> <div>
{props.data.departmentVOList.map((item,index)=>{ {props.data.departmentVOList.map((item,index)=>{
return <div><Checkbox onChange={(e)=>{selectDep(e,item)}}> return <div><Checkbox onChange={(e)=>{selectDep(e,item)}} checked={_.pluck(props.selectList, 'id').indexOf(item.id)=== -1?false:true}>
<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">
<WWOpenDataCom type="departmentName" openid={item.name}/> <Tooltip title={ <WWOpenDataCom type="departmentName" openid={item.name}/>}>
<span className="departmentName">
<WWOpenDataCom type="departmentName" openid={item.name}/>
</span>
</Tooltip>
</div> </div>
</div> </div>
</Checkbox> </Checkbox>
...@@ -104,10 +150,21 @@ function SearchUser(props) { ...@@ -104,10 +150,21 @@ function SearchUser(props) {
} }
</div> </div>
</div> </div>
</div> </div>)
} }
{(!props.data.departmentUserVOList && !props.data.departmentVOList)&& {(!props.data.departmentUserVOList && !props.data.departmentVOList)&&
<div>暂无数据</div> <div className="empty-con">
<img src="https://image.xiaomaiketang.com/xm/wRDrb2pJFb.png" className="empty-img"/>
<div className="empty-text">暂无数据</div>
</div>
}
{ (props.data.departmentUserVOList && props.data.departmentVOList) &&(
(props.data.departmentUserVOList.length === 0 && props.data.departmentVOList.length ===0) &&
<div className="empty-con">
<img src="https://image.xiaomaiketang.com/xm/wRDrb2pJFb.png" className="empty-img"/>
<div className="empty-text">暂无数据</div>
</div>
)
} }
</div> </div>
</div> </div>
......
...@@ -10,14 +10,38 @@ ...@@ -10,14 +10,38 @@
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; width:270px;
max-height:280px;
overflow-y: scroll;
// .drop-down__item-user{
// margin-bottom:30px;
// }
.drop-down__item__title{
font-size:14px;
color:#666;
margin-bottom:14px;
}
.ant-checkbox-wrapper{ .ant-checkbox-wrapper{
width:100%; width:100%;
.drop-down__item__con__item{ .drop-down__item__con__item{
margin-bottom:24px;
display:flex; display:flex;
width:220px; width:220px;
justify-content:space-between; justify-content:space-between;
color:#333; color:#333;
font-size:14px; font-size:14px;
.drop-down__item__con__item__left{
.title-icon{
color:#999;
margin-right:3px;
}
.departmentName{
display: inline-block;
max-width:190px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.drop-down__item__con__item__right{ .drop-down__item__con__item__right{
width:84px; width:84px;
text-align:right; text-align:right;
...@@ -28,5 +52,15 @@ ...@@ -28,5 +52,15 @@
} }
} }
} }
.empty-con{
text-align:center;
.empty-img{
width:150px;
height:150px;
}
.empty-text{
color:#666;
}
}
} }
} }
\ No newline at end of file
...@@ -328,10 +328,11 @@ class ChooseMembersModal extends React.Component { ...@@ -328,10 +328,11 @@ class ChooseMembersModal extends React.Component {
visible={isOpen} visible={isOpen}
onCancel={() => this.handleClose()} onCancel={() => this.handleClose()}
onOk={() => { onOk={() => {
if (User.getVersion() && User.getVersion().whetherReachUserNum) { //xmqxy446去除此优化
message.error("添加失败,企业使用人数超出限制") // if (User.getVersion() && User.getVersion().whetherReachUserNum) {
return // message.error("添加失败,企业使用人数超出限制")
} // return
// }
if (_.isEmpty(selectUserList)) { if (_.isEmpty(selectUserList)) {
message.warning(type === 'USER' ? '请选择员工' : '请选择学员') message.warning(type === 'USER' ? '请选择员工' : '请选择学员')
return null; return null;
......
...@@ -17,7 +17,7 @@ import { DepType } from "@/domains/store-domain/constants"; ...@@ -17,7 +17,7 @@ import { DepType } from "@/domains/store-domain/constants";
import StoreService from "@/domains/store-domain/storeService"; import StoreService from "@/domains/store-domain/storeService";
import SearchUser from "../components/SearchUser" import SearchUser from "../components/SearchUser"
import WWOpenDataCom from '@/components/WWOpenDataCom'; import WWOpenDataCom from '@/components/WWOpenDataCom';
import './ChooseMembersModal.less'; import './NewChooseMembersModal.less';
import _ from 'underscore'; import _ from 'underscore';
const { Search } = Input; const { Search } = Input;
...@@ -26,7 +26,8 @@ class NewChooseMembersModal extends React.Component { ...@@ -26,7 +26,8 @@ class NewChooseMembersModal extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
selectUserList:[], selectList:[], //所有的选中项
selectUserList:[], // 所有的选中的用户
selectObject: {}, selectObject: {},
openSetModal: false, openSetModal: false,
visible:this.props.visible, visible:this.props.visible,
...@@ -57,7 +58,7 @@ class NewChooseMembersModal extends React.Component { ...@@ -57,7 +58,7 @@ class NewChooseMembersModal extends React.Component {
<div className='avatar'> <div className='avatar'>
<span className="icon iconfont avatar-icon">&#xe84a;</span> <span className="icon iconfont avatar-icon">&#xe84a;</span>
<Tooltip title={<WWOpenDataCom type="userName" openid={userName}/>}> <Tooltip title={<WWOpenDataCom type="userName" openid={userName}/>}>
<span className='userImg'> <span className='userName'>
<WWOpenDataCom type="userName" openid={userName}/> <WWOpenDataCom type="userName" openid={userName}/>
{/* {userName} */} {/* {userName} */}
</span> </span>
...@@ -84,26 +85,41 @@ class NewChooseMembersModal extends React.Component { ...@@ -84,26 +85,41 @@ class NewChooseMembersModal extends React.Component {
} }
treeSelect = (record)=>{ treeSelect = (record)=>{
// console.log('record',record)
this.setState({ this.setState({
selectUserList:record selectList:record,
selectUserList:this.handleSelectUserList(record)
}) })
} }
clearOneUser = (record) =>{ // 将所有的选中项里的人员挑出来
console.log("record",record); handleSelectUserList =(list)=>{
const {selectUserList} = this.state; const _list = [];
const _selectUserList = selectUserList.filter((item,index)=>{ list.map((item,index)=>{
return item.userId !== record.userId if(item.userId){
_list.push(item);
}
}) })
console.log('selectUserList',selectUserList); return _list
}
clearOneUser = (record) =>{
const {selectUserList,selectList} = this.state;
const _selectList = [];
selectList.map((item,index)=>{
if(item.userId !== record.userId && item.id !==record.departmentId){
_selectList.push(item);
}
}); //字部门移除时将其对应的父部门也移除
console.log('_selectList',_selectList);
this.setState({ this.setState({
selectUserList:_selectUserList selectList:_selectList,
selectUserList:this.handleSelectUserList(_selectList)
}) })
} }
// 清空所有成员 // 清空所有成员
clearAllUser = () => { clearAllUser = () => {
this.setState({ this.setState({
selectList:[],
selectUserList : [], selectUserList : [],
}) })
} }
...@@ -119,9 +135,14 @@ class NewChooseMembersModal extends React.Component { ...@@ -119,9 +135,14 @@ class NewChooseMembersModal extends React.Component {
_item.departmentId = item.departmentId; _item.departmentId = item.departmentId;
_item.enterpriseVisibleUserId = item.userId; _item.enterpriseVisibleUserId = item.userId;
}else{ }else{
_item.depUserType = 'STORE_USER'; if(item.depId === '10000'){
_item.departmentId = this.props.selectDep.id; _item.depUserType = 'WE_CHART_USER'; // depid=10000代表是微信学员
_item.userId = item.userId;
}else{
_item.depUserType = 'STORE_USER';
}
_item.enterpriseVisibleUserId = item.enterpriseUserId; _item.enterpriseVisibleUserId = item.enterpriseUserId;
_item.departmentId = this.props.selectDep.id;
} }
return _item return _item
}) })
...@@ -132,6 +153,7 @@ class NewChooseMembersModal extends React.Component { ...@@ -132,6 +153,7 @@ class NewChooseMembersModal extends React.Component {
} }
Service.Hades('public/hades/addBatchUserAndDepartmentStoreCustomer', _params).then((res) => { Service.Hades('public/hades/addBatchUserAndDepartmentStoreCustomer', _params).then((res) => {
this.handleClose(); this.handleClose();
message.success('添加成功')
this.props.onConfirm(); this.props.onConfirm();
}) })
} }
...@@ -233,6 +255,12 @@ class NewChooseMembersModal extends React.Component { ...@@ -233,6 +255,12 @@ class NewChooseMembersModal extends React.Component {
userId:User.getUserId(), userId:User.getUserId(),
whetherCount:false whetherCount:false
} }
if(this.props.addDepType){
params.nowDepType = this.props.addDepType;
}
if(this.props.selectDep){
params.departmentId = this.props.selectDep.id;
}
StoreService.getDepartmentUser(params).then((res) => { StoreService.getDepartmentUser(params).then((res) => {
const { result = {}} = res; const { result = {}} = res;
this.setState({ this.setState({
...@@ -242,39 +270,23 @@ class NewChooseMembersModal extends React.Component { ...@@ -242,39 +270,23 @@ class NewChooseMembersModal extends React.Component {
} }
confirmSearchSelect=(record,type)=>{ confirmSearchSelect=(record,type)=>{
const { selectUserList } = this.state; const { selectUserList,selectList} = this.state;
if(type==='user'){ this.setState({selectList:record,selectUserList:this.handleSelectUserList(record)});
this.setState({selectUserList:[...selectUserList,...record]}); // if(type==='user'){
}else{ // this.setState({selectList:[...record],selectUserList:this.handleSelectUserList(record)});
let _list = [];
if(record.departmentUserVOList){
_list = record.departmentUserVOList;
}
console.log('_list',_list);
this.setState({selectUserList:[...selectUserList,..._list]},()=>{
console.log('selectUserList',this.state.selectUserList);
});
}
// }else{ // }else{
// const params = { // let _userList = [];
// depType:this.props.treeDepType, // if(record.departmentUserVOList){
// enterpriseId: User.getEnterpriseId(), // _userList = record.departmentUserVOList;
// source: 0,
// storeId: User.getStoreId(),
// userId: User.getUserId(),
// departmentId:record.id
// } // }
// StoreService.getStoreCustomerAndDepNamePage(params).then((res) => { // this.setState({selectList:[...selectList,..._userList],selectUserList:[...selectUserList,..._userList]});
// const { records = []} = res.result; // }
// this.setState({selectUserList:[...selectUserList,...records]});
// });
// }
} }
render() { render() {
const {type,treeDepType,selectDep={},addDepType=''} = this.props; const {type,treeDepType,selectDep={},addDepType=''} = this.props;
const { id=''} = selectDep; const { id=''} = selectDep;
const {selectUserList,selectObject,visible,openSetModal,searchUserResultList} = this.state; const {selectUserList,selectObject,visible,openSetModal,searchUserResultList,selectList} = this.state;
const title = type === 'USER' ? '添加员工' : '添加学员'; const title = type === 'USER' ? '添加员工' : '添加学员';
return ( return (
<div> <div>
...@@ -284,10 +296,11 @@ class NewChooseMembersModal extends React.Component { ...@@ -284,10 +296,11 @@ class NewChooseMembersModal extends React.Component {
visible={visible} visible={visible}
onCancel={() => this.handleClose()} onCancel={() => this.handleClose()}
onOk={() => { onOk={() => {
if (User.getVersion() && User.getVersion().whetherReachUserNum) { //xmqxy446去除此优化
message.error("添加失败,企业使用人数超出限制") // if (User.getVersion() && User.getVersion().whetherReachUserNum) {
return // message.error("添加失败,企业使用人数超出限制")
} // return
// }
if (_.isEmpty(selectUserList)) { if (_.isEmpty(selectUserList)) {
message.warning(type === 'USER' ? '请选择员工' : '请选择学员') message.warning(type === 'USER' ? '请选择员工' : '请选择学员')
return null; return null;
...@@ -303,15 +316,9 @@ class NewChooseMembersModal extends React.Component { ...@@ -303,15 +316,9 @@ class NewChooseMembersModal extends React.Component {
<div className='member-container'> <div className='member-container'>
<div className='container-left'> <div className='container-left'>
<div className='container-left-body'> <div className='container-left-body'>
{/* <Search <SearchUser onChange={(value)=>{this.getCompleteOptionData(value)}} data={searchUserResultList} onSelect={(record,type)=>{this.confirmSearchSelect(record,type)}} selectUserList={selectUserList} selectList={selectList}/>
placeholder='搜索成员'
className='search search-input'
enterButton={<span className="icon iconfont">&#xe832;</span>}
/> */}
{/* {this.Complete()} */}
<SearchUser onChange={(value)=>{this.getCompleteOptionData(value)}} data={searchUserResultList} onSelect={(record,type)=>{this.confirmSearchSelect(record,type)}}/>
<div className='container-left-body-table'> <div className='container-left-body-table'>
<MemberTree departmentId={id} treeDepType={treeDepType} nowTreeDepType={addDepType} onSelect={(record)=>{this.treeSelect(record)}} selectUserList={selectUserList} type={type}/> <MemberTree departmentId={id} treeDepType={treeDepType} nowTreeDepType={addDepType} onSelect={(record)=>{this.treeSelect(record)}} selectUserList={selectUserList} type={type} selectList={selectList}/>
</div> </div>
</div> </div>
</div> </div>
......
.choose-member-modal {
.member-container{
display: flex;
height: 417px;
.container-left{
width: 50%;
padding-right: 10px;
margin-left: 10px;
.container-left-header{
margin-bottom: 12px;
}
.container-left-body{
border: 1px solid #E9E9E9;
height: 100%;
.ant-table-thead > tr > th {
font-weight:400!important;
}
.search{
width: 305px;
padding: 7px 7px;
}
.container-left-body-table{
width: 300px;
max-height: 360px;
overflow: scroll;
.ant-table {
border: none;
min-height: 250px !important;
.ant-table-header{
margin-bottom: -7px !important;
>table > .ant-table-thead > tr > th {
background-color: #fff !important;
}
}
.ant-table-tbody{
>tr {
>td {
border-bottom: none;
background-color: #fff !important;
padding: 11px 0!important;
}
&:hover {
>td {
background: #F3F6FA !important;
}
}
}
}
}
.ant-empty-normal {
margin: 80px 0 !important;
}
.avatar{
display: flex;
align-items: center;
.avatar-icon {
font-size:14px;
color:#999;
margin-right: 6px;
}
.userName {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size:14px;
color:#333;
}
}
}
}
}
.container-right{
width: 50%;
border: 1px solid #E9E9E9;
.span-left{
line-height: 45px;
margin-left: 10px;
.span-left-l{
color: #2966FF;
cursor: pointer;
}
}
.span-right{
line-height: 45px;
float: right;
margin-right: 10px;
color: #999;
.span-right-l{
color: #2966FF;
cursor: pointer;
}
}
.container-right-body{
min-height:376px;
border-top: 1px solid #e8e8e8;
.edit {
.edit-icon {
color:#999;
font-size:14px;
}
}
.edit-img{
width: 16px;
height: 16px;
}
.ant-table .ant-table-body {
overflow: auto;
max-height: 376px!important;
}
.ant-table tbody {
tr{
background: #fff;
&:first-child {
display: block;
overflow: hidden;
}
td{
padding:12px 18px !important;
}
}
}
.ant-empty-normal {
margin: 120px 0 !important;
}
.ant-empty {
margin-top: 76px;
}
.avatar{
display: flex;
align-items: center;
.avatar-icon {
font-size:14px;
color:#999;
margin-right: 6px;
}
.userName {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size:14px;
color:#333;
}
}
.ant-table-tbody{
>tr >td {
border-bottom:none;
}
>tr .ant-table-selection-column{
width: 30px !important;
}
}
}
}
}
}
\ No newline at end of file
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
flex-shrink: 0; flex-shrink: 0;
} }
&.selected { &.selected {
background: rgba(255, 183, 20, 0.1); background:rgba(41, 102, 255,0.1);
&::after { &::after {
content: ''; content: '';
position: absolute; position: absolute;
......
...@@ -42,6 +42,7 @@ function CourseCatalogSelect(props) { ...@@ -42,6 +42,7 @@ function CourseCatalogSelect(props) {
return ( return (
<TreeSelect <TreeSelect
className={props.className}
treeNodeLabelProp='categoryName' treeNodeLabelProp='categoryName'
showSearch={showSearch} showSearch={showSearch}
treeNodeFilterProp={treeNodeFilterProp} treeNodeFilterProp={treeNodeFilterProp}
......
...@@ -374,6 +374,7 @@ class AddLive extends React.Component { ...@@ -374,6 +374,7 @@ class AddLive extends React.Component {
CourseService.createLiveCloudCourse(params).then((res) => { CourseService.createLiveCloudCourse(params).then((res) => {
if (res.success) { if (res.success) {
message.success('新建成功'); message.success('新建成功');
routeHook.cancel()
window.RCHistory.push({ window.RCHistory.push({
pathname: `/live-course`, pathname: `/live-course`,
}); });
...@@ -389,6 +390,7 @@ class AddLive extends React.Component { ...@@ -389,6 +390,7 @@ class AddLive extends React.Component {
CourseService.updateLiveCloudCourse(params).then((res) => { CourseService.updateLiveCloudCourse(params).then((res) => {
if (res.success) { if (res.success) {
message.success('更新成功'); message.success('更新成功');
routeHook.cancel()
window.RCHistory.push({ window.RCHistory.push({
pathname: `/live-course`, pathname: `/live-course`,
}); });
......
...@@ -212,9 +212,10 @@ class DataList extends React.Component { ...@@ -212,9 +212,10 @@ class DataList extends React.Component {
<Tooltip <Tooltip
title={()=> { title={()=> {
return <div> return <div>
<div>学员-已加入当前学院的企业员工</div> <div>学员:已加入当前学院的企业员工</div>
<div>待加入-未加入当前学院的企业员工</div> <div>待加入:未加入当前学院的企业员工</div>
<div>游客-非企业员工</div> <div>游客:非企业员工</div>
<div>*企业员工以企业微信通讯录为准</div>
</div> </div>
}}> }}>
<i className='icon iconfont' style={{fontSize:"14px",fontWeight:"400"}}> &#xe61d;</i> <i className='icon iconfont' style={{fontSize:"14px",fontWeight:"400"}}> &#xe61d;</i>
...@@ -237,8 +238,6 @@ class DataList extends React.Component { ...@@ -237,8 +238,6 @@ class DataList extends React.Component {
{ {
title: '累计在线时长', title: '累计在线时长',
dataIndex: 'totalDuration', dataIndex: 'totalDuration',
sorter: (a, b) => a.totalDuration - b.totalDuration,
sortDirections: ['descend', 'ascend'],
render: (text, record) => { render: (text, record) => {
//如无离开时间,就置空 //如无离开时间,就置空
return <span>{text ? dealTimeDuration(text) : '00:00:00'}</span>; return <span>{text ? dealTimeDuration(text) : '00:00:00'}</span>;
...@@ -252,21 +251,40 @@ class DataList extends React.Component { ...@@ -252,21 +251,40 @@ class DataList extends React.Component {
handleExportV5 = () => { handleExportV5 = () => {
const { liveCourseId, storeId } = this.state; const { liveCourseId, storeId } = this.state;
CourseService.exportStudentCourseData({ if (this.state.type === "qiwei") {
liveCourseId: liveCourseId, CourseService.exportWorkWXStudentCourseData({
exportLiveType: 'VISITOR', liveCourseId: liveCourseId,
storeId, exportLiveType: 'VISITOR',
}).then((res) => { storeId,
const link = res.result; }).then((res) => {
this.setState({ const link = res.result;
link, this.setState({
link,
});
document.getElementById('loadExcel').click();
if (res.success) {
message.success('导出成功!');
}
}); });
document.getElementById('loadExcel').click(); } else {
CourseService.exportStudentCourseData({
liveCourseId: liveCourseId,
exportLiveType: 'VISITOR',
storeId,
}).then((res) => {
const link = res.result;
this.setState({
link,
});
document.getElementById('loadExcel').click();
if (res.success) {
message.success('导出成功!');
}
});
}
if (res.success) {
message.success('导出成功!');
}
});
}; };
handleCheckEnterTimes = () => { handleCheckEnterTimes = () => {
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
.title { .title {
font-size: 16px; font-size: 16px;
font-family: PingFangSC-Medium, PingFang SC; font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500; font-weight: 600;
color: #333333; color: #333333;
margin-bottom: 16px; margin-bottom: 16px;
position: relative; position: relative;
...@@ -84,6 +84,7 @@ ...@@ -84,6 +84,7 @@
background: #ffffff; background: #ffffff;
border: 1px solid #e8e8e8; border: 1px solid #e8e8e8;
display: flex; display: flex;
justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 32px; margin-bottom: 32px;
.item-block { .item-block {
......
...@@ -28,7 +28,8 @@ class AddLiveBasic extends React.Component { ...@@ -28,7 +28,8 @@ class AddLiveBasic extends React.Component {
showSelectFileModal: false, showSelectFileModal: false,
cutImageBlob: null, cutImageBlob: null,
hasImgReady: false, // 图片是否上传成功 hasImgReady: false, // 图片是否上传成功
cropperInstace: null, cropperInstace:null,
courseNameLimit: props.courseNameLimit?props.courseNameLimit:40
} }
} }
componentWillUnmount() {} componentWillUnmount() {}
...@@ -105,15 +106,18 @@ class AddLiveBasic extends React.Component { ...@@ -105,15 +106,18 @@ class AddLiveBasic extends React.Component {
<span className='label'> <span className='label'>
<span className='require'>*</span>课程名称: <span className='require'>*</span>课程名称:
</span> </span>
<div id="courseName" style={{display:"inline-block"}}>
<Input <Input
className={_.find(this.props.exItems,(item)=>{return item === "courseName"})?"err":""}
value={courseName} value={courseName}
placeholder='请输入直播名称(40字以内)' placeholder={`请输入直播名称(${this.state.courseNameLimit}字以内)`}
maxLength={40} maxLength={this.state.courseNameLimit}
style={{ width: 240 }} style={{ width: 240 }}
onChange={(e) => { onChange={(e) => {
this.props.onChange('courseName', e.target.value) this.props.onChange('courseName', e.target.value)
}} }}
/> />
</div>
</div> </div>
<div className='course-cover'> <div className='course-cover'>
<span className='label'>封面图:</span> <span className='label'>封面图:</span>
...@@ -144,12 +148,15 @@ class AddLiveBasic extends React.Component { ...@@ -144,12 +148,15 @@ class AddLiveBasic extends React.Component {
<span className='label'> <span className='label'>
<span className='require'>*</span>课程分类: <span className='require'>*</span>课程分类:
</span> </span>
<div id="categoryId" style={{display:"inline-block"}}>
<CourseCatalogSelect <CourseCatalogSelect
className={_.find(this.props.exItems,(item)=>{return item === "categoryId"})?"err":""}
value={categoryId} value={categoryId}
onChange={(value, label) => { onChange={(value, label) => {
this.handleChangeCatalogList(value, label) this.handleChangeCatalogList(value, label)
}} }}
/> />
</div>
</div> </div>
{showSelectFileModal && ( {showSelectFileModal && (
<SelectPrepareFileModal <SelectPrepareFileModal
......
...@@ -66,6 +66,30 @@ ...@@ -66,6 +66,30 @@
.course-catalog { .course-catalog {
margin: 20px 0 0 14px; margin: 20px 0 0 14px;
} }
//输入框异常项
.err.ant-input:hover {
border-color: #FF4F4F;
}
.err.ant-input:focus {
border-color: #FF4F4F !important;
box-shadow: 0 0 0 2px rgba(255,0,0,0.2);
}
.err.ant-input {
border-color: #FF4F4F;
}
//下拉选择异常项
.err.ant-select-focused:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input) .ant-select-selector {
border-color: #FF4F4F;
box-shadow: 0 0 0 2px rgba(255,0,0,0.2);
}
.err.ant-select:not(.ant-select-disabled):hover {
.ant-select-selector {
border-color: #FF4F4F;
}
}
.err.ant-select:not(.ant-select-customize-input) .ant-select-selector {
border-color: #FF4F4F;
}
} }
.ant-cascader-menu-item-active:not(.ant-cascader-menu-item-disabled) { .ant-cascader-menu-item-active:not(.ant-cascader-menu-item-disabled) {
font-weight: normal !important; font-weight: normal !important;
......
.AddLiveClassInfoWorkWX { .AddLiveClassInfoWorkWX {
margin-left: 16px; margin-left: 16px;
margin-bottom: 98px;
.remind-time {
.ant-select-single.ant-select-show-arrow .ant-select-selection-placeholder {
color: #333333;
}
}
.item { .item {
margin: 24px 0; margin: 24px 0;
.label { .label {
...@@ -10,8 +17,61 @@ ...@@ -10,8 +17,61 @@
color: red; color: red;
} }
} }
//日期时间选择异常项
.err.ant-picker-focused {
border-color: #FF4F4F;
box-shadow: 0 0 0 2px rgba(255,0,0,0.2);
}
.err.ant-picker:hover {
border-color: #FF4F4F;
}
.err.ant-picker {
border-color: #FF4F4F;
}
} }
.introduce { .introduce {
display: flex; display: flex;
} }
.ant-select-item-option-selected:not(.ant-select-item-option-disabled) {
color: #2966FF;
}
// .eerr .ant-select-focused:not(.ant-select-disabled) .ant-select:not(.ant-select-customize-input) {
// .ant-select-selector {
// border-color: red;
// box-shadow: 0 0 0 2px rgba(255,0,0,0.2);
// }
// }
// .eerr .ant-select:not(.ant-select-disabled):hover {
// .ant-select-selector {
// border-color: red;
// }
// }
//下拉选择异常项
.err.ant-select-focused:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input) .ant-select-selector {
border-color: #FF4F4F;
box-shadow: 0 0 0 2px rgba(255,0,0,0.2);
}
.err.ant-select:not(.ant-select-disabled):hover {
.ant-select-selector {
border-color: #FF4F4F;
}
}
.err.ant-select:not(.ant-select-customize-input) .ant-select-selector {
border-color: #FF4F4F;
}
//输入框异常项
.err.ant-input:hover {
border-color: #FF4F4F;
}
.err.ant-input:focus {
border-color: #FF4F4F;
box-shadow: 0 0 0 2px rgba(255,0,0,0.2);
}
.err.ant-input {
border-color: #FF4F4F;
}
} }
\ No newline at end of file
import React, { useState, useRef, useEffect, useContext } from 'react'
import { Route, withRouter } from 'react-router-dom';
import Breadcrumbs from "@/components/Breadcrumbs";
import moment from 'moment'
import { LIVE_SHARE } from "@/domains/course-domain/constants";
import { Form, Alert, Input, Button, InputNumber, DatePicker, Select, Radio, message, Modal } from 'antd';
import Service from "@/common/js/service";
import User from "@/common/js/user";
import qrcode from "@/libs/qrcode/qrcode.js";
declare var wx: any;
const { Option } = Select;
const courseType = {
0: '通用直播',
1: '小班课',
2: '大班课',
3: '企业培训',
4: '活动直播'
}
function CerateQWCourse(props: any) {
const [courseName, setCourseName] = useState('');
const [liveDuration, setLiveDuration] = useState(60);
const [liveStart, setLiveStart] = useState(0);
const [type, setType] = useState('0');
const [livingId, setLivingId] = useState(0);
function handleSave() {
const param = {
courseName,
description: '直播的简介,最多支持300个字节直播的简介,最多支持300个字节直播的简介,最多支持300个字节直播的简介,最多支持300个字节直播的简介,最多支持300个字节直播的简介,最多支持300个字节',
liveDuration: liveDuration * 60 * 100,
liveStart,
remindTime: 1000 * 60 * 10,
storeId: User.getStoreId(),
storeUserId: User.getStoreUserId(),
type: parseInt(type)
}
Service.Hades('anon/hades/wxWorkCreateLiveDemo', param).then((res) => {
console.log(22)
handleConvertShortUrl(res.result)
setLivingId(res.result)
wx.invoke('startLiving', {
"livingId": res.result,
}, function (res: any) {
console.log(122, res)
if (res.err_msg == "startLiving:ok") {
// livingId = res.livingId;
}
});
})
}
function handleConvertShortUrl(id: any) {
const longUrl = `${LIVE_SHARE}qw/live/${id}?id=${User.getStoreId()}`
console.log(longUrl)
// 发请求
Service.Sales('public/businessShow/convertShortUrls', {
urls: [longUrl]
}).then((res) => {
const { result = [] } = res;
const qrcodeWrapDom: any = document.querySelector('.qrcode');
qrcodeWrapDom.innerHTML = ''
const qrcodeNode = new qrcode({
text: result[0].shortUrl,
size: 100,
});
(qrcodeWrapDom as any).appendChild(qrcodeNode);
})
}
function downloadLivingReplay(){
wx.invoke('downloadLivingReplay', {
livingId
}, function(res:any) {
console.log(res,'tyuuioythbn')
if (res.err_msg != "downloadLivingReplay:ok") {
// 错误处理
}
});
}
return <div className="page createQWCourse ">
<Breadcrumbs navList={props.type === 'edit' ? "编辑考试" : "新建直播课"} goBack={props.history.goBack} />
<div className="box">
<div className="form">
<div className="title">直播信息</div>
<Form
labelCol={{ span: 3 }}
wrapperCol={{ span: 14 }}
layout="horizontal"
>
<Form.Item label="课程名称"
required>
<Input value={courseName} onChange={(e) => { setCourseName(e.target.value) }} style={{ width: 200 }} ></Input>
</Form.Item>
<Form.Item label="持续时长"
required>
<InputNumber value={liveDuration} max={1440} min={1} onChange={(value: any) => { setLiveDuration(parseInt(value) as any) }} style={{ width: 100 }} />
</Form.Item>
<Form.Item label="开始时间"
required>
<DatePicker
format="YYYY/MM/DD HH:mm"
value={liveStart ? moment(Number(liveStart)) : null}
style={{ width: 200 }}
placeholder="开始时间"
showTime
onChange={(date: any) => { setLiveStart(date ? date.valueOf() : 0) }}
/>
</Form.Item>
<Form.Item label="直播的类型"
required>
<Select value={type} placeholder="请选直播的类型" style={{ width: 200 }} onChange={(val) => {
setType(val)
}} >
{
Object.keys(courseType).map((key: any) => {
return <Option value={key}>{(courseType as any)[key]}</Option>
})
}
</Select>
</Form.Item>
</Form>
</div>
</div>
<div style={{marginTop:100}} className="qrBox">
<div style={{width:100,margin:'0 auto'}} className="qrcode"></div>
</div>
<div className="footer">
<Button onClick={downloadLivingReplay}>下载直播回放</Button>
<Button onClick={props.history.goBack}>取消</Button>
<Button type="primary" onClick={handleSave}>保存</Button>
</div>
</div>
}
export default withRouter(CerateQWCourse);
\ No newline at end of file
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
color: #333; color: #333;
font-weight: 500; font-weight: 500;
line-height: 22px; line-height: 22px;
margin-bottom:8px; margin-bottom:25px;
} }
.add-live__class-info { .add-live__class-info {
margin-left: 14px; margin-left: 14px;
......
...@@ -14,6 +14,7 @@ import moment from 'moment' ...@@ -14,6 +14,7 @@ import moment from 'moment'
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 './LiveCourseFilter.less' import './LiveCourseFilter.less'
import { brandLiveName } from '@/domains/brand/constants'
const { Search } = Input const { Search } = Input
const { Option } = Select const { Option } = Select
...@@ -51,6 +52,7 @@ class LiveCourseFilter extends React.Component { ...@@ -51,6 +52,7 @@ class LiveCourseFilter extends React.Component {
current, current,
size: 10, size: 10,
} }
StoreService.getStoreUserBasicPage(_query).then((res) => { StoreService.getStoreUserBasicPage(_query).then((res) => {
const { result = {} } = res const { result = {} } = res
const { records = [], total = 0, hasNext } = result const { records = [], total = 0, hasNext } = result
...@@ -324,7 +326,7 @@ class LiveCourseFilter extends React.Component { ...@@ -324,7 +326,7 @@ class LiveCourseFilter extends React.Component {
</span> </span>
}> }>
<Option value='WECHAT'>企微直播</Option> <Option value='WECHAT'>企微直播</Option>
<Option value='TENCENT'>小麦直播</Option> <Option value='TENCENT'>{brandLiveName}</Option>
</Select> </Select>
</div> </div>
)} )}
......
...@@ -63,22 +63,24 @@ class LiveCourseOpt extends React.Component { ...@@ -63,22 +63,24 @@ class LiveCourseOpt extends React.Component {
// 下载直播客户端 // 下载直播客户端
handleDownloadClient = () => { handleDownloadClient = () => {
const { isMac } = this.state; const { isMac } = this.state;
const BRAND = process.env.BRAND;
// 判断学员系统 // 判断学员系统
let platform; let platform;
if(!isMac){ if (!isMac) {
platform = 1 platform = 1
} else { } else {
platform = 4 platform = 4
} }
BaseService BaseService
.getLastedVersion({ model: 5, platform}) .getLastedVersion({ model: 5, platform })
.then((res) => { .then((res) => {
const a = document.createElement("a"); const a = document.createElement("a");
document.body.appendChild(a); document.body.appendChild(a);
a.href = res.result.releaseUrl; a.href = res.result.releaseUrl;
a.click(); a.click();
document.body.removeChild(a); document.body.removeChild(a);
}) })
} }
render() { render() {
const userRole = User.getUserRole(); const userRole = User.getUserRole();
...@@ -87,7 +89,7 @@ class LiveCourseOpt extends React.Component { ...@@ -87,7 +89,7 @@ class LiveCourseOpt extends React.Component {
<div className="live-course-opt"> <div className="live-course-opt">
<LiveModeSelect onClose={this.onModeSelectClose} onSelected={this.onModeSelected} isShow={this.state.showModeSelect}/> <LiveModeSelect onClose={this.onModeSelectClose} onSelected={this.onModeSelected} isShow={this.state.showModeSelect}/>
<div className="opt__left"> <div className="opt__left">
{ userRole !== "CloudLecturer" && {userRole !== "CloudLecturer" &&
<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> */}
......
import React, { useState } from "react"; import React, { useState } from "react";
import "./LiveModeSelect.less" import "./LiveModeSelect.less"
import { createPortal } from "react-dom"; import { createPortal } from "react-dom";
import { brandLiveName } from "@/domains/brand/constants";
interface LiveModeSelectProps { interface LiveModeSelectProps {
isShow: boolean; isShow: boolean;
...@@ -32,14 +33,14 @@ export default function LiveModeSelect(props: LiveModeSelectProps) { ...@@ -32,14 +33,14 @@ export default function LiveModeSelect(props: LiveModeSelectProps) {
<div className="content"> <div className="content">
<div className="item xiaomai-logo"> <div className="item xiaomai-logo">
<div className="logo"></div> <div className="logo"></div>
<div className="item-title">小麦直播</div> <div className="item-title">{brandLiveName}</div>
<div className="des">通过小麦企学院“PC客户<br/>端”进行直播</div> <div className="des">通过{window.brandName}“PC客户<br/>端”进行直播</div>
<div className="button" onClick={handleSelect0}>立即创建</div> <div className="button" onClick={handleSelect0}>立即创建</div>
</div> </div>
<div className="item qiwei-logo"> <div className="item qiwei-logo">
<div className="logo qiwei-logo"></div> <div className="logo qiwei-logo"></div>
<div className="item-title">企微直播</div> <div className="item-title">企微直播</div>
<div className="des">通过“企业微信APP”进行<br/>直播进行直播</div> <div className="des">通过“企业微信APP”<br/>进行直播</div>
<div className="button" onClick={handleSelect1}>立即创建</div> <div className="button" onClick={handleSelect1}>立即创建</div>
</div> </div>
</div> </div>
......
...@@ -107,47 +107,56 @@ class PreviewCourseModal extends React.Component { ...@@ -107,47 +107,56 @@ class PreviewCourseModal extends React.Component {
timeHorizonStart, timeHorizonStart,
timeHorizonEnd, timeHorizonEnd,
teacherName, teacherName,
duration
} = courseClassInfo; } = courseClassInfo;
const { introduce, categoryName } = courseIntroInfo; const { introduce, categoryName } = courseIntroInfo;
let { activeTab } = this.state; let { activeTab } = this.state;
let liveDateStr, startTimeStr, endTimeStr; let liveDateStr, startTimeStr, endTimeStr;
if (type === "add") { if (this.props.bizType === "qiwei") {
const _liveDate = moment(calendarTime[0]).format("YYYY-MM-DD"); let _startTime = startTime === 0 ? moment().valueOf():startTime
console.log("_liveDate", _liveDate); startTimeStr = moment(_startTime).format("YYYY-MM-DD HH:mm")
const _timeHorizonStart = moment(startTime).format("HH:mm"); endTimeStr = moment(endTime === 0?moment(_startTime+Number(duration)*1000).valueOf():endTime).format("HH:mm")
const _timeHorizonEnd = moment(endTime).format("HH:mm"); console.log(duration)
const _startTime = moment(_liveDate + " " + _timeHorizonStart).format(
"x"
);
const _endTime = moment(_liveDate + " " + _timeHorizonEnd).format("x");
const {
liveDateStr: _liveDateStr,
startTimeStr: _startTimeStr,
endTimeStr: _endTimeStr,
} = this.dealWithTime(_startTime, _endTime);
liveDateStr = _liveDateStr;
startTimeStr = _startTimeStr;
endTimeStr = _endTimeStr;
} else { } else {
const _liveDate = moment(liveDate).format("YYYY-MM-DD"); if (type === "add") {
const _timeHorizonStart = moment(timeHorizonStart).format("HH:mm"); const _liveDate = moment(calendarTime[0]).format("YYYY-MM-DD");
const _timeHorizonEnd = moment(timeHorizonEnd).format("HH:mm"); console.log("_liveDate", _liveDate);
const startTime = moment(_liveDate + " " + _timeHorizonStart).format("x"); const _timeHorizonStart = moment(startTime).format("HH:mm");
const endTime = moment(_liveDate + " " + _timeHorizonEnd).format("x"); const _timeHorizonEnd = moment(endTime).format("HH:mm");
const { const _startTime = moment(_liveDate + " " + _timeHorizonStart).format(
liveDateStr: _liveDateStr, "x"
startTimeStr: _startTimeStr, );
endTimeStr: _endTimeStr, const _endTime = moment(_liveDate + " " + _timeHorizonEnd).format("x");
} = this.dealWithTime(startTime, endTime); const {
liveDateStr: _liveDateStr,
liveDateStr = _liveDateStr; startTimeStr: _startTimeStr,
startTimeStr = _startTimeStr; endTimeStr: _endTimeStr,
endTimeStr = _endTimeStr; } = this.dealWithTime(_startTime, _endTime);
liveDateStr = _liveDateStr;
startTimeStr = _startTimeStr;
endTimeStr = _endTimeStr;
} 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");
const {
liveDateStr: _liveDateStr,
startTimeStr: _startTimeStr,
endTimeStr: _endTimeStr,
} = this.dealWithTime(startTime, endTime);
liveDateStr = _liveDateStr;
startTimeStr = _startTimeStr;
endTimeStr = _endTimeStr;
}
} }
return ( return (
<Modal <Modal
title="预览" title="预览"
......
...@@ -60,10 +60,12 @@ ...@@ -60,10 +60,12 @@
.title__state { .title__state {
min-width: 40px; min-width: 40px;
height: 17px; height: 17px;
padding: 0px 8px; padding-left: 8px;
padding-right: 8px;
border-radius: 10px; border-radius: 10px;
margin-left: 6px; margin-left: 6px;
font-size: 12px; font-size: 12px;
line-height: 17px;
color: #FFF; color: #FFF;
background-color: #34B88B; background-color: #34B88B;
} }
......
...@@ -102,7 +102,7 @@ class ShareLiveModal extends React.Component { ...@@ -102,7 +102,7 @@ class ShareLiveModal extends React.Component {
render() { render() {
const { courseDivision, data, type, title } = this.props; const { courseDivision, data, type, title } = this.props;
const { courseName, scheduleVideoUrl, courseMediaVOS, coverUrl } = data; const { courseName, scheduleVideoUrl, courseMediaVOS, coverUrl, thirdPartType } = data;
const { shareUrl, showImg, time } = this.state; const { shareUrl, showImg, time } = this.state;
// 判断是否是默认图, 默认图不需要在URL后面增加字符串 // 判断是否是默认图, 默认图不需要在URL后面增加字符串
let coverImgSrc = ''; let coverImgSrc = '';
...@@ -188,8 +188,8 @@ class ShareLiveModal extends React.Component { ...@@ -188,8 +188,8 @@ class ShareLiveModal extends React.Component {
<div className='right'> <div className='right'>
<div className='share-poster right__item'> <div className='share-poster right__item'>
<div className='title'>① 海报分享</div> <div className='title'>① 海报分享</div>
{type === 'liveClass' && <div className='sub-title'>学员可通过微信扫描海报二维码,观看{title}</div>} {type === 'liveClass' && <div className='sub-title'>学员可通过微信{thirdPartType === "WECHAT"?"/企业微信":""}扫描海报二维码,观看{title}</div>}
{type === 'videoClass' && <div className='sub-title'>学员可通过微信识别二维码,报名观看{title}</div>} {type === 'videoClass' && <div className='sub-title'>学员可通过微信{thirdPartType === "WECHAT"?"/企业微信":""}识别二维码,报名观看{title}</div>}
<div className='content' onClick={_.debounce(this.handleDownloadPoster, 1000, true)}> <div className='content' onClick={_.debounce(this.handleDownloadPoster, 1000, true)}>
下载海报 下载海报
...@@ -198,7 +198,7 @@ class ShareLiveModal extends React.Component { ...@@ -198,7 +198,7 @@ class ShareLiveModal extends React.Component {
<div className='share-url right__item'> <div className='share-url right__item'>
<div className='title'>② 链接分享</div> <div className='title'>② 链接分享</div>
{type === 'liveClass' && <div className='sub-title'>学员可通过微信打开以下链接,观看{title}</div>} {type === 'liveClass' && <div className='sub-title'>学员可通过微信{thirdPartType === "WECHAT"?"/企业微信":""}打开以下链接,观看{title}</div>}
{type === 'videoClass' && <div className='sub-title'>学员可通过打开链接,报名观看{title}</div>} {type === 'videoClass' && <div className='sub-title'>学员可通过打开链接,报名观看{title}</div>}
<div className='content url-content'> <div className='content url-content'>
<div className='share-url' id='shareUrl'> <div className='share-url' id='shareUrl'>
......
...@@ -363,15 +363,15 @@ class AddVideoCourse extends React.Component { ...@@ -363,15 +363,15 @@ class AddVideoCourse extends React.Component {
// 保存 // 保存
handleSubmit = () => { handleSubmit = () => {
//过期判断 //过期判断
if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) { if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) {
Modal.warning({ Modal.warning({
title: '服务已到期', title:"服务已到期",
content: '当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买', content:`当前企业购买的${window.brandName}服务已到期,如需继续使用学院功能,请尽快续费购买`,
okText: '我知道了', okText: "我知道了"
}); })
return; return
} }
const { const {
id, id,
......
...@@ -61,8 +61,8 @@ function PlanFilter(props) { ...@@ -61,8 +61,8 @@ function PlanFilter(props) {
delete _query.startTime; delete _query.startTime;
delete _query.endTime; delete _query.endTime;
} else { } else {
_query.startTime = dates[0].valueOf(); _query.startTime = dates[0]?.startOf('day').valueOf()
_query.endTime = dates[1].valueOf(); _query.endTime = dates[1]?.endOf('day').valueOf()
} }
const param ={ const param ={
..._query, ..._query,
......
...@@ -16,10 +16,10 @@ import User from '@/common/js/user'; ...@@ -16,10 +16,10 @@ 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 { VersionContext, VersionInfo, XMContext } from '@/store/context'; import { VersionContext, VersionInfo, XMContext } from '@/store/context';
import WechatApi from '@/common/js/wechatApi';
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;
......
...@@ -87,9 +87,9 @@ function ExpirationPopover(props) { ...@@ -87,9 +87,9 @@ function ExpirationPopover(props) {
<div className="title">{props.surplusDayTime === 0 ? "服务已到期" : "服务到期提醒"}</div> <div className="title">{props.surplusDayTime === 0 ? "服务已到期" : "服务到期提醒"}</div>
{ {
showType === 3 ? ( showType === 3 ? (
<div className="tip-text">当前企业购买的小麦企学院服务已于<span style={{ color: "#FF4F4F" }}>{moment(props.endTime).format("YYYY-MM-DD HH:mm:ss")}</span>到期,到期后仍可访问,但功能不可使用,建议尽快续费购买哦~</div> <div className="tip-text">当前企业购买的{`${window.brandName}`}服务已于<span style={{ color: "#FF4F4F" }}>{moment(props.endTime).format("YYYY-MM-DD HH:mm:ss")}</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="tip-text">当前企业购买的{`${window.brandName}`}服务 <span style={{ color: "#FF4F4F" }}>仅剩{props.surplusDayTime}</span>(于<span>{moment(props.endTime).format("YYYY-MM-DD")}</span>到期),为了不影响使用,建议尽快续费购买哦~</div>
) )
} }
...@@ -235,9 +235,6 @@ export default class CollegeManagePage extends React.Component { ...@@ -235,9 +235,6 @@ export default class CollegeManagePage extends React.Component {
User.removeToken(); User.removeToken();
User.removeEnterpriseId(); User.removeEnterpriseId();
window.RCHistory.replace('/login'); window.RCHistory.replace('/login');
// User.clearUserInfo();
// const htmlUrl = `${LIVE_SHARE}store/index?id=${User.getCustomerStoreId()||User.getStoreId()}&userId=${User.getUserId()}&from=work_weixin`;
// window.location.href = htmlUrl;
}); });
} }
......
...@@ -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: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-08-04 16:22:40 * @LastEditTime: 2021-08-11 20:26:53
* @Description: * @Description:
*/ */
import React, { useRef, useContext, useEffect, useState } from 'react'; import React, { useRef, useContext, useEffect, useState } from 'react';
...@@ -76,8 +76,8 @@ function Header(props) { ...@@ -76,8 +76,8 @@ function Header(props) {
storeUserId: User.getStoreUserId(), storeUserId: User.getStoreUserId(),
}; };
BaseService.getStoreUser(param).then((res) => { BaseService.getStoreUser(param).then((res) => {
const { nickName, phone } = res.result; const { weChatAccount, phone } = res.result;
setNickName(nickName); setNickName(weChatAccount);
setPhone(phone); setPhone(phone);
setAvatar(res.result.avatar); setAvatar(res.result.avatar);
User.setAvatar(res.result.avatar); User.setAvatar(res.result.avatar);
...@@ -341,7 +341,7 @@ function Header(props) { ...@@ -341,7 +341,7 @@ function Header(props) {
<div <div
className='url-link' className='url-link'
onClick={() => { onClick={() => {
window.open(`${LIVE_SHARE}store/index?id=${window.currentStoreUserInfo.storeId||User.getStoreId()}&userId=${window.currentStoreUserInfo.userId||User.getUserId()}&enterpriseId=${window.currentStoreUserInfo.enterpriseId||User.getEnterpriseId()}&from=admin&avatar=${avatar}`); window.open(`${LIVE_SHARE}store/index?id=${window.currentStoreUserInfo.storeId || User.getStoreId()}&userId=${window.currentStoreUserInfo.userId || User.getUserId()}&enterpriseId=${window.currentStoreUserInfo.enterpriseId || User.getEnterpriseId()}&from=admin&avatar=${avatar}`);
}}> }}>
{'立即前往 >'} {'立即前往 >'}
</div> </div>
...@@ -359,12 +359,15 @@ function Header(props) { ...@@ -359,12 +359,15 @@ function Header(props) {
<span className='text'>分享学院</span> <span className='text'>分享学院</span>
</span> </span>
</div> </div>
<div className='help'> {
<a href={helpCenterUrl} target='_blank' className='help-btn'> process.env.BRAND == 'xiaomai' && <div className='help'>
<span className='icon iconfont tool-tip-right'>&#xe8ed;</span> <a href={helpCenterUrl} target='_blank' className='help-btn'>
<span className='text'>帮助中心</span> <span className='icon iconfont tool-tip-right'>&#xe8ed;</span>
</a> <span className='text'>帮助中心</span>
</div> </a>
</div>
}
</div> </div>
<Dropdown overlay={userMenu()} arrow> <Dropdown overlay={userMenu()} arrow>
<div className='user'> <div className='user'>
......
...@@ -10,21 +10,26 @@ function Main(props) { ...@@ -10,21 +10,26 @@ function Main(props) {
console.log("menuType", menuType); console.log("menuType", menuType);
useEffect(() => { useEffect(() => {
Bus.bind('showRouteChangeModal', () => { Bus.bind('showRouteChangeModal',showModal )
Modal.confirm({ return ()=>{
title: '确定要返回吗?', Bus.unbind('showRouteChangeModal',showModal)
content: '返回后,本次编辑的内容将不被保存', }
okText: '确认返回',
cancelText: '留在本页',
icon: <span className='icon iconfont default-confirm-icon'>&#xe6f4;</span>,
onOk: () => {
routeHook.leave()
},
});
})
}, []) }, [])
function showModal(){
Modal.confirm({
title: '确定要返回吗?',
content: '返回后,本次编辑的内容将不被保存',
okText: '确认返回',
cancelText: '留在本页',
icon: <span className='icon iconfont default-confirm-icon'>&#xe6f4;</span>,
onOk: () => {
routeHook.leave()
},
});
}
return ( return (
<div <div
......
/* /*
* @Author: wufan * @Author: wufan
* @Date: 2020-11-27 16:21:49 * @Date: 2020-11-27 16:21:49
* @LastEditors: wufan * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-05-11 10:58:58 * @LastEditTime: 2021-08-09 13:47:18
* @Description: Description * @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -23,6 +23,7 @@ import _, { values } from "underscore"; ...@@ -23,6 +23,7 @@ import _, { values } from "underscore";
import "./EmployeeAddOrEditModal.less"; import "./EmployeeAddOrEditModal.less";
import { CropperModal } from "@/components/"; import { CropperModal } from "@/components/";
import StoreService from "@/domains/store-domain/storeService"; import StoreService from "@/domains/store-domain/storeService";
import WWOpenDataCom from '@/components/WWOpenDataCom';
import $ from "jquery"; import $ from "jquery";
import User from "@/common/js/user"; import User from "@/common/js/user";
...@@ -36,7 +37,8 @@ interface AddEmployeeModalProps { ...@@ -36,7 +37,8 @@ interface AddEmployeeModalProps {
role: Array<string>; role: Array<string>;
avatar?: string; avatar?: string;
storeUserId?: string; storeUserId?: string;
weChatAccount?: string weChatAccount?: string;
depNameList?: any;
}; };
onClose: () => void; onClose: () => void;
isWorkWechat: boolean; isWorkWechat: boolean;
...@@ -219,20 +221,20 @@ function AddEmployeeModal(props: AddEmployeeModalProps) { ...@@ -219,20 +221,20 @@ function AddEmployeeModal(props: AddEmployeeModalProps) {
initialValues={{ nickName: nickName, phone: phone, role: role }} initialValues={{ nickName: nickName, phone: phone, role: role }}
> >
<Form.Item <Form.Item
label="员工昵称" label="员工姓名"
name="nickName" name="nickName"
rules={[{ required: true }]} // rules={[{ required: true }]}
validateStatus={nameStatus} // validateStatus={nameStatus}
help={nameErrorMsg || undefined} // help={nameErrorMsg || undefined}
style={{ marginBottom: 0 }} style={{ marginBottom: 0 }}
> >
<Input <div style={{
style={{ width: 200 }} whiteSpace: 'nowrap',
placeholder="请输入员工昵称" textOverflow: 'ellipsis',
maxLength={15} overflow: 'hidden',
autoComplete="off" }}>
onChange={(e) => handleChangeValues("nickName", e.target.value)} <WWOpenDataCom type="userName" openid={props.choosedItem.weChatAccount}/>
/> </div>
</Form.Item> </Form.Item>
{props.isWorkWechat ? ( {props.isWorkWechat ? (
<Form.Item <Form.Item
...@@ -272,6 +274,21 @@ function AddEmployeeModal(props: AddEmployeeModalProps) { ...@@ -272,6 +274,21 @@ function AddEmployeeModal(props: AddEmployeeModalProps) {
/> />
</Form.Item> </Form.Item>
)} )}
<Form.Item
label="所在部门"
name="weChatAccount"
style={{ marginBottom: 0 }}
>
<div style={{
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
overflow: 'hidden',
}}>
{props.choosedItem.depNameList.map((item:any,index:any)=>{
return <span><WWOpenDataCom type="departmentName" openid={item}/>{index<props.choosedItem.depNameList.length-1?'、':''}</span>
})}
</div>
</Form.Item>
<Form.Item <Form.Item
label="员工角色" label="员工角色"
name="role" name="role"
...@@ -312,25 +329,6 @@ function AddEmployeeModal(props: AddEmployeeModalProps) { ...@@ -312,25 +329,6 @@ function AddEmployeeModal(props: AddEmployeeModalProps) {
<div className="avatart-img"> <div className="avatart-img">
<img className="avatar" src={avatar}></img> <img className="avatar" src={avatar}></img>
</div> </div>
<div className="upload-avatar">
<Button id="click_upload_btn" onClick={_onUpload}>
上传头像
</Button>
<input
type="file"
accept="image/*"
id="CrpperAvatarPic"
style={{ display: "none" }}
onChange={_handleUpdateAvatar}
/>
{cropperModalVisible && (
<CropperModal
imgUrl={imgUrl}
save={changeAvatar}
close={closeCropperModal}
/>
)}
</div>
</div> </div>
</Col> </Col>
</Row> </Row>
......
...@@ -218,8 +218,9 @@ class StoreH5Decoration extends React.Component { ...@@ -218,8 +218,9 @@ class StoreH5Decoration extends React.Component {
termType: 'H5_ADMIN', termType: 'H5_ADMIN',
} }
StoreService.editStoreBanner(params).then((res) => { StoreService.editStoreBanner(params).then((res) => {
message.success('设置成功') message.success('设置成功');
this.getStoreDecorationList() this.getStoreDecorationList();
this.setState({showSelectFileModal:false});
}) })
} }
...@@ -243,8 +244,9 @@ class StoreH5Decoration extends React.Component { ...@@ -243,8 +244,9 @@ class StoreH5Decoration extends React.Component {
termType: 'H5_ADMIN', termType: 'H5_ADMIN',
} }
StoreService.addStoreBanner(params).then((res) => { StoreService.addStoreBanner(params).then((res) => {
message.success('设置成功') message.success('设置成功');
this.getStoreDecorationList() this.getStoreDecorationList();
this.setState({showSelectFileModal:false});
}) })
} }
......
...@@ -218,6 +218,7 @@ class StoreWebDecoration extends React.Component { ...@@ -218,6 +218,7 @@ class StoreWebDecoration extends React.Component {
StoreService.editStoreBanner(params).then((res) => { StoreService.editStoreBanner(params).then((res) => {
message.success('设置成功') message.success('设置成功')
this.getStoreDecorationList() this.getStoreDecorationList()
this.setState({showSelectFileModal:false});
}) })
} }
...@@ -242,7 +243,8 @@ class StoreWebDecoration extends React.Component { ...@@ -242,7 +243,8 @@ class StoreWebDecoration extends React.Component {
} }
StoreService.addStoreBanner(params).then((res) => { StoreService.addStoreBanner(params).then((res) => {
message.success('设置成功') message.success('设置成功')
this.getStoreDecorationList() this.getStoreDecorationList();
this.setState({showSelectFileModal:false});
}) })
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-04-29 10:26:32 * @Date: 2020-04-29 10:26:32
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-08-03 14:34:27 * @LastEditTime: 2021-08-11 20:27:02
* @Description: 内容线路由配置 * @Description: 内容线路由配置
*/ */
import Home from '@/modules/home/Home'; import Home from '@/modules/home/Home';
......
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