Commit 1837e46b by Kyle_Li

Merge branch 'feature/202011' of http://git.gicdev.com/office/haoban-4 into dev

parents 14f8d665 d176ad86
......@@ -4,13 +4,14 @@
* @Author: 无尘
* @Date: 2020-07-24 12:19:48
* @LastEditors: 无尘
* @LastEditTime: 2020-09-11 16:26:02
* @LastEditTime: 2020-11-17 13:46:07
*/
import getFetch from './get-fetch.js';
let api = {
getAuthEnterprise: '/auth-enterprise-list', // 获取授权商户列表
getGroupList: '/department-list', // 获取 gic 分组列表
getTagList: '/', // 获取标签
getStoreList: '/store-list', // 获取 gic 门店
getAuthDetail: '/enterprise-auth-detail', // 获取授权详情(编辑时获取信息)
getAuditLog: '/enterprise-auth-audit-list', // 获取审核日志
......
......@@ -4,17 +4,38 @@
* @Author: 无尘
* @Date: 2020-11-09 10:15:36
* @LastEditors: 无尘
* @LastEditTime: 2020-11-09 10:17:03
* @LastEditTime: 2020-11-12 11:26:09
*/
import getFetch from './get-fetch.js';
let api = {
// 指标管理
getTargetList: '/', // 获取指标列表
getTargetList: '/perfromance/total-performance-list', // 获取指标列表
getDaySet: '/', // 获取日指标设置
saveDaySet: { // 保存日指标设置
url: '/',
method: 'post',
useFormData: true,
useIntercept: false
},
getSaleSet: '/', // 获取导购指标设置
saveSaleSet: { // 保存导购指标设置
url: '/',
method: 'post',
useFormData: true,
useIntercept: false
},
getYearList: '/setting/get-year-list', // 获取年份
saveStorePerformance: { // 指标设置-新建门店指标
url: '/setting/add-store-performance',
method: 'post',
useFormData: true,
useIntercept: true
},
};
api = getFetch(api, '/hb-app-customer-web');
api = getFetch(api, '/hb-app-performance-web');
export default api;
<!--
* @Descripttion: 应用内选择门店分组
* @version: 1.0.0
* @Author: 无尘
* @Date: 2020-11-17 14:02:31
* @LastEditors: 无尘
* @LastEditTime: 2020-11-17 14:22:27
-->
<!--
<app-select-group :company-id="companyId" :store-type="storeType" :select-group="selectGroup"></app-select-group>
import appSelectGroup from '@/components/set/app-select-group.vue';
-->
<template>
<div class="bind-store-body">
<div class="select-search">
<el-input placeholder="请输入分组名称" clearable v-model="searchSelect" @keyup.native="value => toInput(value, searchSelect)" @clear="clearSearch"> <i slot="prefix" class="el-input__icon el-icon-search"></i> </el-input>
</div>
<div class="select-tree-wrap auth-select-tree m-t-20">
<el-tree ref="groupTree" :filter-node-method="filterNode" check-strictly :data="groupData" node-key="storeGroupId" show-checkbox default-expand-all :props="defaultProps" :expand-on-click-node="false" @check="checkGroup">
<span :id="data.storeGroupId" class="custom-tree-node" slot-scope="{ node, data }" >
<span class="font-14 color-606266">{{ node.label }}</span>
</span>
</el-tree>
</div>
</div>
</template>
<script>
import { _debounce } from '@/common/js/public';
import fetch from '@/api/merchant-auth.js';
const { getGroupList } = fetch;
// import showMsg from '@/common/js/showmsg';
export default {
name: 'AppSelectGroup',
props: {
companyId: {
type: String,
default: ''
},
storeType: {
type: String,
default: '1' // 1 门店绑定, 2 门店共享
},
selectGroup: {
type: [ Object, Array ],
default() {
return {};
}
}
},
data() {
return {
searchSelect: '', // 搜索字段
groupData: [],
groupDataCopy: [],
defaultProps: {
children: 'children',
label: 'storeGroupName'
}
};
},
mounted() {
const that = this;
if (that.companyId) {
that.getGroup();
}
if (that.selectGroup.length) {
that.$nextTick(()=>{
that.$refs.groupTree.setCheckedKeys(that.selectGroup.map(ele=>ele.storeGroupId));
});
}else {
that.$nextTick(()=>{
that.$refs.groupTree.setCheckedKeys([]);
});
}
},
methods: {
/**
* @description: 过滤搜索
* @param {String} value
* @param {Object} data
* @returns {Boolean}
* @author: 无尘
*/
filterNode(value, data) {
if (!value || !data.label) return true;
return data.label.indexOf(value) !== -1;
},
/**
* @description: 输入
* @param {Object} e
* @param {String} value
* @returns {Boolean}
* @author: 无尘
*/
toInput: _debounce(function(e, value) {
const that = this;
if (!that.groupDataCopy.length) {
return false;
}
}, 200),
/**
* @description: 清空
* @returns {Boolean}
* @author: 无尘
*/
clearSearch() {
// const that = this;
return false;
// that.groupData = JSON.parse(JSON.stringify(that.groupDataCopy));
},
/**
* @description: 选择 tree 节点,获取选择节点信息
* @param {Object} e
* @param {Array} checkedKeys
* @author: 无尘
*/
checkGroup: function(e, checkedKeys) {
const that = this;
const groups = that.$refs.groupTree.getCheckedNodes();
that.$emit('checkGroupIds', groups);
},
/**
* @description: 简单数组-->父子结构
* @param {Array} data
* @returns {Array}
* @author: 无尘
*/
treeData(data) {
let tree = data.filter(father => {
// 循环所有项
let branchArr = data.filter(child => {
return father.storeGroupId == child.parentId; // 返回每一项的子级数组
});
if (branchArr.length > 0) {
father.hasSonNode = true;
father.children = branchArr; // 如果存在子级,则给父级添加一个children属性,并赋值
} else {
father.children = [];
father.hasSonNode = false;
}
return father.parentId == 0; // 返回第一层
});
return tree;
},
/**
* @description: 获取门店分组
* @author: 无尘
*/
getGroup() {
const that = this;
const para = {
type: that.storeType,
enterpriseId: that.companyId
};
getGroupList(para)
.then(async res => {
if (!!res.result && res.result.length) {
res.result.forEach(ele => {
ele.expand = false;
ele.children = [];
ele.disabled = false;
ele.label = ele.storeGroupName;
});
}
that.groupData = await that.treeData(JSON.parse(JSON.stringify(res.result))) || [];
// 存一份数据自己搜索
that.groupDataCopy = JSON.parse(JSON.stringify(res.result));
})
.catch(function(error) {
});
},
},
watch: {
searchSelect(val) {
this.$refs.groupTree.filter(val);
},
selectGroup(val) {
const that = this;
if (val.length) {
that.$nextTick(()=>{
that.$refs.groupTree.setCheckedKeys(val.map(ele=>ele.storeGroupId));
});
}else {
that.$nextTick(()=>{
that.$refs.groupTree.setCheckedKeys([]);
});
}
},
companyId(val) {
const that = this;
if (!!val) {
that.getGroup();
}
}
},
};
</script>
<style lang="less" scoped>
.bind-store-body {
width: 331px;
padding: 10px;
margin: 20px 0 0 0 ;
border: 1px solid #e4e7ed;
.w-215 {
width: 215px;
}
.w-115 {
width: 115px;
}
.select-tree-wrap {
height: 323px;
overflow-y: auto;
.el-tree {
width: 309px;
height: 323px;
overflow-x: auto;
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
}
}
}
</style>
<!--
* @Descripttion: 应用内选择门店
* @version: 1.0.0
* @Author: 无尘
* @Date: 2020-11-17 14:03:15
* @LastEditors: 无尘
* @LastEditTime: 2020-11-17 14:22:41
-->
<!--
<app-select-store :company-id="companyId" :store-type="storeType" ></app-select-store>
import appSelectStore from '@/components/set/app-select-store.vue';
-->
<template>
<div class="daily-store-select">
<div class="select-search">
<el-input placeholder="请输入门店名称/代码" v-model="searchSelect" style="width: 100%;" clearable @keyup.native="value => toInput(value, searchSelect)" @clear="clearSearch"> <i slot="prefix" class="el-input__icon el-icon-search"></i> </el-input>
</div>
<!-- <div class="checkbox border-box" style="padding: 15px 20px;">
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
</div> -->
<div class="el-scrollbar define-search-select">
<div class="el-select-dropdown__wrap el-scrollbar__wrap" style="overflow: auto;">
<el-checkbox-group v-model="dailyRuleForm.stores" @change="handleStoresChange" :max="50">
<ul class="el-scrollbar__view el-select-dropdown__list">
<li :class="['el-select-dropdown__item', item.select ? 'selected hover' : '']" v-for="item in stores" :key="item.storeInfoId" >
<el-checkbox :label="item.storeInfoId" >{{ item.storeInfoName }}</el-checkbox>
</li>
<li v-if="!stores.length" class="text-center"><span>暂无数据</span></li>
</ul>
</el-checkbox-group>
</div>
</div>
</div>
</template>
<script>
import { _debounce } from '@/common/js/public';
import fetch from '@/api/merchant-auth.js';
const { getStoreList } = fetch;
import showMsg from '@/common/js/showmsg';
export default {
name: 'AppSelectStore',
props: {
companyId: {
type: String,
default: ''
},
storeType: {
type: String,
default: '1' // 1 门店绑定, 2 门店共享
},
selectStore: {
type: [ Object, Array ],
default() {
return {};
}
}
},
data() {
return {
checkAll: false, // 全选
isIndeterminate: false,
searchSelect: '', // 搜索字段
stores: [], // 门店列表集合
storesCopy: [],
dailyRuleForm: {
stores: [], // 已选门店id结果集
},
pageNum: 1,
pageSize: 300
};
},
mounted() {
const that = this;
that.stores = [];
that.storesCopy = [];
if (!!that.companyId) {
that.pageNum = 1;
that.getStoreData();
}
if (!!that.selectStore.length) {
that.dailyRuleForm.stores = that.selectStore.map(el=>el.storeInfoId) || [];
}else {
that.dailyRuleForm.stores = [];
}
},
methods: {
/**
* @description: 判断提示
* @param {Object} data
* @author: 无尘
*/
toShowMsg(data) {
if (data.bindFlag == 1) {
showMsg.showmsg('当前门店已被其他企业绑定,当前企业无法选择!', 'warning');
}
},
/**
* @description: 选择改变
* @param {Array} value
* @author: 无尘
*/
handleStoresChange(value) {
const that = this;
let arr = [];
that.stores.forEach(ele => {
if (value.includes(ele.storeInfoId)) {
arr.push(ele);
}
});
that.$emit('checkStoreIds', JSON.parse(JSON.stringify(arr)));
},
/**
* @description: 输入
* @param {Object} e
* @param {String} value
* @author: 无尘
*/
toInput: _debounce(function(e, value) {
const that = this;
if (that.searchSelect != '') {
that.stores = [];
that.pageNum = 1;
that.getStoreData();
}
}, 500),
/**
* @description: 清空
* @author: 无尘
*/
clearSearch() {
const that = this;
that.stores = [];
that.pageNum = 1;
that.getStoreData();
// that.stores = JSON.parse(JSON.stringify(that.storesCopy));
},
/**
* @description: 获取门店
* @author: 无尘
*/
getStoreData() {
const that = this;
const para = {
search: that.searchSelect,
enterpriseId: that.companyId,
type: that.storeType,
pageNum: that.pageNum,
pageSize: that.pageSize
};
getStoreList(para)
.then(res => {
if (that.pageNum == 1) {
that.stores = JSON.parse(JSON.stringify(res.result.result)) || [];
that.storesCopy = JSON.parse(JSON.stringify(res.result.result)) || [];
}else {
res.result.result.forEach(ele => {
that.stores.push(ele);
that.storesCopy.push(ele);
});
}
if (that.pageNum * that.pageSize < res.result.totalCount) {
that.pageNum ++;
that.$nextTick(()=>{
that.getStoreData();
});
}
})
.catch(function(error) {
});
}
},
watch: {
selectStore: function(newData, oldData) {
const that = this;
if (!!newData.length) {
that.dailyRuleForm.stores = newData.map(el=>el.storeInfoId) || [];
}else {
that.dailyRuleForm.stores = [];
}
},
companyId(val) {
const that = this;
if (!!val) {
that.pageNum = 1;
that.getStoreData();
}
}
}
};
</script>
<style lang="less" scoped>
.daily-store-select {
position: relative;
width: 331px;
min-height: 398px;
margin: 20px 0 0 0;
padding: 10px;
border: 1px solid #e4e7ed;
.define-search-select {
.el-select-dropdown__wrap {
max-height: 343px;
}
.el-checkbox-group {
overflow-x: auto;
height: 338px;
ul {
height: 100%;
li {
overflow: unset;
text-overflow: unset;
}
}
}
}
}
</style>
<!--
* @Descripttion: 当前组件信息
* @Descripttion: 选择门店分组组件
* @version: 1.0.0
* @Author: 无尘
* @Date: 2020-02-08 10:27:21
* @Date: 2020-11-08 10:27:21
* @LastEditors: 无尘
* @LastEditTime: 2020-09-14 10:11:19
* @LastEditTime: 2020-11-17 17:50:58
-->
<!--
选择门店分组组件:
<gic-select-group-mult
:select-data="selectData"
@checkGroupIds="checkGroupIds">
......@@ -27,7 +26,7 @@
</div>
<div class="select-tree-wrap m-t-10">
<!--:load="loadNode"-->
<el-tree :filter-node-method="filterNode" clearable :data="groupData" :default-checked-keys="checkedKeys" node-key="storeGroupId" ref="groupTree" show-checkbox default-expand-all :props="defaultProps" :expand-on-click-node="false" @check="checkGroup">
<el-tree :filter-node-method="filterNode" :data="groupData" :default-checked-keys="checkedKeys" node-key="storeGroupId" ref="groupTree" show-checkbox default-expand-all :props="defaultProps" :expand-on-click-node="false" @check="checkGroup">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span :class="['font-14 p-r-10 iconfont', data.isStore == 1 ? 'icondianpu-kuai' : 'iconqiye-tianchong', data.bindFlag == 1 ? 'color-2f54eb' : 'color-dedfe6']"></span><span class="font-14 color-606266">{{ node.label }}</span>
</span>
......@@ -53,8 +52,8 @@
</el-popover>
</template>
<script>
import fetch from '@/api/contact.js';
const { getGicGroup } = fetch;
import fetch from '@/api/merchant-auth.js';
const { getGroupList } = fetch;
import { _debounce } from '@/common/js/public';
export default {
name: 'GicSelectGroupMult',
......@@ -116,21 +115,7 @@ export default {
if (!value || !data.label) return true;
return data.label.indexOf(value) !== -1;
},
/**
* @description: 加载更多
* @param {Object} node
* @param {Function} resolve
* @returns {Function}
* @author: 无尘
*/
async loadNode(node, resolve) {
const that = this;
if (node.level === 0) {
return resolve(that.getGroup());
} else {
await that.getGroup(node, node.data, resolve);
}
},
/**
* @description: 输入
* @param {Object} e
......@@ -186,24 +171,6 @@ export default {
that.$refs.groupTree.setCheckedKeys(keys);
that.$emit('checkGroupIds', that.$refs.groupTree.getCheckedNodes());
},
/**
* @description: 处理排序
* @param {Object} item
* @author: 无尘
*/
async handleSort(item) {
const that = this;
for (let i = 0; i < item.children.length; i++) {
item.children.sort(function(a, b) {
return a.storeGroupSort - b.storeGroupSort;
});
if (item.children[i].length) {
await that.handleSort(item.children[i]);
}
}
},
/**
* @description: 简单数组-->父子数组对象
* @param {Array} data
......@@ -213,30 +180,14 @@ export default {
let tree = data.filter(father => {
// 循环所有项
let branchArr = data.filter(child => {
return father.storeGroupId == child.parentGroupId; // 返回每一项的子级数组
return father.storeGroupId == child.parentId; // 返回每一项的子级数组
});
if (branchArr.length > 0) {
father.children = branchArr; // 如果存在子级,则给父级添加一个children属性,并赋值
}else {
father.children = [];
}
return father.parentGroupId == 0; // 返回第一层
});
// 排序
if (tree.length) {
tree.sort(function(a, b) {
return a.storeGroupSort - b.storeGroupSort;
});
}
/* for (let i = 0; i < tree[0].children.length; i++) {
if (tree[0].children[i].lenth) {
await that.handleSort(tree[0].children[i]);
}
} */
tree.forEach(function(ele, index) {
if (!!ele.children && ele.children.length) {
ele.children.sort(function(a, b) {
return a.storeGroupSort - b.storeGroupSort;
});
}
return father.parentId == 0; // 返回第一层
});
return tree;
},
......@@ -250,12 +201,11 @@ export default {
let para = {
enterpriseId: that.brandId
};
getGicGroup(para)
getGroupList(para)
.then(async res => {
if (!!res.result && !!res.result.length) {
res.result.forEach(ele => {
ele.label = ele.storeGroupName;
ele.departmentName = ele.storeGroupName;
});
const data = await that.treeData(res.result);
that.$nextTick(() => {
......
<!--
* @Descripttion: 当前组件信息
* @version: 1.0.0
* @Author: 无尘
* @Date: 2020-02-08 10:27:21
* @LastEditors: 无尘
* @LastEditTime: 2020-11-17 13:49:40
-->
<!--
选择门店分组组件:
<gic-select-tag
:selectData="selectData"
@returnTags="returnTags">
</gic-select-tag>
import gicSelectTag from '@/components/app/card/gic-select-tag.vue';
returnTags: function(nodes) {
const that = this;
that.conditionObj.tags = nodes;
},
-->
<template>
<el-popover placement="bottom" title="" width="350" trigger="click" v-model="storeVisible">
<div class="daily-store-select">
<div class="el-scrollbar define-search-select">
<div class="el-select-dropdown__wrap el-scrollbar__wrap" style="margin-bottom: -5px; margin-right: -5px;">
<el-checkbox-group v-model="dailyRuleForm.tags" @change="handleStoresChange">
<ul class="el-scrollbar__view el-select-dropdown__list">
<li class="el-select-dropdown__item" v-for="item in tags" :key="item.tagId">
<el-checkbox :label="item.tagId">{{ item.tagName }}</el-checkbox>
</li>
<li v-if="!tags.length" class="text-center el-select-dropdown__item"><span>暂无门店标签</span></li>
</ul>
</el-checkbox-group>
</div>
<div class="el-scrollbar__bar is-horizontal"><div class="el-scrollbar__thumb" style="transform: translateX(0%);"></div></div>
<div class="el-scrollbar__bar is-vertical"><div class="el-scrollbar__thumb" style="transform: translateY(0%);"></div></div>
</div>
</div>
<div class="flex-column item-cell-select inline-block " slot="reference">
<div class="depart-item-wrap">
<div :style="{ width: width }" class="el-select el-select--large depart-item-content">
<span class="font-14 color-c0c4cc p-l-10" style="display: inline-block;line-height: 32px;color: #c0c4cc;" v-if="!dailyRuleForm.tags.length">请选择门店标签</span>
<div class="el-select__tags" style="max-width: 348px;">
<span style="display:block">
<template v-for="(item, index) in selectTags">
<span class="el-tag el-tag--info el-tag--small" :key="index + 'tag'">
<span class="el-select__tags-text">{{ item.tagName }}</span>
<i class="el-tag__close el-icon-close" @click.stop="delDepart(index, selectTags)"></i>
</span>
</template>
</span>
</div>
</div>
</div>
</div>
</el-popover>
</template>
<script>
import fetch from '@/api/merchant-auth.js';
const { getTagList } = fetch;
// import errMsg from '@/common/js/error';
// import { _debounce } from '@/common/js/public';
export default {
name: 'GicSelectTag',
props: {
width: {
type: String,
default() {
return '357px';
}
},
selectData: {
type: [ Object, Array ],
default() {
return [];
}
},
brandId: {
type: String,
default() {
return '';
}
}
},
data() {
return {
projectName: '', // 当前项目名
enterpriseId: this.brandId,
storeVisible: false,
tags: [],
dailyRuleForm: {
tags: []
},
selectTags: []
};
},
mounted() {
const that = this;
if (!!that.brandId) {
that.tags = [];
that.getTagsData();
}
if (!!that.selectData.length) {
that.selectTags = JSON.parse(JSON.stringify(that.selectData));
that.dailyRuleForm.tags = that.selectData.map(ele => ele.tagId);
} else {
that.dailyRuleForm.tags = [];
that.selectTags = [];
}
},
methods: {
/**
* @description: 选中改变
* @param {Array} value
* @author: 无尘
*/
handleStoresChange(value) {
const that = this;
let arr = [];
that.tags.forEach(ele => {
if (value.includes(ele.tagId)) {
arr.push(ele);
}
});
that.selectTags = JSON.parse(JSON.stringify(arr));
that.$emit('returnTags', that.selectTags);
},
/**
* @description: 删除
* @param {Number} index
* @param {Array} arr
* @author: 无尘
*/
delDepart(index, arr) {
const that = this;
arr.splice(index, 1);
that.$emit('returnTags', that.selectTags);
},
/**
* @description: 获取门店标签
* @author: 无尘
*/
getTagsData() {
const that = this;
let para = {
gicEnterpriseId: that.brandId
};
getTagList(para)
.then(res => {
if (res.code == '0000') {
that.tags = res.result || [];
return;
}
})
.catch(function(error) {
});
}
},
watch: {
brandId(val) {
const that = this;
if (val) {
that.dailyRuleForm.tags = [];
that.selectTags = [];
that.tags = [];
that.getTagsData();
}
},
selectData: function(newData, oldData) {
const that = this;
if (!!newData.length) {
that.selectTags = JSON.parse(JSON.stringify(newData));
that.dailyRuleForm.tags = newData.map(ele => ele.tagId);
} else {
that.dailyRuleForm.tags = [];
that.selectTags = [];
}
}
}
};
</script>
<style lang="less" scoped>
.depart-item-content {
width: 213px;
height: 32px;
overflow: hidden;
white-space: nowrap;
border-radius: 2px;
border: 1px solid #c4c6cf;
cursor: pointer;
box-sizing: border-box;
}
.select-tree-wrap {
max-height: 300px;
overflow-y: auto;
}
.item-cell-select {
/deep/ .el-select__tags {
white-space: nowrap;
overflow: hidden;
}
.el-select {
.el-tag {
border-radius: 2px;
border: 1px solid rgba(220, 223, 230, 1);
background-color: #fff;
.el-tag__close {
top: 1px;
color: #909399;
&:hover {
background-color: transparent;
}
}
}
}
}
.w-350 {
width: 350px;
}
.show-select-num {
position: relative;
display: inline-block;
font-size: inherit;
height: 32px;
line-height: 32px;
padding-left: 10px;
-webkit-appearance: none;
background-color: #fff;
background-image: none;
border-radius: 4px;
border: 1px solid #dcdfe6;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: #606266;
.el-select__caret {
color: #c0c4cc;
font-size: 14px;
transition: transform 0.3s;
transform: rotate(180deg);
cursor: pointer;
&.is-reverse {
transform: rotate(0deg);
}
}
}
.daily-store-select {
position: relative;
}
</style>
......@@ -4,7 +4,7 @@
* @Author: 无尘
* @Date: 2020-07-16 16:37:05
* @LastEditors: 无尘
* @LastEditTime: 2020-11-09 10:39:13
* @LastEditTime: 2020-11-12 11:33:51
*/
import _import from './_import.js';
......@@ -233,6 +233,16 @@ export const routes = [
component: _import('apps/target-manage', 'target-store')
},
{
path: '/perfect-sale-target',
name: '完善导购指标',
component: _import('apps/target-manage', 'perfect-sale-target')
},
{
path: '/perfect-day-target',
name: '完善日指标',
component: _import('apps/target-manage', 'perfect-day-target')
},
{
path: '/set-month-target',
name: '设置月指标',
component: _import('apps/target-manage', 'set-month-target')
......
<template>
<div id="month-target">
<div class="target-box" v-for="item in tableData" :key="item.num">
<header>{{ item.head }}</header>
<div :class="{ content: true, red: isAllNot ? false : (isAllRed || month < item.num) && !item.val }">
<el-input-number v-model="item.val" :controls="false" placeholder="请输入" @change="$emit('change', tableData)"></el-input-number>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'MonthTarget',
props: {
data: {
type: Object,
default: () => []
},
year: {
type: [ String, Number ],
default: '2020'
}
},
data() {
return {
tableData: [
{ head: '一月', num: '01', val: undefined },
{ head: '二月', num: '02', val: undefined },
{ head: '三月', num: '03', val: undefined },
{ head: '四月', num: '04', val: undefined },
{ head: '五月', num: '05', val: undefined },
{ head: '六月', num: '06', val: undefined },
{ head: '七月', num: '07', val: undefined },
{ head: '八月', num: '08', val: undefined },
{ head: '九月', num: '09', val: undefined },
{ head: '十月', num: '10', val: undefined },
{ head: '十一月', num: '11', val: undefined },
{ head: '十二月', num: '12', val: undefined },
],
thisYear: new Date().getFullYear(),
month: new Date().getMonth()
};
},
mounted() {
this.$emit('change', this.tableData);
},
methods: {
validate() {
// eslint-disable-next-line
return this.tableData.some(item => this.isAllNot ? false : (this.isAllRed || this.month < item.num) && !item.val);
}
},
computed: {
isAllRed() {
return this.year > this.thisYear;
},
isAllNot() {
return this.year < this.thisYear;
}
}
};
</script>
<style lang="less">
#month-target {
display: flex;
flex-wrap: wrap;
margin-bottom: 30px;
width: 962px;
color: #303133;
.target-box {
width: 160px;
header {
height: 44px;
line-height: 44px;
text-indent: 22px;
background-color: #EBECF0;
}
.content {
display: flex;
justify-content: center;
align-items: center;
height: 62px;
border-bottom: 1px solid #DCDFE6;
}
.red .el-input__inner {
border-color: #F5222D;
}
}
.el-input-number {
width: 120px;
&:before {
content: '¥';
position: absolute;
top: 0px;
left: 11px;
z-index: 3;
font-size: 14px;
color: #303133;
}
.el-input__inner {
text-align: left;
padding-left: 30px;
}
}
}
</style>
\ No newline at end of file
......@@ -6,3 +6,199 @@
* @LastEditors: 无尘
* @LastEditTime: 2020-11-09 10:41:18
-->
<template>
<div class="common-app-right">
<el-alert
show-icon
:closable="false">
<template slot="title">
<div>1.下发类型修改后、日权重/日指标修改后、指标设置立即生效,修改后数据统计次日生效</div>
<div>2.修改当月指标会导致已完善的日指标重新下发及完善。请谨慎设置</div>
</template>
</el-alert>
<el-form :model="form" ref="form" :rules="rules" label-width="180px" hide-required-asterisk>
<el-form-item label="选择年份" prop="performanceYear">
<el-select v-model="form.performanceYear" placeholder="请选择年份">
<el-option v-for="item in yearList" :key="item" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item label="选择门店" prop="storeValue">
<el-radio-group v-model="form.storeMode">
<el-radio :label="0">所有门店</el-radio>
<el-radio :label="1">选择分组</el-radio>
<el-radio :label="2">选择门店</el-radio>
</el-radio-group>
<customer-store-group v-if="form.storeMode == 1" :brand-id="brandId" :select-group="storeValue" @checkGroupIds="checkGroupIds"></customer-store-group>
<customer-store v-if="form.storeMode == 2" :brand-id="brandId" :select-store="storeValue" @checkStoreIds="checkGroupIds"></customer-store>
</el-form-item>
<el-form-item label="指标类型(必填一项)" prop="type">
<el-checkbox v-model="form.performanceFlag" :true-label="1" :false-label="0">
业绩指标(元)
<el-select v-model="form.performaceSubType" style="width: 240px;margin: 0 20px 20px 48px" :disabled="form.performanceFlag == 0">
<el-option v-for="item in targetList" :key="item.name" :label="item.name" :value="item.val"></el-option>
</el-select>
<span class="color2">设置日指标,则需先设置月指标,再设置门店日指标额。指标会计算每日完成度。</span>
</el-checkbox>
<month-target ref="monthTargetRef1" v-show="form.performanceFlag == 1" :year="form.performanceYear" :data="performanceCallback" @change="val => monthTargetChange(val, 'performanceVal')" />
<el-checkbox v-model="form.addMemberFlag" :true-label="1" :false-label="0">
新增会员指标(人)
<el-select v-model="form.addMemebrSubType" style="width: 240px;margin: 0 20px 20px 21px" :disabled="form.addMemberFlag == 0">
<el-option v-for="item in targetList" :key="item.name" :label="item.name" :value="item.val"></el-option>
</el-select>
<span class="color2">设置日指标,则需先设置月指标,再设置门店日指标额。指标会计算每日完成度。</span>
</el-checkbox>
<month-target ref="monthTargetRef2" v-show="form.addMemberFlag == 1" :year="form.performanceYear" :data="addMemberCallback" @change="val => monthTargetChange(val, 'addMemberVal')" />
</el-form-item>
<el-form-item label="指标编辑权限" prop="storeEdit">
<el-checkbox v-model="storeEdit" :true-label="1" :false-label="0">店长可修改指标</el-checkbox>
</el-form-item>
<el-form-item label="">
<el-button type="primary" @click="confirm" :loading="loading">保存</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import customerStoreGroup from '@/components/app/my-customer/customer-store-group.vue';
import customerStore from '@/components/app/my-customer/customer-store.vue';
import MonthTarget from './MonthTarget.vue';
import fetch from '@/api/target-manage-app.js';
const { getYearList, saveStorePerformance } = fetch;
export default {
name: 'EditStoreQuota',
components: { customerStoreGroup, customerStore, MonthTarget },
props: {
brandId: {
type: String,
default: ''
}
},
data() {
const storeCheck = (rule, value, callback) => {
this.$nextTick(() => {
const { storeMode, storeValue } = this.form;
if (storeMode === 0) callback();
if (!storeValue || !storeValue.length) callback(new Error('请选择分组或门店'));
callback();
});
};
return {
loading: false,
form: {
performanceYear: '', // 年
storeMode: 0, // 0,所有门店,1选择分组,2部门门店
storeValue: [], // 选择的值aaa,bbb,ccc
storeEdit: 0, // 1门店可编辑,0不可
performanceFlag: 0, // 业绩指标 1已勾选
performaceSubType: 1, // 业绩指标:1,日权重,2,指标额
addMemberFlag: 0, // 新增会员指标1已勾选
addMemebrSubType: 1, // 新增会员指标:1,日权重,2,指标额
},
rules: {
performanceYear: [ { required: true, message: '请选择年份', trigger: 'blur' } ],
storeValue: [ { required: true, validator: storeCheck, trigger: [ 'blur', 'change' ] } ],
},
targetList: [
{ name: '日权重', val: 1 },
{ name: '指标额', val: 2 }
],
yearList: [],
performanceCallback: null, // 回显数据
performanceVal: null,
addMemberCallback: null, // 回显数据
addMemberVal: null,
};
},
mounted() {
this.$emit('showTab', '/quota-set');
let bread = [ { name: '指标设置', path: '/quota-set' }, { name: '编辑指标' } ];
// 修改面包屑
this.$emit('change-nav', bread);
this.getYearList();
},
methods: {
// 获取组件的值
checkGroupIds(val) {
this.form.storeValue = JSON.parse(JSON.stringify(val));
},
// 返值
monthTargetChange(val, str) {
this[str] = val;
},
// 保存
confirm() {
this.$refs.form.validate(valid => {
if (!valid) return;
const { performanceFlag, addMemberFlag, storeValue, performanceYear } = this.form;
if (performanceFlag && this.$refs.monthTargetRef1.validate()) return this.$message.warning('请完善业绩指标');
if (addMemberFlag && this.$refs.monthTargetRef2.validate()) return this.$message.warning('请完善新增会员指标');
this.loading = true;
const { staffName, staffId, wxEnterpriseId } = JSON.parse(localStorage.getItem('haoBanUser'));
let params = {
...this.form,
wxEnterpriseId,
submitStaffName: staffName,
submitStaffId: staffId,
enterpriseId: this.brandId,
storeValue: storeValue.map(item => item.storeGroupId).join(','),
performanceValue: this.filterTargetVal('performanceVal', performanceYear),
addMemebrValue: this.filterTargetVal('addMemberVal', performanceYear)
};
saveStorePerformance(params, { headers: { sign: this.brandId } })
.then(res => {
this.$message.success('保存成功');
this.$router.go(-1);
})
.finally(() => this.loading = false);
});
},
// 获取年份
getYearList() {
getYearList('', { headers: { sign: this.brandId } }).then(res => {
this.yearList = res.result || [];
});
},
// 转化传给后端的数据
filterTargetVal(type, year) {
if (!type) return '';
return JSON.stringify(this[type].map(item => {
return {
performanceYm: `${year.toString()}-${item.num}`,
performanceValue: item.val
};
}));
}
},
watch: {
brandId(val) {
// val && this.getData();
}
}
};
</script>
<style lang="less" scoped>
.el-alert {
width: 590px;
margin-bottom: 20px;
font-size: 13px;
}
.color2 {
color: #606266;
font-size: 12px;
}
</style>
\ No newline at end of file
......@@ -17,7 +17,7 @@
</div>
<div class="apps-content-right">
<transition name="fade" mode="out-in">
<router-view :brand-id="activeBrand" :active-group-id="activeGroup" :tab-type="activeTab" @showTab="showTab"> </router-view>
<router-view :brand-id="activeBrand" :active-group-id="activeGroup" :tab-type="activeTab" @showTab="showTab" @change-nav="changeNav"> </router-view>
</transition>
</div>
</div>
......@@ -54,10 +54,6 @@ export default {
{
name: '首页',
path: '/app-list'
},
{
name: '指标管理',
path: ''
}
],
tabListData: [
......@@ -143,6 +139,16 @@ export default {
const that = this;
that.activeTab = menuUrl;
that.activeSelTab = menuUrl;
},
// 修改面包屑
changeNav(arr) {
this.navpath = [
{
name: '首页',
path: '/app-list'
},
...arr
];
}
},
watch: {
......
<!--
* @Descripttion: 完善日指标
* @version: 1.0.0
* @Author: 无尘
* @Date: 2020-11-12 10:47:17
* @LastEditors: 无尘
* @LastEditTime: 2020-11-12 11:19:24
-->
<template>
<div class="common-app-right" style="padding: 20px 0;color: #303133">
<el-form :model="form" label-width="110px">
<el-form-item label="门店名称"></el-form-item>
<el-form-item label="指标额">
<el-button type="text" @click="dialogVisible=true">修改</el-button>
</el-form-item>
<el-form-item label="指标类型">业绩指标日权重</el-form-item>
<el-form-item label="">
<div class="content-data">
<span class="color2">月指标:¥ </span>
<span class="color1">100,000</span>
<span class="color2">日指标总和:¥ </span>
<span class="color1" :style="{ color: totalDayTarget > monthTarget ? '#F5222D' : '#606266' }">{{ parseFloat(totalDayTarget).toFixed(2) }}</span>
</div>
</el-form-item>
</el-form>
<div class="target-title">
<span>2020年9月</span>
<el-button type="text">设置默认日权重</el-button>
</div>
<div class="target-table">
<ul class="table-title">
<li>周日</li>
<li>周一</li>
<li>周二</li>
<li>周三</li>
<li>周四</li>
<li>周五</li>
<li>周六</li>
</ul>
<ul class="table-content">
<!-- 补充空白 -->
<li v-for="(item, i) in zerofill" :key="i"></li>
<li v-for="(item, i) in tableData" :key="i">
<div>{{ item.perfromanceDay }}</div>
<el-input-number v-model="item.performanceValue" :precision="2" :controls="false" style="width: 80px;margin-left:40px;margin-top:5px"></el-input-number>
</li>
<!-- 补充空白 -->
<li v-for="(item, i) in zerofillLast" :key="i"></li>
</ul>
</div>
<el-button type="primary" :loading="loading" style="margin-left:20px">保存</el-button>
<el-dialog
title="修改指标"
:visible.sync="dialogVisible"
width="600px"
@close="dialogClose">
<el-alert
title="修改当月指标会导致已完善的日指标重新下发,并完善。请谨慎设置"
type="danger"
show-icon
:closable="false">
</el-alert>
<el-form :model="targetForm" ref="targetForm" hide-required-asterisk label-width="175px">
<el-form-item
prop="value"
:rules="[
{ required: true, message: '请输入月指标额', trigger: 'blur' }
]">
<span slot="label">
<span class="color1" style="padding-right:35px">2020-10</span>
指标额
</span>
<el-input v-model="targetForm.value" style="width: 289px">
<span slot="prefix" style="color:#303133;padding-left:5px"></span>
</el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmMonthTarget">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import errMsg from '@/common/js/error';
// import showMsg from '@/common/js/showmsg';
// import fetch from '@/api/target-manage-app.js';
// const { saveDaySet, getDaySet } = fetch;
export default {
name: 'PerfectDayTarget',
components: {},
props: {
brandId: {
type: String,
default() {
return '';
}
}
},
data() {
return {
form: {},
loading: false,
monthTarget: 10000,
tableData: [],
zerofill: [],
zerofillLast: [],
targetForm: {
value: ''
},
dialogVisible: false,
};
},
created() {
this.init();
},
mounted() {
this.$emit('showTab', '/target-list');
let bread = [ { name: '指标管理', path: '/target-list' }, { name: '查看门店', path: '/target-store' }, { name: '完善日指标' } ];
// 修改面包屑
this.$emit('change-nav', bread);
},
// watch: {
// brandId() {
// }
// },
methods: {
// 初始化表格
init() {
const { date } = this.$route.query;
let sDate = date ? date.split('-') : '';
if (!sDate) return errMsg('缺少参数,请返回重试');
let week = new Date(sDate[0], sDate[1] - 1).getDay(); // 第一天周几
let days = new Date(sDate[0], sDate[1], 0).getDate(); // 一个月天数
this.zerofill = new Array(week).fill(null); // 补空白
this.tableData = new Array(days).fill(null).map((item, i) => {
return {
perfromanceDay: i + 1,
performanceValue: 0,
performanceSubType: 2
};
});
// 末尾补空白
let len = (this.zerofill.length + this.tableData.length) % 7;
if (len) this.zerofillLast = new Array(7 - len).fill(null);
},
// 修改月指标
confirmMonthTarget() {
this.$refs.targetForm.validate(valid => {
if (!valid) return;
});
},
dialogClose() {
this.$refs.targetForm.resetFields();
}
},
computed: {
totalDayTarget() {
return this.tableData.reduce((preV, { performanceValue }) => {
return preV + performanceValue;
}, 0);
}
},
};
</script>
<style type="text/less" lang="less" scoped>
.color1 {
font-size: 16px;
padding-right: 15px;
font-weight: 600;
}
.content-data {
position: relative;
.color2 {
position: relative;
font-size: 14px;
font-weight: 400;
&:not(:first-of-type) {
padding-left: 16px;
&::before {
content: '|';
position: absolute;
left: 0;
color: #DCDFE6;
}
}
}
}
.target-title {
display: flex;
justify-content: space-between;
width: 1145px;
margin: 20px;
span {
font-weight: 600;
}
}
.target-table {
width: 1145px;
margin: 0 20px 50px;
}
.table-title {
display: flex;
background-color: #ebecf0;
li {
width: 163px;
height: 48px;
line-height: 48px;
text-indent: 35px;
font-weight: 500;
// border-bottom: 1px solid #DCDFE6;
&:not(:last-of-type) {
border-right: 1px solid #DCDFE6;
}
}
}
.table-content {
display: flex;
flex-wrap: wrap;
li {
width: 163px;
height: 70px;
padding: 5px 0 8px 10px;
border-bottom: 1px solid #DCDFE6;
&:not(:nth-of-type(7n)) {
border-right: 1px solid #DCDFE6;
}
}
}
.el-input-number /deep/.el-input__inner {
text-align: left;
border: none;
background-color: #F5F7FA;
}
.el-form-item {
margin-bottom: 10px;
}
/deep/.el-alert--danger {
width: 456px;
margin-bottom: 20px;
background: #FFFBE6;
border-radius: 2px;
border: 1px solid #FFE58F;
.el-alert__icon {
color: #FAAD14;
}
}
</style>
<!--
* @Descripttion: 完善导购指标
* @version: 1.0.0
* @Author: 无尘
* @Date: 2020-11-12 10:48:40
* @LastEditors: 无尘
* @LastEditTime: 2020-11-12 11:32:52
-->
<template>
<div class="common-app-right">
<div class="task-set-content border-box">
<el-alert
title="提示:【导购总计】需大于等于【本店指标】金额。否则无法提交"
show-icon
:closable="false"
style="width: 450px;margin-bottom: 20px">
</el-alert>
<div class="saler-set-title flex flex-space-between m-b-15">
<div class="colorFirst">
<span>{{ clerkObj.yearMonth }}</span><span class="p-l-18">{{ clerkObj.storeName }}</span>
</div>
</div>
<div class="saler-set-table">
<el-table class="select-table" ref="multipleTable" :span-method="objectSpanMethod" :data="tableData" tooltip-effect="dark" :style="{ width: '100%', minHeight: tableH }">
<el-table-column label="导购">
<template slot-scope="scope">
<div>{{ scope.row.clerkName }}</div>
</template>
</el-table-column>
<el-table-column label="月指标">
<template slot-scope="scope">
<div>
<el-input class="w-120 p-l-8" maxlength="50" v-model="scope.row.clerkPerformance" placeholder="请输入" :disabled="clerkObj.settingAble == 0 || scope.row.bindFlag == 0" @blur="value => inputPerformance(value, scope.$index, scope.row)">
<i slot="prefix" style="font-style: normal;position: absolute;top: 4px;left: 12px;"></i>
</el-input>
</div>
</template>
</el-table-column>
<el-table-column label="总计 >= 门店月指标" width="418px">
<template >
<div><span class="font-14 color-606266 text-left">总计</span><span class=" p-l-175 font-14 color-606266 text-left">门店月指标</span></div>
<div style="margin-top: 4px;">
<el-input class="w-161" v-model="performanceSum" disabled>
<i slot="prefix" style="font-style: normal;position: absolute;top: 4px;left: 10px;"></i>
</el-input>
<span class="p-l-10 p-r-10"> &gt;= </span>
<el-input class="w-161 p-l-8" maxlength="50" v-model="clerkObj.storePerformance" placeholder="请输入指标值" disabled>
<i slot="prefix" style="font-style: normal;position: absolute;top: 4px;left: 16px;"></i>
</el-input>
</div>
</template>
</el-table-column>
</el-table>
</div>
<div class="task-set-save m-t-30">
<el-button v-if="clerkObj.settingAble == 1" :disabled="!equalFlag ? true : false" type="primary" @click="saveSet">确认</el-button>
</div>
</div>
</div>
</template>
<script>
import { _debounce } from '@/common/js/public';
import errMsg from '@/common/js/error';
import showMsg from '@/common/js/showmsg';
import fetch from '@/api/target-manage-app.js';
const { saveSaleSet, getSaleSet } = fetch;
export default {
name: 'PerfectSaleTarget',
components: {},
props: {
brandId: {
type: String,
default() {
return '';
}
}
},
data() {
return {
tableH: window.screen.availHeight - 464 - 126,
activeTab: '1',
activeBrand: this.brandId, // 商户(品牌) id
operationStaffName: localStorage.getItem('userInfos') ? JSON.parse(localStorage.getItem('userInfos')).staffDTO['staffName'] : '',
activeId: '4',
tableData: [ {}, {} ],
performanceSum: '0.00', // 总指标
clerkObj: {
storeId: '',
storeName: '',
yearMonth: '',
settingAble: 1,
storePerformance: 0
},
equalFlag: false // 相等标志
};
},
mounted() {
let that = this;
this.$emit('showTab', '/target-list');
let bread = [ { name: '指标管理', path: '/target-list' }, { name: '查看门店', path: '/target-store' }, { name: '完善导购指标' } ];
// 修改面包屑
this.$emit('change-nav', bread);
if (!!that.brandId) {
that.getData();
}
},
methods: {
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
const that = this;
if (columnIndex === 2) {
if (rowIndex == 0) {
return {
rowspan: that.tableData.length,
colspan: 1
};
} else {
return {
rowspan: 0,
colspan: 0
};
}
}
},
/**
* @description:输入
* @param {Function} val
* @param {Number} index
* @param {Object} row
* @author: 无尘
*/
inputPerformance: function(val, index, row) {
const that = this;
row.clerkPerformance = !!Number(row.clerkPerformance.replace(/[^\d.]/g, '')) ? row.clerkPerformance.replace(/[^\d+(.\d+)]/g, '') : '';
row.clerkPerformance = Number(row.clerkPerformance).toFixed(2);
let sumData = 0;
that.tableData.forEach(ele => {
sumData += Number(ele.clerkPerformance);
});
that.performanceSum = Number(sumData).toFixed(2);
that.diffData();
},
diffData() {
let that = this;
let dataFlag = Number(that.performanceSum) > Number(that.clerkObj.storePerformance) || Number(that.performanceSum) == Number(that.clerkObj.storePerformance);
if (!dataFlag) {
that.equalFlag = false;
} else {
that.equalFlag = true;
}
return dataFlag;
},
/**
* @description:保存
* @author: 无尘
*/
saveSet: _debounce(function() {
const that = this;
if (!that.diffData()) {
return false;
}
/* 非空验证 */
if (that.clerkObj.storePerformance == '') {
that.$message.error({
duration: 1000,
message: '请输入门店月指标'
});
return false;
}
const data = {
clerkPerformanceList: that.tableData,
storePerformance: that.clerkObj.storePerformance,
operationStaffName: that.operationStaffName
};
that.postSave(data);
}, 500),
postSave(data) {
const that = this;
const para = {
enterpriseId: that.activeBrand,
storeId: that.clerkObj.storeId,
yearMonth: that.clerkObj.yearMonth,
performance: JSON.stringify(data)
};
saveSaleSet(para)
.then(res => {
if (res.code == '0000') {
showMsg.showmsg('保存成功', 'success');
return;
}
errMsg.errorMsg(res);
})
.catch(function(error) {
that.$message.error({
duration: 1000,
message: error.message
});
});
},
/**
* @description:获取设置数据
* @author: 无尘
*/
getData() {
const that = this;
const para = {
enterpriseId: that.activeBrand,
storeId: that.clerkObj.storeId,
yearMonth: that.clerkObj.yearMonth
};
getSaleSet(para)
.then(res => {
if (res.code == '0000') {
if (!!res.result.clerkPerformanceList && !!res.result.clerkPerformanceList.length) {
res.result.clerkPerformanceList.forEach(ele => {
ele.clerkPerformance = Number(ele.clerkPerformance).toFixed(2);
});
that.tableData = res.result.clerkPerformanceList || [];
}
res.result.storePerformance = Number(res.result.storePerformance).toFixed(2);
that.clerkObj = res.result;
let allSum = 0;
that.tableData.forEach(ele => {
allSum += Number(ele.clerkPerformance);
});
that.performanceSum = Number(allSum).toFixed(2);
return;
}
errMsg.errorMsg(res);
})
.catch(function(error) {
that.$message.error({
duration: 1000,
message: error.message
});
});
}
},
watch: {
brandId: function(newData, oldData) {
const that = this;
if (!!newData) {
that.activeBrand = newData;
that.clerkObj.yearMonth = that.$route.query.yearMonth;
that.clerkObj.storeId = that.$route.query.storeId;
that.getData();
}
}
},
};
</script>
<style type="text/scss" lang="scss" scoped>
.task-set-content {
box-sizing: border-box;
.w-105 {
width: 105px;
}
.w-120 {
width: 120px;
}
.w-161 {
width: 161px;
}
.m-b-15 {
margin-bottom: 15px;
}
.p-l-8 {
padding-left: 8px;
}
.p-l-18 {
padding-left: 18px;
}
.p-l-24 {
padding-left: 24px;
}
.p-l-175 {
padding-left: 175px;
}
.color-1890ff {
color: #2f54eb;
}
.color-f5222d {
color: #f5222d;
}
.colorFirst {
color: #303133;
font-weight: 600;
}
}
</style>
......@@ -8,8 +8,106 @@
-->
<!-- -->
<template>
<div>
<div class="common-app-right" style="padding: 0" v-loading="loading">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="已设置指标门店" name="first"></el-tab-pane>
<el-tab-pane label="未设置指标门店" name="second"></el-tab-pane>
</el-tabs>
<div class="list-content">
<div class="content-search">
<div>
<el-input
v-model.trim="search.input"
placeholder="请输入名称/code"
prefix-icon="el-icon-search"
@keydown.enter.native="searchStrategy"
clearable
@change="searchStrategy">
</el-input>
<el-select v-model="search.date" placeholder="选择年份" style="width: 128px"></el-select>
<span v-show="activeName === 'first'">
<el-select v-model="search.type" placeholder="全部指标类型">
<el-option label="业绩指标日权重" value="1"></el-option>
<el-option label="业绩指标日指标" value="2"></el-option>
<el-option label="新增会员日权重" value="3"></el-option>
<el-option label="新增会员日指标" value="4"></el-option>
</el-select>
<el-select v-model="search.auth" placeholder="全部编辑权限">
<el-option label="店长可编辑" value="1"></el-option>
<el-option label="店长不可编辑" value="0"></el-option>
</el-select>
</span>
<el-select v-model="search.state" style="width: 106px;margin-right: -1px">
<el-option label="门店分组" value="1"></el-option>
<el-option label="门店标签" value="2"></el-option>
</el-select>
<el-select v-model="search.store" placeholder="选择门店分组"></el-select>
</div>
<el-select placeholder="操作" @change="batchOperation">
<el-option label="新增指标" :value="1"></el-option>
<el-option label="编辑指标" :value="2"></el-option>
<el-option label="修改编辑权限" :value="3"></el-option>
</el-select>
</div>
<div class="content-data">
<div>
<span class="color2">年业绩指标:¥ </span>
<span class="color1">100,000</span>
<span class="color2">年新增会员指标:¥ </span>
<span class="color1">100,000</span>
</div>
<span v-show="activeName === 'second'">
<el-checkbox v-model="search.noPerformanceFlag" :true-label="1" :false-label="0">未设置业绩指标门店</el-checkbox>
<el-checkbox v-model="search.noAddMemberFlag" :true-label="1" :false-label="0">未设置新增会员指标门店</el-checkbox>
</span>
</div>
<el-table
:data="tableData"
style="width: 100%"
ref="multipleTable"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="date" label="门店"></el-table-column>
<el-table-column prop="date" label="年业绩指标"></el-table-column>
<el-table-column prop="date" label="年新增会员指标"></el-table-column>
<el-table-column prop="date" label="编辑权限"></el-table-column>
<el-table-column prop="date" label="更新时间"></el-table-column>
<el-table-column prop="date" label="提交人"></el-table-column>
<el-table-column prop="date" label="操作">
<template>
<el-button type="text">编辑</el-button>
<el-button type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
<dm-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="page.currentPage"
:page-sizes="[20, 40, 60, 80]"
:page-size="page.pageSize"
layout="total, sizes, prev, pager, next"
:total="page.total"
style="text-align:right">
</dm-pagination>
</div>
</div>
</template>
......@@ -19,22 +117,116 @@ export default {
components: {},
data() {
return {
activeName: '',
search: {
input: '',
date: '',
type: '',
auth: '',
state: '1',
store: '',
noPerformanceFlag: '0',
noAddMemberFlag: '0'
},
multipleSelection: [],
tableData: [],
loading: false,
page: {
currentPage: 1,
pageSize: 20,
total: 0
}
};
},
// 生命周期 - 挂载完成(访问DOM元素)
// mounted() {
// },
created() {
const { tab } = this.$route.query;
this.activeName = tab || 'first';
console.log(this);
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted() {
this.$emit('showTab', '/quota-set');
this.$emit('change-nav', [ { name: '指标设置' } ]);
},
// methods
methods: {
batchOperation(val) {
console.log(val);
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
handleClick({ name }) {
console.log(name);
},
handleSizeChange(val) {
this.page.pageSize = val;
this.page.currentPage = 1;
// this.getList();
},
handleCurrentChange(val) {
this.page.currentPage = val;
// this.getList();
}
},
watch: {}
};
</script>
<style lang='less' scoped>
.list-content {
padding: 5px 20px 20px;
.el-input {
width: 180px;
margin-right: 10px;
}
.el-select {
width: 148px;
margin-right: 10px;
}
.el-date-picker {
margin-right: 10px;
}
}
// .el-select .el-input.is-focus .el-input__inner {
// z-index: 2;
// }
.content-search {
display: flex;
justify-content: space-between;
}
.content-data {
display: flex;
justify-content: space-between;
margin: 20px 0;
}
.color1 {
color: #303133;
font-size: 16px;
padding-right: 15px;
font-weight: 500;
}
.color2 {
position: relative;
color: #606266;
font-size: 14px;
font-weight: 400;
&:not(:first-of-type) {
padding-left: 16px;
&::before {
content: '|';
position: absolute;
top: 0;
left: 0;
color: #DCDFE6;
}
}
}
</style>
......@@ -8,8 +8,37 @@
-->
<template>
<div class="common-app-right">
<div>
<div class="common-app-right" style="padding: 0">
<div v-loading="loading">
<el-tabs v-model="activeName" @tab-click="getData">
<el-tab-pane label="业绩指标" name="1"></el-tab-pane>
<el-tab-pane label="新增会员指标" name="2"></el-tab-pane>
</el-tabs>
<div class="list-content">
<el-select v-model="search.date">
<el-option v-for="item in yearList" :key="item" :label="item" :value="item"></el-option>
</el-select>
<el-table
:data="tableData"
style="width: 100%;margin-top: 20px">
<el-table-column prop="performanceYm" label="月份"></el-table-column>
<el-table-column prop="storeCount" label="门店总数"></el-table-column>
<el-table-column prop="totalPerformanceValue" label="总业绩指标"></el-table-column>
<el-table-column label="业绩指标">
<template slot-scope="{row}">
{{ row.noPerfectCount || '--' }} 未完善;{{ row.prefectCount || '--' }} 已完善
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="{row}">
<el-button type="text" @click="$router.push({ path: '/target-store', query: { tab: activeName, id: row.id } })">查看门店</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
......@@ -18,7 +47,7 @@
<script>
import fetch from '@/api/target-manage-app.js';
const { getTargetList } = fetch;
const { getTargetList, getYearList } = fetch;
// import showMsg from '@/common/js/showmsg.js';
export default {
name: 'TargetList',
......@@ -32,15 +61,27 @@ export default {
data() {
return {
wxEnterpriseId: localStorage.getItem('haoBanUser') ? JSON.parse(localStorage.getItem('haoBanUser')).wxEnterpriseId : '',
tableData: []
tableData: [ {} ],
activeName: '1',
search: {
date: ''
},
yearList: [],
loading: false
};
},
created() {
const { tab } = this.$route.query;
this.activeName = tab || '1';
},
// 生命周期 - 挂载完成(访问DOM元素)
mounted() {
const that = this;
that.$emit('showTab', '/target-list');
that.$emit('change-nav', [ { name: '指标管理' } ]);
if (!!that.brandId) {
that.getData();
that.getYearList();
}
},
// methods
......@@ -50,19 +91,27 @@ export default {
* @author: 无尘
*/
getData() {
this.loading = true;
const that = this;
const para = {
wxEnterpriseId: that.wxEnterpriseId,
enterpriseId: that.brandId
enterpriseId: that.brandId,
perfromanceType: this.activeName,
performanceYear: this.search.date
};
getTargetList(para, { headers: { sign: that.brandId } })
.then(res => {
that.tableData = res.result || [];
})
.catch(function(error) {
.finally(() => {
this.loading = false;
});
},
getYearList() {
getYearList('', { headers: { sign: this.brandId } }).then(res => {
this.yearList = res.result || [];
});
}
},
watch: {
......@@ -90,4 +139,7 @@ export default {
color: #303133;
}
}
.list-content {
padding: 5px 20px 20px;
}
</style>
......@@ -4,37 +4,112 @@
* @Author: 无尘
* @Date: 2020-11-09 10:05:27
* @LastEditors: 无尘
* @LastEditTime: 2020-11-09 10:22:49
* @LastEditTime: 2020-11-17 17:12:42
-->
<!-- -->
<template>
<div>
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm" @submit.native.prevent>
<el-form-item label="" prop="days">
<span class="font-14 color-606266">下发时间当月,第 </span><el-input-number controls-position="right" class="w-100" v-model="ruleForm.days" placeholder="请输入" :step="1" :step-strictly="true" :min="1" :max="99999999"></el-input-number><span class="font-14 color-606266 p-l-10"></span>
<span class="font-14 color-909399">注:如当月第28天下发,如果现在是1月份,即1月28号下发2月份指标。设置后次日生效</span>
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="loadingBtn" @click="submitForm('ruleForm')">保存</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import fetch from '@/api/target-manage-app.js';
const { saveTargetSet, getTargetSet } = fetch;
import { _debounce } from '@/common/js/public';
export default {
name: 'TargetSet',
components: {},
props: {
brandId: {
type: String,
default() {
return '';
}
}
},
data() {
return {
wxEnterpriseId: localStorage.getItem('haoBanUser') ? JSON.parse(localStorage.getItem('haoBanUser')).wxEnterpriseId : '',
userInfo: localStorage.getItem('haoBanUser') ? JSON.parse(localStorage.getItem('haoBanUser')) : { staffId: '', staffName: '' },
ruleForm: {
days: ''
},
rules: {
days: [
{ required: true, message: '请输入', trigger: 'blur' },
]
},
loadingBtn: false
};
},
// 生命周期 - 挂载完成(访问DOM元素)
// mounted() {
// },
// methods
methods: {
/**
* 保存
*/
saveSet: _debounce(function() {
const that = this;
that.loadingBtn = true;
that.postSave();
}, 300),
postSave() {
const that = this;
const para = {
days: that.ruleForm.days,
enterpriseId: that.brandId,
wxEnterpriseId: that.wxEnterpriseId,
submitStaffId: that.userInfo.staffId,
submitStaffName: that.userInfo.staffName
};
saveTargetSet(para)
.then(res => {
that.loadingBtn = false;
that.$message.success('保存成功');
})
.catch(function(error) {
that.loadingBtn = false;
});
},
/**
* 获取设置数据
*/
getData() {
const that = this;
const para = {
enterpriseId: that.brandId,
wxEnterpriseId: that.wxEnterpriseId
};
getTargetSet(para)
.then(res => {
that.ruleForm.days = res.result.days || '';
})
.catch(function(error) {
});
}
},
watch: {
brandId: function(newData, oldData) {
const that = this;
if (!!newData) {
that.getData();
}
}
},
watch: {}
};
</script>
<style lang='less' scoped>
</style>
......@@ -6,3 +6,26 @@
* @LastEditors: 无尘
* @LastEditTime: 2020-11-09 10:40:34
-->
<template>
<div class="common-app-right">
<el-button type="text" @click="$router.push({ path: '/perfect-day-target' })">完善日指标</el-button>
</div>
</template>
<script>
export default {
name: 'TargetStore',
mounted() {
const that = this;
// that.$emit('showTab', '/target-store');
that.$emit('change-nav', [ { name: '指标管理', path: '/target-list' }, { name: '查看门店' } ]);
if (!!that.brandId) {
// that.getData();
}
},
};
</script>
<style>
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment