Selaa lähdekoodia

1、可视化功能接入审核流程
2、审核展示可视化关联的轮播组资源
3、审核支持跳转可视化预览页面

lihao16 5 kuukautta sitten
vanhempi
sitoutus
18778c0b95

+ 2 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/vo/SmsbItemPushReviewVo.java

@@ -31,4 +31,6 @@ public class SmsbItemPushReviewVo extends SmsbItemPushVo implements Serializable
      */
     private List<SmsbItemPushTimeRangeBo> timeList;
 
+    private Long programId;
+
 }

+ 8 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/mapper/SmsbItemProgramMapper.java

@@ -2,6 +2,7 @@ package com.inspur.source.mapper;
 
 import com.inspur.source.domain.SmsbItemProgram;
 import com.inspur.source.domain.vo.SmsbItemProgramVo;
+import org.apache.ibatis.annotations.Param;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 
 /**
@@ -25,4 +26,11 @@ public interface SmsbItemProgramMapper extends BaseMapperPlus<SmsbItemProgram, S
      * 更新节目名称
      */
     int updateNameById(@org.apache.ibatis.annotations.Param("id") Long id, @org.apache.ibatis.annotations.Param("name") String name);
+
+    /**
+     * 根据发布ID 查询可视化详情
+     * @param pushId
+     * @return
+     */
+    SmsbItemProgramVo selectVoByPushId(@Param("pushId") Long pushId);
 }

+ 2 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/mapper/SmsbMinioDataMapper.java

@@ -62,4 +62,6 @@ public interface SmsbMinioDataMapper extends BaseMapperPlus<SmsbMinioData, SmsbM
      * @return
      */
     DiskUseVo diskUse();
+
+    List<SmsbMinioDataVo> selectVoListByItemId(@Param("itemId") Long itemId);
 }

+ 44 - 8
smsb-modules/smsb-source/src/main/java/com/inspur/source/service/impl/SmsbItemPushServiceImpl.java

@@ -7,6 +7,9 @@ import cn.hutool.core.date.DatePattern;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -40,7 +43,6 @@ import org.dromara.common.core.utils.StreamUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.redis.utils.RedisUtils;
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.workflow.common.constant.FlowConstant;
 import org.dromara.workflow.common.enums.MessageTypeEnum;
@@ -87,17 +89,15 @@ import java.util.stream.Collectors;
 @Service
 @Slf4j
 public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
-
-    private final static String PUSH_CONTENT_INFO_KEY = "global:msr:device:push:";
-
     private final SmsbItemPushMapper baseMapper;
-    private final SmsbItemPushTimeMapper itemPushTimeMapper;
     private final SmsbItemPushRelMapper itemPushRelMapper;
     private final SmsbItemFileRelMapper itemFileRelMapper;
     private final SmsbItemSplitScreenMapper itemSplitScreenMapper;
     private final SmsbItemMapper itemMapper;
     private final SmsbItemPushPlaylistMapper smsbItemPushPlaylistMapper;
     private final SmsbItemPushPlaylineMapper smsbItemPushPlaylineMapper;
+    private final SmsbItemProgramMapper smsbItemProgramMapper;
+    private final SmsbMinioDataMapper smsbMinioDataMapper;
     @Autowired
     private ISmsbDeviceService smsbDeviceService;
     @Autowired
@@ -141,12 +141,16 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
         // 根据pushId查询所有设备信息
         List<SmsbDeviceVo> deviceList = smsbDeviceMapper.queryDeviceVoByPushId(pushId);
         reviewVo.setDeviceList(deviceList);
-        // 根据pushId查询所有节目资源信息
+        // 根据pushId查询所有节目资源信息 轮播组+分屏组OLD
         if (itemPushVo.getItemType() == 1L || itemPushVo.getItemType() == 2L) {
             List<SmsbMinioDataVo> sourceList = itemFileRelMapper.selectMinioDataByPushId(pushId);
             reviewVo.setResourceList(sourceList);
         }
-
+        // 解析可视化json获取轮播组ID,获取文件列表
+        if (itemPushVo.getItemType() == 3L) {
+            List<SmsbMinioDataVo> sourceList = getSourceListByProgram(itemPushVo,reviewVo);
+            reviewVo.setResourceList(sourceList);
+        }
         List<SmsbItemPushPlaylistVo> pushPlaylistVos = smsbItemPushPlaylistMapper.selectVoList(new LambdaQueryWrapper<SmsbItemPushPlaylist>()
             .eq(SmsbItemPushPlaylist::getPushId, pushId));
         String dateStart = pushPlaylistVos.get(0).getStartDate();
@@ -163,6 +167,38 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
         return reviewVo;
     }
 
+    private List<SmsbMinioDataVo> getSourceListByProgram(SmsbItemPushVo itemPushVo,SmsbItemPushReviewVo reviewVo) {
+        List<SmsbMinioDataVo> 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");
+                    // 根据itemId 查询资源列表
+                    result = smsbMinioDataMapper.selectVoListByItemId(Long.parseLong(itemId));
+                    reviewVo.setProgramId(smsbItemProgram.getProgramId());
+                }
+            }
+        }catch (Exception e) {
+            log.error("解析可视化布局JSON异常!");
+        }
+        return result;
+    }
+
     /**
      * 分页查询内容发布列表
      *
@@ -257,7 +293,7 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
         // 保存设备内容播放单
         saveItemPushPlaylist(bo);
         // 轮播组 分屏组关联保存
-        if (bo.getItemType() == 1 || bo.getItemType() == 2) {
+        if (bo.getItemType() == 1 || bo.getItemType() == 2 || bo.getItemType() == 3) {
             addItemPushRel(bo.getId(), bo.getItemIds());
         }
         // 下架超过播单结束时间的旧播单

+ 11 - 0
smsb-modules/smsb-source/src/main/resources/mapper/SmsbItemProgramMapper.xml

@@ -18,4 +18,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <update id="updateNameById">
         UPDATE smsb_item_program SET name = #{name} WHERE id = #{id}
     </update>
+
+    <select id="selectVoByPushId" resultType="com.inspur.source.domain.vo.SmsbItemProgramVo" parameterType="Long">
+        SELECT
+            sip.*
+        FROM
+            smsb_item_program sip
+            INNER JOIN smsb_item si ON sip.id = si.program_id
+            INNER JOIN smsb_item_push_rel sipr ON sipr.item_id = si.ID
+        WHERE
+            sipr.push_id = #{pushId}
+    </select>
 </mapper>

+ 10 - 0
smsb-modules/smsb-source/src/main/resources/mapper/SmsbMinioDataMapper.xml

@@ -76,4 +76,14 @@
         FROM
             smsb_minio_data
     </select>
+
+    <select id="selectVoListByItemId" resultType="com.inspur.source.domain.vo.SmsbMinioDataVo" parameterType="Long">
+        SELECT
+            smd.*
+        FROM
+            smsb_minio_data smd
+            INNER JOIN smsb_item_file_rel sifr ON smd.id = sifr.file_id
+        WHERE
+            sifr.item_id = #{itemId}
+    </select>
 </mapper>

+ 5 - 3
smsb-plus-ui/src/api/smsb/source/item_push_type.ts

@@ -36,11 +36,13 @@ export interface ItemPushVO {
 
   taskId: number;
 
-  deviceList ?: any;
+  deviceList?: any;
 
-  resourceList ?: any;
+  resourceList?: any;
 
-  timeList ?: any;
+  timeList?: any;
+
+  programId?: number | string;
 }
 
 export interface PushTimeVO {

+ 3 - 1
smsb-plus-ui/src/layout/components/Sidebar/index.vue

@@ -30,7 +30,9 @@ const topMenus = computed(() => permissionStore.getTopbarRoutes().filter((menu)
 const currentTopMenuPath = computed(() => {
   // console.log("[Sidebar] route.path", route.path);
   // 特例
-  if (route.path === '/source/push/approval' || route.path.startsWith('/source/split/edit') || route.path.startsWith('/smsb/itemProgram/edit') || route.path.startsWith('/smsb/itemProgram/preview')) {
+  if (route.path === '/source/push/approval' || route.path === '/source/push/review'
+    || route.path.startsWith('/source/split/edit')
+    || route.path.startsWith('/smsb/itemProgram/edit') || route.path.startsWith('/smsb/itemProgram/preview')) {
     return '/source';
   }
   // 取当前路由的一级菜单 path

+ 2 - 2
smsb-plus-ui/src/views/smsb/deviceTask/index.vue

@@ -59,11 +59,11 @@
             <template #default="scope">
               <el-tooltip content="详情" placement="top">
                 <el-button link type="primary" icon="InfoFilled" @click="handleTaskDetail(scope.row)"
-                           v-hasPermi="['device:deviceTask:edit']"></el-button>
+                           v-hasPermi="['device:task:edit']"></el-button>
               </el-tooltip>
               <el-tooltip content="删除" placement="top">
                 <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
-                           v-hasPermi="['device:deviceTask:remove']"></el-button>
+                           v-hasPermi="['device:task:remove']"></el-button>
               </el-tooltip>
             </template>
           </el-table-column>

+ 6 - 6
smsb-plus-ui/src/views/smsb/itemProgram/index.vue

@@ -102,9 +102,9 @@
     </el-card>
     <!-- 添加或修改节目信息对话框 -->
     <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-      <el-form ref="itemProgramFormRef" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="节目名称" prop="name">
-          <el-input v-model="form.name" placeholder="请输入节目名称" />
+      <el-form ref="itemProgramFormRef" :model="form" :rules="rules" label-width="65px">
+        <el-form-item label="名称" prop="name">
+          <el-input v-model="form.name" placeholder="请输入分屏组名称" />
         </el-form-item>
         <el-form-item label="分辨率" prop="resolutionRatio">
           <el-select v-model="form.resolutionRatio" placeholder="请选择分辨率或自定义" filterable allow-create
@@ -178,7 +178,7 @@ const data = reactive<PageData<ItemProgramForm, ItemProgramQuery>>({
     params: {}
   },
   rules: {
-    name: [{ required: true, message: '节目名称不能为空', trigger: 'blur' }],
+    name: [{ required: true, message: '分屏组名称不能为空', trigger: 'blur' }],
     resolutionRatio: [
       { required: true, message: '分辨率不能为空', trigger: 'blur' },
       { pattern: /^\d+x\d+$/, message: '请输入如1920x1080的分辨率', trigger: 'blur' }
@@ -251,7 +251,7 @@ const handleSelectionChange = (selection: ItemProgramVO[]) => {
 const handleAdd = () => {
   reset();
   dialog.visible = true;
-  dialog.title = '添加节目信息';
+  dialog.title = '添加分屏组';
 };
 
 /** 修改按钮操作 */
@@ -287,7 +287,7 @@ const submitForm = () => {
 /** 删除按钮操作 */
 const handleDelete = async (row?: ItemProgramVO) => {
   const _ids = row?.id || ids.value;
-  await proxy?.$modal.confirm('是否确认删除节目信息编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
+  await proxy?.$modal.confirm('是否确认删除分屏组编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
   await delItemProgram(_ids);
   proxy?.$modal.msgSuccess('删除成功');
   await getList();

+ 16 - 3
smsb-plus-ui/src/views/smsb/itemPush/approval.vue

@@ -1,12 +1,14 @@
 <template>
   <div class="p-2">
-    <el-card shadow="always" style="height: 50px">
+    <el-card shadow="always" style="height: 65px;margin-top: 10px">
       <div style="display: flex; justify-content: space-between">
         <div>
           <!--          <el-button v-if="submitButtonShow" :loading="buttonLoading" type="info" @click="submitForm('draft')">暂存</el-button>-->
           <!--          <el-button v-if="submitButtonShow" :loading="buttonLoading" type="primary" @click="submitForm('submit')">提 交</el-button>-->
           <el-button v-if="approvalButtonShow" :loading="buttonLoading" type="primary" @click="approvalVerifyOpen"> 审批
           </el-button>
+          <el-button v-if="viewFlag" type="primary" @click="handleView">预览
+          </el-button>
           <el-button v-if="itemPushBase && itemPushBase.id && itemPushBase.status !== 'draft'" type="primary"
             @click="handleApprovalRecord">
             流程进度
@@ -111,12 +113,15 @@ import { ItemPushForm, ItemPushQuery, ItemPushTimeRangeVO, ItemPushVO } from '@/
 import { DeviceVO } from '@/api/smsb/device/device_type';
 import { MinioDataVO } from '@/api/smsb/source/minioData_type';
 import { ElTable } from 'element-plus';
+import {useRouter} from "vue-router";
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const router = useRouter();
 const { smsb_push_type, smsb_push_level, smsb_push_state, smsb_source_type } = toRefs<any>(
   proxy?.useDict('smsb_push_type', 'smsb_push_level', 'smsb_push_state', 'smsb_source_type')
 );
 const approvalButtonShow = ref(false);
+const viewFlag = ref(false);
 const buttonLoading = ref(false);
 const loading = ref(true);
 //路由参数
@@ -166,7 +171,12 @@ const { form, rules } = toRefs(data);
 const reset = () => {
   form.value = { ...initFormData };
 };
-
+const handleView = () => {
+  router.push({
+    name: 'PreviewItemProgram',
+    params: { id: itemPushBase.value.programId }
+  });
+};
 /** 获取详情 */
 const getInfo = () => {
   loading.value = true;
@@ -184,6 +194,9 @@ const getInfo = () => {
     } else {
       approvalButtonShow.value = false;
     }
+    if (itemPushBase.value.itemType === 3 && itemPushBase.value.programId != null) {
+      viewFlag.value = true;
+    }
   });
 };
 
@@ -286,7 +299,7 @@ onMounted(() => {
 
 <style scoped>
 .custom-card {
-  margin-top: 20px;
+  margin-top: 10px;
   border-radius: 8px;
 }
 

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

@@ -208,17 +208,17 @@
         <!--发布内容-->
         <el-col :span="8" style="height: 100%; overflow: auto; padding-left: 10px">
           <!--轮播组-->
-          <div v-if="form.itemType === 1 || form.itemType === 2">
+          <div v-if="form.itemType === 1 || form.itemType === 3">
             <!--<el-table v-loading="loading" :data="itemList" @selection-change="handleSelectItem">
                             <el-table-column type="selection" width="55" align="center" />-->
             <el-table v-loading="loading" :data="itemList" style="height: 520px">
-              <el-table-column label="ID" width="200" align="left" :show-overflow-tooltip="true">
+              <el-table-column label="ID" width="220" align="left" :show-overflow-tooltip="true">
                 <template #default="{ row }">
                   <el-radio v-model="selectedRowId" :label="row.id" @change="handleRadioChange(row)" />
                 </template>
               </el-table-column>
               <el-table-column label="名称" align="left" prop="itemName" :show-overflow-tooltip="true" />
-              <el-table-column label="资源数量" align="center" prop="sourceNum" width="80" />
+<!--              <el-table-column label="资源数量" align="center" prop="sourceNum" width="80" />-->
               <!--
                             <el-table-column label="创建人" align="left" prop="createUser" width="100" :show-overflow-tooltip="true" />
               -->
@@ -435,7 +435,7 @@ const getDeviceList = async () => {
 
 const getItemList = async () => {
   transQueryParams.value.itemType = form.value.itemType;
-  if (form.value.itemType === 1 || form.value.itemType === 2) {
+  if (form.value.itemType === 1 || form.value.itemType === 3) {
     const res = await listItem(transQueryParams.value);
     itemList.value = res.rows;
     itemTotal.value = res.total;

+ 16 - 4
smsb-plus-ui/src/views/smsb/itemPush/review.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="p-2">
-    <el-card shadow="always">
+    <el-card shadow="always" style="height: 65px;margin-top: 10px">
       <div style="display: flex; justify-content: space-between">
         <div>
           <!--          <el-button v-if="submitButtonShow" :loading="buttonLoading" type="info" @click="submitForm('draft')">暂存</el-button>-->
@@ -8,6 +8,7 @@
 <!--
           <el-button v-if="approvalButtonShow" :loading="buttonLoading" type="primary" @click="approvalVerifyOpen"> 审批 </el-button>
 -->
+          <el-button v-if="viewFlag" type="primary" @click="handleView">预览</el-button>
           <el-button v-if="itemPushBase && itemPushBase.id && itemPushBase.status !== 'draft'" type="primary" @click="handleApprovalRecord">
             流程进度
           </el-button>
@@ -111,11 +112,14 @@ import { ItemPushForm, ItemPushQuery, ItemPushTimeRangeVO, ItemPushVO } from '@/
 import { DeviceVO } from '@/api/smsb/device/device_type';
 import { MinioDataVO } from '@/api/smsb/source/minioData_type';
 import { ElTable } from 'element-plus';
-
+import {useRouter} from "vue-router";
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const router = useRouter();
 const { smsb_push_type, smsb_push_level, smsb_push_state, smsb_source_type } = toRefs<any>(
   proxy?.useDict('smsb_push_type', 'smsb_push_level', 'smsb_push_state', 'smsb_source_type')
 );
+const viewFlag = ref(false);
 const approvalButtonShow = ref(false);
 const buttonLoading = ref(false);
 const loading = ref(true);
@@ -168,7 +172,12 @@ const reset = () => {
   form.value = { ...initFormData };
   leaveTime.value = [];
 };
-
+const handleView = () => {
+  router.push({
+    name: 'PreviewItemProgram',
+    params: { id: itemPushBase.value.programId }
+  });
+};
 /** 获取详情 */
 const getInfo = () => {
   loading.value = true;
@@ -186,6 +195,9 @@ const getInfo = () => {
     } else {
       approvalButtonShow.value = false;
     }
+    if (itemPushBase.value.itemType === 3 && itemPushBase.value.programId != null) {
+      viewFlag.value = true;
+    }
   });
 };
 
@@ -291,7 +303,7 @@ onMounted(() => {
 
 <style scoped>
 .custom-card {
-  margin-top: 20px;
+  margin-top: 10px;
   border-radius: 8px;
 }
 

+ 2 - 2
smsb-plus-ui/src/views/smsb/otaRecord/index.vue

@@ -17,10 +17,10 @@
             <el-form-item>
               <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
               <el-button icon="Refresh" @click="resetQuery">重置</el-button>
-              <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:otaRecord:add']"> 新增
+              <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['device:otaRecord:add']"> 新增
               </el-button>
               <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
-                v-hasPermi="['system:otaRecord:remove']">删除
+                v-hasPermi="['device:otaRecord:remove']">删除
               </el-button>
             </el-form-item>
           </el-form>