Эх сурвалжийг харах

feat: 下发详情展示功能,增加展示下发资源列表

lihao16 4 сар өмнө
parent
commit
01cde1e70b

+ 13 - 4
smsb-modules/smsb-source/src/main/java/com/inspur/source/controller/SmsbItemPushController.java

@@ -4,10 +4,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.annotation.SaIgnore;
 import com.inspur.source.domain.SmsbItemPush;
 import com.inspur.source.domain.bo.SmsbItemPushBo;
-import com.inspur.source.domain.vo.PushStatisticsVo;
-import com.inspur.source.domain.vo.ResponseBaseBean;
-import com.inspur.source.domain.vo.SmsbItemPushReviewVo;
-import com.inspur.source.domain.vo.SmsbItemPushVo;
+import com.inspur.source.domain.vo.*;
 import com.inspur.source.service.ISmsbItemPushService;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.NotEmpty;
@@ -53,6 +50,18 @@ public class SmsbItemPushController extends BaseController {
         return smsbItemPushService.queryPageList(bo, pageQuery);
     }
 
+
+    /**
+     * 获取内容发布列表
+     * @param pushId
+     * @return
+     */
+    @SaCheckPermission("source:itemPush:list")
+    @GetMapping("/sourceList/{pushId}")
+    public R<List<SmsbItemFileRelVo>> getPushSourceList(@PathVariable("pushId") Long pushId) {
+        return smsbItemPushService.getPushSourceList(pushId);
+    }
+
     /**
      * 查询内容发布列表
      */

+ 1 - 1
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/SmsbItemPush.java

@@ -40,7 +40,7 @@ public class SmsbItemPush extends TenantEntity {
     private Long level;
 
     /**
-     * 类型 1-轮播 2-分屏 3-素材
+     * 类型 1-轮播 2-固定分屏 3-分屏 4-素材
      */
     private Long itemType;
 

+ 5 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/vo/SmsbItemFileRelVo.java

@@ -73,5 +73,10 @@ public class SmsbItemFileRelVo implements Serializable {
     @ExcelProperty(value = "创建时间")
     private Date createTime;
 
+    private String fileName;
+
+    private String screenshot;
+
+    private Integer fileType;
 
 }

+ 4 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/mapper/SmsbItemFileRelMapper.java

@@ -29,4 +29,8 @@ public interface SmsbItemFileRelMapper extends BaseMapperPlus<SmsbItemFileRel, S
     List<SmsbMinioDataVo> selectMinioDataByPushId(@Param("pushId") Long pushId);
 
     List<ItemFileRelReqBo> selectedFilesByItemId(@Param("itemId") Long itemId);
+
+    List<SmsbItemFileRelVo> selectSourceListByPushId(@Param("pushId") Long pushId);
+
+    List<SmsbItemFileRelVo> selectSourceListByItemIds(@Param("itemIds") List<Long> itemIds);
 }

+ 7 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/service/ISmsbItemPushService.java

@@ -149,4 +149,11 @@ public interface ISmsbItemPushService {
      * @return
      */
     R<List<FrontItemSourceVO>> getItemSourceList(Long itemId);
+
+    /**
+     * 获取发布资源列表详情
+     * @param pushId
+     * @return
+     */
+    R<List<SmsbItemFileRelVo>> getPushSourceList(Long pushId);
 }

+ 50 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/service/impl/SmsbItemPushServiceImpl.java

@@ -199,6 +199,36 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
         return result;
     }
 
+    private List<Long> getItemIdsByProgram(SmsbItemPushVo itemPushVo) {
+        List<Long> result = new ArrayList<>();
+        SmsbItemProgramVo smsbItemProgram = smsbItemProgramMapper.selectVoByPushId(itemPushVo.getId());
+        if (null == smsbItemProgram) {
+            return result;
+        }
+        String itemJsonStr = smsbItemProgram.getItemJsonStr();
+        if (StringUtils.isEmpty(itemJsonStr)) {
+            return result;
+        }
+        // 解析可视化数据,获取轮播组ID
+        try {
+            JSONObject itemJson = JSONUtil.parseObj(itemJsonStr);
+            JSONArray elements = itemJson.getJSONArray("elements");
+            for (Object elementObj : elements) {
+                JSONObject element = JSONUtil.parseObj(elementObj);
+                String type = element.getStr("type");
+                // 类型是一个媒资
+                if (type.equals("mediaAsset")) {
+                    JSONObject mediaId = JSONUtil.parseObj(element.getStr("mediaId"));
+                    String itemId = mediaId.getStr("id");
+                    result.add(Long.parseLong(itemId));
+                }
+            }
+        }catch (Exception e) {
+            log.error("解析可视化布局JSON异常!");
+        }
+        return result;
+    }
+
     /**
      * 分页查询内容发布列表
      *
@@ -408,6 +438,26 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
         return R.ok(results);
     }
 
+    @Override
+    public R<List<SmsbItemFileRelVo>> getPushSourceList(Long pushId) {
+        SmsbItemPushVo itemPushVo = baseMapper.selectVoById(pushId);
+        Long itemType = itemPushVo.getItemType();
+        // 轮播组或者素材 获取素材
+        if (itemType == 1L ||  itemType == 4L) {
+            return R.ok(itemFileRelMapper.selectSourceListByPushId(pushId));
+        }
+        // 解析可视化json获取轮播组ID,获取文件列表
+        if (itemPushVo.getItemType() == 3L) {
+            List<Long> itemIds = getItemIdsByProgram(itemPushVo);
+            if (CollectionUtil.isEmpty(itemIds)) {
+                return R.ok(new ArrayList<>());
+            }
+            List<SmsbItemFileRelVo> sourceList = itemFileRelMapper.selectSourceListByItemIds(itemIds);
+            return R.ok(sourceList);
+        }
+        return null;
+    }
+
     @Override
     public R<Void> submitReview(Long pushId) {
         SmsbItemPush smsbItemPush = baseMapper.selectById(pushId);

+ 35 - 0
smsb-modules/smsb-source/src/main/resources/mapper/SmsbItemFileRelMapper.xml

@@ -63,4 +63,39 @@
         ORDER BY
             sifr.sort
     </select>
+
+    <select id="selectSourceListByPushId" parameterType="Long" resultType="com.inspur.source.domain.vo.SmsbItemFileRelVo">
+        SELECT
+            sifr.sort,
+            sifr.duration,
+            md.original_name as fileName,
+            md.screenshot,
+            md.type as fileType
+        FROM
+            smsb_item_file_rel sifr
+        LEFT JOIN
+            smsb_minio_data md on sifr.file_id = md.id
+        WHERE
+            sifr.item_id = (SELECT item_id FROM smsb_item_push_rel WHERE push_id = #{pushId})
+        order by sifr.sort asc
+    </select>
+
+    <select id="selectSourceListByItemIds" resultType="com.inspur.source.domain.vo.SmsbItemFileRelVo">
+        SELECT
+            sifr.sort,
+            sifr.duration,
+            md.original_name as fileName,
+            md.screenshot,
+            md.type as fileType
+        FROM
+            smsb_item_file_rel sifr
+        LEFT JOIN
+            smsb_minio_data md on sifr.file_id = md.id
+        WHERE
+            sifr.item_id in
+        <foreach item="itemId" collection="itemIds" separator="," open="(" close=")" index="">
+            #{itemId}
+        </foreach>
+        order by sifr.sort asc
+    </select>
 </mapper>

+ 7 - 0
smsb-plus-ui/src/api/smsb/source/item.ts

@@ -17,6 +17,13 @@ export const listItem = (query?: ItemQuery): AxiosPromise<ItemVO[]> => {
   });
 };
 
+export const listItemPushSource = (id: string | number): AxiosPromise<ItemFileRelVO[]> => {
+  return request({
+    url: '/source/itemPush/sourceList/' + id,
+    method: 'get'
+  });
+}
+
 /**
  * 查询节目管理详细
  * @param id

+ 76 - 50
smsb-plus-ui/src/views/smsb/itemPush/index.vue

@@ -253,57 +253,72 @@
     </el-dialog>
 
     <!-- 下发详情弹窗 -->
-    <el-dialog :title="deviceDialog.title" v-model="deviceDialog.visible" width="900px" append-to-body>
+    <el-dialog :title="deviceDialog.title" v-model="deviceDialog.visible" width="1400px" append-to-body>
       <!--发布名称-->
       <div>
-        <el-form ref="itemPushFormRef" :model="form" :rules="rules" label-width="70px">
-          <el-form-item label="发布名称" prop="name">
-            <el-input v-model="form.name" style="width: 500px" placeholder="请输入名称" :disabled="true" />
-          </el-form-item>
-          <el-row>
-            <el-col :span="12">
-              <el-form-item label="发布类型" prop="itemType">
-                <el-select v-model="form.itemType" placeholder="请选择类型" @change="getItemList" :disabled="true">
-                  <el-option v-for="dict in smsb_push_type" :key="dict.value" :label="dict.label"
-                    :value="parseInt(dict.value)"></el-option>
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="优先级" prop="level">
-                <el-select v-model="form.level" placeholder="请选择优先级" :disabled="true">
-                  <el-option v-for="dict in smsb_push_level" :key="dict.value" :label="dict.label"
-                    :value="parseInt(dict.value)"></el-option>
-                </el-select>
-              </el-form-item>
-            </el-col>
-          </el-row>
-        </el-form>
+        <el-descriptions title="详情信息" :column="2" border>
+          <el-descriptions-item label="发布名称">
+            {{form.name}}
+          </el-descriptions-item>
+          <el-descriptions-item label="发布类型">
+            <dict-tag :options="smsb_push_type" :value="form.itemType" />
+          </el-descriptions-item>
+          <el-descriptions-item label="开始时间">
+            {{form.startDate}}
+          </el-descriptions-item>
+          <el-descriptions-item label="结束时间">
+            {{form.endDate}}
+          </el-descriptions-item>
+        </el-descriptions>
       </div>
-      <!--设备列表-->
-      <el-button type="primary" v-if="removeItemTag" icon="Bottom" :disabled="removeButtonTag"
-        @click="handleDoRemoveItem()"> 下架 </el-button>
-      <el-table v-loading="deviceLoading" :data="pushDeviceList" style="height: 500px; margin-top: 10px"
-        @selection-change="handleDeviceSelectionChange">
-        <el-table-column type="selection" v-if="removeItemTag" width="55" align="center" />
-        <el-table-column label="设备名称" align="left" prop="deviceName" :show-overflow-tooltip="true" />
-        <el-table-column label="发布排序" align="center" prop="sortNum" width="100" :show-overflow-tooltip="true" />
-        <el-table-column label="发布状态" align="center" prop="pushState" width="120" :show-overflow-tooltip="true">
-          <template #default="scope">
-            <dict-tag :options="smsb_push_device_state" :value="scope.row.pushState" />
-          </template>
-        </el-table-column>
-        <el-table-column label="发布时间" align="left" prop="createTime" width="170" :show-overflow-tooltip="true" />
-        <el-table-column label="操作" v-if="removeItemTag" align="center" class-name="small-padding fixed-width"
-          width="150">
-          <template #default="scope">
-            <el-tooltip content="下架" placement="top">
-              <el-button link type="primary" icon="Bottom" @click="handleDoRemoveItem(scope.row)"
-                v-hasPermi="['source:itemPush:edit']"></el-button>
-            </el-tooltip>
-          </template>
-        </el-table-column>
-      </el-table>
+
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-table v-loading="deviceLoading" :data="pushSourceList" style="height: 500px; margin-top: 10px">
+            <el-table-column label="排序" align="center" prop="sort" width="60" :show-overflow-tooltip="true" />
+            <el-table-column label="时长" align="center" prop="duration" width="80" :show-overflow-tooltip="true"/>
+            <el-table-column label="资源" align="left" prop="fileName" :show-overflow-tooltip="true"/>
+            <el-table-column label="预览" align="center" prop="screenshot" width="120">
+              <template #default="scope">
+                <div v-if="scope.row.fileType === 1">
+                  <image-preview :src="scope.row.screenshot" style="width: 40px; height: 40px; cursor: pointer" />
+                </div>
+                <div v-else-if="scope.row.fileType === 2">
+                  <el-icon class="VideoPlay" @click="viewVideo(scope.row.screenshot)" size="40" style="cursor: pointer">
+                    <VideoPlay />
+                  </el-icon>
+                </div>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-col>
+        <el-col :span="12">
+          <!--设备列表-->
+          <el-button type="primary" v-if="removeItemTag" icon="Bottom" :disabled="removeButtonTag"
+                     @click="handleDoRemoveItem()" style="margin-top: 10px"> 下架 </el-button>
+          <el-table v-loading="deviceLoading" :data="pushDeviceList" style="height: 500px; margin-top: 10px"
+                    @selection-change="handleDeviceSelectionChange">
+            <el-table-column type="selection" v-if="removeItemTag" width="55" align="center" />
+            <el-table-column label="设备名称" align="left" prop="deviceName" :show-overflow-tooltip="true" />
+            <el-table-column label="发布排序" align="center" prop="sortNum" width="80" :show-overflow-tooltip="true" />
+            <el-table-column label="发布状态" align="center" prop="pushState" width="100" :show-overflow-tooltip="true">
+              <template #default="scope">
+                <dict-tag :options="smsb_push_device_state" :value="scope.row.pushState" />
+              </template>
+            </el-table-column>
+            <el-table-column label="发布时间" align="left" prop="createTime" width="160" :show-overflow-tooltip="true" />
+            <el-table-column label="操作" v-if="removeItemTag" align="center" class-name="small-padding fixed-width"
+                             width="80">
+              <template #default="scope">
+                <el-tooltip content="下架" placement="top">
+                  <el-button link type="primary" icon="Bottom" @click="handleDoRemoveItem(scope.row)"
+                             v-hasPermi="['source:itemPush:edit']"></el-button>
+                </el-tooltip>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-col>
+      </el-row>
       <template #footer>
         <div class="dialog-footer">
           <el-button @click="cancel">取 消</el-button>
@@ -312,7 +327,7 @@
     </el-dialog>
 
     <!-- 用于展示播放的视频 -->
-    <el-dialog v-model="videoDialogVisible">
+    <el-dialog v-model="videoDialogVisible" append-to-body>
       <video width="100%" controls :src="videoUrl"></video>
     </el-dialog>
   </div>
@@ -333,11 +348,12 @@ import {ItemPushForm, ItemPushQuery, ItemPushVO} from '@/api/smsb/source/item_pu
 import {DeviceQuery, DeviceVO} from '@/api/smsb/device/device_type';
 import {listDevice} from '@/api/smsb/device/device';
 import {ItemQuery, ItemVO} from '@/api/smsb/source/item_type';
-import {listItem} from '@/api/smsb/source/item';
+import {listItem, listItemPushSource} from '@/api/smsb/source/item';
 import {ItemPushDeviceVO} from '@/api/smsb/source/item_push_device_type';
 import {listItemPushDeviceV2, removeItemPushDevice} from '@/api/smsb/source/item_push_device';
 import {MinioDataVO} from "@/api/smsb/source/minioData_type";
 import {listMinioData} from "@/api/smsb/source/minioData";
+import {ItemFileRelVO} from "@/api/smsb/source/itemFile_type";
 
 const {proxy} = getCurrentInstance() as ComponentInternalInstance;
 const {smsb_push_state, smsb_push_device_state, smsb_push_type, smsb_push_level,smsb_push_isuse} = toRefs<any>(
@@ -368,6 +384,7 @@ const scNum = ref(0);
 const dateRangeCreateTime = ref<[DateModelType, DateModelType]>(['', '']);
 const deviceList = ref<DeviceVO[]>([]);
 const pushDeviceList = ref<ItemPushDeviceVO[]>([]);
+const pushSourceList = ref<ItemFileRelVO[]>([]);
 // 存储选中行的唯一标识
 const selectedRowId = ref<number | null>(null);
 const selectedMinioDataIds = ref<[]>;
@@ -526,6 +543,7 @@ const handleDevice = async (row?: ItemPushVO) => {
   const pushInfo = await getItemPush(pushId);
   Object.assign(form.value, pushInfo.data);
   await getItemDeviceList(pushId);
+  await getItemSourceList(pushId);
 };
 const handleRemoveItem = async (row?: ItemPushVO) => {
   removeItemTag.value = true;
@@ -541,6 +559,7 @@ const handleRemoveItem = async (row?: ItemPushVO) => {
   const pushInfo = await getItemPush(pushId);
   Object.assign(form.value, pushInfo.data);
   await getItemDeviceList(pushId);
+  await getItemSourceList(pushId);
 };
 const handleDoRemoveItem = async (row?: ItemPushDeviceVO) => {
   const deviceIds = Array<number | string>();
@@ -568,6 +587,13 @@ const getItemDeviceList = async (pushId: number | string) => {
   deviceLoading.value = false;
 };
 
+const getItemSourceList = async (pushId: number | string) => {
+  deviceLoading.value = true;
+  const res = await listItemPushSource(pushId);
+  pushSourceList.value = res.data;
+  deviceLoading.value = false;
+};
+
 /** 重置按钮操作 */
 const resetQuery = () => {
   dateRangeCreateTime.value = ['', ''];