|
@@ -9,13 +9,17 @@
|
|
|
@keyup.enter.native="handleQuery"
|
|
@keyup.enter.native="handleQuery"
|
|
|
/>
|
|
/>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
- <el-form-item label="封面图片" prop="imageUrl">
|
|
|
|
|
- <el-input
|
|
|
|
|
- v-model="queryParams.imageUrl"
|
|
|
|
|
- placeholder="请输入封面图片"
|
|
|
|
|
- clearable
|
|
|
|
|
- @keyup.enter.native="handleQuery"
|
|
|
|
|
- />
|
|
|
|
|
|
|
+ <el-form-item label="内容形式" prop="contentType">
|
|
|
|
|
+ <el-select v-model="queryParams.contentType" placeholder="请选择内容形式" clearable>
|
|
|
|
|
+ <el-option label="文章" value="article"></el-option>
|
|
|
|
|
+ <el-option label="视频" value="video"></el-option>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="内容分类" prop="contentCategory">
|
|
|
|
|
+ <el-select v-model="queryParams.contentCategory" placeholder="请选择内容分类" clearable>
|
|
|
|
|
+ <el-option label="农技知识" value="tech"></el-option>
|
|
|
|
|
+ <el-option label="政策解读" value="policy"></el-option>
|
|
|
|
|
+ </el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="来源" prop="source">
|
|
<el-form-item label="来源" prop="source">
|
|
|
<el-input
|
|
<el-input
|
|
@@ -25,30 +29,6 @@
|
|
|
@keyup.enter.native="handleQuery"
|
|
@keyup.enter.native="handleQuery"
|
|
|
/>
|
|
/>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
- <el-form-item label="阅读量" prop="viewCount">
|
|
|
|
|
- <el-input
|
|
|
|
|
- v-model="queryParams.viewCount"
|
|
|
|
|
- placeholder="请输入阅读量"
|
|
|
|
|
- clearable
|
|
|
|
|
- @keyup.enter.native="handleQuery"
|
|
|
|
|
- />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- <el-form-item label="视频链接,仅当类型为视频时有值" prop="videoUrl">
|
|
|
|
|
- <el-input
|
|
|
|
|
- v-model="queryParams.videoUrl"
|
|
|
|
|
- placeholder="请输入视频链接,仅当类型为视频时有值"
|
|
|
|
|
- clearable
|
|
|
|
|
- @keyup.enter.native="handleQuery"
|
|
|
|
|
- />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- <el-form-item label="视频时长,格式:MM:SS,仅当类型为视频时有值" prop="duration">
|
|
|
|
|
- <el-input
|
|
|
|
|
- v-model="queryParams.duration"
|
|
|
|
|
- placeholder="请输入视频时长,格式:MM:SS,仅当类型为视频时有值"
|
|
|
|
|
- clearable
|
|
|
|
|
- @keyup.enter.native="handleQuery"
|
|
|
|
|
- />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
<el-form-item label="作者" prop="author">
|
|
<el-form-item label="作者" prop="author">
|
|
|
<el-input
|
|
<el-input
|
|
|
v-model="queryParams.author"
|
|
v-model="queryParams.author"
|
|
@@ -57,13 +37,11 @@
|
|
|
@keyup.enter.native="handleQuery"
|
|
@keyup.enter.native="handleQuery"
|
|
|
/>
|
|
/>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
- <el-form-item label="发布时间" prop="publishDate">
|
|
|
|
|
- <el-date-picker clearable
|
|
|
|
|
- v-model="queryParams.publishDate"
|
|
|
|
|
- type="date"
|
|
|
|
|
- value-format="yyyy-MM-dd"
|
|
|
|
|
- placeholder="请选择发布时间">
|
|
|
|
|
- </el-date-picker>
|
|
|
|
|
|
|
+ <el-form-item label="发布状态" prop="status">
|
|
|
|
|
+ <el-select v-model="queryParams.status" placeholder="请选择发布状态" clearable>
|
|
|
|
|
+ <el-option label="已发布" :value="1"></el-option>
|
|
|
|
|
+ <el-option label="已下架" :value="0"></el-option>
|
|
|
|
|
+ </el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item>
|
|
<el-form-item>
|
|
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
@@ -71,6 +49,57 @@
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
|
|
|
|
|
|
|
+ <!-- 统计面板 -->
|
|
|
|
|
+ <div class="statistics-panel">
|
|
|
|
|
+ <el-row :gutter="12">
|
|
|
|
|
+ <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
|
|
|
|
|
+ <div class="stat-card total-card">
|
|
|
|
|
+ <div class="stat-content">
|
|
|
|
|
+ <div class="stat-title">内容总数</div>
|
|
|
|
|
+ <div class="stat-number">{{ statistics.totalCount || 0 }}</div>
|
|
|
|
|
+ <div class="stat-desc">累计内容数量</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
|
|
|
|
|
+ <div class="stat-card tech-card">
|
|
|
|
|
+ <div class="stat-content">
|
|
|
|
|
+ <div class="stat-title">农技知识</div>
|
|
|
|
|
+ <div class="stat-number">{{ statistics.techCount || 0 }}</div>
|
|
|
|
|
+ <div class="stat-desc">农业技术内容</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
|
|
|
|
|
+ <div class="stat-card policy-card">
|
|
|
|
|
+ <div class="stat-content">
|
|
|
|
|
+ <div class="stat-title">政策解读</div>
|
|
|
|
|
+ <div class="stat-number">{{ statistics.policyCount || 0 }}</div>
|
|
|
|
|
+ <div class="stat-desc">政策相关内容</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
|
|
|
|
|
+ <div class="stat-card published-card">
|
|
|
|
|
+ <div class="stat-content">
|
|
|
|
|
+ <div class="stat-title">已发布</div>
|
|
|
|
|
+ <div class="stat-number">{{ statistics.publishedCount || 0 }}</div>
|
|
|
|
|
+ <div class="stat-desc">正在展示中</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
|
|
|
|
|
+ <div class="stat-card draft-card">
|
|
|
|
|
+ <div class="stat-content">
|
|
|
|
|
+ <div class="stat-title">已下架</div>
|
|
|
|
|
+ <div class="stat-number">{{ statistics.draftCount || 0 }}</div>
|
|
|
|
|
+ <div class="stat-desc">待重新发布</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
<el-row :gutter="10" class="mb8">
|
|
<el-row :gutter="10" class="mb8">
|
|
|
<el-col :span="1.5">
|
|
<el-col :span="1.5">
|
|
|
<el-button
|
|
<el-button
|
|
@@ -119,34 +148,52 @@
|
|
|
|
|
|
|
|
<el-table v-loading="loading" :data="knowledgeContentList" @selection-change="handleSelectionChange">
|
|
<el-table v-loading="loading" :data="knowledgeContentList" @selection-change="handleSelectionChange">
|
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
|
- <el-table-column label="${comment}" align="center" prop="id" />
|
|
|
|
|
|
|
+ <el-table-column label="序号" align="center" width="80" type="index">
|
|
|
|
|
+ <template slot-scope="scope">
|
|
|
|
|
+ <span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
<el-table-column label="标题" align="center" prop="title" />
|
|
<el-table-column label="标题" align="center" prop="title" />
|
|
|
- <el-table-column label="描述" align="center" prop="description" />
|
|
|
|
|
- <el-table-column label="内容类型:文章或视频" align="center" prop="contentType" />
|
|
|
|
|
- <el-table-column label="内容分类:农技知识或政策解读" align="center" prop="contentCategory" />
|
|
|
|
|
- <el-table-column label="封面图片" align="center" prop="imageUrl" />
|
|
|
|
|
|
|
+ <el-table-column label="内容形式" align="center" prop="contentType">
|
|
|
|
|
+ <template slot-scope="scope">
|
|
|
|
|
+ <span>{{ scope.row.contentType === 'article' ? '文章' : scope.row.contentType === 'video' ? '视频' : scope.row.contentType }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="内容分类" align="center" prop="contentCategory">
|
|
|
|
|
+ <template slot-scope="scope">
|
|
|
|
|
+ <span>{{ scope.row.contentCategory === 'tech' ? '农技知识' : scope.row.contentCategory === 'policy' ? '政策解读' : scope.row.contentCategory }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
<el-table-column label="来源" align="center" prop="source" />
|
|
<el-table-column label="来源" align="center" prop="source" />
|
|
|
- <el-table-column label="阅读量" align="center" prop="viewCount" />
|
|
|
|
|
- <el-table-column label="视频链接,仅当类型为视频时有值" align="center" prop="videoUrl" />
|
|
|
|
|
- <el-table-column label="视频时长,格式:MM:SS,仅当类型为视频时有值" align="center" prop="duration" />
|
|
|
|
|
- <el-table-column label="文章内容,仅当类型为文章时有值" align="center" prop="articleContent" />
|
|
|
|
|
<el-table-column label="作者" align="center" prop="author" />
|
|
<el-table-column label="作者" align="center" prop="author" />
|
|
|
- <el-table-column label="标签,JSON数组格式" align="center" prop="tags" />
|
|
|
|
|
|
|
+ <el-table-column label="阅读量" align="center" prop="viewCount" />
|
|
|
<el-table-column label="发布时间" align="center" prop="publishDate" width="180">
|
|
<el-table-column label="发布时间" align="center" prop="publishDate" width="180">
|
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
|
<span>{{ parseTime(scope.row.publishDate, '{y}-{m}-{d}') }}</span>
|
|
<span>{{ parseTime(scope.row.publishDate, '{y}-{m}-{d}') }}</span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="状态:1启用,0禁用" align="center" prop="status" />
|
|
|
|
|
|
|
+ <el-table-column label="发布状态" align="center" prop="status">
|
|
|
|
|
+ <template slot-scope="scope">
|
|
|
|
|
+ <span>{{ scope.row.status === 1 ? '已发布' : scope.row.status === 0 ? '已下架' : scope.row.status }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
|
<el-button
|
|
<el-button
|
|
|
|
|
+ v-if="scope.row.status !== 1"
|
|
|
size="mini"
|
|
size="mini"
|
|
|
type="text"
|
|
type="text"
|
|
|
icon="el-icon-edit"
|
|
icon="el-icon-edit"
|
|
|
@click="handleUpdate(scope.row)"
|
|
@click="handleUpdate(scope.row)"
|
|
|
v-hasPermi="['base:knowledgeContent:edit']"
|
|
v-hasPermi="['base:knowledgeContent:edit']"
|
|
|
>修改</el-button>
|
|
>修改</el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ :icon="scope.row.status === 1 ? 'el-icon-bottom' : 'el-icon-top'"
|
|
|
|
|
+ @click="handleToggleStatus(scope.row)"
|
|
|
|
|
+ v-hasPermi="['base:knowledgeContent:edit']"
|
|
|
|
|
+ >{{ scope.row.status === 1 ? '下架' : '发布' }}</el-button>
|
|
|
<el-button
|
|
<el-button
|
|
|
size="mini"
|
|
size="mini"
|
|
|
type="text"
|
|
type="text"
|
|
@@ -167,47 +214,78 @@
|
|
|
/>
|
|
/>
|
|
|
|
|
|
|
|
<!-- 添加或修改农技知识管理对话框 -->
|
|
<!-- 添加或修改农技知识管理对话框 -->
|
|
|
- <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
|
|
|
|
- <el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
|
|
|
|
- <el-form-item label="标题" prop="title">
|
|
|
|
|
- <el-input v-model="form.title" placeholder="请输入标题" />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- <el-form-item label="描述" prop="description">
|
|
|
|
|
- <el-input v-model="form.description" type="textarea" placeholder="请输入内容" />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
|
|
+ <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
|
|
|
|
|
+ <el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="标题" prop="title">
|
|
|
|
|
+ <el-input v-model="form.title" placeholder="请输入标题" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="内容分类" prop="contentCategory">
|
|
|
|
|
+ <el-select v-model="form.contentCategory" placeholder="请选择内容分类" style="width: 100%">
|
|
|
|
|
+ <el-option label="农技知识" value="tech"></el-option>
|
|
|
|
|
+ <el-option label="政策解读" value="policy"></el-option>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="内容形式" prop="contentType">
|
|
|
|
|
+ <el-select v-model="form.contentType" placeholder="请选择内容形式" style="width: 100%" @change="handleContentTypeChange">
|
|
|
|
|
+ <el-option label="文章" value="article"></el-option>
|
|
|
|
|
+ <el-option label="视频" value="video"></el-option>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="来源" prop="source">
|
|
|
|
|
+ <el-input v-model="form.source" placeholder="请输入来源" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="作者" prop="author">
|
|
|
|
|
+ <el-input v-model="form.author" placeholder="请输入作者" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="发布时间" prop="publishDate">
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="form.publishDate"
|
|
|
|
|
+ type="datetime"
|
|
|
|
|
+ value-format="yyyy-MM-dd HH:mm:ss"
|
|
|
|
|
+ placeholder="请选择发布时间"
|
|
|
|
|
+ style="width: 100%">
|
|
|
|
|
+ </el-date-picker>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+
|
|
|
<el-form-item label="封面图片" prop="imageUrl">
|
|
<el-form-item label="封面图片" prop="imageUrl">
|
|
|
- <el-input v-model="form.imageUrl" placeholder="请输入封面图片" />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- <el-form-item label="来源" prop="source">
|
|
|
|
|
- <el-input v-model="form.source" placeholder="请输入来源" />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- <el-form-item label="阅读量" prop="viewCount">
|
|
|
|
|
- <el-input v-model="form.viewCount" placeholder="请输入阅读量" />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- <el-form-item label="视频链接,仅当类型为视频时有值" prop="videoUrl">
|
|
|
|
|
- <el-input v-model="form.videoUrl" placeholder="请输入视频链接,仅当类型为视频时有值" />
|
|
|
|
|
|
|
+ <image-upload v-model="form.imageUrl" :limit="1" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
- <el-form-item label="视频时长,格式:MM:SS,仅当类型为视频时有值" prop="duration">
|
|
|
|
|
- <el-input v-model="form.duration" placeholder="请输入视频时长,格式:MM:SS,仅当类型为视频时有值" />
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item v-if="form.contentType === 'video'" label="视频上传" prop="videoUrl">
|
|
|
|
|
+ <file-upload v-model="form.videoUrl" :fileType="['mp4', 'avi', 'mov', 'wmv']" :fileSize="500" :limit="1" />
|
|
|
|
|
+ <div style="color: #999; font-size: 12px; margin-top: 5px;">支持格式:MP4、AVI、MOV、WMV,大小不超过500MB</div>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
- <el-form-item label="文章内容,仅当类型为文章时有值">
|
|
|
|
|
- <editor v-model="form.articleContent" :min-height="192"/>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- <el-form-item label="作者" prop="author">
|
|
|
|
|
- <el-input v-model="form.author" placeholder="请输入作者" />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- <el-form-item label="发布时间" prop="publishDate">
|
|
|
|
|
- <el-date-picker clearable
|
|
|
|
|
- v-model="form.publishDate"
|
|
|
|
|
- type="date"
|
|
|
|
|
- value-format="yyyy-MM-dd"
|
|
|
|
|
- placeholder="请选择发布时间">
|
|
|
|
|
- </el-date-picker>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item v-if="form.contentType === 'article'" label="文章内容" prop="articleContent">
|
|
|
|
|
+ <div class="editor-container">
|
|
|
|
|
+ <editor v-model="form.articleContent" :min-height="300" />
|
|
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
|
|
+
|
|
|
<div slot="footer" class="dialog-footer">
|
|
<div slot="footer" class="dialog-footer">
|
|
|
- <el-button type="primary" @click="submitForm">确 定</el-button>
|
|
|
|
|
- <el-button @click="cancel">取 消</el-button>
|
|
|
|
|
|
|
+ <el-button type="primary" @click="submitForm">发布</el-button>
|
|
|
|
|
+ <el-button @click="cancel">取消</el-button>
|
|
|
</div>
|
|
</div>
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
</div>
|
|
</div>
|
|
@@ -234,6 +312,14 @@ export default {
|
|
|
total: 0,
|
|
total: 0,
|
|
|
// 农技知识管理表格数据
|
|
// 农技知识管理表格数据
|
|
|
knowledgeContentList: [],
|
|
knowledgeContentList: [],
|
|
|
|
|
+ // 统计数据
|
|
|
|
|
+ statistics: {
|
|
|
|
|
+ totalCount: 0,
|
|
|
|
|
+ techCount: 0,
|
|
|
|
|
+ policyCount: 0,
|
|
|
|
|
+ publishedCount: 0,
|
|
|
|
|
+ draftCount: 0
|
|
|
|
|
+ },
|
|
|
// 弹出层标题
|
|
// 弹出层标题
|
|
|
title: "",
|
|
title: "",
|
|
|
// 是否显示弹出层
|
|
// 是否显示弹出层
|
|
@@ -265,19 +351,32 @@ export default {
|
|
|
{ required: true, message: "标题不能为空", trigger: "blur" }
|
|
{ required: true, message: "标题不能为空", trigger: "blur" }
|
|
|
],
|
|
],
|
|
|
contentType: [
|
|
contentType: [
|
|
|
- { required: true, message: "内容类型:文章或视频不能为空", trigger: "change" }
|
|
|
|
|
|
|
+ { required: true, message: "内容形式不能为空", trigger: "change" }
|
|
|
],
|
|
],
|
|
|
contentCategory: [
|
|
contentCategory: [
|
|
|
- { required: true, message: "内容分类:农技知识或政策解读不能为空", trigger: "blur" }
|
|
|
|
|
|
|
+ { required: true, message: "内容分类不能为空", trigger: "change" }
|
|
|
|
|
+ ],
|
|
|
|
|
+ source: [
|
|
|
|
|
+ { required: true, message: "来源不能为空", trigger: "blur" }
|
|
|
|
|
+ ],
|
|
|
|
|
+ author: [
|
|
|
|
|
+ { required: true, message: "作者不能为空", trigger: "blur" }
|
|
|
],
|
|
],
|
|
|
imageUrl: [
|
|
imageUrl: [
|
|
|
- { required: true, message: "封面图片不能为空", trigger: "blur" }
|
|
|
|
|
|
|
+ { required: true, message: "封面图片不能为空", trigger: "change" }
|
|
|
|
|
+ ],
|
|
|
|
|
+ articleContent: [
|
|
|
|
|
+ { required: true, message: "文章内容不能为空", trigger: "blur" }
|
|
|
],
|
|
],
|
|
|
|
|
+ publishDate: [
|
|
|
|
|
+ { required: true, message: "发布时间不能为空", trigger: "change" }
|
|
|
|
|
+ ]
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
created() {
|
|
created() {
|
|
|
this.getList()
|
|
this.getList()
|
|
|
|
|
+ this.getStatistics()
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
/** 查询农技知识管理列表 */
|
|
/** 查询农技知识管理列表 */
|
|
@@ -289,6 +388,29 @@ export default {
|
|
|
this.loading = false
|
|
this.loading = false
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
+ /** 获取统计数据 */
|
|
|
|
|
+ getStatistics() {
|
|
|
|
|
+ // 这里可以调用专门的统计API,目前先用列表数据计算
|
|
|
|
|
+ listKnowledgeContent({}).then(response => {
|
|
|
|
|
+ const data = response.rows || []
|
|
|
|
|
+
|
|
|
|
|
+ this.statistics = {
|
|
|
|
|
+ totalCount: data.length,
|
|
|
|
|
+ techCount: data.filter(item => item.contentCategory === 'tech').length,
|
|
|
|
|
+ policyCount: data.filter(item => item.contentCategory === 'policy').length,
|
|
|
|
|
+ publishedCount: data.filter(item => item.status === 1).length,
|
|
|
|
|
+ draftCount: data.filter(item => item.status === 0).length
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(() => {
|
|
|
|
|
+ this.statistics = {
|
|
|
|
|
+ totalCount: 0,
|
|
|
|
|
+ techCount: 0,
|
|
|
|
|
+ policyCount: 0,
|
|
|
|
|
+ publishedCount: 0,
|
|
|
|
|
+ draftCount: 0
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
// 取消按钮
|
|
// 取消按钮
|
|
|
cancel() {
|
|
cancel() {
|
|
|
this.open = false
|
|
this.open = false
|
|
@@ -300,7 +422,7 @@ export default {
|
|
|
id: null,
|
|
id: null,
|
|
|
title: null,
|
|
title: null,
|
|
|
description: null,
|
|
description: null,
|
|
|
- contentType: null,
|
|
|
|
|
|
|
+ contentType: 'article', // 默认选中文章
|
|
|
contentCategory: null,
|
|
contentCategory: null,
|
|
|
imageUrl: null,
|
|
imageUrl: null,
|
|
|
source: null,
|
|
source: null,
|
|
@@ -349,21 +471,38 @@ export default {
|
|
|
this.title = "修改农技知识管理"
|
|
this.title = "修改农技知识管理"
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
+ /** 内容形式变化处理 */
|
|
|
|
|
+ handleContentTypeChange(value) {
|
|
|
|
|
+ // 切换到文章时清空视频相关字段
|
|
|
|
|
+ if (value === 'article') {
|
|
|
|
|
+ this.form.videoUrl = null
|
|
|
|
|
+ this.form.duration = null
|
|
|
|
|
+ }
|
|
|
|
|
+ // 切换到视频时清空文章内容
|
|
|
|
|
+ else if (value === 'video') {
|
|
|
|
|
+ this.form.articleContent = null
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
/** 提交按钮 */
|
|
/** 提交按钮 */
|
|
|
submitForm() {
|
|
submitForm() {
|
|
|
this.$refs["form"].validate(valid => {
|
|
this.$refs["form"].validate(valid => {
|
|
|
if (valid) {
|
|
if (valid) {
|
|
|
|
|
+ // 设置发布状态为已发布
|
|
|
|
|
+ this.form.status = 1
|
|
|
|
|
+
|
|
|
if (this.form.id != null) {
|
|
if (this.form.id != null) {
|
|
|
updateKnowledgeContent(this.form).then(response => {
|
|
updateKnowledgeContent(this.form).then(response => {
|
|
|
- this.$modal.msgSuccess("修改成功")
|
|
|
|
|
|
|
+ this.$modal.msgSuccess("发布成功")
|
|
|
this.open = false
|
|
this.open = false
|
|
|
this.getList()
|
|
this.getList()
|
|
|
|
|
+ this.getStatistics()
|
|
|
})
|
|
})
|
|
|
} else {
|
|
} else {
|
|
|
addKnowledgeContent(this.form).then(response => {
|
|
addKnowledgeContent(this.form).then(response => {
|
|
|
- this.$modal.msgSuccess("新增成功")
|
|
|
|
|
|
|
+ this.$modal.msgSuccess("发布成功")
|
|
|
this.open = false
|
|
this.open = false
|
|
|
this.getList()
|
|
this.getList()
|
|
|
|
|
+ this.getStatistics()
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -376,6 +515,7 @@ export default {
|
|
|
return delKnowledgeContent(ids)
|
|
return delKnowledgeContent(ids)
|
|
|
}).then(() => {
|
|
}).then(() => {
|
|
|
this.getList()
|
|
this.getList()
|
|
|
|
|
+ this.getStatistics()
|
|
|
this.$modal.msgSuccess("删除成功")
|
|
this.$modal.msgSuccess("删除成功")
|
|
|
}).catch(() => {})
|
|
}).catch(() => {})
|
|
|
},
|
|
},
|
|
@@ -384,7 +524,220 @@ export default {
|
|
|
this.download('base/knowledgeContent/export', {
|
|
this.download('base/knowledgeContent/export', {
|
|
|
...this.queryParams
|
|
...this.queryParams
|
|
|
}, `knowledgeContent_${new Date().getTime()}.xlsx`)
|
|
}, `knowledgeContent_${new Date().getTime()}.xlsx`)
|
|
|
|
|
+ },
|
|
|
|
|
+ /** 发布/下架状态切换 */
|
|
|
|
|
+ handleToggleStatus(row) {
|
|
|
|
|
+ const statusText = row.status === 1 ? '下架' : '发布'
|
|
|
|
|
+ const newStatus = row.status === 1 ? 0 : 1
|
|
|
|
|
+ this.$modal.confirm('确认要' + statusText + '该农技知识吗?').then(function() {
|
|
|
|
|
+ return updateKnowledgeContent({ ...row, status: newStatus })
|
|
|
|
|
+ }).then(() => {
|
|
|
|
|
+ this.getList()
|
|
|
|
|
+ this.getStatistics()
|
|
|
|
|
+ this.$modal.msgSuccess(statusText + "成功")
|
|
|
|
|
+ }).catch(() => {})
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+.article-content-cell {
|
|
|
|
|
+ max-width: 180px;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+ line-height: 1.5;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.editor-container {
|
|
|
|
|
+ max-height: 400px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.editor-container::-webkit-scrollbar {
|
|
|
|
|
+ width: 6px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.editor-container::-webkit-scrollbar-track {
|
|
|
|
|
+ background: #f1f1f1;
|
|
|
|
|
+ border-radius: 3px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.editor-container::-webkit-scrollbar-thumb {
|
|
|
|
|
+ background: #c1c1c1;
|
|
|
|
|
+ border-radius: 3px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.editor-container::-webkit-scrollbar-thumb:hover {
|
|
|
|
|
+ background: #a8a8a8;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 统计面板样式 */
|
|
|
|
|
+.statistics-panel {
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+ padding: 20px;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.statistics-panel .el-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.statistics-panel .el-col {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ max-width: none !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 统一各部分间距 */
|
|
|
|
|
+.app-container .el-form {
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.app-container .mb8 {
|
|
|
|
|
+ margin-bottom: 16px !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.app-container .el-table {
|
|
|
|
|
+ margin-top: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.stat-card {
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ padding: 16px;
|
|
|
|
|
+ height: 120px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.05);
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.stat-card:hover {
|
|
|
|
|
+ transform: translateY(-3px);
|
|
|
|
|
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15), 0 4px 10px rgba(0, 0, 0, 0.1);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.stat-content {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.stat-title {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: rgba(255, 255, 255, 0.9);
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
|
|
+ line-height: 1.2;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.stat-number {
|
|
|
|
|
+ font-size: 32px;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+ line-height: 1.0;
|
|
|
|
|
+ margin: 6px 0;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.stat-desc {
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ color: rgba(255, 255, 255, 0.85);
|
|
|
|
|
+ line-height: 1.2;
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 不同卡片的主题色 */
|
|
|
|
|
+.total-card {
|
|
|
|
|
+ background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.tech-card {
|
|
|
|
|
+ background: linear-gradient(135deg, #10b981 0%, #34d399 100%);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.policy-card {
|
|
|
|
|
+ background: linear-gradient(135deg, #f59e0b 0%, #fbbf24 100%);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.published-card {
|
|
|
|
|
+ background: linear-gradient(135deg, #ec4899 0%, #f472b6 100%);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.draft-card {
|
|
|
|
|
+ background: linear-gradient(135deg, #06b6d4 0%, #38bdf8 100%);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 响应式设计 */
|
|
|
|
|
+@media (max-width: 1200px) {
|
|
|
|
|
+ .stat-card {
|
|
|
|
|
+ padding: 14px;
|
|
|
|
|
+ height: 110px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .stat-title {
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .stat-number {
|
|
|
|
|
+ font-size: 28px;
|
|
|
|
|
+ margin: 4px 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .stat-desc {
|
|
|
|
|
+ font-size: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@media (max-width: 992px) {
|
|
|
|
|
+ .stat-card {
|
|
|
|
|
+ padding: 16px;
|
|
|
|
|
+ height: 120px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .stat-title {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .stat-number {
|
|
|
|
|
+ font-size: 30px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .stat-desc {
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@media (max-width: 768px) {
|
|
|
|
|
+ .stat-card {
|
|
|
|
|
+ padding: 20px;
|
|
|
|
|
+ height: 140px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .stat-title {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .stat-number {
|
|
|
|
|
+ font-size: 36px;
|
|
|
|
|
+ margin: 8px 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .stat-desc {
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|