Commit e04dd1fa by chenxin

fix: save

parents 2f57c8cb 3fb01a54
{
"name": "marketing1",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "",
"private": true,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"build": "node build/build.js",
"format": "onchange 'test/**/*.js' 'src/**/*.js' 'src/**/*.vue' -- prettier --write {{changed}}"
},
"dependencies": {
"@antv/data-set": "^0.8.9",
"@antv/g2": "^3.5.17",
"@riophae/vue-treeselect": "^0.0.36",
"@tinymce/tinymce-vue": "^1.0.8",
"animate.css": "^3.7.2",
"animated-vue": "^0.5.3",
"axios": "^0.18.0",
"echarts": "^4.8.0",
"element-ui": "^2.13.2",
"packele": "^1.0.5",
"scriptjs": "^2.5.8",
"tinymce": "^4.9.11",
"uuid": "^3.3.2",
"v-charts": "^1.17.8",
"viser-vue": "^2.2.5",
"vue-axios": "^2.1.1",
"vue-qr": "^1.3.8",
"vue-router": "^3.3.4",
"vue-ueditor-wrap": "^1.3.4",
"vue2-editor": "^2.5.0",
"vuedraggable": "^2.24.0",
"vuex": "^3.5.1"
},
"devDependencies": {
"ansi-html": "^0.0.7",
"autoprefixer": "^7.1.2",
"babel-cli": "^6.26.0",
"babel-core": "^6.22.1",
"babel-eslint": "^9.0.0",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.3.2",
"babel-preset-flow": "^6.23.0",
"babel-preset-stage-2": "^6.22.0",
"chalk": "^2.0.1",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.28.0",
"element-theme-chalk": "^2.13.2",
"eslint": "^5.6.0",
"eslint-config-prettier": "^4.0.0",
"eslint-config-standard": "^12.0.0",
"eslint-friendly-formatter": "^4.0.1",
"eslint-loader": "^2.1.1",
"eslint-plugin-html": "^5.0.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-node": "^7.0.1",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-promise": "^4.0.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^4.7.1",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"localforage": "^1.8.0",
"node-notifier": "^5.1.2",
"node-sass": "^4.14.1",
"onchange": "^5.2.0",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.27",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"prettier": "^1.16.4",
"rimraf": "^2.6.0",
"sass-loader": "^7.0.3",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
"vue-lazyload": "^1.2.6",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^2.11.3",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
<template>
<el-dialog title="卡券销毁" :visible.sync="show" width="600px" :before-close="close">
<div v-loading="loading">
<div class="dm-title__label--tips" style="padding-bottom: 10px;"><i class="el-icon-warning pr8 warning-color"></i>卡券销毁将不可撤回,请注意确认操作。</div>
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="120px" class="pt20">
<el-form-item label="选择卡券" prop="cardId">
<el-button v-show="!ruleForm.cardId" @click="showCardDialog = true">选择卡券</el-button>
<div v-show="ruleForm.cardId">
{{ ruleForm.cardName }}
<el-button v-if="type === 'add'" type="text" @click="cleanCard" class="ml10">删除</el-button>
</div>
</el-form-item>
<el-form-item label="销毁方式" prop="destoryMode">
<el-radio-group :disabled="type !== 'add'" v-model="ruleForm.destoryMode">
<el-radio :label="0">全部销毁</el-radio>
<el-radio :label="1">部分销毁</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="type === 'add'" label="导入券码文件" prop="fileId">
<div>
<!-- eslint-disable-nextline -->
<div v-if="ruleForm.fileId" class="inline-block">已导入</div>
<file v-if="!ruleForm.fileId" :noUse="!ruleForm.destoryMode" needExtraParams :paramsObj="{ destoryPlanId: ruleForm.destoryPlanId }" ref="fileUpload" class="dash-btn inline-block" label="点击上传" @backImg="backImg" acceptType=".csv" tips="" :url="uploadUrl" width="50" iconClass="el-icon-upload2" /><!-- 上传 -->
<el-button type="text" class="ml10" @click="download">点击下载文件模板</el-button>
</div>
<p style="margin-top:8px;color:#909399;font-size:12px;line-height:1;">券码数量单次最多不超过5000条</p>
<p style="margin-top:8px;color:#909399;font-size:12px;line-height:1;">填写示例:‘123456(英文单引号'+券码编号文本形式)</p>
</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="close">关闭</el-button>
<el-button v-if="type === 'add'" type="primary" @click="submit">确认销毁</el-button>
</span>
<!-- 只有卡券销毁处传这个参数 -->
<vue-gic-card getCardListUrl="/api-marketing/list-coupon-destroy" appendToBody :showCardDialog="showCardDialog" @selectCard="selectCard" :cardLimit="-1" :cardType="null"></vue-gic-card>
</el-dialog>
</template>
<script>
import { _debounce } from '@/utils/index';
import file from '@/components/upload/file';
import { getCoupDestoryDetail, importDestoryCoupCode, saveCoupDestoryPlan, downloadDestroyCodeTemplate } from '@/service/api/cardApi.js';
export default {
name: 'destory-dialog',
props: {
show: {
type: Boolean,
default: false
},
type: {
type: String,
default: 'add' // add edit
},
destoryItem: {
type: Object,
default: () => {}
}
},
data() {
// 部分销毁必传
const checkFileId = (rule, value, callback) => {
if (this.ruleForm.destoryMode && !value) {
return callback(new Error(rule.message));
}
callback();
};
return {
loading: false,
uploadUrl: importDestoryCoupCode,
showCardDialog: false,
ruleForm: {
destoryPlanId: '',
cardId: '',
cardName: '',
destoryMode: 0,
fileId: ''
},
rules: {
cardId: [{ required: true, message: '请选择卡券', trigger: 'change' }],
destoryMode: [{ required: true, message: '请选择销毁方式', trigger: 'change' }],
fileId: [{ validator: checkFileId, message: '请上传文件', trigger: 'change' }]
}
};
},
watch: {
show(val) {
if (val) {
if (this.type === 'add') {
this.loading = true;
getCoupDestoryDetail({})
.then(res => {
this.loading = false;
this.ruleForm.destoryPlanId = res.result;
})
.catch(() => {
this.loading = false;
});
} else {
this.ruleForm = { ...this.destoryItem };
}
}
}
},
components: {
file
},
methods: {
download() {
window.location = downloadDestroyCodeTemplate;
},
close() {
this.$refs.ruleForm.resetFields();
this.$emit('update:show', false);
},
submit: _debounce(function() {
if (this.loading) {
return;
}
this.$refs.ruleForm.validate(valid => {
if (!valid) {
return;
}
this.loading = true;
let params = { ...this.ruleForm };
delete params.fileId;
saveCoupDestoryPlan(params)
.then(res => {
this.loading = false;
this.$message({ message: '操作成功', type: 'success' });
this.close();
this.$emit('refresh');
})
.catch(() => {
this.loading = false;
});
});
}),
cleanCard() {
this.ruleForm.cardId = '';
this.ruleForm.cardName = '';
this.$refs.ruleForm.validateField('cardId');
},
//选择卡券后置
selectCard(val) {
if (val) {
this.ruleForm.cardId = val.coupCardId;
this.ruleForm.cardName = val.cardName;
this.$refs.ruleForm.validateField('cardId');
}
this.showCardDialog = false;
},
// ****上传图片***
upload() {
this.$refs.fileUpload.$el.querySelector('input').click();
},
backImg(res) {
this.ruleForm.fileId = new Date().getTime(); // 代表以及上传过文件
}
}
};
</script>
<style lang="scss" scoped>
/deep/ .dash-btn .el-button {
width: 174px;
border-style: dashed;
border-radius: 4px;
&:not(.is-disabled) {
background: white;
color: #606266;
border-color: #c0c4cc;
}
&.is-disabled {
color: #c0c4cc;
}
}
.dm-title__label--tips {
background: #fffbe6;
border-color: #ffe58f;
}
</style>
<template>
<section class="dm-wrap" v-loading="loading">
<div class="pb22 clearfix">
<el-select class="dm-select" clearable="" v-model="listParams.effectType" placeholder="选择时效" @change="search">
<el-option v-for="(v, i) in effectTypeOption" :key="i" :label="v.label" :value="v.value"></el-option>
</el-select>
<el-select class="dm-select" clearable v-model="listParams.marketingType" placeholder="选择营销方式" @change="search">
<el-option v-for="(v, i) in marketingTypeOptions" :key="i" :label="v.label" :value="v.value"></el-option>
</el-select>
<activity-select class="vertical-middle w150 mr5" :actId.sync="listParams.marketingActivityId" onlySelect @actUpdate="search"></activity-select>
<el-select class="dm-select" clearable v-model="listParams.onlineStatus" placeholder="选择上线状态" @change="search">
<el-option v-for="(v, i) in onlineOptions" :key="i" :label="v.label" :value="v.value"></el-option>
</el-select>
<el-input v-model="listParams.searchName" class="w200" placeholder="输入计划名称" clearable @change="search"><i slot="prefix" class="el-input__icon el-icon-search"></i></el-input>
<el-checkbox class="vertical-middle" v-if="$store.state.marketing.isShowSelf" v-model="listParams.showSelfFlag" :true-label="1" :false-label="0" label="仅看本人" border @change="search" />
<el-button class="fr" type="primary" @click="$router.push('/ecm/add')">新建计划</el-button>
</div>
<el-table tooltipEffect="light" :data="tableList" style="width: 100%" element-loading-text="拼命加载中">
<el-table-column v-for="(v, i) in tableHeader" :fixed="v.fixed" :show-overflow-tooltip="v.tooltip" :width="v.width" :min-width="v.minWidth" :align="v.align" :key="i" :prop="v.prop" :label="v.label" :formatter="v.formatter">
<template slot-scope="scope">
<span v-if="v.formatter" v-html="v.formatter(scope.row)"></span>
<span v-else>{{ scope.row[v.prop] }}</span>
</template>
</el-table-column>
<el-table-column min-width="100" align="left" prop="creatorName" label="创建人" v-if="$store.state.marketing.openFlag"></el-table-column>
<el-table-column label="操作" align="left" width="220" fixed="right">
<template slot-scope="scope">
<template v-if="scope.row.canEdit !== false">
<el-button type="text" v-if="scope.row.effectType == 0 || scope.row.effectType == 1" @click="editData(scope.row)">编辑</el-button>
<el-button type="text" v-if="scope.row.effectType == 2" @click="$router.push(`/ecm/info/${scope.row.ecmPlanId}`)">详情</el-button>
</template>
<dm-delete v-if="scope.row.effectType !== 2 && scope.row.onlineStatus === 1 && scope.row.canEdit !== false" @confirm="offlineEcmPlan(scope.row)" tips="是否下线该计划?">
<el-button type="text">下线</el-button>
</dm-delete>
<dm-delete v-if="scope.row.putonStatus !== 2 && scope.row.canEdit !== false" @confirm="delData(scope.row)" tips="是否删除该计划?">
<el-button type="text">删除</el-button>
</dm-delete>
<el-button type="text" @click="toRecord(scope.row)">记录</el-button>
</template>
</el-table-column>
</el-table>
<dm-pagination v-show="tableList.length" background class="dm-pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listParams.currentPage" :page-sizes="[20, 40, 60, 80]" :page-size="listParams.pageSize" layout="total, sizes, prev, pager, next" :total="total"></dm-pagination>
</section>
</template>
<script>
import activitySelect from '@/components/activity-select';
import { loadEcmList, deleteEcm, offlineEcmPlan } from '@/service/api/ecmApi.js';
const marketingTypeOptions = [{ value: '', label: '所有发送类型' }, { value: 'card', label: '卡券营销' }, { value: 'message', label: '短信营销' }, { value: 'teletext', label: '图文营销' }, { value: 'text', label: '文本营销' }, { value: 'teltask', label: '话务' }, { value: 'image', label: '微信图片' }]; // eslint-disable-line
export default {
name: 'ecm',
data() {
return {
effectTypeOption: [{ value: '', label: '所有时效' }, { value: 0, label: '实时' }, { value: 1, label: '定时' }, { value: 2, label: '立即发送' }], // eslint-disable-line
onlineOptions: [{ value: '', label: '所有上线状态' }, { value: 0, label: '待上线' }, { value: 1, label: '已上线' }, { value: 2, label: '已下线' }], // eslint-disable-line
marketingTypeOptions,
listParams: {
effectType: '', // 全部失效的默认值是-1,提交时判断''改为-1
marketingType: '',
marketingActivityId: '',
onlineStatus: '',
searchName: '',
currentPage: 1,
pageSize: 20,
showSelfFlag: ''
},
total: 0,
loading: false,
tableHeader: [
{ label: '计划名称', prop: 'ecmPlanName', minWidth: '160', align: 'left', fixed: 'left' },
{
label: '时效',
prop: 'effectType',
width: '160',
align: 'left',
formatter(row) {
if (row.effectType == 0) {
return '实时';
} else if (row.effectType == 1) {
return `<span><i class="el-icon-time fz18 vertical-middle"></i><span class="vertical-middle"> 每天${row.effectTime}:00</span></span>`;
} else if (row.effectType == 2) {
return '立即执行';
}
}
},
{ label: '营销方式', prop: 'marketingType', minWidth: '160', align: 'left' },
{
label: '营销活动',
prop: 'marketingActivityName',
width: '160',
align: 'left',
formatter(row) {
return row.marketingActivityName || '--';
}
},
{ label: '营销人次', prop: 'timesForPeople', width: '160', align: 'left' },
{
label: '上线状态',
prop: 'onlineStatus',
width: '160',
align: 'left',
formatter(row) {
let result = '--';
switch (row.onlineStatus) {
case 0:
result = '<span class="dm-status--primary">待上线</span>';
break;
case 1:
result = '<span class="dm-status--success">已上线</span>';
break;
case 2:
result = '<span class="dm-status--info">已下线</span>';
break;
}
return result;
}
}
],
tableList: []
};
},
components: {
activitySelect
},
created() {
this.loadEcmList();
this.$store.commit('aside_handler', false);
this.$store.commit('mutations_breadcrumb', [{ name: '营销管理', path: '' }, { name: '智能营销', path: '/ecm' }]); // eslint-disable-line
},
methods: {
search() {
this.listParams.currentPage = 1;
this.loadEcmList();
},
handleSizeChange(val) {
this.listParams.pageSize = val;
this.loadEcmList();
},
handleCurrentChange(val) {
this.listParams.currentPage = val;
this.loadEcmList();
},
async loadEcmList() {
this.loading = true;
const params = { ...this.listParams };
if (params.effectType === '') {
params.effectType = -1; // 全部时效的默认值是-1
}
let res = await loadEcmList(params);
console.log(res);
this.tableList = res.result.result || [];
this.total = res.result.totalCount;
this.loading = false;
},
//编辑
editData(row) {
this.$router.push('/ecm/edit/' + row.ecmPlanId);
},
// 记录
toRecord(row) {
const prefix = row.effectType == 1 ? 'batchlist' : row.effectType == 2 ? 'oncelist' : 'currentlist';
this.$router.push({ path: `/ecm/${prefix}/${row.ecmPlanId}`, query: { name: row.ecmPlanName } });
},
// 删除
async delData(row) {
try {
let res = await deleteEcm({ ecmPlanId: row.ecmPlanId });
if (res.errorCode === 0) {
this.$tips({ type: 'success', message: '删除成功!' });
if (this.tableList.length === 1 && this.listParams.currentPage !== 1) {
this.listParams.currentPage--;
}
this.loadEcmList();
} else {
this.$tips({ type: 'error', message: res.message || '删除失败!' });
}
} catch (err) {
this.$tips({ type: 'error', message: '删除失败!' });
}
},
// 下线
async offlineEcmPlan(row) {
try {
let res = await offlineEcmPlan({ ecmPlanId: row.ecmPlanId });
if (res.errorCode === 0) {
this.$tips({ type: 'success', message: '下线成功!' });
this.loadEcmList();
} else {
this.$tips({ type: 'error', message: res.message || '下线失败!' });
}
} catch (err) {
this.$tips({ type: 'error', message: '下线失败!' });
}
}
}
};
</script>
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