You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

729 lines
23 KiB

<template>
<div class="article-manager">
<Card
:bordered="false"
dis-hover
class="ivu-mt"
>
<PageHeader
style="padding: 10px 0; margin-bottom: 20px;"
hidden-breadcrumb
>
<div slot="title">
<router-link :to="{ path: '/store/article/index' }"><Button
icon="ios-arrow-back"
size="small"
class="mr20"
>返回</Button></router-link>
<span
v-text="$route.params.id > 0 ? '编辑文章' : '添加文章'"
class="mr20"
></span>
</div>
</PageHeader>
<Form
class="form"
ref="formValidate"
:model="formValidate"
:rules="ruleValidate"
:label-width="labelWidth"
:label-position="labelPosition"
@submit.native.prevent
>
<div class="goodsTitle acea-row">
<div class="title">文章信息</div>
</div>
<Row
>
<Col
span='24'
v-bind="grid"
class="mr50"
>
<FormItem
label="标题:"
prop="title"
label-for="title"
>
<Input
v-model="formValidate.title"
placeholder="请输入"
maxlength="20"
element-id="title"
style="width:400px"
/>
</FormItem>
</Col>
</Row>
<Row>
<Col v-bind="grid" class="mr50">
<FormItem label="文章分类:" label-for="cid" prop="cid">
<Select v-model="formValidate.cid" style="width:400px" >
<Option v-for="item in treeData" :value="item.id" :key="item.id">{{ item.title }}</Option>
</Select>
</FormItem>
</Col>
</Row>
<Row >
<Col class="mr50">
<FormItem label="关联内容:">
<Row :class="{'mb10':!(formValidate.relate.length==index+1)}" v-for="(item,index) in formValidate.relate" :key="index">
<Select
@on-change="selectType"
placeholder="请选择关联类型"
v-model="formValidate.relate[index].type"
style="width:150px;margin-right: 10px;" >
<Option :value="1">首发活动</Option>
<Option :value="2">合成活动</Option>
<Option :value="3">流转市场(藏品)</Option>
<Option :value="4">流转市场(盲盒)</Option>
</Select>
<template v-if="formValidate.relate[index].type==1">
<Select ref="select_1" filterable @on-select="itemSelect($event,index)" :disabled='!formValidate.relate[index].type' placeholder="请搜索或选择关联的活动" v-model.lazy="formValidate.relate[index].active_id" style="width:240px" >
<Option v-for="item in activeList" :value="item.id" :key="item.id" :label="item.title">{{`${item.title}(${item.active_type==4? '秒杀活动':item.active_type==2? '盲拍活动':'抽签活动' })`}}</Option>
</Select>
</template>
<template v-else-if="formValidate.relate[index].type==2">
<Select filterable @on-select="itemSelect($event,index)" :disabled='!formValidate.relate[index].type' placeholder="请搜索或选择关联的活动" v-model.lazy="formValidate.relate[index].merge_id" style="width:240px" >
<Option v-for="item in mergeList" :value="item.id" :key="item.id">{{ item.title }}</Option>
</Select>
</template>
<template v-else-if="formValidate.relate[index].type==3">
<Select filterable @on-select="itemSelect($event,index)" :disabled='!formValidate.relate[index].type' placeholder="请搜索或选择关联的活动" v-model="formValidate.relate[index].goods_id" style="width:240px" >
<Option v-for="item in goodsList" :value="item.id" :key="item.id">{{ item.title }}</Option>
</Select>
</template>
<template v-else-if="formValidate.relate[index].type==4">
<Select filterable @on-select="itemSelect($event,index)" :disabled='!formValidate.relate[index].type' placeholder="请搜索或选择关联的活动" v-model.lazy="formValidate.relate[index].box_id" style="width:240px" >
<Option v-for="item in boxList" :value="item.id" :key="item.id">{{ item.title }}</Option>
</Select>
</template>
<template v-else>
<Select :disabled='!formValidate.relate[index].type' placeholder="请搜索或选择关联的活动" v-model="formValidate.relate[index].goods_id" style="width:240px" >
<Option v-for="item in goodsList" :value="item.id" :key="item.id">{{ item.title }}</Option>
</Select>
</template>
<a @click="RelateFn('del',index)" v-if="formValidate.relate.length>1" style="color: red; margin-left: 8px;">删除</a>
<a @click="RelateFn('add',index)" v-if="formValidate.relate.length==index+1" style="margin-left: 8px;">添加</a>
<a @click="RelateFn('clear',index)" v-if="index==0" style="margin-left: 8px;">清空</a>
</Row>
</FormItem>
</Col>
</Row>
<Row >
<Col class="mr50">
<FormItem label="推送时间:">
<RadioGroup v-model="formValidate.send_type">
<Radio :label="1">立即推送</Radio>
<Radio :label="2">定时推送</Radio>
</RadioGroup>
<DatePicker
v-model="formValidate.send_time"
v-if="formValidate.send_type==2"
type="datetime"
format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择推送时间"
style="width: 200px;margin-left: 15px;" />
</FormItem>
</Col>
</Row>
<Row >
<Col class="mr50">
<FormItem label="微信通知:">
<RadioGroup v-model="formValidate.open_wechat_msg">
<Radio :label="1">开</Radio>
<Radio :label="0"></Radio>
</RadioGroup>
</FormItem>
</Col>
</Row>
<Row >
<FormItem label="状态:" >
<Switch
:true-value="1"
:false-value="0"
v-model="formValidate.status"
size="large"
>
<template #open>
<span>上架</span>
</template>
<template #close>
<span>下架</span>
</template>
</Switch>
</FormItem>
</Row>
<Col
v-bind="grid"
class="mr50"
>
<FormItem
label="图文封面:"
>
<div
class="picBox"
@click="modalPicTap('单选')"
>
<div
class="pictrue"
v-if="formValidate.image_input"
><img :src="formValidate.image_input"></div>
<div
class="upLoad acea-row row-center-wrapper"
v-else
>
<Icon
type="ios-camera-outline"
size="26"
class="iconfont"
/>
</div>
</div>
</FormItem>
</Col>
<Row>
<Col
span="12"
class="mr50"
>
<FormItem
label="文章简介:"
prop="synopsis"
label-for="synopsis"
>
<Input
v-model="formValidate.synopsis"
type="textarea"
placeholder="请输入简介..."
style="width: 90%"
:rows="5"
/>
</FormItem>
</Col>
</Row>
<div class="goodsTitle acea-row">
<div class="title">文章内容</div>
</div>
<FormItem
label="文章内容:"
prop="content"
>
<vue-ueditor-wrap
v-model="formValidate.content"
@beforeInit="addCustomDialog"
:config="myConfig"
style="width: 90%;"
></vue-ueditor-wrap>
</FormItem>
<Row
span='24'
style="justify-content: center;"
>
<Button
type="primary"
class="submission"
@click="onsubmit('formValidate')"
>提交</Button>
</Row>
</Form>
<Modal
v-model="modalPic"
width="950px"
scrollable
footer-hide
closable
title='上传商品图'
:mask-closable="false"
:z-index="1"
>
<uploadPictures
:isChoice="isChoice"
@getPic="getPic"
:gridBtn="gridBtn"
:gridPic="gridPic"
v-if="modalPic"
></uploadPictures>
</Modal>
<Spin fix v-show="spin"></Spin>
</Card>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
import uploadPictures from '@/components/uploadPictures';
import VueUeditorWrap from 'vue-ueditor-wrap';
import { cmsAddApi, createApi, categoryListApi } from '@/api/cms';
import {getList} from '@/api/merge'
import {getGoodsActiveList,getGoodsList} from '@/api/duandian/digitalStorage'
import {getBoxList} from "@/api/duandian/sell";
export default {
name: 'addArticle',
components: { uploadPictures, VueUeditorWrap },
data () {
const validateUpload = (rule, value, callback) => {
if (this.formValidate.image_input) {
callback()
} else {
callback(new Error('请上传图文封面'))
}
}
const validateUpload2 = (rule, value, callback) => {
if (!this.formValidate.cid) {
callback(new Error('请选择文章分类'))
} else {
callback()
}
}
return {
spin:false,
activeList:[],//首发活动列表
mergeList:[],//合成活动列表
goodsList:[],//流转市场藏品列表
boxList:[],//流转市场盲盒列表
dialog: {},
isChoice: '单选',
grid: {
xl: 8,
lg: 8,
md: 12,
sm: 24,
xs: 24
},
gridPic: {
xl: 6,
lg: 8,
md: 12,
sm: 12,
xs: 12
},
gridBtn: {
xl: 4,
lg: 8,
md: 8,
sm: 8,
xs: 8
},
loading: false,
formValidate: {
id: 0,
title: '',
author: '',
image_input: '',
content: '',
synopsis: '',
url: '',
is_hot: 0,
is_banner: 0,
cid: '',
visit: 0,
status:1,
open_wechat_msg:1,
send_type:1,
formValidate:'',
relate:[
{
title:'',
type:'',
merge_id:'',
goods_id:'',
box_id:'',
active_id:'',
type:'',
}
]
},
ruleValidate: {
title: [
{ required: true, message: '请输入标题', trigger: 'blur' }
],
// author: [
// { required: true, message: '请输入作者', trigger: 'blur' }
// ],
cid: [
{ required: true, validator: validateUpload2, trigger: 'change', type: 'number' }
],
image_input: [
{ required: true, validator: validateUpload, trigger: 'change' }
],
content: [
{ required: true, message: '请输入文章内容', trigger: 'change' }
]
},
value: '',
modalPic: false,
template: false,
treeData: [],
formValidate2: {
type: 1
},
myConfig: {
autoHeightEnabled: false, // 编辑器不自动被内容撑高
initialFrameHeight: 500, // 初始容器高度
initialFrameWidth: '100%', // 初始容器宽度
UEDITOR_HOME_URL: '/store/UEditor/',
serverUrl: ''
}
}
},
computed: {
...mapState('admin/layout', [
'isMobile'
]),
labelWidth () {
return this.isMobile ? undefined : 120;
},
labelPosition () {
return this.isMobile ? 'top' : 'right';
}
},
watch: {
$route (to, from) {
if (this.$route.params.id) {
this.getDetails()
} else {
this.formValidate = {
id: 0,
title: '',
author: '',
image_input: '',
content: '',
synopsis: '',
url: '',
is_hot: 0,
is_banner: 0
}
}
}
},
methods: {
itemSelect(e,index){
this.$set(this.formValidate.relate[index],'title',e.label);
},
selectType(e){
if(!e) return;
// this.spin=true;
// // 首发活动列表
// if(e==1){
// if(this.activeList.length==0) {
// this.spin=false;
// }
// this.spin=false;
// }
// // 合成活动列表
// else if(e==2){
// if(this.mergeList.length==0) {
// }
// this.spin=false;
// }
// // 藏品列表
// else if(e==3) {
// if(this.goodsList.length==0) {
// }
// }
// // 盲盒列表
// else if(e==4) {
// if(this.boxList.length==0) {
// }
// }
},
RelateFn(value,index){
console.log(value,index);
if(value=='add') {
console.log(this.formValidate.relate[index]);
if(!this.formValidate.relate[index].merge_id && !this.formValidate.relate[index].active_id && !this.formValidate.relate[index].goods_id&& !this.formValidate.relate[index].box_id) return this.$Message.error('请完善改行数据再添加')
this.formValidate.relate.push({
type:'',
merge_id:0,
goods_id:0,
active_id:0,
box_id:0,
})
} else if(value=='clear'){
this.$set(this.formValidate,'relate',[]);
const item ={
type:'',
merge_id:0,
goods_id:0,
active_id:0,
box_id:0,
}
this.$set(this.formValidate.relate,index,item);
setTimeout(res=>{
this.$set(this.formValidate.relate[index],'goods_id',0);
},200)
}
else {
this.formValidate.relate.splice(index,1)
}
},
...mapActions('admin/page', [
'close'
]),
// getContent (val) {
// this.formValidate.content = val.content;
// },
// 选择图片
modalPicTap () {
this.modalPic = true
},
// 选中图片
getPic (pc) {
this.formValidate.image_input = pc.att_dir;
this.modalPic = false;
},
// 分类
getClass () {
categoryListApi(this.formValidate2).then(async res => {
this.treeData = res.data;
}).catch(res => {
this.$Message.error(res.msg);
})
},
//获取下拉列表活动
getSelectData(){
getGoodsActiveList({page:1,limit:999,is_show:1,active_type:''}).then(res=>{
this.activeList=res.data.data;
})
getList({status:[3,4,5],page:1,limit:999}).then(res=>{
this.mergeList=[...res.data.data];
this.spin=false;
})
getGoodsList({page:1,limit:999,status:1}).then(res=>{
this.goodsList=[...res.data.data];
this.spin=false;
})
getBoxList({page:1,limit:999,status:2}).then(res=>{
this.boxList=[...res.data.data];
this.spin=false;
})
},
// 提交数据
onsubmit (name) {
const type =this.formValidate.relate[0].type;
this.$refs[name].validate((valid) => {
if (valid) {
if(this.formValidate.send_type==2 && this.formValidate.send_time=='') return this.$Message.error(`请选择定时推送时间`);
// if(!type) {
// this.formValidate.relate=[];
// }
cmsAddApi(this.formValidate).then(async res => {
if(res.status != 200) return this.$Message.error(`${res.msg},不可修改`);
this.$Message.success('保存成功');
setTimeout(() => {
this.$router.push({ path: '/store/article/index' });
}, 500);
}).catch(res => {
this.$Message.error(res.msg);
})
} else {
return false;
}
})
},
// 文章详情
getDetails () {
createApi(this.$route.params.id ? this.$route.params.id : 0).then(async res => {
let data = res.data;
let news = data.info;
this.formValidate = {
id: news.id,
title: news.title,
author: news.author,
image_input: news.image_input,
content: news.content.content,
synopsis: news.synopsis,
status:news.status,
url: news.url,
is_hot: news.is_hot,
is_banner: news.is_banner,
cid: news.cid,
visit: news.visit,
relate:news.relate,
content:news.content.content,
send_type:news.send_type,
send_time:news.send_time,
open_wechat_msg:news.open_wechat_msg
}
if(this.formValidate.relate.length==0) {
this.formValidate.relate.push({
type:'',
merge_id:'',
goods_id:'',
active_id:'',
type:'',
})
}
}).catch(res => {
this.loading = false;
this.$Message.error(res.msg);
})
},
// 添加自定义弹窗
addCustomDialog (editorId) {
window.UE.registerUI('test-dialog', function (editor, uiName) {
// 创建 dialog
let dialog = new window.UE.ui.Dialog({
// 指定弹出层中页面的路径,这里只能支持页面,路径参考常见问题 2
iframeUrl: '/admin/widget.images/index.html?fodder=dialog',
// 需要指定当前的编辑器实例
editor: editor,
// 指定 dialog 的名字
name: uiName,
// dialog 的标题
title: '上传图片',
// 指定 dialog 的外围样式
cssRules: 'width:1200px;height:500px;padding:20px;'
});
this.dialog = dialog;
var btn = new window.UE.ui.Button({
name: 'dialog-button',
title: '上传图片',
cssRules: `background-image: url(../../../assets/images/icons.png);background-position: -726px -77px;`,
onclick: function () {
// 渲染dialog
dialog.render();
dialog.open();
}
});
return btn;
}, 37);
window.UE.registerUI(
"video-dialog",
function (editor, uiName) {
let dialog = new window.UE.ui.Dialog({
iframeUrl: "/admin/widget.video/index.html?fodder=video",
editor: editor,
name: uiName,
title: "上传视频",
cssRules: "width:1000px;height:500px;padding:20px;",
});
this.dialog = dialog;
let btn = new window.UE.ui.Button({
name: "video-button",
title: "上传视频",
cssRules: `background-image: url(../../../assets/images/icons.png);background-position: -320px -20px;`,
onclick: function () {
// 渲染dialog
dialog.render();
dialog.open();
},
});
return btn;
},
38
);
}
},
mounted () {
if (this.$route.params.id) {
this.getDetails()
}
},
created () {
this.getClass();
this.getSelectData();
}
}
</script>
<style scoped>
.picBox {
display: inline-block;
cursor: pointer;
}
.form .goodsTitle {
border-bottom: 1px solid rgba(0, 0, 0, 0.09);
margin-bottom: 25px;
}
.form .goodsTitle ~ .goodsTitle {
margin-top: 20px;
}
.form .goodsTitle .title {
border-bottom: 2px solid #1890ff;
padding: 0 8px 12px 5px;
color: #000;
font-size: 14px;
}
.form .goodsTitle .icons {
font-size: 15px;
margin-right: 8px;
color: #999;
}
.form .add {
font-size: 12px;
color: #1890ff;
padding: 0 12px;
cursor: pointer;
}
.form .radio {
margin-right: 20px;
}
.form .submission {
width: 10%;
margin-left: 27px;
}
.form .upLoad {
width: 58px;
height: 58px;
line-height: 58px;
border: 1px dotted rgba(0, 0, 0, 0.1);
border-radius: 4px;
background: rgba(0, 0, 0, 0.02);
}
.form .iconfont {
color: #898989;
}
.form .pictrue {
width: 60px;
height: 60px;
border: 1px dotted rgba(0, 0, 0, 0.1);
margin-right: 10px;
}
.form .pictrue img {
width: 100%;
height: 100%;
}
.Modals .address {
width: 90%;
}
.Modals .address .iconfont {
font-size: 20px;
}
</style>