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.

682 lines
23 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

<template>
<div class="container">
<!-- 查询配置 -->
<div style="padding: 0px 20px">
<div ref="lxHeader">
<LxHeader icon="md-apps" text="活动管理" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
<div slot="content"></div>
<slot>
<div>
<Input style="width: 200px; margin-right: 10px" v-model="searchFields.name" placeholder="关键字搜索" />
<Button type="primary" @click="load" style="margin-left: 10px">查询</Button>
<Button type="primary" @click="edit()" style="margin-left: 10px">新增活动</Button>
</div>
</slot>
</LxHeader>
</div>
<div class="table-tree">
<el-table :data="tableData" class="v-table" :height="tableHeight" style="width: 100%">
<el-table-column type="index" width="50" label="序号" align="center"> </el-table-column>
<el-table-column :prop="column.field" :align="column.align" v-for="(column,index) in columns"
:label="column.title" :width="column.width">
<template slot-scope="scope">
<div v-if="column.type=='opt'">
<Button ghost size="small" @click="toactive(scope.row)" type="success"
style="margin-left: 10px;">订单</Button>
<Button ghost size="small" @click="edit(scope.row)" type="primary"
style="margin-left: 10px;">编辑</Button>
<Button ghost size="small" type="error" @click="del(scope.row)" style="margin-left: 10px;">删除</Button>
<Button v-if="scope.row['status']==1" ghost size="small" type="info" @click="changeStatus(scope.row)"
style="margin-left: 10px;">下架</Button>
<Button v-if="scope.row['status']==0" ghost size="small" type="warning" @click="changeStatus(scope.row)"
style="margin-left: 10px;">上架</Button>
</div>
<div v-else-if="column.type=='dateRange'">
<!-- {{dateRange}} -->
{{scope.row["start_time"]+"-"+changeEndTime(scope.row["end_time"])}}
</div>
<div v-else-if="column.type=='status'">
<el-tag v-if="scope.row['status']==1" type="" effect="dark">
上架中
</el-tag>
<el-tag v-if="scope.row['status']==0" type="info" effect="dark">
下架
</el-tag>
</div>
<div v-else>{{scope.row[column.field]}}</div>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination @current-change="handleCurrentChange" :current-page="paginations.page"
:page-size="paginations.page_size" background layout="prev, pager, next" :total="paginations.total">
</el-pagination>
</div>
</div>
</div>
<el-dialog title="详情编辑" :visible.sync="dialogFormVisible" fullscreen width="90%">
<el-form :model="form" :rules="rules" ref="form" label-position="right" :label-width="formLabelWidth">
<el-row>
<el-col :span="10">
<el-form-item label="活动名称" prop="name">
<el-input v-model="form.name" placeholder="请填写活动名称" autocomplete="off"></el-input>
</el-form-item>
</el-col>
<el-col :span="10" :offset="4">
<el-form-item label="所属区域" prop="area">
<el-select v-model="form.area" placeholder="请选择所属区域" style="width:100%">
<el-option v-for="item in parameters.activityArea" :key="item.value" :label="item.value"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="关联类型" prop="type">
<el-select v-model="form.type" placeholder="请选择关联类型" style="width:100%">
<el-option v-for="item in parameters.activityType" :key="item.value" :label="item.value"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10" :offset="4">
<el-form-item label="关联内容" prop="con">
<el-select v-model="form.form" placeholder="请选择关联内容" style="width:100%">
<el-option v-for="item in parameters.activityCon" :key="item.value" :label="item.value"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="地址" prop="address">
<avue-input-map :params="mapparams" placeholder="请选择地图" v-model="mapform" ></avue-input-map>
</el-form-item>
</el-col>
<el-col :span="10" :offset="4">
<el-form-item label="集合地" prop="resort">
<el-input v-model="form.assemble" placeholder="请填写集合地" autocomplete="off"></el-input>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="地址经度" prop="longitude">
<el-input disabled="" v-model="form.longitude" placeholder="请填写地址经度" autocomplete="off"></el-input>
</el-form-item>
</el-col>
<el-col :span="10" :offset="4">
<el-form-item label="地址纬度" prop="latitude">
<el-input disabled="" v-model="form.latitude" placeholder="请填写地址纬度" autocomplete="off"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="总人数" prop="total">
<el-input v-model="form.total" placeholder="请填写总人数(0为不限制)" autocomplete="off"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="价格" prop="price">
<el-input v-model="form.price" placeholder="请填写价格" autocomplete="off"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="目标群体" prop="group">
<el-select v-model="form.target" placeholder="请选择目标群体" style="width:100%">
<el-option v-for="item in parameters.activityGroup" :key="item.value" :label="item.value"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="预定截止" prop="end_plan">
<el-date-picker style="width:100%" v-model="form.end_plan" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择预定截止时间">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="活动时间" prop="dateRange">
<el-date-picker
style="width:100%"
v-model="dateRange"
type="datetimerange"
value-format="yyyy-MM-dd HH:mm:ss"
range-separator="至"
start-placeholder="活动开始日期"
end-placeholder="活动结束日期">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-form-item class='nextlabel' label="海报图(建议上传图片宽度750px)" prop="cover">
<el-upload action="/api/admin/upload-file" list-type="picture-card" :file-list="coverlist" ref="pictureUpload"
:limit="1" :auto-upload="true" :data="uploadOther"
:on-success="function(responsose,file,fileList) {return handlesuccess(responsose,file,fileList,1)}">
<i slot="default" class="el-icon-plus"></i>
<div slot="file" slot-scope="{file}">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
<span class="el-upload-list__item-actions">
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
<i class="el-icon-zoom-in"></i>
</span>
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
</el-form-item>
<el-form-item class='nextlabel' label="轮播图(最多三张,建议上传图片宽度750px)" prop="banners_list">
<el-upload action="/api/admin/upload-file" list-type="picture-card" :file-list="bannersList"
ref="pictureUploads" :limit="3" :auto-upload="true" :data="uploadOther"
:on-success="function(responsose,file,fileList) {return handlesuccess(responsose,file,fileList,2)}">
<i slot="default" class="el-icon-plus"></i>
<div slot="file" slot-scope="{file}">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
<span class="el-upload-list__item-actions">
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
<i class="el-icon-zoom-in"></i>
</span>
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
</el-form-item>
<el-form-item label="活动介绍" prop="content">
<div style="width: 99.9%;">
<tinymce v-model="form.content" ref="tiny" :height="300" />
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="resetForm('form')">取 消</el-button>
<el-button type="primary" @click="submitForm('form')">确 定</el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
</div>
</template>
<script>
import LxHeader from "@/components/LxHeader/index.vue";
import Tinymce from '@/components/Tinymce'
import AvueMap from 'avue-plugin-map'
import {
getToken
} from '@/utils/auth'
import {
listactive,
store,
save,
del,
get,
chanStatus
} from "../../api/active/activity.js";
export default {
components: {
LxHeader,
Tinymce,
AvueMap
},
data() {
return {
dialogFormVisible: false,
formLabelWidth: "120px",
selectedValue: null,
dialogImageUrl: '',
dialogVisible: false,
disabled: false,
tableHeight: 0,
//查询条件字段
searchFields: {
name: ""
},
tableData: [],
paginations: {
page: 1,
page_size: 15,
total: 0
},
uploadOther: {
token: ""
},
parameters: {
activityArea: [{
id: 1,
value: "本馆"
}, {
id: 2,
value: "馆外"
}],
activityType: [{
id: 1,
value: "公益"
}, {
id: 2,
value: "商业"
}],
activityCon: [{
id: 1,
value: "讲座"
}, {
id: 2,
value: "主题参观"
}, {
id: 3,
value: "体验活动"
}],
activityGroup: [{
id: 1,
value: "幼儿园"
}, {
id: 2,
value: "小学生"
}, {
id: 3,
value: "初中生"
}, {
id: 4,
value: "高中生"
}, {
id: 5,
value: "不限"
}]
},
mapparams:{
zoom: 11,
},
mapform:[] ,
form: {
name: "",
area: "",
type: "",
form: "",
target: "",
address: "",
assemble: "",
cover: "",
start_time: "",
end_time: "",
end_plan: "",
total: 0,
content: "",
price: "",
longitude: "",
latitude: "",
banners_list: []
},
dateRange:"",
showTime: "",
coverlist: [],
bannersList: [],
// fileList:[],
columns: [{
field: "name",
title: "活动名称",
type: "string",
},
{
field: "address",
title: "活动地址",
type: "string",
},
{
field: "dateRange",
title: "活动时间",
type: "dateRange",
align: "center",
width: 300
},
{
field: "end_plan",
title: "截止时间",
type: "string",
align: "center",
width: 220
},
{
field: "status",
title: "状态",
type: "status",
align: "center",
width: 120
},
{
field: "操作",
title: "操作",
width: 240,
type: "opt",
}
],
rules: {
name: [{
required: true,
message: '请输入活动名称',
trigger: 'blur'
}],
longitude: [{
required: true,
message: '请输入经度',
trigger: 'blur'
}],
latitude: [{
required: true,
message: '请输入纬度',
trigger: 'blur'
}],
start_time: [{
required: true,
message: '请选择开始时间',
trigger: 'blur'
}],
end_time: [{
required: true,
message: '请选择结束时间',
trigger: 'blur'
}],
end_plan: [{
required: true,
message: '请选择截止日期',
trigger: 'blur'
}]
},
markerLayer: {},
map: null,
imgsrc: "/src/assets/imgs/ditu.png"
}
},
mounted() {
},
destroyed() {
},
beforeUpdate() {
},
created() {
this.uploadOther.token = getToken();
this.initLoad();
this.load();
},
watch: {
mapform(newVal, oldVal) {
this.form.longitude = newVal[0];
this.form.latitude = newVal[1];
this.form.address = newVal[2];
}
},
methods: {
initLoad() {
var that = this;
var clientHeight = document.documentElement.clientHeight
var lxHeader_height = 96.5; //查询 头部
var paginationHeight = 37; //分页的高度
var topHeight = 50; //页面 头部
let tableHeight = clientHeight - lxHeader_height - topHeight - paginationHeight - 20;
that.tableHeight = tableHeight;
},
load() {
var that = this;
listactive({
page: this.paginations.page,
page_size: this.paginations.page_size,
name: this.searchFields.name
}).then(res => {
this.tableData = res.data;
this.paginations.total = res.total
}).catch(error => {
})
},
info(obj) {
var that = this;
get(obj.id).then(res => {
that.coverlist = [];
let result = Object.assign(that.form, res);
that.form = result;
that.dateRange = [result.start_time, result.end_time];
that.mapform = [result.longitude,result.latitude,result.address]
console.log(that.dateRange);
// that.showTime = result.start_time.substring(11, result.start_time.length);
// that.form.end_time = result.end_time.substring(11, result.end_time.length);
result.cover_upload.coverType = "cover";
that.coverlist.push(result.cover_upload);
let _files = [];
for (var mod of result.banners) {
let m = Object.assign({}, mod);
m.url = mod.upload.url;
m.id = mod.upload.id;
m.coverType = "poster";
_files.push(m);
}
that.bannersList = _files;
this.$refs.tiny.setContent(result.content);
}).catch(error => {
//reject(error)
})
},
edit(obj) {
this.form = this.$options.data().form;
this.clientHeight = document.documentElement.clientHeight - 84 - 110;
if (obj) {
var that = this;
that.info(obj);
} else {
this.dateRange=[];
this.mapform = ['','',''];
}
this.dialogFormVisible = true;
},
compareDate (d1, d2) {
  let reg = new RegExp('-', 'g')
  return ((new Date(d1.replace(reg, '/'))) > (new Date(d2.replace(reg, '/'))))
},
submitForm(formName) {
var that = this;
that.form.start_time = this.dateRange[0];
that.form.end_time = this.dateRange[1];
if(!that.form.start_time||!that.form.end_time){
that.$message.error('请选择活动时间');
return false;
}
//比较预约截止不能大于活动开始时间
let checktime = that.compareDate(that.form.start_time,that.form.end_plan);
if(!checktime){
that.$message.error('截止时间不能晚于开始时间');
return false;
}
// console.log(a)
// that.form.end_time = that.form.start_time.substring(0, 10) + " " + that.form.end_time;
let listUrl = [];
for (var m of that.bannersList) {
if (m.response)
listUrl.push({
"upload_id": m.response.id
});
else
listUrl.push({
"upload_id": m.upload_id
});
}
that.form.banners_list = listUrl;
this.$refs[formName].validate((valid) => {
if (valid) {
if (that.form.id) {
save(that.form).then(response => {
console.log(response)
this.$Message.success('操作成功');
that.dialogFormVisible = false;
that.load();
}).catch(error => {})
} else {
store(that.form).then(response => {
console.log(response)
this.$Message.success('操作成功');
that.dialogFormVisible = false;
that.load();
}).catch(error => {})
}
} else {
this.$Message.error('数据校验失败');
return false;
}
});
},
changeStatus(obj) {
var that = this;
if (obj) {
let status = obj.status == 0 ? 1 : 0;
let para = {
id: obj.id,
status: status
}
this.$Modal.confirm({
title: '确认要变更状态?',
onOk: () => {
chanStatus({
id: para.id,
status: para.status
}).then(response => {
this.$Message.success('操作成功');
that.load();
}).catch(error => {
console.log(error)
reject(error)
})
},
onCancel: () => {
//this.$Message.info('Clicked cancel');
}
});
}
},
resetForm(formName) {
var that = this;
this.coverlist = [];
this.bannersList = [];
this.$refs.tiny.setContent("");
this.$refs[formName].resetFields();
that.dialogFormVisible = false;
},
del(obj) {
var that = this;
if (obj) {
this.$Modal.confirm({
title: '确认要删除数据?',
onOk: () => {
del(obj.id).then(response => {
this.$Message.success('操作成功');
that.load();
}).catch(error => {
console.log(error)
reject(error)
})
},
onCancel: () => {
//this.$Message.info('Clicked cancel');
}
});
}
},
handleRemove(file) {
if (file.coverType == "cover") {
this.coverlist = [];
} else if (file.coverType == "poster") {
for (var i = 0; i < this.bannersList.length; i++) {
if (this.bannersList[i].url == file.url) {
this.bannersList.splice(i, 1)
}
}
}
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
handlesuccess(response, file, fileList, index) {
if (index == 1) {
let listid = "";
for (var m of fileList) {
m.coverType = "cover";
if (m.response)
listid = m.response.id;
else
listid = m.id;
}
this.coverlist = fileList;
this.form.cover = listid;
} else {
let listUrl = [];
for (var m of fileList) {
m.coverType = "poster";
if (m.response)
listUrl.push({
"upload_id": m.response.id
});
else
listUrl.push({
"upload_id": m.id
});
}
this.bannersList = fileList
this.form.banners_list = listUrl
}
},
handleCurrentChange(page) {
this.paginations.page = page;
this.load();
},
toactive(obj) {
if (obj.id) {
this.$router.push({
path: '/order/activeorder',
query: {
activity_id: obj.id
}
})
}
},
changeEndTime(val) {
if (val) {
val = val.substring(11, val.length);
return val
}
},
isShowTime(val) {
this.showTime = val.substring(11, val.length);
},
}
};
</script>
<style>
.nextlabel label{
display: block;
width: 100%!important;
text-align: left;
}
</style>