index.vue 10.8 KB
<template>

	<div style="background-color:#f7f7f7;padding:10px 10px;">
		<div class="history">
			<div style="height:58px;line-height:58px;">
				<div style="color:#0006"> <span>渠道售票统计分析</span> <span style="padding:0 5px;">></span> <span
						style="color:#000000e6">票种销售数据统计</span></div>
			</div>
			<div>

				<!-- 顶部搜索 -->
				<div class="toolbar">
					<el-form ref="formParams" :inline="true" :model="pageIndex">
						<el-form-item label="渠道">
							<el-select placeholder="全部" v-model="pageIndex.ticketChannel"
								style="width: 120px;margin-right: 15px">
								<el-option v-for="(item,index) in type" :label="item==1?'有赞':'其他'" :value="item" />
							</el-select>
						</el-form-item>
						<el-form-item label="票种">
							<el-select placeholder="全部" v-model="pageIndex.ticketType"
								style="width: 120px;margin-right: 15px">
								<el-option v-for="(item,index) in listType" :label="item" :value="item" />
							</el-select>
						</el-form-item>
						<el-form-item label="日期">
							<el-date-picker v-model="pageIndex.list" type="daterange" range-separator="至"
								start-placeholder="开始时间" end-placeholder="结束时间" value-format="yyyy-MM-dd" />
						</el-form-item>

						<el-form-item label-width="0">
							<el-button @click="search" style="background-color: #3F9B6A;color: #fff">查询</el-button>
							<el-button @click="clear" class="buttonHover"
								style="color: #606266;border: 1px solid #dddfe5;background-color: #fff;">重置</el-button>
						</el-form-item>
					</el-form>
				</div>
			</div>
			<!-- 表格 -->
			<div class="content_table" style="padding: 15px 10px 10px 10px;background-color:#F2F3F5">
				<div style='padding:20px 10px;background-color:#fff;margin-bottom: 10px;'>
					<div style="font-size:14px;justify-content: space-around;display:flex;">
						<div style="display:flex;width:50%;justify-content: space-around;text-align: center;" v-for="(item,index) in titleList">
							<div style="width:45%;border-right:1px solid #F2F3F5" >
								<div style="margin-bottom: 10px;font-weight: 600;">{{item.ticketType}}销售数量(张)</div>
								<div style="font-weight: 600;">{{item.sumNum}}</div>
							</div>
							<div style="width:45%;border-right:1px solid #F2F3F5">
								<div style="margin-bottom: 10px;font-weight: 600;">{{item.ticketType}}销售总额(元)</div>
								<div style="font-weight: 600;">{{item.moyeTwo}}</div>
							</div>
						</div>
					<!-- 	<div style="width:15%;border-right:1px solid #F2F3F5">
							<div style="margin-bottom: 10px;font-weight: 600;">演唱会票销售数量(张)</div>
							<div style="font-weight: 600;">{{numOne}}</div>
						</div>
						<div style="width:15%;">
							<div style="margin-bottom: 10px;font-weight: 600;">演唱会票销售总额(元)</div>
							<div style="font-weight: 600;">{{moyeOne}}</div>
						</div> -->
					</div>
				</div>
				<div style="background-color: #fff;padding: 10px;margin-bottom: 20px;">
					<div style="display: flex;margin-bottom: 20px;">
						<div style="width: 100%;padding: 10px 0;">各渠道票种销售数据</div>
						<!-- <el-select  placeholder="全部渠道"
              style="width: 120px;margin-right: 15px">
              <el-option label="1" value="1" />
            </el-select> -->
						<el-button style="background-color: #3F9B6A;color: #fff;" @click="daochu">导出</el-button>
					</div>
					<div class="table">
						<!-- :span-method="objectSpanMethod" -->
						<el-table :summary-method="getSummaries"  show-summary
							:data="tableData.slice((currentPage - 1) * pageSize, currentPage * pageSize)"
							:header-cell-style="{fontSize: '14px',color:'#0009',fontWeight: 'normal',backgroundColor:'#F2F3F5'}">
							<el-table-column label="序号" min-width="50">
								<template slot-scope="scope">
									{{scope.$index +1}}
								</template>
							</el-table-column>
							<el-table-column prop="ticketChannel" label="渠道" min-width="60">
								<template slot-scope="scope">
									{{scope.row.ticketChannel == '1'?'有赞':'其他'}}
								</template>
							</el-table-column>
							<el-table-column prop="ticketType" label="票种" min-width="60"/>
							<el-table-column prop="ticketName" label="票名" min-width="160" :show-overflow-tooltip="true"/>
							<el-table-column prop="num" label="销售数量(张)" />
							<el-table-column prop="ticketPrice" label="客单价(元)" />
							<el-table-column prop="price" label="销售金额(元)" />
							<!-- <el-table-column label="操作">
                <template slot-scope="scope">
                  <el-button type="text"   style="background-color: transparent;color: #3F9B6A;;border: none;">详情</el-button>
                  <el-button type="text"   style="background-color: transparent;color: #3F9B6A;;border: none;">删除</el-button>
                </template>
              </el-table-column> -->
						</el-table>
					</div>
					<!-- 分页 -->
					<div class="fenye">

						<el-pagination class="pagination" :hide-on-single-page="flag" background 
							:current-page="currentPage" :page-sizes="[10, 20, 50, 100]" :page-size="pageSize"
							layout="total,prev, pager,next" :total="total " @size-change="handleSizeChange"
							@current-change="handleCurrentChange" />
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script>
	import {
		getTicketType,
		excelToTicketTypeSalesSituation
	} from '@/api/piaowu'
	export default {
		data() {
			return {
				flag: false,
				total: 0,
				pageSize: 10,
				currentPage: 1,
				tipsList: [],
				tableData: [],
				pageIndex: {
					list: [],
					page: 1,
					pageSize: 10,
					startTime: "",
					endTime: "",
					ticketChannel: "",
					ticketType: ""
				},
				numOne: 0,
				moyeOne: 0,
				numTwo: 0,
				moyeTwo: 0,
				type: [],
				listType: [],
				titleList:[]
			}
		},
		mounted() {
			this.getAll()
			getTicketType(this.pageIndex).then(res=>{
				this.type = this.extractAndDeduplicateTicketChannels(res.data)
				this.listType = this.listype(res.data)
			})
			
		},
		methods: {
			async getAll() {
				let res = await getTicketType(this.pageIndex)
				this.tableData = res.data
				this.total = res.data.length
				this.titleList = this.processTicketData(res.data)
			},
			processTicketData(data) {
			    const result = {};	
			    // 遍历原始数据
			    data.forEach(item => {
			        const ticketType = item.ticketType;
			        if (!result[ticketType]) {
			            // 如果该 ticketType 还未在结果对象中,初始化它
			            result[ticketType] = {
			                ticketType: ticketType,
			                sumNum: 0,
			                moyeTwo: 0
			            };
			        }
			        // 累加 num 和 price
			        result[ticketType].sumNum += item.num;
			        result[ticketType].moyeTwo += item.price;
			    });
			
			    // 将结果对象转换为数组
			    return Object.values(result);
			},
			search() {
				if (this.pageIndex.list.length != 0) {
					this.pageIndex.startTime = this.pageIndex.list[0]
					this.pageIndex.endTime = this.pageIndex.list[1]
				}
				this.getAll()
			},
			extractAndDeduplicateTicketChannels(arr) {
				const ticketChannels = [];
				for (let i = 0; i < arr.length; i++) {
					if (arr[i].hasOwnProperty('ticketChannel')) {
						ticketChannels.push(arr[i].ticketChannel);
					}
				}
				return [...new Set(ticketChannels)];
			},
			listype(arr) {
				const ticketChannels = [];
				for (let i = 0; i < arr.length; i++) {
					if (arr[i].hasOwnProperty('ticketType')) {
						ticketChannels.push(arr[i].ticketType);
					}
				}
				return [...new Set(ticketChannels)];
			},
			clear() {
				this.pageIndex = {
					list: [],
					page: 1,
					pageSize: 10,
					startTime: "",
					endTime: "",
					ticketChannel: "",
					ticketType: ""
				}
				this.getAll()
			},
			changepiao() {
				this.getAll()
			},
			async daochu() {
				let res = await excelToTicketTypeSalesSituation(this.pageIndex)
				if (!res) {
					return
				}
				const blob = new Blob([res], {
					type: 'application/vnd.ms-excel'
				})
				const fileName = '票种销售表.xls'
				if ('download' in document.createElement('a')) {
					// 非IE下载
					const elink = document.createElement('a')
					elink.download = fileName
					elink.style.display = 'none'
					elink.href = URL.createObjectURL(blob)
					document.body.appendChild(elink)
					elink.click()
					URL.revokeObjectURL(elink.href) // 释放URL 对象
					document.body.removeChild(elink)
				} else {
					// IE10+下载
					navigator.msSaveBlob(blob, fileName)
				}
				this.$message({
					message: '导出成功',
					type: 'success'
				})
			},
			getSummaries(param) {
				const {
					columns,
					data
				} = param;
				const sums = [];
				columns.forEach((column, index) => {
					if (index === 0) {
						sums[index] = '总计';
						return;
					}
					if (['销售数量(张)', '客单价(元)', '销售金额(元)'].includes(column.label)) {
						const values = data.map(item => Number(item[column.property]))

						if (!values.every(value => isNaN(value))) {
							sums[index] = values.reduce((prev, curr) => {
								const value = Number(curr);

								if (!isNaN(value)) {

									return prev + curr;

								} else {
									return prev;
								}
							}, 0);
						} else {
							sums[index] = '';
						}
					} else {
						sums[index] = '';
					}
				});

				return sums;
			},

			handleCurrentChange(val) {
				this.currentPage = val
			},
			handleSizeChange(val) {
				this.pageSize = val
			},
			// objectSpanMethod({
			// 	row,
			// 	column,
			// 	rowIndex,
			// 	columnIndex
			// }) {
			// 	if (columnIndex === 0) {
			// 		if (rowIndex % 2 === 0) {
			// 			return {
			// 				rowspan: 2,
			// 				colspan: 1
			// 			};
			// 		} else {
			// 			return {
			// 				rowspan: 0,
			// 				colspan: 0
			// 			};
			// 		}
			// 	}
			// },
		},
	}
</script>

<style lang='scss' scoped>
	.history {
		padding: 0 20px 20px 20px;
		min-height: calc(100vh - 50px - 20px);
		background-color: #Fff;
	}

	::v-deep .el-form-item__label {
		font-weight: normal;
		font-size: 14px;

	}

	::v-deep .el-pagination.is-background .el-pager li:not(.disabled).active {
		background-color: #3F9B6A;
	}
</style>
<style scoped>
	.history /deep/ .el-table .cell.el-tooltip img {
		max-height: 100px;
	}


	.pagination {
		text-align: right;
		line-height: 20px;
	}

	.greens {
		color: #3F9B6A;
	}

	/deep/ .el-table__row {
		font-size: 14px;
		color: #000000e6;
		height: 42px;
	}

	.fenye {
		margin-top: 20px;
		display: flex;
		justify-content: flex-end;
	}

	::v-deep .el-pagination__total {
		position: absolute;
		left: 60px;
	}

	::v-deep .buttonHover:hover {
		color: #3f9b6a !important;
		border-color: #c5e1d2 !important;
		background-color: #ecf5f0 !important;
		outline: none;
	}
</style>
<style>
	.el-tooltip__popper {
		max-width: 50%;
	}
</style>