|
@@ -0,0 +1,457 @@
|
|
|
|
+<template>
|
|
|
|
+ <div class="app-container">
|
|
|
|
+ <!-- 顶部操作区域 -->
|
|
|
|
+ <div class="filter-container">
|
|
|
|
+ <div class="filter-control">
|
|
|
|
+ <span>标签:</span>
|
|
|
|
+ <el-input
|
|
|
|
+ v-model="listQuery.keyword"
|
|
|
|
+ placeholder="关键词"
|
|
|
|
+ clearable
|
|
|
|
+ @keyup.enter.native="getList"
|
|
|
|
+ @clear="getList"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="filter-control">
|
|
|
|
+ <el-button type="primary" @click="getList">查询</el-button>
|
|
|
|
+ <el-button v-permission="'tag:list:add'" type="primary" @click="selectionTagDialog = true">选择标签</el-button>
|
|
|
|
+ <el-button v-permission="'tag:list:del'" type="danger" :disabled="disabled" @click="handleDeleteTag">
|
|
|
|
+ 删除
|
|
|
|
+ </el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <!-- 关键词列表 -->
|
|
|
|
+ <el-table v-loading="isLoading" :data="list" border @selection-change="handleSelectionChange">
|
|
|
|
+ <el-table-column type="selection" width="55" align="center" />
|
|
|
|
+ <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 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 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>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table>
|
|
|
|
+
|
|
|
|
+ <!-- 页码 -->
|
|
|
|
+ <pagination
|
|
|
|
+ :total="total"
|
|
|
|
+ :page.sync="listQuery.pageNum"
|
|
|
|
+ :limit.sync="listQuery.pageSize"
|
|
|
|
+ @pagination="fetchKeywordList"
|
|
|
|
+ />
|
|
|
|
+
|
|
|
|
+ <!-- 选择标签 -->
|
|
|
|
+ <el-dialog
|
|
|
|
+ title="选择标签"
|
|
|
|
+ :visible.sync="selectionTagDialog"
|
|
|
|
+ width="1000px"
|
|
|
|
+ :close-on-click-modal="false"
|
|
|
|
+ :show-close="false"
|
|
|
|
+ >
|
|
|
|
+ <div class="filter-container">
|
|
|
|
+ <div class="filter-control">
|
|
|
|
+ <span>标签:</span>
|
|
|
|
+ <el-input
|
|
|
|
+ v-model="listQuery.keyword"
|
|
|
|
+ placeholder="标签"
|
|
|
|
+ clearable
|
|
|
|
+ @keyup.enter.native="getList"
|
|
|
|
+ @clear="getList"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="filter-control">
|
|
|
|
+ <el-button type="primary" @click="getList">查询</el-button>
|
|
|
|
+ <el-button type="primary" @click="handleAddTag">新增标签</el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <el-table ref="table" v-loading="isLoading" :data="supplierList" height="400px" border @selection-change="handleSelectionTagChange">
|
|
|
|
+ <el-table-column type="selection" width="55" />
|
|
|
|
+ <el-table-column prop="keyword" label="标签" align="center" />
|
|
|
|
+ <el-table-column prop="frequency" label="搜索次数" width="120" align="center" sortable />
|
|
|
|
+ <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>
|
|
|
|
+ <div slot="footer">
|
|
|
|
+ <el-button @click="selectionTagDialog = false">取 消</el-button>
|
|
|
|
+ <el-button type="primary" @click="handleSelectionTagConfirm">确 定</el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </el-dialog>
|
|
|
|
+
|
|
|
|
+ <!-- 添加标签 -->
|
|
|
|
+ <el-dialog
|
|
|
|
+ title="添加标签"
|
|
|
|
+ :visible.sync="addTagDialog"
|
|
|
|
+ width="460px"
|
|
|
|
+ :close-on-click-modal="false"
|
|
|
|
+ :show-close="false"
|
|
|
|
+ >
|
|
|
|
+ <el-form ref="tagForm" :model="tagForm" :rules="tagFormRules">
|
|
|
|
+ <el-form-item label="标签名:" prop="keyword">
|
|
|
|
+ <el-input v-model="tagForm.keyword" />
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-form>
|
|
|
|
+ <div slot="footer">
|
|
|
|
+ <el-button @click="closeAddTagDialog">取 消</el-button>
|
|
|
|
+ <el-button type="primary" @click="handleAddTagConfirm">确 定</el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </el-dialog>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+import { parseTime } from '@/utils'
|
|
|
|
+import { addKeyword, deleteKeyword, fetchKeywordList, importKeywordXlsx } from '@/api/library/keyword'
|
|
|
|
+import { export_json_to_excel } from '@/vendor/Export2Excel'
|
|
|
|
+export default {
|
|
|
|
+ data() {
|
|
|
|
+ const pickerOptions = {
|
|
|
|
+ shortcuts: [
|
|
|
|
+ {
|
|
|
|
+ text: '近1年',
|
|
|
|
+ onClick(picker) {
|
|
|
|
+ const end = new Date()
|
|
|
|
+ const start = new Date()
|
|
|
|
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 365)
|
|
|
|
+ picker.$emit('pick', [start, end])
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ text: '近半年',
|
|
|
|
+ onClick(picker) {
|
|
|
|
+ const end = new Date()
|
|
|
|
+ const start = new Date()
|
|
|
|
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 183)
|
|
|
|
+ picker.$emit('pick', [start, end])
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ text: '近1月',
|
|
|
|
+ onClick(picker) {
|
|
|
|
+ const end = new Date()
|
|
|
|
+ const start = new Date()
|
|
|
|
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
|
|
|
|
+ picker.$emit('pick', [start, end])
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ text: '近1周',
|
|
|
|
+ onClick(picker) {
|
|
|
|
+ const end = new Date()
|
|
|
|
+ const start = new Date()
|
|
|
|
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
|
|
|
|
+ picker.$emit('pick', [start, end])
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ text: '昨天',
|
|
|
|
+ onClick(picker) {
|
|
|
|
+ const end = new Date()
|
|
|
|
+ const start = new Date()
|
|
|
|
+ start.setTime(start.getTime() - 3600 * 1000 * 24)
|
|
|
|
+ picker.$emit('pick', [start, end])
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ ]
|
|
|
|
+ }
|
|
|
|
+ return {
|
|
|
|
+ isLoading: true,
|
|
|
|
+ pickerOptions,
|
|
|
|
+ time: '',
|
|
|
|
+ listQuery: {
|
|
|
|
+ keyword: '',
|
|
|
|
+ beginTime: '',
|
|
|
|
+ endTime: '',
|
|
|
|
+ labelStatus: 1,
|
|
|
|
+ searchTimeCode: '',
|
|
|
|
+ fromSearch: '',
|
|
|
|
+ pageNum: 1,
|
|
|
|
+ pageSize: 10
|
|
|
|
+ },
|
|
|
|
+ list: [],
|
|
|
|
+ total: 0,
|
|
|
|
+ currentList: [],
|
|
|
|
+ currentTabsList: [],
|
|
|
|
+ searchDialog: false,
|
|
|
|
+ visibleKeyword: '',
|
|
|
|
+ addTagDialog: false,
|
|
|
|
+ selectionTagDialog: false,
|
|
|
|
+ tagForm: {
|
|
|
|
+ keyword: ''
|
|
|
|
+ },
|
|
|
|
+ tagFormRules: {
|
|
|
|
+ keyword: [{ required: true, message: '请输入标签名称', trigger: ['blur'] }]
|
|
|
|
+ },
|
|
|
|
+ exportKeywordList: [],
|
|
|
|
+ importDialog: false,
|
|
|
|
+ fileList: [],
|
|
|
|
+ importForm: {
|
|
|
|
+ fileUrl: ''
|
|
|
|
+ },
|
|
|
|
+ importFormRules: {
|
|
|
|
+ fileUrl: [{ required: true, message: '文件不能为空', trigger: ['change'] }]
|
|
|
|
+ },
|
|
|
|
+ supplierList: [
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' },
|
|
|
|
+ { frequency: '45454', keyword: '综合供应商公司似手打发送到', searchTime: '2022-09-16 10:37:12', parseTime: '2022-09-16 10:37:12' }
|
|
|
|
+ ]
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ disabled() {
|
|
|
|
+ return this.currentList.length === 0
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ created() {
|
|
|
|
+ this.getList()
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ // 获取关键词列表
|
|
|
|
+ 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)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 选中标签项
|
|
|
|
+ handleSelectionTagChange(current) {
|
|
|
|
+ this.currentTabsList = current
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 选中列表项
|
|
|
|
+ handleSelectionChange(current) {
|
|
|
|
+ this.currentList = current
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 去搜索
|
|
|
|
+ handleSearch(keyword) {
|
|
|
|
+ this.visibleKeyword = keyword
|
|
|
|
+ this.searchDialog = true
|
|
|
|
+ },
|
|
|
|
+ // 添加标签
|
|
|
|
+ handleAddTag() {
|
|
|
|
+ this.selectionTagDialog = false
|
|
|
|
+ this.addTagDialog = true
|
|
|
|
+ },
|
|
|
|
+ // 添加标签取消
|
|
|
|
+ closeAddTagDialog() {
|
|
|
|
+ this.$refs.tagForm.resetFields()
|
|
|
|
+ this.addTagDialog = false
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 添加标签确定
|
|
|
|
+ async handleAddTagConfirm() {
|
|
|
|
+ try {
|
|
|
|
+ await this.$refs.tagForm.validate()
|
|
|
|
+ this.addTagSubmit()
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.log(error)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 选择标签确定
|
|
|
|
+ async handleSelectionTagConfirm() {
|
|
|
|
+ try {
|
|
|
|
+ await this.$refs.tagForm.validate()
|
|
|
|
+ this.addTagSubmit()
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.log(error)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 提交添加标签信息
|
|
|
|
+ async addTagSubmit() {
|
|
|
|
+ try {
|
|
|
|
+ await addKeyword(this.tagForm)
|
|
|
|
+ this.$message.success('添加标签成功')
|
|
|
|
+ this.getList()
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.log(error)
|
|
|
|
+ }
|
|
|
|
+ this.closeAddTagDialog()
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 删除标签
|
|
|
|
+ async handleDeleteTag(row) {
|
|
|
|
+ try {
|
|
|
|
+ await this.$confirm('确定删除已选标签?', {
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
+ cancelButtonText: '取消',
|
|
|
|
+ type: 'warning'
|
|
|
|
+ })
|
|
|
|
+ this.deleteTagSubmit(row)
|
|
|
|
+ } catch (error) {
|
|
|
|
+ this.$message.info('已取消删除操作')
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 提交删除标签操作
|
|
|
|
+ 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() {},
|
|
|
|
+
|
|
|
|
+ // 导入关键词取消
|
|
|
|
+ closeImportDialog() {
|
|
|
|
+ this.$refs.importForm.resetFields()
|
|
|
|
+ this.importDialog = false
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 导入关键词确定
|
|
|
|
+ async handleImportConfirm() {
|
|
|
|
+ console.log(1)
|
|
|
|
+ try {
|
|
|
|
+ await this.$refs.importForm.validate()
|
|
|
|
+ this.importSumbit()
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.log(error)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ 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() {
|
|
|
|
+ try {
|
|
|
|
+ await this.$confirm('确定将所选标签导出为xlsx?', {
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
+ cancelButtonText: '取消',
|
|
|
|
+ type: 'warning'
|
|
|
|
+ })
|
|
|
|
+ // 导出数据格式化
|
|
|
|
+ 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]
|
|
|
|
+ })
|
|
|
|
+ )
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 文件上传成功
|
|
|
|
+ handleUploadSuccess(response, file, fileList) {
|
|
|
|
+ this.importForm.fileUrl = response.url
|
|
|
|
+ this.fileList = fileList
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 上传文件删除
|
|
|
|
+ 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
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style></style>
|