Commit 4e8a79af by zhangleyuan

feat:处理店铺员工增加运营师

parent 24ad52f8
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: zhangleyuan * @Author: zhangleyuan
* @Date: 2021-02-21 16:08:38 * @Date: 2021-02-21 16:08:38
* @LastEditors: zhangleyuan * @LastEditors: zhangleyuan
* @LastEditTime: 2021-02-28 17:51:46 * @LastEditTime: 2021-03-01 10:21:33
* @Description: 描述一下 * @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -14,3 +14,6 @@ export function getTrainingPlanPage(params: object) { ...@@ -14,3 +14,6 @@ export function getTrainingPlanPage(params: object) {
export function createTrainingPlan(params: object) { export function createTrainingPlan(params: object) {
return Service.Hades("public/hades/createTrainingPlan", params); return Service.Hades("public/hades/createTrainingPlan", params);
} }
export function updateStateTrainingPlan(params: object) {
return Service.Hades("public/hades/updateStateTrainingPlan", params);
}
/*
* @Author: zhangleyuan
* @Date: 2021-03-01 15:33:02
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-03-01 15:35:09
* @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
* @Author: zhangleyuan * @Author: zhangleyuan
* @Date: 2021-02-21 16:15:38 * @Date: 2021-02-21 16:15:38
* @LastEditors: zhangleyuan * @LastEditors: zhangleyuan
* @LastEditTime: 2021-02-28 17:52:28 * @LastEditTime: 2021-03-01 10:22:19
* @Description: 描述一下 * @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import {getTrainingPlanPage,createTrainingPlan} from '@/data-source/plan/request-apis'; import {getTrainingPlanPage,createTrainingPlan,updateStateTrainingPlan} from '@/data-source/plan/request-apis';
export default class PlanService { export default class PlanService {
// 获取员工列表 // 获取员工列表
static getTrainingPlanPage(params: any) { static getTrainingPlanPage(params: any) {
...@@ -15,4 +15,7 @@ export default class PlanService { ...@@ -15,4 +15,7 @@ export default class PlanService {
static createTrainingPlan(params: any) { static createTrainingPlan(params: any) {
return createTrainingPlan(params); return createTrainingPlan(params);
} }
static updateStateTrainingPlan(params: any) {
return updateStateTrainingPlan(params);
}
} }
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: zhangleyuan * @Author: zhangleyuan
* @Date: 2021-02-20 16:13:39 * @Date: 2021-02-20 16:13:39
* @LastEditors: zhangleyuan * @LastEditors: zhangleyuan
* @LastEditTime: 2021-02-28 19:37:07 * @LastEditTime: 2021-03-01 13:41:08
* @Description: 描述一下 * @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -22,7 +22,7 @@ function PlanPage() { ...@@ -22,7 +22,7 @@ function PlanPage() {
handleFetchPlanList(); handleFetchPlanList();
}, [query]); }, [query]);
const [totalCount,setTotalCount] = useState(0); const [totalCount,setTotalCount] = useState(0);
function queryChange(){ function queryChange(_query){
const params = { const params = {
...query, ...query,
..._query, ..._query,
......
...@@ -2,19 +2,25 @@ ...@@ -2,19 +2,25 @@
* @Author: zhangleyuan * @Author: zhangleyuan
* @Date: 2021-02-20 16:46:46 * @Date: 2021-02-20 16:46:46
* @LastEditors: zhangleyuan * @LastEditors: zhangleyuan
* @LastEditTime: 2021-02-28 19:39:39 * @LastEditTime: 2021-03-01 16:48:31
* @Description: 描述一下 * @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React from 'react'; import React, { useState, useRef, useEffect } from 'react';
import { Table, Modal, message , Tooltip,Switch,Dropdown} from 'antd'; import { Table, Modal, message , Tooltip,Switch,Dropdown} from 'antd';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { PageControl } from "@/components"; import { PageControl } from "@/components";
import PlanService from "@/domains/plan-domain/planService";
import SharePlanModal from '../modal/SharePlanModal';
import {LIVE_SHARE} from '@/domains/course-domain/constants';
import User from '@/common/js/user';
import './PlanList.less'; import './PlanList.less';
const { confirm } = Modal;
const userRole = User.getUserRole();
function PlanList(props) { function PlanList(props) {
const [sharePlanModal, setSharePlanModal] = useState(null);
function parseColumns(){ function parseColumns(){
const columns = [ const columns = [
...@@ -49,9 +55,9 @@ function PlanList(props) { ...@@ -49,9 +55,9 @@ function PlanList(props) {
width: '10%', width: '10%',
dataIndex: "status", dataIndex: "status",
render: (val, item, index) => { render: (val, item, index) => {
return ( return (
<Switch defaultChecked={true} /> <Switch defaultChecked={item.enableState==="YES"? true:false} onChange={()=>changeEnableState(item)} disabled={(userRole === "CloudManager" || userRole === "StoreManager")?false:true}/>
) )
}, },
}, },
{ {
...@@ -62,7 +68,7 @@ function PlanList(props) { ...@@ -62,7 +68,7 @@ function PlanList(props) {
render: (val) => { render: (val) => {
return ( return (
<div className="create-name"> <div className="create-name">
张某某 {val}
</div> </div>
) )
} }
...@@ -90,13 +96,13 @@ function PlanList(props) { ...@@ -90,13 +96,13 @@ function PlanList(props) {
{ {
title: '参培人数', title: '参培人数',
width: "10%", width: "10%",
key: 'joinNumber', key: 'cultureCustomerNum',
dataIndex: 'joinNumber', dataIndex: 'cultureCustomerNum',
sorter: true, sorter: true,
render: (val) => { render: (val) => {
return ( return (
<div className="join-number"> <div className="join-number">
3 {val}
</div> </div>
) )
} }
...@@ -111,19 +117,21 @@ function PlanList(props) { ...@@ -111,19 +117,21 @@ function PlanList(props) {
<div className="operate"> <div className="operate">
<div className="operate__item">学习数据</div> <div className="operate__item">学习数据</div>
<span className="operate__item split"> | </span> <span className="operate__item split"> | </span>
<div className="operate__item">分享</div> <div className="operate__item" onClick={() => {handleShowShareModal(record); }}>分享</div>
<span className="operate__item split"> | </span> <span className="operate__item split"> | </span>
<Dropdown overlay={renderMoreOperate(record)}> {(userRole === "CloudManager" || userRole === "StoreManager") &&
<span className="more-operate"> <Dropdown overlay={renderMoreOperate(record)}>
<span className="operate-text">更多</span> <span className="more-operate">
<span <span className="operate-text">更多</span>
className="iconfont icon" <span
style={{ color: "#5289FA" }} className="iconfont icon"
> style={{ color: "#5289FA" }}
&#xe824; >
</span> &#xe824;
</span> </span>
</Dropdown> </span>
</Dropdown>
}
</div> </div>
) )
} }
...@@ -134,7 +142,9 @@ function PlanList(props) { ...@@ -134,7 +142,9 @@ function PlanList(props) {
function renderMoreOperate(item){ function renderMoreOperate(item){
return ( return (
<div className="live-course-more-menu"> <div className="live-course-more-menu">
<div className="operate__item" <div className="operate__item"
onClick={()=>toEditPlanPage(item)}
>编辑</div> >编辑</div>
<div <div
className="operate__item" className="operate__item"
...@@ -142,6 +152,101 @@ function PlanList(props) { ...@@ -142,6 +152,101 @@ function PlanList(props) {
</div> </div>
) )
} }
function handleChangeTable(pagination, filters, sorter){
const { columnKey, order } = sorter;
const { query } = props;
let _columnKey;
let _order;
// 按创建时间升序排序
if (columnKey === 'created' && order === 'ascend') {_columnKey="UPDATED"; _order = 'SORT_ASC'; }
// 按创建时间降序排序
if (columnKey === 'created' && order === 'descend') { _columnKey="UPDATED"; _order = 'SORT_DESC';}
// 按更新时间升序排序
if (columnKey === 'updated' && order === 'ascend') { _columnKey="CREATED"; _order = 'SORT_ASC'; }
// 按更新时间降序排序
if (columnKey === 'updated' && order === 'descend') { _columnKey="CREATED"; _order = 'SORT_DESC'; }
// 按更新时间升序排序
if (columnKey === 'cultureCustomerNum' && order === 'ascend') { _columnKey="CUSTOMER_NUM"; _order = 'SORT_ASC'; }
// 按更新时间降序排序
if (columnKey === 'cultureCustomerNum' && order === 'descend') { _columnKey="CUSTOMER_NUM"; _order = 'SORT_DESC'; }
const _query = {
...query,
sortMap:{}
};
_query.sortMap[_columnKey]=_order;
props.onChange(_query);
}
// 显示分享弹窗
function handleShowShareModal(item) {
const htmlUrl = `${LIVE_SHARE}live_detail?id=${User.getStoreId()}`;
const longUrl = htmlUrl
const shareData = { ...item, longUrl };
const sharePlanModal = (
<SharePlanModal
data={shareData}
type="liveClass"
close={() => {
setSharePlanModal(null)
}}
/>
)
setSharePlanModal(sharePlanModal)
}
//改变上架状态
function changeEnableState(record){
let _enableState = record.enableState
if(_enableState==='NO'){
// _enableState = "YES";
const params={
"planId": record.planId,
"enableState":"YES"
}
PlanService.updateStateTrainingPlan(params).then((res)=>{
if(res.success){
// if(_enableState === "YES"){
record.enableState = "YES";
message.success("已启用此计划");
// }
}
})
}else{
// _enableState = "NO";
// item.enableState = "YES";
return confirm({
title: "确定要禁用培训计划吗?",
content: "禁用后,培训计划不再支持新用户加入,已参与培训的用户可继续培训",
icon: (
<span className="icon iconfont default-confirm-icon">&#xe839; </span>
),
okText: "确定",
okType: "danger",
cancelText: "取消",
onOk: () => {
const params={
"planId": record.planId,
"enableState":"NO"
}
PlanService.updateStateTrainingPlan(params).then((res)=>{
if(res.success){
// if(_enableState === "NO"){
record.enableState = "NO";
message.success("已禁用此计划");
// }
}
})
},
});
}
}
function toEditPlanPage(item){
window.RCHistory.push({
pathname: `/create-plan?type=edit&id=${item.planId}`,
})
}
return ( return (
<div className="plan-list"> <div className="plan-list">
<Table <Table
...@@ -149,6 +254,7 @@ function PlanList(props) { ...@@ -149,6 +254,7 @@ function PlanList(props) {
dataSource={props.planListData} dataSource={props.planListData}
columns={ parseColumns() } columns={ parseColumns() }
pagination={false} pagination={false}
onChange={handleChangeTable}
bordered bordered
/> />
<div className="box-footer"> <div className="box-footer">
...@@ -162,6 +268,7 @@ function PlanList(props) { ...@@ -162,6 +268,7 @@ function PlanList(props) {
}} }}
/> />
</div> </div>
{sharePlanModal }
</div> </div>
) )
} }
......
...@@ -2,16 +2,18 @@ ...@@ -2,16 +2,18 @@
* @Author: zhangleyuan * @Author: zhangleyuan
* @Date: 2021-02-20 16:45:51 * @Date: 2021-02-20 16:45:51
* @LastEditors: zhangleyuan * @LastEditors: zhangleyuan
* @LastEditTime: 2021-02-28 15:41:33 * @LastEditTime: 2021-03-01 16:43:16
* @Description: 描述一下 * @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React from 'react'; import React from 'react';
import { Button } from 'antd'; import { Button } from 'antd';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import User from '@/common/js/user';
import './PlanOpt.less'; import './PlanOpt.less';
function PlanOpt() { const userRole = User.getUserRole();
function PlanOpt() {
function handleCreatePlan(){ function handleCreatePlan(){
window.RCHistory.push({ window.RCHistory.push({
pathname: '/create-plan?type=add', pathname: '/create-plan?type=add',
...@@ -19,11 +21,13 @@ import './PlanOpt.less'; ...@@ -19,11 +21,13 @@ import './PlanOpt.less';
} }
return ( return (
<div className="plan-opt"> <div className="plan-opt">
<Button { (userRole === "CloudManager" || userRole === "StoreManager") &&
type="primary" <Button
className="mr12" type="primary"
onClick={handleCreatePlan} className="mr12"
>新建培训计划</Button> onClick={handleCreatePlan}
>新建培训计划</Button>
}
</div> </div>
); );
} }
......
/*
* @Author: 吴文洁
* @Date: 2020-07-20 19:12:49
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-07-20 20:25:13
* @Description: 大班直播分享弹窗
*/
import React from 'react';
import { Modal, Input, Button, message } from 'antd';
import domtoimage from 'dom-to-image';
import qrcode from "@/libs/qrcode/qrcode.js";
import User from '@/common/js/user';
import $ from 'jquery';
import CourseService from "@/domains/course-domain/CourseService";
import './SharePlanModal.less';
const storeName = User.getStoreName();
const DEFAULT_COVER = 'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png';
class ShareLiveModal extends React.Component {
constructor(props) {
super(props);
this.state = {
shareUrl: ''
}
}
componentDidMount() {
// 获取短链接
this.handleConvertShortUrl();
}
handleConvertShortUrl = () => {
const { longUrl } = this.props.data;
// 发请求
CourseService.getQrcode({
urls: [longUrl]
}).then((res) => {
const { result = [] } = res;
this.setState({
shareUrl: result[0].shortUrl
}, () => {
const qrcodeWrapDom = document.querySelector('#qrcodeWrap');
const qrcodeNode = new qrcode({
text: this.state.shareUrl,
size: 98,
})
qrcodeWrapDom.appendChild(qrcodeNode);
});
})
}
componentWillUnmount() {
// 页面销毁之前清空定时器
clearTimeout(this.timer);
}
// 下载海报
handleDownloadPoster = () => {
this.setState({
showImg:true,
time:new Date().valueOf()
},()=>{
this.setState({time:new Date().valueOf()},()=>{
let node = document.getElementById('poster');
domtoimage.toPng(node)
.then((imgData) => {
console.log(imgData)
const download = document.createElement('a');
const { planName } = this.props.data;
$(download).attr('href', imgData).attr('download', `${planName}.png`).get(0).click();
})
})
})
}
// 复制分享链接
handleCopy = () => {
const textContent = document.getElementById('shareUrl').innerText;
window.copyText(textContent);
message.success('复制成功!');
}
render() {
const {data} = this.props;
const { planName, coverUrl = DEFAULT_COVER} = data;
const { shareUrl,showImg,time} = this.state;
return (
<Modal
title={'分享培训计划'}
width={680}
visible={true}
footer={null}
maskClosable={false}
closeIcon={<span className="icon iconfont modal-close-icon">&#xe6ef;</span>}
className="share-live-modal"
onCancel={this.props.close}
>
<div className="left">
<div id="poster">
<div className="store-name">
<span className="text">{storeName}</span>
</div>
<div className="course-name-title">邀请你参与培训:</div>
<div class="live-couse-name">{planName}</div>
{
showImg ? <img
crossOrigin='*'
src={coverUrl+`?=${time}`}
className="course-cover"
/>: <img
src={coverUrl+`?=${time}`}
className="course-cover"
/>
}
<div className="qrcode-wrap">
<div className="qrcode-wrap__left">
<div className="text">长按识别二维码进入观看</div>
<img className="finger" src="https://image.xiaomaiketang.com/xm/thpkWDwJsC.png"/>
</div>
<div className="qrcode-wrap__right" id="qrcodeWrap">
</div>
</div>
</div>
</div>
<div className="right">
<div className="share-poster right__item">
<div className="title">① 海报分享</div>
<div className="sub-title">用户可通过微信扫描海报二维码,查看培训计划</div>
<div className="content" onClick={this.handleDownloadPoster}>下载海报</div>
</div>
<div className="share-url right__item">
<div className="title">② 链接分享</div>
<div className="sub-title">用户可通过微信打开以下链接,查看培训计划</div>
<div className="content url-content">
<div className="share-url" id="shareUrl">{shareUrl}</div>
<Button type="primary" onClick={this.handleCopy}>复制</Button>
</div>
</div>
</div>
</Modal>
)
}
}
export default ShareLiveModal;
.share-live-modal {
.ant-modal-body {
display: flex;
#poster{
background: #FFF;
margin:0;
padding: 20px;
}
.left {
width: 303px;
margin: 0 32px 0 16px;
box-shadow:0px 2px 10px 0px rgba(0,0,0,0.05);
border-radius: 12px;
.course-name-title {
font-size: 14px;
color: #333;
line-height: 20px;
margin-bottom: 4px;
}
.live-couse-name{
font-size:16px;
color:#333333;
font-weight: 600;
}
.course-name {
color: #333;
font-size: 16px;
font-weight: 600;
line-height: 20px;
}
.course-cover {
width: 263px;
height: 143px;
border-radius: 6px;
margin-top: 8px;
}
.qrcode-wrap {
padding: 0 16px;
display: flex;
align-items: center;
margin: 24px 0 16px 0;
&__left {
width: 98px;
text-align: center;
margin-right: 22px;
.text {
line-height: 20px;
}
.finger {
width: 40px;
height: 40px;
margin-top: 8px;
}
}
&__right {
width: 110px;
height: 110px;
padding: 6px
}
}
.store-name {
// padding: 8px 16px;
display: flex;
align-items: center;
margin-bottom: 8px;
.text {
font-size: 12px;
color: #999;
font-size: 14px;
line-height: 20px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 100%;
}
}
}
.right {
.title {
color: #333;
font-weight: 500;
}
.sub-title {
color: #999;
margin-top: 16px;
}
.content {
display: flex;
align-items: center;
margin-top: 8px;
.share-url {
width: 212px;
overflow: hidden;
height: 28px;
line-height: 28px;
border-radius: 4px 0 0 4px;
padding-left: 12px;
white-space: nowrap;
color: #999999;
background: #EFEFEF;
}
.ant-btn {
margin-left: -2px;
}
}
.url-content{
position:relative;
&:after{
content:'';
width: 12px;
height: 22px;
background: #EFEFEF;
position:absolute;
right:71px;
}
}
.share-poster {
margin-bottom: 40px;
.content {
color:rgba(82, 137, 250, 1);
cursor: pointer;
}
}
}
}
}
\ No newline at end of file
/* /*
* @Author: wufan * @Author: wufan
* @Date: 2020-11-27 16:21:49 * @Date: 2020-11-27 16:21:49
* @LastEditors: wufan * @LastEditors: zhangleyuan
* @LastEditTime: 2021-01-25 21:14:48 * @LastEditTime: 2021-03-01 19:22:10
* @Description: Description * @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -40,11 +40,10 @@ interface AddEmployeeModalProps { ...@@ -40,11 +40,10 @@ interface AddEmployeeModalProps {
onClose: () => void; onClose: () => void;
isWorkWechat: boolean; isWorkWechat: boolean;
} }
function AddEmployeeModal(props: AddEmployeeModalProps) { function AddEmployeeModal(props: AddEmployeeModalProps) {
const [nickName, setName] = useState(""); const [nickName, setName] = useState("");
const [phone, setPhone] = useState(""); const [phone, setPhone] = useState("");
const [role, setRole] = useState("CloudLecturer"); const [role, setRole] = useState("CloudOperation");
const [avatar, setAvatar] = useState( const [avatar, setAvatar] = useState(
"https://image.xiaomaiketang.com/xm/rJeQaZxtc7.png" "https://image.xiaomaiketang.com/xm/rJeQaZxtc7.png"
); );
...@@ -64,16 +63,15 @@ function AddEmployeeModal(props: AddEmployeeModalProps) { ...@@ -64,16 +63,15 @@ function AddEmployeeModal(props: AddEmployeeModalProps) {
const [form] = Form.useForm(); const [form] = Form.useForm();
useEffect(() => { useEffect(() => {
if (props.choosedItem.nickName) { if (props.choosedItem.nickName) {
console.log("props.choosedItem", props.choosedItem); console.log("props.choosedItem", props.choosedItem);
setName(props.choosedItem.nickName); setName(props.choosedItem.nickName);
console.log('choosedItem',props.choosedItem);
props.choosedItem.phone && setPhone(props.choosedItem.phone); props.choosedItem.phone && setPhone(props.choosedItem.phone);
props.choosedItem.role && setRole(props.choosedItem.role[0]); props.choosedItem.role && setRole(props.choosedItem.role[0]);
props.choosedItem.avatar && setAvatar(props.choosedItem.avatar); props.choosedItem.avatar && setAvatar(props.choosedItem.avatar);
const _role = const _role = props.choosedItem.role[0];
props.choosedItem.role[0] === "CloudLecturer"
? "CloudLecturer"
: "CloudManager";
form.setFieldsValue({ form.setFieldsValue({
nickName: props.choosedItem.nickName, nickName: props.choosedItem.nickName,
role: _role, role: _role,
...@@ -284,8 +282,13 @@ function AddEmployeeModal(props: AddEmployeeModalProps) { ...@@ -284,8 +282,13 @@ function AddEmployeeModal(props: AddEmployeeModalProps) {
}} }}
className="mt5" className="mt5"
> >
<Radio value={"CloudLecturer"} className="mt-4" <Radio value={"CloudOperation"} className="mt-4">
> <span style={{ color: "#333" }}>运营师</span>
<p className="radio-tip">
仅可查看/转发培训计划内容,并查看其负责的用户学习进度
</p>
</Radio>
<Radio value={"CloudLecturer"} className="mt-4">
<span style={{ color: "#333" }}>普通讲师</span> <span style={{ color: "#333" }}>普通讲师</span>
<p className="radio-tip"> <p className="radio-tip">
仅可查看/使用与自己相关的文件和课表,并进行上课 仅可查看/使用与自己相关的文件和课表,并进行上课
......
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