|
@@ -1,6 +1,7 @@
|
|
|
<script setup name="reportChapterList">
|
|
|
import {computed, nextTick, reactive, ref} from 'vue'
|
|
|
import { useRoute, useRouter } from "vue-router";
|
|
|
+import { V3ColorPicker } from "v3-color-picker-teleport"
|
|
|
import apiReport from '@/api/report'
|
|
|
import { apiGetWXQRCodeImg,getSystemInfo } from '@/api/common'
|
|
|
import moment from 'moment';
|
|
@@ -12,13 +13,17 @@ import {usePublicSettingStore} from '@/store/modules/publicSetting'
|
|
|
import EditBaseInfo from './components/EidtBaseInfo.vue'
|
|
|
import ReportPublishTimeSet from '../components/ReportPublishTimeSet.vue'
|
|
|
import html2canvas from "html2canvas";
|
|
|
-import {transfImgTobase64} from '@/hooks/common'
|
|
|
+import {transfImgTobase64,isWeiXin} from '@/hooks/common'
|
|
|
import draggable from 'vuedraggable'
|
|
|
import {reportManageBtn,useAuthBtn} from '@/hooks/useAuthBtn'
|
|
|
import {useReportApprove} from '@/hooks/useReportApprove'
|
|
|
import AddReportBaseInfoV2 from '../components/AddReportBaseInfoV2.vue'
|
|
|
import EditChapterBaseInfo from './components/EditChapterBaseInfo.vue'
|
|
|
+import ReportLayoutImg from '../smartReport/components/ReportLayoutImg.vue'
|
|
|
import { useReportHandles } from '../hooks/useReport'
|
|
|
+import AudioBox from '../components/AudioBox.vue'
|
|
|
+import {useUploadFileToOSS} from '@/hooks/useUploadFileToOSS'
|
|
|
+import MD5 from 'js-md5'
|
|
|
|
|
|
const cachedViewsStore=useCachedViewsStore()
|
|
|
const publicSettingStore = usePublicSettingStore()
|
|
@@ -128,25 +133,6 @@ async function getChapterList(){
|
|
|
}
|
|
|
|
|
|
|
|
|
-// 水印
|
|
|
-const waterMarkStr=ref('')
|
|
|
-function getSystemInfoFun(){
|
|
|
- getSystemInfo().then(res=>{
|
|
|
- if(res.Ret===200){
|
|
|
- const systemUserInfo=res.Data
|
|
|
- // 设置水印文案
|
|
|
- let waterMarkString=''
|
|
|
- if(systemUserInfo){
|
|
|
- waterMarkString=`${systemUserInfo.RealName}${systemUserInfo.Mobile?systemUserInfo.Mobile:systemUserInfo.Email}`
|
|
|
- waterMarkString=encodeURIComponent(waterMarkString)
|
|
|
- waterMarkStr.value=Base64.encode(waterMarkString)
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-getSystemInfoFun()
|
|
|
-
|
|
|
-
|
|
|
/* 章节操作弹窗 */
|
|
|
const showItemOpt = ref(false)
|
|
|
const activeItem = ref(null)
|
|
@@ -169,7 +155,7 @@ function handleChapterBaseInfoSave() {
|
|
|
}
|
|
|
|
|
|
|
|
|
-const { handleSubmitReport } = useReportHandles()
|
|
|
+const { handlePublishReportHook,handleDSPublish,showDSFBTime } = useReportHandles()
|
|
|
/* 发布报告 */
|
|
|
async function handlePublishReportCheck(tp) {
|
|
|
//校验章节是否都已发布
|
|
@@ -188,130 +174,14 @@ async function handlePublishReportCheck(tp) {
|
|
|
async function handlePublishReport(tp) {
|
|
|
cachedViewsStore.removeCaches('ReportList')
|
|
|
|
|
|
- if(tp==='dsfb'){
|
|
|
- showDSFBTime.value=true
|
|
|
- return
|
|
|
- }else if(tp==='submit'){
|
|
|
- handleSubmitReport({id:Number(route.query.id)})
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- let sendMsg = reportInfo.value.MsgIsSend;
|
|
|
- if(sendMsg===1){
|
|
|
- reportPublish({sendMsg: false})
|
|
|
- }else {
|
|
|
- const isPost = checkAuthBtn(reportManageBtn.reportManage_sendMsg)
|
|
|
-
|
|
|
- showDialog({
|
|
|
- title: '发布提示',
|
|
|
- showCancelButton: true,
|
|
|
- message: isPost?'发布后,是否推送模板消息?':'是否立即发布报告?',
|
|
|
- confirmButtonText: isPost?'推送':'发布',
|
|
|
- cancelButtonText: isPost?'不推送':'取消',
|
|
|
- }).then(() => {
|
|
|
- reportPublish({sendMsg: isPost?true:false})
|
|
|
- })
|
|
|
- .catch(() => {
|
|
|
- if(isPost) reportPublish({sendMsg: false});
|
|
|
- });
|
|
|
-
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-async function reportPublish({sendMsg}){
|
|
|
- const res=await apiReport.reportPublish({ReportIds:String(route.query.id),ReportUrl:generatePdfLinks()})
|
|
|
- if(res.Ret===200){
|
|
|
- sendMsg && apiReport.reportMessageSend({ReportId: Number(route.query.id)})
|
|
|
-
|
|
|
- showToast('发布成功')
|
|
|
- console.log('back');
|
|
|
- setTimeout(() => {
|
|
|
- router.back()
|
|
|
- },1000)
|
|
|
- }
|
|
|
-}
|
|
|
-function generatePdfLinks(){
|
|
|
- let code = reportInfo.value.ReportCode
|
|
|
-
|
|
|
- return `${publicSettingStore.publicSetting.ReportViewUrl}/reportshare_pdf?code=${code}&flag=${waterMarkStr.value}`
|
|
|
+ handlePublishReportHook(tp,reportInfo.value)
|
|
|
}
|
|
|
|
|
|
|
|
|
// 定时发布报告选择时间
|
|
|
-const showDSFBTime=ref(false)
|
|
|
function onConfirmDSFBTime(time){
|
|
|
|
|
|
- if(reportInfo.value.MsgIsSend===1){//已经推送过了
|
|
|
- apiReport.reportPublishTimeSet({
|
|
|
- ReportId:reportInfo.value.Id,
|
|
|
- PrePublishTime:time,
|
|
|
- PreMsgSend:0,
|
|
|
- ReportUrl:generatePdfLinks()
|
|
|
- }).then(res=>{
|
|
|
- if(res.Ret===200){
|
|
|
- showToast('定时发布成功!')
|
|
|
- setTimeout(() => {
|
|
|
- router.back()
|
|
|
- }, 1000);
|
|
|
- }
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- const isAuthPushMsg=checkAuthBtn(reportManageBtn.reportManage_sendMsg)
|
|
|
- showDialog({
|
|
|
- title: '提示',
|
|
|
- message:isAuthPushMsg?'是否发布定时报告,并推送模板消息?':'是否发布定时报告',
|
|
|
- confirmButtonText:isAuthPushMsg?'推送':'确定',
|
|
|
- cancelButtonText:isAuthPushMsg?'不推送':'取消',
|
|
|
- showCancelButton:true
|
|
|
- }).then(()=>{
|
|
|
- if(!isAuthPushMsg){
|
|
|
- apiReport.reportPublishTimeSet({
|
|
|
- ReportId:reportInfo.value.Id,
|
|
|
- PrePublishTime:time,
|
|
|
- PreMsgSend:0,
|
|
|
- ReportUrl:generatePdfLinks()
|
|
|
- }).then(res=>{
|
|
|
- if(res.Ret===200){
|
|
|
- showToast('定时发布成功!')
|
|
|
- setTimeout(() => {
|
|
|
- router.back()
|
|
|
- }, 1000);
|
|
|
- }
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- //推送
|
|
|
- apiReport.reportPublishTimeSet({
|
|
|
- ReportId:reportInfo.value.Id,
|
|
|
- PrePublishTime:time,
|
|
|
- PreMsgSend:1,
|
|
|
- ReportUrl:generatePdfLinks()
|
|
|
- }).then(res=>{
|
|
|
- if(res.Ret===200){
|
|
|
- showToast('定时发布成功!')
|
|
|
- setTimeout(() => {
|
|
|
- router.back()
|
|
|
- }, 1000);
|
|
|
- }
|
|
|
- })
|
|
|
- }).catch(()=>{
|
|
|
- if(!isAuthPushMsg) return
|
|
|
- //不推送
|
|
|
- apiReport.reportPublishTimeSet({
|
|
|
- ReportId:reportInfo.value.Id,
|
|
|
- PrePublishTime:time,
|
|
|
- PreMsgSend:0,
|
|
|
- ReportUrl:generatePdfLinks()
|
|
|
- }).then(res=>{
|
|
|
- if(res.Ret===200){
|
|
|
- showToast('定时发布成功!')
|
|
|
- setTimeout(() => {
|
|
|
- router.back()
|
|
|
- }, 1000);
|
|
|
- }
|
|
|
- })
|
|
|
- })
|
|
|
+ handleDSPublish(time,reportInfo.value)
|
|
|
}
|
|
|
|
|
|
/* 预览报告 */
|
|
@@ -347,8 +217,71 @@ function handleDelChapter(item) {
|
|
|
}
|
|
|
|
|
|
/* 上传章节音频 */
|
|
|
-function handleUploadChapterAudio(item) {
|
|
|
- showItemOpt.value = false
|
|
|
+// 上传音频
|
|
|
+const showUploadAudio=ref(false)
|
|
|
+const temAudioData=reactive({
|
|
|
+ time:0,
|
|
|
+ size:0,
|
|
|
+ url:'',
|
|
|
+})
|
|
|
+function handleShowUploadAudio(){
|
|
|
+ temAudioData.time=activeItem.value.audioDuration
|
|
|
+ temAudioData.size=activeItem.value.audioSize
|
|
|
+ temAudioData.url=activeItem.value.audioUrl
|
|
|
+ showUploadAudio.value=true
|
|
|
+}
|
|
|
+// 获取音频时长
|
|
|
+function handleGetAudioDuration(file){
|
|
|
+ return new Promise((resolve,reject)=>{
|
|
|
+ if(isWeiXin()){
|
|
|
+ console.log('微信?');
|
|
|
+ resolve(0)
|
|
|
+ }
|
|
|
+
|
|
|
+ const fileUrl=URL.createObjectURL(file)
|
|
|
+ const audioEl=new Audio(fileUrl)
|
|
|
+ audioEl.addEventListener('loadedmetadata',(e)=>{
|
|
|
+ console.log('e.path',e.path)
|
|
|
+ console.log('e.composedPath',e.composedPath())
|
|
|
+ console.log('获取音频时长',e.composedPath()[0].duration);
|
|
|
+ console.log(audioEl.duration);
|
|
|
+ const t=e.composedPath()[0].duration
|
|
|
+ resolve(t)
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+function handleAudioUploadBeforeRead(e){
|
|
|
+ const allowedTypes = ['audio/mpeg', 'audio/mp4','audio/aac','audio/x-m4a','audio/wav']
|
|
|
+ //由于部分安卓机的部分浏览器无法获取到文件类型,无法判断故先去除判断
|
|
|
+ // if(!allowedTypes.includes(e.type)){
|
|
|
+ // showToast('上传失败,上传音频格式不正确')
|
|
|
+ // return false
|
|
|
+ // }
|
|
|
+ return true
|
|
|
+}
|
|
|
+async function handleAudioUploadAfterRead(e){
|
|
|
+ // console.log(e);
|
|
|
+ const duration=await handleGetAudioDuration(e.file)
|
|
|
+
|
|
|
+ temAudioData.time=duration||0
|
|
|
+ temAudioData.size=e.file.size/1024/1024 //单位MB
|
|
|
+ temAudioData.name=e.file.name
|
|
|
+ console.log('音频数据temAudioData',temAudioData);
|
|
|
+ // 生成文件名
|
|
|
+ const t=new Date().getTime().toString()
|
|
|
+ const temName=`static/yb/audio/${import.meta.env.MODE}/${MD5(t)}.${e.file.type.split('/')[1]}`
|
|
|
+ console.log(temName);
|
|
|
+ temAudioData.url=await useUploadFileToOSS(e.file,temName)
|
|
|
+}
|
|
|
+function handleUpdateAudio(){
|
|
|
+ activeItem.value.audioUrl=temAudioData.url
|
|
|
+ activeItem.value.audioDuration=temAudioData.time
|
|
|
+ activeItem.value.audioSize=temAudioData.size
|
|
|
+ showUploadAudio.value=false
|
|
|
+}
|
|
|
+//更新下音频时长
|
|
|
+function handleUpdateAudioTime(e){
|
|
|
+ temAudioData.time=e
|
|
|
}
|
|
|
|
|
|
//章节拖动
|
|
@@ -447,12 +380,13 @@ async function goChapterDetail(item){
|
|
|
path:reportInfo.value.ReportLayout===1 ? '/report/edit' : "/smart_report/edit",
|
|
|
query:{
|
|
|
id:reportInfo.value.Id,
|
|
|
+ chapterId: item.ReportChapterId,
|
|
|
coopType: reportInfo.value.CollaborateType
|
|
|
}
|
|
|
})
|
|
|
}else {
|
|
|
router.push({
|
|
|
- path:'/report/chapter/detail',
|
|
|
+ path:'/report/chapter/preview',
|
|
|
query:{
|
|
|
id:item.ReportChapterId
|
|
|
}
|
|
@@ -498,14 +432,69 @@ async function handleShowPoster(item){
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+//显示版图设置弹窗
|
|
|
+const showLayoutSetPop = ref(false)
|
|
|
+const showLayoutImgPop = ref(false)
|
|
|
+const layoutState = reactive({
|
|
|
+ defaultType: 1,
|
|
|
+ bgColor: '',
|
|
|
+ headImg:'',//版头图片
|
|
|
+ endImg: '',//版尾图片
|
|
|
+ headImgId: 0,//版头Id
|
|
|
+ endImgId: 0,//版尾Id
|
|
|
+})
|
|
|
+function handleShowLayoutSet() {
|
|
|
+ layoutState.defaultType = 1
|
|
|
+ layoutState.bgColor = reportInfo.value.CanvasColor
|
|
|
+ layoutState.headImg = reportInfo.value.HeadImg
|
|
|
+ layoutState.endImg = reportInfo.value.EndImg
|
|
|
+ layoutState.headImgId = reportInfo.value.HeadResourceId
|
|
|
+ layoutState.endImgId = reportInfo.value.EndResourceId
|
|
|
+
|
|
|
+ showLayoutSetPop.value = true
|
|
|
+}
|
|
|
+//设置版图图片
|
|
|
+function handleConfirmSetLayoutImg(e) {
|
|
|
+ if(e.type===1){
|
|
|
+ layoutState.headImg=e.data.ImgUrl
|
|
|
+ layoutState.headImgId = e.data.ResourceId
|
|
|
+ }else{
|
|
|
+ layoutState.endImg=e.data.ImgUrl
|
|
|
+ layoutState.endImgId = e.data.ResourceId
|
|
|
+ }
|
|
|
+ showLayoutImgPop.value = false
|
|
|
+}
|
|
|
+async function handleConfirmSetLayout() {
|
|
|
+ const res = await apiReport.setReportLayoutImg({
|
|
|
+ ReportId: reportInfo.value.Id,
|
|
|
+ HeadImg: layoutState.headImg,
|
|
|
+ EndImg: layoutState.endImg,
|
|
|
+ HeadResourceId: layoutState.headImgId,
|
|
|
+ EndResourceId: layoutState.endImgId,
|
|
|
+ CanvasColor: layoutState.bgColor,
|
|
|
+ })
|
|
|
+
|
|
|
+ if(res.Ret !== 200) return
|
|
|
+
|
|
|
+ showToast('设置成功')
|
|
|
+
|
|
|
+ reportInfo.value.CanvasColor = layoutState.bgColor
|
|
|
+ reportInfo.value.HeadImg = layoutState.headImg
|
|
|
+ reportInfo.value.EndImg = layoutState.endImg
|
|
|
+ reportInfo.value.HeadResourceId = layoutState.headImgId
|
|
|
+ reportInfo.value.EndResourceId = layoutState.endImgId
|
|
|
+
|
|
|
+ showLayoutSetPop.value = false
|
|
|
+}
|
|
|
+
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
<div class="report-chapterlist-page" v-if="reportInfo">
|
|
|
- <!-- <van-cell title="基础信息" is-link @click="showBaseInfoPop=true"/> -->
|
|
|
<div class="chapter-list-wrap">
|
|
|
|
|
|
- <!-- <ul class="chapter-list"> -->
|
|
|
<draggable
|
|
|
class="chapter-list"
|
|
|
:list="chapterList"
|
|
@@ -547,8 +536,7 @@ async function handleShowPoster(item){
|
|
|
</div>
|
|
|
</li>
|
|
|
</template>
|
|
|
- </draggable>
|
|
|
- <!-- </ul> -->
|
|
|
+ </draggable>
|
|
|
|
|
|
<van-button
|
|
|
v-if="checkAuthBtn(reportManageBtn.reportMange_chapter_add)"
|
|
@@ -560,7 +548,11 @@ async function handleShowPoster(item){
|
|
|
|
|
|
<div class="bot-action-box">
|
|
|
<div class="action-box">
|
|
|
- <div class="item" @click="showBaseInfoPop=true">
|
|
|
+ <div class="item" @click="handleShowLayoutSet" v-if="reportInfo.ReportLayout===2&&isCreator">
|
|
|
+ <img src="@/assets/imgs/report/icon_set.png" alt="">
|
|
|
+ <span>版图设置</span>
|
|
|
+ </div>
|
|
|
+ <div class="item" @click="showBaseInfoPop=true" v-if="isCreator">
|
|
|
<img src="@/assets/imgs/report/icon_info.png" alt="">
|
|
|
<span>基础信息</span>
|
|
|
</div>
|
|
@@ -689,12 +681,69 @@ async function handleShowPoster(item){
|
|
|
<div class="item" @click="handleChapterInfo(activeItem)" v-if="isCreator">基础信息</div>
|
|
|
<div class="item" @click="handleDelChapter(activeItem)" v-if="isCreator">删除</div>
|
|
|
<div class="item" @click="handleShowTrendTag(activeItem)" v-permission="reportManageBtn.reportMange_chapter_editTag">添加标签</div>
|
|
|
- <div class="item" @click="handleUploadChapterAudio(activeItem)">上传录音</div>
|
|
|
+ <div class="item" @click="handleShowUploadAudio()">上传录音</div>
|
|
|
</div>
|
|
|
</van-action-sheet>
|
|
|
|
|
|
+ <!-- 版图设置 -->
|
|
|
+ <van-popup
|
|
|
+ v-model:show="showLayoutSetPop"
|
|
|
+ position="bottom"
|
|
|
+ :style="{height:'70%'}"
|
|
|
+ >
|
|
|
+ <div class="top-box">
|
|
|
+ <span style="color:#666666" @click="showLayoutSetPop=false">取消</span>
|
|
|
+ <span class="title">版图设置</span>
|
|
|
+ <span style="color:#0052D9" @click="handleConfirmSetLayout">确定</span>
|
|
|
+ </div>
|
|
|
+ <van-cell-group>
|
|
|
+ <van-cell
|
|
|
+ title="版头设置"
|
|
|
+ is-link
|
|
|
+ @click="layoutState.defaultType=1;showLayoutImgPop=true"
|
|
|
+ />
|
|
|
+ <div class="show-wrapper" v-if="layoutState.headImg">
|
|
|
+ <img :src="layoutState.headImg" width="100" height="100">
|
|
|
+ </div>
|
|
|
+ </van-cell-group>
|
|
|
+ <van-cell-group>
|
|
|
+ <van-cell
|
|
|
+ title="版尾设置"
|
|
|
+ is-link
|
|
|
+ @click="layoutState.defaultType=2;showLayoutImgPop=true;"
|
|
|
+
|
|
|
+ />
|
|
|
+ <div class="show-wrapper" v-if="layoutState.endImg">
|
|
|
+ <img :src="layoutState.endImg" width="100" height="100">
|
|
|
+ </div>
|
|
|
+ </van-cell-group>
|
|
|
+ <van-cell-group>
|
|
|
+ <div class="show-wrapper">
|
|
|
+ <span style="margin-right: 20px">背景色</span>
|
|
|
+ <V3ColorPicker v-model:value="layoutState.bgColor" :zIndex="9999"/>
|
|
|
+ </div>
|
|
|
+ </van-cell-group>
|
|
|
+ </van-popup>
|
|
|
+
|
|
|
+ <!-- 版图图片设置 -->
|
|
|
+ <van-popup
|
|
|
+ v-model:show="showLayoutImgPop"
|
|
|
+ position="bottom"
|
|
|
+ >
|
|
|
+ <ReportLayoutImg
|
|
|
+ v-if="showLayoutImgPop"
|
|
|
+ :defaultVal="layoutState.defaultType"
|
|
|
+ @close="showLayoutImgPop=false"
|
|
|
+ @confirm="handleConfirmSetLayoutImg"
|
|
|
+ />
|
|
|
+ </van-popup>
|
|
|
+
|
|
|
<!-- 定时发布选择时间 -->
|
|
|
- <ReportPublishTimeSet v-model="showDSFBTime" :prePublishTime="reportInfo?.PrePublishTime" @confirm="onConfirmDSFBTime" />
|
|
|
+ <ReportPublishTimeSet
|
|
|
+ v-model="showDSFBTime"
|
|
|
+ :prePublishTime="reportInfo?.PrePublishTime"
|
|
|
+ @confirm="onConfirmDSFBTime"
|
|
|
+ />
|
|
|
|
|
|
<!-- 海报dom模块 -->
|
|
|
<div v-if="chapterItemPosterInfo" class="select-text-disabled chapter-poster-box" id="chapter-poster-box">
|
|
@@ -893,14 +942,56 @@ async function handleShowPoster(item){
|
|
|
background: #eee;
|
|
|
}
|
|
|
.item{
|
|
|
- padding: 10px 0;
|
|
|
+ padding: 20px 0;
|
|
|
text-align: center;
|
|
|
line-height: 48px;
|
|
|
font-size: 32px;
|
|
|
border-top: 1px solid $border-color;
|
|
|
}
|
|
|
}
|
|
|
+.upload-audio-wrap{
|
|
|
+ height: 100%;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ padding: $page-padding;
|
|
|
+ p{
|
|
|
+ color: rgba(0, 0, 0, 0.6);
|
|
|
+ padding-bottom: 32px;
|
|
|
+ border-bottom: 1px solid $border-color;
|
|
|
+ margin-bottom: 32px;
|
|
|
+ word-wrap: break-word;
|
|
|
+ }
|
|
|
+ .bot-btns{
|
|
|
+ // width: 100%;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ padding: 20px 0;
|
|
|
+ text-align: center;
|
|
|
+ .bot-btn{
|
|
|
+ width: 315px;
|
|
|
+ margin: 0 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
+.top-box{
|
|
|
+ padding:32px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ border-bottom: 1px solid #DCDFE6;
|
|
|
+ .close{
|
|
|
+ color:#666666;
|
|
|
+ }
|
|
|
+ .title{
|
|
|
+ font-size: 36px;
|
|
|
+ }
|
|
|
+ .add-btn{
|
|
|
+ color:$theme-color;
|
|
|
+ }
|
|
|
+}
|
|
|
+.show-wrapper {
|
|
|
+ padding: 20px;
|
|
|
+}
|
|
|
@media screen and (min-width:$media-width){
|
|
|
.report-chapterlist-page{
|
|
|
padding-bottom: 80px;
|
|
@@ -981,7 +1072,9 @@ async function handleShowPoster(item){
|
|
|
|
|
|
.report-item-action-box{
|
|
|
.item{
|
|
|
- font-size: 12px;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 20px;
|
|
|
+ padding: 20px 0;
|
|
|
}
|
|
|
}
|
|
|
}
|