Ver código fonte

Merge branch 'dev'

347617796@qq.com 3 anos atrás
pai
commit
255bc34c6e
48 arquivos alterados com 2560 adições e 1690 exclusões
  1. 676 195
      package-lock.json
  2. 5 5
      package.json
  3. 3 3
      src/api/websocket.js
  4. 1 1
      src/assets/css/reset.css
  5. 45 24
      src/components/EmployeeSelector.vue
  6. 1 1
      src/components/UserImage.vue
  7. 10 12
      src/components/applicationIntegrationPopup.vue
  8. 6 9
      src/components/bonusPointsPopup.vue
  9. 4 4
      src/home.vue
  10. 46 21
      src/index.vue
  11. 2 2
      src/init.vue
  12. 5 2
      src/main.js
  13. 3 4
      src/router/index.js
  14. 0 4
      src/store/getters.js
  15. 16 15
      src/store/index.js
  16. 0 25
      src/store/modules/user.js
  17. 2 2
      src/views/abPoint/apply_list.vue
  18. 3 5
      src/views/abPoint/award_punish.vue
  19. 1 1
      src/views/common/rewardTask.vue
  20. 13 9
      src/views/common/rewardTaskAmend.vue
  21. 1 1
      src/views/common/temporaryTask.vue
  22. 22 16
      src/views/common/temporaryTaskAmend.vue
  23. 2 2
      src/views/ranking/balanceA.vue
  24. 0 9
      src/views/ranking/department_statistics.vue
  25. 3 3
      src/views/ranking/dept_rank.vue
  26. 3 1
      src/views/ranking/log_rank.vue
  27. 1 1
      src/views/ranking/manager_statistics.vue
  28. 3 1
      src/views/ranking/task_rank.vue
  29. 2 2
      src/views/ranking/total_rank.vue
  30. 16 28
      src/views/set/framework.vue
  31. 0 1
      src/views/set/initialPoint.vue
  32. 2 2
      src/views/set/jurisdiction.vue
  33. 4 3
      src/views/set/rule.vue
  34. 16 2
      src/views/set/systemLayout.vue
  35. 2 2
      src/views/set/voluntarilyPoint.vue
  36. 1 2
      src/views/task/allTask.vue
  37. 3 5
      src/views/task/myExamine.vue
  38. 1 1
      src/views/task/my_issue.vue
  39. 1 2
      src/views/task/my_task.vue
  40. 443 215
      src/views/welfare/conversion.vue
  41. 6 2
      src/views/welfare/flBox.vue
  42. 480 150
      src/views/welfare/flManagement.vue
  43. 175 174
      src/views/welfare/operatingRecord.vue
  44. 434 691
      src/views/welfare/prize.vue
  45. 1 1
      src/views/workbench/alreadySp.vue
  46. 3 7
      src/views/workbench/approval_batch.vue
  47. 1 1
      src/views/workbench/approval_list.vue
  48. 92 21
      vue.config.js

Diferenças do arquivo suprimidas por serem muito extensas
+ 676 - 195
package-lock.json


+ 5 - 5
package.json

@@ -7,8 +7,7 @@
     "build": "vue-cli-service build",
     "lint": "vue-cli-service lint",
     "devbuild": "vue-cli-service build --mode development",
-    "prebuild": "vue-cli-service build --mode production",
-    "analyzer": "cross-env use_analyzer=true npm run serve"
+    "prebuild": "vue-cli-service build --mode production --report"
   },
   "dependencies": {
     "@wangeditor/editor": "^0.12.3",
@@ -21,6 +20,7 @@
     "echarts": "^4.9.0",
     "element-ui": "^2.13.2",
     "file-saver": "^2.0.5",
+    "imagemin-pngquant": "^9.0.2",
     "moment": "^2.29.0",
     "nprogress": "^0.2.0",
     "qrcodejs2": "0.0.2",
@@ -38,14 +38,14 @@
     "@vue/cli-plugin-vuex": "~4.4.0",
     "@vue/cli-service": "~4.4.0",
     "babel-eslint": "^10.1.0",
-    "compression-webpack-plugin": "^1.1.12",
     "eslint": "^6.7.2",
     "eslint-plugin-vue": "^6.2.2",
+    "image-webpack-loader": "^8.0.1",
     "sass": "^1.26.5",
     "sass-loader": "^8.0.2",
     "script-loader": "^0.7.2",
     "svg-sprite-loader": "^5.2.1",
-    "vue-template-compiler": "^2.6.11",
-    "webpack-bundle-analyzer": "^4.3.0"
+    "uglifyjs-webpack-plugin": "^2.2.0",
+    "vue-template-compiler": "^2.6.11"
   }
 }

+ 3 - 3
src/api/websocket.js

@@ -1,4 +1,4 @@
-// let wsurl = 'ws://113.99.163.45:12358'
+
 let wsurl='wss://' + process.env.VUE_APP_WEBSCOKET + '/ws/';
 let ws = null
 let weboscket_callback = null
@@ -72,10 +72,10 @@ let sendData = (data, callback) => {
 	}
 	if(ws){//  判断 websocket 的状态
 		if (ws.readyState === ws.OPEN) {// 已经打开,可以直接发送
-			console.log("1")
+			// console.log("1")
 			ws.send(data)
 		} else if (ws.readyState === ws.CONNECTING) {// 正在开启状态中,则 1 秒后重新发送
-			console.log("2")
+			// console.log("2")
 			setTimeout(() => {
 				ws.send(data)
 			}, 2000)

+ 1 - 1
src/assets/css/reset.css

@@ -221,7 +221,7 @@ table { border-collapse:collapse; border-spacing:0; }
 .all{
 	background-color: #fff;
 	border-radius: 5px;
-	min-height:calc(100vh - 184px);
+	min-height:calc(100vh - 120px);
 	min-width: 800px;
 	position: relative;
 }

+ 45 - 24
src/components/EmployeeSelector.vue

@@ -24,11 +24,7 @@
 						<div class="choose_left">
 							<div class="persons_box" v-if="list.length > 0">
 								<div class="employee_cell_a"  v-for="(item, index) in list" :key="index">
-									<div
-										class="employee_cell flex-box flex-v-ce"
-										v-if="can_select_employee && item.name.indexOf(keyword) >= 0"
-										@click.prevent.stop="select_employee(item)"
-									>
+									<div class="employee_cell flex-box flex-v-ce" v-show="can_select_employee" @click.prevent.stop="select_employee(item)">
 										<div class="employee_checkbox"><el-checkbox v-model="item.checked"></el-checkbox></div>
 										<img :src="item.img_url" width="30" height="30" class="imgUrl" v-if="item.img_url">
 										<div class="imgUrl" v-else style="background: #238DFA;color: #fff;">{{item.name.substring(item.name.length-2)}}</div>
@@ -172,7 +168,8 @@ export default {
 			checked: false, //是否全选
 			indeterminate: false,
 			not_user: user_no_select,
-			all_list: []
+			all_list: [],
+			searchBox: [], //用于搜索的全部人员
 		};
 	},
 	watch: {
@@ -203,32 +200,50 @@ export default {
 		},
 		//搜索
 		keyword(val) {
-			this.checked = false;
+			this.list = this.searchBox.filter(item => item.name.includes(this.keyword));
+			if (!val) {
+			  this.checked = false;
+			}
 		}
 	},
 	methods: {
 		//全选择
 		checkedChange(val) {
 			if (val) {
-				for (let i in this.list) {
-					this.$set(this.list[i], 'checked', true);
-				}
 				this.$nextTick(() => {
-					let employeeSelectedList = JSON.parse(JSON.stringify(this.employee_selected_list));
-					let employeeSelectedIds = [],
-						total = 0;
-					employeeSelectedList.forEach(element => {
-						employeeSelectedIds.push(element.id);
-					});
-					for (const i in this.list) {
-						if (employeeSelectedIds.includes(this.list[i].id)) {
-							total += 1;
-						} else {
-							this.employee_selected_list.push(this.list[i]);
-						}
-					}
-					this.list.length == total ? (this.indeterminate = true) : (this.indeterminate = false);
+				  let employeeSelectedList = JSON.parse(JSON.stringify(this.employee_selected_list)); //获取选择的人员
+				  
+				  let employeeSelectedIds = [],total = 0;
+				  employeeSelectedList.forEach(element => {
+				    employeeSelectedIds.push(element.id);
+				  });
+				  for (let i in this.list) {
+				    this.$set(this.list[i], 'checked', true);
+				    if (!employeeSelectedIds.includes(this.list[i].id)) {
+				      //去除已经选择的人员
+				      this.employee_selected_list.push(this.list[i]);
+				    }
+				  }
 				});
+				
+				// for (let i in this.list) {
+				// 	this.$set(this.list[i], 'checked', true);
+				// }
+				// this.$nextTick(() => {
+				// 	let employeeSelectedList = JSON.parse(JSON.stringify(this.employee_selected_list));
+				// 	let employeeSelectedIds = [],total = 0;
+				// 	employeeSelectedList.forEach(element => {
+				// 		employeeSelectedIds.push(element.id);
+				// 	});
+				// 	for (const i in this.list) {
+				// 		if (employeeSelectedIds.includes(this.list[i].id)) {
+				// 			total += 1;
+				// 		} else {
+				// 			this.employee_selected_list.push(this.list[i]);
+				// 		}
+				// 	}
+				// 	this.list.length == total ? (this.indeterminate = true) : (this.indeterminate = false);
+				// });
 			} else {
 				this.clear_data();
 			}
@@ -375,6 +390,7 @@ export default {
 			let list = this.employee_list;
 			if (userlist) {
 				list = [...userlist].filter(x => [...list].some(y => y.id === x.id));
+				employee_selected_list=[...userlist].filter(x => [...employee_selected_list].some(y => y.id === x.id));
 			}
 			list.map(item => {
 				item['checked'] = false;
@@ -385,7 +401,9 @@ export default {
 					}
 				}
 			});
+			this.employee_selected_list = employee_selected_list;
 			this.list = list;
+			this.searchBox=list;
 			this.table_loading = false;
 		},
 		//获取员工详情
@@ -430,7 +448,10 @@ export default {
 							}
 						}
 					});
+					// employee_selected_list=[...employee].filter(x => [...employee_selected_list].some(y => y.id === x.id));
+					// that.employee_selected_list = employee_selected_list;
 					that.list = userAll;
+					this.searchBox=userAll;
 				})
 				.finally(() => {
 					that.table_loading = false;

+ 1 - 1
src/components/UserImage.vue

@@ -44,7 +44,7 @@
       return {
         imgUrl: "",
         name: "",
-		employeeMap:JSON.parse(localStorage.getItem("userList"))
+		employeeMap:this.$getCache("userList")
       }
     },
 	watch:{

+ 10 - 12
src/components/applicationIntegrationPopup.vue

@@ -245,7 +245,6 @@
 import moment from 'moment';
 import EmployeeSelector from '@/components/EmployeeSelector';
 import uploadOss from '@/components/upload';
-import {setCache,getCache,removeCache} from '@/api/auth';
 export default {
 	name: 'applicationIntegration',
 	// 数据
@@ -358,10 +357,10 @@ export default {
 			this.dialogData.items[0].approvalName = this.LocalValObj.name;
 		}
 		if(this.isBreak){
-			let data=getCache('apply_list');
+			let data=this.$getCache('apply_list');
 			data.forEach(item=>{
-				item.name=getCache('userList')[item.employee_id]?getCache('userList')[item.employee_id].name:'--';
-				item.reviewer_name=getCache('userList')[item.reviewer_id]?getCache('userList')[item.reviewer_id].name:'--';
+				item.name=this.$getCache('userList')[item.employee_id]?this.$getCache('userList')[item.employee_id].name:'--';
+				item.reviewer_name=this.$getCache('userList')[item.reviewer_id]?this.$getCache('userList')[item.reviewer_id].name:'--';
 			})
 			this.breakList=data;
 			this.isShowBreak=true;
@@ -385,13 +384,13 @@ export default {
 		colseBreak(){
 			this.isShowBreak = false;
 			this.breakList=[];
-			removeCache('apply_list');
+			this.$removeCache('apply_list');
 			this.closeDialog();
 			this.closeDialog2();
 		},
 		// 提交缓存申请
 		submitBreak(){
-			removeCache('apply_list');
+			this.$removeCache('apply_list');
 			this.resultList=JSON.parse(JSON.stringify(this.breakList));
 			this.resultIndex=0;
 			this.percentage=0;
@@ -410,17 +409,16 @@ export default {
 						if(data.employee_detail.superior_list && data.employee_detail.superior_id != 0){
 							obj = data.employee_detail.superior_list.filter(x => x.id == data.employee_detail.superior_id)[0];
 							if(obj.id == this.user_info.id){
-								obj = localStorage.getItem(id)
+								obj = this.$getCache(id)
 							}
 						}else{
-							obj = localStorage.getItem(id);
+							obj = this.$getCache(id);
 						}
 					}
 				}).finally(_ =>{
 					resolve(obj)
 				})
 			})
-			// var obj = localStorage.getItem(id);
 		},
 		submitMembers(name) {
 			this.$refs[name][0].confirm(); //调用组件的confirm();
@@ -720,14 +718,14 @@ export default {
 				.finally(() => {
 					this.btn_loading = false;
 					data.items.forEach(element => {
-						localStorage.setItem(element.employee_id, JSON.stringify({ id: element.reviewer_id, name: element.approvalName }));
+						this.$setCache(element.employee_id,{ id: element.reviewer_id, name: element.approvalName });
 					});
 				});
 		},
 		webSocket(data){
 			data.items.forEach(item=>{
 				item.type='point_apply';
-				localStorage.setItem(item.employee_id, JSON.stringify({ id: item.reviewer_id, name: item.approvalName }));
+				this.$setCache(item.employee_id,{ id: item.reviewer_id, name: item.approvalName });
 			})
 			this.resultList=data.items;
 			this.resultIndex=0;
@@ -761,7 +759,7 @@ export default {
 			if(e.type=='break'){
 				let wsData=this.resultList;
 				this.errorMsg=e.msg
-				setCache('apply_list',wsData.slice(this.resultIndex,wsData.length));
+				this.$setCache('apply_list',wsData.slice(this.resultIndex,wsData.length));
 				this.isShowError2 = true;
 			}
 			// 连接不上

+ 6 - 9
src/components/bonusPointsPopup.vue

@@ -266,8 +266,6 @@
 				</span>
 			</div>
 		</el-dialog>
-		
-		
 	</div>
 </template>
 
@@ -275,7 +273,6 @@
 import moment from 'moment';
 import EmployeeSelector from '@/components/EmployeeSelector.vue';
 import upload from '@/components/upload';
-import {setCache,getCache,removeCache} from '@/api/auth';
 export default {
 	name: 'bonusPointsForm',
 	// 数据
@@ -392,10 +389,10 @@ export default {
 	components: { EmployeeSelector, upload },
 	watch: {
 		isBreak(){
-			let data=getCache('award_punish').obj;
+			let data=this.$getCache('award_punish').obj;
 			data.forEach(item=>{
-				item.name=getCache('userList')[item.employee_id]?getCache('userList')[item.employee_id].name:'--';
-				item.reviewer_name=getCache('userList')[item.reviewer_id]?getCache('userList')[item.reviewer_id].name:'--';
+				item.name=this.$getCache('userList')[item.employee_id]?this.$getCache('userList')[item.employee_id].name:'--';
+				item.reviewer_name=this.$getCache('userList')[item.reviewer_id]?this.$getCache('userList')[item.reviewer_id].name:'--';
 			})
 			this.breakList=data;
 			this.isShowBreak=true;
@@ -436,13 +433,13 @@ export default {
 		colseBreak(){
 			this.isShowBreak = false;
 			this.breakList=[];
-			removeCache('award_punish');
+			this.$removeCache('award_punish');
 			this.$emit('update:refresh',this.$moment().format().valueOf());
 			this.closePopup();
 		},
 		// 提交缓存奖扣
 		submitBreak(){
-			removeCache('award_punish');
+			this.$removeCache('award_punish');
 			this.resultList=JSON.parse(JSON.stringify(this.breakList));
 			this.resultIndex=0;
 			this.percentage=0;
@@ -872,7 +869,7 @@ export default {
 					type:this.integralType,
 					obj:wsData.slice(this.resultIndex,wsData.length)
 				}
-				setCache('award_punish',data);
+				this.$setCache('award_punish',data);
 				this.isShowError2 = true;
 			}
 			// 连接不上

+ 4 - 4
src/home.vue

@@ -665,13 +665,13 @@ export default {
 				.then(res => {
 					if (res.data.code == 1) {
 						let list = res.data.data.list[0];
-						if (localStorage.getItem('noticeId')) {
-							if (localStorage.getItem('noticeId') != list.id) {
+						if (this.$getCache('noticeId')) {
+							if (this.$getCache('noticeId') != list.id) {
 								this.updateVisible = true;
-								localStorage.setItem('noticeId', list.id);
+								this.$setCache('noticeId', list.id);
 							}
 						} else {
-							localStorage.setItem('noticeId', list.id);
+							this.$setCache('noticeId', list.id);
 							this.updateVisible = true;
 						}
 						this.announcement = list;

+ 46 - 21
src/index.vue

@@ -45,17 +45,32 @@
 				<el-menu :default-active="defaultActive" class="el-menu-vertical-demo" :router="true" @select="activeRouter" :unique-opened="true">
 					<template v-for="(item, index) in routers">
 						<div v-if="item.children.length != 0" :key="index">
-							<el-submenu :index="index.toString()" :key="index" v-if="item.children.length >= 1 && item.name != '首页'">
-								<template slot="title">
-									<span class="iconfont titleIcon" :class="item.icon" style="font-size: 20px;"></span>
-									<span style="margin-left: 5px;">{{ item.name }}</span>
+							<template v-if="item.children.length >= 1 && item.name != '首页'">
+								<template v-if="item.name=='福利'">
+									<el-submenu :index="index.toString()" :key="index" v-if="returnConfig">
+										<template slot="title">
+											<span class="iconfont titleIcon" :class="item.icon" style="font-size: 20px;"></span>
+											<span style="margin-left: 5px;">{{ item.name }}</span>
+										</template>
+										<template v-for="(item2, index2) in item.children">
+											<el-menu-item :index="returnIndex(index, index2)" :ref="item2.path" :route="item2.path" :key="index2" class="font-flex-word">
+												<span slot="title" style="margin-left: 10px;width:120px">{{ item2.name }}</span>
+											</el-menu-item>
+										</template>
+									</el-submenu>
 								</template>
-								<template v-for="(item2, index2) in item.children">
-									<el-menu-item :index="returnIndex(index, index2)" :ref="item2.path" :route="item2.path" :key="index2" class="font-flex-word">
-										<span slot="title" style="margin-left: 10px;width:120px">{{ item2.name }}</span>
-									</el-menu-item>
-								</template>
-							</el-submenu>
+								<el-submenu :index="index.toString()" :key="index" v-else>
+									<template slot="title">
+										<span class="iconfont titleIcon" :class="item.icon" style="font-size: 20px;"></span>
+										<span style="margin-left: 5px;">{{ item.name }}</span>
+									</template>
+									<template v-for="(item2, index2) in item.children">
+										<el-menu-item :index="returnIndex(index, index2)" :ref="item2.path" :route="item2.path" :key="index2" class="font-flex-word">
+											<span slot="title" style="margin-left: 10px;width:120px">{{ item2.name }}</span>
+										</el-menu-item>
+									</template>
+								</el-submenu>
+							</template>
 							<el-menu-item :index="returnIndex(index, index)" :route="item.children[0].path" :ref="item.children[0].path" v-else>
 								<span class="iconfont titleIcon" :class="item.icon" style="font-size: 20px;"></span>
 								<span slot="title" style="margin-left: 5px;">{{ item.children[0].name }}</span>
@@ -77,7 +92,7 @@
 			<div class="fontColorF" style="text-align: center;margin-top: 15px;font-size: 18px;">手机钉钉扫码,付费升级</div>
 		</el-dialog>
 		<el-dialog title="设置向导" :visible.sync="wn_show" width="600px">
-			<div>
+			<div v-if="routers_one[0]">
 				<div class="wn-title fontColorF">三步轻松搭建积分管理体系:定人员、分责权、建制度</div>
 				<div class="flex-box flex-v-ce wn-box">
 					<div class="flex-1 flex-box-v flex-v-ce" @click="openView(0)">
@@ -94,7 +109,7 @@
 					</div>
 				</div>
 			</div>
-			<div>
+			<div v-if="routers_one[0]">
 				<div class="wn-title fontColorF">更有效地做好积分激励和认可,你还可以设置以下3项</div>
 				<div class="flex-box flex-v-ce wn-box">
 					<div class="flex-1 flex-box-v flex-v-ce" @click="openView(3)">
@@ -143,18 +158,24 @@ export default {
 					item.children.map((item2, index2) => {
 						if (item2.path == str) {
 							this.defaultActive = index + '-' + index2;
-							localStorage.setItem('path', index + '-' + index2);
+							this.$setCache('path', index + '-' + index2);
 						}
 					});
 				}
 			});
-			if(localStorage.getItem('inform')){
+			if(this.$getCache('inform')){
 				this.getInform()
 				removeCache('inform')
 			}
 		}
 	},
+	computed:{
+		returnConfig(){
+			return this.$store.getters.config.shop_status==1;
+		}
+	},
 	created() {
+		this.cheakAx();
 		this.initRouter();
 		this.getEmployee()//缓存人员列表
 		this.getInform();
@@ -164,19 +185,18 @@ export default {
 		this.getInfo();
 		var url = window.location.href;
 		var str = this.GetRequest(url).corpId || '123';
-		// var rUrl = this.GetRequest(url).url || '';
 		var corpId = str.split('#')[0];
 		if (corpId) {
 			this.getCorp(corpId);
 		}
 		this.$nextTick(function() {
 			if (!this.$authoritys('employee') && !this.$authoritys('dept_manager')) {
-				if (localStorage.getItem('wn_show')) {
+				if (this.$getCache('wn_show')) {
 					this.wn_show = false;
 					this.isShowWn = false;
 				} else {
 					this.wn_show = true;
-					localStorage.setItem('wn_show', 'true');
+					this.$setCache('wn_show', 'true');
 				}
 			}
 		});
@@ -211,19 +231,24 @@ export default {
 				}
 			});
 		},
+		async cheakAx(name) {
+		   await this.$axios('get', '/api/integral/site/config').then(res => {
+				this.$store.dispatch('setConfig', res.data.data);
+			})
+		},
 		initRouter() {
 			this.routers = [
 				{ name: '首页', children: this.returnRoutersArr('home'), icon: 'icon-shouye' },
 				{ name: 'A/B分', children: this.returnRoutersArr('abPoint'), icon: 'icon-PC_gongzuotai_ABfen' },
 				{ name: '任务', children: this.returnRoutersArr('task'), icon: 'icon-kaoqin_kaoqinyuebaobiao' },
 				{ name: '统计', children: this.returnRoutersArr('ranking'), icon: 'icon-dingdingPC_tongji1' },
-				// { name: '福利', children: this.returnRoutersArr('welfare'), icon: 'icon-fulizhongxin'}
 			];
 			//this.$authoritys('权限名') 判断权限
 			if (this.$authoritys('creator') || this.$authoritys('admin') || this.$authoritys('point_manager') || this.$authoritys('dept_manager')) {
 				this.routers.splice(3, 0, { name: '审批', children: this.returnRoutersArr('workbench'), icon: 'icon-shezhi_jifenguize' });
 			}
 			if (this.$authoritys('creator') || this.$authoritys('admin') || this.$authoritys('point_manager')) {
+				this.routers.push({ name: '福利', children: this.returnRoutersArr('welfare'), icon: 'icon-fulizhongxin'});
 				this.routers.push({ name: '设置', children: this.returnRoutersArr('set'), icon: 'icon-dingdingPC_shezhi1' });
 			}
 			//this.returnRoutersArr('set',true) 加true表示不限制路由
@@ -231,7 +256,7 @@ export default {
 			this.userData = this.$getUserData();
 			if (this.$route.path != '/home') {
 				//当刷新页面是控制左边导航栏的选中
-				this.defaultActive = localStorage.getItem('path');
+				this.defaultActive = this.$getCache('path');
 			}
 		},
 		openHome() {
@@ -262,7 +287,7 @@ export default {
 		},
 		//当刷新页面是控制左边导航栏的选中
 		activeRouter(index, indexPath) {
-			localStorage.setItem('path', indexPath[1] ? indexPath[1] : indexPath[0]);
+			this.$setCache('path', indexPath[1] ? indexPath[1] : indexPath[0]);
 		},
 		routerAstrict(data) {
 			//限制路由
@@ -325,7 +350,7 @@ export default {
 				res.data.data.list.map(item=>{
 					 map[item.id]=item
 				})
-				localStorage.setItem("userList",JSON.stringify(map))
+				this.$setCache("userList",map)
 			})
 		},
 	},

+ 2 - 2
src/init.vue

@@ -44,7 +44,7 @@ export default {
 	methods: {
 		bundleOfServices(){
 			this.$dd.biz.util.openSlidePanel({
-				url:"https://page.dingtalk.com/wow/dingtalk/act/serviceconversation?wh_biz=tm&showmenu=false&goodsCode=DT_GOODS_881607043109331&corpId="+localStorage.getItem('corpId')+"&token=5784a3e6b5e025ee891517ea814180f4",
+				url:"https://page.dingtalk.com/wow/dingtalk/act/serviceconversation?wh_biz=tm&showmenu=false&goodsCode=DT_GOODS_881607043109331&corpId="+this.$getCache('corpId')+"&token=5784a3e6b5e025ee891517ea814180f4",
 				title: '客服群',
 				onSuccess : function(result) {
 				},
@@ -80,7 +80,7 @@ export default {
 		login(corpId) {
 			var that = this;
 			this.loading = true;
-     		localStorage.setItem('corpId',corpId)
+     		this.$setCache('corpId',corpId)
 			this.$dd.runtime.permission.requestAuthCode({
 				corpId: corpId, // 企业id
 				onSuccess: function(info) {

+ 5 - 2
src/main.js

@@ -13,7 +13,7 @@ import service from './api/axios'
 import echarts from 'echarts'
 import NProgress from 'nprogress';
 import 'nprogress/nprogress.css'
-import { getToken, setToken,getUserData,setUserData,getTyps,setTyps,getIsCreator,supremeAuthority,authoritys,getTypsName,generateUUID} from './api/auth';
+import { getToken, setToken,getUserData,setUserData,getTyps,setTyps,getIsCreator,supremeAuthority,authoritys,getTypsName,generateUUID,getCache,setCache,removeCache} from './api/auth';
 import * as socketApi from './api/websocket'
 
 // 头像
@@ -40,7 +40,10 @@ Vue.prototype.$authoritys = authoritys
 Vue.prototype.$moment = moment
 Vue.prototype.$appId = process.env.VUE_APP_APPID
 Vue.prototype.$socketApi = socketApi   //长连接
-Vue.prototype.$generateUUID = generateUUID   //长连接
+Vue.prototype.$generateUUID = generateUUID   //UID 唯一标识
+Vue.prototype.$getCache = getCache
+Vue.prototype.$setCache = setCache
+Vue.prototype.$removeCache = removeCache
 
 Vue.prototype.$http = service;
 var CancelToken = axios.CancelToken;

+ 3 - 4
src/router/index.js

@@ -36,8 +36,7 @@ const routes = [{
 			{
 				path: '/award_punish',
 				name: '我奖扣的',
-				component: () => import( /* webpackChunkName: "award_punish" */
-					'@/views/abPoint/award_punish.vue'),
+				component: () => import( /* webpackChunkName: "award_punish" */'@/views/abPoint/award_punish.vue'),
 				meta: {
 					icon: 'icon-shezhi_zuzhijiagou',
 					groupCode: 'abPoint',
@@ -350,7 +349,7 @@ const routes = [{
 			},
 			{
 				path: '/prize',
-				name: '奖品清单',
+				name: '奖品管理',
 				component: () => import( /* webpackChunkName: "approval_list" */'@/views/welfare/prize.vue'),
 				meta: {
 					icon: 'icon-shezhi_gongdaolbiao',
@@ -359,7 +358,7 @@ const routes = [{
 			},
 			{
 				path: '/conversion',
-				name: '兑换记录',
+				name: '兑换管理',
 				component: () => import( /* webpackChunkName: "approval_list" */'@/views/welfare/conversion.vue'),
 				meta: {
 					icon: 'icon-shezhi_gongdaolbiao',

+ 0 - 4
src/store/getters.js

@@ -1,4 +0,0 @@
-const getters = {
-
-}
-export default getters

+ 16 - 15
src/store/index.js

@@ -1,21 +1,22 @@
 import Vue from 'vue'
 import Vuex from 'vuex'
-import getters from './getters'
-import user from './modules/user'
-// import createPersistedState from 'vuex-persistedstate'
-
 Vue.use(Vuex)
 
 export default new Vuex.Store({
-  state: {
-  },
-  mutations: {
-  },
-  actions: {
-  },
-  getters,
-  modules: {
-    user
-  },
-  // plugins: [createPersistedState()]  //Vuex内容固化到本地
+	state: {
+		config: {}
+	},
+	getters:{
+		 config: state => state.config,
+	},
+	mutations: {
+		CONFING: (state, data) => {
+			state.config = data
+		},
+	},
+	actions: {
+		setConfig({commit}, data) {
+			commit('CONFING', data);
+		},
+	},
 })

+ 0 - 25
src/store/modules/user.js

@@ -1,25 +0,0 @@
-
-import axios from '@/api/axios'
-const user = {
-
-    status: {
-
-    },
-    mutations: {
-
-    },
-    actions: {
-        export_filter({commit},arr){
-            return new Promise((resolve, reject)=>{
-                // axios('get','xxx').then(()=>{
-                    if(arr){
-                        resolve('yes')
-                    }else{
-                        reject('no')
-                    }
-                // })
-            })
-        },
-    }
-}
-export default user

+ 2 - 2
src/views/abPoint/apply_list.vue

@@ -181,7 +181,7 @@ import moment from 'moment';
 import EmployeeSelector from '@/components/EmployeeSelector.vue';
 import applicationIntegrationPopup from '@/components/applicationIntegrationPopup';
 import Steps from '@/components/Steps'; 
-import {getToken,getCache } from '@/api/auth';
+import {getToken } from '@/api/auth';
 export default {
 	data() {
 		return {
@@ -232,7 +232,7 @@ export default {
 		this.userId = this.$getUserData().id;
 		this.get_list();
 		setTimeout(() => {
-			let apply_list=getCache('apply_list')
+			let apply_list=this.$getCache('apply_list')
 			if(apply_list&&apply_list.length>0){
 				this.isBreak=true;
 				this.dialogVisible=true;

+ 3 - 5
src/views/abPoint/award_punish.vue

@@ -246,11 +246,9 @@
 
 <script>
 import EmployeeSelector from '@/components/EmployeeSelector.vue';
-import moment from 'moment';
-
 import bonusPointsPopup from '@/components/bonusPointsPopup';
 import Steps from '@/components/Steps'; 
-import {getToken,getCache } from '@/api/auth';
+import {getToken } from '@/api/auth';
 export default {
 	data() {
 		return {
@@ -277,7 +275,7 @@ export default {
 				process:[]
 			},
 			detailShow: false,
-			employee_name: JSON.parse(localStorage.getItem('SET_EMPLOYEE_MAP')),
+			employee_name: this.$getCache('SET_EMPLOYEE_MAP'),
 			userId:'',
 			cx_loading:false,
 			selectId:'',//打开详情ID
@@ -296,7 +294,7 @@ export default {
 		this.userId=this.$getUserData().id
 		this.getData()
 		setTimeout(() => {
-			let award_punish=getCache('award_punish')
+			let award_punish=this.$getCache('award_punish')
 			if(award_punish&&award_punish.obj.length>0){
 				this.isBreak=true;
 				award_punish.type==3? this.point_b():this.point_a()

+ 1 - 1
src/views/common/rewardTask.vue

@@ -424,7 +424,7 @@ export default {
 		}
 	},
 	mounted() {
-		this.point_types = JSON.parse(localStorage.getItem('types'));
+		this.point_types = this.$getCache('types');
 		this.getDepartment();
 	},
 	methods: {

+ 13 - 9
src/views/common/rewardTaskAmend.vue

@@ -18,7 +18,7 @@
 					</el-form-item>
 					
 					<el-form-item label="指定规则">
-						 <el-switch  v-model="isSelectType"></el-switch>
+						 <el-switch  v-model="isSelectType" @change="isSelectTypeC"></el-switch>
 					</el-form-item>
 					<!-- 选择分类 -->
 					<el-form-item class="test_cascader_id" label="选择分类"	v-if="!isSelectType"
@@ -254,6 +254,7 @@ export default {
 				dept_ids: null
 			},
 			point_types: [],
+			arr:[],
 			// 审批人
 			reviewerName: null,
 			reviewer_not_select: [],
@@ -398,23 +399,26 @@ export default {
 			})
 			this.fileList = filtList
 			this.fileFun('', filtList)
-			
 			if(this.rewardTaskAmendData.point_config.item_info){
 				let itemInfo = this.rewardTaskAmendData.point_config.item_info
-				this.formData.tree_echo = this.ruleChange(itemInfo.rule_id,[itemInfo.id])
-				this.isSelectType=false;
+				// 获取规则的上级分类
+				this.arr=[itemInfo.id];
+				this.ruleChange(itemInfo.rule_id)
+				this.formData.tree_echo = this.arr
+				this.isSelectType=true;
 				this.$nextTick(_=>{
+					this.arr=[];
 					this.ruleItemChange(this.formData.tree_echo)
 				})
 			}else if(this.rewardTaskAmendData.rule_id){//指定了分类
-				this.isSelectType=true;
+				this.isSelectType=false;
 				this.formData.rule_id = this.rewardTaskAmendData.rule_id;
 				this.formData.rule_value = this.returnRuleVal(this.rewardTaskAmendData.rule_id,[]);
 			}
 		}
 	},
 	mounted() {
-		this.point_types = JSON.parse(localStorage.getItem('types'));
+		this.point_types = this.$getCache('types');
 		this.getDepartment();
 	},
 	methods: {
@@ -450,11 +454,11 @@ export default {
 			}
 			return arr;
 		},
-		ruleChange(aid,att){
-			att.unshift(aid)
+		ruleChange(aid){
+			this.arr.unshift(aid);
 			let list = this.trees_ab.rule_tree.filter(x => x.id == aid)
 			if(list[0].pid == 0){
-				return att
+				return false
 			}else{
 				this.ruleChange(list[0].pid)
 			}

+ 1 - 1
src/views/common/temporaryTask.vue

@@ -407,7 +407,7 @@ export default {
 		}
 	},
 	mounted() {
-		this.point_types = JSON.parse(localStorage.getItem('types'));
+		this.point_types = this.$getCache('types');
 	},
 	methods: {
 		trees_PtId(id) {

+ 22 - 16
src/views/common/temporaryTaskAmend.vue

@@ -12,7 +12,7 @@
 						<el-input type="textarea" rows="3" maxlength="20" show-word-limit v-model="formData.task_name" placeholder="请输入任务内容(限20字)"></el-input>
 					</el-form-item>
 					<el-form-item label="指定规则">
-						 <el-switch  v-model="isSelectType"></el-switch>
+						 <el-switch  v-model="isSelectType" @change="isSelectTypeActive"></el-switch>
 					</el-form-item>
 					<!-- 选择分类 -->
 					<el-form-item class="test_cascader_id" label="选择分类"	v-if="!isSelectType"
@@ -258,6 +258,8 @@ export default {
 				ahead_award_point_limit: null,
 			},
 			point_types: [],
+			arr:[],
+			
 			// 执行者
 			executorName: null,
 			show_employee_selector: false,
@@ -360,10 +362,10 @@ export default {
 		},
 	},
 	mounted() {
-		this.point_types = JSON.parse(localStorage.getItem('types'));
+		this.point_types = this.$getCache('types');
 	},
 	methods: {
-		isSelectTypeC(){
+		isSelectTypeActive(){
 			let item = this.formData;
 			this.max = 0;
 			this.min = 0;
@@ -391,7 +393,7 @@ export default {
 			return id == 2 ? 'A分' : 'B分'
 		},
 		ruleItemChange(val){
-			let item = this.formData
+			let item = this.formData;
 			if(val.length>0){
 				let data = this.$refs.ruleItem.getCheckedNodes()[0].data;//当前选中的节点数据
 				item.task_remark = data.name;
@@ -439,13 +441,17 @@ export default {
 			// 指定了规则
 			if(this.modifyData.point_config.item_info){
 				let itemInfo = this.modifyData.point_config.item_info
-				this.formData.tree_echo = this.ruleChange(itemInfo.rule_id,[itemInfo.id])
-				this.isSelectType=false;
+				this.arr=[itemInfo.id];
+				// 获取规则的上级分类
+				this.ruleChange(itemInfo.rule_id)
+				this.formData.tree_echo = this.arr
+				this.isSelectType=true;
 				this.$nextTick(_=>{
+					this.arr=[];
 					this.ruleItemChange(this.formData.tree_echo);
 				})
 			}else if(this.modifyData.rule_id){//指定了分类
-				this.isSelectType=true;
+				this.isSelectType=false;
 				this.formData.rule_id = this.modifyData.rule_id;
 				this.formData.rule_value = this.returnRuleVal(this.modifyData.rule_id,[]);
 			}
@@ -456,6 +462,15 @@ export default {
 			})
 
 		},
+		ruleChange(aid){
+			this.arr.unshift(aid);
+			let list = this.trees_ab.rule_tree.filter(x => x.id == aid)
+			if(list[0].pid == 0){
+				return false
+			}else{
+				this.ruleChange(list[0].pid)
+			}
+		},
 		returnRuleVal(rule_id,arr){
 			arr.unshift(rule_id)
 			let list = this.trees_ab.rule_tree.filter(x => x.id == rule_id)
@@ -474,15 +489,6 @@ export default {
 		handleClose(done) {
 			done();
 		},
-		ruleChange(aid,att){
-			att.unshift(aid)
-			let list = this.trees_ab.rule_tree.filter(x => x.id == aid)
-			if(list[0].pid == 0){
-				return att
-			}else{
-				this.ruleChange(list[0].pid)
-			}
-		},
 		deductionPoint(item){
 			if (this.modifyData.point_config[item] != '0') {
 				this.formData[item] = this.modifyData.point_config[item];

+ 2 - 2
src/views/ranking/balanceA.vue

@@ -167,7 +167,7 @@ export default {
     },
     // 提示信息
     tips_close() {
-      localStorage.setItem('balanceA_tips', 'true');
+      this.$setCache('balanceA_tips', 'true');
       this.tips_show = false;
     },
     // 页码变更
@@ -245,7 +245,7 @@ export default {
  	this.getDepartment();
  },
   mounted() {
-    if (localStorage.getItem('balanceA_tips')) {
+    if (this.$getCache('balanceA_tips')) {
       this.tips_show = false;
     } else {
       this.tips_show = true;

+ 0 - 9
src/views/ranking/department_statistics.vue

@@ -377,15 +377,6 @@ export default {
 		this.formData.month = this.$moment().format('YYYY-MM');
 		this.executiveFunction();
 		window.addEventListener('resize', this.selfAdaption);
-		// 		if (localStorage.getItem('dept_tree')) {
-		// 			this.dept_tree = this.getTreeData(JSON.parse(localStorage.getItem('dept_tree')))
-		//   }else{
-		// this.$store.dispatch('get_dept_tree').then((res) => {
-		//   this.$nextTick(() => {
-		//     this.dept_tree = 	this.getTreeData(JSON.parse(localStorage.getItem('dept_tree')))
-		//   })
-		// })
-		//   }
 	},
 	methods: {
 		//需要执行的所有函数

+ 3 - 3
src/views/ranking/dept_rank.vue

@@ -296,7 +296,7 @@ export default {
 				// time_range: [new Date(new Date().toLocaleDateString()).getTime(), new Date(new Date().toLocaleDateString()).getTime()]
 				time_range: []
 			},
-			employee_map: JSON.parse(localStorage.getItem('SET_EMPLOYEE_MAP')),
+			employee_map: this.$getCache('SET_EMPLOYEE_MAP'),
 			positions: [{ id: 0, age: 'all', name: '全部' }, { id: 1, age: 'manager', name: '管理者' }, { id: 2, age: 'employee', name: '员工' }],
 			tips_show: false,
 			byRankingShow: false,
@@ -490,7 +490,7 @@ export default {
 		},
 		// 提示信息
 		tips_close() {
-			localStorage.setItem('dept_rank_tips', 'true');
+			this.$setCache('dept_rank_tips', 'true');
 			this.tips_show = false;
 		},
 		// 查询
@@ -680,7 +680,7 @@ export default {
 	},
 	mounted() {
 		this.point_types = this.$getTyps();
-		this.tips_show = JSON.parse(localStorage.getItem('dept_rank_tips')) ? false : true;
+		this.tips_show = this.$getCache('dept_rank_tips') ? false : true;
 		this.getDepartment();
 		this.getEmployeeList();
 		this.get_list(this.formData, true);

+ 3 - 1
src/views/ranking/log_rank.vue

@@ -207,7 +207,7 @@ export default {
 			},
 			rule_ids: null,
 			
-			employee_map: JSON.parse(localStorage.getItem('SET_EMPLOYEE_MAP')),
+			employee_map: this.$getCache('SET_EMPLOYEE_MAP'),
 			total: 0,
 			time_types: [{ label: '月份', value: '1' }, { label: '季度', value: '3' }, { label: '年份', value: '2' }, { label: '自定义', value: '4' }],
 			time_type: '1',
@@ -261,6 +261,8 @@ export default {
 			} else {
 				this.formData.sort = 'DESC';
 			}
+			this.formData.page = 1;
+			this.get_list();
 		},
 		dept_name(val) {
 			if (val.length !== 0) {

+ 1 - 1
src/views/ranking/manager_statistics.vue

@@ -364,7 +364,7 @@ export default {
 			//是否达标
 			this.condition.complete != 0 ? (data += '&complete=' + this.condition.complete) : (data += '&complete=0');
 			//当前页数
-			data += '&page=' + this.condition.page;
+			data += '&page=1&page_size=9999';
 			window.open(process.env.VUE_APP_BASE_API + 'api/download/prize/list/v4?employee_id=' + this.$getUserData().id + data, '_blank');
 			this.dialogVisible = false;
 		},

+ 3 - 1
src/views/ranking/task_rank.vue

@@ -209,7 +209,7 @@ export default {
 			},
 			rule_ids: null,
 			
-			employee_map: JSON.parse(localStorage.getItem('SET_EMPLOYEE_MAP')),
+			employee_map: this.$getCache('SET_EMPLOYEE_MAP'),
 			total: 0,
 			time_types: [{ label: '月份', value: '1' }, { label: '季度', value: '3' }, { label: '年份', value: '2' }, { label: '自定义', value: '4' }],
 			time_type: '1',
@@ -268,6 +268,8 @@ export default {
 			} else {
 				this.formData.sort = 'DESC';
 			}
+			this.formData.page = 1;
+			this.get_list();
 		},
 		dept_name(val) {
 			if (val.length !== 0) {

+ 2 - 2
src/views/ranking/total_rank.vue

@@ -197,7 +197,7 @@ export default {
 		},
 		// 提示信息
 		tips_close() {
-			localStorage.setItem('total_rank_tips', 'true');
+			this.$setCache('total_rank_tips', 'true');
 			this.tips_show = false;
 		},
 		// 页面变更
@@ -248,7 +248,7 @@ export default {
 		this.getDepartment();
 	},
 	mounted() {
-		this.tips_show = JSON.parse(localStorage.getItem('total_rank_tips')) ? false : true;
+		this.tips_show = this.$getCache('total_rank_tips') ? false : true;
 		this.get_list();
 	}
 };

+ 16 - 28
src/views/set/framework.vue

@@ -351,6 +351,7 @@ export default {
 			newId: 0,
 			dirSupList: [],
 			selected_dirSup: { employee: [], dept: [] },
+			employeeAll:[],//人员列表
 		};
 	},
 	components: {
@@ -374,13 +375,14 @@ export default {
 		}
 	},
 	created() {
+		this.filtration();
 		this.getInfo();
 		this.getEmployee();
 		this.manageList();
 	},
 	mounted() {
 		this.$nextTick(function() {
-			if (localStorage.getItem('rule')) {
+			if (this.$getCache('rule')) {
 				this.tips_show = false;
 			} else {
 				this.tips_show = true;
@@ -465,7 +467,9 @@ export default {
 							}else{
 								this.dirSupervisor = {}
 							}
-							this.propList = this.nameStrList(employeeD.superior_list, 'name');
+							// 过滤已经离职人员
+							let sup=[...this.employeeAll].filter(x => [...employeeD.superior_list].some(y => y.id === x.id));
+							this.propList = this.nameStrList(sup, 'name');
 						}
 						this.messageMore = data
 					}
@@ -478,34 +482,13 @@ export default {
 			}).finally(() =>{
 				this.show_loading = false
 			})
-			// this.$axios('get', '/api/employee/info', { id: isId })
-			// .then(res => {
-			// 	if (res.data.code == 1) {
-			// 		let data = res.data.data
-			// 		if(data.employee_detail.dept_list){
-			// 			this.deptList = this.nameStrList(data.employee_detail.dept_list, 'dept_name');
-			// 		}
-			// 		if(data.employee_detail.superior_list){
-			// 			let employeeD = data.employee_detail
-			// 			if(employeeD.superior_id != 0){
-			// 				this.dirSupervisor = employeeD.superior_list.filter(x => x.id == employeeD.superior_id)[0]
-			// 				console.log(this.dirSupervisor)
-			// 			}
-			// 			this.propList = this.nameStrList(employeeD.superior_list, 'name');
-			// 		}
-			// 		this.messageMore = data
-			// 	}
-			// }).finally(()=>{
-			// 	this.show_loading = false
-			// })
 		},
 		setSuperior(row){
 			this.mangeId = row.id
-			let createData = {}
-			createData = this.manageData.filter(x => x.is_creator == 1)
+			let createData = this.manageData.filter(x => x.is_creator == 1);
 			let list = this.manageData.filter(x => x.id != row.id && x.is_creator != 1)
 			this.employeeList = list
-			let supList = row.employee_detail.superior_list
+			let supList =row.employee_detail.superior_list
 			if(createData[0]){
 				supList.forEach(item =>{
 					createData.some(arr =>{
@@ -519,6 +502,11 @@ export default {
 			this.selected_manage.employee = supList
 			this.manageScope_show = true
 		},
+		filtration() {
+		  this.$axios('get', '/api/employee/index', { dept_id: this.pid, page: 0, page_size: 3000,is_official:1 }).then(res => {
+			 this.employeeAll = res.data.data.list;
+		  }); 
+		},
 		dirSuperior(row){
 			this.dirSupList = row.employee_detail.superior_list
 			if(this.dirSupervisor.name){
@@ -806,7 +794,7 @@ export default {
 			this.$axios('get', '/api/employee/index', data).then(res => {
 					this.total = res.data.data.pageInfo.count;
 					this.userList = res.data.data.list;
-					var visible = localStorage.getItem('visible');
+					var visible = this.$getCache('visible');
 					if (!visible) {
 						this.visible = true;
 					}
@@ -816,12 +804,12 @@ export default {
 				});
 		},
 		visible_close() {
-			localStorage.setItem('visible', 'true');
+			this.$setCache('visible', 'true');
 			this.visible = false;
 		},
 		//关闭提示
 		tips_close() {
-			localStorage.setItem('rule', 'true');
+			this.$setCache('rule', 'true');
 			this.tips_show = false;
 		},
 		handleSizeChange: function(val) {

+ 0 - 1
src/views/set/initialPoint.vue

@@ -45,7 +45,6 @@ export default {
 	components: {
 		workpoints
 	},
-	created() {},
 	mounted() {
 		this.cheak_ax();
 	},

+ 2 - 2
src/views/set/jurisdiction.vue

@@ -863,7 +863,7 @@ export default {
 		this.isStart = this.$getIsCreator('creator');
 	},
 	mounted() {
-		if (localStorage.getItem('framework')) {
+		if (this.$getCache('framework')) {
 			this.tips_show = false;
 		} else {
 			this.tips_show = true;
@@ -1461,7 +1461,7 @@ export default {
 		},
 		// 关闭提示语
 		tips_close() {
-			localStorage.setItem('framework', 'true');
+			this.$setCache('framework', 'true');
 			this.tips_show = false;
 		}
 	}

+ 4 - 3
src/views/set/rule.vue

@@ -392,7 +392,7 @@ export default {
 	},
 	mounted() {
 		this.$nextTick(function() {
-			if (localStorage.getItem('rule')) {
+			if (this.$getCache('rule')) {
 				this.tips_show = false;
 			} else {
 				this.tips_show = true;
@@ -428,7 +428,7 @@ export default {
 		payOrder (row) {// 展示二维码
 			let url = 'dingtalk://dingtalkclient/action/open_micro_app'
 			let appid = '?appId='+this.$appId
-			let corpId = '&corpId='+localStorage.getItem('corpId')
+			let corpId = '&corpId='+this.$getCache('corpId')
 			// let corpId = '&corpId=ding011f57ab048cf202ffe93478753d9884'
 			let page = '&page='+encodeURIComponent(`pages/workbench/apply/apply?id=${encodeURIComponent(row)}`)//encodeURIComponent('小米')
 			let urls = url+appid+corpId+page
@@ -879,6 +879,7 @@ export default {
 		handleNodeClick(e) {
 			if(e.id){
 				var items = this.getItemData(e);
+				console.log(items,e.id)
 				this.selectItem = {
 					child: e.child,
 					id: e.id,
@@ -1041,7 +1042,7 @@ export default {
 		},
 		//关闭提示
 		tips_close() {
-			localStorage.setItem('rule', 'true');
+			this.$setCache('rule', 'true');
 			this.tips_show = false;
 		},
 		//添加分类

+ 16 - 2
src/views/set/systemLayout.vue

@@ -11,6 +11,17 @@
 					</p>
 					<div style="margin-top:5px;" class="fontColorF"><span>指定规则的审批或奖扣分,均可直接通过</span></div>
 				</div>
+				<div class="integralApproval">
+					<b>
+						福利模块
+						<el-switch style="margin-left:30px;" :active-value="1" :inactive-value="0" v-model="shop_status"></el-switch>
+					</b>
+					<div style="margin-top:5px;" class="fontColorF">
+						<div>开启后,通过“功勋点”可兑换公司的福利奖品;</div>
+						<div>员工可通过公司定期统一发放或挣更多个人B分来获得功勋点</div>
+					</div>
+				</div>
+				
 				<div class="integralApproval">
 					<b>
 						提交积分时,必须选择积分规则
@@ -144,6 +155,7 @@ export default {
 			activeName: 'first',
 			examine: false,
 			ruleOnoff: false,
+			shop_status:0,//是否开启福利模块
 
 			checked: false, //积分日报展示A分数据
 			individualPoints: false, //个人积分日报
@@ -181,12 +193,10 @@ export default {
 	methods: {
 		hisList() {
 			let params = this.formData
-			console.log(params)
 			this.hisload = true
 			this.$axios('get', '/api/log/operation/list', params).then(res =>{
 				if(res.data.code == 1){
 					let list = res.data.data.list
-					console.log(res)
 					this.list = list.list
 					this.total = list.total
 				}
@@ -213,6 +223,7 @@ export default {
 				data.specified_rule_item = this.ruleOnoff ? 1 : 0;
 				data.rule_limit_check = this.examine ? 0 : 1;
 				data.task_review = this.task_review ? 1 : 0;
+				data.shop_status = this.shop_status;//是否开启福利模块
 				if (this.isApB) {
 					if (this.pointNum == 0 || !this.pointNum) {
 						this.$message({
@@ -242,6 +253,7 @@ export default {
 				})
 				.finally(() => {
 					this.loading = false;
+					this.cheakAx('first');
 				});
 		},
 		cheakAx(name) {
@@ -249,12 +261,14 @@ export default {
 			this.$axios('get', '/api/integral/site/config')
 				.then(res => {
 					let data = res.data.data;
+					this.$store.dispatch('setConfig', res.data.data);
 					if (name == 'first') {
 						if(data.specified_rule_item){
 							this.ruleOnoff = data.specified_rule_item == 1 ? true : false;
 						}else{
 							this.ruleOnoff = false
 						}
+						this.shop_status=data.shop_status;//是否开启福利模块
 						this.examine = data.rule_limit_check == 0 ? true : false;
 						this.isApB = data.a2b == 0 ? false : true;
 						this.task_review = data.task_review == 1 ? true : false;

+ 2 - 2
src/views/set/voluntarilyPoint.vue

@@ -447,7 +447,7 @@ export default {
 		}
 	},
 	mounted() {
-		if (localStorage.getItem('voluntarilyPoint')) {
+		if (this.$getCache('voluntarilyPoint')) {
 			this.tips_show = false;
 		} else {
 			this.tips_show = true;
@@ -676,7 +676,7 @@ export default {
 		},
 		// 关闭提示语
 		tips_close() {
-			localStorage.setItem('voluntarilyPoint', 'true');
+			this.$setCache('voluntarilyPoint', 'true');
 			this.tips_show = false;
 		},
 		//新增加分项

+ 1 - 2
src/views/task/allTask.vue

@@ -281,8 +281,7 @@ export default {
 			this.completeShow = false;
 		},
 		getPointType() {
-			let point = window.plus ? JSON.parse(puls.storage.getItem('types')) : JSON.parse(localStorage.getItem('types'));
-			// point.splice(0,1)
+			let point = this.$getCache('types');
 			point.unshift({ code: 'AF', id: 0, name: '全部' });
 			return point;
 		},

+ 3 - 5
src/views/task/myExamine.vue

@@ -111,8 +111,7 @@ export default {
 	name: 'my_task',
 	data() {
 		return {
-			active: 'running',
-			tabsOption: [{ label: '待完成', name: 'running' }, { label: '待审批', name: 'complete' }, { label: '已审批', name: 'reviewed' }],
+			tabsOption: [{ label: '待审批', name: 'complete' },{ label: '待完成', name: 'running' }, { label: '已审批', name: 'reviewed' }],
 			list: [],
 			loading: false,
 			total: null,
@@ -124,7 +123,7 @@ export default {
 			},
 			formData: {
 				employee_id:'',
-				status: 'running',
+				status: 'complete',
 				pt_id: 0,
 				sort: 'publish',
 				source_type: '0',
@@ -195,8 +194,7 @@ export default {
 			this.detailShow = true;
 		},
 		getPointType() {
-			let point = window.plus ? JSON.parse(puls.storage.getItem('types')) : JSON.parse(localStorage.getItem('types'));
-			// point.splice(0,1)
+			let point =this.$getCache('types');
 			point.unshift({ code: 'AF', id: 0, name: '全部' });
 			return point;
 		},

+ 1 - 1
src/views/task/my_issue.vue

@@ -522,7 +522,7 @@ export default {
 		},
 		// 获取积分类型
 		getPointTypes() {
-			let point = window.plus ? JSON.parse(plus.storage('types')) : JSON.parse(localStorage.getItem('types'));
+			let point =this.$getCache('types');
 			point.unshift({ code: 'all', id: 0, name: '全部' });
 			return point;
 		},

+ 1 - 2
src/views/task/my_task.vue

@@ -297,8 +297,7 @@ export default {
 
 		},
 		getPointType() {
-			let point = window.plus ? JSON.parse(puls.storage.getItem('types')) : JSON.parse(localStorage.getItem('types'));
-			// point.splice(0,1)
+			let point = this.$getCache('types');
 			point.unshift({ code: 'AF', id: 0, name: '全部' });
 			return point;
 		},

+ 443 - 215
src/views/welfare/conversion.vue

@@ -1,19 +1,18 @@
 <template>
 	<div>
-		<div class="all" style="padding: 20px;" v-loading="attendload">
+		<div class="all" style="padding: 20px;">
 			<div>
 				<el-form :inline="true">
-					<el-button type="primary" size="medium">批量发放</el-button>
 					<el-form-item label="兑换码">
-						<el-input placeholder="奖品搜索" size="medium" style="width: 200px;margin: 0 10px;" v-model="formData.event_type" clearable></el-input>
+						<el-input placeholder="奖品搜索" size="medium" style="width: 200px;margin: 0 10px;" v-model="formData.sn" clearable></el-input>
 					</el-form-item>
 					<el-form-item label="人员">
-						<el-select v-model="select_employee_id" size="medium" filterable placeholder="请输入或选择人员" clearable>
+						<el-select v-model="formData.employee_id" size="medium" filterable placeholder="请输入或选择人员" clearable>
 							<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
 						</el-select>
 					</el-form-item>
 					<el-form-item label="状态">
-						<el-select v-model="formData.event_type" size="medium" @change="selectgroupId" style="width:110px" placeholder="请选择">
+						<el-select v-model="formData.status" size="medium" style="width:110px" placeholder="请选择" clearable>
 							<el-option v-for="(item, index) in event_type" :key="index" :label="item.name" :value="item.id"></el-option>
 						</el-select>
 					</el-form-item>
@@ -30,88 +29,220 @@
 							start-placeholder="开始日期"
 							end-placeholder="结束日期"
 							:picker-options="instantPickerOptions"
-							@change="onFilterChanged"
 						></el-date-picker>
 					</el-form-item>
-					<el-form-item><el-button type="primary" plain @click="exportRanking">导出排名</el-button></el-form-item>
+<!-- 					<el-form-item>
+						<el-button type="primary" size="medium" @click="grants" style="margin-right: 10px;">批量发放</el-button>
+						<el-button type="primary" size="medium" plain @click="exportExcel">导出</el-button>
+					</el-form-item> -->
 				</el-form>
+				<div style="margin-bottom: 10px;">
+					<el-button type="primary" size="medium" @click="grants" style="margin-right: 10px;">批量发放</el-button>
+				</div>
 			</div>
-			<el-table :data="all_integral_list" style="width: 100%" v-loading="loading">
-				<el-table-column type="selection"></el-table-column>
+			<el-table :data="list" style="width: 100%;cursor: pointer;" v-loading="loading" @row-click="openDetail" @selection-change="handleSelectionChange">
+				<el-table-column type="selection" :selectable="selectable"></el-table-column>
 				<el-table-column label="姓名" align="left">
 					<template slot-scope="scope">
 						<div style="display:flex;">
-							<userImage :user_name="scope.row.name" :img_url="scope.row.img_url" width="50px" height="50px"></userImage>
-							<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.name }}</span>
+							<userImage :user_name="scope.row.employee.name" :id="scope.row.employee.id" width="50px" height="50px"></userImage>
+							<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.employee.name }}</span>
 						</div>
 					</template>
 				</el-table-column>
-				<el-table-column prop="point" label="奖品名称" align="center"></el-table-column>
-				<el-table-column prop="point" label="数量" align="center"></el-table-column>
-				<el-table-column prop="point" label="总价" align="center"></el-table-column>
-				<el-table-column prop="point" label="兑换时间" align="center"></el-table-column>
-				<el-table-column prop="point" label="兑换码" align="center"></el-table-column>
-				<el-table-column prop="point" label="发放时间" align="center"></el-table-column>
-				<el-table-column prop="point" label="状态" align="center"></el-table-column>
+				<el-table-column prop="goods_name" label="奖品名称" align="center"></el-table-column>
+				<el-table-column prop="num" label="数量" align="center"></el-table-column>
+				<el-table-column prop="total_price" label="总价" align="center"></el-table-column>
+				<el-table-column prop="create_time" label="兑换时间" align="center">
+					<template slot-scope="scope">
+						{{ $moment.unix(scope.row.create_time).format('YYYY-MM-DD HH:mm:ss') }}
+					</template>
+				</el-table-column>
+				<el-table-column prop="sn" label="兑换码" align="center" min-width="140"></el-table-column>
+				<el-table-column prop="complete_time" label="发放时间" align="center">
+					<template slot-scope="scope">
+						<span v-if="scope.row.complete_time">{{ $moment.unix(scope.row.complete_time).format('YYYY-MM-DD HH:mm:ss') }}</span>
+						<span v-else>--</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="status" label="状态" align="center">
+					<template slot-scope="scope">
+						<span v-if="scope.row.status == 0" class="fontColorT">未发放</span>
+						<span v-if="scope.row.status == 1" class="green">已发放</span>
+						<span v-if="scope.row.status == 2" class="red">已取消</span>
+					</template>
+				</el-table-column>
 				<el-table-column prop="point" label="操作" align="left">
+					<template slot="header" slot-scope="scope">
+						<el-tooltip effect="dark" placement="top-start">
+							<div slot="content"><div style="margin-bottom: 10px;">7日内可执行撤销操作</div></div>
+							<span>
+								<span>操作</span>
+								<i class="el-icon-warning"></i>
+							</span>
+						</el-tooltip>
+					</template>
 					<template slot-scope="scope">
-						<el-link type="primary">主要链接</el-link>
-						<el-link type="primary">主要链接</el-link>
-						<el-link type="primary">主要链接</el-link>
+						<el-link type="primary" :underline="false" @click.stop="grant(scope.row.id)" v-if="scope.row.status == 0" style="padding-right: 10px;">发放</el-link>
+						<el-link type="primary" :underline="false" @click.stop="revoke(scope.row.id)" v-if="scope.row.status == 1" style="padding-right: 10px;">撤销</el-link>
+						<el-link type="primary" :underline="false" @click.stop="cancel(scope.row.id)" v-if="scope.row.status == 0" style="padding-right: 10px;">取消</el-link>
+						<el-link type="primary" :underline="false">查看明细</el-link>
 					</template>
 				</el-table-column>
 
 				<template slot="empty">
-					<noData :content="checkingInGroup.length == 0 ? '请先开启钉钉考勤' : '暂无数据'"></noData>
+					<noData></noData>
 				</template>
 			</el-table>
 			<center style="padding: 20px 0;">
 				<el-pagination
 					background
-					@size-change="handleSizeChange1"
+					@size-change="handleSizeChange"
 					@current-change="handleCurrentChange"
 					:current-page="formData.page"
 					:page-sizes="[10, 20, 50, 100]"
 					layout="total, sizes, prev, pager, next"
-					:page-size="pageLimit1"
+					:page-size="pageLimit"
 					:total="total"
 				></el-pagination>
 			</center>
 		</div>
-		<!-- 导出弹窗 -->
-		<el-dialog title="导出排名" :visible.sync="dialogVisible" width="730px">
-			<div style="font-size:15px;margin:20px 0 20px 0;">系统将按以下已选条件导出对应的排名报表</div>
-			<div v-loading="exportLoad">
-				<el-form :inline="true">
-					<el-form-item label="考勤组">
-						<el-select v-model="exportData.group_id" @change="selectgroupId" filterable :clearable="false" placeholder="请选择考勤组">
-							<el-option v-for="item in checkingInGroup" :key="item.id" :label="item.name" :value="item.id"></el-option>
-						</el-select>
-					</el-form-item>
 
-					<el-form-item label="排名类型">
-						<el-select v-model="exportData.event_type" style="width:150px" placeholder="请选择">
-							<el-option v-for="(item, index) in event_type" :key="index" :label="item.name" :value="item.id"></el-option>
-						</el-select>
-					</el-form-item>
+		<el-dialog title="发放结果" :visible.sync="isResult" width="600" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
+			<div v-if="!isShowError">
+				<div style="text-align: center;margin-bottom: 10px;" class="red" v-if="isShowError2">{{ errorMsg }}</div>
+				<el-progress :text-inside="true" :stroke-width="24" :percentage="percentage"></el-progress>
+				<div style="margin-top: 20px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
+					<div class="flex-box-ce results" style="font-weight: 600;">
+						<div style="border-right: 1px solid #f1f1f1;width: 50px;">序号</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">姓名</div>
+						<div class="flex-2">提交结果</div>
+					</div>
+					<div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
+						<div style="border-right: 1px solid #f1f1f1;width: 50px;">{{ results.length - index }}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.task.msg.name }}</div>
+						<div class="flex-2 green" v-if="item.status == 1">{{ item.msg }}</div>
+						<div class="flex-2 red" v-else>{{ item.msg }}</div>
+					</div>
+				</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;" v-show="isShowError2 && results.length != resultList.length">
+						<el-button type="primary" @click="isResult = false" size="small">确 定</el-button>
+					</div>
+					<div class="flex-box-end" style="margin-top: 20px;" v-show="results.length == resultList.length">
+						<el-button type="primary" @click="isResult = false" size="small">确 定</el-button>
+					</div>
+				</span>
+			</div>
+			<div v-else>
+				<div style="text-align: center;" class="red">{{ errorMsg }}</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;"><el-button type="primary" @click="isResult = false" size="small">确 定</el-button></div>
+				</span>
+			</div>
+		</el-dialog>
 
-					<el-form-item label="时间">
-						<el-date-picker
-							class="first-element-btn"
-							:clearable="false"
-							v-model="exportTime_range"
-							type="daterange"
-							value-format="yyyy-MM-dd"
-							range-separator="至"
-							start-placeholder="开始日期"
-							end-placeholder="结束日期"
-							:picker-options="instantPickerOptions"
-						></el-date-picker>
+		<!-- 缓存的奖扣 -->
+		<el-dialog title="网络中断发放对象列表" :visible.sync="isShowBreak" width="800" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
+			<div>
+				<div style="margin-top: 20px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
+					<div class="flex-box-ce results" style="font-weight: 600;">
+						<div style="border-right: 1px solid #f1f1f1;width: 50px;">序号</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">姓名</div>
+					</div>
+					<div class="flex-box-ce results" v-for="(item, index) in breakList" :key="index">
+						<div style="border-right: 1px solid #f1f1f1;width: 50px;">{{ index + 1 }}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.name }}</div>
+					</div>
+				</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;">
+						<el-button type="primary" @click="colseBreak()" size="small">取 消</el-button>
+						<el-button type="primary" @click="submitBreak()" size="small">再次提交</el-button>
+					</div>
+				</span>
+			</div>
+		</el-dialog>
+
+		<!-- 取消 -->
+		<el-dialog title="取消兑换" :visible.sync="isCancel" width="500px">
+			<div style="margin: 10px 0;">
+				<el-form ref="addTypeName" :model="addTypeName" label-width="85px" @submit.native.prevent>
+					<el-form-item
+						label="取消原因"
+						:rules="[{ required: true, message: '取消原因不能为空' }, { min: 2, max: 200, message: '长度在 2 到 200 个字符', trigger: 'blur' }]"
+						prop="remark"
+					>
+						<el-input v-model="addTypeName.remark" type="textarea" placeholder="请输入取消原因" :rows="5" maxlength="200" show-word-limit></el-input>
 					</el-form-item>
 				</el-form>
 				<span class="dialog-footer" style="display:flex;justify-content: flex-end;">
-					<el-button @click="dialogVisible = false">取 消</el-button>
-					<el-button type="primary" @click="exportExcel">导 出</el-button>
+					<el-button @click="isCancel = false">取 消</el-button>
+					<el-button type="primary" @click="subGroupForm('addTypeName')">确 定</el-button>
+				</span>
+			</div>
+		</el-dialog>
+		<!-- 详情 -->
+		<el-dialog title="兑换详情" :visible.sync="isDetail" width="600px">
+			<div style="margin: 10px 0;" v-loading="attendload">
+				<div class="flex-box-ce">
+					<div class="flex-box-ce flex-1">
+						<userImage :user_name="detailData.employee.name" :id="detailData.employee.id" width="50px" height="50px" fontSize="1"></userImage>
+						<div style="margin-left:10px;margin-right:4px;">
+							<div style="font-size: 16px;font-weight: 700;">{{ detailData.employee.name }}</div>
+							<div v-if="detailData.employee.employee_detail">
+							  <span v-for="(item, index) in detailData.employee.employee_detail.dept_list" :key="index">
+								{{ item.dept_name }}
+								<span v-if="detailData.employee.employee_detail.dept_list.length - index > 1">,</span>
+							  </span>
+							</div>
+						</div>
+					</div>
+					<div v-if="detailData.status == 0" class="fontColorT" style="font-size: 16px;">未发放</div>
+					<div v-if="detailData.status == 1" class="green" style="font-size: 16px;">已发放</div>
+					<div v-if="detailData.status == 2" class="red" style="font-size: 16px;">已取消</div>
+				</div>
+				<div class="imgBox flex-box" style="height: 100px">
+					<el-image style="width: 100px; height: 100px" :src="detailData.goods_image" :preview-src-list="[detailData.goods_image]"></el-image>
+					<div class="flex-box-v" style="padding: 10px;">
+						<div class="flex-1" style="width: 230px;">{{ detailData.goods_name }}</div>
+						<div>单价 :<span class="blue">{{ detailData.price }}</span> 功勋点</div>
+					</div>
+				</div>
+				<div style="margin-bottom: 30px;" class="message">
+					<div class="flex-box-ce">
+						<span class="tabel">数量</span>
+						<span class="flex-1">{{ detailData.num }}</span>
+					</div>
+					<div class="flex-box-ce">
+						<span class="tabel">总价</span>
+						<span class="flex-1">{{ detailData.total_price }}</span>
+					</div>
+					<div class="flex-box-ce">
+						<span class="tabel">兑换时间</span>
+						<span class="flex-1">{{ $moment.unix(detailData.create_time).format('YYYY-MM-DD HH:mm:ss') }}</span>
+					</div>
+					<div class="flex-box" style="margin-bottom: 10px;">
+						<span class="tabel">备注</span>
+						<div class="flex-1" style="min-height: 80px;border-radius: 5px;background-color: #f1f1f1;padding: 10px;">{{ detailData.remark }}</div>
+					</div>
+					<div class="flex-box-ce" v-if="detailData.status == 1">
+						<span class="tabel">发放时间</span>
+						<span class="flex-1">{{ $moment.unix(detailData.complete_time).format('YYYY-MM-DD HH:mm:ss') }}</span>
+					</div>
+					<div class="flex-box-ce" v-if="detailData.status == 2">
+						<span class="tabel">取消时间</span>
+						<span class="flex-1">{{ $moment.unix(detailData.complete_time).format('YYYY-MM-DD HH:mm:ss') }}</span>
+					</div>
+
+					<div class="flex-box" v-if="detailData.status == 2">
+						<span class="tabel">取消原因</span>
+						<div class="flex-1" style="min-height: 80px;border-radius: 5px;background-color: #f1f1f1;padding: 10px;">{{ detailData.cancel_remark }}</div>
+					</div>
+				</div>
+
+				<span class="dialog-footer" style="display:flex;justify-content: flex-end;">
+					<el-button type="primary" @click="isDetail = false">确 定</el-button>
 				</span>
 			</div>
 		</el-dialog>
@@ -121,63 +252,6 @@
 export default {
 	data() {
 		return {
-			// 设置只能选择当前日期及之后的日期
-			pickerOptions: {
-				disabledDate(time) {
-					return time.getTime() > Date.now() - 8.64e7; //如果没有后面的-8.64e7就是不可以选择今天的
-				}
-			},
-			exportLoad: false,
-			dialogVisible: false,
-			checkingInGroup: [],
-			employee_map: [],
-			select_employee_id: '',
-			event_type: [
-				{ id: 0, name: '总分' },
-				{ id: 1, name: '迟到' },
-				{ id: 2, name: '早退' },
-				{ id: 6, name: '准时打卡' },
-				{ id: 20, name: '上班缺卡' },
-				{ id: 21, name: '下班缺卡' },
-				{ id: 16, name: '加班 ' },
-				{ id: 10, name: '缺勤' }
-			],
-			attendload: false,
-			loading: false,
-			all_integral_list: null,
-			Month_range: this.$moment().format('YYYY-MM'),
-			time_range: [
-				this.$moment()
-					.startOf('month')
-					.format('YYYY-MM-DD'),
-				this.$moment()
-					.endOf('month')
-					.format('YYYY-MM-DD')
-			],
-			formData: {
-				group_id: '',
-				// date_type: 3,
-				page: 1,
-				page_size: 10,
-				event_type: 0
-			},
-			exportMonth_range: this.$moment().format('YYYY-MM'),
-			exportTime_range: [
-				this.$moment()
-					.startOf('month')
-					.format('YYYY-MM-DD'),
-				this.$moment()
-					.endOf('month')
-					.format('YYYY-MM-DD')
-			],
-			exportData: {
-				group_id: '',
-				event_type: 0
-			},
-			total: 0,
-			dept_tree: [],
-			dept_name: [],
-			pageLimit1: 10,
 			instantPickerOptions: {
 				shortcuts: [
 					{
@@ -220,150 +294,283 @@ export default {
 					}
 				]
 			},
-			// 更新考勤数据
-			isUpdate: false,
-			update: {
-				type: 'daily',
-				target_date: '',
-				target_month: ''
+
+			employee_map: [],
+			event_type: [{ id: 0, name: '未发放' }, { id: 1, name: '已发放' }, { id: 2, name: '已取消' }],
+			attendload: false,
+			loading: false,
+			list: null,
+			time_range: [
+				this.$moment()
+					.startOf('month')
+					.format('YYYY-MM-DD'),
+				this.$moment()
+					.endOf('month')
+					.format('YYYY-MM-DD')
+			],
+			formData: {
+				this_only: '',
+				status: '',
+				page: 1,
+				page_size: 10,
+				export: 0,
+				sn: '',
+				employee_id: '',
+				start_time: '',
+				end_time: ''
+			},
+
+			total: 0,
+			pageLimit: 10,
+			selectIds: [],
+			// 长连接结果
+			results: [], //提交的返回结果集合
+			isResult: false,
+			percentage: 0,
+			resultList: [], //要发送数据的集合
+			resultIndex: 0,
+			isShowError: false,
+			isShowError2: false,
+			errorMsg: '服务器繁忙,请稍后再试',
+			breakList: [],
+			isShowBreak: false,
+			isCancel: false,
+			isDetail: false,
+			addTypeName: {
+				id: '',
+				remark: ''
+			},
+			detailData: {
+				employee: {}
 			}
 		};
 	},
 
 	watch: {
-		isUpdate(val) {
+		'formData.employee_id'() {
+			this.formData.page = 1;
+			this.getList();
+		},
+		'formData.sn'() {
+			this.formData.page = 1;
+			this.getList();
+		},
+		'formData.status'() {
+			this.formData.page = 1;
+			this.getList();
+		},
+		time_range() {
+			this.formData.page = 1;
+			this.getList();
+		},
+		isResult(val) {
 			if (!val) {
-				this.update = {
-					type: 'daily',
-					target_date: '',
-					target_month: ''
-				};
+				this.isShowError = false;
+				this.isShowBreak = false;
+				this.errorMsg = '服务器繁忙,请稍后再试';
+				this.$socketApi.closewebsocket();
+				this.getList();
 			}
 		}
 	},
 	created() {
-		this.employee_map = JSON.parse(localStorage.getItem('userList'));
+		this.employee_map = this.$getCache('userList');
 	},
 	mounted() {
-		this.checkingIn_group(); //考勤组
+		this.getList(); //考勤组
+		let data = this.$getCache('conversion');
+		if (data) {
+			this.breakList = data.obj;
+			this.isShowBreak = true;
+		}
 	},
 	methods: {
-		saveUpdate() {
-			let update = this.update;
-			let data = { type: update.type };
-			if (update.type == 'daily') {
-				if (!update.target_date) {
-					this.$message.error('请选择日期');
-					return false;
-				}
-				data.target_date = update.target_date;
-			} else {
-				if (!update.target_month) {
-					this.$message.error('请选择月份');
-					return false;
-				}
-				data.target_month = update.target_month;
-			}
-			this.$axios('post', '/api/ding/ad_sync', data).then(res => {
-				if (res.data.code == 1) {
-					this.$message.success('已更新');
-					this.isUpdate = false;
+		operation(url, str, data) {
+			this.$confirm(`您确认${str}该奖品?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				this.$axios('post', url, data).then(res => {
+					this.$message.success(`已${str}`);
+					this.isCancel = false;
+					this.getList();
+				});
+			});
+		},
+		// 提交表单
+		subGroupForm(formName) {
+			this.$refs[formName].validate(valid => {
+				if (valid) {
+					this.operation('api/shop/exchange/cancel', '取消', this.addTypeName);
 				}
 			});
 		},
-		exportRanking() {
-			if (this.checkingInGroup.length > 0) {
-				this.exportData.group_id = this.checkingInGroup[0].id;
+		//取消
+		cancel(id) {
+			this.isCancel = true;
+			if (this.$refs['addTypeName']) {
+				this.$refs['addTypeName'].resetFields();
 			}
-			this.dialogVisible = true;
+			this.addTypeName.remark = '';
+			this.addTypeName.id = id;
 		},
-		exportExcel() {
-			window.open(
-				process.env.VUE_APP_BASE_API +
-					'api/download/groups_ranking/export?start_date=' +
-					this.exportTime_range[0] +
-					'&end_date=' +
-					this.exportTime_range[1] +
-					'&page=' +
-					1 +
-					'&page_size=' +
-					2000 +
-					'&group_id=' +
-					this.exportData.group_id +
-					'&event_type=' +
-					this.exportData.event_type +
-					'&employee_id=' +
-					this.$getUserData().id,
-				'_blank'
-			);
+		//撤销
+		revoke(id) {
+			this.operation('api/shop/exchange/revoke', '撤销', { id: id });
 		},
-		selectgroupId() {
-			this.get_all_integral();
+		//发放
+		grant(id) {
+			this.operation('api/shop/exchange/deal', '发放', { id: id });
 		},
-		onFilterChanged() {
-			this.get_all_integral();
+		selectable(e) {
+			return e.status == 0;
 		},
-		//分页
-		handleSizeChange1(val) {
-			this.pageLimit1 = val;
-			this.formData.page_size = this.pageLimit1;
-			this.get_all_integral();
+		// 关闭缓存弹窗
+		colseBreak() {
+			this.isShowBreak = false;
+			this.breakList = [];
+			this.$removeCache('conversion');
 		},
-		handleCurrentChange(val) {
-			this.formData.page = val;
-			this.get_all_integral();
+		// 提交缓存奖扣
+		submitBreak() {
+			this.$removeCache('conversion');
+			this.resultList = JSON.parse(JSON.stringify(this.breakList));
+			this.resultIndex = 0;
+			this.percentage = 0;
+			this.results = [];
+			this.isResult = true;
+			this.opneWebSocket();
 		},
-		//请求数据
-		checkingIn_group() {
+		returnName(id) {
+			return this.employee_map[id].name;
+		},
+		grants() {
+			if (this.selectIds.length == 0) {
+				this.$message.error('请选择兑换记录');
+				return false;
+			}
+			this.webSocket();
+		},
+		webSocket() {
+			let arr = [];
+			this.selectIds.forEach(item => {
+				let data = {
+					type: 'consume_deal',
+					id: item.id,
+					name: item.name
+				};
+				arr.push(data);
+			});
+			this.resultList = arr;
+			this.resultIndex = 0;
+			this.percentage = 0;
+			this.results = [];
+			this.isResult = true;
+			this.opneWebSocket();
+		},
+		opneWebSocket() {
+			let wsData = this.resultList;
+			if (wsData[this.resultIndex] && !this.isShowError) {
+				this.$socketApi.sendData(wsData[this.resultIndex], this.onmessageWS);
+			}
+		},
+		onmessageWS(e) {
+			if (e.type == 'consume_deal') {
+				this.results.unshift(e.result);
+				this.resultIndex++;
+				this.opneWebSocket();
+				// 进度条
+				let lng = this.resultList.length;
+				this.percentage += Math.floor(100 / lng);
+				if (lng == this.results.length) {
+					this.percentage = 100;
+				}
+			}
+			// 中途断开
+			if (e.type == 'break') {
+				let wsData = this.resultList;
+				this.errorMsg = e.msg;
+				let data = {
+					obj: wsData.slice(this.resultIndex, wsData.length)
+				};
+				this.$setCache('conversion', data);
+				this.isShowError2 = true;
+			}
+			// 连接不上
+			if (e.type == 'error') {
+				this.errorMsg = e.msg;
+				this.isShowError = true;
+			}
+		},
+		handleSelectionChange(e) {
+			this.selectIds = e.map(item => {
+				let data = {
+					id: item.id,
+					name: item.employee.name
+				};
+				return data;
+			});
+		},
+		openDetail(e) {
+			this.isDetail = true;
 			this.attendload = true;
-			let self = this;
-			let params = {
-				page: 1,
-				page_size: 2000
-			};
-			this.$axios('get', '/api/ad/groups', params)
+			this.$axios('get', '/api/shop/exchange/detail', { id: e.id })
 				.then(res => {
-					if (res.data.code == 1) {
-						let list = res.data.data.list;
-						let datas = [];
-						for (let key in list) {
-							let obj = {};
-							obj.id = key;
-							obj.name = list[key];
-							datas.push(obj);
-						}
-						this.checkingInGroup = datas;
-						this.formData.group_id = datas[0].id;
-					}
+					this.detailData = res.data.data;
 				})
 				.finally(() => {
-					this.get_all_integral();
 					this.attendload = false;
 				});
 		},
+		exportExcel() {
+			let url=`${process.env.VUE_APP_BASE_API}/api/download/shop/exchange/list?page=1&download_employee_id=${this.$getUserData().id}&page_size=8000&start_time=${this.time_range[0]}&end_time=${this.time_range[1]}`;
+			if(this.formData.employee_id){
+				url=url+'&employee_id='+this.formData.employee_id
+			}
+			if (this.formData.status === 0 || this.formData.status === 1 || this.formData.status === 2) {
+				url=url+'&status='+this.formData.status
+			}
+			window.open(url,'_blank');
+		},
+		//分页
+		handleSizeChange(val) {
+			this.pageLimit = val;
+			this.formData.page_size = this.pageLimit;
+			this.getList();
+		},
+		handleCurrentChange(val) {
+			this.formData.page = val;
+			this.getList();
+		},
 		//请求数据
-		get_all_integral() {
-			let self = this;
-			self.loading = true;
+		getList() {
+			this.loading = true;
 			let data = {
-				group_id: this.formData.group_id,
+				self_only: '2',
 				page: this.formData.page,
 				page_size: this.formData.page_size,
-				event_type: this.formData.event_type
+				// status: this.formData.status,
+				export: this.formData.export,
+				sn: this.formData.sn
+				// employee_id: this.formData.employee_id,
 			};
-			data.start_date = this.time_range[0];
-			data.end_date = this.time_range[1];
-			this.$axios('post', '/api/ad/rank', data)
+			if (this.formData.employee_id) {
+				data.employee_id = this.formData.employee_id;
+			}
+
+			if (this.formData.status === 0 || this.formData.status === 1 || this.formData.status === 2) {
+				data.status = this.formData.status;
+			}
+			data.start_time = this.time_range[0];
+			data.end_time = this.time_range[1];
+			this.$axios('get', '/api/shop/exchange/list', data)
 				.then(res => {
-					if (res.data.code == 1) {
-						self.all_integral_list = res.data.data.list;
-						this.total = res.data.data.total;
-					} else {
-						self.$message.error(res.data.data.msg);
-					}
+					this.list = res.data.data.list;
+					this.total = res.data.data.count;
 				})
 				.finally(() => {
-					self.loading = false;
+					this.loading = false;
 				});
 		}
 	}
@@ -371,6 +578,27 @@ export default {
 </script>
 
 <style scoped lang="scss">
+.message .flex-box-ce {
+	margin-bottom: 10px;
+}
+.tabel {
+	width: 80px;
+	color: #606266;
+}
+.imgBox {
+	width: 350px;
+	border-radius: 5px;
+	border: 1px solid #f1f1f1;
+	margin: 10px 0;
+	box-shadow: 0 0 5px #f1f1f1;
+}
+.results {
+	border-bottom: 1px solid #f1f1f1;
+	text-align: center;
+}
+.results div {
+	padding: 10px;
+}
 .el-date-editor.el-input {
 	width: auto;
 }

+ 6 - 2
src/views/welfare/flBox.vue

@@ -5,7 +5,7 @@
 				<flManagement></flManagement>
 			</el-tab-pane>
 			<el-tab-pane label="操作记录" name="2">
-				<operatingRecord></operatingRecord>
+				<operatingRecord ref="operatingRecord"></operatingRecord>
 			</el-tab-pane>
 		</el-tabs>
 	</div>
@@ -36,7 +36,11 @@ export default {
 		}
 	},
 	methods: {
-		handleClick() {},
+		handleClick(e) {
+			if(e.name==2){
+				this.$refs.operatingRecord.get_all_integral()
+			}
+		},
 	},
 	created() {
 	}

+ 480 - 150
src/views/welfare/flManagement.vue

@@ -9,7 +9,7 @@
 				</div>
 				<div class="flex-box-end flex-v-ce" style="font-size: 16px;margin-left: 10px;margin-bottom: 10px;">
 					<span>当前转换比例</span>
-					<span class="blue" style="padding: 0 10px;font-weight: 600;">1 : 10</span>
+					<span class="blue" style="padding: 0 10px;font-weight: 600;">{{configData.ratio_molecule}} : {{configData.ratio_denominator}}</span>
 					<i class="el-icon-edit" style="font-size: 16px;" @click="isZh = true"></i>
 				</div>
 				<div class="flex-1"></div>
@@ -29,66 +29,79 @@
 				</div>
 				<div class="flex-box-ce" style="margin-bottom: 10px;">
 					<div class="label">人员</div>
-					<el-select v-model="select_employee_id" size="medium" filterable placeholder="请输入或选择人员" clearable>
+					<el-select v-model="formData.employee_id" size="medium" filterable placeholder="请输入或选择人员" clearable>
 						<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
 					</el-select>
 				</div>
 			</div>
 
 			<el-table :data="list" style="width: 100%" v-loading="loading" @selection-change="deleteEvents">
-				<el-table-column label="姓名" align="center" prop="point">
+				<el-table-column label="姓名" align="left" prop="point">
 					<template slot-scope="scope">
 						<div class="flex-box">
-							<userImage :user_name="scope.row.employee_name" :img_url="scope.row.employee_img_url" width="50px" height="50px"></userImage>
-							<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.employee_name }}</span>
+							<userImage :user_name="scope.row.name" :img_url="scope.row.img_url" width="50px" height="50px"></userImage>
+							<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.name }}</span>
 						</div>
 					</template>
 				</el-table-column>
-				<el-table-column label="部门" align="center" prop="point"></el-table-column>
-				<el-table-column label="累计B分" align="center" prop="point"></el-table-column>
-				<el-table-column label="当前可转B分" align="center" prop="point">
+				<el-table-column prop="dept" label="部门">
+				  <template slot-scope="scope">
+					<div v-if="scope.row.employee_detail.dept_list.length > 0">
+					  <span v-for="(item, index) in scope.row.employee_detail.dept_list" :key="index">
+						{{ item.dept_name }}
+						<span v-if="scope.row.employee_detail.dept_list.length - index > 1">,</span>
+					  </span>
+					</div>
+					<span v-else>--</span>
+				  </template>
+				</el-table-column>
+				<!-- <el-table-column label="累计B分" align="center" prop="total_point"></el-table-column> -->
+				<el-table-column label="当前可转B分余额" align="center" prop="may_point">
 					<template slot="header" slot-scope="scope">
 					  <el-tooltip effect="dark" placement="top-start">
 					    <div slot="content">
 					      <div style="margin-bottom: 10px;">说明</div>
 					      <div style="padding-left: 20px;">
-							  1、可转B分余额,来自员工在企业内所得的累计B分(包含基础分和工龄分)			        <br />
+							  1、可转B分余额,来自员工在企业内所得的累计B分(包含基础分和工龄分)			        <br />
 							  2、员工可以通过获得更多的累计B分,来增加可转B分余额的收入			        <br />
 							  3、回收功勋点不会增加可转B分余额			        <br />
 							  4、转换成功勋点后,余额将被扣除
 					      </div>
 					    </div>
 					    <span>
-					      <span>当前可转B分</span>
+					      <span>当前可转B分余额</span>
 					      <i class="el-icon-warning"></i>
 					    </span>
 					  </el-tooltip>
 					</template>
-					
 				</el-table-column>
-				<el-table-column label="转换后可得功勋点" align="center" prop="point"></el-table-column>
-				<el-table-column label="现有功勋点" align="center" prop="point"></el-table-column>
+				<el-table-column label="转换后可得功勋点" align="center" prop="acquire_point"></el-table-column>
+				<el-table-column label="现有功勋点" align="center" prop="achievement">
+					<template slot-scope="scope">
+						<span v-if="scope.row.achievement">
+							{{scope.row.achievement.achievement}}
+						</span>
+						<span v-else>0</span>
+					</template>
+				</el-table-column>
 				<el-table-column label="操作">
 					<template slot-scope="scope">
-						<el-link type="primary" @click="moreMessage(scope.row.id)" :underline="false" style="padding-right: 10px;">个人明显</el-link>
+						<el-link type="primary" @click="moreMessage(scope.row.id)" :underline="false" style="padding-right: 10px;">个人明</el-link>
 						<el-dropdown @command="handleCommand">
 							<el-button size="mini">
 								管理
 								<i class="el-icon-arrow-down el-icon--right"></i>
 							</el-button>
 							<el-dropdown-menu slot="dropdown">
-								<el-dropdown-item :command="{id:scope.row.employee_id,name:'1'}">发放</el-dropdown-item>
-								<el-dropdown-item :command="{id:scope.row.employee_id,name:'2'}">回收</el-dropdown-item>
-								<el-dropdown-item :command="{id:scope.row.employee_id,name:'3'}">转换</el-dropdown-item>
+								<el-dropdown-item :command="{id:scope.row.id,index:'1',item:scope.row}">发放</el-dropdown-item>
+								<el-dropdown-item :command="{id:scope.row.id,index:'2',item:scope.row}">回收</el-dropdown-item>
+								<el-dropdown-item :command="{id:scope.row.id,index:'3',item:scope.row}">转换</el-dropdown-item>
 							</el-dropdown-menu>
 						</el-dropdown>
 					</template>
 				</el-table-column>
 				<template slot="empty">
-					<div class="nopoint_box">
-						<div class="noimg noperson"></div>
-						<span class="title">没有对应的数据</span>
-					</div>
+					<noData></noData>
 				</template>
 			</el-table>
 
@@ -108,8 +121,8 @@
 		<!-- 转换设置 -->
 		<el-dialog title="转换设置" :visible.sync="isZh" width="500px" top="10%">
 			<div class="flex-box-ce" style="margin-bottom: 20px;">
-				<span class="yellow flex-1">B分转换功勋点将按以下比进行转换</span>
-				<span style="cursor: pointer;" class="blue" @click="innerVisible = true">查看转换历史</span>
+				<span class="yellow flex-1">B分转换功勋点将按以下比进行转换</span>
+				<span style="cursor: pointer;" class="blue" @click="innerVisible = true">历史修改记录</span>
 			</div>
 			<div class="flex-box-ce flex-center-center" style="margin-bottom: 10px;font-size: 16px;">
 				<span>转换比例 1:</span>
@@ -123,14 +136,14 @@
 			</div>
 			<span slot="footer" class="dialog-footer">
 				<el-button @click="isZh = false" size="medium">取 消</el-button>
-				<el-button type="primary" @click="exportExcel" size="medium">确 定</el-button>
+				<el-button type="primary" @click="editRatio" size="medium">确 定</el-button>
 			</span>
-			<el-dialog width="500px" title="历史转换比例记录" :visible.sync="innerVisible" append-to-body>
+			<el-dialog width="500px" title="历史修改记录" :visible.sync="innerVisible" append-to-body>
 				<div style="max-height: 400px;overflow-y: auto;" class="scroll-bar">
-					<div v-for="(item, index) in innerList" :key="index" style="padding-bottom: 16px;">
-						<span class="green">{{ item.name }}</span>
-						在{{ item.date }} 修改转换比列
-						<span class="blue">{{ item.num }}</span>
+					<div v-for="(item, index) in configData.change_log" :key="index" style="padding-bottom: 16px;">
+						<span class="green">{{ item.employee_name }}</span>
+						在 {{ $moment.unix(item.time).format('YYYY年MM月DD日  HH:mm:ss') }} 修改转换比例
+						<span class="blue">{{ item.molecule }}:{{ item.denominator }}</span>
 					</div>
 				</div>
 				<span slot="footer" class="dialog-footer"><el-button @click="innerVisible = false" size="medium">关 闭</el-button></span>
@@ -139,6 +152,14 @@
 		<!-- 发放/回收/转换 -->
 		<el-dialog :title="czText + '功勋点'" :visible.sync="isCz" width="500px" top="10%">
 			<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="120px">
+				<div v-if="isEmployee&&czText!='发放'" class="yellow" style="text-align: center;margin-bottom: 17px;">
+					<span v-if="czText=='回收'">该操作将会{{czText}}所选对象的全部功勋点,请谨慎操作</span>
+					<span v-else>该操作将会{{czText}}所选对象的全部可转B分,请谨慎操作</span>
+				</div>
+				<div class="flex-box-ce" v-if="!isEmployee&&ruleForm.employee_ids[0]" style="margin-bottom: 17px;">
+					<span style="width: 120px;text-align: right;box-sizing: border-box;padding-right: 10px;">{{czText}}对象</span>
+					<span>{{returnName(ruleForm.employee_ids[0])}}</span>
+				</div>
 				<el-form-item :label="czText+'对象'" prop="employee_ids" v-if="isEmployee">
 					<div class="border flex-box-ce">
 						<div class="flex-1" v-if="Administrator.length == 0">请选择人员</div>
@@ -153,18 +174,30 @@
 						<div @click="openAdministrator()" class="inputDc"></div>
 					</div>
 				</el-form-item>
-				<el-form-item :label="czText+'数值'" prop="zhNum">
-					<el-input type="text" class="width-250" placeholder="请输入功勋点" v-model="ruleForm.zhNum" @input="[ruleForm.zhNum=ruleForm.zhNum.replace(/[^\d]/g,'')]"/>
-				</el-form-item>
-				<el-form-item label="备注原因:" prop="content">
+				
+				<template v-if="czText=='发放'||!isEmployee">
+					<template v-if="czText=='转换'">
+						<el-form-item :label="'B分'+czText+'功勋点'" prop="num">
+							<el-input type="text" style="width: 150px;" placeholder="请输入B分" v-model="ruleForm.num" @input="[ruleForm.num=ruleForm.num.replace(/[^\d]/g,'')]"/>
+							<i class="el-icon-sort" style="transform: rotate(90deg);margin: 0 5px;"></i>
+							<el-input type="text" style="width: 90px;" v-model="countVal" disabled/>
+						</el-form-item>
+						<div style="padding-left: 120px;">转换比例 <span class="blue">{{configData.ratio_molecule}} : {{configData.ratio_denominator}}</span></div>
+					</template>
+					<el-form-item :label="czText+'功勋点'" prop="num" v-else>
+						<el-input type="text" class="width-250" placeholder="请输入功勋点" v-model="ruleForm.num" @input="[ruleForm.num=ruleForm.num.replace(/[^\d]/g,'')]"/>
+					</el-form-item>
+				</template>
+				
+				<el-form-item label="备注" prop="remark">
 					<el-input
 						type="textarea"
-						v-model="ruleForm.content"
-						placeholder="请输入原因"
+						v-model="ruleForm.remark"
+						placeholder="请输入备注"
 						class="width-250"
 						:autosize="{ minRows: 3, maxRows: 6 }"
 						show-word-limit
-						maxlength="100"
+						maxlength="200"
 					></el-input>
 				</el-form-item>
 			</el-form>
@@ -173,6 +206,7 @@
 				<el-button type="primary" @click="submit('ruleForm')" size="medium">确 定</el-button>
 			</span>
 		</el-dialog>
+		
 		<el-dialog title="选择人员" width="640px" :visible.sync="isChecks" append-to-body>
 			<EmployeeSelector ref="members" v-if="isChecks" :selected="selected" @confirm="employeeConfirm" />
 			<span slot="footer" class="dialog-footer">
@@ -181,39 +215,140 @@
 			</span>
 		</el-dialog>
 		<!-- 个人明细 -->
-		<el-dialog title="个人明细" width="700px" :visible.sync="isDetail" top="5%">
-			<div class="flex-box-ce">
-				<div class="titled" v-for="(item,index) in detailData" :key="index">
-					<div class="num" :class="item.num>0? 'blue':'red'">{{item.num}}</div>
-					<div class="fontColorF">{{item.name}}</div>
+		<el-dialog title="个人明细" width="800px" :visible.sync="isDetail" top="5%">
+			<div v-loading="loadingDetail">
+				<div class="flex-box-ce">
+					<div class="titled" v-for="(item,index) in detailData" :key="index">
+						<div class="num" :class="item.num>=0? 'blue':'red'">{{item.num}}</div>
+						<div class="fontColorF">{{item.name}}</div>
+					</div>
 				</div>
+				<div class="flex-box-end " style="margin-bottom: 10px;">
+					<el-button type="primary" plain size="small" @click="exportExcel">导出个人明细</el-button>
+				</div>
+				<el-table :data="DetailList" style="width: 100%" border>
+					<el-table-column label="姓名" align="left" prop="point">
+						<template slot-scope="scope">
+							<div class="flex-box">
+								<!-- <userImage :user_name="scope.row.employee.name" :id="scope.row.employee.id" width="50px" height="50px"></userImage> -->
+								<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.employee.name }}</span>
+							</div>
+						</template>
+					</el-table-column>
+<!-- 					<el-table-column prop="dept" label="部门"  align="center" min-width="200">
+						<template slot-scope="scope">
+							<div v-if="scope.row.employee.employee_detail.dept_list.length > 0">
+								<span v-for="(item, index) in scope.row.employee.employee_detail.dept_list" :key="index">
+									{{ item.dept_name }}
+									<span v-if="scope.row.employee.employee_detail.dept_list.length - index > 1">,</span>
+								</span>
+							</div>
+							<span v-else>--</span>
+						</template>
+					</el-table-column> -->
+					<el-table-column label="类型" align="center">
+							<template slot-scope="scope">
+								<span v-if="scope.row.type==1">发放</span>
+								<span v-if="scope.row.type==2">回收</span>
+								<span v-if="scope.row.type==3">转换</span>
+								<span v-if="scope.row.type==4">兑换</span>
+							</template>
+					</el-table-column>
+					<el-table-column label="功勋点" align="center" prop="achievement"></el-table-column>
+					<el-table-column label="描述" align="center" prop="remark" min-width="200">
+						<template slot-scope="scope">
+							<el-tooltip  effect="dark" :content="scope.row.remark" placement="top">
+								<div slot="content" style="max-width: 400px;">{{scope.row.remark}}</div>
+								<div class="remark">{{scope.row.remark}}</div>
+							</el-tooltip>
+						</template>
+					</el-table-column>
+					<el-table-column label="时间" align="center" prop="point" min-width="150">
+						<template slot-scope="scope">
+							{{ $moment.unix(scope.row.create_time).format('YYYY-MM-DD HH:mm') }}
+						</template>
+					</el-table-column>
+					<template slot="empty">
+						<noData></noData>
+					</template>
+				</el-table>
+				<center style="padding-top: 20px;">
+					<el-pagination background 
+						:current-page="detail_page" 
+						:page-size="5" 
+						@current-change="handleCurrentChange2" 
+						layout="total, prev, pager, next" 
+						:total="count">
+					</el-pagination>
+				</center>
 			</div>
-			<div class="flex-box-end " style="margin-bottom: 10px;">
-				<el-button type="primary" plain size="small">导出个人明细</el-button>
-			</div>
-			<el-table :data="[]" style="width: 100%" border v-loading="loading">
-				<el-table-column label="姓名" align="left" prop="point"></el-table-column>
-				<el-table-column label="部门" align="center" prop="point"></el-table-column>
-				<el-table-column label="功勋点" align="center" prop="point"></el-table-column>
-				<el-table-column label="描述" align="center" prop="point"></el-table-column>
-				<el-table-column label="时间" align="center" prop="point"></el-table-column>
-				<template slot="empty">
-					<noData></noData>
-				</template>
-			</el-table>
-			<center style="padding-top: 20px;">
-					  <el-pagination
-					   background
-						@current-change="handleCurrentChange2"
-						layout="prev, pager, next"
-						:total="total">
-					  </el-pagination>
-			</center>
+
 			<span slot="footer" class="dialog-footer">
-				<el-button @click="isDetail = false">取 消</el-button>
-				<el-button type="primary">确 定</el-button>
+				<el-button @click="isDetail = false">关 闭</el-button>
 			</span>
 		</el-dialog>
+		
+		<el-dialog title="提交结果" :visible.sync="isResult"  width="800" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
+			<div v-if="!isShowError">
+				<div style="text-align: center;margin-bottom: 10px;" class="red" v-if="isShowError2">{{errorMsg}}</div>
+				<el-progress :text-inside="true" :stroke-width="24" :percentage="percentage"></el-progress>
+				<div style="margin-top: 20px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
+					<div class="flex-box-ce results" style="font-weight: 600;">
+						<div style="border-right: 1px solid #f1f1f1;width: 50px;">序号</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">对象</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">功勋点</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">备注</div>
+						<div class="flex-2" >提交结果</div>
+					</div>
+					<div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
+						<div style="border-right: 1px solid #f1f1f1;width: 50px;">{{results.length-index}}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{returnName(item.task.msg.employee_id)}}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.task.msg.num }}</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.task.msg.remark }}</div>
+						<div class="flex-2 green" v-if="item.status==1">{{ item.msg }}</div>
+						<div class="flex-2 red" v-else>{{ item.msg }}</div>
+					</div>
+				</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;" v-show="isShowError2&&results.length!=resultList.length"><el-button type="primary" @click="isResult = false" size="small">确 定</el-button></div>
+					<div class="flex-box-end" style="margin-top: 20px;" v-show="results.length==resultList.length"><el-button type="primary" @click="isResult = false" size="small">确 定</el-button></div>
+				</span>
+			</div>
+			<div v-else>
+				<div style="text-align: center;" class="red">{{errorMsg}}</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;"><el-button type="primary" @click="isResult = false" size="small">确 定</el-button></div>
+				</span>
+			</div>
+		</el-dialog>
+		<!-- 缓存的奖扣 -->
+		<el-dialog title="网络中断提交列表" :visible.sync="isShowBreak"  width="800" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
+			<div>
+				<template v-if="breakList[0]">
+					<div v-if="breakList[0].type=='achievement_grant'" style="text-align: center;margin-bottom: 10px;" class="blue">发放功勋点</div>
+					<div v-if="breakList[0].type=='achievement_take_back'" style="text-align: center;margin-bottom: 10px;" class="blue">回收功勋点</div>
+					<div v-if="breakList[0].type=='achievement_exchange'" style="text-align: center;margin-bottom: 10px;" class="blue">转换功勋点</div>
+				</template>
+				<div style="margin-top: 20px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
+					<div class="flex-box-ce results" style="font-weight: 600;">
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">对象</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">功勋点</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">备注</div>
+					</div>
+					<div class="flex-box-ce results" v-for="(item, index) in breakList" :key="index">
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{returnName(item.employee_id)}}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.num }}</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.remark }}</div>
+					</div>
+				</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;">
+						<el-button type="primary" @click="colseBreak()" size="small">取 消</el-button>
+						<el-button type="primary" @click="submitBreak()" size="small">再次提交</el-button>
+					</div>
+				</span>
+			</div>
+		</el-dialog>
 	</div>
 </template>
 <script>
@@ -223,80 +358,101 @@ export default {
 	components: { EmployeeSelector },
 	data() {
 		return {
-			activeName: '1',
-			select_employee_id: '',
 			employee_map: [],
 			dept_name: [],
 			dept_tree: [],
 			loading: false,
 			formData: {
-				dept_id: '0',
-				sort: 'DESC',
+				dept_id: 0,
+				employee_id: '',
 				page: 1,
 				page_size: 10,
-				pt_id: 3,
-				type: 'all'
 			},
 			list: null,
 			pageLimit: 10,
 			total: null,
-			isZh: false,
-			zhNum:1,
-			positions: [{ id: 0, age: 'all', name: '全部' }, { id: 1, age: 'manager', name: '管理者' }, { id: 2, age: 'employee', name: '员工' }],
-			Dc_Data: {
-				//导出数据
-				value1: '', //时间
-				DC_position: '全部', //人员
-				dept_name: [] //部门
-			},
 			innerVisible: false,
-			innerList: [
-				{ name: '阿松大阿松大', date: '2020-20-1', num: '1:30' },
-				{ name: '阿松大阿松大', date: '2020-20-1', num: '1:30' },
-				{ name: '阿松大阿松大', date: '2020-20-1', num: '1:30' },
-				{ name: '阿松大阿松大', date: '2020-20-1', num: '1:30' }
-			],
 
 			// 发放/回收/转换
 			Administrator: [],
 			isChecks: false,
 			selected: { dept: [], employee: [] },
 			ruleForm: {
-				content: '',
-				zhNum: '', 
+				remark: '',
+				num: '', 
 				employee_ids: []
 			},
 			rules: {
-				zhNum: [{ required: true, message: '请输入数值', trigger: 'blur' }],
-				employee_ids: [{ required: true, message: '请选择被考核人员', trigger: 'change' }]
+				num: [{required: true, message: '请输入数值', trigger: 'blur' }],
+				employee_ids: [{ required: true, message: '请选择人员', trigger: 'change' }]
 			},
 			czText: '发放',
 			isCz: false,
 			isEmployee:true,
+			countVal:0,
 			
 			// 个人明显
 			isDetail:false,
+			loadingDetail:false,
+			count:0,
+			detail_page:1,
+			DetailList:[],
+			detailId:0,
 			detailData:[
 				{name:'现有功勋点',num:1000},
 				{name:'管理员发放',num:254},
 				{name:'B分转换',num:20},
-				{name:'同事点赞',num:166},
 				{name:'兑换奖品',num:-100},
 				{name:'被回收',num:-25}
-			]
+			],
+			// 转换比例
+			configData:{},
+			isZh: false,
+			zhNum:1,
+			
+			// 长连接结果
+			results: [], //提交的返回结果集合
+			isResult: false,
+			percentage: 0,
+			resultList:[],//要发送数据的集合
+			resultIndex:0,
+			isShowError:false,
+			isShowError2:false,
+			errorMsg:'服务器繁忙,请稍后再试',
+			breakList:[],
+			isShowBreak:false,
 		};
 	},
 	watch: {
+		'ruleForm.num'(val){
+			if(this.czText=='转换'){
+				this.countVal=val*this.configData.ratio_denominator;
+			}
+		},
+		'formData.employee_id'(){
+			this.formData.page = 1;
+			this.get_list();
+		},
+		isZh(val){
+			if(val){
+				this.zhNum=this.configData.ratio_denominator;
+			}
+		},
 		isCz(val){
 			if(!val){
-				this.ruleForm={
-				content: '',
-				zhNum: '', 
-				employee_ids:[]
-				};
+				this.$refs['ruleForm'].resetFields();
+				this.ruleForm={remark: '',num: '', employee_ids:[]};
 				this.isEmployee=true;
+				this.countVal=0;
 				this.Administrator= [];
 				this.selected={ dept: [], employee: [] };
+				this.$socketApi.closewebsocket();
+			}
+		},
+		isDetail(val) {
+			if(!val){
+				this.detail_page=1;
+				
 			}
 		},
 		dept_name(val) {
@@ -310,30 +466,205 @@ export default {
 				this.$refs.dept.dropDownVisible = false;
 				this.get_list();
 			});
-		}
+		},
+		isResult(val){
+			if(!val){
+				this.isCz=false;
+				this.isShowError = false;
+				this.isShowBreak = false;
+				this.errorMsg='服务器繁忙,请稍后再试';
+				this.$socketApi.closewebsocket();
+				this.get_list();
+			}
+		},
 	},
 	methods: {
-		moreMessage(){
-			this.isDetail=true;
+		exportExcel() {
+			let url=`${process.env.VUE_APP_BASE_API}/api/download/shop/achievement/detail?page=1&page_size=8000&employee_id=${this.detailId}&download_employee_id=${this.$getUserData().id}`;
+			window.open(url,'_blank');
 		},
-		handleCommand(e){
-			this.ruleForm.employee_ids.push(e.id);
-			this.isEmployee=false;
-			this.openCz(Number(e.name))
+		// 关闭缓存弹窗
+		colseBreak(){
+			this.isShowBreak = false;
+			this.breakList=[];
+			this.$removeCache('flManagement');
+		},
+		// 提交缓存奖扣
+		submitBreak(){
+			this.$removeCache('flManagement');
+			this.resultList=JSON.parse(JSON.stringify(this.breakList));
+			this.resultIndex=0;
+			this.percentage=0;
+			this.results=[];
+			this.isResult=true;
+			this.opneWebSocket()
+		},
+		returnName(id){
+			return this.employee_map[id].name
 		},
 		submit(str){
+			if(this.czText=='发放'&&this.ruleForm.num==0){
+				this.$message.error("功勋点数值不能为0或者空")
+				return
+			}
+			if(this.ruleForm.num>10000000){
+				this.$message.error("功勋点数值不能大于10000000")
+				return
+			}
 			this.$refs[str].validate((valid) => {
 			  if (valid) {
-				console.log(this.ruleForm)
+				  this.$confirm(`您确认 ${this.czText} 功勋点?`, '提示', {
+				  	confirmButtonText: '确定',
+				  	cancelButtonText: '取消',
+				  	type: 'warning'
+				  }).then(() => {
+						this.webSocket()
+				  });
 			  } else {
 				console.log('error submit!!');
 				return false;
 			  }
+			}); 
+		},
+		webSocket(data){
+			let type='achievement_grant';
+			switch (this.czText) {
+				case '发放':
+					type = 'achievement_grant';
+					break;
+				case '回收':
+					type = 'achievement_take_back';
+					break;
+				case '转换':
+					type = 'achievement_exchange';
+					break;
+			}
+			let arr=[];
+			this.ruleForm.employee_ids.forEach(item=>{
+				let data={
+					type:type,
+					employee_id:item,
+					num:this.ruleForm.num||0,
+					remark:this.ruleForm.remark,
+					all:(type=='achievement_grant'||!this.isEmployee)? 0:1
+				}
+				arr.push(data)
+			})
+			this.resultList=arr;
+			this.resultIndex=0;
+			this.percentage=0;
+			this.results=[];
+			this.isResult=true;
+			this.opneWebSocket()
+		},
+		opneWebSocket() {
+			let wsData=this.resultList;
+			if(wsData[this.resultIndex]&&!this.isShowError){
+				this.$socketApi.sendData(wsData[this.resultIndex],this.onmessageWS)
+			}
+		},
+		onmessageWS(e){
+			if(e.type=='achievement_grant'||e.type=='achievement_take_back'||e.type=='achievement_exchange'){
+				this.results.unshift(e.result);
+				this.resultIndex++;
+				this.opneWebSocket();
+				// 进度条
+				let lng = this.resultList.length;
+				this.percentage += Math.floor(100 / lng);
+				if (lng == this.results.length) {
+					this.percentage = 100;
+				}
+			}
+			// 中途断开
+			if(e.type=='break'){
+				let wsData=this.resultList;
+				this.errorMsg=e.msg
+				let data={
+					obj:wsData.slice(this.resultIndex,wsData.length)
+				}
+				this.$setCache('flManagement',data);
+				this.isShowError2 = true;
+			}
+			// 连接不上
+			if(e.type=='error'){
+				this.errorMsg=e.msg
+				this.isShowError = true;
+			}
+			
+		},
+		// 确定转换
+		editRatio() {
+			if(!Number(this.zhNum)){
+				this.$message.error("转换比例不能为0或空")
+				return
+			}
+			if(Number(this.zhNum)>1000){
+				this.$message.error("转换比例不能超过1 : 1000")
+				return
+			}
+			this.$axios('post', '/api/shop/achievement/edit_ratio',{denominator:this.zhNum}).then(res => {
+				this.isZh=false;
+				this.$message.success("设置成功");
+				this.getConfig();
+			});
+		},
+		//获取转换比例
+		async getConfig() {
+		    const w=await this.$axios('get', '/api/shop/achievement/config').then(res => {
+				this.configData =res.data.data;
+			});
+			this.get_list();
+		},
+		handleCommand(e){
+			this.ruleForm.employee_ids.push(e.id);
+			this.isEmployee=false;
+			this.openCz(Number(e.index))
+		},
+		//获取部门
+		getDepartment() {
+			this.$axios('get', '/api/department/tree').then(res => {
+				this.dept_tree = this.getTreeData(res.data.data.list);
 			});
-			this.isCz=true;   
 		},
-		keyupEvent(str){
-			this.ruleForm.zhNum=this.ruleForm.zhNum.replace(/^(0+)|[^\d]+/g,'')
+		get_list() {
+			this.loading = true;
+			let data={
+				page:this.formData.page,
+				page_size:this.formData.page_size,
+			}
+			if(Number(this.formData.dept_id)){
+				data.dept_id=this.formData.dept_id
+			}
+			if(Number(this.formData.employee_id)){
+				data.employee_id=this.formData.employee_id
+			}
+			this.$axios('get','/api/shop/achievement/list',data).then(res => {
+				let list = res.data.data.list;
+				list.forEach(item=>{
+					let may_point=item.achievement?Number(item.total_point)-Number(item.achievement.point):Number(item.total_point)
+					// item.may_point=may_point;//可转
+					// item.acquire_point=may_point*this.configData.ratio_denominator;//转换可得
+					item.may_point=may_point>=0? may_point:0;//可转
+					item.acquire_point=may_point*this.configData.ratio_denominator>=0 ? may_point*this.configData.ratio_denominator:0;//转换可得
+				})
+				this.list = list;
+				this.total = res.data.data.count;
+			}).finally(() => {
+				this.loading = false;
+			});
+		},
+		// 递归判断列表,把最后的children设为undefined
+		getTreeData(data) {
+			for (var i = 0; i < data.length; i++) {
+				if (data[i]._child.length < 1) {
+					// children若为空数组,则将children设为undefined
+					data[i]._child = undefined;
+				} else {
+					// children若不为空数组,则继续 递归调用 本方法
+					this.getTreeData(data[i]._child);
+				}
+			}
+			return data;
 		},
 		openCz(index) {
 			switch (index) {
@@ -349,6 +680,26 @@ export default {
 			}
 			this.isCz=true;
 		},
+		moreMessage(id){
+			if(id){this.detailId=id};
+			this.isDetail=true;
+			this.loadingDetail=true;
+			this.$axios('get', '/api/shop/achievement/detail',{page:this.detail_page,page_size:5,export:0,employee_id:this.detailId}).then(res => {
+				let data=res.data.data;
+				this.detailData=[
+					{name:'现有功勋点',num:data.all},
+					{name:'管理员发放',num:data.grant},
+					{name:'B分转换',num:data.exchange},
+					{name:'兑换奖品',num:data.consume},
+					{name:'被回收',num:data.take_back}
+				]
+				console.log(res.data.data.count)
+				this.DetailList =data.list;
+				this.count =data.count;
+			}).finally(()=>{
+				this.loadingDetail=false;
+			});
+		},
 		// 选择录入对象
 		employeeConfirm(e) {
 			this.ruleForm.employee_ids = e.employee.map(item=>{
@@ -360,9 +711,6 @@ export default {
 		},
 		openAdministrator() {
 			this.isChecks = true;
-		},
-		handleClick() {
-			
 		},
 		deleteEvents(selection) {
 			let listId = [];
@@ -371,10 +719,9 @@ export default {
 			});
 			this.selectionID = listId;
 		},
-		exportExcel() {},
 		handleCurrentChange2(val) {
-			this.formData.page = val;
-			this.get_list();
+			this.detail_page = val;
+			this.moreMessage();
 		},
 		// 页面变更
 		handleCurrentChange(val) {
@@ -386,52 +733,35 @@ export default {
 			this.formData.page_size = this.pageLimit;
 			this.get_list();
 		},
-		//获取部门
-		getDepartment() {
-			this.$axios('get', '/api/department/tree').then(res => {
-				this.dept_tree = this.getTreeData(res.data.data.list);
-			});
-		},
-		get_list() {
-			this.loading = true;
-			this.$axios('get', '/api/integral/statistics/ranking', this.formData, 'v2')
-				.then(res => {
-					if (res.data.code == 1) {
-						this.list = res.data.data.list;
-						this.total = res.data.data.total;
-					} else {
-						this.$message.error(res.data.data.msg);
-					}
-				})
-				.finally(() => {
-					this.loading = false;
-				});
-		},
-		// 递归判断列表,把最后的children设为undefined
-		getTreeData(data) {
-			for (var i = 0; i < data.length; i++) {
-				if (data[i]._child.length < 1) {
-					// children若为空数组,则将children设为undefined
-					data[i]._child = undefined;
-				} else {
-					// children若不为空数组,则继续 递归调用 本方法
-					this.getTreeData(data[i]._child);
-				}
-			}
-			return data;
-		}
 	},
 	created() {
 		this.getDepartment();
-		this.employee_map = JSON.parse(localStorage.getItem('userList'));
+		this.getConfig();
+		this.employee_map = this.$getCache('userList');
 	},
 	mounted() {
-		this.tips_show = JSON.parse(localStorage.getItem('total_rank_tips')) ? false : true;
-		this.get_list();
+		let data=this.$getCache('flManagement');
+		if(data){
+			this.breakList=data.obj;
+			this.isShowBreak=true;	
+		}
 	}
 };
 </script>
 <style scoped lang="scss">
+	.remark{
+		  display: -webkit-box;
+		  -webkit-box-orient: vertical;
+		  overflow: hidden;
+		  -webkit-line-clamp: 2;
+	}
+	.results {
+		border-bottom: 1px solid #f1f1f1;
+		text-align: center;
+	}
+	.results div {
+		padding: 10px;
+	}
 .titled{
 	width: 110px;
 	text-align: left;

+ 175 - 174
src/views/welfare/operatingRecord.vue

@@ -1,15 +1,15 @@
 <template>
 	<div>
-		<div class="all" v-loading="attendload">
+		<div class="all">
 			<div>
 				<el-form :inline="true">
-					<el-form-item label="人">
-						<el-select v-model="select_employee_id" size="medium" filterable placeholder="请输入或选择人" clearable>
+					<el-form-item label="操作人">
+						<el-select v-model="formData.operator_id" size="medium" filterable placeholder="请输入或选择操作人" clearable>
 							<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
 						</el-select>
 					</el-form-item>
-					<el-form-item label="排名类型">
-						<el-select v-model="formData.event_type" size="medium" @change="selectgroupId" style="width:110px" placeholder="请选择">
+					<el-form-item label="类型">
+						<el-select v-model="formData.type" size="medium" style="width:110px" placeholder="请选择" clearable>
 							<el-option v-for="(item, index) in event_type" :key="index" :label="item.name" :value="item.id"></el-option>
 						</el-select>
 					</el-form-item>
@@ -26,38 +26,78 @@
 							start-placeholder="开始日期"
 							end-placeholder="结束日期"
 							:picker-options="instantPickerOptions"
-							@change="onFilterChanged"
 						></el-date-picker>
 					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" plain @click="exportRanking">导出排名</el-button>
+					<el-form-item label="人员">
+						<el-select v-model="formData.employee_id" size="medium" filterable placeholder="请输入或选择人员" clearable>
+							<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
+						</el-select>
 					</el-form-item>
+					<el-form-item><el-button type="primary" size="medium" plain @click="exportRanking">导出</el-button></el-form-item>
 				</el-form>
 			</div>
 			<el-table :data="all_integral_list" style="width: 100%" v-loading="loading">
-				<el-table-column label="名次" width="100" align="center">
+				<el-table-column label="操作人" align="left" prop="point">
+					<template slot-scope="scope">
+							<!-- <userImage :user_name="scope.row.operator.name" :id="scope.row.operator.id" width="50px" height="50px"></userImage> -->
+							<div>{{ scope.row.operator.name }}</div>
+					</template>
+				</el-table-column>
+				<el-table-column prop="point" label="操作类型" align="center">
+					<template slot-scope="scope">
+						<span v-if="scope.row.type == 1">发放</span>
+						<span v-if="scope.row.type == 2">回收</span>
+						<span v-if="scope.row.type == 3">转换</span>
+						<span v-if="scope.row.type == 4">兑换</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="create_time" label="操作时间" align="center" min-width="120">
 					<template slot-scope="scope">
-						<img v-if="scope.row.rank === 1" src="@/assets/image/statistics_NO1.png" alt />
-						<img v-if="scope.row.rank === 2" src="@/assets/image/statistics_NO2.png" alt />
-						<img v-if="scope.row.rank === 3" src="@/assets/image/statistics_NO3.png" alt />
-						<span v-if="scope.row.rank > 3">{{ scope.row.rank }}</span>
+						{{ $moment.unix(scope.row.create_time).format('YYYY-MM-DD HH:mm') }}
 					</template>
 				</el-table-column>
-				<el-table-column label="姓名" align="left">
+				<el-table-column label="姓名" align="center" prop="point">
 					<template slot-scope="scope">
-						<div style="display:flex;">
-							<userImage :user_name="scope.row.name" :img_url="scope.row.img_url" width="50px" height="50px"></userImage>
-							<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.name }}</span>
+							<!-- <userImage :user_name="scope.row.employee.name" :id="scope.row.employee.id" width="50px" height="50px"></userImage> -->
+							<div>{{ scope.row.employee.name }}</div>
+					</template>
+				</el-table-column>
+				<el-table-column prop="dept" label="部门"  align="center">
+					<template slot-scope="scope">
+						<div v-if="scope.row.employee.employee_detail.dept_list.length > 0">
+							<span v-for="(item, index) in scope.row.employee.employee_detail.dept_list" :key="index">
+								{{ item.dept_name }}
+								<span v-if="scope.row.employee.employee_detail.dept_list.length - index > 1">,</span>
+							</span>
 						</div>
+						<span v-else>--</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="gxd1" label="发放功勋点" align="center"></el-table-column>
+				<el-table-column prop="gxd2" label="回收功勋点" align="center"></el-table-column>
+				<el-table-column prop="gxd3" label="转换功勋点" align="center"></el-table-column>
+				<el-table-column prop="point" label="转换B分" align="center">
+					<template slot-scope="scope">
+						<span v-if="scope.row.type == 3">{{ scope.row.point }}</span>
+						<span v-else>--</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="point" label="转换比例" align="center">
+					<template slot-scope="scope">
+						<span v-if="scope.row.type == 3">{{ scope.row.ratio_molecule }}:{{ scope.row.ratio_denominator }}</span>
+						<span v-else>--</span>
 					</template>
 				</el-table-column>
-				<el-table-column prop="point" label="B分" align="left">
+				<el-table-column prop="remark" label="备注" align="center">
 					<template slot-scope="scope">
-						<b style="font-size:15px;color:#909399">{{ scope.row.point }}</b>
+						<el-tooltip  effect="dark" :content="scope.row.remark" placement="top">
+							<div slot="content" style="max-width: 400px;">{{scope.row.remark}}</div>
+							<div class="remark">{{scope.row.remark}}</div>
+						</el-tooltip>
 					</template>
 				</el-table-column>
 				<template slot="empty">
-					<noData :content="checkingInGroup.length == 0 ? '请先开启钉钉考勤' : '暂无数据'"></noData>
+					<noData></noData>
 				</template>
 			</el-table>
 			<center style="padding: 20px 0;">
@@ -68,30 +108,30 @@
 					:current-page="formData.page"
 					:page-sizes="[10, 20, 50, 100]"
 					layout="total, sizes, prev, pager, next"
-					:page-size="pageLimit1"
+					:page-size="pageLimit"
 					:total="total"
 				></el-pagination>
 			</center>
 		</div>
 		<!-- 导出弹窗 -->
-		<el-dialog title="导出排名" :visible.sync="dialogVisible" width="730px">
-			<div style="font-size:15px;margin:20px 0 20px 0;">系统将按以下已选条件导出对应的排名报表</div>
+		<el-dialog title="导出" :visible.sync="dialogVisible" width="730px">
+			<div style="font-size:15px;margin:20px 0 20px 0;">系统将按以下已选条件导出对应的报表</div>
 			<div v-loading="exportLoad">
 				<el-form :inline="true">
-					<el-form-item label="考勤组">
-						<el-select v-model="exportData.group_id" @change="selectgroupId" filterable :clearable="false" placeholder="请选择考勤组">
-							<el-option v-for="item in checkingInGroup" :key="item.id" :label="item.name" :value="item.id"></el-option>
+					<el-form-item label="操作人">
+						<el-select v-model="exportData.operator_id" size="medium" filterable placeholder="请输入或选择操作人" clearable>
+							<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
 						</el-select>
 					</el-form-item>
-
-					<el-form-item label="排名类型">
-						<el-select v-model="exportData.event_type" style="width:150px" placeholder="请选择">
+					<el-form-item label="类型">
+						<el-select v-model="exportData.type" size="medium" style="width:110px" placeholder="请选择" clearable>
 							<el-option v-for="(item, index) in event_type" :key="index" :label="item.name" :value="item.id"></el-option>
 						</el-select>
 					</el-form-item>
-
 					<el-form-item label="时间">
 						<el-date-picker
+							size="medium"
+							style="width:290px"
 							class="first-element-btn"
 							:clearable="false"
 							v-model="exportTime_range"
@@ -103,6 +143,11 @@
 							:picker-options="instantPickerOptions"
 						></el-date-picker>
 					</el-form-item>
+					<el-form-item label="人员">
+						<el-select v-model="exportData.employee_id" size="medium" filterable placeholder="请输入或选择人员" clearable>
+							<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item>
 				</el-form>
 				<span class="dialog-footer" style="display:flex;justify-content: flex-end;">
 					<el-button @click="dialogVisible = false">取 消</el-button>
@@ -124,39 +169,20 @@ export default {
 			},
 			exportLoad: false,
 			dialogVisible: false,
-			checkingInGroup: [],
-			employee_map:[],
-			select_employee_id:'',
-			event_type: [
-				{ id: 0, name: '总分' },
-				{ id: 1, name: '迟到' },
-				{ id: 2, name: '早退' },
-				{ id: 6, name: '准时打卡' },
-				{ id: 20, name: '上班缺卡' },
-				{ id: 21, name: '下班缺卡' },
-				{ id: 16, name: '加班 ' },
-				{ id: 10, name: '缺勤' }
-			],
-			attendload: false,
+			employee_map: [],
+			event_type: [{ id: 1, name: '发放' }, { id: 2, name: '回收' }, { id: 3, name: '转换' }],
 			loading: false,
 			all_integral_list: null,
-			Month_range: this.$moment().format('YYYY-MM'),
-			time_range: [
-				this.$moment()
-					.startOf('month')
-					.format('YYYY-MM-DD'),
-				this.$moment()
-					.endOf('month')
-					.format('YYYY-MM-DD')
-			],
+			time_range: [this.$moment().startOf('month').format('YYYY-MM-DD'),this.$moment().endOf('month').format('YYYY-MM-DD')],
 			formData: {
-				group_id: '',
-				// date_type: 3,
+				employee_id: '',
 				page: 1,
 				page_size: 10,
-				event_type: 0
+				type: '',
+				start_time: '',
+				end_time: '',
+				operator_id:''
 			},
-			exportMonth_range: this.$moment().format('YYYY-MM'),
 			exportTime_range: [
 				this.$moment()
 					.startOf('month')
@@ -166,13 +192,14 @@ export default {
 					.format('YYYY-MM-DD')
 			],
 			exportData: {
-				group_id: '',
-				event_type: 0
+				type: '',
+				employee_id: '',
+				start_time: '',
+				end_time: '',
+				operator_id:''
 			},
 			total: 0,
-			dept_tree: [],
-			dept_name: [],
-			pageLimit1: 10,
+			pageLimit: 10,
 			instantPickerOptions: {
 				shortcuts: [
 					{
@@ -215,93 +242,73 @@ export default {
 					}
 				]
 			},
-			// 更新考勤数据
-			isUpdate: false,
-			update: {
-				type: 'daily',
-				target_date: '',
-				target_month: ''
-			}
 		};
 	},
 
 	watch: {
-		isUpdate(val) {
-			if (!val) {
-				this.update = {
-					type: 'daily',
-					target_date: '',
-					target_month: ''
+		'formData.operator_id'() {
+			this.formData.page==1;
+			this.get_all_integral();
+		},
+		'formData.employee_id'() {
+			this.formData.page==1;
+			this.get_all_integral();
+		},
+		time_range() {
+			this.formData.page==1;
+			this.get_all_integral();
+		},
+		'formData.type'() {
+			this.formData.page==1;
+			this.get_all_integral();
+		},
+		dialogVisible(val){
+			if(!val){
+				this.exportData={
+				type: '',
+				employee_id: '',
+				start_time: '',
+				end_time: ''
 				};
+				this.exportTime_range=[
+					this.$moment()
+						.startOf('month')
+						.format('YYYY-MM-DD'),
+					this.$moment()
+						.endOf('month')
+						.format('YYYY-MM-DD')
+				];
 			}
 		}
 	},
 	created() {
-		this.employee_map = JSON.parse(localStorage.getItem('userList'));
+		this.employee_map = this.$getCache('userList');
 	},
 	mounted() {
-		this.checkingIn_group(); //考勤组
+		this.get_all_integral();
 	},
 	methods: {
-		saveUpdate() {
-			let update = this.update;
-			let data = { type: update.type };
-			if (update.type == 'daily') {
-				if (!update.target_date) {
-					this.$message.error('请选择日期');
-					return false;
-				}
-				data.target_date = update.target_date;
-			} else {
-				if (!update.target_month) {
-					this.$message.error('请选择月份');
-					return false;
-				}
-				data.target_month = update.target_month;
-			}
-			this.$axios('post', '/api/ding/ad_sync', data).then(res => {
-				if (res.data.code == 1) {
-					this.$message.success('已更新');
-					this.isUpdate = false;
-				}
-			});
-		},
 		exportRanking() {
-			if (this.checkingInGroup.length > 0) {
-				this.exportData.group_id = this.checkingInGroup[0].id;
-			}
 			this.dialogVisible = true;
 		},
 		exportExcel() {
-			window.open(
-				process.env.VUE_APP_BASE_API +
-					'api/download/groups_ranking/export?start_date=' +
-					this.exportTime_range[0] +
-					'&end_date=' +
-					this.exportTime_range[1] +
-					'&page=' +
-					1 +
-					'&page_size=' +
-					2000 +
-					'&group_id=' +
-					this.exportData.group_id +
-					'&event_type=' +
-					this.exportData.event_type +
-					'&employee_id=' +
-					this.$getUserData().id,
-				'_blank'
-			);
-		},
-		selectgroupId() {
-			this.get_all_integral();
-		},
-		onFilterChanged() {
-			this.get_all_integral();
+			let url=`${process.env.VUE_APP_BASE_API}/api/download/shop/achievement/operation_log?start_time=${this.exportTime_range[0]}
+			&end_time=${this.exportTime_range[1]}&page=1&page_size=8000&download_employee_id=${this.$getUserData().id}`;
+			if(this.exportData.type){
+				url=url+'&type='+this.exportData.type
+			}
+			if(this.exportData.employee_id){
+				url=url+'&employee_id='+this.exportData.employee_id
+			}
+			if(this.exportData.operator_id){
+				url=url+'&employee_id='+this.exportData.operator_id
+			}
+			window.open(url,'_blank');
 		},
 		//分页
 		handleSizeChange1(val) {
-			this.pageLimit1 = val;
-			this.formData.page_size = this.pageLimit1;
+			this.pageLimit = val;
+			this.formData.page_size = this.pageLimit;
 			this.get_all_integral();
 		},
 		handleCurrentChange(val) {
@@ -309,63 +316,59 @@ export default {
 			this.get_all_integral();
 		},
 		//请求数据
-		checkingIn_group() {
-			this.attendload = true;
-			let self = this;
-			let params = {
-				page: 1,
-				page_size: 2000
-			};
-			this.$axios('get', '/api/ad/groups', params)
-				.then(res => {
-					if (res.data.code == 1) {
-						let list = res.data.data.list;
-						let datas = [];
-						for (let key in list) {
-							let obj = {};
-							obj.id = key;
-							obj.name = list[key];
-							datas.push(obj);
-						}
-						this.checkingInGroup = datas;
-						this.formData.group_id = datas[0].id;
-					}
-				})
-				.finally(() => {
-					this.get_all_integral();
-					this.attendload = false;
-				});
-		},
-		//请求数据
 		get_all_integral() {
-			let self = this;
-			self.loading = true;
+			this.loading = true;
 			let data = {
-				group_id: this.formData.group_id,
 				page: this.formData.page,
 				page_size: this.formData.page_size,
-				event_type: this.formData.event_type
+				start_time: this.time_range[0],
+				end_time: this.time_range[1],
+				export: 0
 			};
-			data.start_date = this.time_range[0];
-			data.end_date = this.time_range[1];
-			this.$axios('post', '/api/ad/rank', data)
+			if (Number(this.formData.type)) {
+				data.type = this.formData.type;
+			}
+			if (Number(this.formData.employee_id)) {
+				data.employee_id = this.formData.employee_id;
+			}
+			if (Number(this.formData.operator_id)) {
+				data.operator_id = this.formData.operator_id;
+			}
+			this.$axios('get', '/api/shop/achievement/operation_log', data)
 				.then(res => {
-					if (res.data.code == 1) {
-						self.all_integral_list = res.data.data.list;
-						this.total = res.data.data.total;
-					} else {
-						self.$message.error(res.data.data.msg);
-					}
+					let list = res.data.data.list;
+					list.forEach(item => {
+						item.point = item.achievement / item.ratio_denominator;
+						item.gxd1 = '--';
+						item.gxd2 = '--';
+						item.gxd3 = '--';
+						if (item.type == 1) {
+							item.gxd1 = item.achievement; //发放功勋点
+						} else if (item.type == 2) {
+							item.gxd2 = item.achievement; //回收功勋点
+						} else if (item.type == 3) {
+							item.gxd3 = item.achievement; //转换功勋点
+						}
+					});
+
+					this.all_integral_list = list;
+					this.total = res.data.data.count;
 				})
 				.finally(() => {
-					self.loading = false;
+					this.loading = false;
 				});
 		}
 	}
 };
 </script>
 
-<style scoped>
+<style scoped lang="scss">
+.remark{
+	  display: -webkit-box;
+	  -webkit-box-orient: vertical;
+	  overflow: hidden;
+	  -webkit-line-clamp: 2;
+}	
 .el-date-editor.el-input {
 	width: auto;
 }
@@ -378,8 +381,6 @@ export default {
 .search ::v-deep .el-input-group__append:active .el-icon-search {
 	color: #fff;
 }
-</style>
-<style lang="scss" scoped>
 ::v-deep .el-dialog__body {
 	padding: 0px 20px 30px;
 }

Diferenças do arquivo suprimidas por serem muito extensas
+ 434 - 691
src/views/welfare/prize.vue


+ 1 - 1
src/views/workbench/alreadySp.vue

@@ -101,7 +101,7 @@ export default {
 			point_types: null,
 			detailShow: false,
 			detail_id: null,
-			employee_map: JSON.parse(localStorage.getItem("userList")),
+			employee_map: this.$getCache("userList"),
 			sourceList: [{ name: '全部', id: '0' }, { name: '积分任务', id: '1' }, { name: '积分申请', id: '2' }, { name: '积分录入', id: '3' }]
 		};
 	},

+ 3 - 7
src/views/workbench/approval_batch.vue

@@ -135,7 +135,7 @@ export default {
 		return {
 			detailShow: false,
 			detail_id: null,
-			employee_map: JSON.parse(localStorage.getItem('SET_EMPLOYEE_MAP')),
+			employee_map: this.$getCache('SET_EMPLOYEE_MAP'),
 			total: 0,
 			target_id: '',
 			formData: {
@@ -198,21 +198,17 @@ export default {
 		this.getEmployeeList();
 	},
 	mounted() {
-		if (localStorage.getItem('voluntarilyPoint')) {
+		if (this.$getCache('voluntarilyPoint')) {
 			this.tips_show = false;
 		} else {
 			this.tips_show = true;
 		}
 		this.getSpList();
 	},
-	// beforeDestroy() {
-	// 	// 关闭连接
-	// 	this.$socketApi.closewebsocket();
-	// },
 	methods: {
 		// 关闭提示语
 		tips_close() {
-			localStorage.setItem('voluntarilyPoint', 'true');
+			this.$setCache('voluntarilyPoint', 'true');
 			this.tips_show = false;
 		},
 		// 详情

+ 1 - 1
src/views/workbench/approval_list.vue

@@ -90,7 +90,7 @@ export default {
 			point_types: null,
 			detailShow: false,
 			detail_id: null,
-			employee_map: JSON.parse(localStorage.getItem("userList")),
+			employee_map: this.$getCache("userList"),
 			sourceList: [{ name: '全部', id: '0' }, { name: '积分任务', id: '1' }, { name: '积分申请', id: '2' }, { name: '积分录入', id: '3' }]
 		};
 	},

+ 92 - 21
vue.config.js

@@ -3,8 +3,8 @@ const path = require('path')
 function resolve(dir) {
 	return path.join(__dirname, dir)
 }
-const WebpackBundleAnalyzer = require('webpack-bundle-analyzer');
-const CompressionWebpackPlugin = require('compression-webpack-plugin')
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
+const DEV = process.env.NODE_ENV == 'production';
 module.exports = {
 	// 选项...
 	publicPath: './',
@@ -23,11 +23,19 @@ module.exports = {
 		disableHostCheck: true,
 	},
 	chainWebpack: (config) => {
-		// 配置可视化打包结构构成
-		if (process.env.use_analyzer) {
-			config.plugin('webpack-bundle-analyzer').use(WebpackBundleAnalyzer.BundleAnalyzerPlugin);
-		}
-
+		// 移除 prefetch 插件
+		config.plugins.delete('prefetch')
+		// 移除 preload 插件
+		config.plugins.delete('preload');
+		// ============压缩图片 start============
+		config.module
+			.rule('images')
+			.use('image-webpack-loader')
+			.loader('image-webpack-loader')
+			.options({bypassOnDebug: true})
+			.end()
+		// ============压缩图片 end============
+		
 		//配置 svg-sprite-loader
 		// 第一步:让其他svg loader不要对src/icons进行操作
 		config.module
@@ -49,20 +57,83 @@ module.exports = {
 			.end()
 	},
 	configureWebpack: config => {
-		let plugins = [
-			new CompressionWebpackPlugin({
-				filename: '[path].gz[query]',
-				algorithm: 'gzip',
-				test: new RegExp(
-					'\\.(' + ['js', 'css'].join('|') +
-					')$',
-				),
-				threshold: 10240,
-				minRatio: 0.8,
-			}),
-		]
-		if (process.env.NODE_ENV !== 'development') {
-			config.plugins = [...config.plugins, ...plugins]
+		if(DEV){
+			config.plugins.push(
+				new UglifyJsPlugin({
+					uglifyOptions: {
+						//生产环境自动删除console
+						compress: {
+							drop_debugger: true,
+							drop_console: true,
+							pure_funcs: ['console.log']
+						}
+					},
+					sourceMap: false,
+					parallel: true
+				})
+			)
+		}
+		config.optimization.splitChunks = {
+			cacheGroups: {
+				vendors: {
+					chunks: 'all',
+					name: "chunk-vendors",
+					test: /[\\/]node_modules[\\/]/,
+					chunks: "initial",
+					priority: 2,
+					reuseExistingChunk: true,
+					enforce: true
+				},
+				elementUI: {
+					chunks: 'all',
+					name: "stabled-elementui",
+					test: /[\\/]node_modules[\\/]element-ui[\\/]/,
+					priority: 3,
+					reuseExistingChunk: true,
+					enforce: true
+				},
+				echarts: {
+					chunks: 'all',
+					name: "stabled-echarts",
+					test: /[\\/]node_modules[\\/]echarts[\\/]/,
+					priority: 4,
+					reuseExistingChunk: true,
+					enforce: true
+				},
+				vue: {
+					name: 'stabled-vue',
+					test: /[\\/]node_modules[\\/]vue[\\/]/,
+					chunks: "all",
+					priority: 5,
+					reuseExistingChunk: true,
+					enforce: true
+				},
+				vuex: {
+					name: 'stabled-vue',
+					test: /[\\/]node_modules[\\/]vuex[\\/]/,
+					chunks: "all",
+					priority: 6,
+					reuseExistingChunk: true,
+					enforce: true
+				},
+				'vue-router': {
+					name: 'stabled-vue',
+					test: /[\\/]node_modules[\\/]vue-router[\\/]/,
+					chunks: "all",
+					priority: 7,
+					reuseExistingChunk: true,
+					enforce: true
+				},
+				zrender: {
+					name: "stabled-zrender",
+					test: /[\\/]node_modules[\\/]zrender[\\/]/,
+					chunks: "all",
+					priority: 8,
+					reuseExistingChunk: true,
+					enforce: true
+				}
+			}
 		}
 	},
+
 }

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff