joway před 2 roky
rodič
revize
33ddf882a7

+ 47 - 0
src/api/ad.js

@@ -28,3 +28,50 @@ export function fetchChangeSort(query) {
     }
   })
 }
+
+export function fetchDetail(query) {
+  return request({
+    url: '/v1/ad/edit/' + query,
+    method: 'get'
+  })
+}
+
+export function fetchEdit(query, data) {
+  return request({
+    url: '/v1/ad/edit/' + query,
+    method: 'post',
+    data
+  })
+}
+
+export function fetchDelete(data) {
+  return request({
+    url: '/v1/ad/ad-delete',
+    method: 'post',
+    data
+  })
+}
+
+export function fetchHide(data) {
+  return request({
+    url: '/v1/ad/ad-hide',
+    method: 'post',
+    data
+  })
+}
+
+export function fetchUnhide(data) {
+  return request({
+    url: '/v1/ad/ad-un-hide',
+    method: 'post',
+    data
+  })
+}
+
+export function fetchAdd(data) {
+  return request({
+    url: '/v1/ad/add',
+    method: 'post',
+    data
+  })
+}

+ 10 - 0
src/api/log.js

@@ -0,0 +1,10 @@
+import request from '@/utils/request'
+
+export function fetchAdminLoginList(query) {
+  return request({
+    url: '/v1/log/admin-login',
+    method: 'get',
+    data: query,
+    params: query
+  })
+}

+ 16 - 0
src/api/upload.js

@@ -0,0 +1,16 @@
+import request from '@/utils/request'
+
+export function getToken() {
+  return request({
+    url: '/v1/file/token',
+    method: 'get'
+  })
+}
+
+export function upload(data) {
+  return request({
+    url: '/v1/ad/upload',
+    method: 'post',
+    data
+  })
+}

+ 213 - 0
src/components/Upload/index.vue

@@ -0,0 +1,213 @@
+<template>
+  <div class="singleImageUpload2 upload-container">
+    <el-upload
+      v-show="uploaderShow"
+      v-loading="uploaderLoading"
+      class="image-uploader"
+      :action="uploaderRequestUrl"
+      name="file"
+      :headers="uploaderHeaders"
+      :data="uploaderFormData"
+      :show-file-list="false"
+      :before-upload="uploaderHandleBefore"
+      :on-success="uploaderHandleSuccess"
+      :disabled="uploaderDisabled"
+      :style="isImgUpload ? `width:${width};height:${height};` : ''"
+    >
+      <template v-if="isImgUpload">
+        <img
+          v-if="uploaderImageUrl"
+          :src="uploaderImageUrl"
+          class="image-preview"
+          :style="`width:${width};height:${height};display: block;`"
+        >
+        <i
+          v-else
+          class="el-icon-plus uploader-icon"
+          :style="`width:${width};height:${height};line-height:${height};`"
+        />
+      </template>
+      <template v-else>
+        <el-button type="primary">{{ uploadBtnTitle }}</el-button>
+      </template>
+    </el-upload>
+    <template v-if="isImgUpload">
+      <div v-show="!uploaderShow" class="image-show">
+        <img :src="uploaderImageUrl" alt="" :width="width" :height="height">
+      </div>
+    </template>
+  </div>
+</template>
+
+<script>
+import { getToken } from '@/api/upload'
+export default {
+  name: 'Uploader',
+  props: {
+    isImgUpload: {
+      type: Boolean,
+      default: true
+    },
+    uploadBtnTitle: {
+      type: String,
+      default: '上传'
+    },
+    requestRoute: {
+      type: String,
+      required: true
+    },
+    defaultImageUrl: {
+      type: String,
+      default: null
+    },
+    uploaderSuccessCanChange: {
+      type: Boolean,
+      default: true
+    },
+    width: {
+      type: String,
+      default: '100px'
+    },
+    height: {
+      type: String,
+      default: '100px'
+    }
+  },
+  data() {
+    return {
+      uploaderShow: true,
+      uploaderLoading: false,
+      uploaderFormData: {
+        'uploadToken': ''
+      },
+      uploaderRequestUrl: `${this.requestRoute}`,
+      uploaderHeaders: {
+        'Device-Type': 'pc',
+        'Suppress-Response-Code': '1',
+        'Authorization': ''
+      },
+      uploaderDisabled: false,
+      successImageUrl: null,
+      uploaderImage: null
+    }
+  },
+  computed: {
+    uploaderImageUrl() {
+      if (this.uploaderImage != null) {
+        return this.uploaderImage
+      }
+      console.log(this.defaultImageUrl)
+      if (this.successImageUrl !== null) {
+        return this.successImageUrl
+      } else if (this.defaultImageUrl !== null) {
+        // this.uploaderShow = false
+        // this.uploaderDisabled = true
+
+        // this.uploaderLoading = false
+        return this.defaultImageUrl
+      } else {
+        return ''
+      }
+    }
+  },
+  watch: {
+    defaultImageUrl(newVal, oldVal) {
+      this.uploaderImage = newVal
+      // console.log(oldVal)
+    }
+  },
+  created() {
+    console.log(this.uploaderImage)
+  },
+  methods: {
+    uploaderHandleBefore() {
+      const auth_token = localStorage.accessToken
+      this.uploaderHeaders.Authorization = 'Bearer  ' + auth_token
+      return new Promise((resolve, reject) => {
+        getToken().then(response => {
+          console.log(response)
+          this.uploaderFormData.uploadToken = response.data
+          resolve(true)
+        }).catch(() => {
+          reject(false)
+        })
+      })
+    },
+    uploaderHandleSuccess(response, file) {
+      // console.log(response)
+      if (response.success) {
+        this.$message({
+          message: 'Successful',
+          type: 'success'
+        })
+        this.successImageUrl = URL.createObjectURL(file.raw)
+        if (!this.uploaderSuccessCanChange) {
+          this.uploaderShow = false
+          this.uploaderDisabled = true
+          this.uploaderLoading = false
+        }
+        this.$emit('on-success', response.data)
+      } else {
+        this.$message({
+          message: response.data.message,
+          type: 'warning'
+        })
+        this.uploaderLoading = false
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.upload-container {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  .image-uploader {
+    height: 100%;
+  }
+  .image-preview {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    left: 0px;
+    top: 0px;
+    border: 1px dashed #d9d9d9;
+    .image-preview-wrapper {
+      position: relative;
+      width: 100%;
+      height: 100%;
+      img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .image-preview-action {
+      position: absolute;
+      width: 100%;
+      height: 100%;
+      left: 0;
+      top: 0;
+      cursor: default;
+      text-align: center;
+      color: #fff;
+      opacity: 0;
+      font-size: 20px;
+      background-color: rgba(0, 0, 0, .5);
+      transition: opacity .3s;
+      cursor: pointer;
+      text-align: center;
+      line-height: 200px;
+      .el-icon-delete {
+        font-size: 36px;
+      }
+    }
+    &:hover {
+      .image-preview-action {
+        opacity: 1;
+      }
+    }
+  }
+}
+</style>

+ 7 - 2
src/lang/en.js

@@ -97,7 +97,11 @@ export default {
     modifiedBy: 'Modified By',
     modifiedTime: 'Modified Time',
     status: 'Status',
-    adLocation: 'Ad Location'
+    adLocation: 'Ad Location',
+    selectData: 'Select Data',
+    add: 'Add',
+    hide: 'Hide',
+    unhide: 'Unhide'
   },
   documentation: {
     documentation: 'Documentation',
@@ -228,7 +232,8 @@ export default {
     pleaseInputContent: '请输入内容',
     relation: '关系',
     reset: '重置',
-    desc: '描述'
+    desc: '描述',
+    upload: 'Upload'
   },
 
   filter: {

+ 7 - 2
src/lang/zh.js

@@ -97,7 +97,11 @@ export default {
     modifiedBy: '更新人',
     modifiedTime: '更新时间',
     status: '类型',
-    adLocation: '位置'
+    adLocation: '位置',
+    selectData: '所选数据',
+    add: '添加数据',
+    hide: '展示',
+    unhide: '不展示'
   },
   documentation: {
     documentation: '文档',
@@ -230,7 +234,8 @@ export default {
     pleaseInputContent: '请输入内容',
     relation: '关系',
     reset: '重置',
-    desc: '描述'
+    desc: '描述',
+    upload: '上传'
   },
 
   filter: {

+ 30 - 2
src/router/index.js

@@ -172,15 +172,43 @@ export const asyncRoutes = [
       {
         path: 'location',
         component: () => import('@/views/ad/index'),
-        name: 'Ad Location',
+        name: 'ad-location',
         meta: { title: 'adLocation', icon: 'user', noCache: true }
       },
       {
         path: 'list/:ID(\\w+)',
         component: () => import('@/views/ad/list'),
-        name: 'Ad List',
+        name: 'ad-list',
         meta: { title: 'adList', noCache: true, activeMenu: '/ad/location' },
         hidden: true
+      },
+      {
+        path: 'edit/:ID(\\w+)',
+        component: () => import('@/views/ad/edit'),
+        name: 'ad-edit',
+        meta: { title: 'adEdit', noCache: true, activeMenu: '/ad/location' },
+        hidden: true
+      },
+      {
+        path: 'add',
+        component: () => import('@/views/ad/edit'),
+        name: 'ad-add',
+        meta: { title: 'adAdd', noCache: true, activeMenu: '/ad/location' },
+        hidden: true
+      }
+    ]
+  },
+  {
+    path: '/log',
+    component: Layout,
+    redirect: '/log/admin-login',
+    hidden: true,
+    children: [
+      {
+        path: 'admin-login',
+        component: () => import('@/views/log/admin-login'),
+        name: 'admin-login',
+        meta: { title: 'admin-login', icon: 'user', noCache: true }
       }
     ]
   },

+ 166 - 0
src/views/ad/edit.vue

@@ -0,0 +1,166 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <el-form ref="form" :model="form" label-width="250px" class="form-page">
+        <el-form-item :label="$t('ad.adTitle')">
+          <el-input v-model="form.title" />
+        </el-form-item>
+        <el-form-item :label="$t('ad.adLocation')">
+          <el-select v-model="form.lid" placeholder="Select Type"> <!-- 请选择广告类型 -->
+            <el-option
+              v-for="item in allLocation"
+              :key="item.ID"
+              :label="item.LOCATION_NAME"
+              :value="item.ID"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item :label="$t('ad.type')"> <!-- 广告类型 -->
+          <el-select v-model="form.type" placeholder="Select Type" style="width: 400px;"> <!-- 请选择广告类型 -->
+            <el-option :key="1" label="External Link" value="1" /> <!-- 外链 -->
+            <el-option :key="2" label="Article" value="2" /> <!-- 文章 -->
+          </el-select>
+        </el-form-item>
+        <el-form-item v-if="form.type==='1'" label="Url"> <!-- '链接地址' '文章ID' -->
+          <el-input v-model="url" style="width: 400px;" />
+          <span class="note" /> <!-- 注:外链请明确输入 http://或https://,文章则不需要输入 -->
+        </el-form-item>
+        <el-form-item :label="$t('ad.article')">
+          <el-select v-model="article" placeholder="Select Article"> <!-- 请选择广告类型 -->
+            <el-option
+              v-for="item in allArticle"
+              :key="item.ID"
+              :label="item.TITLE"
+              :value="item.ID"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item :label="$t('ad.image')" prop="image">
+          <Upload
+            v-model="form.image"
+            :request-route="'v1/ad/upload'"
+            :default-image-url="defaultImageUrl"
+            width="400px"
+            height="160px"
+            @on-success="handleSuccess"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" :loading="submitButtonStat" @click="onSubmit">{{ $t('common.save') }}</el-button>
+        </el-form-item>
+        </el-form-item></el-form>
+    </div>
+  </div>
+</template>
+
+<script>
+import { fetchDetail, fetchEdit, fetchAdd } from '@/api/ad'
+import tool from '@/utils/tool'
+import Upload from '@/components/Upload'
+export default {
+  name: 'RoleAdd',
+  components: { Upload },
+  data() {
+    return {
+      allLocation: null,
+      form: {
+        content: '',
+        image: '',
+        lid: '',
+        title: '',
+        type: ''
+      },
+      url: '',
+      article: '',
+      allArticle: '',
+      loading: false,
+      submitButtonStat: false,
+      defaultImageUrl: null
+    }
+  },
+  watch: {
+    'form.type': {
+      deep: true,
+      handler: function handler(modern) {
+        if (modern === '1') {
+          this.article = ''
+        } else {
+          this.url = ''
+        }
+      }
+    }
+  },
+  mounted() {
+    if (this.$route.name === 'ad-edit') {
+      fetchDetail(this.$route.params.ID).then(response => {
+        this.form.title = response.data.oneData.TITLE
+        this.allLocation = response.data.allLocation
+        this.form.lid = response.data.oneData.LID
+        this.form.type = response.data.oneData.TYPE
+        this.allArticle = response.data.allArticle
+        this.form.image = response.data.oneData.IMAGE
+        this.form.content = response.data.oneData.CONTENT
+        this.defaultImageUrl = tool.getArImage(response.data.oneData.IMAGE, '/files/')
+        if (response.data.oneData.TYPE === '1') {
+          this.url = response.data.oneData.CONTENT
+        } else {
+          this.article = response.data.oneData.CONTENT
+        }
+        this.loading = false
+      }).catch(err => {
+        console.log('err---------' + err)
+      })
+    } else {
+      fetchDetail(this.$route.params.ID).then(response => {
+        this.allLocation = response.data.allLocation
+        this.allArticle = response.data.allArticle
+
+        this.loading = false
+      }).catch(err => {
+        console.log('err---------' + err)
+      })
+    }
+  },
+  methods: {
+    onSubmit() {
+      this.form.content = this.form.type === '1' ? this.url : this.article
+      this.submitButtonStat = true
+      if (this.$route.name === 'ad-edit') {
+        fetchEdit(this.$route.params.ID, this.form).then(response => {
+          this.submitButtonStat = false
+          console.log(response)
+          this.$message({
+            message: response.data,
+            type: "$t('common.successfully')"
+          })
+          this.$router.go(-1)
+        }).catch(err => {
+          console.log('err---------' + err)
+        })
+      } else {
+        console.log(this.form)
+        fetchAdd(this.form).then(response => {
+          this.submitButtonStat = false
+          console.log(response)
+          this.$message({
+            message: response.data,
+            type: 'success'
+          })
+          this.$router.go(-1)
+        }).catch(err => {
+          console.log('err---------' + err)
+        })
+      }
+    },
+    handleSuccess(imageUrl) {
+      this.imageAd = imageUrl
+      this.form.image = tool.getArImage(imageUrl, '/files/')
+      this.defaultImageUrl = tool.getArImage(imageUrl, '/files/')
+    }
+  }
+}
+</script>
+
+  <style scoped>
+
+  </style>

+ 2 - 2
src/views/ad/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="app-container">
+  <div class="white-box">
     <el-table
       :key="tableKey"
       v-loading="listLoading"
@@ -55,7 +55,7 @@
 
     <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
   </div>
-</template>
+  </div></template>
 
 <script>
 import { fetchList } from '@/api/ad'

+ 227 - 82
src/views/ad/list.vue

@@ -1,95 +1,131 @@
 <template>
-  <div class="app-container">
-    <el-table
-      :key="tableKey"
-      v-loading="listLoading"
-      :data="list"
-      border
-      fit
-      highlight-current-row
-      style="width: 100%;"
-    >
-      <el-table-column :label="$t('ad.adTitle')" prop="id" align="center" :class-name="getSortClass('id')">
-        <template slot-scope="{row}">
-          <span>{{ row.TITLE }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column :label="$t('ad.adLocation')" prop="id" align="center" :class-name="getSortClass('id')">
-        <template :value="{allLocation}">
-          <span>{{ allLocation.LOCATION_NAME }}</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">External Links</el-tag> <!-- 外链 -->
+  <div class="white-box">
+    <div class="filter-box">
+      <el-table
+        :key="tableKey"
+        v-loading="listLoading"
+        :data="list"
+        border
+        fit
+        highlight-current-row
+        style="width: 100%;"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column type="selection" width="55" />
+        <el-table-column :label="$t('ad.adTitle')" prop="id" align="center" :class-name="getSortClass('id')">
+          <template slot-scope="{row}">
+            <span>{{ row.TITLE }}</span>
           </template>
-          <template v-else-if="row.TYPE === '2'">
-            <el-tag>Article</el-tag> <!-- 文章 -->
+        </el-table-column>
+        <el-table-column :label="$t('ad.adLocation')" prop="id" align="center" :class-name="getSortClass('id')">
+          <template :value="{allLocation}">
+            <span>{{ allLocation.LOCATION_NAME }}</span>
           </template>
-        </template>
-      </el-table-column>
-      <el-table-column :label="$t('ad.content')" prop="id" align="center" :class-name="getSortClass('id')">
-        <template slot-scope="{row}">
-          <div v-if="row.TYPE === '1'">
-            <el-link type="primary" target="_blank" :href="getHref(row.CONTENT)">{{ row.CONTENT }}</el-link>
-          </div><!-- 链接 -->
-          <div v-else-if="row.TYPE === '2'">
-            <router-link :to="`/article/detail/${row.CONTENT}`" target="_blank" style="cursor: pointer;">{{ getContent(row.CONTENT) }}</router-link>
-          </div><!-- 文章 -->
-        </template>
-      </el-table-column>
-      <el-table-column :label="$t('ad.sort')" prop="id" align="center" :class-name="getSortClass('id')">
-        <template slot-scope="{row}">
-          <el-input
-            v-model="row.SORT"
-            min="0"
-            max="99"
-            @change="handleChangeSort(row.ID, row.SORT)"
-            @click.native.stop=""
-          />
-        </template>
-      </el-table-column>
-      <el-table-column :label="$t('ad.creator')" prop="id" align="center" :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.modifiedBy')" prop="id" align="center" width="80" :class-name="getSortClass('id')">
-        <template slot-scope="{row}">
-          <span>{{ row.UPDATE_ADMIN_NAME }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column :label="$t('ad.modifiedTime')" align="center">
-        <template slot-scope="{row}">
-          <span>{{ row.UPDATED_AT | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column :label="$t('ad.status')" align="center"> <!-- 类型 -->
-        <template slot-scope="{row}">
-          <template v-if="row.STATUS === '1'">
-            <el-tag type="success">show</el-tag> <!-- 外链 -->
+        </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">External Links</el-tag> <!-- 外链 -->
+            </template>
+            <template v-else-if="row.TYPE === '2'">
+              <el-tag>Article</el-tag> <!-- 文章 -->
+            </template>
           </template>
-          <template v-else>
-            <el-tag>hide</el-tag> <!-- 文章 -->
+        </el-table-column>
+        <el-table-column :label="$t('ad.content')" prop="id" align="center" :class-name="getSortClass('id')">
+          <template slot-scope="{row}">
+            <div v-if="row.TYPE === '1'">
+              <el-link type="primary" target="_blank" :href="getHref(row.CONTENT)">{{ row.CONTENT }}</el-link>
+            </div><!-- 链接 -->
+            <div v-else-if="row.TYPE === '2'">
+              <router-link :to="`/article/detail/${row.CONTENT}`" target="_blank" style="cursor: pointer;">{{ getContent(row.CONTENT) }}</router-link>
+            </div><!-- 文章 -->
           </template>
-        </template>
-      </el-table-column>
-      <el-table-column :label="$t('ad.action')" align="center" class-name="small-padding fixed-width" />
-    </el-table>
-    <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.pageSize" @pagination="getList" />
+        </el-table-column>
+        <el-table-column :label="$t('ad.sort')" prop="id" align="center" :class-name="getSortClass('id')">
+          <template slot-scope="{row}">
+            <el-input
+              v-model="row.SORT"
+              min="0"
+              max="99"
+              @change="handleChangeSort(row.ID, row.SORT)"
+              @click.native.stop=""
+            />
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('ad.creator')" prop="id" align="center" :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.modifiedBy')" prop="id" align="center" width="80" :class-name="getSortClass('id')">
+          <template slot-scope="{row}">
+            <span>{{ row.UPDATE_ADMIN_NAME }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('ad.modifiedTime')" align="center">
+          <template slot-scope="{row}">
+            <span>{{ tool.formatDate(row.UPDATED_AT) }}</span>
+
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('ad.status')" align="center"> <!-- 类型 -->
+          <template slot-scope="{row}">
+            <template v-if="row.STATUS === '1'">
+              <el-tag type="success">show</el-tag> <!-- 外链 -->
+            </template>
+            <template v-else>
+              <el-tag>hide</el-tag> <!-- 文章 -->
+            </template>
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('ad.action')" align="center">
+
+          <template slot-scope="{row}">
+            <el-dropdown v-if="permission.hasPermission(`ad/ad-delete`) || permission.hasPermission(`ad/edit`)" size="small" trigger="click">
+              <el-button type="primary" size="small" @click.stop="">
+                {{ $t('ad.action') }}<i class="el-icon-arrow-down el-icon--right" />
+              </el-button>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item v-if="permission.hasPermission(`ad/edit`)" command="edit" @click.native="handleEdit(row)">{{ $t('common.edit') }}</el-dropdown-item>
+                <el-dropdown-item v-if="permission.hasPermission(`ad/ad-delete`)" command="delete" @click.native="handleDeleteOne(row)">{{ $t('common.delete') }}</el-dropdown-item>
+                <el-dropdown-item v-if="permission.hasPermission(`ad/ad-hide`)" command="hide" @click.native="handleHideOne(row)">{{ $t('ad.hide') }}</el-dropdown-item>
+                <el-dropdown-item v-if="permission.hasPermission(`ad/ad-un-hide`)" command="un-hide" @click.native="handleUnHideOne(row)">{{ $t('ad.unhide') }}</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="white-box-footer">
+        <el-dropdown v-if="permission.hasPermission(`ad/ad-delete`)" size="small">
+          <el-button type="primary" size="small">
+            {{ $t('ad.selectData') }}<i class="el-icon-arrow-down el-icon--right" />
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="delete" @click.native="handleMuliDel()">{{ $t('table.delete') }}</el-dropdown-item>
+            <el-dropdown-item command="hide" @click.native="handleMultiHide()">{{ $t('ad.hide') }}</el-dropdown-item>
+            <el-dropdown-item command="un-hide" @click.native="handleMultiUnHide()">{{ $t('ad.unhide') }}</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+        <el-button v-if="permission.hasPermission(`ad/ad-add`)" type="primary" size="small" icon="el-icon-plus" @click="handleAdd">{{ $t('ad.add') }}</el-button>
+        <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.pageSize" @pagination="getList" />
+      </div>
+
+      </el-table></div>
   </div>
 </template>
 
 <script>
-import { fetchAdList, fetchChangeSort } from '@/api/ad'
+import { fetchAdList, fetchChangeSort, fetchDelete, fetchHide, fetchUnhide } from '@/api/ad'
 import waves from '@/directive/waves' // waves directive
 import { parseTime } from '@/utils'
+import tool from '@/utils/tool'
+import permission from '@/utils/permission'
 import Pagination from '@/components/Pagination' // secondary package based on el-pagination
 
 const calendarTypeOptions = [
@@ -125,7 +161,11 @@ export default {
       tableKey: 0,
       list: null,
       total: 0,
+      loading: true,
       listLoading: true,
+      tool: tool,
+      permission: permission,
+      multipleSelection: null,
       listQuery: {
         page: 1,
         pageSize: 20,
@@ -135,7 +175,7 @@ export default {
         id: null,
         sort: null
       },
-      sort: '',
+      sort: null,
       importanceOptions: [1, 2, 3],
       calendarTypeOptions,
       sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
@@ -174,6 +214,9 @@ export default {
     this.getList()
   },
   methods: {
+    handleSelectionChange(val) {
+      this.multipleSelection = val
+    },
     getList() {
       this.listLoading = true
       this.listQuery.adId = this.$route.params
@@ -236,6 +279,108 @@ export default {
     },
     getHref(link) {
       return link.indexOf('http') > -1 ? link : 'http://' + link
+    },
+    handleEdit(row) {
+      this.$router.push({ path: `/ad/edit/${row.ID}` })
+    },
+    handleAdd() {
+      this.$router.push({ path: `/ad/add` })
+    },
+    handleMuliDel() {
+      this.handleDelete()
+    },
+    handleMultiHide() {
+      this.handleHide()
+    },
+    handleHideOne(row) {
+      this.handleHide(row.ID)
+    },
+    handleMultiUnHide() {
+      this.handleUnhide()
+    },
+    handleDeleteOne(row) {
+      this.handleDelete(row.ID)
+    },
+    handleDelete(id = null) {
+      const obj = this
+      obj.$confirm('Are you sure to delete the selected data?', 'Notice', { // 确定删除选定的数据?
+        confirmButtonText: 'confirm', // 确定
+        cancelButtonText: 'cancel', // 取消
+        type: 'warning'
+      }).then(() => {
+        const selectedIds = []
+        if (id === null) {
+          for (const val of obj.multipleSelection) {
+            selectedIds.push(val.ID)
+          }
+        } else {
+          selectedIds.push(id)
+        }
+        fetchDelete({ selected: selectedIds }).then(response => {
+          this.$message({
+            message: response.data,
+            type: 'success'
+          })
+          obj.getList(obj.currentPage, obj.pageSize)
+        }).catch(response => {
+
+        })
+      })
+    },
+    handleHide(id = null) {
+      const obj = this
+      obj.$confirm('Are you sure to hide the selected data?', 'Notice', { // 确定删除选定的数据?
+        confirmButtonText: 'confirm', // 确定
+        cancelButtonText: 'cancel', // 取消
+        type: 'warning'
+      }).then(() => {
+        const selectedIds = []
+        if (id === null) {
+          for (const val of obj.multipleSelection) {
+            selectedIds.push(val.ID)
+          }
+        } else {
+          selectedIds.push(id)
+        }
+        fetchHide({ selected: selectedIds }).then(response => {
+          this.$message({
+            message: response.data,
+            type: 'success'
+          })
+          obj.getList(obj.currentPage, obj.pageSize)
+        }).catch(response => {
+
+        })
+      })
+    },
+    handleUnHideOne(row) {
+      this.handleUnhide(row.ID)
+    },
+    handleUnhide(id = null) {
+      const obj = this
+      obj.$confirm('Are you sure to hide the selected data?', 'Notice', { // 确定删除选定的数据?
+        confirmButtonText: 'confirm', // 确定
+        cancelButtonText: 'cancel', // 取消
+        type: 'warning'
+      }).then(() => {
+        const selectedIds = []
+        if (id === null) {
+          for (const val of obj.multipleSelection) {
+            selectedIds.push(val.ID)
+          }
+        } else {
+          selectedIds.push(id)
+        }
+        fetchUnhide({ selected: selectedIds }).then(response => {
+          this.$message({
+            message: response.data,
+            type: 'success'
+          })
+          obj.getList(obj.currentPage, obj.pageSize)
+        }).catch(response => {
+
+        })
+      })
     }
   }
 }

+ 102 - 0
src/views/log/admin-login.vue

@@ -0,0 +1,102 @@
+<template>
+  <div class="white-box">
+    <div class="filter-box">
+      <filter-user
+        :filter-types.sync="filterTypes"
+        filter-btn-name="Select"
+        @select-value="handleFilterUser"
+      />
+    </div>
+    <el-table ref="multipleTable" :data="tableData" stripe style="width: 100%;" :height="tool.getTableHeight()">
+      <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
+        <template slot-scope="scope">
+          <template v-if="scope.row[tableHeader.index].other.tag">
+            <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null">{{ scope.row[tableHeader.index].value }}</el-tag>
+          </template>
+          <template v-else>
+            <div v-html="scope.row[tableHeader.index].value" />
+          </template>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="white-box-footer">
+      <pagination
+        :total="totalCount"
+        :page_size="pageSize"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import tool from '@/utils/tool'
+import permission from '@/utils/permission'
+import { fetchAdminLoginList } from '@/api/log'
+import filterHelper from '@/utils/filterHelper'
+import FilterUser from '@/components/FilterUser'
+import Pagination from '@/components/Pagination'
+
+export default {
+  name: 'LogAdminLogin',
+  components: { FilterUser, Pagination },
+  data() {
+    return {
+      tableHeaders: null,
+      allData: null,
+      tableData: null,
+      loading: true,
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      filterTypes: null,
+      filterModel: {}
+    }
+  },
+  mounted() {
+    this.getList()
+  },
+  methods: {
+    handleCurrentChange(page) {
+      this.getList(page, this.pageSize)
+    },
+    handleSizeChange(pageSize) {
+      this.getList(this.currentPage, pageSize)
+    },
+    handleFilterUser(filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    getList(page, pageSize) {
+      const filterData = this.filterModel
+      const vueObj = this
+      const paramsData = Object.assign({
+        page: (page === null || page === undefined) ? 1 : page,
+        pageSize: (pageSize === null || pageSize === undefined) ? vueObj.pageSize : pageSize
+      }, filterData)
+      fetchAdminLoginList(paramsData).then(response => {
+        vueObj.filterTypes = response.data.filterTypes
+        vueObj.tableData = response.data.list
+        vueObj.tableHeaders = response.data.columnsShow
+        vueObj.currentPage = page
+        vueObj.totalPages = parseInt(response.data.totalPages)
+        vueObj.totalCount = parseInt(response.data.totalCount)
+        vueObj.pageSize = pageSize
+        this.loading = false
+      })
+    },
+    handleFilter() {
+      this.listQuery.page = 1
+      this.getList()
+    }
+  }
+}
+
+</script>
+
+<style scoped>
+
+</style>