fix(shopGoods): 修复编辑弹窗视频裂图问题
- 新增 isVideo() 函数判断视频文件类型 - 编辑弹窗预览区域分支渲染,视频显示 <video> 组件 - 视频预览添加 PlayCircleOutlined 播放图标覆盖层 - 保持图片预览使用原有 <a-image> 组件 - 引入并使用 PlayCircleOutlined 图标组件
This commit is contained in:
@@ -76,3 +76,13 @@
|
|||||||
### 验证
|
### 验证
|
||||||
- 前端 `vue-tsc --noEmit`:user/pending 两页无新增实质类型错误(残留均为项目既有噪音:$router、getPageTitle、TS6133 未使用、TS7053 导出数组索引)。
|
- 前端 `vue-tsc --noEmit`:user/pending 两页无新增实质类型错误(残留均为项目既有噪音:$router、getPageTitle、TS6133 未使用、TS7053 导出数组索引)。
|
||||||
- 后端落地核对:UserParam auditPending 字段=1、XML 两条件各=1,片段上下文正确。SELECT 用 `a.*` 会返回 `audit_status`(驼峰映射 auditStatus),列表标签正常。
|
- 后端落地核对:UserParam auditPending 字段=1、XML 两条件各=1,片段上下文正确。SELECT 用 `a.*` 会返回 `audit_status`(驼峰映射 auditStatus),列表标签正常。
|
||||||
|
|
||||||
|
## 修复 shopGoods 编辑弹窗视频裂图问题
|
||||||
|
|
||||||
|
`src/views/shop/shopGoods/components/shopGoodsEdit.vue` 商品图片(400x400) 预览区域:
|
||||||
|
|
||||||
|
- **问题**:`form.image` 存视频 URL 时 `<a-image>` 组件无法渲染,显示裂图
|
||||||
|
- **修复**:新增 `isVideo()` 函数(通过扩展名 .mp4/.webm/.mov 等判断),模板分两个分支:
|
||||||
|
- 视频 → `<video preload="metadata">` + PlayCircleOutlined 播放图标覆盖层(100×100 深色背景圆角)
|
||||||
|
- 图片 → 原有 `<a-image>` 不变
|
||||||
|
- 新增 `PlayCircleOutlined` 图标 import
|
||||||
|
|||||||
@@ -127,10 +127,31 @@
|
|||||||
<!-- @done="chooseImage"-->
|
<!-- @done="chooseImage"-->
|
||||||
<!-- @del="onDeleteItem"-->
|
<!-- @del="onDeleteItem"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
|
<!-- 视频预览 -->
|
||||||
|
<div
|
||||||
|
v-if="form.image && isVideo(form.image)"
|
||||||
|
class="relative"
|
||||||
|
style="width: 100px; height: 100px; margin-right: 10px; border-radius: 6px; overflow: hidden; border: 1px solid #434343; background: #1a1a1a;"
|
||||||
|
>
|
||||||
|
<video
|
||||||
|
:src="form.image"
|
||||||
|
style="width: 100%; height: 100%; object-fit: cover;"
|
||||||
|
preload="metadata"
|
||||||
|
muted
|
||||||
|
/>
|
||||||
|
<!-- 播放图标覆盖层 -->
|
||||||
|
<div
|
||||||
|
class="absolute inset-0 flex items-center justify-center"
|
||||||
|
style="background: rgba(0,0,0,0.25);"
|
||||||
|
>
|
||||||
|
<PlayCircleOutlined style="font-size: 28px; color: rgba(255,255,255,0.85);" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 图片预览 -->
|
||||||
<a-image
|
<a-image
|
||||||
|
v-else-if="form.image"
|
||||||
width="100px"
|
width="100px"
|
||||||
height="100px"
|
height="100px"
|
||||||
v-if="form.image"
|
|
||||||
:src="form.image"
|
:src="form.image"
|
||||||
style="margin-right: 10px"
|
style="margin-right: 10px"
|
||||||
/>
|
/>
|
||||||
@@ -677,6 +698,7 @@ import {
|
|||||||
CloseCircleOutlined,
|
CloseCircleOutlined,
|
||||||
DeleteOutlined,
|
DeleteOutlined,
|
||||||
InfoCircleOutlined,
|
InfoCircleOutlined,
|
||||||
|
PlayCircleOutlined,
|
||||||
SettingOutlined,
|
SettingOutlined,
|
||||||
UploadOutlined
|
UploadOutlined
|
||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
@@ -1956,6 +1978,14 @@ const getRoleList = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 判断是否为视频文件(支持 mp4/webm/mov/avi 等常见格式)
|
||||||
|
const isVideo = (url: string): boolean => {
|
||||||
|
if (!url) return false;
|
||||||
|
const videoExts = ['.mp4', '.webm', '.mov', '.avi', '.m3u8', '.ogg'];
|
||||||
|
const lowerUrl = url.toLowerCase().split('?')[0]; // 去掉查询参数
|
||||||
|
return videoExts.some((ext) => lowerUrl.endsWith(ext));
|
||||||
|
};
|
||||||
|
|
||||||
const onUploadImage = (item) => {
|
const onUploadImage = (item) => {
|
||||||
const {file} = item;
|
const {file} = item;
|
||||||
if (file.size / 1024 / 1024 > 10) {
|
if (file.size / 1024 / 1024 > 10) {
|
||||||
|
|||||||
Reference in New Issue
Block a user