|
|
@@ -0,0 +1,228 @@
|
|
|
+<template>
|
|
|
+ <div class="app-container">
|
|
|
+ <el-table
|
|
|
+ :key="tableKey"
|
|
|
+ v-loading="listLoading"
|
|
|
+ :data="list"
|
|
|
+ border
|
|
|
+ fit
|
|
|
+ highlight-current-row
|
|
|
+ style="width: 100%;"
|
|
|
+ @sort-change="sortChange"
|
|
|
+ >
|
|
|
+ <el-table-column :label="$t('ad.ad')" prop="id" align="center" :class-name="getSortClass('id')">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <span>{{ row.LOCATION_NAME }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column :label="$t('ad.description')" prop="id" align="center" :class-name="getSortClass('id')">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <span>{{ row.REMARK }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column :label="$t('ad.type')" align="center"> <!-- 类型 -->
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <template v-if="row.TYPE === '1'">
|
|
|
+ <el-tag type="success">Slideshow</el-tag> <!-- 外链 -->
|
|
|
+ </template>
|
|
|
+ <template v-else-if="row.TYPE === '2'">
|
|
|
+ <el-tag>Image</el-tag> <!-- 文章 -->
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column :label="$t('ad.creator')" prop="id" align="center" width="80" :class-name="getSortClass('id')">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <span>{{ row.CREATE_ADMIN_NAME }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column :label="$t('ad.createTime')" align="center">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <span>{{ row.CREATED_AT | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column :label="$t('ad.action')" align="center" class-name="small-padding fixed-width">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <el-button type="primary" size="mini" @click="handleView(row)">
|
|
|
+ {{ $t('ad.view') }}
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
|
|
|
+
|
|
|
+ <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
|
|
|
+ <el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="70px" style="width: 400px; margin-left:50px;">
|
|
|
+ <el-form-item :label="$t('table.type')" prop="type">
|
|
|
+ <el-select v-model="temp.type" class="filter-item" placeholder="Please select">
|
|
|
+ <el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item :label="$t('table.date')" prop="timestamp">
|
|
|
+ <el-date-picker v-model="temp.timestamp" type="datetime" placeholder="Please pick a date" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item :label="$t('table.title')" prop="title">
|
|
|
+ <el-input v-model="temp.title" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item :label="$t('table.status')">
|
|
|
+ <el-select v-model="temp.status" class="filter-item" placeholder="Please select">
|
|
|
+ <el-option v-for="item in statusOptions" :key="item" :label="item" :value="item" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item :label="$t('table.importance')">
|
|
|
+ <el-rate v-model="temp.importance" :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :max="3" style="margin-top:8px;" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item :label="$t('table.remark')">
|
|
|
+ <el-input v-model="temp.remark" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="Please input" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button @click="dialogFormVisible = false">
|
|
|
+ {{ $t('table.cancel') }}
|
|
|
+ </el-button>
|
|
|
+ <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
|
|
|
+ {{ $t('table.confirm') }}
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <el-dialog :visible.sync="dialogPvVisible" title="Reading statistics">
|
|
|
+ <el-table :data="pvData" border fit highlight-current-row style="width: 100%">
|
|
|
+ <el-table-column prop="key" label="Channel" />
|
|
|
+ <el-table-column prop="pv" label="Pv" />
|
|
|
+ </el-table>
|
|
|
+ <span slot="footer" class="dialog-footer">
|
|
|
+ <el-button type="primary" @click="dialogPvVisible = false">{{ $t('table.confirm') }}</el-button>
|
|
|
+ </span>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { fetchList } from '@/api/ad'
|
|
|
+import waves from '@/directive/waves' // waves directive
|
|
|
+import { parseTime } from '@/utils'
|
|
|
+import Pagination from '@/components/Pagination' // secondary package based on el-pagination
|
|
|
+
|
|
|
+const calendarTypeOptions = [
|
|
|
+ { key: 'CN', display_name: 'China' },
|
|
|
+ { key: 'US', display_name: 'USA' }
|
|
|
+]
|
|
|
+
|
|
|
+// arr to obj, such as { CN : "China", US : "USA" }
|
|
|
+const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
|
|
|
+ acc[cur.key] = cur.display_name
|
|
|
+ return acc
|
|
|
+}, {})
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'ComplexTable',
|
|
|
+ components: { Pagination },
|
|
|
+ directives: { waves },
|
|
|
+ filters: {
|
|
|
+ statusFilter(status) {
|
|
|
+ const statusMap = {
|
|
|
+ published: 'success',
|
|
|
+ draft: 'info',
|
|
|
+ deleted: 'danger'
|
|
|
+ }
|
|
|
+ return statusMap[status]
|
|
|
+ },
|
|
|
+ typeFilter(type) {
|
|
|
+ return calendarTypeKeyValue[type]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ tableKey: 0,
|
|
|
+ list: null,
|
|
|
+ total: 0,
|
|
|
+ listLoading: true,
|
|
|
+ listQuery: {
|
|
|
+ page: 1,
|
|
|
+ limit: 20,
|
|
|
+ importance: undefined,
|
|
|
+ title: undefined,
|
|
|
+ type: undefined,
|
|
|
+ sort: '+id'
|
|
|
+ },
|
|
|
+ importanceOptions: [1, 2, 3],
|
|
|
+ calendarTypeOptions,
|
|
|
+ sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
|
|
+ statusOptions: ['published', 'draft', 'deleted'],
|
|
|
+ showReviewer: false,
|
|
|
+ temp: {
|
|
|
+ id: undefined,
|
|
|
+ importance: 1,
|
|
|
+ remark: '',
|
|
|
+ timestamp: new Date(),
|
|
|
+ title: '',
|
|
|
+ type: '',
|
|
|
+ status: 'published'
|
|
|
+ },
|
|
|
+ dialogFormVisible: false,
|
|
|
+ dialogStatus: '',
|
|
|
+ textMap: {
|
|
|
+ update: 'Edit',
|
|
|
+ create: 'Create'
|
|
|
+ },
|
|
|
+ dialogPvVisible: false,
|
|
|
+ pvData: [],
|
|
|
+ rules: {
|
|
|
+ type: [{ required: true, message: 'type is required', trigger: 'change' }],
|
|
|
+ timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
|
|
|
+ title: [{ required: true, message: 'title is required', trigger: 'blur' }]
|
|
|
+ },
|
|
|
+ downloadLoading: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.getList()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getList() {
|
|
|
+ this.listLoading = true
|
|
|
+ fetchList(this.listQuery).then(response => {
|
|
|
+ this.list = response.data.list
|
|
|
+ this.total = response.data.totalCount
|
|
|
+
|
|
|
+ // Just to simulate the time of the request
|
|
|
+ setTimeout(() => {
|
|
|
+ this.listLoading = false
|
|
|
+ }, 1.5 * 1000)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleFilter() {
|
|
|
+ this.listQuery.page = 1
|
|
|
+ this.getList()
|
|
|
+ },
|
|
|
+ resetTemp() {
|
|
|
+ this.temp = {
|
|
|
+ id: undefined,
|
|
|
+ importance: 1,
|
|
|
+ remark: '',
|
|
|
+ timestamp: new Date(),
|
|
|
+ title: '',
|
|
|
+ status: 'published',
|
|
|
+ type: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleView(row) {
|
|
|
+ this.$router.push(`/ad/list/${row.ID}`)
|
|
|
+ },
|
|
|
+ formatJson(filterVal) {
|
|
|
+ return this.list.map(v => filterVal.map(j => {
|
|
|
+ if (j === 'timestamp') {
|
|
|
+ return parseTime(v[j])
|
|
|
+ } else {
|
|
|
+ return v[j]
|
|
|
+ }
|
|
|
+ }))
|
|
|
+ },
|
|
|
+ getSortClass: function(key) {
|
|
|
+ const sort = this.listQuery.sort
|
|
|
+ return sort === `+${key}` ? 'ascending' : 'descending'
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|