Commit 718169da by liuchenxi

Merge branch 'feature/12月迭代'

# Conflicts:
#	src/components/allCustomers/customerDetail.vue
parents c0cd185c 5df8be9b
const authCode = {
memberBatchSetIntegral: "memberBatchSetIntegral",
memberBatchSetGrade: "memberBatchSetGrade",
memberBatchSetService: "memberBatchSetService",
memberBatchSetCustomer: "memberBatchSetCustomer",
memberBatchImport: "memberBatchImport",
memberIntoCustomDetail: "memberIntoCustomDetail",
memberEditInfo: "memberEditInfo",
memberEditManualTag: "memberEditManualTag",
memberEditGrade: "memberEditGrade",
memberAdjustIntegral: "memberAdjustIntegral",
memberCardDestory: 'memberCardDestory',
memberCardWriteOff: 'memberCardWriteOff',
memberFrozenMember: 'memberFrozenMember',
memberCleanFrozen: 'memberCleanFrozen',
memberBatchCleanFrozen: 'memberBatchCleanFrozen',
memberFrozenNovelMember: 'memberFrozenNovelMember',
memberFrozen: 'memberFrozen',
memberTaskSwitch: 'memberTaskSwitch', // 会员任务-停用、启用开关
memberTaskSetAward: 'memberTaskSetAward', // 会员任务-配置任务奖励
memberAchievementSwitch: 'memberAchievementSwitch', // 会员成就消费类-开关
memberAchievementSetAmount: 'memberAchievementSetAmount', // 会员成就消费类-配置额度
memberAchievementSetAward: 'memberAchievementSetAward', // 会员成就消费类-配置奖励
memberInteractionSwitch: 'memberInteractionSwitch', // 会员成就互动类-开关
memberInteractionSetAmount: 'memberInteractionSetAmount', // 会员成就互动类-配置额度
memberInteractionSetAward: 'memberInteractionSetAward', // 会员成就互动类-配置奖励
};
export default authCode;
......@@ -75,15 +75,15 @@ export default {
});
},
setStore(data) {
const { enterpriseId, superAdmin } = data;
const ids = [
'ff8080816dd0385e016ddca436d01fe1', // 生产巴拉商户
'ff8080816a36326c016a53380d8b5f52', // 生产金华达摩
'ff8080815dacd3a2015dacd3ef5c0000', // 测试金华达摩
]
this.$store.commit('checkAdmin', data);
// 如果是巴拉的子账号,不显示积分相关的操作按钮
this.$store.commit('showHandleScoreBtn', !(ids.includes(enterpriseId) && superAdmin == 0));
// // 如果是巴拉的子账号,不显示积分相关的操作按钮(废弃)
// const { enterpriseId, superAdmin } = data;
// const ids = [
// 'ff8080816dd0385e016ddca436d01fe1', // 生产巴拉商户
// 'ff8080816a36326c016a53380d8b5f52', // 生产金华达摩
// 'ff8080815dacd3a2015dacd3ef5c0000', // 测试金华达摩
// ]
// this.$store.commit('showHandleScoreBtn', !(ids.includes(enterpriseId) && superAdmin == 0));
}
}
}
......
......@@ -19,7 +19,7 @@
</router-link>
</el-breadcrumb-item>
</el-breadcrumb>
<div class="navtitle">
<div class="navtitle" v-if="showTitle">
{{ navpath[navpath.length - 1].name }}
<slot name="member"></slot>
<div v-html="layoutTips" class="layout--tips--wrap"></div>
......@@ -42,6 +42,10 @@ export default {
default() {
return [];
}
},
showTitle: {
type: Boolean,
default:true
}
},
methods: {},
......
......@@ -19,6 +19,8 @@
<span class="achievement-title">{{ item.achievementName }}</span>
<div class="achievement-handler tr">
<el-switch
v-if="getCodeAuth('memberInteractionSwitch')"
:limit-code="getCode('memberInteractionSwitch')"
v-model="item.isOpen"
@change="changeValue(item, index)"
>
......@@ -50,6 +52,8 @@
></el-input-number>
<span v-show="scope.row.isEdit !== true">{{ scope.row.achievementTarget }} </span> <span>{{ item.achievementDoc | formatEnd }}</span>
<i
v-if="getCodeAuth('memberInteractionSetAmount')"
:limit-code="getCode('memberInteractionSetAmount')"
v-show="isEdit == 1 && scope.row.isEdit !== true"
@click="editAchievementTarget(scope.row)"
class="el-icon-edit pointer"
......@@ -81,6 +85,8 @@
<span v-if="scope.row.achievementRewardType === 1">{{ scope.row.rewardValue }} <span> 积分</span></span>
<span v-if="scope.row.achievementRewardType === 2">{{ scope.row.rewardName }}</span>
<i
v-if="getCodeAuth('memberInteractionSetAward')"
:limit-code="getCode('memberInteractionSetAward')"
@click="eidtRewardValue(scope.row)"
v-show="isEdit == 1"
class="el-icon-edit pointer"
......@@ -183,6 +189,7 @@
import nav from "../../common/navbar/navbar.vue";
import { doFetch } from "../../components/axios/api";
import url from "../../components/axios/url";
import authMethods from '@/mixins/auth.js';
import {
checkFalse,
checkStatus,
......@@ -232,6 +239,7 @@ export default {
cardType: null
};
},
mixins: [ authMethods ],
filters: {
formatStart: function(value) {
if (value && value.indexOf("XX") !== -1) {
......
......@@ -14,6 +14,8 @@
<span class="achievement-title">{{ item.achievementName }}</span>
<div class="achievement-handler tr">
<el-switch
v-if="getCodeAuth('memberAchievementSwitch')"
:limit-code="getCode('memberAchievementSwitch')"
v-model="item.isOpen"
:disabled="item.disabled"
@change="changeValue(item)"
......@@ -44,6 +46,8 @@
></el-input-number>
<span v-show="scope.row.isEdit !== true">{{ scope.row.achievementTarget }} </span> <span>{{ item.achievementDoc | formatEnd }}</span>
<i
v-if="getCodeAuth('memberAchievementSetAmount')"
:limit-code="getCode('memberAchievementSetAmount')"
v-show="isEdit == 1 && scope.row.isEdit !== true"
@click="editAchievementTarget(scope.row)"
class="el-icon-edit pointer"
......@@ -74,6 +78,8 @@
<span v-if="scope.row.achievementRewardType === 1">{{ scope.row.rewardValue }} <span> 积分</span></span>
<span v-if="scope.row.achievementRewardType === 2">{{ scope.row.rewardName }}</span>
<i
v-if="getCodeAuth('memberAchievementSetAward')"
:limit-code="getCode('memberAchievementSetAward')"
@click="eidtRewardValue(scope.row)"
v-show="isEdit == 1"
class="el-icon-edit pointer"
......@@ -179,6 +185,7 @@
import nav from "../../common/navbar/navbar.vue";
import { doFetch } from "../../components/axios/api";
import url from "../../components/axios/url";
import authMethods from '@/mixins/auth.js';
import {
checkFalse,
checkStatus,
......@@ -225,6 +232,7 @@ export default {
cardType: null
};
},
mixins: [ authMethods ],
filters: {
formatStart: function(value) {
if(value && value.indexOf('XX') !== -1) {
......
......@@ -65,31 +65,16 @@
style="width: 150px;margin-right:10px;"
@visible-change="handleVisibleBatch"
>
<!-- 如果是巴拉的子账号,不显示积分相关的操作按钮 -->
<el-option
key="integral"
label="调整积分"
value="integral"
v-if="showHandleScoreBtn"
/>
<el-option
:key="item.value"
v-for="item in batchOpt"
:label="item.label"
:value="item.value"
/>
<template v-for="item in batchOpt">
<el-option
v-if="getCodeAuth(item.code)"
:key="item.value"
:label="item.label"
:limit-code="getCode(item.code)"
:value="item.value"
/>
</template>
</el-select>
<el-popover
placement="top-start"
:width="isdot ? 450 : 160"
trigger="hover"
@show="getProcessList"
>
<batch-list :dataList="processList" />
<el-badge slot="reference" :is-dot="isdot" class="item">
<el-button type="primary" class="member-wechat-timer" icon="el-icon-time" />
</el-badge>
</el-popover>
</div>
</div>
<div v-show="showSearch" class="senior-search-content">
......@@ -140,7 +125,7 @@
<div v-if="colum == 'name'" class="customer-info-cell">
<img :src="row.thirdImgUrl||defaultImg" alt="">
<p class="memberName">
{{ row.memberName | formatMember }}
{{ row.memberName || '--' }}
</p>
</div>
<!-- 等级 -->
......@@ -233,9 +218,10 @@
<i class="el-icon-setting" @click="dialogFieldVisible=true" />
</template>
<template slot-scope="{row}">
<el-button type="text" @click="linkDetail(row.memberId)">
<el-button v-if="getCodeAuth('memberIntoCustomDetail')" type="text" @click="linkDetail(row.memberId)" :limit-code="getCode('memberIntoCustomDetail')">
查看
</el-button>
<span v-else>--</span>
</template>
</el-table-column>
</el-table>
......@@ -268,6 +254,7 @@
:integralFlag="integralFlag"
:ajaxObj="{...ajaxObj}"
:selectObj="{...selectObj}"
@successImport="successImport"
/>
<!-- 批量修改等级弹窗 -->
<grade-dailog
......@@ -277,6 +264,7 @@
:cliqueGradeList="cliqueMemberGrade"
:ajaxObj="{...ajaxObj}"
:selectObj="{...selectObj}"
@successImport="successImport"
/>
<!-- 批量修改服务门店弹窗 -->
<mainstore-dailog
......@@ -284,6 +272,7 @@
@refresh="batchRefresh"
:selectObj="{...selectObj}"
:ajaxObj="{...ajaxObj}"
@successImport="successImport"
/>
<!-- 批量修改协管门店弹窗 -->
<substore-dailog
......@@ -291,7 +280,10 @@
@refresh="batchRefresh"
:selectObj="{...selectObj}"
:ajaxObj="{...ajaxObj}"
@successImport="successImport"
/>
<!-- 批量导入 -->
<import-dialog :dialogVisible.sync="dialogImportVisible" @successImport="successImport"/>
</div>
</template>
<script>
......@@ -311,4 +303,10 @@ export default { ...action };
.customer-dialog .el-dialog__body {
padding-bottom: 0;
}
.import-link-confirm-content{
.el-message-box__status{
top: 0;
transform: translateY(0);
}
}
</style>
......@@ -6,75 +6,56 @@
:visible.sync="visible"
:close-on-click-modal="false"
@close="cancel"
width="636px"
width="480px"
>
<el-tabs v-model="activeName">
<el-tab-pane
v-for="(item,index) in fieldsList"
:key="index"
:label="item.form.name||item.bName"
:label="`宝宝${index + 1}${item['k20301'] ? `(${item['k20301']})`: '' }`"
:name="`${index}`"
/>
>
<el-form
ref="form"
:model="item.form"
label-width="122px"
>
<el-form-item v-for="item in babyConfigTemplate.template" :key="item.unifiedIdentification" :label="item.fieldName+ ':'" :prop="item.unifiedIdentification" :rules="getRules(item)">
<el-input
v-if="item.fieldType == 0"
v-model="fieldsList[activeName].form[item.systemFieldId]"
:placeholder="item.fieldDescription"
type="text"
:show-word-limit="item.unifiedIdentification == 'k20301'"
:maxlength="item.limitCountMax"
:class="{'baby-name': item.unifiedIdentification == 'k20301'}"
:style="{width: item.unifiedIdentification == 'k20301' ? '300px' : '160px'}"
/>
<el-date-picker
v-if="item.fieldType == 4"
:placeholder="item.fieldDescription"
style="width: 160px;"
value-format="yyyy-MM-dd"
v-model="fieldsList[activeName].form[item.systemFieldId]"
type="date"
/>
<el-select v-if="item.fieldType == 2" :placeholder="item.fieldDescription" v-model="fieldsList[activeName].form[item.systemFieldId]" style="width: 160px;">
<el-option v-for="(el, index) in JSON.parse(item.fieldContent.replaceAll('\'', '&quot;'))" :key="index" :label="el.name" :value="el.name" />
</el-select>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
<el-form
v-if="fieldsList[activeName]"
ref="form"
:model="fieldsList[activeName].form"
label-width="122px"
:inline="true"
:disabled="true"
>
<el-form-item label="宝宝名称:" prop="name">
<el-input
type="text"
maxlength="10"
show-word-limit
v-model="fieldsList[activeName].form.name"
style="width: 160px;"
/>
</el-form-item>
<el-form-item label="宝宝生日:" prop="birthDay">
<el-date-picker
style="width: 160px;"
v-model="fieldsList[activeName].form.birthDay"
type="date"
/>
</el-form-item>
<el-form-item label="宝宝性别:" prop="sex">
<el-select v-model="fieldsList[activeName].form.sex" style="width: 160px;">
<el-option label="男" :value="1" />
<el-option label="女" :value="2" />
</el-select>
</el-form-item>
<el-form-item label="宝宝身高(cm):" prop="height">
<el-input
v-model="fieldsList[activeName].form.height"
type="text"
show-word-limit
style="width: 160px;"
/>
</el-form-item>
<el-form-item label="宝宝体重(kg):" prop="weight">
<el-input
v-model="fieldsList[activeName].form.weight"
type="text"
show-word-limit
style="width: 160px;"
/>
</el-form-item>
<el-form-item label="鞋码(码):" prop="shoeSize">
<el-input
v-model="fieldsList[activeName].form.shoeSize"
type="text"
show-word-limit
style="width: 160px;"
/>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="$emit('update:dialogVisible', false)">取消</el-button>
<el-button type="primary" @click="onSave" :loading="loading">保存</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { doFetch } from '../../axios/api';
import url from '../../axios/url';
export default {
name: 'BabyinfoDialog',
props: {
......@@ -88,43 +69,133 @@ export default {
return [];
},
},
babyConfigTemplate: {
type: Object,
default: () => {
return {}
}
}
},
data () {
return {
visible: false,
fieldsList: [],
activeName: '0',
loading: false
};
},
watch: {
dialogVisible (n, o) {
this.visible = n;
if (n) {
const filterObj = {
'宝宝名称': 'name',
'宝宝性别': 'sex',
'宝宝生日': 'birthDay',
'宝宝身高(cm)': 'height',
'宝宝体重(kg)': 'weight',
'鞋码(码)': 'shoeSize',
};
const fieldList = this.childFieldsList.map(el => {
el.form = {
name: '',
sex: '',
birthDay: '',
height: '',
weight: '',
shoeSize: '',
'k20301': '',
'k20302': '',
'k20303': '',
'k20304': '',
'k20305': '',
'k20306': '',
};
el.sonFields.map(field => (el.form[filterObj[field.fieldName]] = field.fieldValue));
el.sonFields.forEach(field => {
el.form[field.unifiedIdentification] = field.fieldValue || '';
el[field.unifiedIdentification] = field.fieldValue || '';
});
return el;
});
this.fieldsList = JSON.parse(JSON.stringify(fieldList));
let formRef = this.$refs.form
if(Array.isArray(formRef)) {
formRef.forEach(el => {
el.clearValidate();
})
} else if(formRef) {
formRef.clearValidate();
}
}
},
},
methods: {
async onSave() {
let formRefs = this.$refs.form;
if(Array.isArray(formRefs)) {
for(let i = 0; i < formRefs.length; i++) {
let valid = await formRefs[i].validate().catch(() => {
this.$message.error(`宝宝${i+1}信息填写错误`);
})
if(!valid) return;
}
} else if(formRefs) {
let valid = await formRefs.validate();
if(!valid) return;
}
let params = {
fieldValueId: this.babyConfigTemplate.fieldValueId,
memberId: this.babyConfigTemplate.memberId,
enterpriseOpencardFieldId: this.babyConfigTemplate.enterpriseOpencardFieldId,
systemFieldId: this.babyConfigTemplate.systemFieldId,
unifiedIdentification: this.babyConfigTemplate.unifiedIdentification,
fieldName: this.babyConfigTemplate.fieldName,
fieldType: this.babyConfigTemplate.fieldType,
fieldContent: this.babyConfigTemplate.fieldContent,
fieldCode: this.babyConfigTemplate.fieldCode,
fieldValue: this.babyConfigTemplate.fieldValue,
}
let babyTemplates = this.babyConfigTemplate.template;
let child = this.fieldsList.map(el => {
let value = [];
for(let key in el.form) {
if(el.form[key]) {
let findItem = babyTemplates.find(e => e.unifiedIdentification == key);
let fieldValue = el.form[key];
if(findItem.fieldType == 4) {
fieldValue = fieldValue.replaceAll('-', '');
}
value.push({enterpriseOpencardFieldId: findItem.enterpriseOpencardFieldId, unifiedIdentification: findItem.unifiedIdentification, fieldValue, systemFieldId: findItem.systemFieldId});
}
}
return value;
})
params.child = child;
this.loading = true;
doFetch(url.updateBabyInfo, Object.assign({}, params)).then(() => {
this.$emit('update:dialogVisible', false);
this.$parent.initData();
}).finally(() => {
this.loading = false;
})
},
getRules(item) {
let ruleReg = new RegExp(item.ruleContent)
let validatePass = null
if(item.fieldType == 0) {
validatePass = (rule, value, callback) => {
if (value === '' || ruleReg.test(value)) {
callback();
} else {
callback(new Error('请输入正确的内容'));
}
}
return { validator: validatePass, trigger: 'blur' }
} else if(item.unifiedIdentification == 'k20303') {
let rule = JSON.parse(item.fieldContent.replaceAll('\'', '"'));
let time = rule.timeLong
validatePass = (rule, value, callback) => {
if (value === '' || value === null) {
callback();
} else if (new Date().getFullYear() - new Date(value).getFullYear() > parseInt(time)) {
callback(new Error(`超过当前日期时间之前${time}年`));
} else if(new Date(value) > new Date()) {
callback(new Error(`超过当前日期时间`));
} else {
callback();
}
}
return { validator: validatePass, trigger: 'blur' }
} else {
return null
}
},
cancel () {
this.$emit('update:dialogVisible', false);
},
......@@ -134,6 +205,11 @@ export default {
</script>
<style lang="less">
// 去除dailog-footer上边框
.baby-name {
.el-input__inner {
padding-right: 45px;
}
}
.customer-dialog .el-dialog__footer {
padding-top: 0;
padding-bottom: 20px;
......@@ -153,6 +229,9 @@ export default {
.el-form-item__label {
padding-right: 0;
}
.el-tabs__content {
overflow: initial !important;
}
}
.customer-dialog.baby-info-dialog .el-dialog__body{
padding-top: 5px;
......
......@@ -164,6 +164,7 @@ export default {
checkSuccess();
this.$refs.form.resetFields();
this.$emit('update:dialogVisible', false);
this.$emit('successImport', res.data.result);
this.$emit('refresh');
} else {
checkFalse();
......
......@@ -259,6 +259,10 @@ export default {
}
.customer-dialog .el-dialog__body {
padding-bottom: 0;
.tags-list {
max-height: 240px;
overflow: auto;
}
}
.label-dailog {
.el-tabs__header {
......
<template>
<!-- 新建导入 -->
<el-dialog title="新建导入" custom-class="customer-dialog" :visible.sync="dialogImport" width="600px" @closed="onDialogImportClosed">
<el-form ref="formByImport" :rules="rules" :model="formByImport" label-width="100px"
label-suffix=":" style="margin-bottom: 36px;">
<el-form-item label="导入类型" prop="importValue">
<el-select v-model="formByImport.importValue" placeholder="请选择导入类型"
@change="handleChangeType">
<el-option label="积分增加" value="11"></el-option>
<el-option label="积分扣除" value="12"></el-option>
<el-option label="等级调整" value="13"></el-option>
<el-option label="服务门店调整" value="14"></el-option>
<el-option label="批量冻结会员" value="15"></el-option>
<el-option label="批量解冻会员" value="16"></el-option>
</el-select>
</el-form-item>
<el-form-item label="选择文件" prop="file" required>
<el-upload ref="memberUpload" v-loading="load" class="upload-demo" :action="actionUrl"
accept=".xlsx" :file-list="formByImport.fileList" :before-upload="beforeUpload" :limit="1"
:data="expendParams" :with-credentials="true" :on-error="handleError"
:on-exceed="handelExceed" :on-change="handleChange" :on-success="handleSuccess"
:auto-upload="false">
<div slot="trigger">
<div class="importBox">
<i class="iconfont icon-shangchuan"></i>
点击上传
</div>
</div>
<el-button type="text" style="font-size: 12px; margin-left: 12px;"
v-if="formByImport.importValue" @click="downloadTemplate">
点击下载{{ formByImport.importValue | formatType }}模板
</el-button>
</el-upload>
</el-form-item>
</el-form>
<div class="dialogTips">
<h3>导入规则</h3>
<p>1. 通过导入Excel表格的形式变更GIC已存在会员的积分等级门店;不支持导入新会员数据 </p>
<p>2. 仅支持.xlsx 文件的导入;每次导入数据量最多为10000条;文件大小不超过1M </p>
<p>3. 导入类型不同,文件模板也不同,请严格按照模板内容填入会员数据,否则将会报错 </p>
<p>4. 请仔细核对需要变更的会员数据是否准确,否则GIC校验不通过将无法执行成功</p>
<p>5. 超管账号支持导入变更全部会员信息,已分权商户的子管理员账号仅可修改管辖范围内的会员信息</p>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="onDialogImportClosed">取 消</el-button>
<el-button type="primary" @click="importTable" :disable="load">确 定</el-button>
</span>
</el-dialog>
</template>
<script>
import url from "@/components/axios/url";
import {
checkFalse,
checkSuccess
} from "../../../../static/js/checkStatus";
export default {
props: {
dialogVisible: {
type: Boolean,
default: false,
},
},
filters: {
// 模板下载文字过滤
formatType(val) {
val = +val;
switch (val) {
case 11:
return '积分增加';
case 12:
return '积分扣除';
case 13:
return '等级调整';
case 14:
return '服务门店调整';
case 15:
return '批量冻结会员';
case 16:
return '批量解冻会员';
}
}
},
data() {
return {
actionUrl: url.uploadExecl,
// 搜索选项值
importType: '',
// 新建dialog
dialogImport: false,
// 表单
formByImport: {
importValue: '',
fileList: [],
},
// 请求数据
expendParams: {
requestProject: 'member',
batchType: ''
},
rules: {
importValue: [ { required: true, message: '请选择导入类型', trigger: 'change' } ]
},
rows: 0, // excel数据数量
// 上传验证加载
load: false,
};
},
watch: {
dialogVisible (n, o) {
this.dialogImport=n;
}
},
methods: {
handleChangeType(val) {
console.log(val);
this.expendParams.batchType = val;
},
// 打开dialog
openDialogImport() {
this.formByImport.importValue = '';
this.dialogImport = true;
},
// 表单清除
onDialogImportClosed() {
this.$refs.formByImport.resetFields();
this.$emit('update:dialogVisible',false)
},
// 下载模板
downloadTemplate() {
window.location.href = url.downLoadExcelTemplate + '?requestProject=member&batchType=' + this.formByImport.importValue;
},
// 确认导入
importTable() {
this.$refs.formByImport.validateField('importValue', err => {
if (!err) {
// console.log(this.formByImport.fileList);
if (this.formByImport.fileList.length) {
this.load = true;
this.$refs.memberUpload.submit();
// this.getIntegral();
} else {
checkFalse('请上传积分数据');
}
}
});
},
// 上传验证
beforeUpload(file) {
// let _this = this;
const isLt2M = file.size / 1024 / 1024 < 1;
const types = file.name.split(".");
const type = types[ types.length - 1 ];
const fileType = [ "xlsx", "xlc", "xlm", "xls", "xlt", "xlw", "csv" ].some(item => item === type);
if (!fileType) {
this.$message.warning("请上传excel表格");
return false;
}
if (!isLt2M) {
this.$message.error('上传模板大小不能超过 1MB');
return false;
}
},
handleChange(file, fileList) {
this.formByImport.fileList = fileList;
},
handelExceed() {
this.$message.warning('超出最大上传数');
},
handleError() {
checkFalse('上传失败');
this.$refs.memberUpload.clearFiles();
this.load = false;
},
handleSuccess(response, file, fileList) {
if (response.errorCode == 0) {
checkSuccess('上传成功');
this.load = false;
this.$refs.memberUpload.clearFiles();
this.$emit('update:dialogVisible', false);
this.$emit('successImport', response.result)
} else {
this.$refs.memberUpload.clearFiles();
this.load = false;
checkFalse(response.message);
}
}
},
created() {
},
}
</script>
<style lang="scss" scoped>
/deep/ .el-dialog__footer {
border: none;
}
.importBox {
width: 174px;
border: 1px dashed #c0c4cc;
border-radius: 6px;
}
.dialogTips {
padding-bottom: 8px;
padding-top: 22px;
border-top: 1px solid #e4e7ed;
color: #909399;
h3 {
font-weight: normal;
font-size: 14px;
margin-bottom: 10px;
}
p {
font-size: 12px;
}
}
.success_icon {
text-align: center;
color: #52c41a;
font-size: 47px;
}
.successHeader {
text-align: center;
color: #303133;
font-size: 16px;
line-height: 39px;
}
.successCon {
text-align: center;
color: #606266;
font-size: 12px;
}
.member-wechat-timer {
width: 20px;
height: 20px;
font-size: 10px;
line-height: 20px;
padding: 0;
}
.dialogSuccess /deep/ .el-dialog__footer {
text-align: center;
padding-bottom: 22px;
}
</style>
......@@ -189,10 +189,12 @@ export default {
pageName: pageName,
}))
.then(res => {
console.log(res);
if (res.data.errorCode === 0) {
checkSuccess('');
this.$refs.form.resetFields();
this.$emit('update:dialogVisible', false);
this.$emit('successImport', res.data.result);
this.$emit('refresh');
} else {
checkFalse();
......
......@@ -139,6 +139,7 @@ export default {
checkSuccess();
this.$refs.form.resetFields();
this.$emit('update:dialogVisible', false);
this.$emit('successImport', res.data.result);
this.$emit('refresh');
} else {
checkFalse();
......@@ -198,4 +199,4 @@ export default {
line-height: 17px;
}
}
</style>
\ No newline at end of file
</style>
......@@ -171,6 +171,7 @@ export default {
checkSuccess();
this.$refs.form.resetFields();
this.$emit('update:dialogVisible', false);
this.$emit('successImport', res.data.result);
this.$emit('refresh');
} else {
checkFalse();
......
......@@ -21,11 +21,19 @@
<div class="record" v-loading="fullscreenLoading">
<div class="record-search">
<div class="record-searchitem">
<el-select v-model="orderType" style="width:160px;" placeholder="所有类型"
<el-select v-model="orderType" style="width:160px;margin-right:6px;" placeholder="所有类型"
@change="handleSearch">
<el-option v-for="item in orderOpts" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
<el-input
style="width:260px;"
v-model="searchInfo"
prefix-icon="el-icon-search"
placeholder="输入订单编号/原始单号"
@change="handleSearch"
clearable
/>
</div>
</div>
<div class="table-content" v-loading="load">
......@@ -41,6 +49,9 @@
<p class="order-number">
订单编号:{{ group.orderNumber }}
</p>
<p class="order-number" v-if="group.orderStatus!==1">
原始单号:{{ group.oorderNumber||'无' }}
</p>
<p class="order-time">
订单时间:{{ group.receiptsDate|formatTime }}
</p>
......@@ -61,7 +72,7 @@
v-if="['orderStatus','clerkName','payAmount'].includes(colunm.prop)">
<!-- 订单类型 -->
<template v-if="colunm.prop==='orderStatus'">
<div style="padding-left:14px;">{{ group[colunm.prop]|orderTypeFilter }}
<div :style="{paddingLeft:'14px',color:orderColor[group.orderStatus]}">{{ group.orderStatus|orderTypeFilter }}
</div>
</template>
<template v-else-if="colunm.prop==='clerkName'">
......@@ -229,6 +240,7 @@ export default {
avgDiscount: 0,
},
orderType: -1,
searchInfo:'',
orderLoading: false,
orderInfo: {},
payInfo: [],
......@@ -265,6 +277,7 @@ export default {
{ label: '导购', width: '120', prop: 'clerkName' },
{ label: '小计(实付)', width: '120', prop: 'payAmount' },
],
orderColor:{1:'#303133',2:'#FA8C16',4:'#F5222D'},
brokeImg,
};
},
......@@ -299,6 +312,7 @@ export default {
...this.page,
memberId: this.memberId,
orderType: this.orderType,
searchInfo: this.searchInfo,
});
this.memberData = [];
......@@ -477,7 +491,7 @@ p {
.left {
display: flex;
align-items: center;
gap: 32px;
gap: 40px;
}
p {
line-height: 48px;
......
......@@ -171,15 +171,28 @@
margin: 0 9px 0 13px;
background: #e4e7ed;
}
}
.extend-description {
display: flex;
padding: 20px 0 0;
transition: height 1s;
&.shrink{
height: 47px;
overflow: hidden;
box-sizing: border-box;
}
.toggleTag {
flex-shrink: 0;
width: 70px;
text-align: right;
font-size: 14px;
font-weight: 400;
color: #1890ff;
cursor: default;
}
}
.extend-description {
padding: 20px 0 0;
.empty-block{
flex: 1;
}
}
}
}
......@@ -221,27 +234,6 @@
height: 48px;
margin: 0 25px 0 0;
border-radius: 6px;
&.integral {
background: rgba(255, 203, 71, 0.15);
.icon-jifen1 {
font-size: 33px;
color: #ffcb48;
}
}
&.coupon {
background: #ecf8fe;
.icon-01_kaquanguanli {
font-size: 38px;
color: #26dad0;
}
}
&.balance {
background: #ecf8fe;
.icon-chuzhizhanghu {
font-size: 27px;
color: #5c89ff;
}
}
&.market {
background: #ecf8fe;
.icon-yingxiaojilu {
......@@ -286,28 +278,46 @@
transform: translateX(5px);
}
}
& + .assets-item {
margin-top: 20px;
}
// 资产信息
&.assets-item {
.el-icon-arrow-right {
align-self: flex-end;
}
}
// 交易记录
&.transaction-item {
& + .transaction-item {
&.line-item {
& + .line-item {
margin-top: 10px;
}
.icon-wrap {
width: 40px;
height: 40px;
margin-right: 10px;
background: #ecf8fe;
// background: #ecf8fe;
img {
height: 26px;
}
&.integral_clique {
background: #FFF5E9;
.icon-jifenjiabei {
font-size: 20px;
color: #FF9D1A;
}
}
&.integral {
background:#FFF7E3;
.icon-jifenduihuan {
font-size: 20px;
color: #ffcb48;
}
}
&.coupon {
background: #ecf8fe;
.icon-01_kaquanguanli {
font-size: 26px;
color: #26dad0;
}
}
&.balance {
background: #ecf8fe;
.icon-chuzhizhanghu {
font-size: 20px;
color: #5c89ff;
}
}
.iconfont {
color: #597ef7;
&.icon-mendianbaojiadan {
......@@ -334,6 +344,32 @@
line-height: 28px;
vertical-align: middle;
}
&.transaction-item .icon-wrap{
background: #ecf8fe;
}
}
}
.other-assets-item {
position: relative;
& + .other-assets-item {
margin-top: 20px !important;
}
.icon-wrap {
width: 48px !important;
height: 48px !important;
}
.left {
display: block !important;
}
.label {
position: absolute;
top: 0;
left: 70px;
}
.num {
position: absolute;
top: 25px;
left: 60px;
}
}
.flex-column-wrap {
......@@ -418,7 +454,7 @@
flex-direction: column;
justify-content: center;
}
}
/deep/.el-tabs__item {
height: 48px;
......
......@@ -5,11 +5,13 @@ import gradeDailog from "./components/batchgradeDialog.vue";
import mainstoreDailog from "./components/mainstoreDialog.vue";
import substoreDailog from "./components/substoreDialog.vue";
import batchList from "./components/batchList.vue";
import importDialog from "./components/importDialog.vue";
import { doFetch } from "../../components/axios/api";
import url from "../../components/axios/url";
import { mapState } from "vuex";
import { formatLongTime, paddingBorth } from "@/utils/utils";
import defaultImg from "../../../static/img/default.png";
import authMethods from "@/mixins/auth";
import {
checkFalse,
checkStatus,
......@@ -55,16 +57,17 @@ export default {
dialogGradeVisible: false,
dialogMainstoreVisible: false,
dialogSubStoreVisible: false,
dialogImportVisible: false,
selectAll: false, // 列表全选开关
batchValue: '',
batchOpt: [
// 批处理选项
{ value: "grade", label: "修改等级" },
{ value: "mainstore", label: "修改服务门店" },
{ value: "store", label: "修改协管门店" },
{ value: "batchImport", label: "批量导入" }
{ value: "integral", label: "调整积分", code: "memberBatchSetIntegral" },
{ value: "grade", label: "修改等级", code: "memberBatchSetGrade" },
{ value: "mainstore", label: "修改服务门店", code: "memberBatchSetService" },
{ value: "store", label: "修改协管门店", code: "memberBatchSetCustomer" },
{ value: "batchImport", label: "批量导入", code: "memberBatchImport" }
],
isdot: false, // 批量处理记录标记
processList: [], // 批量处理记录
defaultImg,
integralFlag: "", // 积分调整权限
memberGrade: [], // 商户等级列表
......@@ -99,6 +102,7 @@ export default {
}
};
},
mixins: [authMethods],
components: {
NavPath,
tableColumDailog,
......@@ -106,6 +110,7 @@ export default {
gradeDailog,
mainstoreDailog,
substoreDailog,
importDialog,
batchList
},
computed: {
......@@ -134,7 +139,7 @@ export default {
ajaxObj: function() {
return { ...this.pageParam, pageName: this.pageName };
},
...mapState(["storeImageUrl", "showEditClique", "showHandleScoreBtn"])
...mapState(["storeImageUrl", "showEditClique"])
},
filters: {
sexFilter: function(v) {
......@@ -307,8 +312,8 @@ export default {
age: ele.age ? ele.age : "--",
cardNo: ele.cardNo ? ele.cardNo : "--",
mainStoreName: ele.mainStoreName
? ele.mainStoreName
: "--",
? ele.mainStoreName
: "--",
thirdImgUrl: ele.thirdImgUrl
? ele.thirdImgUrl
: this.storeImageUrl
......@@ -430,12 +435,37 @@ export default {
this.$refs.multipleTable.clearSelection();
}
},
// 批量导入
openDialogImport() {
this.dialogImportVisible = true;
},
successImport(taskId) {
// this.dialogImportVisible = false;
this.$confirm(
"任务发起成功,请去【企业管理】-【任务中心】查看处理结果和执行进度",
"任务发起成功",
{
confirmButtonText: "去任务中心",
cancelButtonText: "取消",
closeOnClickModal: false,
customClass: "import-link-confirm-content",
type: "warning"
}
)
.then(() => {
window.open(`/gic-web/#/taskDetail/${taskId}`)
this.batchRefresh()
})
.catch(() => {
this.batchRefresh()
});
},
// 批量处理
handleFocusBatch(val) {
if (this.batchValue == "batchImport") {
// 批量导入
this.batchValue = "";
this.$router.push({ path: "/bulkIntegral" });
this.openDialogImport();
} else if (this.multipleList.length < 1) {
this.batchValue = "";
checkFalse("请勾选会员");
......@@ -454,7 +484,6 @@ export default {
},
batchRefresh() {
this.getAjaxMembers();
this.getProcessList();
},
getGradeList() {
doFetch(url.gradeList)
......@@ -484,29 +513,6 @@ export default {
checkStatus(err);
});
},
// 在经过批量处理之后调用
getProcessList() {
if (this.timer) clearInterval(this.timer);
doFetch(url.batchProcess)
.then(res => {
if (res.data.errorCode === 0) {
this.isdot = res.data.result.list.length > 0;
this.popWidth = this.isdot ? this.popWidth : 160;
if (!this.processList.length && !res.data.result.list.length) {
return;
}
this.processList = res.data.result.list.map(ele => ({
...ele,
name: ele.name ? ele.name : "--"
}));
} else {
checkFalse(res.data.message);
}
})
.catch(err => {
checkStatus(err);
});
},
linkDetail(memberId) {
this.$router.push({
path: "/customerDetail",
......
......@@ -9,6 +9,7 @@ import defaultImg from '../../../static/img/default.png';
import { mapState } from 'vuex';
import url from '../../components/axios/url';
import { doFetch, doFetchqs } from '../../components/axios/api';
import authMethods from '@/mixins/auth';
import {
checkFalse,
checkStatus,
......@@ -16,6 +17,7 @@ import {
} from '../../../static/js/checkStatus';
export default {
name: 'customersDetail',
mixins: [authMethods],
data () {
return {
navpath: [
......@@ -40,6 +42,8 @@ export default {
// 开卡字段、扩展字段
openField: [],
fieldList: [],
openChildrenField: [],
babyConfigTemplate:{}
},
babyStr: '', // 宝宝信息
// 标签备注
......@@ -103,8 +107,15 @@ export default {
// 资产信息
assets: [
{
label: '积分',
icon: 'icon-jifen1',
label: '集团积分',
icon: 'icon-jifenjiabei',
iconTheme: 'integral_clique',
key: 'accumulatPoints',
path: '',
},
{
label: '商户积分',
icon: 'icon-jifenduihuan',
iconTheme: 'integral',
key: 'accumulatPoints',
path: '/integralDataPage',
......@@ -253,15 +264,19 @@ export default {
const ret = res.data.result;
if (api === 'memberLoadBaseDetail') {
this.member = Object.assign({}, ret.member);
const extendInfo={
babyConfigTemplate:ret.extendInfo.babyConfigTemplate||{},
fieldList:ret.extendInfo.fieldList||[],
openChildrenField:ret.extendInfo.openChildrenField||[],
openField:ret.extendInfo.openField||[]
}
const babyArr = [];
Array.isArray(ret.extendInfo.openChildrenField) &&
ret.extendInfo.openChildrenField.forEach(el =>
babyArr.push(
el.sonFields[0].fieldValue&&el.sonFields[0].fieldName==='宝宝名称'
? el.sonFields[0].fieldValue
: el.bName,
),
);
extendInfo.openChildrenField.forEach(el => {
let item = el.sonFields.find(e => e.unifiedIdentification == 'k20301');
babyArr.push(
item && item.fieldValue ? `${el.bName}${item.fieldValue})` : el.bName,
)
});
this.extendInfo = Object.assign({}, ret.extendInfo);
this.babyStr = babyArr.join(';');
}
......
......@@ -2,6 +2,7 @@ const host = window.location.origin;
const baseUrl = host.indexOf('localhost') > -1 ? 'http://gicdev.demogic.com' : host;
const urlConfig = {
updateBabyInfo: '/api-member/update-member-baby-info',// 更新宝宝信息
cliqueGradeList: '/api-admin/clique-grade-list',
doLogin: '/api-auth/dologin', // 登录
enterprise: '/api-auth/list-login-enterprise',//企业列表
......
<template>
<div>
<el-dialog title="批量修改服务门店" custom-class="customer-dialog" :visible.sync="visible"
:close-on-click-modal="false" @close="cancel" width="600px">
<div class="checkedCustomers">
当前选中<span class="num">
{{ selectObj.selectAll?selectObj.totalCount:selectObj.multipleList.length }} </span>位客户
</div>
<el-form ref="form" :model="form" :rules="rules" label-width="133px">
<el-form-item label="服务门店:" prop="mainStoreId">
<el-select style="width: 382px" v-model="form.mainStoreId" filterable remote
reserve-keyword placeholder="请输入门店名称/门店code" :remote-method="getMainStoreCodeName"
popper-class="option-wrap" :loading="loading">
<el-option v-for="item in mainstoreList" :key="item.storeId" :label="item.storeName"
:value="item.storeId">
<p class="name">
{{ item.storeName }}
</p>
<p class="code">
{{ item.storeCode }}
</p>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="原因备注:" prop="remark">
<el-input type="text" maxlength="20" show-word-limit v-model="form.remark"
placeholder="请输入内容" style="width: 382px;" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" :loading="btnLoading" @click="submit">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { doFetch, doFetchqs } from '../../axios/api';
import url from '../../axios/url';
import { mapState } from 'vuex';
import { checkFalse, checkStatus, checkSuccess } from '../../../../static/js/checkStatus';
export default {
name: 'MainstoreDailog',
props: {
dialogVisible: {
type: Boolean,
default: false,
},
ajaxObj: {
type: Object,
default: () => {
return {
pageName: '',
};
},
},
selectObj: {
type: Object,
default: () => {
return {
totalCount: 0,
selectAll: false,
multipleList: [],
};
},
},
},
data() {
return {
visible: false,
form: {
remark: '',
optType: 1, // 1服务门店(主门店),2协管门店
mainOptType: 4, // 服务门店类型 1替换为最新协管的门店 2替换为最新协管的自营门店 3 替换为最新协管的自营/联营门店 4自定义服务门店
mainStoreId: '',
},
rules: {
mainStoreId: [
{ required: true, message: '请选择服务门店', trigger: 'change' },
],
remark: [
{ required: true, message: '请输入原因备注', trigger: 'change' },
],
},
mainstoreList: [],
loading: false,
btnLoading: false,
};
},
computed: {
...mapState([ 'showEditClique' ]),
},
watch: {
dialogVisible(n, o) {
this.visible = n;
},
},
methods: {
cancel() {
this.$refs.form.resetFields();
this.$emit('update:dialogVisible', false);
},
getMainStoreCodeName(val) {
this.loading = true;
doFetchqs(url.storeCodeName, {
searchParam: val,
flag: 1,
})
.then(res => {
if (res.data.errorCode === 0) {
this.mainstoreList = res.data.result;
} else {
checkFalse(res.data.message);
}
})
.catch(err => {
checkStatus(err);
}).finally(_ => (this.loading = false));
},
submit() {
this.$refs.form.validate(valid => {
if (valid) {
const { selectAll, multipleList } = this.selectObj;
const { memberSearchStr, pageSize, phoneNameCard, pageName } = this.ajaxObj;
this.btnLoading = true;
const memberIdsArr = [];
multipleList.forEach(item => {
memberIdsArr.push(item.memberId);
});
doFetch(url.updateStore, Object.assign({}, this.form, {
memberIds: selectAll == true ? '-1' : memberIdsArr.join(','),
isCurrent: selectAll == true ? 2 : multipleList.length == pageSize ? 1 : 0,
memberSearchParamStr: selectAll == true ? (memberSearchStr || '-1') : '',
phoneNameCard: phoneNameCard,
pageName: pageName,
}))
.then(res => {
if (res.data.errorCode === 0) {
checkSuccess();
this.$refs.form.resetFields();
this.$emit('update:dialogVisible', false);
this.$emit('successImport', res.data.result);
this.$emit('refresh');
} else {
checkFalse();
}
})
.catch(err => {
checkStatus(err);
}).finally(_ => (this.btnLoading = false));
} else {
return false;
}
});
},
},
};
</script>
<style lang="less" scoped>
.customer-dialog {
.checkedCustomers {
margin-left: 133px;
margin-bottom: 20px;
font-size: 14px;
font-weight: 400;
color: #909399;
line-height: 20px;
.num {
color: #303133;
}
}
.sub-tip {
margin: 4px 0 -5px;
font-size: 12px;
font-weight: 400;
color: #909399;
line-height: 17px;
}
}
</style>
<style lang="less">
.el-select-dropdown.option-wrap .el-select-dropdown__item {
display: flex;
flex-direction: column;
justify-content: center;
height: 57px;
}
.option-wrap {
color: #303133;
.name {
margin: 0 0 3px;
font-size: 14px;
line-height: 20px;
}
.code {
margin: 0;
font-size: 12px;
line-height: 17px;
}
}
</style>
<template>
<div>
<el-dialog title="批量修改协管门店" custom-class="customer-dialog" :visible.sync="visible"
:close-on-click-modal="false" @close="cancel" width="600px">
<div class="checkedCustomers">
当前选中<span class="num">
{{ selectObj.selectAll?selectObj.totalCount:selectObj.multipleList.length }} </span>位客户
</div>
<el-form ref="form" :model="form" :rules="rules" label-width="133px">
<el-form-item label="协管门店:" prop="fromSubStoreIds">
<el-form-item prop="subOptType" style="margin-bottom:12px;">
<el-radio-group v-model="form.subOptType">
<el-radio :label="1">
增加
</el-radio>
<el-radio :label="2">
减少
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="fromSubStoreIds">
<el-select v-model="form.fromSubStoreIds" filterable remote multiple
class="fromSubStoreIds-select" style="width:384px;" :remote-method="getSubStoreList"
placeholder="请输入请输入门店名称/门店code" popper-class="option-wrap"
v-select-loadmore="getOnlineStore"
@visible-change="(flag) => flag ? getSubStoreList() : ''">
<el-option v-for="item in subStoreList" :key="item.storeId" :label="item.storeName"
:value="item.storeId">
<p class="name">
{{ item.storeName }}
</p>
<p class="code">
{{ item.storeCode }}
</p>
</el-option>
<el-option class="loadmore-loading" v-if="loading">
<i class="loading-icon" v-loading="true" /> 加载中...
</el-option>
</el-select>
</el-form-item>
</el-form-item>
<el-form-item label="原因备注:" prop="remark">
<el-input type="text" maxlength="20" show-word-limit v-model="form.remark"
placeholder="请输入内容" style="width: 386px;" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" :loading="btnLoading" @click="submit">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { doFetch, doFetchqs } from '../../axios/api';
import url from '../../axios/url';
import { mapState } from 'vuex';
import { checkFalse, checkStatus, checkSuccess } from '../../../../static/js/checkStatus';
export default {
name: 'SubstoreDialog',
props: {
dialogVisible: {
type: Boolean,
default: false,
},
ajaxObj: {
type: Object,
default: () => {
return {
pageName: '',
};
},
},
selectObj: {
type: Object,
default: () => {
return {
totalCount: 0,
selectAll: false,
multipleList: [],
};
},
},
},
data() {
return {
visible: false,
form: {
remark: '',
optType: 2, // 1服务门店(主门店),2协管门店
subOptType: 1, // 协管门店时必填 1增加,2删除
fromSubStoreIds: [], // 批量处理协管门店时使用,存放门店id,以","分割
},
rules: {
fromSubStoreIds: [
{ required: true, message: '请选择要操作的协管门店', trigger: 'change' },
],
remark: [
{ required: true, message: '请输入原因备注', trigger: 'change' },
],
},
pageParam: {
loading: false,
searchName: '',
currentPage: 1,
pageSize: 20,
totalPage: 1,
},
subStoreList: [],
btnLoading: false,
};
},
computed: {
...mapState([ 'showEditClique' ]),
},
watch: {
dialogVisible(n, o) {
this.visible = n;
},
},
methods: {
cancel() {
this.$refs.form.resetFields();
this.$emit('update:dialogVisible', false);
},
getOnlineStore() {
const { searchName, currentPage, loading, totalPage } = this.pageParam;
if (loading || currentPage >= totalPage) return;
this.pageParam.loading = true;
doFetchqs(url.getOnlineStore, {
currentPage: currentPage + 1,
pageSize: 20,
searchName: searchName,
}).then(res => {
const { errorCode, message, result } = res.data || {};
if (errorCode == 0) {
this.subStoreList = this.subStoreList.concat(result.list || []);
this.pageParam.totalPage = result.page.totalPage || 1;
this.pageParam.currentPage = currentPage + 1;
} else {
checkFalse(message);
}
}).finally(() => (this.pageParam.loading = false));
},
getSubStoreList(query) {
this.pageParam.searchName = query;
this.pageParam.currentPage = 0;
this.subStoreList = [];
this.getOnlineStore();
},
submit() {
this.$refs.form.validate(valid => {
if (valid) {
const { selectAll, multipleList } = this.selectObj;
const { memberSearchStr, pageSize, phoneNameCard, pageName } = this.ajaxObj;
this.btnLoading = true;
const memberIdsArr = [];
multipleList.forEach(item => {
memberIdsArr.push(item.memberId);
});
doFetch(url.updateStore, Object.assign({}, this.form, {
fromSubStoreIds: this.form.fromSubStoreIds.join(','),
memberIds: selectAll == true ? '-1' : memberIdsArr.join(','),
isCurrent: selectAll == true ? 2 : multipleList.length == pageSize ? 1 : 0,
memberSearchParamStr: selectAll == true ? (memberSearchStr || '-1') : '',
phoneNameCard: phoneNameCard,
pageName: pageName,
}))
.then(res => {
if (res.data.errorCode === 0) {
checkSuccess();
this.$refs.form.resetFields();
this.$emit('update:dialogVisible', false);
this.$emit('successImport', res.data.result);
this.$emit('refresh');
} else {
checkFalse();
}
})
.catch(err => {
checkStatus(err);
}).finally(_ => (this.btnLoading = false));
} else {
return false;
}
});
},
},
};
</script>
<style lang="less" scoped>
.customer-dialog {
.checkedCustomers {
margin-left: 133px;
margin-bottom: 20px;
font-size: 14px;
font-weight: 400;
color: #909399;
line-height: 20px;
.num {
color: #303133;
}
}
.sub-tip {
margin: 4px 0 -5px;
font-size: 12px;
font-weight: 400;
color: #909399;
line-height: 17px;
}
}
</style>
<style lang="less">
// 去除dailog-footer上边框
.customer-dialog .el-dialog__footer {
padding-top: 0;
padding-bottom: 20px;
border-top: none !important;
}
.customer-dialog .el-dialog__body {
padding-bottom: 0;
}
.el-select-dropdown.option-wrap .el-select-dropdown__item {
display: flex;
flex-direction: column;
justify-content: center;
height: 57px;
}
.option-wrap {
color: #303133;
.name {
margin: 0 0 3px;
font-size: 14px;
line-height: 20px;
}
.code {
margin: 0;
font-size: 12px;
line-height: 17px;
}
}
</style>
......@@ -27,7 +27,7 @@ export default {
memberSearchStr: -1,
navpath: [
{ name: "首页", path: "" },
{ name: "会员列表", path: "/posmembers" },
{ name: "客户列表", path: "/allCustomers" },
{ name: "回收站门店会员", path: "" }
],
sceneValue: "member",
......
......@@ -40,6 +40,8 @@
></el-input-number>
<span v-show="scope.row.isEdit !== true"> {{ scope.row.rewardValue }} </span> 积分
<i
v-if="getCodeAuth('memberTaskSetAward')"
:limit-code="getCode('memberTaskSetAward')"
v-show="isEdit == 1 && scope.row.isEdit !== true"
@click="editRewardValue(scope.row)"
class="el-icon-edit pointer"
......@@ -71,6 +73,8 @@
<template slot-scope="scope">
<div class="achievement-handler">
<el-switch
v-if="getCodeAuth('memberTaskSwitch')"
:limit-code="getCode('memberTaskSwitch')"
v-model="scope.row.statusEdit"
@change="changeValue(scope.row)"
active-text="启用"
......@@ -96,6 +100,7 @@
import nav from "../../common/navbar/navbar.vue";
import { doFetch } from "../../components/axios/api";
import url from "../../components/axios/url";
import authMethods from '@/mixins/auth.js';
import {
checkFalse,
checkStatus,
......@@ -104,6 +109,7 @@ import {
import Vue from "vue";
export default {
name: "membertask",
mixins: [ authMethods ],
data() {
return {
bodyHeight:
......
......@@ -83,7 +83,6 @@
key="integral"
label="调整积分"
value="integral"
v-if="showHandleScoreBtn"
></el-option>
<el-option
key="bulkIntegral"
......
......@@ -573,7 +573,7 @@ export default {
}
// 上一次勾选的数据 对比具体是哪一项不匹配
this.midSelect = val;
}
},
}
};
</script>
......
......@@ -77,6 +77,8 @@
<router-link
to="/abnormal-member-option"
class="el-button el-button--primary"
:limit-code='getCode("memberFrozenNovelMember")'
v-if='getCodeAuth("memberFrozenNovelMember")'
>冻结会员</router-link>
</div>
</div>
......@@ -246,11 +248,15 @@
<template slot-scope="scope">
<el-button
type="text"
:limit-code='getCode("memberIntoCustomDetail")'
v-if='getCodeAuth("memberIntoCustomDetail")'
@click="linkDetail(scope.row.memberId)"
>查看</el-button>
<el-button
type="text"
@click="unFrozenItem(scope.$index, scope.row.frozenStatus)"
:limit-code='getCode("memberFrozen")'
v-if='getCodeAuth("memberFrozen")'
>{{ scope.row.frozenStatus == 2 ? '解冻' : '冻结' }}</el-button>
</template>
</el-table-column>
......@@ -288,12 +294,13 @@ import { formatLongTime } from "@/utils/utils";
import url from "@/components/axios/url";
import { mapState } from "vuex";
import { checkFalse, checkStatus } from '../../../static/js/checkStatus';
import authMethods from '@/mixins/auth';
export default {
name: "forzenlist",
components: {
NavPath
},
mixins: [authMethods],
filters: {
formatDate(val, format) {
if(!val) return '--';
......@@ -711,7 +718,7 @@ export default {
}
}
}
.basic-info-table {
.basic-img {
......
......@@ -110,8 +110,8 @@
prop="importValue"
>
<el-select v-model="formByImport.importValue" placeholder="请选择导入类型" @change="handleChangeType">
<el-option v-if="showHandleScoreBtn" label="积分增加" value="11"></el-option>
<el-option v-if="showHandleScoreBtn" label="积分扣除" value="12"></el-option>
<el-option label="积分增加" value="11"></el-option>
<el-option label="积分扣除" value="12"></el-option>
<el-option label="等级调整" value="13"></el-option>
<el-option label="服务门店调整" value="14"></el-option>
<el-option label="批量冻结会员" value="15"></el-option>
......@@ -200,7 +200,7 @@
</div>
</template>
<script>
import { doFetch, doFetchqs } from "../../components/axios/api";
import { doFetchqs } from "../../components/axios/api";
import NavPath from "@/common/navbar/navbar.vue";
import url from "../../components/axios/url";
import {
......@@ -208,7 +208,6 @@ import {
checkStatus,
checkSuccess
} from "../../../static/js/checkStatus";
import { mapState } from 'vuex';
export default {
components: {
......@@ -289,9 +288,6 @@ export default {
}
}
},
computed: {
...mapState(['showHandleScoreBtn'])
},
methods: {
handleChangeType(val) {
console.log(val);
......
......@@ -174,12 +174,14 @@
<div class="operate">
<el-button
type="text"
v-if="scope.row.status === 4"
v-if="scope.row.status === 4 && getCodeAuth('memberCardDestory')"
:limit-code='getCode("memberCardDestory")'
@click="handleCheckDestory(scope.row)"
>核销</el-button>
<el-button
type="text"
v-if="scope.row.status === 4"
v-if="scope.row.status === 4 && getCodeAuth('memberCardWriteOff')"
:limit-code='getCode("memberCardWriteOff")'
@click="handleCardDestroy(scope.row)"
>销毁</el-button>
<span
......@@ -308,6 +310,7 @@
import nav from "../../common/navbar/navbar.vue";
import { doFetch } from "../../components/axios/api";
import url from "../../components/axios/url";
import authMethods from '@/mixins/auth';
import {
checkFalse,
checkStatus,
......@@ -357,6 +360,7 @@ export default {
orderNumber: null,
};
},
mixins: [authMethods],
methods: {
formatStatus(row) {
let _content = '';
......
......@@ -53,10 +53,14 @@
<router-link
to="/frozenList/frozenMember"
class="inner-btn-link"
:limit-code='getCode("memberFrozenMember")'
v-if='getCodeAuth("memberFrozenMember")'
>冻结会员</router-link>
<el-button
type="primary"
@click="unFrozen"
:limit-code='getCode("memberBatchCleanFrozen")'
v-if='getCodeAuth("memberBatchCleanFrozen")'
>批量解冻</el-button>
</div>
</div>
......@@ -209,6 +213,8 @@
<el-button
type="text"
@click="unFrozenItem(scope.$index)"
:limit-code='getCode("memberBatchCleanFrozen")'
v-if='getCodeAuth("memberBatchCleanFrozen")'
>解冻</el-button>
</template>
</el-table-column>
......@@ -246,12 +252,13 @@ import { formatLongTime } from "@/utils/utils";
import url from "@/components/axios/url";
import { mapState } from "vuex";
import { checkFalse, checkStatus } from '../../../static/js/checkStatus';
import authMethods from '@/mixins/auth';
export default {
name: "forzenlist",
components: {
NavPath
},
mixins: [authMethods],
filters: {
formatTimeYMD(val) {
return val != "--" ? val.split(" ")[0] : "--";
......@@ -489,7 +496,7 @@ export default {
status: options.frozenType, // 1 冻结 0 解冻
phoneNameCard: this.keywords // 会员名称 手机号
};
doFetch("/api-member/members-batch-update-frozen", datas).then(res => {
doFetch("/api-member/members-batch-update-frozen", datas).then(async res => {
if (res.data.errorCode === 0) {
this.$message({
message: "解冻成功",
......@@ -499,6 +506,7 @@ export default {
pSize: 20,
cPage: 1
});
this.handleToTaskCenter(res.data.result);
}
});
},
......@@ -517,6 +525,15 @@ export default {
});
});
},
async handleToTaskCenter(id) {
await this.$confirm(`请去【企业管理】-【任务中心】查看处理结果和执行进度`, `任务发起成功`, {
type: 'success',
confirmButtonText: '去任务中心',
cancelButtonText: '取消',
showClose: false
})
window.open(`/gic-web/#/taskDetail/${id}`);
},
submit() {
this.getList({
pSize: 20,
......
......@@ -476,6 +476,15 @@ export default {
this.frozenMethod();
});
},
async handleToTaskCenter(id) {
await this.$confirm(`请去【企业管理】-【任务中心】查看处理结果和执行进度`, `任务发起成功`, {
type: 'success',
confirmButtonText: '去任务中心',
cancelButtonText: '取消',
showClose: false
})
window.open(`/gic-web/#/taskDetail/${id}`);
},
changeReason(val) {
if (val) {
this.reasonbtn = false;
......@@ -501,6 +510,7 @@ export default {
this.remark = "";
this.middleList.length = 0;
this.loading = true;
this.handleToTaskCenter(res.data.result);
setTimeout(() => {
this.loading = false;
this.$message({
......
......@@ -54,8 +54,9 @@
</el-select>
</div>
<el-button
v-if="showHandleScoreBtn"
v-if="getCodeAuth('memberAdjustIntegral')"
type="primary"
:limit-code="getCode('memberAdjustIntegral')"
@click="linkRoute('/modifyintegral')"
>调整积分</el-button>
</div>
......@@ -224,8 +225,7 @@ import {
} from "../../../static/js/checkStatus";
import searchinput from "common/searchinput";
import { formatLongTime } from "@/utils/utils";
import { mapState } from 'vuex';
import authMethods from '@/mixins/auth';
export default {
name: "talkLogPage",
data() {
......@@ -271,9 +271,7 @@ export default {
integralFlag: ""
};
},
computed: {
...mapState(['showHandleScoreBtn'])
},
mixins: [authMethods],
methods: {
linkRoute(route) {
this.$router.push({ path: route, query: { memberId: this.memberId } });
......
......@@ -20,14 +20,13 @@ import directive from './utils/directive.js';
// import vueGicAsideMenu from '@gic-test/vue-gic-aside-menu'
// import vueGicUploadImage from '@gic-test/vue-gic-upload-image'
// import vueGicFooter from '@gic-test/vue-gic-footer'
import authCode from '../config/authCode';
import * as custom from './common/filters/custom'
Vue.config.productionTip = false;
Vue.config.devtools = true;
axios.defaults.withCredentials = true;
Vue.prototype.axios = axios;
Vue.component('icon-svg', IconSvg)
Vue.component('gic-textarea', gictextarea);
Vue.component('gic-input', gicinput);
......@@ -80,11 +79,13 @@ Object.keys(directive).forEach(key => {
Vue.directive(key, directive[key]);
})
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
});
window.getLimit(router, 'member').then(() => {
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
});
})
export default {
computed: {
getCodeAuth() {
return code => this.$getButtonLimit(this.getCode(code));
},
getCode() {
return code => this.$buttonCode[code];
}
}
};
......@@ -16,7 +16,7 @@ export default new Vuex.Store({
uniqueId: '',
isAdmin: false,
layoutTips: '',
showHandleScoreBtn: true, // 是否显示积分相关的操作按钮 true:显示 false:不显示
// showHandleScoreBtn: true, // 是否显示积分相关的操作按钮 true:显示 false:不显示 【废弃】
},
mutations: {
[types.TITLE]: (state, data) => {
......@@ -47,9 +47,10 @@ export default new Vuex.Store({
['setEditClique'](state, val) {
state.showEditClique = val;
},
showHandleScoreBtn(state, data) {
state.showHandleScoreBtn = data;
}
// 废弃 巴拉定制需求 子账号不显示积分相关
// showHandleScoreBtn(state, data) {
// state.showHandleScoreBtn = data;
// }
},
actions: {
getStorePicture({ commit }) {
......
......@@ -55,6 +55,48 @@
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe696;</span>
<div class="name">积分加倍</div>
<div class="code-name">&amp;#xe696;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe697;</span>
<div class="name">积分兑换</div>
<div class="code-name">&amp;#xe697;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe695;</span>
<div class="name">详情</div>
<div class="code-name">&amp;#xe695;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe694;</span>
<div class="name">企微</div>
<div class="code-name">&amp;#xe694;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe673;</span>
<div class="name">外部</div>
<div class="code-name">&amp;#xe673;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe672;</span>
<div class="name">search</div>
<div class="code-name">&amp;#xe672;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe693;</span>
<div class="name">QuestionCircleOutlined</div>
<div class="code-name">&amp;#xe693;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe68f;</span>
<div class="name">通话记录</div>
<div class="code-name">&amp;#xe68f;</div>
......@@ -217,18 +259,6 @@
</li>
<li class="dib">
<span class="icon iconfont">&#xe672;</span>
<div class="name">SwapOutlined</div>
<div class="code-name">&amp;#xe672;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe673;</span>
<div class="name">BellOutlined</div>
<div class="code-name">&amp;#xe673;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe892;</span>
<div class="name">查看详情</div>
<div class="code-name">&amp;#xe892;</div>
......@@ -1758,9 +1788,9 @@
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1638173401408') format('woff2'),
url('iconfont.woff?t=1638173401408') format('woff'),
url('iconfont.ttf?t=1638173401408') format('truetype');
src: url('iconfont.woff2?t=1639982128381') format('woff2'),
url('iconfont.woff?t=1639982128381') format('woff'),
url('iconfont.ttf?t=1639982128381') format('truetype');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
......@@ -1787,6 +1817,69 @@
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-jifenjiabei"></span>
<div class="name">
积分加倍
</div>
<div class="code-name">.icon-jifenjiabei
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-jifenduihuan"></span>
<div class="name">
积分兑换
</div>
<div class="code-name">.icon-jifenduihuan
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xiangqing1"></span>
<div class="name">
详情
</div>
<div class="code-name">.icon-xiangqing1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-qiwei"></span>
<div class="name">
企微
</div>
<div class="code-name">.icon-qiwei
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-waibu"></span>
<div class="name">
外部
</div>
<div class="code-name">.icon-waibu
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-search"></span>
<div class="name">
search
</div>
<div class="code-name">.icon-search
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-QuestionCircleOutlined"></span>
<div class="name">
QuestionCircleOutlined
</div>
<div class="code-name">.icon-QuestionCircleOutlined
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-tonghuajilu1"></span>
<div class="name">
通话记录
......@@ -2030,24 +2123,6 @@
</li>
<li class="dib">
<span class="icon iconfont icon-SwapOutlined"></span>
<div class="name">
SwapOutlined
</div>
<div class="code-name">.icon-SwapOutlined
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-BellOutlined"></span>
<div class="name">
BellOutlined
</div>
<div class="code-name">.icon-BellOutlined
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-chakanxiangqing"></span>
<div class="name">
查看详情
......@@ -4344,6 +4419,62 @@
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-jifenjiabei"></use>
</svg>
<div class="name">积分加倍</div>
<div class="code-name">#icon-jifenjiabei</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-jifenduihuan"></use>
</svg>
<div class="name">积分兑换</div>
<div class="code-name">#icon-jifenduihuan</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xiangqing1"></use>
</svg>
<div class="name">详情</div>
<div class="code-name">#icon-xiangqing1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-qiwei"></use>
</svg>
<div class="name">企微</div>
<div class="code-name">#icon-qiwei</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-waibu"></use>
</svg>
<div class="name">外部</div>
<div class="code-name">#icon-waibu</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-search"></use>
</svg>
<div class="name">search</div>
<div class="code-name">#icon-search</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-QuestionCircleOutlined"></use>
</svg>
<div class="name">QuestionCircleOutlined</div>
<div class="code-name">#icon-QuestionCircleOutlined</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-tonghuajilu1"></use>
</svg>
<div class="name">通话记录</div>
......@@ -4560,22 +4691,6 @@
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-SwapOutlined"></use>
</svg>
<div class="name">SwapOutlined</div>
<div class="code-name">#icon-SwapOutlined</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-BellOutlined"></use>
</svg>
<div class="name">BellOutlined</div>
<div class="code-name">#icon-BellOutlined</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-chakanxiangqing"></use>
</svg>
<div class="name">查看详情</div>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -6,6 +6,55 @@
"description": "",
"glyphs": [
{
"icon_id": "20657659",
"name": "积分加倍",
"font_class": "jifenjiabei",
"unicode": "e696",
"unicode_decimal": 59030
},
{
"icon_id": "20657666",
"name": "积分兑换",
"font_class": "jifenduihuan",
"unicode": "e697",
"unicode_decimal": 59031
},
{
"icon_id": "966293",
"name": "详情",
"font_class": "xiangqing1",
"unicode": "e695",
"unicode_decimal": 59029
},
{
"icon_id": "26390250",
"name": "企微",
"font_class": "qiwei",
"unicode": "e694",
"unicode_decimal": 59028
},
{
"icon_id": "26389942",
"name": "外部",
"font_class": "waibu",
"unicode": "e673",
"unicode_decimal": 58995
},
{
"icon_id": "462796",
"name": "search",
"font_class": "search",
"unicode": "e672",
"unicode_decimal": 58994
},
{
"icon_id": "20893446",
"name": "QuestionCircleOutlined",
"font_class": "QuestionCircleOutlined",
"unicode": "e693",
"unicode_decimal": 59027
},
{
"icon_id": "25982878",
"name": "通话记录",
"font_class": "tonghuajilu1",
......@@ -195,20 +244,6 @@
"unicode_decimal": 58999
},
{
"icon_id": "20893458",
"name": "SwapOutlined",
"font_class": "SwapOutlined",
"unicode": "e672",
"unicode_decimal": 58994
},
{
"icon_id": "22596519",
"name": "BellOutlined",
"font_class": "BellOutlined",
"unicode": "e673",
"unicode_decimal": 58995
},
{
"icon_id": "9002691",
"name": "查看详情",
"font_class": "chakanxiangqing",
......
No preview for this file type
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