<template> <div class="index"> <div class="b-title">群发列表 <el-button style="float: right; margin-bottom: 10px;" type="primary" plain @click="show = true">新建群发消息</el-button></div> <el-table :data="tableData" style="width: 100%"> <el-table-column type="expand"> <template slot-scope="props"> <el-table :border="false" :data="[JSON.parse(props.row.content)]"> <el-table-column label="类型" > <template slot-scope="item"> {{item.row.type | typeFilter}} </template> </el-table-column> <el-table-column v-if="JSON.parse(props.row.content).type !== 'text'" prop="media_id" label="media_id" > <template slot-scope="item"> {{item.row.content}} </template> </el-table-column> <el-table-column prop="url" label="内容" > <template slot-scope="item"> <div v-if="item.row.type === 'text'"> <span v-html="item.row.content.replace(/\/[\u4E00-\u9FA5]{1,3}/gi, emotion)"></span> </div> <div v-else-if="item.row.type === 'image'"> <img style="width: 80px;" :src="item.row.url"/> </div> <div v-else-if="item.row.type === 'video'"> <a :href="item.row.url" target="_blank">点击查看视频</a> </div> </template> </el-table-column> </el-table> </template> </el-table-column> <el-table-column prop="send_id" label="消息ID"> </el-table-column> <el-table-column label="消息类型"> <template slot-scope="scope"> {{ scope.row.type | typeListFilter}} </template> </el-table-column> <el-table-column prop="send_num" label="预计发送"> </el-table-column> <el-table-column prop="arrive_num" label="已发送"> </el-table-column> <el-table-column prop="failed_num" label="发送失败"> </el-table-column> <el-table-column prop="start_at" label="开始时间"> </el-table-column> <el-table-column prop="end_at" label="截止时间"> </el-table-column> <el-table-column prop="created_at" label="发送时间"> </el-table-column> <el-table-column label="操作" min-width="100" > <template slot-scope="scope"> <el-button @click="getMsgResult(scope.row.send_id)" type="text" plain size="mini"> 查询及时结果 </el-button> </template> </el-table-column> </el-table> <page :total="total" :limit="limit" @pageChange="onPageChange" @sizeChange="onSizeChange"/> <el-dialog title="新建群发消息" :visible.sync="show"> <el-form ref="searchFrom" :model="searchFrom" label-width="150px"> <el-form-item label="是否发送筛选用户"> <el-switch v-model="searchFrom.is_test" active-color="#13ce66" inactive-color="#ff4949"/> </el-form-item> <el-form-item label="时间" v-if="searchFrom.type === 1"> <el-date-picker v-model="searchFrom.time" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00','23:59:59']"> </el-date-picker> </el-form-item> <el-form-item label="类型"> <el-radio-group v-model="searchFrom.type"> <el-radio :label="1">48时内关注但未购课用户</el-radio> <el-radio :label="2">有体验课但没有正式课用户</el-radio> <el-radio :label="3">未试听用户</el-radio> <el-radio :label="4">指定用户手机号发送</el-radio> </el-radio-group> </el-form-item> <el-row v-if="searchFrom.type === 4"> <el-col :span="16"> <el-form-item label="用户手机号"> <el-input v-model="searchFrom.mobiles" placeholder="提示:多个手机号换行输入" type="textarea"></el-input> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="16"> <el-form-item label="用户ID"> <el-input v-model="searchFrom.user_ids"></el-input> </el-form-item> </el-col> <el-col :span="6" :offset="2"> <el-button type="primary" @click="onSelectUser">选择用户</el-button> </el-col> </el-row> <el-tabs v-model="activeName" type="card" @tab-click="handleClick"> <el-tab-pane label="文本" name="text"> <div class="inner-edit_area"> <el-input type="textarea" :autosize="{ minRows: 4, maxRows: 8}" placeholder="请输入内容" v-model="content"> </el-input> </div> <div style="float: right;margin-right:15px;"> <el-popover placement="bottom-end" width="400" :offset="10" trigger="hover" v-model="showEmotion"> <div> <emotion @emotion="handleEmotion" :height="200"></emotion> </div> <el-button @click="showEmotion = !showEmotion" slot="reference" type="text"> <span class="icon_emotion emotion_switch" ></span> </el-button> </el-popover> </div> </el-tab-pane> <el-tab-pane label="图片" name="image"> <div class="flex-start"> <div> <el-upload action="/api/public/upload/zone" :http-request="uploadFile" :before-upload="beforeAvatarUpload" list-type="picture-card" :file-list="imageList" :on-success="handleAvatarSuccess" :on-remove="handleRemove" :limit="1"> <i class="el-icon-plus"></i> </el-upload> </div> <div class="display-b" style="margin-left: 10px"> <div class="choose_item" style="color: #888;" @click="getMediaList()"><i class="el-icon-plus" style="color: #8c939d"></i>从素材库中选择</div> </div> </div> <div v-if="showImage && mediaImageList.length > 0"> <el-table :data="mediaImageList" @row-click="onChooseMedia" style="width: 100%"> <el-table-column prop="name" label="名称"> </el-table-column> <el-table-column prop="media_id" label="mediaId"> </el-table-column> <el-table-column label="URL"> <template slot-scope="scope"> <a :href="scope.row.url"> <img style="width: 60px;" :src="scope.row.url"/> </a> </template> </el-table-column> </el-table> <page-image :total="mediaImagePage.total" v-model="mediaImagePage.nowPage" :limit="mediaImagePage.limit" @pageChange="onImagePageChange" @sizeChange="onImageSizeChange"/> </div> </el-tab-pane> <el-tab-pane label="视频" name="video"> <div class="flex-start"> <el-upload class="upload-video" action="/api/public/upload/zone" :http-request="uploadVideo" :file-list="fileList" :on-remove="handleRemoveVideo" :limit="1"> <el-button size="small" type="primary" :disabled="(fileUid && progress < 99)">点击上传</el-button> <div style="width: 300px"> <el-progress v-if="fileUid" :percentage="progress"></el-progress> </div> </el-upload> <div class="display-b"> <div class="choose_item" style="color: #888;" @click="getMediaList()"><i class="el-icon-plus" style="color: #8c939d"></i>从素材库中选择</div> </div> </div> <div v-if="showVideo && mediaVideoList.length > 0"> <el-table :data="mediaVideoList" @row-click="onChooseMedia" style="width: 100%"> <el-table-column prop="name" label="名称"> </el-table-column> <el-table-column prop="media_id" label="mediaId"> </el-table-column> <el-table-column label="URL"> <template slot-scope="scope"> <a :href="scope.row.info.down_url" target="_blank" v-if="scope.row.info && scope.row.info.down_url"> {{scope.row.info.title}} </a> </template> </el-table-column> </el-table> <page :total="total" v-model="nowPage" :limit="limit" @pageChange="onPageChange" @sizeChange="onSizeChange"/> </div> </el-tab-pane> <el-tab-pane label="图文" name="news"> <div v-if="newsContent && newsContent.content && newsContent.content.news_item"> <div class="news-media" style="display: inline-block"> <el-card :body-style="{ padding: '0px' }"> <div v-for="(child, childIndex) in newsContent.content.news_item" style="position: relative"> <div v-if="newsContent.content.news_item.length === 1" class="single-cover"> <div class="title">{{child.title}}</div> <img :src="child.thumb_url" style="width: 100%;margin-top: 20px;"/> <div class="digest">{{child.digest}}</div> <a class="preview" :href="child.url" target="_blank"> 预览文章 </a> </div> <div v-else-if="newsContent.content.news_item.length > 1" class="clear-both bottomCover" style="position: relative"> <div v-if="childIndex === 0" class="muti-cover"> <img style="width: 100%;margin-top: 20px;" :src="child.thumb_url"/> <div class="bottom-title">{{child.title}}</div> </div> <div class="next-cover clear-both" v-else> <span class="next-title">{{child.title}}</span> <img class="next-img" :src="child.thumb_url"/> </div> <a class="preview" :href="child.url" target="_blank"> 预览文章 </a> </div> </div> </el-card> </div> <i class="el-icon-delete" @click="newsContent=''" style="display: inline-block"></i> </div> <div class="display-b"> <div class="choose_item" style="color: #888;" @click="getMediaList()"><i class="el-icon-plus" style="color: #8c939d"></i>从素材库中选择</div> </div> <div v-if="showMedia && mediaList.length > 0"> <el-table :data="mediaList" @row-click="onChooseMedia" style="width: 100%"> <el-table-column prop="media_id" label="mediaId"> </el-table-column> <el-table-column label="URL"> <template slot-scope="scope"> <div class="news-media" style="display: inline-block;width: 200px;" v-if="scope.row.content && scope.row.content.news_item"> <div v-for="(child, childIndex) in scope.row.content.news_item" style="position: relative"> <div v-if="scope.row.content.news_item.length === 1" class="single-cover"> <div class="title">{{child.title}}</div> <img :src="child.thumb_url" style="width: 100%;margin-top: 20px;"/> <div class="digest">{{child.digest}}</div> <a class="preview" :href="child.url" target="_blank"> 预览文章 </a> </div> <div v-else-if="scope.row.content.news_item.length > 1" class="clear-both bottomCover" style="position: relative"> <div v-if="childIndex === 0" class="muti-cover"> <img style="width: 100%;margin-top: 20px;" :src="child.thumb_url"/> <div class="bottom-title">{{child.title}}</div> </div> <div class="next-cover clear-both" v-else> <span class="next-title">{{child.title}}</span> <img class="next-img" :src="child.thumb_url"/> </div> <a class="preview" :href="child.url" target="_blank"> 预览文章 </a> </div> </div> </div> </template> </el-table-column> </el-table> <page2 :total="total" v-model="mediaPage.nowPage" :limit="mediaPage.limit" @pageChange="onMediaPageChange" @sizeChange="onMediaSizeChange"/> </div> </el-tab-pane> </el-tabs> </el-form> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="send()">确 定</el-button> </span> <el-dialog :visible.sync="userDialog.show" append-to-body> <el-form label-width="90px"> <el-row> <el-col :span="8"> <el-form-item label="ID"> <el-input v-model="searchUserFrom.userId"></el-input> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="昵称"> <el-input v-model="searchUserFrom.nickName"></el-input> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="电话"> <el-input v-model="searchUserFrom.mobile"></el-input> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="8" :offset="16"> <el-form-item> <el-button style="float: right" type="primary" plain @click="getUser">搜索</el-button> </el-form-item> </el-col> </el-row> </el-form> <el-table :data="userList" ref="multipleTable" @selection-change="handleSelectionChange" style="width: 100%"> <el-table-column type="selection" width="55"> </el-table-column> <el-table-column className="f-c" label="用户"> <template slot-scope="scope"> <img style="margin-right:5px;width: 50px;height: 50px;border-radius: 50px" :src="scope.row.avatar">{{scope.row.nickname}}(ID:{{scope.row.user_id}}) </template> </el-table-column> <el-table-column prop="mobile" label="手机号"> </el-table-column> </el-table> <page :total="userDialog.total" :limit="userDialog.limit" @pageChange="onUserPageChange" @sizeChange="onUserSizeChange"/> <span slot="footer" class="dialog-footer"> <el-button @click="userDialog.show = false">取 消</el-button> <el-button type="primary" @click="onConfirm">确 定</el-button> </span> </el-dialog> </el-dialog> </div> </template> <script> import { uploadFileApi, getMsgListApi, sendMsgApi, getUserListApi, getMediaListApi } from "../../service/api"; import page from "../framework/page"; import page2 from "../framework/page"; import pageImage from "../framework/page"; import pageVideo from "../framework/page"; import emotion from "../framework/Emotion/index"; import CommonJs from "../../util/common"; export default { name: "index", components: { page, page2, pageImage, pageVideo, emotion }, data() { return { nowPage: 1, total: 0, limit: 10, mediaPage: { nowPage: 1, total: 0, limit: 5 }, show: false, loading: false, activeName: "text", list: [], content: "", uploadShow: true, imageList: [], fileList: [], imageContent: "", videoContent: "", searchFrom: { type: 1, is_test: false }, tableData: [], fileUid: null, userDialog: { total: 0, limit: 10, nowPage: 1, show: false }, userList: [], searchUserFrom: {}, multipleSelection: [], showEmotion: false, showMedia: false, showImage: false, showVideo: false, mediaList: [], mediaImageList: [], mediaVideoList: [], mediaImagePage: { nowPage: 1, total: 0, limit: 5 }, mediaVideoPage: { nowPage: 1, total: 0, limit: 5 }, imageContent: null, videoContent: null, newsContent: null }; }, filters: { typeFilter(val) { if (!val) return; if (val === "text") return "文本"; if (val === "image") return "图片"; if (val === "video") return "视频"; if (val === "news") return "图文"; }, typeListFilter(val) { if (!val) return ""; if (val === 1) return "48时内关注但未购课用户"; if (val === 2) return "有体验课但没有正式课用户"; if (val === 3) return "未试听用户"; if (val === 4) return "指定用户手机号"; } }, methods: { handleClick(tab) { this.activeName = tab.name; }, handleRemove() { this.uploadShow = true; this.imageList = []; this.imageContent = ""; }, handleRemoveVideo() { this.videoContent = ""; this.fileList = []; }, beforeAvatarUpload() { this.uploadShow = false; }, handleAvatarSuccess(res) { this.imageList = [ { name: res.data.url, url: process.env.IMAGE_URL_HEAD + res.data.url } ]; }, uploadFile(a) { this.$store.dispatch("setProgress", { type: "new", id: a.file.uid }); uploadFileApi({ file: a.file, type: "wechat" }) .then(res => { this.imageContent = { content: res.media_id, url: res.url }; this.imageList = [{ name: res.media_id, url: res.url }]; this.$message({ type: "success", message: "上传成功!" }); }) .catch(() => { this.$message({ type: "error", message: "上传失败!" }); }); }, uploadVideo(a) { uploadFileApi({ file: a.file, type: "wechat" }) .then(res => { this.uploadVideoFile(a, res); }) .catch(() => { this.$message({ type: "error", message: "上传失败!" }); }); }, uploadVideoFile(a, data) { this.fileUid = a.file.uid; this.loading = true; this.$store.dispatch("setProgress", { type: "new", id: a.file.uid }); uploadFileApi({ file: a.file, type: "local" }) .then(res => { this.videoContent = { content: data.media_id, url: process.env.IMAGE_URL_HEAD + res.url }; this.fileList = [ { name: res.name, url: process.env.IMAGE_URL_HEAD + res.url } ]; this.loading = false; this.$message({ type: "success", message: "上传成功!" }); this.$store.dispatch("setProgress", { type: "delete", id: a.file.uid }); this.fileUid = null; }) .catch(() => { this.loading = false; this.$message({ type: "error", message: "上传失败!" }); }); }, send() { let json = {}; json.type = this.searchFrom.type; let msgTips = this.searchFrom.is_test ? "发送筛选用户," : "不发送筛选用户,"; if (this.searchFrom.type === 1) { if (this.searchFrom.time && this.searchFrom.time.length > 0) { console.log("this.searchFrom.time", this.searchFrom.time); json.start_at = CommonJs.dateFmt( this.searchFrom.time[0], "yyyy-MM-dd hh:mm:ss" ); json.end_at = CommonJs.dateFmt( this.searchFrom.time[1], "yyyy-MM-dd hh:mm:ss" ); msgTips += "48时内关注但未购课用户(" + json.start_at + "~" + json.end_at + ","; } else { this.$message({ type: "error", message: "请选择时间!" }); return; } } else if (this.searchFrom.type === 2) { msgTips += "有体验课但没有正式课用户,"; } else if (this.searchFrom.type === 3) { msgTips += "未试听用户,"; } else if (this.searchFrom.type === 4) { if(!this.searchFrom.mobiles){ this.searchFrom.mobiles=""; } var str= this.searchFrom.mobiles //去掉空格 str = str.replace(/\ +/g,""); //去掉回车换行换为逗号 str = str.replace(/[\r\n]/g,","); } if (this.searchFrom.user_ids && this.searchFrom.type != 4) { json.user_ids = this.searchFrom.user_ids; console.log(json) msgTips += "用户ID:" + json.user_ids; }else if(this.searchFrom.mobiles){ if(this.searchFrom.user_ids==undefined){ }else{ json.user_ids = this.searchFrom.user_ids; msgTips += "用户ID:" + json.user_ids; } json.mobiles =str; msgTips += "指定手机号用户("+json.mobiles+"),"; } else { this.$message({ type: "error", message: "请加入内部人员!" }); return; } let _content = {}; _content.type = this.activeName; if (this.activeName === "text") { if (!this.content) { this.$message({ type: "error", message: "请输入文本!" }); return; } else { _content.content = this.content; } } else if (this.activeName === "image") { if (!this.imageContent) { this.$message({ type: "error", message: "请上传图片!" }); return; } else { _content.content = this.imageContent.content; _content.url = this.imageContent.url; } } else if (this.activeName === "video") { if (!this.videoContent) { this.$message({ type: "error", message: "请上传视频!" }); return; } else { _content.content = this.videoContent.content; _content.url = this.videoContent.url; } } else if (this.activeName === "news") { if (this.newsContent && this.newsContent.media_id) { _content.content = this.newsContent.media_id; } else { this.$message({ type: "error", message: "请选择图文!" }); } } json.content = JSON.stringify(_content); json.is_test = this.searchFrom.is_test ? 2 : 1; console.log("json", json); this.$confirm(msgTips, "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }) .then(() => { sendMsgApi(json).then(res => { this.$message({ message: res, type: "success" }); this.show = false; this.clearData(); this.getMsgList(); }); }) .catch(() => { this.$message({ type: "info", message: "已取消发送" }); }); }, clearData() { this.content = ""; this.videoContent = null; this.imageContent = null; this.newsContent = null; this.activeName === "text"; this.searchFrom = {}; this.fileList = []; this.imageList = []; }, getMsgList() { let json = { limit: this.limit, page: this.nowPage }; getMsgListApi(json).then(res => { this.tableData = res.list; this.total = res.total; }); }, onMediaPageChange(val) { this.mediaPage.nowPage = val; this.getMediaList(); }, onMediaSizeChange() { this.mediaPage.nowPage = 1; this.mediaPage.limit = val; this.getMediaList(); }, onImagePageChange(val) { this.mediaImagePage.nowPage = val; this.getMediaList(); }, onImageSizeChange(val) { this.mediaImagePage.nowPage = 1; this.mediaImagePage.limit = val; this.getMediaList(); }, onVideoPageChange(val) { this.mediaVideoPage.nowPage = val; this.getMediaList(); }, onVideoSizeChange(val) { this.mediaVideoPage.nowPage = 1; this.mediaVideoPage.limit = val; this.getMediaList(); }, onPageChange(val) { this.nowPage = val; this.getMsgList(); }, onSizeChange(val) { this.nowPage = 1; this.limit = val; this.getMsgList(); }, getMsgResult(id) { if (!id) return; let json = { only_text: 1, send_id: id }; getMsgListApi(json).then(res => { this.$message({ message: res, type: "success" }); this.getMsgList(); }); }, getUser() { let json = { page: this.userDialog.nowPage, limit: this.userDialog.limit }; if (this.searchUserFrom.userId) { json.user_id = this.searchUserFrom.userId; } if (this.searchUserFrom.nickName) { json.nickname = this.searchUserFrom.nickName; } if (this.searchUserFrom.mobile) { json.mobile = this.searchUserFrom.mobile; } getUserListApi(json).then(res => { this.userList = res.list; this.userDialog.total = res.total; }); }, onUserPageChange(val) { this.userDialog.nowPage = val; this.getUser(); }, onUserSizeChange(val) { this.userDialog.nowPage = 1; this.userDialog.limit = val; this.getUser(); }, handleSelectionChange(val) { this.multipleSelection = val; }, onSelectUser() { this.userDialog.show = true; if (this.searchFrom.user_ids) { this.multipleSelection = this.searchFrom.user_ids.split(","); } else { this.multipleSelection = []; } this.getUser(); }, onConfirm() { let _list = this.multipleSelection; if (_list.length === 0) { this.$message({ type: "error", message: "请选择用户!" }); } else { let _userIds = []; _list.forEach(item => { _userIds.push(item.user_id); }); let _tmp = _userIds; if (this.searchFrom.user_ids) { _tmp = _userIds.concat( this.stringToInt(this.searchFrom.user_ids.split(",")) ); } let _result = this.dedupe(_tmp); this.searchFrom.user_ids = _result.join(","); this.userDialog.show = false; } }, dedupe(array) { return Array.from(new Set(array)); }, stringToInt(list) { let _list = list || []; _list = _list.map(val => { return parseInt(val, 10); }); return _list; }, emotion(res) { let word = res.replace(/\//gi, ""); const list = [ "微笑", "撇嘴", "色", "发呆", "得意", "流泪", "害羞", "闭嘴", "睡", "大哭", "尴尬", "发怒", "调皮", "呲牙", "惊讶", "难过", "酷", "冷汗", "抓狂", "吐", "偷笑", "可爱", "白眼", "傲慢", "饥饿", "困", "惊恐", "流汗", "憨笑", "大兵", "奋斗", "咒骂", "疑问", "嘘", "晕", "折磨", "衰", "骷髅", "敲打", "再见", "擦汗", "抠鼻", "鼓掌", "糗大了", "坏笑", "左哼哼", "右哼哼", "哈欠", "鄙视", "委屈", "快哭了", "阴险", "亲亲", "吓", "可怜", "菜刀", "西瓜", "啤酒", "篮球", "乒乓", "咖啡", "饭", "猪头", "玫瑰", "凋谢", "示爱", "爱心", "心碎", "蛋糕", "闪电", "炸弹", "刀", "足球", "瓢虫", "便便", "月亮", "太阳", "礼物", "拥抱", "强", "弱", "握手", "胜利", "抱拳", "勾引", "拳头", "差劲", "爱你", "NO", "OK", "爱情", "飞吻", "跳跳", "发抖", "怄火", "转圈", "磕头", "回头", "跳绳", "挥手", "激动", "街舞", "献吻", "左太极", "右太极" ]; let index = list.indexOf(word); return `<img src="https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/${index}.gif" align="middle">`; }, handleEmotion(i) { this.content += i; }, onChooseMedia(val) { console.log("onChooseMedia", val); if (this.type === "image") { this.imageContent = { content: val.media_id, url: val.url }; this.imageList = [{ name: val.media_id, url: val.url }]; this.showImage = false; } else if (this.type === "video") { this.videoContent = { content: val.media_id, url: val.info.down_url }; this.fileList = [{ name: val.info.title, url: val.info.url }]; this.showVideo = false; } else if (this.type === "news") { this.newsContent = val; this.showMedia = false; } }, getMediaList() { let type = this.activeName; let json = { type: type, page: this.mediaPage.nowPage, limit: this.mediaPage.limit }; if (type === "image") { json.page = this.mediaImagePage.nowPage; json.limit = this.mediaImagePage.limit; this.showImage = true; } else if (type === "video") { json.page = this.mediaVideoPage.nowPage; json.limit = this.mediaVideoPage.limit; this.showVideo = true; } else if (type === "news") { json.page = this.mediaPage.nowPage; json.limit = this.mediaPage.limit; this.showMedia = true; } this.loading = true; getMediaListApi(json) .then(res => { this.loading = false; this.type = type; this.mediaList = res.item; this.mediaPage.total = res.total_count; if (type === "image") { this.mediaImageList = res.item; this.mediaImagePage.total = res.total_count; } else if (type === "video") { this.mediaVideoList = res.item; this.mediaVideoPage.total = res.total_count; } else if (type === "news") { this.mediaList = res.item; this.mediaPage.total = res.total_count; } if (this.total === 0) { this.$message({ showClose: true, message: "暂无数据" }); } }) .catch(() => { this.loading = false; }); }, defaultTime() { let date = new Date(); let now_seconds = date.getTime(); let start_seconds = now_seconds - 48 * 60 * 60 * 1000; this.searchFrom.time = [new Date(start_seconds), new Date(now_seconds)]; } }, mounted() { this.getMsgList(); this.defaultTime(); }, computed: { progress() { return this.$store.state.progressList.find(i => { return i.id === this.fileUid; }).num < 100 ? this.$store.state.progressList.find(i => { return i.id === this.fileUid; }).num : 100; } } }; </script> <style scoped> .index { padding: 20px 0; } .top { margin-bottom: 30px; margin-left: 20px; } .title { font-size: 16px; font-weight: 400; display: block; line-height: 1.2; color: #353535; } .inner-edit_area { width: 96%; margin: 0 auto; } .upload-video { width: 50%; margin-left: 2%; } .b-title { padding: 20px; color: #666; } .emotion_switch { float: left; height: 28px; line-height: 999em; overflow: hidden; background: transparent url(https://res.wx.qq.com/mpres/en_US/htmledition/pages/modules/reply/images/icon_emotion_switch.png) no-repeat 0 0; width: 20px; height: 20px; vertical-align: middle; display: inline-block; } .img { position: relative; width: 25%; img { width: 100%; } .el-icon-delete { position: absolute; top: 50%; left: 50%; display: none; } } .img:hover img { opacity: 0.3; } .img:hover .el-icon-delete { display: block; } .tool_bar { float: right; margin-top: 20px; } .choose_item { box-sizing: border-box; margin-bottom: 25px; color: rgb(136, 136, 136); height: 148px; line-height: 148px; width: 148px; text-align: center; border: 1px dashed #c0ccda; border-radius: 6px; } .display-b { display: flex; flex-flow: row nowrap; justify-content: space-between; align-items: center; } .my-teacher { width: 25%; height: 80px; background-color: #eee; line-height: 80px; text-align: center; margin-bottom: 10px; } .news-media { padding: 10px; width: 25%; } .news-media img { width: 100%; } .s-news img { width: 50px; float: right; } .title { font-size: 16px; font-weight: 400; display: block; line-height: 1.2; color: #353535; } .digest { padding-top: 12px; color: #9a9a9a; font-size: 14px; } .single-cover { /*padding: 20px 15px 15px;*/ } .muti-cover { position: relative; padding: 20px 15px 0 15px; } .bottom-title { color: #ffffff; background-color: rgba(0, 0, 0, 0.55); position: absolute; left: 15px; right: 15px; bottom: 0; padding: 8px 12px; } .next-cover { padding: 12px 15px; position: relative; } .next-img { float: right; margin-left: 12px; width: 60px !important; height: 60px !important; } .next-title { overflow: hidden; font-weight: 400; word-wrap: break-word; -webkit-hyphens: auto; -ms-hyphens: auto; hyphens: auto; color: #353535; } .single-cover:hover .preview, .bottomCover:hover .preview { display: flex; justify-content: center; align-items: center; color: #fff; } .preview { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); text-decoration: none; } .f-bt { display: flex; position: relative; justify-content: space-between; align-items: flex-start; } .ellip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .flex-start { display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: flex-start; } </style> <style> .el-radio-group { display: flex !important; flex-flow: column; justify-content: flex-start; align-items: flex-start; } .el-radio + .el-radio { margin-left: 0 !important; } .el-radio { margin-bottom: 6px; } </style>