|
@@ -4,20 +4,26 @@
|
|
|
<div class="filter-container">
|
|
|
<div class="filter-control">
|
|
|
<span>关键词:</span>
|
|
|
- <el-input v-model="listQuery.keyword" placeholder="关键词" @keyup.enter.native="getList" />
|
|
|
+ <el-input
|
|
|
+ v-model="listQuery.keyword"
|
|
|
+ placeholder="关键词"
|
|
|
+ clearable
|
|
|
+ @keyup.enter.native="getList"
|
|
|
+ @clear="getList"
|
|
|
+ />
|
|
|
</div>
|
|
|
<div class="filter-control">
|
|
|
<span>来源:</span>
|
|
|
- <el-select v-model="listQuery.status" clearable @change="getList">
|
|
|
- <el-option :value="0" label="手动添加" />
|
|
|
- <el-option :value="1" label="用户关键词统计" />
|
|
|
- <el-option :value="2" label="导入" />
|
|
|
+ <el-select v-model="listQuery.fromSearch" clearable @change="getList">
|
|
|
+ <el-option :value="1" label="单个添加" />
|
|
|
+ <el-option :value="2" label="系统推荐" />
|
|
|
+ <el-option :value="3" label="导入" />
|
|
|
</el-select>
|
|
|
</div>
|
|
|
<div class="filter-control">
|
|
|
<span>搜索统计:</span>
|
|
|
<el-date-picker
|
|
|
- v-model="listQuery.time"
|
|
|
+ v-model="time"
|
|
|
type="daterange"
|
|
|
unlink-panels
|
|
|
range-separator="至"
|
|
@@ -30,38 +36,57 @@
|
|
|
<div class="filter-control">
|
|
|
<el-button type="primary" @click="getList">查询</el-button>
|
|
|
<el-button v-permission="'tag:list:add'" type="primary" @click="handleAddTag">添加标签</el-button>
|
|
|
- <el-button v-permission="'tag:list:del'" type="danger" :disabled="disabled" @click="handleDeleteTag">删除</el-button>
|
|
|
- <el-button v-permission="'tag:list:improt'" type="primary" @click="importDialog = true">导入</el-button>
|
|
|
- <el-button v-permission="'tag:list:export'" type="primary" @click="handleExport">导出</el-button>
|
|
|
+ <el-button v-permission="'tag:list:del'" type="danger" :disabled="disabled" @click="handleDeleteTag">
|
|
|
+ 删除
|
|
|
+ </el-button>
|
|
|
+ <el-button v-permission="'tag:list:improt'" type="primary" @click="importDialog = true"> 导入 </el-button>
|
|
|
+ <el-button v-permission="'tag:list:export'" type="primary" :disabled="disabled" @click="handleExport">导出</el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 关键词列表 -->
|
|
|
- <el-table :data="list" border @selection-change="handleSelectionChange">
|
|
|
+ <el-table v-loading="isLoading" :data="list" border @selection-change="handleSelectionChange">
|
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
|
- <el-table-column prop="name" label="序号" width="100" align="center" />
|
|
|
- <el-table-column prop="name" label="关键词" align="center" />
|
|
|
- <el-table-column prop="count" label="搜索次数" width="120" align="center" sortable />
|
|
|
+ <el-table-column label="序号" :index="indexMethod" type="index" sortable="custom" align="center" width="80" />
|
|
|
+ <el-table-column prop="keyword" label="关键词" align="center" />
|
|
|
+ <el-table-column prop="frequency" label="搜索次数" width="120" align="center" sortable />
|
|
|
<el-table-column width="180" label="来源" align="center">
|
|
|
- <template>单个添加</template>
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <span v-if="row.fromSearch === 1">单个添加</span>
|
|
|
+ <span v-else-if="row.fromSearch === 2">系统推荐</span>
|
|
|
+ <span v-else>导入</span>
|
|
|
+ </template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="name" label="最近搜索时间" align="center" width="160" />
|
|
|
- <el-table-column width="140" label="标签库状态" align="center">
|
|
|
- <template>未添加</template>
|
|
|
+ <el-table-column label="最近搜索时间" align="center" width="200">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <span v-if="row.searchTime">{{ row.searchTime | parseTime }}</span>
|
|
|
+ <span v-else>-</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="添加时间" align="center" width="200">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <span v-if="row.searchTime">{{ row.searchTime | parseTime }}</span>
|
|
|
+ <span v-else>-</span>
|
|
|
+ </template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" align="center" width="240">
|
|
|
<template slot-scope="{ row }">
|
|
|
<el-button v-permission="'tag:list:del'" type="danger" size="mini" @click="handleDeleteTag(row)">删除</el-button>
|
|
|
- <el-button type="primary" size="mini" @click="searchDialog = true">去搜索</el-button>
|
|
|
+ <el-button type="primary" size="mini" @click="handleSearch(row.keyword)">去搜索</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
|
|
|
<!-- 页码 -->
|
|
|
- <pagination :total="total" :page.sync="listQuery.pageNum" :limit.sync="listQuery.pageSize" @pagination="getList" />
|
|
|
+ <pagination
|
|
|
+ :total="total"
|
|
|
+ :page.sync="listQuery.pageNum"
|
|
|
+ :limit.sync="listQuery.pageSize"
|
|
|
+ @pagination="fetchKeywordList"
|
|
|
+ />
|
|
|
|
|
|
<!-- 去搜索跳转 -->
|
|
|
- <SearchModel v-model="searchDialog" @click="handleSearch" />
|
|
|
+ <SearchModel v-model="searchDialog" :keyword="visibleKeyword" />
|
|
|
|
|
|
<!-- 添加标签 -->
|
|
|
<el-dialog
|
|
@@ -72,8 +97,8 @@
|
|
|
:show-close="false"
|
|
|
>
|
|
|
<el-form ref="tagForm" :model="tagForm" :rules="tagFormRules">
|
|
|
- <el-form-item label="标签名:" prop="name">
|
|
|
- <el-input v-model="tagForm.name" />
|
|
|
+ <el-form-item label="标签名:" prop="keyword">
|
|
|
+ <el-input v-model="tagForm.keyword" />
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
<div slot="footer">
|
|
@@ -100,6 +125,8 @@
|
|
|
:file-list="fileList"
|
|
|
:on-success="handleUploadSuccess"
|
|
|
:on-remove="handleUploadRemove"
|
|
|
+ :on-change="handleUploadChange"
|
|
|
+ :auto-upload="false"
|
|
|
>
|
|
|
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
|
|
|
<div slot="tip" class="el-upload__tip">只能上传.xlsx, .xls文件</div>
|
|
@@ -109,7 +136,7 @@
|
|
|
</el-form>
|
|
|
<div slot="footer">
|
|
|
<el-button @click="closeImportDialog">取 消</el-button>
|
|
|
- <el-button type="primary" @click="handleImportConfirm">导 入</el-button>
|
|
|
+ <el-button v-debounce="handleImportConfirm" type="primary">导 入</el-button>
|
|
|
</div>
|
|
|
</el-dialog>
|
|
|
</div>
|
|
@@ -117,7 +144,9 @@
|
|
|
|
|
|
<script>
|
|
|
import SearchModel from '@/components/SearchModel'
|
|
|
-import { downloadWithUrl } from '@/utils'
|
|
|
+import { parseTime } from '@/utils'
|
|
|
+import { addKeyword, deleteKeyword, fetchKeywordList, importKeywordXlsx } from '@/api/library/keyword'
|
|
|
+import { export_json_to_excel } from '@/vendor/Export2Excel'
|
|
|
export default {
|
|
|
components: { SearchModel },
|
|
|
data() {
|
|
@@ -171,24 +200,30 @@ export default {
|
|
|
]
|
|
|
}
|
|
|
return {
|
|
|
+ isLoading: true,
|
|
|
pickerOptions,
|
|
|
+ time: '',
|
|
|
listQuery: {
|
|
|
- pageNum: 1,
|
|
|
- pageSize: 10,
|
|
|
keyword: '',
|
|
|
- time: '',
|
|
|
- status: ''
|
|
|
+ beginTime: '',
|
|
|
+ endTime: '',
|
|
|
+ labelStatus: 1,
|
|
|
+ searchTimeCode: '',
|
|
|
+ fromSearch: '',
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10
|
|
|
},
|
|
|
list: [],
|
|
|
total: 0,
|
|
|
currentList: [],
|
|
|
searchDialog: false,
|
|
|
+ visibleKeyword: '',
|
|
|
addTagDialog: false,
|
|
|
tagForm: {
|
|
|
- name: ''
|
|
|
+ keyword: ''
|
|
|
},
|
|
|
tagFormRules: {
|
|
|
- name: [{ required: true, message: '请输入标签名称', trigger: ['blur'] }]
|
|
|
+ keyword: [{ required: true, message: '请输入标签名称', trigger: ['blur'] }]
|
|
|
},
|
|
|
exportKeywordList: [],
|
|
|
importDialog: false,
|
|
@@ -206,16 +241,45 @@ export default {
|
|
|
return this.currentList.length === 0
|
|
|
}
|
|
|
},
|
|
|
+ created() {
|
|
|
+ this.getList()
|
|
|
+ },
|
|
|
methods: {
|
|
|
// 获取关键词列表
|
|
|
- getList() {},
|
|
|
+ getList() {
|
|
|
+ this.listQuery.pageNum = 1
|
|
|
+ if (this.time && this.time.length > 0) {
|
|
|
+ this.listQuery.beginTime = this.time[0]
|
|
|
+ this.listQuery.endTime = this.time[1]
|
|
|
+ } else {
|
|
|
+ this.listQuery.beginTime = ''
|
|
|
+ this.listQuery.endTime = ''
|
|
|
+ }
|
|
|
+ this.fetchKeywordList()
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取关键词列表
|
|
|
+ async fetchKeywordList() {
|
|
|
+ try {
|
|
|
+ this.isLoading = true
|
|
|
+ const res = await fetchKeywordList(this.listQuery)
|
|
|
+ this.list = res.data.results
|
|
|
+ this.total = res.data.totalRecord
|
|
|
+ this.isLoading = false
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
// 选中列表项
|
|
|
- handleSelectionChange() {},
|
|
|
+ handleSelectionChange(current) {
|
|
|
+ this.currentList = current
|
|
|
+ },
|
|
|
|
|
|
// 去搜索
|
|
|
- handleSearch(type) {
|
|
|
- this.searchDialog = false
|
|
|
+ handleSearch(keyword) {
|
|
|
+ this.visibleKeyword = keyword
|
|
|
+ this.searchDialog = true
|
|
|
},
|
|
|
|
|
|
// 添加标签
|
|
@@ -240,7 +304,14 @@ export default {
|
|
|
},
|
|
|
|
|
|
// 提交添加标签信息
|
|
|
- addTagSubmit() {
|
|
|
+ async addTagSubmit() {
|
|
|
+ try {
|
|
|
+ await addKeyword(this.tagForm)
|
|
|
+ this.$message.success('添加标签成功')
|
|
|
+ this.getList()
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
this.closeAddTagDialog()
|
|
|
},
|
|
|
|
|
@@ -259,7 +330,17 @@ export default {
|
|
|
},
|
|
|
|
|
|
// 提交删除标签操作
|
|
|
- deleteTagSubmit(row) {},
|
|
|
+ async deleteTagSubmit(row) {
|
|
|
+ const keywords = row instanceof Event ? this.currentList : [].concat(row)
|
|
|
+ const ids = keywords.map((item) => item.id).join(',')
|
|
|
+ try {
|
|
|
+ await deleteKeyword({ id: ids })
|
|
|
+ this.$message.success('已忽略所选关键词')
|
|
|
+ this.getList()
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
// 导入关键词
|
|
|
async handleImport() {},
|
|
@@ -272,6 +353,7 @@ export default {
|
|
|
|
|
|
// 导入关键词确定
|
|
|
async handleImportConfirm() {
|
|
|
+ console.log(1)
|
|
|
try {
|
|
|
await this.$refs.importForm.validate()
|
|
|
this.importSumbit()
|
|
@@ -280,35 +362,57 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
- importSumbit() {},
|
|
|
+ async importSumbit() {
|
|
|
+ const file = this.fileList.length > 0 && this.fileList[0]
|
|
|
+ if (!file) return
|
|
|
+ try {
|
|
|
+ const formData = new FormData()
|
|
|
+ this.fileList = []
|
|
|
+ this.importDialog = false
|
|
|
+ formData.append('keywordFile', file.raw)
|
|
|
+ await importKeywordXlsx(formData)
|
|
|
+ this.$message.success('导入标签成功')
|
|
|
+ this.getList()
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
// 导出
|
|
|
async handleExport() {
|
|
|
- const text = await this.$confirm(`确认导出全部关键词?`, '提示', {
|
|
|
- confirmButtonText: '确定',
|
|
|
- cancelButtonText: '取消',
|
|
|
- type: 'warning'
|
|
|
- }).catch(() => {
|
|
|
- this.$message.info('已取消操作')
|
|
|
- })
|
|
|
- if (text !== 'confirm') return
|
|
|
- let notification = null
|
|
|
- notification = this.$notify({
|
|
|
- title: '提示',
|
|
|
- message: `正在导出全部关键词,请勿重复操作!`,
|
|
|
- duration: 0
|
|
|
- })
|
|
|
- // 使用a链接下载
|
|
|
- const downUrl = `${process.env.VUE_APP_BASE_API}/download`
|
|
|
- downloadWithUrl(downUrl, '关键词')
|
|
|
- .catch((err) => {
|
|
|
- console.log(err)
|
|
|
- this.$message.error(`导出关键词失败`)
|
|
|
+ try {
|
|
|
+ await this.$confirm('确定将所选标签导出为xlsx?', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
})
|
|
|
- .finally(() => {
|
|
|
- notification.close()
|
|
|
- this.onSelectorCancel()
|
|
|
+ // 导出数据格式化
|
|
|
+ const filterVal = ['index', 'keyword', 'frequency', 'fromSearch', 'searchTime', 'addTime']
|
|
|
+ const data = this.formatJson(filterVal, this.currentList.slice(0))
|
|
|
+ export_json_to_excel({
|
|
|
+ header: ['序号', '标签', '搜索次数', '来源', '最近搜索时间', '添加时间'],
|
|
|
+ data,
|
|
|
+ filename: '标签列表'
|
|
|
})
|
|
|
+ } catch (error) {
|
|
|
+ this.$message.info('已取消导出操作')
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ formatJson(filterVal, jsonData) {
|
|
|
+ return jsonData.map((v, index) =>
|
|
|
+ filterVal.map((key) => {
|
|
|
+ if (['searchTime', 'addTime'].includes(key)) {
|
|
|
+ return parseTime(v[key])
|
|
|
+ }
|
|
|
+ if (key === 'index') return index + 1
|
|
|
+ if (key === 'fromSearch') {
|
|
|
+ const t = ['单个添加', '系统推荐', '导入']
|
|
|
+ return t[v[key] - 1]
|
|
|
+ }
|
|
|
+ return v[key]
|
|
|
+ })
|
|
|
+ )
|
|
|
},
|
|
|
|
|
|
// 文件上传成功
|
|
@@ -320,6 +424,15 @@ export default {
|
|
|
// 上传文件删除
|
|
|
handleUploadRemove(file, fileList) {
|
|
|
this.fileList = fileList
|
|
|
+ },
|
|
|
+
|
|
|
+ handleUploadChange(file, fileList) {
|
|
|
+ this.fileList = fileList
|
|
|
+ this.importForm.fileUrl = file.name
|
|
|
+ },
|
|
|
+
|
|
|
+ indexMethod(index) {
|
|
|
+ return index + this.listQuery.pageSize * (this.listQuery.pageNum - 1) + 1
|
|
|
}
|
|
|
}
|
|
|
}
|