实现敏感词检测后,失败发生邮箱
This commit is contained in:
46
schoolNewsWeb/src/apis/resource/sensitive.ts
Normal file
46
schoolNewsWeb/src/apis/resource/sensitive.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { api } from '@/apis';
|
||||
import type { ResultDomain, SensitiveWord, PageParam } from '@/types';
|
||||
|
||||
export const sensitiveApi = {
|
||||
/**
|
||||
* 获取敏感词列表
|
||||
* @returns Promise<ResultDomain<SensitiveWord>>
|
||||
*/
|
||||
async getSensitivePage(pageParam: PageParam, filter?: SensitiveWord): Promise<ResultDomain<SensitiveWord>> {
|
||||
const response = await api.post<SensitiveWord>('/sensitive/page', {
|
||||
pageParam,
|
||||
filter,
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* 添加敏感词
|
||||
* @param sensitiveWord 敏感词信息
|
||||
* @returns Promise<ResultDomain<SensitiveWord>>
|
||||
*/
|
||||
async addSensitiveWord(sensitiveWord: SensitiveWord): Promise<ResultDomain<SensitiveWord>> {
|
||||
const response = await api.post<SensitiveWord>('/sensitive', sensitiveWord);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* 修改敏感词类型
|
||||
* @param sensitiveWord 敏感词对象
|
||||
* @returns Promise<ResultDomain<boolean>>
|
||||
*/
|
||||
async changeSensitiveWordType(sensitiveWord: SensitiveWord): Promise<ResultDomain<boolean>> {
|
||||
const response = await api.put<boolean>(`/sensitive`, sensitiveWord);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除敏感词
|
||||
* @param sensitiveWord 敏感词对象
|
||||
* @returns Promise<ResultDomain<boolean>>
|
||||
*/
|
||||
async deleteSensitiveWord(sensitiveWord: SensitiveWord): Promise<ResultDomain<boolean>> {
|
||||
const response = await api.delete<boolean>(`/sensitive`, { data: sensitiveWord });
|
||||
return response.data;
|
||||
},
|
||||
}
|
||||
@@ -86,8 +86,12 @@ export enum ResourceStatus {
|
||||
PUBLISHED = 1,
|
||||
/** 下架 */
|
||||
OFFLINE = 2,
|
||||
/** 审核中 */
|
||||
REVIEWING = 3,
|
||||
/** 敏感词未通过 */
|
||||
SENSITIVE_FAILED = 4,
|
||||
/** 审核失败 */
|
||||
FAILED = 3
|
||||
FAILED = 5
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,12 +100,14 @@ export enum ResourceStatus {
|
||||
export enum CourseStatus {
|
||||
/** 未上线 */
|
||||
OFFLINE = 0,
|
||||
/** 已上线 */
|
||||
ONLINE = 1,
|
||||
/** 已下架 */
|
||||
/** 已发布 */
|
||||
PUBLISHED = 1,
|
||||
/** 下架 */
|
||||
DISABLED = 2,
|
||||
/** 审核失败 */
|
||||
FAILED = 3
|
||||
/** 审核中 */
|
||||
REVIEWING = 3,
|
||||
/** 敏感词未通过 */
|
||||
SENSITIVE_FAILED = 4
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -335,3 +335,12 @@ export interface ResourceStatistics {
|
||||
/** 总收藏数 */
|
||||
totalCollections?: number;
|
||||
}
|
||||
|
||||
|
||||
export interface SensitiveWord {
|
||||
id: number;
|
||||
/** 敏感词 */
|
||||
word: string;
|
||||
/** 敏感词类型 allow\deny*/
|
||||
type: string;
|
||||
}
|
||||
@@ -587,7 +587,7 @@ async function loadSelectOptions(reset = false) {
|
||||
// 加载资源列表
|
||||
result = await resourceApi.getResourcePage(
|
||||
selectPageParam.value,
|
||||
searchKeyword.value ? { keyword: searchKeyword.value } : undefined
|
||||
searchKeyword.value ? { title: searchKeyword.value } : undefined
|
||||
);
|
||||
} else if (currentBanner.value.linkType === 2) {
|
||||
// 加载课程列表
|
||||
|
||||
@@ -0,0 +1,377 @@
|
||||
<template>
|
||||
<div class="sensitive-management">
|
||||
<div class="header">
|
||||
<h2>敏感词管理</h2>
|
||||
<el-button type="primary" @click="showAddDialog">
|
||||
<el-icon><Plus /></el-icon>
|
||||
添加敏感词
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 搜索过滤区域 -->
|
||||
<div class="filter-section">
|
||||
<el-form :model="filterForm" inline>
|
||||
<el-form-item label="敏感词">
|
||||
<el-input
|
||||
v-model="filterForm.word"
|
||||
placeholder="请输入敏感词"
|
||||
clearable
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型">
|
||||
<el-select v-model="filterForm.type" class="sensitive-type-selector" placeholder="请选择类型" clearable>
|
||||
<el-option label="禁用词" value="deny" />
|
||||
<el-option label="允许词" value="allow" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="sensitiveList"
|
||||
style="width: 100%"
|
||||
border
|
||||
>
|
||||
<el-table-column prop="id" label="ID" width="80" />
|
||||
<el-table-column prop="word" label="敏感词" min-width="200" />
|
||||
<el-table-column prop="type" label="类型" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.type === 'deny' ? 'danger' : 'success'">
|
||||
{{ row.type === 'deny' ? '禁用词' : '允许词' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleChangeType(row)"
|
||||
>
|
||||
{{ row.type === 'deny' ? '改为允许' : '改为禁用' }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="handleDelete(row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
|
||||
<el-pagination
|
||||
class="pagination-container"
|
||||
v-model:current-page="pageParam.pageNumber"
|
||||
v-model:page-size="pageParam.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="pageParam.totalElements || 0"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 添加敏感词对话框 -->
|
||||
<el-dialog
|
||||
v-model="addDialogVisible"
|
||||
title="添加敏感词"
|
||||
width="500px"
|
||||
@close="resetAddForm"
|
||||
>
|
||||
<el-form
|
||||
ref="addFormRef"
|
||||
:model="addForm"
|
||||
:rules="addFormRules"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item label="敏感词" prop="word">
|
||||
<el-input
|
||||
v-model="addForm.word"
|
||||
placeholder="请输入敏感词"
|
||||
maxlength="50"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-radio-group v-model="addForm.type">
|
||||
<el-radio label="deny">禁用词</el-radio>
|
||||
<el-radio label="allow">允许词</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="addDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleAdd" :loading="addLoading">
|
||||
确定
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, reactive } from 'vue';
|
||||
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import { sensitiveApi } from '@/apis/resource/sensitive';
|
||||
import type { SensitiveWord, PageParam } from '@/types';
|
||||
|
||||
const loading = ref(false);
|
||||
const addLoading = ref(false);
|
||||
const addDialogVisible = ref(false);
|
||||
const addFormRef = ref<FormInstance>();
|
||||
|
||||
const pageParam = ref<PageParam>({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalElements: 0,
|
||||
});
|
||||
|
||||
const sensitiveList = ref<SensitiveWord[]>([]);
|
||||
|
||||
// 过滤表单
|
||||
const filterForm = reactive<Partial<SensitiveWord>>({
|
||||
word: '',
|
||||
type: '',
|
||||
});
|
||||
|
||||
// 添加表单
|
||||
const addForm = reactive<Partial<SensitiveWord>>({
|
||||
word: '',
|
||||
type: 'deny',
|
||||
});
|
||||
|
||||
// 添加表单验证规则
|
||||
const addFormRules: FormRules = {
|
||||
word: [
|
||||
{ required: true, message: '请输入敏感词', trigger: 'blur' },
|
||||
{ min: 1, max: 50, message: '敏感词长度在 1 到 50 个字符', trigger: 'blur' },
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: '请选择类型', trigger: 'change' },
|
||||
],
|
||||
};
|
||||
|
||||
// 获取敏感词分页数据
|
||||
async function getSensitivePage() {
|
||||
try {
|
||||
loading.value = true;
|
||||
const filter: Partial<SensitiveWord> = {};
|
||||
if (filterForm.word) filter.word = filterForm.word;
|
||||
if (filterForm.type) filter.type = filterForm.type;
|
||||
|
||||
const res = await sensitiveApi.getSensitivePage(pageParam.value, filter as SensitiveWord);
|
||||
|
||||
if (res.success) {
|
||||
pageParam.value.totalElements = res.pageDomain?.pageParam?.totalElements || 0;
|
||||
sensitiveList.value = res.pageDomain?.dataList || [];
|
||||
} else {
|
||||
ElMessage.error(res.message || '获取敏感词列表失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取敏感词列表失败:', error);
|
||||
ElMessage.error('获取敏感词列表失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function handleSearch() {
|
||||
pageParam.value.pageNumber = 1;
|
||||
getSensitivePage();
|
||||
}
|
||||
|
||||
// 重置搜索
|
||||
function handleReset() {
|
||||
Object.assign(filterForm, {
|
||||
word: '',
|
||||
type: '',
|
||||
});
|
||||
pageParam.value.pageNumber = 1;
|
||||
getSensitivePage();
|
||||
}
|
||||
|
||||
// 分页大小改变
|
||||
function handleSizeChange(size: number) {
|
||||
pageParam.value.pageSize = size;
|
||||
pageParam.value.pageNumber = 1;
|
||||
getSensitivePage();
|
||||
}
|
||||
|
||||
// 当前页改变
|
||||
function handleCurrentChange(page: number) {
|
||||
pageParam.value.pageNumber = page;
|
||||
getSensitivePage();
|
||||
}
|
||||
|
||||
// 显示添加对话框
|
||||
function showAddDialog() {
|
||||
addDialogVisible.value = true;
|
||||
}
|
||||
|
||||
// 重置添加表单
|
||||
function resetAddForm() {
|
||||
addFormRef.value?.resetFields();
|
||||
Object.assign(addForm, {
|
||||
word: '',
|
||||
type: 'deny',
|
||||
});
|
||||
}
|
||||
|
||||
// 添加敏感词
|
||||
async function handleAdd() {
|
||||
if (!addFormRef.value) return;
|
||||
|
||||
try {
|
||||
const valid = await addFormRef.value.validate();
|
||||
if (!valid) return;
|
||||
|
||||
addLoading.value = true;
|
||||
const res = await sensitiveApi.addSensitiveWord(addForm as SensitiveWord);
|
||||
|
||||
if (res.success) {
|
||||
ElMessage.success('添加敏感词成功');
|
||||
addDialogVisible.value = false;
|
||||
getSensitivePage();
|
||||
} else {
|
||||
ElMessage.error(res.message || '添加敏感词失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('添加敏感词失败:', error);
|
||||
ElMessage.error('添加敏感词失败');
|
||||
} finally {
|
||||
addLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 修改敏感词类型
|
||||
async function handleChangeType(row: SensitiveWord) {
|
||||
try {
|
||||
const newType = row.type === 'deny' ? 'allow' : 'deny';
|
||||
const typeText = newType === 'deny' ? '禁用词' : '允许词';
|
||||
|
||||
await ElMessageBox.confirm(
|
||||
`确定要将敏感词 "${row.word}" 改为${typeText}吗?`,
|
||||
'确认修改',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
);
|
||||
|
||||
const updateData = { ...row, type: newType };
|
||||
const res = await sensitiveApi.changeSensitiveWordType(updateData);
|
||||
|
||||
if (res.success) {
|
||||
ElMessage.success('修改敏感词类型成功');
|
||||
getSensitivePage();
|
||||
} else {
|
||||
ElMessage.error(res.message || '修改敏感词类型失败');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
console.error('修改敏感词类型失败:', error);
|
||||
ElMessage.error('修改敏感词类型失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除敏感词
|
||||
async function handleDelete(row: SensitiveWord) {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定要删除敏感词 "${row.word}" 吗?`,
|
||||
'确认删除',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
);
|
||||
|
||||
const res = await sensitiveApi.deleteSensitiveWord(row);
|
||||
|
||||
if (res.success) {
|
||||
ElMessage.success('删除敏感词成功');
|
||||
getSensitivePage();
|
||||
} else {
|
||||
ElMessage.error(res.message || '删除敏感词失败');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
console.error('删除敏感词失败:', error);
|
||||
ElMessage.error('删除敏感词失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getSensitivePage();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.sensitive-management {
|
||||
padding: 20px;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-section {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
|
||||
.sensitive-type-selector {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.table-section {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -81,7 +81,7 @@ import { useRouter } from 'vue-router';
|
||||
import { resourceApi, resourceTagApi } from '@/apis/resource'
|
||||
import type { PageParam, ResourceSearchParams, Resource, Tag } from '@/types';
|
||||
import { ArticleShowView } from '@/views/public/article';
|
||||
import { ArticleStatus } from '@/types/enums';
|
||||
import { ResourceStatus } from '@/types/enums';
|
||||
|
||||
const router = useRouter();
|
||||
const searchKeyword = ref('');
|
||||
@@ -166,8 +166,8 @@ function editArticle(row: any) {
|
||||
|
||||
async function changeArticleStatus(row: Resource) {
|
||||
try {
|
||||
// status: 0-草稿, 1-已发布, 2-已下架
|
||||
if (row.status === ArticleStatus.DRAFT || row.status === ArticleStatus.OFFLINE) {
|
||||
// status: 0-草稿, 1-已发布, 2-已下架, 3-审核中, 4-敏感词未通过
|
||||
if (row.status === ResourceStatus.DRAFT || row.status === ResourceStatus.OFFLINE || row.status === ResourceStatus.SENSITIVE_FAILED) {
|
||||
// 草稿或下架状态 -> 发布
|
||||
const res = await resourceApi.publishResource(row.resourceID!);
|
||||
if (res.success) {
|
||||
@@ -176,7 +176,7 @@ async function changeArticleStatus(row: Resource) {
|
||||
} else {
|
||||
ElMessage.error('发布失败');
|
||||
}
|
||||
} else if (row.status === ArticleStatus.PUBLISHED) {
|
||||
} else if (row.status === ResourceStatus.PUBLISHED) {
|
||||
// 已发布状态 -> 下架
|
||||
const res = await resourceApi.unpublishResource(row.resourceID!);
|
||||
if (res.success) {
|
||||
@@ -206,40 +206,44 @@ function deleteArticle() {
|
||||
|
||||
function getStatusType(status: number) {
|
||||
const typeMap: Record<number, any> = {
|
||||
[ArticleStatus.DRAFT]: 'info',
|
||||
[ArticleStatus.PUBLISHED]: 'success',
|
||||
[ArticleStatus.OFFLINE]: 'warning',
|
||||
[ArticleStatus.FAILED]: 'danger'
|
||||
[ResourceStatus.DRAFT]: 'info',
|
||||
[ResourceStatus.PUBLISHED]: 'success',
|
||||
[ResourceStatus.OFFLINE]: 'warning',
|
||||
[ResourceStatus.REVIEWING]: 'primary',
|
||||
[ResourceStatus.SENSITIVE_FAILED]: 'danger'
|
||||
};
|
||||
return typeMap[status] || 'info';
|
||||
}
|
||||
|
||||
function getStatusText(status: number) {
|
||||
const textMap: Record<number, string> = {
|
||||
[ArticleStatus.DRAFT]: '草稿',
|
||||
[ArticleStatus.PUBLISHED]: '已发布',
|
||||
[ArticleStatus.OFFLINE]: '已下架',
|
||||
[ArticleStatus.FAILED]: '审核失败'
|
||||
[ResourceStatus.DRAFT]: '草稿',
|
||||
[ResourceStatus.PUBLISHED]: '已发布',
|
||||
[ResourceStatus.OFFLINE]: '已下架',
|
||||
[ResourceStatus.REVIEWING]: '审核中',
|
||||
[ResourceStatus.SENSITIVE_FAILED]: '敏感词未通过'
|
||||
};
|
||||
return textMap[status] || '未知';
|
||||
}
|
||||
|
||||
function getActionButtonType(status: number) {
|
||||
// 草稿或下架状态显示主要按钮(发布), 已发布状态显示警告按钮(下架)
|
||||
if (status === ArticleStatus.DRAFT || status === ArticleStatus.OFFLINE || status === ArticleStatus.FAILED) {
|
||||
// 草稿、下架或敏感词未通过状态显示主要按钮(发布), 已发布状态显示警告按钮(下架)
|
||||
if (status === ResourceStatus.DRAFT || status === ResourceStatus.OFFLINE || status === ResourceStatus.SENSITIVE_FAILED) {
|
||||
return 'primary';
|
||||
} else if (status === ArticleStatus.PUBLISHED) {
|
||||
} else if (status === ResourceStatus.PUBLISHED) {
|
||||
return 'warning';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function getActionButtonText(status: number) {
|
||||
// 草稿或下架状态显示"发布", 已发布状态显示"下架"
|
||||
if (status === ArticleStatus.DRAFT || status === ArticleStatus.OFFLINE || status === ArticleStatus.FAILED) {
|
||||
// 草稿、下架或敏感词未通过状态显示"发布", 已发布状态显示"下架", 审核中状态不可操作
|
||||
if (status === ResourceStatus.DRAFT || status === ResourceStatus.OFFLINE || status === ResourceStatus.SENSITIVE_FAILED) {
|
||||
return '发布';
|
||||
} else if (status === ArticleStatus.PUBLISHED) {
|
||||
} else if (status === ResourceStatus.PUBLISHED) {
|
||||
return '下架';
|
||||
} else if (status === ResourceStatus.REVIEWING) {
|
||||
return '审核中';
|
||||
}
|
||||
return '操作';
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ async function handlePublish() {
|
||||
await formRef.value?.validate();
|
||||
publishing.value = true;
|
||||
|
||||
// 新建或“立即发布”时,明确标记为已发布
|
||||
// 新建或"立即发布"时,明确标记为已发布
|
||||
// 对新建文章:status 没有值,这里设为 1
|
||||
// 对草稿->发布:也会变成 1
|
||||
articleForm.value.resource.status = 1;
|
||||
@@ -233,18 +233,26 @@ async function handlePublish() {
|
||||
if (props.collectionItemId) {
|
||||
await handleConvertFromCollection();
|
||||
} else {
|
||||
const result = await resourceApi.createResource(articleForm.value);
|
||||
let result;
|
||||
if (isEdit.value) {
|
||||
// 编辑模式:调用更新接口
|
||||
result = await resourceApi.updateResource(articleForm.value);
|
||||
} else {
|
||||
// 新建模式:调用创建接口
|
||||
result = await resourceApi.createResource(articleForm.value);
|
||||
}
|
||||
|
||||
if (result.success) {
|
||||
const resourceID = result.data?.resource?.resourceID || '';
|
||||
ElMessage.success('发布成功');
|
||||
const resourceID = result.data?.resource?.resourceID || articleForm.value.resource.resourceID || '';
|
||||
ElMessage.success(isEdit.value ? '更新成功' : '发布成功');
|
||||
emit('publish-success', resourceID);
|
||||
} else {
|
||||
ElMessage.error(result.message || '发布失败');
|
||||
ElMessage.error(result.message || (isEdit.value ? '更新失败' : '发布失败'));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('发布失败:', error);
|
||||
ElMessage.error('发布失败');
|
||||
console.error(isEdit.value ? '更新失败:' : '发布失败:', error);
|
||||
ElMessage.error(isEdit.value ? '更新失败' : '发布失败');
|
||||
} finally {
|
||||
publishing.value = false;
|
||||
}
|
||||
@@ -287,13 +295,29 @@ async function handleSaveDraft() {
|
||||
savingDraft.value = true;
|
||||
|
||||
try {
|
||||
// TODO: 调用API保存草稿
|
||||
console.log('保存草稿:', articleForm);
|
||||
// 设置为草稿状态
|
||||
articleForm.value.resource.status = 0;
|
||||
|
||||
let result;
|
||||
if (isEdit.value) {
|
||||
// 编辑模式:调用更新接口
|
||||
result = await resourceApi.updateResource(articleForm.value);
|
||||
} else {
|
||||
// 新建模式:调用创建接口
|
||||
result = await resourceApi.createResource(articleForm.value);
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
ElMessage.success('草稿已保存');
|
||||
emit('save-draft-success');
|
||||
if (result.success) {
|
||||
// 如果是新建模式,需要更新为编辑模式
|
||||
if (!isEdit.value && result.data?.resource?.resourceID) {
|
||||
isEdit.value = true;
|
||||
articleForm.value.resource.resourceID = result.data.resource.resourceID;
|
||||
}
|
||||
ElMessage.success('草稿已保存');
|
||||
emit('save-draft-success');
|
||||
} else {
|
||||
ElMessage.error(result.message || '保存失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error);
|
||||
ElMessage.error('保存失败');
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
<select v-model="searchForm.status" class="form-select">
|
||||
<option :value="undefined">请选择状态</option>
|
||||
<option :value="0">未上线</option>
|
||||
<option :value="1">已上线</option>
|
||||
<option :value="2">已下架</option>
|
||||
<option :value="3">审核失败</option>
|
||||
<option :value="1">已发布</option>
|
||||
<option :value="2">下架</option>
|
||||
<option :value="3">审核中</option>
|
||||
<option :value="4">敏感词未通过</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
@@ -62,12 +63,13 @@
|
||||
<el-table-column prop="duration" label="时长(分钟)" width="120" />
|
||||
<el-table-column prop="learnCount" label="学习人数" width="100" />
|
||||
<el-table-column prop="viewCount" label="浏览次数" width="100" />
|
||||
<el-table-column label="状态" width="100">
|
||||
<el-table-column label="状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.status === 0" type="info">未上线</el-tag>
|
||||
<el-tag v-else-if="row.status === 1" type="success">已上线</el-tag>
|
||||
<el-tag v-else-if="row.status === 2" type="warning">已下架</el-tag>
|
||||
<el-tag v-else-if="row.status === 3" type="danger">审核失败</el-tag>
|
||||
<el-tag v-else-if="row.status === 1" type="success">已发布</el-tag>
|
||||
<el-tag v-else-if="row.status === 2" type="warning">下架</el-tag>
|
||||
<el-tag v-else-if="row.status === 3" type="primary">审核中</el-tag>
|
||||
<el-tag v-else-if="row.status === 4" type="danger">敏感词未通过</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="orderNum" label="排序" width="80" />
|
||||
@@ -77,13 +79,13 @@
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.status === 0 || row.status === 2 || row.status === 3"
|
||||
v-if="row.status === 0 || row.status === 2 || row.status === 4"
|
||||
type="success"
|
||||
size="small"
|
||||
link
|
||||
@click="handleUpdateStatus(row, 1)"
|
||||
>
|
||||
上线
|
||||
发布
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.status === 1"
|
||||
|
||||
Reference in New Issue
Block a user