Browse Source

开发退改签和两率分析

linehang 7 years ago
parent
commit
cbf5fafbcc

+ 23 - 29
app/statistics/change-back.html

@ -19,33 +19,28 @@
		<div id="main">
		<div id="main">
			<header-tab :appname="appname" :isback="isback" :isrefresh="isrefresh" :isfilter="isfilter" :isopen="isopen"></header-tab>
			<header-tab :appname="appname" :isback="isback" :isrefresh="isrefresh" :isfilter="isfilter" :isopen="isopen"></header-tab>
			<header-prompt></header-prompt>
			<header-prompt></header-prompt>
			<!-- 饼图 -->
			<div class="mt10 mb30">
				<div class="c-row">
					<div class="c-50 c-t-center c-position-r">
						<div class="div-radius-panel">
							<div class="c-f16 c-12b7f5 mt15">{{signRateData.signRateText}}</div>
							<div class="c-f14 c-666">签约率</div>
						</div>
						<div id="signMain" class="c-100 height-120"></div>
						<div class="c-f12 c-999 div-data-value">
							<span class="c-f12 c-12b7f5 qianyuelv">{{signRateData.signAmount}}</span>/
							<span class="c-f12 c-333 qianyuezong">{{signRateData.signRateAll}}</span>
						</div>
					</div>
					<div class="c-50 c-t-center c-position-r">
						<div class="div-radius-panel">
							<div class="c-f16 c-12b7f5 mt15">{{signRateData.completeRateText}}</div>
							<div class="c-f14 c-666">完成率</div>
						</div>
						<div id="completeMain" class="c-100" style="height: 120px;"></div>
						<div class="c-f12 c-999 div-data-value">
							<span class="c-f12 c-12b7f5">{{signRateData.completeAmount}}</span>/
							<span class="c-f12 c-333">{{signRateData.completeRateAll}}</span>
						</div>
					</div>
				</div>
			</div>
			  <div class="clearfix ">
                <ul class="l-banner">
                    <li class="active" >
                        <div class="tag" :class="{'active': index==9}" @click="changeTag(9)">
                            <div id="index_9" class="c-f18">{{topDatas['index_9']}}</div>
                            <div class="mt5 c-f14 l-name">待审核数</div>
                        </div>
                    </li>
                    <li>
                        <div class="tag" :class="{'active': index==10}" @click="changeTag(10)">
                            <div id="index_10" class="c-f18">{{topDatas['index_10']}}</div>
                            <div class="mt5 c-f14 l-name">改签人数</div>
                        </div>
                    </li>
                    <li>
                        <div class="tag" :class="{'active': index==2}" @click="changeTag(2)">
                            <div id="index_2" class="c-f18">{{topDatas['index_2']}}</div>
                            <div class="mt5 c-f14 l-name">退签人数</div>
                        </div>
                    </li>
                </ul>
            </div>
			<!-- 折线图 -->
			<!-- 折线图 -->
			<line-chart v-on:getlinedata="getNewLineData" class="mlr8"></line-chart>
			<line-chart v-on:getlinedata="getNewLineData" class="mlr8"></line-chart>
			<!-- 底部区域图 -->
			<!-- 底部区域图 -->
@ -70,9 +65,8 @@
		<script src="../../component/statistics/line-chart.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/line-chart.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/area-data-panel.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/area-data-panel.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/team-info.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/team-info.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/sign-progress-filter.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/common.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/common.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/sign-progress.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/change-back.js" type="text/javascript" charset="utf-8"></script>
	</body>
	</body>
</html>
</html>

+ 86 - 0
app/statistics/css/common.css

@ -678,4 +678,90 @@ a {
	font-size: 16px !important;
	font-size: 16px !important;
	font-weight: bold !important;
	font-weight: bold !important;
	color: #333 !important;
	color: #333 !important;
}
.mod {
	background-color: #fff;
}
.mod .mod-hd {
	height: 33px;
	line-height: 33px;
	border-bottom: .05rem solid #e1e1e1;
	padding-left: .5rem;
	color: #323232;
}
.mod .mod-hd .title {
	font-size: .75rem;
}
.icon-cyc.sszql {
	background-image: url(../../images/snashi_icon.png);
}
.icon-cyc {
	display: inline-block;
	vertical-align: middle;
	width: 22px;
	height: 22px;
	background: center no-repeat;
	background-size: auto 100%;
}
.icon-cyc.gwrq {
	background-image: url(../../images/gaoweirenqun.png);
}
.div-ssqql canvas {
	width: 150px;
	height: 150px;
	margin-top: 20px;
}
.div-ssqql {
	height: 195px;
	position: relative;
	text-align: center;
	margin: 0 auto;
}
.p-sanshilv {
	position: absolute;
	top: 20px;
	left: 50%;
	font-size: 33px;
	color: #323232;
	width: 106px;
	margin-left: -53px;
}
.p-sanshicount {
	position: absolute;
	top: 90px;
	left: 50%;
	font-size: 15px;
	color: #323232;
	width: 116px;
	margin-left: -58px;
}
.p-gaoweilv {
	position: absolute;
	top: 20px;
	left: 50%;
	font-size: 33px;
	color: #323232;
	width: 106px;
	margin-left: -53px;
}
.p-gaoweicount {
	position: absolute;
	top: 90px;
	left: 50%;
	font-size: 15px;
	color: #323232;
	width: 116px;
	margin-left: -58px;
}
}

+ 330 - 0
app/statistics/js/change-back.js

@ -0,0 +1,330 @@
var reqList = []; //记录请求的参数和url,用于后退时使用
Vue.use(Vuedals.default);
new Vue({
	el: "#main",
	data: {
		appname: "退改签",
		isback: true,
		isrefresh: true,
		isfilter: false,
		isopen: false,
		//请求页面所需参数
		level: '',
		area: '',
		areaTitle: '',
		index: '9',
		selectedDateType: 1, //折线图坐标值1-日,2-周,3-月
		endDate: '',
		startDate: '',
		lowLevel: '',
		chooseYear: '',
		userRole: '',
		//数据结果
		topDatas: {
			index_2: 0,
			index_9: 0,
			index_10: 0
		}
	},
	components: {
		vuedals: Vuedals.Component
	},
	methods: {
		changeTag: function(val) {
			this.index = val;
			loadData([1, 2], this);
			//存储请求所带的参数
			reqList.push({
				level: this.level,
				area: this.area,
				areaTitle: this.areaTitle,
				index: this.index,
				date:this.endDate,
				endDate: this.endDate,
				startDate: this.startDate,
				lowLevel: this.lowLevel
			})
		},
		getNewLineData: function(arg) {
			this.selectedDateType = arg.dateType;
			loadData([1], this);
		},
		getAreaData: function(arg) {
			//如果level改变,则需要重新加载整个页面的数据,否则只需加载底部区域数据
			if(arg.level == this.level) {
				this.lowLevel = arg.lowLevel;
				loadData([2], this);
			} else {
				this.level = arg.level;
				this.lowLevel = arg.lowLevel;
				this.area = arg.area;
				loadData([0, 1, 2], this);
			}
			//存储请求所带的参数
			reqList.push({
				level: this.level,
				area: this.area,
				areaTitle: this.areaTitle,
				index: this.index,
				endDate: this.endDate,
				startDate: this.startDate,
				lowLevel: this.lowLevel,
			})
		}
	},
	mounted: function() {
		//初始化数据
		initData(this);
		//获得顶部各tab的值
		loadData([0, 1, 2], this); //参数组数表示请求的区域为上中下
		//存储请求所带的参数
		reqList.push({
			level: this.level,
			area: this.area,
			areaTitle: this.areaTitle,
			index: this.index,
			endDate: this.endDate,
			startDate: this.startDate,
			lowLevel: this.lowLevel
		});
		//设置监听器, 监听折线图日期变化
		var vm = this;
		//监听后退按钮的操作
		EventBus.$on("back-click", function(arg) {
			EventBus.$emit('update-statistics-time', {}); //更新统计时间
			if(reqList.length == 1) {
				history.go(-1);
			} else {
				var preInfo = reqList.pop();
				var info = reqList[reqList.length - 1];
				vm.level = info.level;
				vm.area = info.area;
				vm.areaTitle = info.areaTitle;
				vm.lowLevel = info.lowLevel;
				vm.index = info.index;
				loadData([0, 1, 2], vm);
			}
		});
		//监听页面刷新
		EventBus.$on("refresh-click", function(arg) {
			EventBus.$emit('update-statistics-time', {}); //更新统计时间
			loadData([0, 1, 2], vm);
		});
	}
})
function initData(vm) {
	//获得缓存中缓存的角色权限
	var userRole = window.localStorage.getItem("selectedRole");
	if(!userRole) {
		return false;
	}
	vm.userRole = JSON.parse(userRole);
	vm.level = vm.userRole.code == '350200' ? 4 : vm.userRole.code.length == 6 ? 3 : 2;
	vm.area = vm.userRole.code;
	vm.areaTitle = vm.userRole.name;
	var now = new Date();
	if(now.getMonth() >= 6) {
		vm.chooseYear = now.getFullYear();
	} else {
		vm.chooseYear = now.getFullYear() - 1;
	}
	vm.startDate = getStartDate(vm.chooseYear);
	vm.endDate = getEndDate(vm.chooseYear);
	//更新头部信息
	EventBus.$emit('update-all-prompt-info', {
		areaName: vm.areaTitle,
		selectDate: "",
		dimensionVal: vm.analysisName
	});
}
function getTopReqParams(index1, vm) {
	var url = "/statistics/index_all",
		data = {
			index: index1,
			level: vm.level,
			area: vm.area,
			startDate: vm.startDate,
			endDate: vm.endDate
		};
	return {
		url: url,
		data: data
	};
}
function getTopTagDatas(vm) {
	var reqs = [],
		indexs = ['2', '9', '10'];
	for(i = 0; i < indexs.length; i++) {
		var item = getTopReqParams(indexs[i], vm);
		reqs.push(httpRequest.get(item.url, {
			data: item.data
		}));
	}
	Promise.all(reqs).then(function(ress) {
		for(i = 0; i < ress.length; i++) {
			var res = ress[i];
			if(res.status == 200) {
				for(key in res.data) {
					vm.topDatas[key] = res.data[key];
				}
			} else {
				console.log(res.msg);
			}
		}
	})
}
function initReqParams(vm) {
	reqParam = [{
		url: "/statistics/interval_total",
		reqType: 'get',
		data: {
			index: vm.index,
			level: vm.level,
			area: vm.area,
			startDate: vm.startDate,
			endDate: vm.endDate,
			interval: vm.selectedDateType
		}
	}, {
		url: "/statistics/lowlevel_all",
		reqType: 'get',
		data: {
			sort: 1,
			date: vm.endDate,
			level: vm.level,
			index: vm.index,
			area: vm.area
		}
	}];
	if(vm.lowLevel) {
		reqParam[1].data.lowLevel = vm.lowLevel;
	}
	return reqParam;
}
function loadData(loadArr, vm) {
	if(loadArr.indexOf(0) > -1) {
		getTopTagDatas(vm);
	}
	//获取其他请求的参数
	var reqParams = initReqParams(vm),
		reqPromise = [],
		newArr = []; //记录非顶部请求的请求数组
	for(i = 0; i < loadArr.length; i++) {
		if(loadArr[i] == 0) {
			// do nothing
		} else {
			var j = loadArr[i] - 1;
			var param = reqParams[j];
			reqPromise.push(httpRequest.get(param.url, {
				data: param.data
			}));
			newArr.push(loadArr[i]);
		}
	}
	if(reqPromise.length > 0) {
		Promise.all(reqPromise).then(function(ress) {
			var res1 = [],
			res2 = [];
			if(ress.length==2){
				res1 = ress[0] || [],
				res2 = ress[1] || [];
			}
			if(loadArr[0]==1){//点击日周月
				res1 = ress[0] || [];
			}
			if(loadArr[0]==2){//点击区、社区
				res2 = ress[0] || [];
			}
			if(res1 && res1.status == 200) {
				handleSecondPanelData(res1.data, vm);
			}
			if(res2) {
				if(res2.status == 200) {
					listHandle(res2.data, vm);
				} else {
					console.log(res2.msg);
				}
			}
		})
	}
}
function handleSecondPanelData(data, vm) {
	var xDatas = [],
		yDatas = [],
		names = [],
		colors = ['#12b7f5'],
		labels = {
			'2': '退签人数新增趋势',
			'9': '待审核数新增趋势',
			'10': '改签人数新增趋势'
		},
		index_names = {
			'index_2': '退签人数',
			'index_9': '待审核数',
			'index_10': '改签人数'
		};
	for(var p in data) {
		names.push(index_names[p]);
		var xData = _.map(data[p].data, function(o) {
			return o.range;
		});
		var yData = _.map(data[p].data, function(o) {
			return o.amount;
		});
		xDatas.push(xData);
		yDatas.push(yData);
	}
	EventBus.$emit("draw-line-chart", {
		panelName: labels[vm.index],
		quotaNames: names,
		xData: xDatas[0],
		yDatas: yDatas,
		colors: colors
	});
}
function listHandle(data, vm) {
	for(i in data) {
		var list = data[i];
		var topArr = [];
		topArr = soreRank(getKeyValueArr(list, 'amount'));
		var arr = _.map(list, function(o, index) {
			var cols = [o.name];
			cols.push(o.amount);
			return {
				rank: topArr[index],
				code: o.code,
				name: o.name,
				cols: cols
			}
		});
		var headers = {
			'2': ["排名", "退签人数"],
			'9': ["排名", "待审核数"],
			'10': ["排名", "改签人数"]
		};
		EventBus.$emit("render-area-data", {
			level: vm.level,
			area: vm.area,
			lowLevel: vm.lowLevel,
			headers: headers[vm.index],
			rows: arr
		});
	}
}

+ 15 - 0
app/statistics/js/common.js

@ -18,6 +18,21 @@ function getEndDate(chooseYear){
    }
    }
}
}
/**
 * 获取多少天前的日期
 */
function getDateBefore(days) {
	var now = new Date();
	var date = new Date(now.getTime() - days * 24 * 3600 * 1000);
	var year = date.getFullYear();
	var month = date.getMonth() + 1;
	var day = date.getDate();
	var hour = date.getHours();
	var minute = date.getMinutes();
	var second = date.getSeconds();
	return year + '-' + (month < 10 ? '0' + month : month) + '-' + (day < 10 ? '0' + day : day);
}
/*
/*
 * 获取用来排序的字段值,返回数组
 * 获取用来排序的字段值,返回数组
 * 参数: list - 列表, key - 字段的名称 
 * 参数: list - 列表, key - 字段的名称 

+ 0 - 15
app/statistics/js/renew-progress.js

@ -39,21 +39,6 @@ new Vue({
		vuedals: Vuedals.Component
		vuedals: Vuedals.Component
	},
	},
	methods: {
	methods: {
		changeTag: function(val) {
			this.index = val;
			loadData([1, 2], this);
			//存储请求所带的参数
			reqList.push({
				level: this.level,
				area: this.area,
				areaTitle: this.areaTitle,
				index: this.index,
				endDate: this.endDate,
				startDate: this.startDate,
				lowLevel: this.lowLevel,
				lowCode: this.lowCode
			})
		},
		getNewLineData: function(arg) {
		getNewLineData: function(arg) {
			this.selectedDateType = arg.dateType;
			this.selectedDateType = arg.dateType;
			loadData([1], this);
			loadData([1], this);

+ 0 - 15
app/statistics/js/sign-progress.js

@ -39,21 +39,6 @@ new Vue({
		vuedals: Vuedals.Component
		vuedals: Vuedals.Component
	},
	},
	methods: {
	methods: {
		changeTag: function(val) {
			this.index = val;
			loadData([1, 2], this);
			//存储请求所带的参数
			reqList.push({
				level: this.level,
				area: this.area,
				areaTitle: this.areaTitle,
				index: this.index,
				endDate: this.endDate,
				startDate: this.startDate,
				lowLevel: this.lowLevel,
				lowCode:this.lowCode
			})
		},
		getNewLineData: function(arg) {
		getNewLineData: function(arg) {
			this.selectedDateType = arg.dateType;
			this.selectedDateType = arg.dateType;
			loadData([1], this);
			loadData([1], this);

+ 263 - 0
app/statistics/js/two-rate-analysis.js

@ -0,0 +1,263 @@
var reqList = []; //记录请求的参数和url,用于后退时使用
Vue.use(Vuedals.default);
new Vue({
	el: "#main",
	data: {
		appname: "两率分析",
		isback: true,
		isrefresh: true,
		isfilter: false,
		isopen: false,
		//请求页面所需参数
		level: '',
		area: '',
		areaTitle: '',
		index: '18',
		endDate: '',
		lowLevel: '',
		userRole: '',
		//数据结果
		topDatas: {
			sanShiData: 0,
			sanShiRate: '0.00%',
			gaoWeiData: 0,
			gaoWeiRate: '0.00%'
		}
	},
	components: {
		vuedals: Vuedals.Component
	},
	methods: {
		changeTag: function(val) {
			this.index = val;
			loadData([1], this);
			//存储请求所带的参数
			reqList.push({
				level: this.level,
				area: this.area,
				areaTitle: this.areaTitle,
				index: this.index,
				date: this.endDate,
				endDate: this.endDate,
				lowLevel: this.lowLevel
			})
		},
		getAreaData: function(arg) {
			//如果level改变,则需要重新加载整个页面的数据,否则只需加载底部区域数据
			if(arg.level == this.level) {
				this.lowLevel = arg.lowLevel;
				loadData([1], this);
			} else {
				this.level = arg.level;
				this.lowLevel = arg.lowLevel;
				this.area = arg.area;
				loadData([0, 1], this);
			}
			//存储请求所带的参数
			reqList.push({
				level: this.level,
				area: this.area,
				areaTitle: this.areaTitle,
				index: this.index,
				endDate: this.endDate,
				lowLevel: this.lowLevel,
			})
		}
	},
	mounted: function() {
		//初始化数据
		initData(this);
		//获得顶部各tab的值
		loadData([0, 1], this); //参数组数表示请求的区域为上中下
		//存储请求所带的参数
		reqList.push({
			level: this.level,
			area: this.area,
			areaTitle: this.areaTitle,
			index: this.index,
			endDate: this.endDate,
			lowLevel: this.lowLevel
		});
		//设置监听器, 监听折线图日期变化
		var vm = this;
		//监听后退按钮的操作
		EventBus.$on("back-click", function(arg) {
			EventBus.$emit('update-statistics-time', {}); //更新统计时间
			if(reqList.length == 1) {
				history.go(-1);
			} else {
				var preInfo = reqList.pop();
				var info = reqList[reqList.length - 1];
				vm.level = info.level;
				vm.area = info.area;
				vm.areaTitle = info.areaTitle;
				vm.lowLevel = info.lowLevel;
				vm.index = info.index;
				loadData([0, 1], vm);
			}
		});
		//监听页面刷新
		EventBus.$on("refresh-click", function(arg) {
			EventBus.$emit('update-statistics-time', {}); //更新统计时间
			loadData([0, 1], vm);
		});
	}
})
function initData(vm) {
	//获得缓存中缓存的角色权限
	var userRole = window.localStorage.getItem("selectedRole");
	if(!userRole) {
		return false;
	}
	vm.userRole = JSON.parse(userRole);
	vm.level = vm.userRole.code == '350200' ? 4 : vm.userRole.code.length == 6 ? 3 : 2;
	vm.area = vm.userRole.code;
	vm.areaTitle = vm.userRole.name;
	vm.endDate = getDateBefore(1);
	//更新头部信息
	EventBus.$emit('update-all-prompt-info', {
		areaName: vm.areaTitle,
		selectDate: "",
		dimensionVal: ""
	});
}
function getTopTagDatas(vm) {
	var reqs = [],
		url = "/statistics/sszq_qwrq_info",
		data = {
			level: vm.level,
			area: vm.area,
			endDate: vm.endDate
		};
	reqs.push(httpRequest.get(url, {
		data: data
	}));
	Promise.all(reqs).then(function(ress) {
		for(i = 0; i < ress.length; i++) {
			var res = ress[i];
			if(res.status == 200) {
				var sszq = res.data.sszq;
				var gwrq = res.data.gwrq;
				vm.topDatas.sanShiData = sszq.amount + "/" + sszq.num;
				vm.topDatas.sanShiRate = sszq.rate == 0 ? '0.00%' : sszq.rate.toString().substring(0, sszq.rate.length - 2) + "%";
				vm.topDatas.gaoWeiData = gwrq.amount + "/" + gwrq.num;
				vm.topDatas.gaoWeiRate = gwrq.rate == 0 ? '0.00%' : gwrq.rate.toString().substring(0, gwrq.rate.length - 2) + "%";
				
				$('#sszql_canvas').waterbubble({
					//txt: res.signRate.rate.substring(0,res.signRate.rate.length-2) + "%",res.signRate.rate/100
					data: sszq.rate / 100,
					waterColor: '#12b7f5',
					lineWidth: 0,
					textColor: 'rgba(0, 0, 0, 0.8)',
					font: 'bold 25px arial'
				});
				
				$('#gaowei_canvas').waterbubble({
					//txt: res.signRate.rate.substring(0,res.signRate.rate.length-2) + "%",res.signRate.rate/100
					data: gwrq.rate / 100,
					waterColor: '#12b7f5',
					lineWidth: 0,
					radius: 75,
					textColor: 'rgba(0, 0, 0, 0.8)',
					font: 'bold 25px arial'
				});
			} else {
				console.log(res.msg);
			}
		}
	})
}
function initReqParams(vm) {
	reqParam = [{
		url: "/statistics/lowlevel_all",
		reqType: 'get',
		data: {
			sort: 1,
			date: vm.endDate,
			level: vm.level,
			index: vm.index,
			area: vm.area
		}
	}];
	if(vm.lowLevel) {
		reqParam[0].data.lowLevel = vm.lowLevel;
	}
	return reqParam;
}
function loadData(loadArr, vm) {
	if(loadArr.indexOf(0) > -1) {
		getTopTagDatas(vm);
	}
	if(vm.level == 2) { //社区管理员不显示团队信息
		$(".area-panel").hide();
		return false;
	}
	//获取其他请求的参数
	var reqParams = initReqParams(vm),
		reqPromise = [],
		newArr = []; //记录非顶部请求的请求数组
	for(i = 0; i < loadArr.length; i++) {
		if(loadArr[i] == 0) {
			// do nothing
		} else {
			var j = loadArr[i] - 1;
			var param = reqParams[j];
			reqPromise.push(httpRequest.get(param.url, {
				data: param.data
			}));
			newArr.push(loadArr[i]);
		}
	}
	if(reqPromise.length > 0) {
		Promise.all(reqPromise).then(function(ress) {
			var res = ress[0] || [];
			if(res && res.status == 200) {
				listHandle(res.data, vm);
			}
		})
	}
}
function listHandle(data, vm) {
	for(i in data) {
		var list = data[i];
		var topArr = [];
		topArr = soreRank(getKeyValueArr(list, 'rate'));
		var arr = _.map(list, function(o, index) {
			var cols = [o.name];
			var rate = o.rate ? parseFloat(o.rate).toFixed(2) + "%" : '0.00%';
			cols.push(rate);
			return {
				rank: topArr[index],
				code: o.code,
				name: o.name,
				cols: cols
			}
		});
		var headers = {
			'18': ["排名", "三师转签率"],
			'19': ["排名", "高危人数签约率"]
		};
		EventBus.$emit("render-area-data", {
			level: vm.level,
			area: vm.area,
			lowLevel: vm.lowLevel,
			headers: headers[vm.index],
			rows: arr
		});
	}
}

+ 0 - 3
app/statistics/sign-progress.html

@ -46,8 +46,6 @@
					</div>
					</div>
				</div>
				</div>
			</div>
			</div>
			<!-- 折线图 -->
			<line-chart v-on:getlinedata="getNewLineData" class="mlr8"></line-chart>
			<!-- 底部区域图 -->
			<!-- 底部区域图 -->
			<area-data-panel class="mt20 mlr8" v-on:getnewdata="getAreaData"></area-data-panel>
			<area-data-panel class="mt20 mlr8" v-on:getnewdata="getAreaData"></area-data-panel>
			<!--模态框组件-->
			<!--模态框组件-->
@ -67,7 +65,6 @@
		<script src="../../component/common/vuedals.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/common/vuedals.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/header-tab.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/header-tab.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/header-prompt.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/header-prompt.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/line-chart.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/area-data-panel.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/area-data-panel.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/team-info.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/team-info.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/sign-progress-filter.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/sign-progress-filter.js" type="text/javascript" charset="utf-8"></script>

+ 40 - 29
app/statistics/two-rate-analysis.html

@ -3,7 +3,7 @@
	<head>
	<head>
		<meta charset="UTF-8">
		<meta charset="UTF-8">
		<title>签约进展</title>
		<title>两率分析</title>
		<meta name="author" content="yihu.com" />
		<meta name="author" content="yihu.com" />
		<meta name="format-detection" content="telephone=no" />
		<meta name="format-detection" content="telephone=no" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0" />
@ -19,35 +19,48 @@
		<div id="main">
		<div id="main">
			<header-tab :appname="appname" :isback="isback" :isrefresh="isrefresh" :isfilter="isfilter" :isopen="isopen"></header-tab>
			<header-tab :appname="appname" :isback="isback" :isrefresh="isrefresh" :isfilter="isfilter" :isopen="isopen"></header-tab>
			<header-prompt></header-prompt>
			<header-prompt></header-prompt>
			<!-- 饼图 -->
			<div class="mt10 mb30">
				<div class="c-row">
					<div class="c-50 c-t-center c-position-r">
						<div class="div-radius-panel">
							<div class="c-f16 c-12b7f5 mt15">{{signRateData.signRateText}}</div>
							<div class="c-f14 c-666">签约率</div>
			<!--市管、区管-->
			<div class="clearfix" v-show="level>2">
				<ul class="l-banner">
					<li class="active" style="width: calc(100% / 2);">
						<div class="tag" :class="{'active': index==18}" @click="changeTag(18)">
							<div id="index_18" class="c-f18">{{topDatas.sanShiRate}}</div>
							<div class="c-f18 mt5">{{topDatas.sanShiData}}</div>
							<div class="mt5 c-f14 l-name">三师转签率</div>
						</div>
						</div>
						<div id="signMain" class="c-100 height-120"></div>
						<div class="c-f12 c-999 div-data-value">
							<span class="c-f12 c-12b7f5 qianyuelv">{{signRateData.signAmount}}</span>/
							<span class="c-f12 c-333 qianyuezong">{{signRateData.signRateAll}}</span>
					</li>
					<li style="width: calc(100% / 2);">
						<div class="tag" :class="{'active': index==19}" @click="changeTag(19)">
							<div id="index_19" class="c-f18">{{topDatas.gaoWeiRate}}</div>
							<div class="c-f18 mt5">{{topDatas.gaoWeiData}}</div>
							<div class="mt5 c-f14 l-name">高危人数签约率</div>
						</div>
						</div>
					</li>
				</ul>
			</div>
			<!--社区管-->
			<div class="clearfix" style="background: #F3F3F3;" v-show="level==2">
				<div class="mod mod-fuwu mb30 c-border-b">
					<div class="mod-hd c-border-t">
						<i class="icon-cyc sszql"></i>&emsp;三师转签率
					</div>
					</div>
					<div class="c-50 c-t-center c-position-r">
						<div class="div-radius-panel">
							<div class="c-f16 c-12b7f5 mt15">{{signRateData.completeRateText}}</div>
							<div class="c-f14 c-666">完成率</div>
						</div>
						<div id="completeMain" class="c-100" style="height: 120px;"></div>
						<div class="c-f12 c-999 div-data-value">
							<span class="c-f12 c-12b7f5">{{signRateData.completeAmount}}</span>/
							<span class="c-f12 c-333">{{signRateData.completeRateAll}}</span>
						</div>
					<div class="div-ssqql">
						<p class="f-fs12 p-sanshilv">{{topDatas.sanShiRate}}</p>
						<p class="p-sanshicount f-fs12">{{topDatas.sanShiData}}</p>
						<canvas id="sszql_canvas"></canvas>
					</div>
				</div>
				<div class="mod mod-fuwu c-border-b">
					<div class="mod-hd c-border-t" style="border-bottom: 0;">
						<i class="icon-cyc gwrq"></i>&emsp;高危人群签约率
					</div>
					<div class="div-ssqql c-border-t">
						<p class="f-fs12 p-gaoweilv">{{topDatas.gaoWeiRate}}</p>
						<p class="p-gaoweicount f-fs12">{{topDatas.gaoWeiData}}</p>
						<canvas id="gaowei_canvas"></canvas>
					</div>
					</div>
				</div>
				</div>
			</div>
			</div>
			<!-- 折线图 -->
			<line-chart v-on:getlinedata="getNewLineData" class="mlr8"></line-chart>
			<!-- 底部区域图 -->
			<!-- 底部区域图 -->
			<area-data-panel class="mt20 mlr8" v-on:getnewdata="getAreaData"></area-data-panel>
			<area-data-panel class="mt20 mlr8" v-on:getnewdata="getAreaData"></area-data-panel>
			<!--模态框组件-->
			<!--模态框组件-->
@ -59,8 +72,6 @@
		<script src="../../js/es6-promise.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../js/es6-promise.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../js/underscore.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../js/underscore.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../js/util.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../js/util.js" type="text/javascript" charset="utf-8"></script>
		<!--<script src="../../plugins/echarts/3.8.5/echarts.min.js" type="text/javascript" charset="utf-8"></script>-->
		<script src="js/echarts.min.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../api/http-request.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../api/http-request.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../api/statistics-api.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../api/statistics-api.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/common/event-bus.js"></script>
		<script src="../../component/common/event-bus.js"></script>
@ -68,11 +79,11 @@
		<script src="../../component/statistics/header-tab.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/header-tab.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/header-prompt.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/header-prompt.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/line-chart.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/line-chart.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/area-data-panel.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/area-data-panel2.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/team-info.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/team-info.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../component/statistics/sign-progress-filter.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/common.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/common.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/sign-progress.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../js/waterbubble.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/two-rate-analysis.js" type="text/javascript" charset="utf-8"></script>
	</body>
	</body>
</html>
</html>

+ 83 - 0
component/statistics/area-data-panel2.js

@ -0,0 +1,83 @@
(function(){
    Vue.component('area-data-panel',{
        template: '<div class="area-panel">\
                <div class="area-tab-panel">\
                    <div v-show="level==4" class="area-tab" :class="{\'active\': level==4 && (!lowLevel || lowLevel==3)}" @click="getLowCodeData(3)"><span>各区</span></div>\
                    <div v-show="level >= 3" class="area-tab" :class="{\'active\': (level==3 && lowLevel!=1) || lowLevel==2}" @click="getLowCodeData(2)"><span>社区</span></div>\
                </div>\
                <table class="bottom-list-table mb20" id="listTable">\
                    <thead><tr>\
                        <th v-for="th in headers">{{th}}</th>\
                        <th v-show="level>2 && lowLevel != 1" width="20"></th>\
                    </tr></thead>\
                    <tbody>\
                        <tr v-for="row in rows" class="data-row" @click="getLowLeverData(row)">\
                            <td v-for="(col, index) in row.cols" :class="{\'area-name\': index == 0}">\
                                <div v-if="index==0" class="ranking" :class="{\'ranking1\': row.rank==1, \'ranking2\': row.rank==2, \'ranking3\': row.rank==3}">{{row.rank}}</div>\
                                <div v-if="index==0" class="ui-col-1 c-nowrap-multi">{{col}}</div>\
                                <span v-else>{{col}}</span>\
                            </td>\
                            <td v-show="level>3"><i class="fa fa-angle-right"></i></td>\
                        </tr>\
                    </tbody>\
                </table>\
            </div>',
        props:[],
        data: function(){
            return {
                level: '',
                lowLevel: '',
                area: '',
                headers: [],
                rows: []
            }
        },
        mounted: function(){
            var vm = this;
            EventBus.$on("render-area-data", function(arg){
                vm.level = arg.level;
                vm.lowLevel = arg.lowLevel;
                vm.area = arg.area;
                vm.headers = arg.headers;
                vm.rows = arg.rows;
            })
        },
        methods: {
            getLowLeverData: function(row){
                if(this.level > 3 && this.lowLevel != 1){
                    //跳转去下一级数据
                    if(this.lowLevel && (this.level - this.lowLevel) >= 2){
                        //从次级tab的内容查看再下一级的数据
                        this.level = this.level - 2;
                        this.lowLevel --;
                    }else{
                        this.level --;
                    }
                    this.area = row.code;
                    this.areaTitle = row.name;
                    //触发组件监听事件,去父页面请求新的数据
                    this.$emit("getnewdata", {
                        level: this.level,
                        area: this.area,
                        areaTitle: this.areaTitle,
                        lowLevel: this.lowLevel,
                    });
                }
            },
            getLowCodeData: function(code){
                if(code == 3){
                    this.lowLevel = '';
                }else{
                    this.lowLevel = code;
                }
                
                //触发组件监听事件,去父页面请求新的数据
                this.$emit("getnewdata", {
                    level: this.level,
                    area: this.area,
                    lowLevel: this.lowLevel
                });
            }
        }
    });
})()

BIN
images/gaoweirenqun.png


BIN
images/snashi_icon.png


+ 168 - 0
js/waterbubble.js

@ -0,0 +1,168 @@
/**
* 水球图 wataerbubble
* @author fiona23 (fiona_fanmy@163.com)
*/
(function($) {
    $.fn.waterbubble = function(options) {
            var config = $.extend({
                radius: 100,
                lineWidth: undefined,
                data: 0.5,
                waterColor: 'rgba(25, 139, 201, 1)',
                textColor: 'rgba(06, 85, 128, 0.8)',
                font: '',
                wave: true,
                txt: undefined,
                animation: true
            }, options);
            var canvas = this[0];
//          config.lineWidth = config.lineWidth ? config.lineWidth : config.radius/24;
			config.lineWidth = options.lineWidth;
            var waterbubble = new Waterbubble(canvas, config);
            return this;
        }
        
        function Waterbubble (canvas, config) {
            this.refresh(canvas, config);
        }
        Waterbubble.prototype = {
            refresh: function (canvas, config) {
                canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height)
                this._init(canvas, config)
            },
            _init: function (canvas, config){
                var radius = config.radius;
                var lineWidth = config.lineWidth;
                canvas.width = radius*2 + lineWidth;
                canvas.height = radius*2 + lineWidth;
                this._buildShape(canvas, config);
            },
            _buildShape: function (canvas, config) {
                var ctx = canvas.getContext('2d');
                var gap = config.lineWidth*2;
                //raidus of water
                var r = config.radius - gap;
                var data = config.data;
                var lineWidth = config.lineWidth
                var waterColor = config.waterColor;
                var textColor = config.textColor;
                var font = config.font;
                var wave = config.wave
                // //the center of circle
                var x = config.radius + lineWidth/2;
                var y = config.radius + lineWidth/2;
                ctx.beginPath();
                
                ctx.arc(x, y, config.radius, 0, Math.PI*2);
                ctx.lineWidth = lineWidth;
                ctx.strokeStyle = waterColor;
                ctx.stroke();
                //if config animation true
                if (config.animation) {
                    this._animate(ctx, r, data, lineWidth, waterColor, x, y, wave)
                } else {
                    this._fillWater(ctx, r, data, lineWidth, waterColor, x, y, wave);
                }
                
                if (typeof config.txt == 'string'){
                    this._drawText(ctx, textColor, font, config.radius, data, x, y, config.txt);
                }
                return;
            },
            _fillWater: function (ctx, r, data, lineWidth, waterColor, x, y, wave) {
                ctx.beginPath();
                ctx.globalCompositeOperation = 'destination-over';
                //start co-ordinates
                var sy = r*2*(1 - data) + (y - r);
                var sx = x - Math.sqrt((r)*(r) - (y - sy)*(y - sy));
                //middle co-ordinates
                var mx = x;
                var my = sy;
                //end co-ordinates
                var ex = 2*mx - sx;
                var ey = sy;
                var extent; //extent
                if (data > 0.9 || data < 0.1 || !wave) {
                    extent = sy
                } else{
                    extent = sy - (mx -sx)/4
                }
                ctx.beginPath();
                
                ctx.moveTo(sx, sy)
                ctx.quadraticCurveTo((sx + mx)/2, extent, mx, my);
                ctx.quadraticCurveTo((mx + ex)/2, 2*sy - extent, ex, ey);
                var startAngle = -Math.asin((x - sy)/r)
                var endAngle = Math.PI - startAngle;
                ctx.arc(x, y, r, startAngle, endAngle, false)
                ctx.fillStyle = waterColor;
                ctx.fill()
            },
            _drawText: function (ctx, textColor, font, radius, data, x, y, txt) {
                ctx.globalCompositeOperation = 'source-over';
                var size = font ? font.replace( /\D+/g, '') : 0.4*radius;
                ctx.font = font ? font : 'bold ' + size + 'px Microsoft Yahei';
                txt = txt.length ? txt : data*100 + '%'
                var sy = y + size/2;
                var sx = x - ctx.measureText(txt).width/2
                ctx.fillStyle = textColor;
                ctx.fillText(txt, sx, sy)
            },
            _animate: function (ctx, r, data, lineWidth, waterColor, x, y, wave) {
                var datanow = {
                    value: 0
                };
                var requestAnimationFrame = window.requestAnimationFrame || window.msRequestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function (func) {
                    setTimeout(func, 16);
                };
                var self = this;
                var update = function () {
                    if (datanow.value < data - 0.01) {
                        datanow.value += (data - datanow.value)/15
                        self._runing = true;
                    } else {
                        self._runing = false;
                    }
                }
                var step = function () {
                    self._fillWater(ctx, r, datanow.value, lineWidth, waterColor, x, y, wave);
                    update();
                    if (self._runing) {
                        requestAnimationFrame(step);
                    }
                }
                step(ctx, r, datanow, lineWidth, waterColor, x, y, wave)
            }
        }
}(jQuery));