|
|
@@ -14,6 +14,33 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
+ <!-- Search form -->
|
|
|
+ <div class="search-container">
|
|
|
+ <el-form :model="searchForm" label-width="100px" class="search-form">
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-col :span="5">
|
|
|
+ <el-form-item label="来源名称">
|
|
|
+ <el-input v-model="searchForm.sourceName" placeholder="请输入来源" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="5">
|
|
|
+ <el-form-item label="来源类型">
|
|
|
+ <el-select v-model="searchForm.sourceType" clearable placeholder="请选择来源类型">
|
|
|
+ <el-option label="网站" :value="1" />
|
|
|
+ <el-option label="公众号" :value="2" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="14" class="search-actions">
|
|
|
+ <el-form-item label=" ">
|
|
|
+ <el-button type="primary" @click="handleSearch">搜索</el-button>
|
|
|
+ <el-button @click="resetSearch">重置</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+
|
|
|
<!-- Sources table -->
|
|
|
<el-table
|
|
|
:data="sources"
|
|
|
@@ -31,23 +58,24 @@
|
|
|
{{ (pagination.currentPage - 1) * pagination.pageSize + scope.$index + 1 }}
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="name" label="名称" min-width="150"></el-table-column>
|
|
|
- <el-table-column label="类型" width="120">
|
|
|
+ <el-table-column prop="sourceName" label="来源名称" min-width="150"></el-table-column>
|
|
|
+ <el-table-column label="来源类型" width="150">
|
|
|
<template #default="scope">
|
|
|
- <el-tag :type="scope.row.type === 'website' ? 'primary' : 'success'">
|
|
|
- {{ scope.row.type === 'website' ? '网站' : '公众号' }}
|
|
|
+ <el-tag :type="scope.row.sourceType === 1 ? 'primary' : 'success'">
|
|
|
+ {{ scope.row.sourceType === 1 ? '网站' : '公众号' }}
|
|
|
</el-tag>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="default_category_name" label="默认分类" width="150"></el-table-column>
|
|
|
- <el-table-column prop="url" label="链接" min-width="200">
|
|
|
+ <el-table-column prop="fakeId" label="公众号唯一标识" width="150"></el-table-column>
|
|
|
+ <el-table-column prop="sourceUrl" label="来源网址" min-width="150">
|
|
|
<template #default="scope">
|
|
|
- <el-link :href="scope.row.url" target="_blank" :underline="false">
|
|
|
- {{ scope.row.url }}
|
|
|
+ <el-link :href="scope.row.sourceUrl" target="_blank" :underline="false">
|
|
|
+ {{ scope.row.sourceUrl }}
|
|
|
</el-link>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="操作" width="150" fixed="right">
|
|
|
+ <el-table-column prop="categoryName" label="类别名称" width="180"></el-table-column>
|
|
|
+ <el-table-column label="操作" width="180" fixed="right">
|
|
|
<template #default="scope">
|
|
|
<el-button size="small" @click="editSource(scope.row)">编辑</el-button>
|
|
|
<el-button size="small" type="danger" @click="deleteSource(scope.row)">删除</el-button>
|
|
|
@@ -73,16 +101,16 @@
|
|
|
<el-dialog v-model="dialogVisible" :title="isEditing ? '编辑来源' : '添加来源'" width="500px">
|
|
|
<el-form :model="currentSource" label-width="100px">
|
|
|
<el-form-item label="名称">
|
|
|
- <el-input v-model="currentSource.name" placeholder="请输入名称" />
|
|
|
+ <el-input v-model="currentSource.sourceName" placeholder="请输入名称" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="类型">
|
|
|
- <el-select v-model="currentSource.type" placeholder="请选择类型">
|
|
|
- <el-option label="网站" value="website" />
|
|
|
- <el-option label="公众号" value="official_account" />
|
|
|
+ <el-select v-model="currentSource.sourceType" placeholder="请选择类型">
|
|
|
+ <el-option label="网站" :value="1" />
|
|
|
+ <el-option label="公众号" :value="2" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="默认分类">
|
|
|
- <el-select v-model="currentSource.default_category_id" placeholder="请选择默认分类">
|
|
|
+ <el-select v-model="currentSource.categoryId" clearable placeholder="请选择默认分类">
|
|
|
<el-option
|
|
|
v-for="category in categories"
|
|
|
:key="category.id"
|
|
|
@@ -92,7 +120,23 @@
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="链接">
|
|
|
- <el-input v-model="currentSource.url" placeholder="请输入链接" />
|
|
|
+ <el-input v-model="currentSource.sourceUrl" placeholder="请输入链接" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="公众号唯一标识" v-if="currentSource.sourceType==2">
|
|
|
+ <el-input v-model="currentSource.fakeId" placeholder="请输入公众号唯一标识" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="配置方法">
|
|
|
+ <el-select v-model="currentSource.configId" clearable placeholder="请选择配置方法">
|
|
|
+ <el-option
|
|
|
+ v-for="configuration in configurations"
|
|
|
+ :key="configuration.id"
|
|
|
+ :label="configuration.configName"
|
|
|
+ :value="configuration.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="配置关键词">
|
|
|
+ <el-input v-model="currentSource.configKey" placeholder="请输入配置关键词" />
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
<template #footer>
|
|
|
@@ -106,26 +150,52 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, onMounted } from 'vue'
|
|
|
-import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
+import { ref, onMounted,reactive } from 'vue'
|
|
|
+import { ElMessage, ElMessageBox,ElLoading } from 'element-plus'
|
|
|
import { Link, Plus, Refresh } from '@element-plus/icons-vue'
|
|
|
-import type { Source, Category } from '@/types'
|
|
|
-import { sourceApi, categoryApi } from '@/services/api'
|
|
|
+import type { Source, Category,Configuration } from '@/types'
|
|
|
+import { sourceApi, categoryApi,configApi } from '@/services/api'
|
|
|
|
|
|
// State
|
|
|
const sources = ref<Source[]>([])
|
|
|
const categories = ref<Category[]>([])
|
|
|
+const configurations = ref<Configuration[]>([])
|
|
|
const loading = ref(false)
|
|
|
const dialogVisible = ref(false)
|
|
|
const isEditing = ref(false)
|
|
|
|
|
|
const currentSource = ref<Source>({
|
|
|
- id: 0,
|
|
|
- name: '',
|
|
|
- type: 'website',
|
|
|
- default_category_id: 0,
|
|
|
- default_category_name: '',
|
|
|
- url: ''
|
|
|
+ sourceInfoId: null,
|
|
|
+ sourceName: '',
|
|
|
+ sourceType: 1,
|
|
|
+ categoryId: null,
|
|
|
+ categoryName: '',
|
|
|
+ sourceUrl: '',
|
|
|
+ configId: null,
|
|
|
+ configValue: '',
|
|
|
+ configName: '',
|
|
|
+ configKey:''
|
|
|
+})
|
|
|
+
|
|
|
+const handleSearch = () => {
|
|
|
+ // 重置到第一页
|
|
|
+ pagination.value.currentPage = 1
|
|
|
+ fetchSources()
|
|
|
+}
|
|
|
+
|
|
|
+const resetSearch = () => {
|
|
|
+ // 重置搜索表单
|
|
|
+ searchForm.sourceName = ''
|
|
|
+ searchForm.sourceType = null
|
|
|
+ // 重置到第一页
|
|
|
+ pagination.value.currentPage = 1
|
|
|
+ fetchSources()
|
|
|
+}
|
|
|
+
|
|
|
+// Search form
|
|
|
+const searchForm = reactive({
|
|
|
+ sourceName: '',
|
|
|
+ sourceType: null as number | null,
|
|
|
})
|
|
|
|
|
|
const pagination = ref({
|
|
|
@@ -135,16 +205,18 @@ const pagination = ref({
|
|
|
})
|
|
|
|
|
|
const fetchSources = async () => {
|
|
|
+
|
|
|
loading.value = true
|
|
|
try {
|
|
|
- const response = await sourceApi.getSources(
|
|
|
- pagination.value.currentPage,
|
|
|
- pagination.value.pageSize
|
|
|
- )
|
|
|
- sources.value = response.data
|
|
|
- // 获取总数
|
|
|
- const countResponse = await sourceApi.getSourcesCount()
|
|
|
- pagination.value.total = countResponse.data.count
|
|
|
+ // 构造搜索参数
|
|
|
+ const params: any = {
|
|
|
+ pageNum: pagination.value.currentPage,
|
|
|
+ pageSize: pagination.value.pageSize,
|
|
|
+ ...searchForm,
|
|
|
+ }
|
|
|
+ const response = await sourceApi.getSources(params)
|
|
|
+ sources.value = response.data.data
|
|
|
+ pagination.value.total = response.data.total
|
|
|
} catch (error) {
|
|
|
ElMessage.error('获取来源列表失败')
|
|
|
} finally {
|
|
|
@@ -155,23 +227,33 @@ const fetchSources = async () => {
|
|
|
const fetchCategories = async () => {
|
|
|
try {
|
|
|
// 获取所有分类,不分页
|
|
|
- const response = await categoryApi.getCategories()
|
|
|
- categories.value = response.data
|
|
|
+ const response = await categoryApi.getCategories({})
|
|
|
+ categories.value = response.data.data
|
|
|
} catch (error) {
|
|
|
ElMessage.error('获取分类列表失败')
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+const fetchConfigurations = async () => {
|
|
|
+ try {
|
|
|
+ // 获取所有分类,不分页
|
|
|
+ const response = await configApi.getConfigurations({})
|
|
|
+ configurations.value = response.data
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('获取配置列表失败')
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
const saveSource = async () => {
|
|
|
try {
|
|
|
- if (!currentSource.value.name || !currentSource.value.url) {
|
|
|
+ if (!currentSource.value.sourceName || !currentSource.value.sourceUrl) {
|
|
|
ElMessage.warning('请填写必填项')
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// Find the category name for the selected category ID
|
|
|
const selectedCategory = categories.value.find(
|
|
|
- category => category.id === currentSource.value.default_category_id
|
|
|
+ category => category.id === currentSource.value.categoryId
|
|
|
)
|
|
|
|
|
|
if (!selectedCategory) {
|
|
|
@@ -182,16 +264,12 @@ const saveSource = async () => {
|
|
|
// Add category name to the source object
|
|
|
const sourceToSave = {
|
|
|
...currentSource.value,
|
|
|
- default_category_name: selectedCategory.name
|
|
|
+ categoryName: selectedCategory.name
|
|
|
}
|
|
|
-
|
|
|
+ await sourceApi.createSource(sourceToSave)
|
|
|
if (isEditing.value) {
|
|
|
- // Update existing source
|
|
|
- await sourceApi.updateSource(currentSource.value.id, sourceToSave)
|
|
|
ElMessage.success('来源更新成功')
|
|
|
} else {
|
|
|
- // Create new source
|
|
|
- await sourceApi.createSource(sourceToSave)
|
|
|
ElMessage.success('来源添加成功')
|
|
|
}
|
|
|
|
|
|
@@ -208,7 +286,10 @@ const deleteSource = async (source: Source) => {
|
|
|
type: 'warning'
|
|
|
})
|
|
|
|
|
|
- await sourceApi.deleteSource(source.id)
|
|
|
+ const params = {
|
|
|
+ sourceInfoId: source.sourceInfoId,
|
|
|
+ }
|
|
|
+ await sourceApi.deleteSource(params)
|
|
|
ElMessage.success('来源删除成功')
|
|
|
fetchSources()
|
|
|
} catch (error) {
|
|
|
@@ -231,12 +312,16 @@ const handleCurrentChange = (val: number) => {
|
|
|
|
|
|
const showAddDialog = () => {
|
|
|
currentSource.value = {
|
|
|
- id: 0,
|
|
|
- name: '',
|
|
|
- type: 'website',
|
|
|
- default_category_id: 0,
|
|
|
- default_category_name: '',
|
|
|
- url: ''
|
|
|
+ sourceInfoId: null,
|
|
|
+ sourceName: '',
|
|
|
+ sourceType: 1,
|
|
|
+ categoryId: null,
|
|
|
+ categoryName: '',
|
|
|
+ sourceUrl: '',
|
|
|
+ configId: null,
|
|
|
+ configValue: '',
|
|
|
+ configName: '',
|
|
|
+ configKey:''
|
|
|
}
|
|
|
isEditing.value = false
|
|
|
dialogVisible.value = true
|
|
|
@@ -249,9 +334,22 @@ const editSource = (source: Source) => {
|
|
|
}
|
|
|
|
|
|
// Lifecycle
|
|
|
-onMounted(() => {
|
|
|
- fetchSources()
|
|
|
- fetchCategories()
|
|
|
+onMounted(async () => {
|
|
|
+ // fetchSources()
|
|
|
+ // fetchCategories()
|
|
|
+ // fetchConfigurations()
|
|
|
+ // 并行发起所有请求
|
|
|
+ const loadingInstance = ElLoading.service({
|
|
|
+ lock: true,
|
|
|
+ });
|
|
|
+ try{
|
|
|
+ await Promise.all([fetchSources(),fetchCategories(),fetchConfigurations()]);
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('请求失败');
|
|
|
+ } finally {
|
|
|
+ loadingInstance.close();
|
|
|
+ }
|
|
|
+
|
|
|
})
|
|
|
</script>
|
|
|
|