Commit d154aeb4 by maolipeng

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

# Conflicts:
#	src/common/js/axios.ts
#	src/modules/college-manage/EmployeeManage.tsx
#	src/modules/college-manage/UserManagePage.tsx
#	src/modules/home/Home.jsx
#	src/modules/root/Menu.tsx
parents 65f7ba35 ba7900dc
......@@ -34,7 +34,7 @@
"bizcharts": "^3.3.0",
"camelcase": "^5.3.1",
"case-sensitive-paths-webpack-plugin": "2.3.0",
"classnames": "^2.2.6",
"classnames": "^2.3.1",
"cropper": "^3.1.4",
"cross-env": "^7.0.3",
"css-loader": "3.4.2",
......
......@@ -7,11 +7,12 @@
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosPromise, AxiosError } from 'axios';
import { message } from 'antd';
import { message, Modal } from 'antd';
import { BASIC_HOST, TIME_OUT, USER_TYPE, VERSION, PROJECT } from '@/domains/basic-domain/constants';
import User from './user';
import { content } from 'html2canvas/dist/types/css/property-descriptors/content';
interface FetchParams {
url: string,
......@@ -28,7 +29,7 @@ interface HeadersType{
storeUserId?:any,
userId?:any,
xmtoken?:any,
EnterpriseId?:any
enterpriseId?:string|null
}
class Axios {
static post(
......@@ -52,8 +53,8 @@ class Axios {
if(User.getToken()){
headerObject.xmtoken = User.getToken();
}
if(User.getEnterpriseId()) {
headerObject.EnterpriseId = User.getEnterpriseId();
if (User.getEnterpriseId()) {
headerObject.enterpriseId = User.getEnterpriseId();
}
const instance: AxiosInstance = axios.create({
timeout: TIME_OUT,
......@@ -88,8 +89,15 @@ class Axios {
})
instance.interceptors.response.use((response: AxiosResponse): AxiosResponse | AxiosPromise => {
const { message: ResMessage, success, resultMsg, resultCode } = response.data;
if (success || resultCode === 0) {
const { message: ResMessage, success, resultMsg, code: resultCode } = response.data;
const requestStatus = response.status;
if (requestStatus === 10001) {
Modal.warning({
title:"服务已到期",
content: "当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买",
okText: "我知道了"
})
} else if (success || resultCode === 0) {
return response;
} else if (!options.reject) {
message.error(ResMessage || resultMsg);
......@@ -108,6 +116,13 @@ class Axios {
window.RCHistory.replace('/login');
return Promise.reject();
break;
case 10001:
Modal.warning({
title:"服务已到期",
content: "当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买",
okText: "我知道了"
})
break;
default:
message.error(error.message);
break;
......
......@@ -11,8 +11,13 @@ import Storage from './storage';
import { PREFIX, USER_PREFIX } from '@/domains/basic-domain/constants';
class User {
getStoreId() {
return Storage.get(`${PREFIX}_storeId`);
getVersion() {
return Storage.getObj(`${PREFIX}_version`)
}
getStoreId(){
return Storage.get(`${PREFIX}_storeId`)
}
getEnterpriseId() {
......@@ -49,8 +54,12 @@ class User {
return Storage.get(`${PREFIX}_isAdmin`);
}
setStoreId(value: any) {
return Storage.set(`${PREFIX}_storeId`, value);
setVersion(value:any) {
return Storage.setObj(`${PREFIX}_version`,value)
}
setStoreId(value:any){
return Storage.set(`${PREFIX}_storeId`,value)
}
setEnterpriseId(value: any) {
......
......@@ -10,4 +10,7 @@
height: 100vh;
padding: 16px;
background-color: #F0F2F5;
}
.ant-tooltip-inner {
max-width: 1000px;
}
\ No newline at end of file
......@@ -7,6 +7,7 @@
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import Service from "@/common/js/service";
import User from "@/common/js/user";
export function sendLoginAuthCode(params: object) {
return Service.Hades("anon/hades/sendLoginAuthCode", params);
......@@ -47,6 +48,9 @@ export function getEnterpriseUser(params: object) {
export function getWXWorkLoginNoCheck(params: object) {
return Service.Hades('anon/hades/getWXWorkLoginNoCheck', params);
}
export function getLesseeVersionMsg() {
return Service.Hades("public/hades/getLesseeVersionMsg",{enterpriseId:User.getEnterpriseId()})
}
export const getOssClient = (
data: object,
instId: string,
......
......@@ -7,6 +7,7 @@
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import Service from "@/common/js/service";
import User from "@/common/js/user"
export function getEmployeeList(params: object) {
return Service.Hades("public/hades/getStoreUserPage", params);
......@@ -76,3 +77,4 @@ export function getStoreDetail(params: object) {
}
......@@ -7,7 +7,7 @@
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import { getUserStore, getUserPermission ,logout,getStoreUser,sendBizAuthCode,editUserPhone,checkBizAuthCode,sendNewPhoneAuthCode,sendLoginAuthCode,login,getLastedVersion, getEnterpriseUser,getWXWorkLoginNoCheck} from '@/data-source/base/request-apis';
import { getUserStore, getUserPermission ,logout,getStoreUser,sendBizAuthCode,editUserPhone,checkBizAuthCode,sendNewPhoneAuthCode,sendLoginAuthCode,login,getLastedVersion, getEnterpriseUser,getWXWorkLoginNoCheck,getLesseeVersionMsg} from '@/data-source/base/request-apis';
export default class StoreService {
// 获取员工列表
......@@ -55,5 +55,8 @@ export default class StoreService {
static getWXWorkLoginNoCheck(params: any){
return getWXWorkLoginNoCheck(params);
}
//获取企业配置的版本信息
static getLesseeVersionMsg() {
return getLesseeVersionMsg();
}
}
\ No newline at end of file
......@@ -17,6 +17,8 @@ import EmployeeAddOrEditModal from "../store-manage/EmployeeAddOrEditModal";
import User from "@/common/js/user";
import WechatApi from '@/common/js/wechatApi';
import WWOpenDataCom from '@/components/WWOpenDataCom';
import LimitTip from "./LimitTip";
import "./EmployeeManage.less";
import ChooseMembersModal from "./modal/ChooseMembersModal";
const { confirm } = Modal;
......@@ -371,6 +373,7 @@ function EmployeeManage() {
</Button>
}
</div>
<LimitTip type="员工" total={total} tip={()=>{return (<div>数据为当前学院的员工数,若员工存在多个学院,企业人数只统计为1人</div>)}}/>
<div className="box-body">
<XMTable
renderEmpty={{
......
.limit-tip {
height: 32px;
background: #E9EFFF;
border-radius: 2px;
margin-bottom: 13px;
.always {
display: inline-block;
font-size: 14px;
line-height: 32px;
font-weight: 400;
color: #666666;
margin-left: 16px;
.renew-text {
display: inline-block;
color: #2966FF;
cursor: pointer;
.renew-popover {
display: none;
position: absolute;
z-index: 1000;
width: 276px;
height: 294px;
transform: translate(-98px,13px);
box-shadow: 0px 2px 20px 0px rgba(0, 0, 0, 0.06);
background-color: white;
background-image: url(https://image.xiaomaiketang.com/xm/CZ4a752jzi.png);
background-repeat: no-repeat;
background-size: cover;
text-align: center;
font-size: 14px;
font-weight: 400;
color: #333333;
line-height: 22px;
box-shadow: 0px 2px 20px 0px rgba(0, 0, 0, 0.06);
.popover-arrow {
position: absolute;
display: block;
width: 8.48528137px;
height: 8.48528137px;
background: 0 0;
border-style: solid;
border-width: 4.24264069px;
left: 50%;
transform: translateX(-50%) rotate(45deg);
top: -4px;
border-top-color: #fff;
border-right-color: transparent;
border-bottom-color: transparent;
border-left-color: #fff;
box-shadow: -2px -2px 5px #0000000f;
}
.qrcode {
width: 182px;
height: 204px;
background-color: white;
margin: 28px auto 16px auto;
img {
width: 150px;
height: 150px;
margin: 16px 16px 8px 16px;
}
}
}
&:hover .renew-popover {
display: block;
}
}
}
}
\ No newline at end of file
import React, { useEffect, useState } from "react";
import BaseService from "@/domains/basic-domain/baseService";
import { Tooltip } from "antd"
import "./LimitTip.less"
export default function LimitTip(props:{total:number,type:string,tip:() => React.ReactNode}) {
const [isOver, setIsOver] = useState(false)
const [limitUser, setLimitUser] = useState(0)
useEffect(()=> {
BaseService.getLesseeVersionMsg()
.then(res=> {
setIsOver(res.result.surplusUserNum === 0 || res.result.whetherReachUserNum)
setLimitUser(res.result.userNum)
})
},[])
return (
<div className="limit-tip">
<div className="always">本学院{props.type}<span style={{color:"#333333",fontWeight:"bold"}}>{props.total}</span>
<Tooltip overlayStyle={{maxWidth:"587px",width:"fit-content"}} placement="topLeft" arrowPointAtCenter title={props.tip}>
<span className="icon iconfont" style={{cursor:"pointer",marginLeft:"4px",color:"#bfbfbf"}}>&#59449;</span>
</Tooltip>
{
isOver ? (
<>
<div style={{marginLeft:"14px",display:"inline-block"}}>当前企业使用人数已达到上限 (<span style={{color:"#333333",fontWeight:"bold"}}>{limitUser}</span>人),将无法添加新员工、新学员,如需增加人数限制,请联系小麦企学院服务平台。</div>
<div className="renew-text">立即续费<span className="icon iconfont" style={{fontSize:"10px"}}>&#59291;</span>
<div className="renew-popover">
<div className="popover-arrow"><span className="popover-arrow-content"></span></div>
<div className="qrcode">
<img src="https://cdn.xiaomai5.com/qixueyuankehu.png" alt=""></img>
<div className="des">微信/企业微信扫码续费</div>
</div>
<div className="phone"><svg style={{position:"relative",top:"2px",marginRight:"4px"}} viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M512.651 3.78c-281.433 0-509.21 228.324-509.21 509.209 0 281.43 228.325 509.203 509.21 509.203 281.427 0 509.202-228.317 509.202-509.203 0.55-280.885-227.775-509.21-509.202-509.21z m198.205 743.553c-36.14 36.136-169.737 1.641-302.24-130.312-131.953-131.959-165.902-266.104-129.768-301.695 31.211-31.21 68.99-85.417 125.939-14.782 56.943 70.629 29.016 90.34-3.291 122.647-22.449 22.448 24.642 79.392 73.37 128.125 49.283 48.73 105.678 95.818 128.126 73.368 32.306-32.305 52.017-60.23 122.646-3.288 71.182 56.949 16.426 95.276-14.782 125.937z" p-id="4409" fill="#999999"></path></svg>
咨询电话:19157875632</div>
</div>
</div>
</>
) : ("")
}
</div>
</div>
)
}
\ No newline at end of file
......@@ -17,4 +17,5 @@
margin-left: 4px;
}
}
}
\ No newline at end of file
......@@ -17,6 +17,8 @@ import User from "@/common/js/user";
import ChooseMembersModal from "./modal/ChooseMembersModal";
import { XMTable } from '@/components';
import college from '@/common/lottie/college.json';
import LimitTip from "./LimitTip"
import "./UserManagePage.less";
import moment from "moment";
......@@ -26,6 +28,8 @@ const { RangePicker } = DatePicker;
declare var window: any;
function UserManagePage() {
const [userList, setUserList] = useState([]);
const [model, setModel] = useState<React.ReactNode>(null);
......@@ -199,6 +203,7 @@ function UserManagePage() {
}}
>添加学员</Button>
}
<LimitTip type="学员" total={total} tip={()=>{ return (<div><div>1、数据为当前学院的员工数,若学员存在多个学院,企业人数只统计为1人;</div><div>2、若一个学员既用「企业微信」登录学习又用「微信」登录学习,企业人数将统计为2人。</div></div>)}}/>
<div className="box-body">
<XMTable
renderEmpty={{
......
import React from 'react';
import React, { useEffect, useState } from 'react';
import { Select, Tooltip } from 'antd';
import DataSet from "@antv/data-set";
import { Chart as G2Chart } from '@antv/g2';
......@@ -19,10 +19,44 @@ import {
} from "bizcharts";
import moment from 'moment'
import Service from "@/common/js/service";
import BaseService from "@/domains/basic-domain/baseService";
import User from '@/common/js/user';
import './Home.less';
const Option = Select.Option;
function HomeTip() {
const [isOverNum, setIsOverNum] = useState(false)
useEffect(()=> {
BaseService.getLesseeVersionMsg()
.then(res=> {
setIsOverNum(res.result.surplusUserNum === 0)
})
},[])
return isOverNum ? (
<div className="home-tip">
<div className="content">
<span className="icon iconfont" style={{color:"#FF4F4F",marginRight:"8px"}}>&#xe61d;</span>温馨提示:企业使用人数已达上限,将无法新增员工、学员,如需增加人数限制,请联系小麦企学院服务平台。
<div className="renew-btn">立即续费
<div className="renew-popover">
<div className="popover-arrow"><span class="popover-arrow-content"></span></div>
<div className="qrcode">
<img src="https://cdn.xiaomai5.com/qixueyuankehu.png" alt=""></img>
<div className="des">微信/企业微信扫码续费</div>
</div>
<div className="phone"><svg style={{position:"relative",top:"2px",marginRight:"4px"}} viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M512.651 3.78c-281.433 0-509.21 228.324-509.21 509.209 0 281.43 228.325 509.203 509.21 509.203 281.427 0 509.202-228.317 509.202-509.203 0.55-280.885-227.775-509.21-509.202-509.21z m198.205 743.553c-36.14 36.136-169.737 1.641-302.24-130.312-131.953-131.959-165.902-266.104-129.768-301.695 31.211-31.21 68.99-85.417 125.939-14.782 56.943 70.629 29.016 90.34-3.291 122.647-22.449 22.448 24.642 79.392 73.37 128.125 49.283 48.73 105.678 95.818 128.126 73.368 32.306-32.305 52.017-60.23 122.646-3.288 71.182 56.949 16.426 95.276-14.782 125.937z" p-id="4409" fill="#999999"></path></svg>
咨询电话:19157875632</div>
</div>
</div>
</div>
</div>
) : ("")
}
class Home extends React.Component {
constructor(props) {
super(props);
......@@ -264,6 +298,7 @@ class Home extends React.Component {
};
return (
<div className="home-page">
<HomeTip />
<div className="data-wrap">
<div className="home-title">数据概况</div>
<div className="data-box">
......
......@@ -28,6 +28,81 @@
font-family: 'number';
src: url('https://image.xiaomaiketang.com/xm/n2sADd2jY6.TTF');
}
.home-tip {
height: 40px;
background: #FFE7E7;
margin-bottom: 16px;
.content {
font-size: 14px;
color: #666666;
font-weight: 400;
line-height: 40px;
padding-left: 16px;
.renew-btn {
display: inline-block;
width: 80px;
height: 28px;
background: #FF4F4F;
border-radius: 2px;
color: #ffffff;
font-size: 14px;
font-weight: 400;
line-height: 28px;
text-align: center;
cursor: pointer;
.renew-popover {
display: none;
position: absolute;
z-index: 1000;
width: 276px;
height: 294px;
transform: translate(-98px,13px);
box-shadow: 0px 2px 20px 0px rgba(0, 0, 0, 0.06);
background-color: white;
background-image: url(https://image.xiaomaiketang.com/xm/CZ4a752jzi.png);
background-repeat: no-repeat;
background-size: cover;
text-align: center;
font-size: 14px;
font-weight: 400;
color: #333333;
line-height: 22px;
box-shadow: 0px 2px 20px 0px rgba(0, 0, 0, 0.06);
.popover-arrow {
position: absolute;
display: block;
width: 8.48528137px;
height: 8.48528137px;
background: 0 0;
border-style: solid;
border-width: 4.24264069px;
left: 50%;
transform: translateX(-50%) rotate(45deg);
top: -4px;
border-top-color: #fff;
border-right-color: transparent;
border-bottom-color: transparent;
border-left-color: #fff;
box-shadow: -2px -2px 5px #0000000f;
}
.qrcode {
width: 182px;
height: 204px;
background-color: white;
margin: 28px auto 16px auto;
img {
width: 150px;
height: 150px;
margin: 16px 16px 8px 16px;
}
}
}
&:hover .renew-popover {
display: block;
}
}
}
}
.data-wrap{
background: #FFF;
.data-box {
......
import React from 'react';
import React, { useEffect, useState } from 'react';
import moment from "moment"
import Service from "@/common/js/service";
import BaseService from "@/domains/basic-domain/baseService";
import User from "@/common/js/user";
import { LIVE_SHARE } from "@/domains/course-domain/constants";
import moment from 'moment';
import { Modal, message } from 'antd';
import './CollegeManagePage.less';
import storage from '@/common/js/storage';
const roleMap = {
CloudManager: "管理员",
......@@ -14,6 +15,88 @@ const roleMap = {
CloudOperator: '运营师',
};
function ExpirationPopover(props) {
const [showType, setShowType] = useState(0); //0不显示,1剩余30天,2小于等于7天,3已过期
useEffect(()=> {
if (props.surplusDayTime === 0 ) {
//已过期
let loginflag = storage.get("expiration_tip_login")
if (loginflag === null || loginflag === "true") {
//只有登陆进来的时候提示一次
console.log("showtype",showType)
setShowType(3)
}
return
}
//即将过期
if (props.surplusDayTime === 30) {
if (storage.get("expiration_tip"+User.getUserId()+"_thirty") == null || storage.get("expiration_tip"+User.getUserId()+"_thirty") === "true") {
setShowType(1)
}
return
}
if (props.surplusDayTime <= 7) {
let daysflag = storage.getObj("expiration_tip"+User.getUserId()+"_7day");
if (!daysflag) {
setShowType(2)
return
}
if (daysflag[props.surplusDayTime - 1] === 0) {
setShowType(2)
}
}
},[props.endTime,props.surplusDayTime])
function iknow() {
if (props.surplusDayTime === 0 ) {
//已过期
storage.set("expiration_tip_login",false)
} else if (props.surplusDayTime === 30) {
storage.set("expiration_tip"+User.getUserId()+"_thirty",false)
} else if (props.surplusDayTime <= 7) {
let daysflag = [0,0,0,0,0,0,0]
daysflag[props.surplusDayTime - 1] = 1
storage.setObj("expiration_tip"+User.getUserId()+"_7day",daysflag)
}
setShowType(0)
}
if (props.surplusDayTime > 30) {
return ("")
}
return (
<>
{
showType === 0 ? ("") :(
<div className="expirationpopover">
<div className="dialog">
<div className="title">服务到期提醒</div>
{
showType === 3 ? (
<div className="tip-text">当前企业购买的小麦企学院服务已于<span style={{color:"#FF4F4F"}}>{moment(props.endTime).format("YYYY-MM-DD")}</span>到期,到期后仍可访问,但功能不可使用,建议尽快续费购买哦~</div>
) : (
<div className="tip-text">当前企业购买的小麦企学院服务 <span style={{color:"#FF4F4F"}}>仅剩{props.surplusDayTime}</span>(于<span>{moment(props.endTime).format("YYYY-MM-DD")}</span>到期),为了不影响使用,建议尽快续费购买哦~</div>
)
}
<div className="qrcode">
<img src="https://cdn.xiaomai5.com/qixueyuankehu.png" alt=""></img>
<div className="des">微信/企业微信扫码续费</div>
</div>
<div className="phone"><svg style={{position:"relative",top:"2px",marginRight:"4px"}} viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M512.651 3.78c-281.433 0-509.21 228.324-509.21 509.209 0 281.43 228.325 509.203 509.21 509.203 281.427 0 509.202-228.317 509.202-509.203 0.55-280.885-227.775-509.21-509.202-509.21z m198.205 743.553c-36.14 36.136-169.737 1.641-302.24-130.312-131.953-131.959-165.902-266.104-129.768-301.695 31.211-31.21 68.99-85.417 125.939-14.782 56.943 70.629 29.016 90.34-3.291 122.647-22.449 22.448 24.642 79.392 73.37 128.125 49.283 48.73 105.678 95.818 128.126 73.368 32.306-32.305 52.017-60.23 122.646-3.288 71.182 56.949 16.426 95.276-14.782 125.937z" p-id="4409" fill="#999999"></path></svg>
咨询电话:19157875632</div>
<div className="button" onClick={iknow}>我知道了</div>
</div>
</div>
)
}
</>
)
}
export default class CollegeManagePage extends React.Component {
constructor(props) {
super(props);
......@@ -24,13 +107,16 @@ export default class CollegeManagePage extends React.Component {
enterpriseId: User.getEnterpriseId(),
isAdmin: false,
createStoreList:[],
joinStoreList:[]
joinStoreList:[],
surplusDayTime:365, //剩余天数
endTime: 0 //有效截至时间
};
}
componentDidMount() {
this.getStoreList();
this.getEnterpriseUser();
this.getVersion()
}
getEnterpriseUser() {
......@@ -44,6 +130,17 @@ export default class CollegeManagePage extends React.Component {
this.setState({ name, avatar, isAdmin })
});
}
getVersion() {
BaseService.getLesseeVersionMsg()
.then(res=> {
User.setVersion(res.result)
this.setState({
surplusDayTime: res.result.stateEnum === "YES" ? 0 : res.result.surplusDayTime,
endTime: res.result.validEndTime
})
})
}
getStoreList() {
const { enterpriseId } = this.state;
......@@ -132,6 +229,7 @@ export default class CollegeManagePage extends React.Component {
} = this.state;
return (
<div className="college-manage-page">
<ExpirationPopover surplusDayTime={this.state.surplusDayTime} endTime={this.state.endTime}/>
<div className="college-header">
<div className="box">
<img className="box-image" src="https://image.xiaomaiketang.com/xm/fe4NCjr7XF.png" />
......
......@@ -183,4 +183,78 @@
}
}
}
.expirationpopover {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0,0,0,0.7);
z-index: 1000;
.dialog {
width: 560px;
height: 486px;
background: #FFFFFF;
border-radius: 4px;
.title {
text-align: center;
font-size: 20px;
color: #333333;
font-weight: 500;
margin-top: 40px;
}
.tip-text {
font-size: 16px;
color: #666666;
font-weight: 400;
margin-top: 16px;
margin-right: 40px;
margin-left: 40px;
}
.qrcode {
width: 182px;
height: 204px;
background: #F1F3F6;
border-radius: 2px;
margin-top: 16px;
margin-left: auto;
margin-right: auto;
img {
width: 150px;
height: 150px;
margin: 16px 16px 8px 16px;
}
.des {
text-align: center;
font-size: 14px;
color: #333333;
font-weight: 400;
}
}
.phone {
text-align: center;
font-size: 14px;
color: #333333;
font-weight: 400;
margin-top: 16px;
}
.button {
width: 80px;
height: 32px;
background: #2966FF;
cursor: pointer;
margin-left: auto;
margin-right: auto;
margin-top: 24px;
font-size: 14px;
font-weight: 400;
color: #ffffff;
line-height: 32px;
text-align: center;
}
}
}
}
\ No newline at end of file
......@@ -6,6 +6,7 @@ import CheckBeforeSendCode from '../../components/CheckBeforeSendCode'
import User from '@/common/js/user'
import WechatLogin from './WechatLogin'
import BaseService from '@/domains/basic-domain/baseService'
import storage from '@/common/js/storage'
import axios from 'axios'
import _ from 'underscore'
import user from '@/common/js/user'
......@@ -43,6 +44,7 @@ function Login(props) {
User.removeToken()
User.removeEnterpriseId()
}
storage.set("expiration_tip_login",true)
}, [])
function getWXWorkLoginNoCheck(enterpriseId, userId) {
const params = {
......
......@@ -5,7 +5,7 @@
@active-color: #2966FF;
.left-container {
position: absolute;
z-index: 2;
z-index: 10;
top: @top-height;
left: 0;
bottom: 0;
......@@ -142,7 +142,153 @@
// display:inline-block;
// }
// }
.version-info {
position: absolute;
height: 74px;
bottom: 0;
width: 100%;
cursor: pointer;
.row-1 {
width: fit-content;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
line-height: 20px;
margin: 0 auto;
.version-name {
display: inline-block;
width: 58px;
text-align: center;
margin: 0 auto;
border-radius: 2px;
border: 1px solid #E8E8E8;
}
.renew {
display: inline-block;
width: 58px;
color: #2966FF;
margin-left: 8px;
.renew-popover {
display: none;
position: absolute;
width: 276px;
height: 294px;
left: 150px;
bottom: 52px;
box-shadow: 0px 2px 20px 0px rgba(0, 0, 0, 0.06);
background-color: white;
background-image: url(https://image.xiaomaiketang.com/xm/CZ4a752jzi.png);
background-repeat: no-repeat;
background-size: cover;
text-align: center;
font-size: 14px;
font-weight: 400;
color: #333333;
line-height: 22px;
.qrcode {
width: 182px;
height: 204px;
background-color: white;
margin: 28px auto 16px auto;
img {
width: 150px;
height: 150px;
margin: 16px 16px 8px 16px;
}
.des {
}
}
}
.renew-popover-show {
display: block;
}
}
}
.expiration-time {
height: 24px;
text-align: center;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
line-height: 22px;
margin: 6px auto 0 auto;
}
.popover {
display: none;
position: absolute;
z-index: 100;
padding: 16px 22px;
bottom: 22px;
width: 352px;
height: 198px;
right: -342px;
background: #FFFFFF;
box-shadow: 0px 2px 15px 0px rgba(0, 0, 0, 0.06);
.title {
display: inline-block;
width: 68px;
height: 22px;
font-size: 16px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 22px;
margin-right: 8px;
}
.expiration-tag {
display: inline-block;
width: 52px;
height: 18px;
background: #EEEEEE;
border-radius: 2px;
text-align: center;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
line-height: 17px;
}
&::before {
position: absolute;
content: "";
width: 16px;
height: 16px;
left: -8px;
top: 80%;
border: 8px solid transparent;
box-shadow: 0px 2px 15px 0px rgba(0, 0, 0, 0.06);
}
.content {
margin-top: 24px;
.widget {
display: inline-block;
}
.lable {
font-size: 14px;
font-weight: 400;
color: #999999;
line-height: 22px;
}
.lable-text {
margin-top: 4px;
font-size: 16px;
font-weight: 500;
color: #333333;
line-height: 22px;
}
}
}
.popover-show {
display: block;
}
}
}
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
background:@active-color !important;
}
......
......@@ -2,16 +2,127 @@ import React, { useContext, useEffect, useRef, useState } from 'react';
import {
withRouter,
} from 'react-router-dom';
import { Menu} from 'antd';
import { Menu, Popover, Tooltip } from 'antd';
import { RightOutlined } from '@ant-design/icons'
import { menuList } from '../../routes//config/menuList'
import { XMContext } from '../../store/context';
import Service from "@/common/js/service";
import StoreService from "@/domains/store-domain/storeService";
import User from "@/common/js/user";
import BaseService from "@/domains/basic-domain/baseService";
import classNames from 'classnames';
import User from "@/common/js/user"
import _ from 'underscore';
import "./Menu.less";
import { display } from 'html2canvas/dist/types/css/property-descriptors/display';
import moment from 'moment';
const { SubMenu } = Menu;
interface VersionInfo {
dayTime: number
stateEnum: string
surplusDayTime: number
surplusUserNum: number
userNum: number
validEndTime: string
validStartTime: string
}
function VersionPanel(props:any) {
const [versionName,setVersionName] = useState("标准版")
const [showVersionPopover, setShowVersionPopover] = useState(false)
const [showRenewPopover, setShowRenewPopover] = useState(false)
const [isExpiration, setIsExpiration] = useState(false)
const [versionInfo, setVersionInfo] = useState<any>({})
useEffect(()=> {
BaseService.getLesseeVersionMsg()
.then(res=> {
let version = res.result
User.setVersion(version)
let versioninfo = {
userNum: version.userNum,
surplusUserNum: version.surplusUserNum,
surplusDayTime: version.surplusDayTime,
validEndTime: moment(version.validEndTime).format("YYYY-MM-DD"),
validStartTime: moment(version.validStartTime).format("YYYY-MM-DD"),
}
setVersionInfo(versioninfo)
if (version.surplusDayTime === 0) {
setIsExpiration(true)
}
})
},[])
function onVersionEnter() {
setShowVersionPopover(true)
}
function onVersionLeave() {
setShowVersionPopover(false)
setShowRenewPopover(false)
}
function onRenewClick() {
setShowRenewPopover(true)
setShowVersionPopover(false)
}
const versionPopoverClass = classNames({
'popover':true,
'popover-show':showVersionPopover
})
const renewPopoverClass = classNames({
'renew-popover': true,
'renew-popover-show': showRenewPopover
})
return (
<div className="version-info" onMouseEnter={onVersionEnter} onMouseLeave={onVersionLeave}>
<div className="row-1">
<div className="version-name">{versionName}</div>
<div className="renew" onClick={onRenewClick}>去续费<span className="icon iconfont" style={{fontSize:"10px"}}>&#59291;</span>
<div className={renewPopoverClass}>
<div className="qrcode">
<img src="https://cdn.xiaomai5.com/qixueyuankehu.png" alt=""></img>
<div className="des">微信/企业微信扫码续费</div>
</div>
<div className="phone"><svg style={{position:"relative",top:"2px",marginRight:"4px"}} viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M512.651 3.78c-281.433 0-509.21 228.324-509.21 509.209 0 281.43 228.325 509.203 509.21 509.203 281.427 0 509.202-228.317 509.202-509.203 0.55-280.885-227.775-509.21-509.202-509.21z m198.205 743.553c-36.14 36.136-169.737 1.641-302.24-130.312-131.953-131.959-165.902-266.104-129.768-301.695 31.211-31.21 68.99-85.417 125.939-14.782 56.943 70.629 29.016 90.34-3.291 122.647-22.449 22.448 24.642 79.392 73.37 128.125 49.283 48.73 105.678 95.818 128.126 73.368 32.306-32.305 52.017-60.23 122.646-3.288 71.182 56.949 16.426 95.276-14.782 125.937z" p-id="4409" fill="#999999"></path></svg>
咨询电话:19157875632</div>
</div>
</div>
</div>
<div className="expiration-time">有效期至{versionInfo.validEndTime}{isExpiration ? "(已过期)" : ""}</div>
<div className={versionPopoverClass}>
<div className="title">版本信息</div>
{isExpiration ? <div className="expiration-tag">已过期</div> : ""}
<div className="content">
<div className="widget" style={{marginRight:"40px",marginBottom:"16px"}}>
<div className="lable">剩余天数</div>
<div className="lable-text">{versionInfo.surplusDayTime}</div>
</div>
<div className="widget" style={{marginBottom:"16px"}}>
<div className="lable">有效起止日期</div>
<div className="lable-text">{versionInfo.validStartTime}~{versionInfo.validEndTime}</div>
</div>
<div className="widget" style={{marginRight:"40px",marginBottom:"8px"}}>
<div className="lable">剩余人数</div>
<div className="lable-text">{versionInfo.surplusUserNum}</div>
</div>
<div className="widget" style={{marginBottom:"8px"}}>
<div className="lable" style={{display:"inline-block"}}>人数限制</div>
<Tooltip overlayStyle={{maxWidth:"587px",width:"587px"}} placement="topLeft" arrowPointAtCenter title={()=>{ return (<div><div>1、若员工/学员存在多个学院,企业人数只统计为1人;</div><div>2、若一个学员既用「企业微信」登录学习又用「微信」登录学习,企业人数将统计为2人。</div></div>)}}>
<div style={{display:"inline-block",position:"relative",top:"2px",marginLeft:"4px"}}><span><svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1026" width="14" height="14"><path d="M512 68.266667c245.111467 0 443.733333 198.656 443.733333 443.733333s-198.621867 443.733333-443.733333 443.733333C266.922667 955.733333 68.266667 757.077333 68.266667 512S266.922667 68.266667 512 68.266667z m29.320533 596.548266c0.477867-27.989333 2.4576-48.196267 5.802667-60.654933 3.413333-12.458667 8.567467-23.4496 15.633067-33.0752 6.997333-9.557333 21.9136-24.507733 44.714666-44.714667 33.928533-30.037333 56.797867-55.637333 68.437334-76.5952a139.1616 139.1616 0 0 0 17.5104-68.846933c0-43.008-16.5888-79.701333-49.800534-110.011733-33.1776-30.378667-77.6192-45.533867-133.358933-45.533867-52.6336 0-94.958933 14.1312-126.976 42.3936-31.9488 28.2624-51.268267 68.949333-57.685333 122.094933l71.8848 8.533334c6.212267-39.6288 19.3536-68.778667 39.3216-87.483734 19.933867-18.6368 44.817067-27.989333 74.6496-27.989333 30.788267 0 56.900267 10.308267 78.165333 30.9248 21.265067 20.5824 31.880533 44.544 31.880533 71.748267 0 15.018667-3.618133 28.910933-10.922666 41.608533-7.168 12.731733-22.971733 29.764267-47.240534 51.131733-24.200533 21.367467-41.028267 37.649067-50.346666 48.810667-12.6976 15.291733-21.9136 30.481067-27.613867 45.533867-7.748267 19.933867-11.639467 43.690667-11.639467 71.133866 0 4.676267 0.1024 11.707733 0.341334 21.026134h67.242666z m8.192 140.3904v-79.735466h-79.701333v79.735466h79.701333z" fill="#bfbfbf" p-id="1027"></path></svg></span></div>
</Tooltip>
<div className="lable-text">{versionInfo.userNum}</div>
</div>
</div>
</div>
</div>
)
}
function Aside(props: any) {
const {menuType,handleMenuType}= props
const ctx: any = useContext(XMContext);
......@@ -162,7 +273,10 @@ function Aside(props: any) {
}
</Menu>
</div>
</div>
<VersionPanel />
</div>
);
}
......
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