| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594 |
- <script lang="ts">
- import Vue from 'vue'
- import * as echarts from 'echarts'
- import { getUtmList, getUtmDetail, saveUtmDetail, deleteUtm, getExpoList, getMyExpoInfo } from '@/api/expo'
- export default Vue.extend({
- name: 'Utm',
- data() {
- return {
- showAdd: false,
- isAdd: true,
- expoList: [],
- page: 1,
- total: 0,
- currentExpo: '',
- loading: false,
- searchData: {
- campaign_name: '',
- campaign_id: ''
- },
- addData: {
- id: '',
- website_url: '',
- campaign_name: '',
- campaign_id: '',
- campaign_source: '',
- campaign_term: '',
- campaign_medium: '',
- campaign_content: ''
- },
- adList: [],
- currentAd: {},
- echartsData: {
- tooltip: { trigger: 'item' },
- graphic: [
- {
- type: 'text',
- left: 'center',
- top: '38%',
- style: {
- text: '3147',
- fontSize: 36,
- fontWeight: 'bold',
- fill: '#666',
- textAlign: 'center'
- }
- },
- {
- type: 'text',
- left: 'center',
- top: '56%',
- style: {
- text: '人均pv',
- fontSize: 16,
- fill: '#111111',
- textAlign: 'center'
- }
- }
- ],
- series: [
- {
- type: 'pie',
- radius: ['60%', '100%'],
- avoidLabelOverlap: false,
- padAngle: 5,
- itemStyle: { borderRadius: 10, color: function(params) {
- const colorList = ['#72cdcd', '#d8ba87']
- return colorList[params.dataIndex]
- } },
- label: { show: false },
- left: 8, right: 8, top: 8, bottom: 8,
- data: [
- { value: 0, name: '访客数' },
- { value: 0, name: '浏览量' }
- ]
- }
- ]
- }
- }
- },
- mounted() {
- this.getExpoListData()
- this.getUtmData()
- },
- methods: {
- openAdd() {
- this.addData = {
- id: '',
- website_url: '',
- campaign_name: '',
- campaign_id: '',
- campaign_source: '',
- campaign_term: '',
- campaign_medium: '',
- campaign_content: ''
- }
- this.currentExpo = ''
- this.isAdd = true
- this.showAdd = true
- },
- getUtmData() {
- if (this.loading) {
- return
- }
- this.loading = true
- getUtmList(this.page, 20, this.searchData.campaign_name, this.searchData.campaign_id)
- .then(res => {
- this.adList = res.data.data
- this.total = res.data.total
- this.page = res.data.current_page
- this.loading = false
- })
- },
- inputSearch() {
- if (this.timer) {
- clearTimeout(this.timer)
- }
- this.timer = setTimeout(() => {
- this.getUtmData()
- }, 500)
- },
- changePage(page) {
- this.page = page
- this.getUtmData()
- },
- editAd() {
- this.addData = Object.assign({}, this.currentAd)
- this.isAdd = false
- this.showAdd = true
- },
- addAd() {
- if (this.addData.campaign_name === '') {
- this.$notify({
- title: '提示',
- message: '请填写广告系列名称',
- type: 'warning'
- })
- return
- }
- if (this.addData.website_url === '') {
- this.$notify({
- title: '提示',
- message: '请选择展会',
- type: 'warning'
- })
- return
- }
- if (this.loading) {
- return
- }
- saveUtmDetail(this.addData.id, this.addData.website_url, this.addData.campaign_name, this.addData.campaign_id, this.addData.campaign_source, this.addData.campaign_term, this.addData.campaign_medium, this.addData.campaign_content)
- .then(res => {
- this.$notify({
- title: '提示',
- message: '添加成功',
- type: 'success'
- })
- this.getUtmData()
- this.loading = false
- })
- .catch(err => {
- this.$notify({
- title: '提示',
- message: '添加失败:' + err,
- type: 'error'
- })
- this.loading = false
- })
- this.showAdd = false
- },
- getExpoListData() {
- getExpoList(1, 100, '').then(res => {
- this.expoList = res.data.data
- })
- },
- getExpoDetail() {
- this.loading = true
- getMyExpoInfo(this.currentExpo).then(res => {
- const host = window.location.protocol + '//' + window.location.host + '/register/'
- this.addData.website_url = host + res.data.urla
- this.loading = false
- }).catch(err => {
- this.$notify({
- title: '提示',
- message: '获取展会信息失败:' + err,
- type: 'error'
- })
- this.loading = false
- })
- },
- rowClick(row) {
- console.log(row)
- this.currentAd = {}
- this.echartsData.series[0].data[1].value = row.pv
- this.echartsData.series[0].data[0].value = row.uv
- this.echartsData.graphic[0].style.text = ((row.pv / row.uv) || 0).toFixed(2)
- if (this.myChart) {
- this.myChart.setOption(this.echartsData)
- } else {
- const dom = document.getElementById('form')
- this.myChart = echarts.init(dom)
- this.myChart.setOption(this.echartsData)
- }
- setTimeout(() => {
- this.currentAd = row
- }, 0)
- },
- shareAd(id) {
- this.$router.push({ path: '/share&utm/share?utmid=' + id })
- },
- deleteAd(id) {
- this.$confirm('确定要删除吗?', '提示', {
- callback: (action) => {
- if (action === 'confirm') {
- deleteUtm(id).then(res => {
- this.$notify({
- title: '提示',
- message: '删除成功',
- type: 'success'
- })
- this.currentAd = {}
- this.getUtmData()
- }).catch(err => {
- this.$notify({
- title: '提示',
- message: '删除失败:' + err,
- type: 'error'
- })
- })
- }
- }
- })
- }
- }
- })
- </script>
- <template>
- <div class="utm">
- <div class="list">
- <div class="head">
- <el-input v-model="searchData.campaign_name" class="search" placeholder="活动名称搜索" @input="inputSearch()" />
- <el-input v-model="searchData.campaign_id" class="search" placeholder="系列ID搜索" @input="inputSearch()" />
- <el-button class="add" icon="el-icon-plus" type="primary" @click="openAdd()">新建广告</el-button>
- </div>
- <div v-loading="loading" class="body">
- <el-table :data="adList" height="100%" class="table" @row-click="rowClick">
- <el-table-column label="ID" prop="id" width="60" />
- <el-table-column label="广告系列" prop="campaign_name" width="200" />
- <el-table-column label="浏览量" prop="pv" width="80" />
- <el-table-column label="访客数" prop="uv" width="80" />
- <el-table-column label="广告系列ID" prop="campaign_id" width="200" />
- <el-table-column label="广告来源" prop="campaign_source" width="200" />
- <el-table-column label="广告媒介" prop="campaign_medium" width="200" />
- <el-table-column label="广告内容" prop="campaign_content" width="200" />
- <el-table-column label="广告字段" prop="campaign_term" width="200" />
- <el-table-column label="更新时间" prop="update_time" width="200" />
- </el-table>
- </div>
- <div class="foot">
- <el-pagination
- background
- :page-size="10"
- layout="total"
- :total="total"
- />
- <el-pagination
- v-permission="'exhibitor.handel'"
- background
- :page-size="10"
- layout="prev, pager, next"
- :total="total"
- @current-change="changePage"
- />
- </div>
- </div>
- <div class="view-cont">
- <div class="view">
- <div class="head">
- <div class="name">{{ currentAd.campaign_name || '请选择广告' }}</div>
- </div>
- <div :class="['ad-info',currentAd.id?'show':'hide']">
- <el-button v-show="currentAd.id" class="edit" icon="el-icon-edit-outline" circle @click="editAd()" />
- <div>广告信息</div>
- <div class="info-list">
- <div class="item">
- <div class="label">ID:</div>
- <div class="value">{{ currentAd.id }}</div>
- </div>
- <div class="item">
- <div class="label">浏览量:</div>
- <div class="value">{{ currentAd.pv }}</div>
- </div>
- <div class="item">
- <div class="label">访客数:</div>
- <div class="value">{{ currentAd.uv }}</div>
- </div>
- <div class="item">
- <div class="label">原链接:</div>
- <div class="value">{{ currentAd.website_url }}</div>
- </div>
- <div class="item">
- <div class="label">短链接:</div>
- <div class="value">{{ currentAd.short_url }}</div>
- </div>
- <div class="item">
- <div class="label">系列ID:</div>
- <div class="value">{{ currentAd.campaign_id }}</div>
- </div>
- <div class="item">
- <div class="label">广告来源:</div>
- <div class="value">{{ currentAd.campaign_source }}</div>
- </div>
- <div class="item">
- <div class="label">广告媒介:</div>
- <div class="value">{{ currentAd.campaign_medium }}</div>
- </div>
- <div class="item">
- <div class="label">广告内容:</div>
- <div class="value">{{ currentAd.campaign_content }}</div>
- </div>
- <div class="item">
- <div class="label">广告字段:</div>
- <div class="value">{{ currentAd.campaign_term }}</div>
- </div>
- <div class="item">
- <div class="label">更新时间:</div>
- <div class="value">{{ currentAd.update_time }}</div>
- </div>
- </div>
- </div>
- <div :class="['info-card',currentAd.id?'show':'hide']">
- <div>人均浏览量</div>
- <div id="form" class="charts" />
- <div class="desc">
- <span v-if="currentAd.pv/currentAd.uv < 1.5">
- 大部分访客仅浏览一个页面后就离开了,也许您需要优化展会的宣传内容。
- </span>
- <span v-else-if="currentAd.pv/currentAd.uv > 1.5 && currentAd.pv/currentAd.uv < 3">
- 部分访客进入网站后又浏览了其它页面,看来访客对您的展会有兴趣!
- </span>
- <span v-else-if="currentAd.pv/currentAd.uv > 3">
- 进入网站的访客平均浏览了三个以上的页面,访客对您的展会非常有兴趣!
- </span>
- <span v-else>
- 网站暂时还没有访客数据,请耐心等待。
- </span>
- </div>
- </div>
- <div :class="['handel-info',currentAd.id?'show':'hide']">
- <div>操作面板</div>
- <div class="button-list">
- <el-button icon="el-icon-share" type="primary" @click="shareAd(currentAd.id)">分享广告</el-button>
- <el-button icon="el-icon-edit-outline" type="primary" @click="editAd()">编辑广告</el-button>
- <el-button icon="el-icon-delete" type="danger" @click="deleteAd(currentAd.id)">删除广告</el-button>
- </div>
- </div>
- </div>
- </div>
- <el-dialog :title="isAdd?'添加广告':'编辑广告'" custom-class="utm-dialog" :close-on-click-modal="false" :append-to-body="true" :visible.sync="showAdd">
- <div class="form">
- <div v-show="isAdd" class="item">
- <span class="label">展会(必选)</span>
- <el-select v-model="currentExpo" @change="getExpoDetail()">
- <el-option
- v-for="item in expoList"
- :key="item.id"
- :label="item.expo_name"
- :value="item.id"
- />
- </el-select>
- </div>
- <div v-show="isAdd" class="item">
- <span class="label">展会网址(自动填写)</span>
- <el-input :value="addData.website_url" />
- </div>
- <div class="item">
- <span class="label">广告系列名称(必填)</span>
- <el-input v-model="addData.campaign_name" />
- </div>
- <div class="item">
- <span class="label">广告来源</span>
- <el-input v-model="addData.campaign_source" />
- </div>
- <div class="item">
- <span class="label">宣传媒介</span>
- <el-input v-model="addData.campaign_medium" />
- </div>
- <div class="item">
- <span class="label">广告内容</span>
- <el-input v-model="addData.campaign_content" />
- </div>
- <div class="item">
- <span class="label">广告系列ID</span>
- <el-input v-model="addData.campaign_id" />
- </div>
- <div class="item">
- <span class="label">广告字段</span>
- <el-input v-model="addData.campaign_term" />
- </div>
- </div>
- <span slot="footer" class="dialog-footer">
- <el-button @click="showAdd=false">取 消</el-button>
- <el-button v-loading="loading" type="primary" @click="addAd()">确 定</el-button>
- </span>
- </el-dialog>
- </div>
- </template>
- <style scoped>
- .utm{
- overflow: hidden;
- padding: 0 !important;
- display: grid;
- width: 100%;
- height: 100%;
- grid-template-columns: 1fr 360px;
- .list{
- display: grid;
- grid-gap: 16px;
- grid-template-rows: auto 1fr auto;
- z-index: 1;
- position: relative;
- padding: 16px;
- box-shadow: 0 1px 4px 0 #00000022;
- .head{
- gap: 16px;
- display: flex;
- .search{
- width: 30%;
- }
- .add{
- margin-left: auto;
- }
- }
- .body{
- height: 100%;
- position: relative;
- .table{
- width: 100%;
- height: 100%;
- position: absolute;
- top: 0;
- left: 0;
- }
- }
- .foot{
- display: flex;
- justify-content: space-between;
- }
- }
- .view-cont{
- position: relative;
- width: 100%;
- height: 100%;
- }
- .view{
- padding: 16px;
- border-radius: 0 16px 16px 0;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- overflow: hidden;
- overflow-y: auto;
- background-color: #F9FAFB;
- .ad-info{
- position: relative;
- margin-top: 16px;
- background-color: #FFFFFF;
- box-shadow: 0 1px 4px 0 #00000011;
- border-radius: 16px;
- padding: 16px;
- transition-duration: 300ms;
- &.hide{
- transition-duration: 0ms;
- opacity: 0;
- transform: translateY(10px);
- }
- .edit{
- position: absolute;
- right: 8px;
- top: 8px;
- }
- .info-list{
- color: grey;
- margin-top: 8px;
- .item{
- display: flex;
- font-size: 14px;
- .label{
- width: 80px;
- text-align: right;
- }
- .value{
- width: 215px;
- overflow: hidden;
- }
- }
- }
- }
- .handel-info{
- background-color: #FFFFFF;
- box-shadow: 0 1px 4px 0 #00000011;
- border-radius: 16px;
- padding: 16px;
- position: relative;
- margin-top: 16px;
- width: 100%;
- transition-delay: 200ms;
- transition-duration: 300ms;
- .button-list{
- display: flex;
- flex-direction: column;
- gap: 8px;
- margin-top: 8px;
- .el-button{
- margin: 0;
- }
- }
- &.hide{
- transition-delay: 0ms;
- transition-duration: 0ms;
- opacity: 0;
- transform: translateY(10px);
- }
- }
- .info-card{
- background-color: #FFFFFF;
- box-shadow: 0 1px 4px 0 #00000011;
- border-radius: 16px;
- padding: 16px;
- position: relative;
- margin-top: 16px;
- width: 100%;
- transition-delay: 100ms;
- transition-duration: 300ms;
- &.hide{
- transition-delay: 0ms;
- transition-duration: 0ms;
- opacity: 0;
- transform: translateY(10px);
- }
- .charts{
- position: relative;
- width: 100%;
- height: 260px;
- }
- .desc{
- margin-top: 16px;
- font-size: 14px;
- color: grey;
- }
- }
- .head{
- display: flex;
- align-items: center;
- .name{
- font-size: 18px;
- font-weight: bold;
- color: #111111;
- overflow: hidden;
- flex: 1;
- margin-right: 16px;
- text-overflow: ellipsis;
- white-space: nowrap;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-line-clamp: 1;
- }
- }
- }
- }
- </style>
- <style>
- .utm-dialog{
- .form{
- display: flex;
- flex-direction: column;
- gap: 12px;
- .item{
- display: flex;
- align-items: center;
- .label{
- width: 160px;
- }
- .el-select{
- width: 100%;
- }
- }
- }
- }
- </style>
|