diff --git a/ZR.LiveForum.Model/Liveforum/Dto/T_PostsDto.cs b/ZR.LiveForum.Model/Liveforum/Dto/T_PostsDto.cs
index aab9d36..d1662d6 100644
--- a/ZR.LiveForum.Model/Liveforum/Dto/T_PostsDto.cs
+++ b/ZR.LiveForum.Model/Liveforum/Dto/T_PostsDto.cs
@@ -111,5 +111,31 @@ namespace ZR.LiveForum.Model.Liveforum.Dto
public string? IsTopLabel { get; set; }
[ExcelColumn(Name = "帖子状态")]
public string? StatusLabel { get; set; }
+
+ ///
+ /// 帖子图片列表
+ ///
+ public List Images { get; set; } = new List();
+ }
+
+ ///
+ /// 帖子图片简单DTO
+ ///
+ public class PostImageDto
+ {
+ ///
+ /// 图片ID
+ ///
+ public long Id { get; set; }
+
+ ///
+ /// 图片URL
+ ///
+ public string ImageUrl { get; set; }
+
+ ///
+ /// 排序顺序
+ ///
+ public int SortOrder { get; set; }
}
}
\ No newline at end of file
diff --git a/ZR.Service/Liveforum/T_PostsService.cs b/ZR.Service/Liveforum/T_PostsService.cs
index 493a9c9..fc31b99 100644
--- a/ZR.Service/Liveforum/T_PostsService.cs
+++ b/ZR.Service/Liveforum/T_PostsService.cs
@@ -64,6 +64,33 @@ namespace ZR.Service.Liveforum
var resp = ToPage(response, parm);
+ // 批量查询并填充图片列表
+ if (resp.Result != null && resp.Result.Any())
+ {
+ var postIds = resp.Result.Select(x => x.Id).ToList();
+ var images = Context.Queryable()
+ .Where(x => postIds.Contains(x.PostId))
+ .OrderBy(x => x.SortOrder)
+ .ToList();
+
+ var imagesDict = images
+ .GroupBy(x => x.PostId)
+ .ToDictionary(
+ g => g.Key,
+ g => g.Select(x => new PostImageDto
+ {
+ Id = x.Id,
+ ImageUrl = x.ImageUrl,
+ SortOrder = x.SortOrder
+ }).ToList()
+ );
+
+ Context.ThenMapper(resp.Result, item =>
+ {
+ item.Images = imagesDict.GetValueOrDefault(item.Id, new List());
+ });
+ }
+
return resp;
}
diff --git a/ZR.Vue/src/views/liveforum/tcomments.vue b/ZR.Vue/src/views/liveforum/tcomments.vue
index 700e8e7..1427ef2 100644
--- a/ZR.Vue/src/views/liveforum/tcomments.vue
+++ b/ZR.Vue/src/views/liveforum/tcomments.vue
@@ -43,7 +43,7 @@
@selection-change="handleSelectionChange"
>
-
+
@@ -79,26 +79,26 @@
-
-
+
+
-
+
-
+
-
+
@@ -110,16 +110,16 @@
-
-
-
+
+
+
@@ -141,9 +141,9 @@
\ No newline at end of file
+
diff --git a/ZR.Vue/src/views/liveforum/tposts.vue b/ZR.Vue/src/views/liveforum/tposts.vue
index ee69b1e..a1011fd 100644
--- a/ZR.Vue/src/views/liveforum/tposts.vue
+++ b/ZR.Vue/src/views/liveforum/tposts.vue
@@ -67,59 +67,73 @@
@selection-change="handleSelectionChange"
>
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+ 暂无图片
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
-
+
+
-
-
-
-
+
+
+
+
+
-
+
@@ -224,6 +238,114 @@
{{ $t('btn.submit') }}
+
+
+
+
+
+
+
+ {{ $t('btn.add') }}
+
+
+
+
+ {{ $t('btn.delete') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 无
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('btn.cancel') }}
+ {{ $t('btn.submit') }}
+
+
+
@@ -233,6 +355,10 @@ import { listtposts,
updatetposts,gettposts,
}
from '@/api/liveforum/tposts.js'
+import { listtpostimages,
+ addtpostimages, deltpostimages,
+ }
+from '@/api/liveforum/tpostimages.js'
const { proxy } = getCurrentInstance()
const ids = ref([])
const loading = ref(false)
@@ -253,18 +379,19 @@ const columns = ref([
{ visible: true, align: 'center', type: '', prop: 'nickName', label: '用户昵称' ,showOverflowTooltip: true },
{ visible: true, align: 'center', type: '', prop: 'title', label: '标题' ,showOverflowTooltip: true },
{ visible: true, align: 'center', type: 'img', prop: 'coverImage', label: '封面图片' ,showOverflowTooltip: true },
+ { visible: true, align: 'center', type: '', prop: 'images', label: '图片列表' ,showOverflowTooltip: false },
{ visible: true, align: 'center', type: '', prop: 'content', label: '正文内容' ,showOverflowTooltip: true },
{ visible: true, align: 'center', type: '', prop: 'categoryId', label: '分类ID' },
{ visible: true, align: 'center', type: '', prop: 'viewCount', label: '浏览次数' },
{ visible: true, align: 'center', type: '', prop: 'likeCount', label: '点赞数量' },
- { visible: false, align: 'center', type: '', prop: 'commentCount', label: '评论数量' },
+ { visible: true, align: 'center', type: '', prop: 'commentCount', label: '评论数量' },
{ visible: false, align: 'center', type: '', prop: 'shareCount', label: '分享次数' },
- { visible: false, align: 'center', type: 'dict', prop: 'isTop', label: '是否置顶' ,dictType: 'liveforum_action_bool' },
- { visible: false, align: 'center', type: 'dict', prop: 'isHot', label: '是否热门' ,dictType: 'liveforum_action_bool' },
- { visible: false, align: 'center', type: 'dict', prop: 'isEssence', label: '是否精华' ,dictType: 'liveforum_action_bool' },
- { visible: false, align: 'center', type: 'dict', prop: 'status', label: '帖子状态' ,dictType: 'liveforum_posts_status' },
- { visible: false, align: 'center', type: '', prop: 'publishTime', label: '发布时间' ,showOverflowTooltip: true },
- { visible: false, align: 'center', type: 'dict', prop: 'isDeleted', label: '是否已删除' ,dictType: 'liveforum_action_bool' },
+ { visible: true, align: 'center', type: 'dict', prop: 'isTop', label: '是否置顶' ,dictType: 'liveforum_action_bool' },
+ { visible: true, align: 'center', type: 'dict', prop: 'isHot', label: '是否热门' ,dictType: 'liveforum_action_bool' },
+ { visible: true, align: 'center', type: 'dict', prop: 'isEssence', label: '是否精华' ,dictType: 'liveforum_action_bool' },
+ { visible: true, align: 'center', type: 'dict', prop: 'status', label: '帖子状态' ,dictType: 'liveforum_posts_status' },
+ { visible: true, align: 'center', type: '', prop: 'publishTime', label: '发布时间' ,showOverflowTooltip: true },
+ { visible: true, align: 'center', type: 'dict', prop: 'isDeleted', label: '是否已删除' ,dictType: 'liveforum_action_bool' },
{ visible: false, align: 'center', type: '', prop: 'deletedAt', label: '删除时间' ,showOverflowTooltip: true },
{ visible: false, align: 'center', type: '', prop: 'createdAt', label: '创建时间' ,showOverflowTooltip: true },
{ visible: false, align: 'center', type: '', prop: 'updatedAt', label: '更新时间' ,showOverflowTooltip: true },
@@ -275,6 +402,42 @@ const dataList = ref([])
const queryRef = ref()
const defaultTime = ref([new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)])
+// 图片管理弹窗相关状态
+const imageManageDialogOpen = ref(false)
+const currentPost = ref({ id: null, title: '' })
+const imageList = ref([])
+const imageTotal = ref(0)
+const imageLoading = ref(false)
+const imageQueryParams = reactive({
+ pageNum: 1,
+ pageSize: 10,
+ sort: 'SortOrder',
+ sortType: 'asc',
+ postId: undefined,
+})
+const imageIds = ref([])
+const imageSingle = ref(true)
+const imageMultiple = ref(true)
+
+// 添加图片表单相关状态
+const imageFormOpen = ref(false)
+const imageFormRef = ref()
+const imageFormSubmitLoading = ref(false)
+const imageForm = reactive({
+ postId: null,
+ imageUrl: null,
+ thumbnailUrl: null,
+ imageWidth: null,
+ imageHeight: null,
+ fileSize: null,
+ sortOrder: 0,
+})
+const imageFormRules = {
+ postId: [{ required: true, message: "帖子ID不能为空", trigger: "blur", type: "number" }],
+ imageUrl: [{ required: true, message: "图片不能为空", trigger: "blur" }],
+ sortOrder: [{ required: true, message: "排序顺序不能为空", trigger: "blur", type: "number" }],
+}
+
var dictParams = [
"liveforum_action_bool",
@@ -504,5 +667,150 @@ function handleExport() {
})
}
+/*************** 图片管理相关方法 ***************/
+// 打开图片管理弹窗
+function handleManageImages(row) {
+ currentPost.value = {
+ id: row.id,
+ title: row.title || '未命名帖子'
+ }
+ imageQueryParams.postId = row.id
+ imageQueryParams.pageNum = 1
+ imageManageDialogOpen.value = true
+ getImageList()
+}
+
+// 查询图片列表
+function getImageList() {
+ imageLoading.value = true
+ listtpostimages(imageQueryParams).then(res => {
+ const { code, data } = res
+ if (code == 200) {
+ imageList.value = data.result
+ imageTotal.value = data.totalNum
+ imageLoading.value = false
+ }
+ })
+}
+
+// 图片列表多选框选中数据
+function handleImageSelectionChange(selection) {
+ imageIds.value = selection.map((item) => item.id)
+ imageSingle.value = selection.length != 1
+ imageMultiple.value = !selection.length
+}
+
+// 打开添加图片表单
+function handleAddImage() {
+ resetImageForm()
+ imageForm.postId = currentPost.value.id
+ // 设置默认排序顺序为当前最大排序+1
+ if (imageList.value && imageList.value.length > 0) {
+ const maxSort = Math.max(...imageList.value.map(img => img.sortOrder || 0))
+ imageForm.sortOrder = maxSort + 1
+ } else {
+ imageForm.sortOrder = 1
+ }
+ imageFormOpen.value = true
+ imageFormSubmitLoading.value = false
+}
+
+// 重置图片表单
+function resetImageForm() {
+ imageForm.postId = null
+ imageForm.imageUrl = null
+ imageForm.thumbnailUrl = null
+ imageForm.imageWidth = null
+ imageForm.imageHeight = null
+ imageForm.fileSize = null
+ imageForm.sortOrder = 0
+ proxy.resetForm("imageFormRef")
+}
+
+// 取消添加图片表单
+function cancelImageForm() {
+ imageFormOpen.value = false
+ resetImageForm()
+}
+
+// 提交添加图片表单
+function submitImageForm() {
+ proxy.$refs["imageFormRef"].validate((valid) => {
+ if (valid) {
+ imageFormSubmitLoading.value = true
+ addtpostimages(imageForm).then((res) => {
+ proxy.$modal.msgSuccess("新增成功")
+ imageFormOpen.value = false
+ resetImageForm()
+ getImageList()
+ // 刷新帖子列表(更新图片列表显示)
+ getList()
+ })
+ .finally(() => {
+ setTimeout(() => {
+ imageFormSubmitLoading.value = false
+ }, 800)
+ })
+ }
+ })
+}
+
+// 删除单张图片
+function handleDeleteImage(row) {
+ const Ids = row.id
+
+ proxy
+ .$confirm('是否确认删除该图片?', "警告", {
+ confirmButtonText: proxy.$t('common.ok'),
+ cancelButtonText: proxy.$t('common.cancel'),
+ type: "warning",
+ })
+ .then(function () {
+ return deltpostimages(Ids)
+ })
+ .then(() => {
+ getImageList()
+ // 刷新帖子列表(更新图片列表显示)
+ getList()
+ proxy.$modal.msgSuccess("删除成功")
+ })
+}
+
+// 批量删除图片
+function handleBatchDeleteImage() {
+ const Ids = imageIds.value
+
+ if (!Ids || Ids.length === 0) {
+ proxy.$modal.msgWarning("请选择要删除的图片")
+ return
+ }
+
+ proxy
+ .$confirm('是否确认删除选中的' + Ids.length + '张图片?', "警告", {
+ confirmButtonText: proxy.$t('common.ok'),
+ cancelButtonText: proxy.$t('common.cancel'),
+ type: "warning",
+ })
+ .then(function () {
+ return deltpostimages(Ids.join(','))
+ })
+ .then(() => {
+ getImageList()
+ // 刷新帖子列表(更新图片列表显示)
+ getList()
+ proxy.$modal.msgSuccess("删除成功")
+ })
+}
+
+// 关闭图片管理弹窗
+function closeImageManageDialog() {
+ imageManageDialogOpen.value = false
+ currentPost.value = { id: null, title: '' }
+ imageQueryParams.postId = undefined
+ imageList.value = []
+ imageTotal.value = 0
+ imageIds.value = []
+}
+
handleQuery()