|
@@ -0,0 +1,277 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="new-app-container layout-vertical operation-setting-page">
|
|
|
|
|
+ <div class="operation-setting-panel">
|
|
|
|
|
+ <el-tabs v-model="activeTab" class="operation-tabs">
|
|
|
|
|
+ <el-tab-pane label="公告管理" name="list" />
|
|
|
|
|
+ <el-tab-pane label="公告日记" name="diary" />
|
|
|
|
|
+ </el-tabs>
|
|
|
|
|
+
|
|
|
|
|
+ <template v-if="activeTab === 'list'">
|
|
|
|
|
+ <el-form :model="list.query" class="operation-search" inline size="small" @submit.native.prevent="searchList">
|
|
|
|
|
+ <el-form-item label="公告分类"><el-select v-model="list.query.category" placeholder="请选择" clearable><el-option v-for="item in categoryOptions" :key="item.value" :label="item.label" :value="item.value" /></el-select></el-form-item>
|
|
|
|
|
+ <el-form-item label="发布平台"><el-select v-model="list.query.platform" placeholder="请选择" clearable><el-option label="全部" value="全部" /><el-option label="H5" value="H5" /><el-option label="App" value="App" /></el-select></el-form-item>
|
|
|
|
|
+ <el-form-item label="状态"><el-select v-model="list.query.status" placeholder="请选择" clearable><el-option label="启用" :value="1" /><el-option label="关闭" :value="0" /></el-select></el-form-item>
|
|
|
|
|
+ <el-form-item label="时间"><el-date-picker v-model="list.query.date_range" type="daterange" value-format="yyyy-MM-dd" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="disableFutureDate" /></el-form-item>
|
|
|
|
|
+ <el-form-item label="公告标题"><el-input v-model="list.query.title" placeholder="搜索公告标题" clearable /></el-form-item>
|
|
|
|
|
+ <el-form-item class="search-actions"><el-button type="primary" :loading="loading" @click="searchList">查询</el-button><el-button @click="resetList">重置</el-button></el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="page-notes">
|
|
|
|
|
+ <p v-for="(note, index) in listNotes" :key="index">{{ note }}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="operation-toolbar"><el-button type="primary" size="small" @click="createAnnouncement">新增</el-button></div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="operation-table-wrap"><el-table v-loading="loading" :data="list.rows" height="100%" class="operation-table">
|
|
|
|
|
+ <el-table-column label="序号" width="70" align="center"><template slot-scope="scope">{{ (list.page - 1) * list.limit + scope.$index + 1 }}</template></el-table-column>
|
|
|
|
|
+ <el-table-column prop="announcement_type" label="公告类型" min-width="120" align="center" />
|
|
|
|
|
+ <el-table-column prop="title" label="公告标题" min-width="220" align="center" />
|
|
|
|
|
+ <el-table-column prop="platform" label="发布平台" min-width="110" align="center" />
|
|
|
|
|
+ <el-table-column prop="frequency" label="展示频率" min-width="110" align="center" />
|
|
|
|
|
+ <el-table-column prop="send_time" label="发送时间" min-width="180" align="center" />
|
|
|
|
|
+ <el-table-column prop="end_time" label="结束时间" min-width="180" align="center" />
|
|
|
|
|
+ <el-table-column label="发送者" min-width="150" align="center"><template slot-scope="scope"><span class="sender-cell">批核者:<span class="sender-name">{{ scope.row.sender }}</span></span></template></el-table-column>
|
|
|
|
|
+ <el-table-column label="功能" width="150" align="center" fixed="right"><template slot-scope="scope"><el-button type="text" size="small" class="operation-link" @click="viewAnnouncement(scope.row)">查看</el-button><el-button type="text" size="small" class="operation-link danger-link" @click="toggleAnnouncement(scope.row)">{{ scope.row.status === 1 ? '关闭' : '开启' }}</el-button></template></el-table-column>
|
|
|
|
|
+ </el-table></div>
|
|
|
|
|
+ <el-pagination background class="operation-pagination" layout="total, sizes, prev, pager, next, jumper" :current-page="list.page" :page-size="list.limit" :page-sizes="pageSizes" :total="list.total" @size-change="changePageSize('list', $event)" @current-change="changePage('list', $event)" />
|
|
|
|
|
+ </template>
|
|
|
|
|
+
|
|
|
|
|
+ <template v-else>
|
|
|
|
|
+ <el-form :model="diary.query" class="operation-search" inline size="small" @submit.native.prevent="searchDiary">
|
|
|
|
|
+ <el-form-item label="时间"><el-date-picker v-model="diary.query.date_range" type="daterange" value-format="yyyy-MM-dd" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="disableFutureDate" /></el-form-item>
|
|
|
|
|
+ <el-form-item label="操作员账号"><el-input v-model="diary.query.operator" placeholder="搜索操作员账号" clearable /></el-form-item>
|
|
|
|
|
+ <el-form-item class="search-actions"><el-button type="primary" :loading="loading" @click="searchDiary">查询</el-button><el-button @click="resetDiary">重置</el-button></el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="operation-table-wrap"><el-table v-loading="loading" :data="diary.rows" height="100%" class="operation-table">
|
|
|
|
|
+ <el-table-column prop="date" label="日期" min-width="180" align="center" />
|
|
|
|
|
+ <el-table-column prop="operator" label="操作员账号" min-width="140" align="center" />
|
|
|
|
|
+ <el-table-column prop="item" label="操作项目" min-width="140" align="center" />
|
|
|
|
|
+ <el-table-column prop="target" label="发送对象" min-width="130" align="center" />
|
|
|
|
|
+ <el-table-column prop="old_value" label="旧值" min-width="120" align="center" />
|
|
|
|
|
+ <el-table-column prop="new_value" label="新值" min-width="120" align="center" />
|
|
|
|
|
+ </el-table></div>
|
|
|
|
|
+ <el-pagination background class="operation-pagination" layout="total, sizes, prev, pager, next, jumper" :current-page="diary.page" :page-size="diary.limit" :page-sizes="pageSizes" :total="diary.total" @size-change="changePageSize('diary', $event)" @current-change="changePage('diary', $event)" />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <Dialog ref="createDialog" :dialog-actions="{ width: '880px', title: '新增公告', buttom: false, confirmButtom: false }">
|
|
|
|
|
+ <template slot="content">
|
|
|
|
|
+ <el-form :model="form" label-width="120px" class="announcement-dialog-form">
|
|
|
|
|
+ <el-form-item label="公告标题"><el-input v-model="form.title" placeholder="请输入公告标题" /></el-form-item>
|
|
|
|
|
+ <el-form-item label="公告分类"><el-select v-model="form.category" placeholder="请选择"><el-option v-for="item in categoryOptions" :key="item.value" :label="item.label" :value="item.value" /></el-select></el-form-item>
|
|
|
|
|
+ <el-form-item label="发布时间"><el-date-picker v-model="form.send_time" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择发布时间" /><span class="inline-label">即使发布</span><el-switch v-model="form.publish_now" class="inline-switch" /></el-form-item>
|
|
|
|
|
+ <el-form-item label="结束时间"><el-date-picker v-model="form.end_time" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择结束时间" /><span class="inline-label">不需要结束</span><el-switch v-model="form.never_end" class="inline-switch" /></el-form-item>
|
|
|
|
|
+ <el-form-item label="发布平台"><el-checkbox-group v-model="form.platforms"><el-checkbox label="H5">H5</el-checkbox><el-checkbox label="App">App</el-checkbox></el-checkbox-group></el-form-item>
|
|
|
|
|
+ <el-form-item label="展示频率"><el-radio-group v-model="form.frequency"><el-radio label="每日首次登录">每日首次登录</el-radio><el-radio label="每次登录">每次登录</el-radio></el-radio-group></el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="form-section-title">公告设定</div>
|
|
|
|
|
+ <el-form-item label="图示点击行为"><el-radio-group v-model="form.click_action"><el-radio label="无链接">无链接</el-radio><el-radio label="外站链接">外站链接</el-radio><el-radio label="站内相对路径">站内相对路径</el-radio><el-radio label="优惠活动">优惠活动</el-radio></el-radio-group></el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item v-if="form.category === '弹出图片公告'" label="图片公告"><div class="upload-placeholder" :class="{ 'has-image': form.image }" @click="pickImage">
|
|
|
|
|
+ <template v-if="form.image">
|
|
|
|
|
+ <img :src="form.image" class="upload-thumb" alt="图片公告">
|
|
|
|
|
+ <span class="upload-replace">点击更换图片</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-else>
|
|
|
|
|
+ <span class="upload-plus">+</span>
|
|
|
|
|
+ <p>网页版图片建议 315 × 300</p>
|
|
|
|
|
+ <p>及(大于等于)同等比例, 300KB内</p>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </div><input ref="imageInput" type="file" accept="image/*" class="hidden-file" @change="onImageChange"></el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item v-else label="内容公告"><el-input v-model="form.content" type="textarea" :rows="8" placeholder="请输入内容" /></el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item label="状态"><el-switch v-model="form.status" :active-value="1" :inactive-value="0" /></el-form-item>
|
|
|
|
|
+ <div class="dialog-actions"><el-button type="primary" @click="submitAnnouncement">提交</el-button></div>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </Dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <Dialog ref="viewDialog" :dialog-actions="{ width: '720px', class: 'is-detail-dialog', title: '查看公告', confirmButtom: false, cancelButtom: true, buttonTextLeft: '关闭' }">
|
|
|
|
|
+ <template slot="content">
|
|
|
|
|
+ <el-form label-width="110px" class="announcement-detail-form">
|
|
|
|
|
+ <el-form-item label="公告类型"><span class="detail-text">{{ detail.announcement_type }}</span></el-form-item>
|
|
|
|
|
+ <el-form-item label="公告标题"><span class="detail-text">{{ detail.title }}</span></el-form-item>
|
|
|
|
|
+ <el-form-item label="发布平台"><span class="detail-text">{{ detail.platform }}</span></el-form-item>
|
|
|
|
|
+ <el-form-item label="展示频率"><span class="detail-text">{{ detail.frequency }}</span></el-form-item>
|
|
|
|
|
+ <el-form-item label="发送时间"><span class="detail-text">{{ detail.send_time }}</span></el-form-item>
|
|
|
|
|
+ <el-form-item label="结束时间"><span class="detail-text">{{ detail.end_time }}</span></el-form-item>
|
|
|
|
|
+ <el-form-item label="发送者"><span class="detail-text">{{ detail.sender }}</span></el-form-item>
|
|
|
|
|
+ <el-form-item label="状态"><span class="detail-text">{{ detail.status === 1 ? '启用' : '关闭' }}</span></el-form-item>
|
|
|
|
|
+ <el-form-item label="公告内容"><div class="detail-content">{{ detail.content }}</div></el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </Dialog>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script>
|
|
|
|
|
+import Dialog from '@/components/Dialog/index.vue'
|
|
|
|
|
+import { disableFutureDate } from '@/utils/index'
|
|
|
|
|
+
|
|
|
|
|
+const CATEGORY_OPTIONS = [
|
|
|
|
|
+ { label: '弹出内容公告', value: '弹出内容公告' },
|
|
|
|
|
+ { label: '弹出图片公告', value: '弹出图片公告' },
|
|
|
|
|
+ { label: '弹出更新公告', value: '弹出更新公告' }
|
|
|
|
|
+]
|
|
|
|
|
+
|
|
|
|
|
+export default {
|
|
|
|
|
+ name: 'AnnouncementManagement',
|
|
|
|
|
+ components: { Dialog },
|
|
|
|
|
+ data() {
|
|
|
|
|
+ return {
|
|
|
|
|
+ disableFutureDate,
|
|
|
|
|
+ pageSizes: [10, 20, 50, 100],
|
|
|
|
|
+ loading: false,
|
|
|
|
|
+ activeTab: 'list',
|
|
|
|
|
+ categoryOptions: CATEGORY_OPTIONS,
|
|
|
|
|
+ listNotes: ['公告分类:弹出图片公告 弹出内容公告 弹出更新公告'],
|
|
|
|
|
+ list: { page: 1, limit: 20, total: 0, query: { category: '', platform: '', status: '', date_range: [], title: '' }, rows: [] },
|
|
|
|
|
+ diary: { page: 1, limit: 20, total: 0, query: { date_range: [], operator: '' }, rows: [] },
|
|
|
|
|
+ form: {},
|
|
|
|
|
+ detail: {}
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ created() {
|
|
|
|
|
+ this.loadList()
|
|
|
|
|
+ this.loadDiary()
|
|
|
|
|
+ },
|
|
|
|
|
+ methods: {
|
|
|
|
|
+ newForm() {
|
|
|
|
|
+ return { title: '', category: '弹出内容公告', send_time: '', publish_now: true, end_time: '', never_end: true, platforms: ['H5', 'App'], frequency: '每日首次登录', click_action: '无链接', content: '', image: '', status: 1 }
|
|
|
|
|
+ },
|
|
|
|
|
+ pickImage() { this.$refs.imageInput.click() },
|
|
|
|
|
+ onImageChange(event) {
|
|
|
|
|
+ const file = event.target.files && event.target.files[0]
|
|
|
|
|
+ if (!file) return
|
|
|
|
|
+ if (file.size > 300 * 1024) { this.$message.warning('图片大小不能超过 300KB'); event.target.value = ''; return }
|
|
|
|
|
+ const reader = new FileReader()
|
|
|
|
|
+ reader.onload = () => { this.form.image = reader.result }
|
|
|
|
|
+ reader.readAsDataURL(file)
|
|
|
|
|
+ event.target.value = ''
|
|
|
|
|
+ },
|
|
|
|
|
+ mockList() {
|
|
|
|
|
+ const base = [
|
|
|
|
|
+ { announcement_type: '网站公告', title: '网站维护', category: '弹出内容公告', frequency: '每次登录' },
|
|
|
|
|
+ { announcement_type: '图片公告', title: '新年活动预告', category: '弹出图片公告', frequency: '每日首次登录' },
|
|
|
|
|
+ { announcement_type: '更新公告', title: '版本更新说明', category: '弹出更新公告', frequency: '每日首次登录' }
|
|
|
|
|
+ ]
|
|
|
|
|
+ return Array.from({ length: 19 }, (_, index) => {
|
|
|
|
|
+ const item = base[index % base.length]
|
|
|
|
|
+ const day = String((index % 9) + 1).padStart(2, '0')
|
|
|
|
|
+ return {
|
|
|
|
|
+ id: index + 1,
|
|
|
|
|
+ announcement_type: item.announcement_type,
|
|
|
|
|
+ title: item.title,
|
|
|
|
|
+ category: item.category,
|
|
|
|
|
+ platform: index % 3 === 0 ? '全部' : (index % 3 === 1 ? 'H5' : 'App'),
|
|
|
|
|
+ frequency: item.frequency,
|
|
|
|
|
+ send_time: `2025-03-${day} 12:12:09`,
|
|
|
|
|
+ end_time: `2025-03-${day} 23:59:59`,
|
|
|
|
|
+ sender: 'admin',
|
|
|
|
|
+ status: index % 4 === 0 ? 0 : 1,
|
|
|
|
|
+ content: `这是「${item.title}」的公告内容示例,用于验证页面排版与查看弹窗的展示效果。`
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ mockDiaryRows() {
|
|
|
|
|
+ const source = [
|
|
|
|
|
+ { item: '网站维护', target: '所有人', old_value: '修改', new_value: '启用' },
|
|
|
|
|
+ { item: '网站维护', target: '所有人', old_value: '启用', new_value: '修改' },
|
|
|
|
|
+ { item: '版本更新说明', target: '所有人', old_value: '关闭', new_value: '启用' }
|
|
|
|
|
+ ]
|
|
|
|
|
+ return Array.from({ length: 14 }, (_, index) => {
|
|
|
|
|
+ const row = source[index % source.length]
|
|
|
|
|
+ const day = String((index % 9) + 1).padStart(2, '0')
|
|
|
|
|
+ return {
|
|
|
|
|
+ id: index + 1,
|
|
|
|
|
+ date: `2025-03-${day} 22:${String(index % 60).padStart(2, '0')}:43`,
|
|
|
|
|
+ operator: 'hope123',
|
|
|
|
|
+ item: row.item,
|
|
|
|
|
+ target: row.target,
|
|
|
|
|
+ old_value: row.old_value,
|
|
|
|
|
+ new_value: row.new_value
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ loadList() {
|
|
|
|
|
+ this.loading = true
|
|
|
|
|
+ const query = this.list.query
|
|
|
|
|
+ const [start_date, end_date] = query.date_range || []
|
|
|
|
|
+ const rows = this.mockList().filter(row => {
|
|
|
|
|
+ const day = row.send_time.slice(0, 10)
|
|
|
|
|
+ if (query.category && row.category !== query.category) return false
|
|
|
|
|
+ if (query.platform && row.platform !== query.platform) return false
|
|
|
|
|
+ if (query.status !== '' && row.status !== query.status) return false
|
|
|
|
|
+ if (query.title && !row.title.includes(query.title)) return false
|
|
|
|
|
+ if (start_date && day < start_date) return false
|
|
|
|
|
+ if (end_date && day > end_date) return false
|
|
|
|
|
+ return true
|
|
|
|
|
+ })
|
|
|
|
|
+ const start = (this.list.page - 1) * this.list.limit
|
|
|
|
|
+ this.list.total = rows.length
|
|
|
|
|
+ this.list.rows = rows.slice(start, start + this.list.limit)
|
|
|
|
|
+ this.loading = false
|
|
|
|
|
+ },
|
|
|
|
|
+ loadDiary() {
|
|
|
|
|
+ const [start_date, end_date] = this.diary.query.date_range || []
|
|
|
|
|
+ const rows = this.mockDiaryRows().filter(row => {
|
|
|
|
|
+ const day = row.date.slice(0, 10)
|
|
|
|
|
+ if (start_date && day < start_date) return false
|
|
|
|
|
+ if (end_date && day > end_date) return false
|
|
|
|
|
+ return !this.diary.query.operator || row.operator.includes(this.diary.query.operator)
|
|
|
|
|
+ })
|
|
|
|
|
+ const start = (this.diary.page - 1) * this.diary.limit
|
|
|
|
|
+ this.diary.total = rows.length
|
|
|
|
|
+ this.diary.rows = rows.slice(start, start + this.diary.limit)
|
|
|
|
|
+ },
|
|
|
|
|
+ searchList() { this.list.page = 1; this.loadList() },
|
|
|
|
|
+ resetList() { this.list.query = { category: '', platform: '', status: '', date_range: [], title: '' }; this.list.page = 1; this.loadList() },
|
|
|
|
|
+ searchDiary() { this.diary.page = 1; this.loadDiary() },
|
|
|
|
|
+ resetDiary() { this.diary.query = { date_range: [], operator: '' }; this.diary.page = 1; this.loadDiary() },
|
|
|
|
|
+ changePage(key, page) { this[key].page = page; key === 'list' ? this.loadList() : this.loadDiary() },
|
|
|
|
|
+ changePageSize(key, limit) { this[key].limit = limit; this[key].page = 1; key === 'list' ? this.loadList() : this.loadDiary() },
|
|
|
|
|
+ createAnnouncement() { this.form = this.newForm(); this.$refs.createDialog.open() },
|
|
|
|
|
+ viewAnnouncement(row) { this.detail = row; this.$refs.viewDialog.open() },
|
|
|
|
|
+ toggleAnnouncement(row) {
|
|
|
|
|
+ const turningOn = row.status !== 1
|
|
|
|
|
+ this.$confirm(`确定${turningOn ? '开启' : '关闭'}这条公告吗?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
|
|
|
|
|
+ .then(() => {
|
|
|
|
|
+ row.status = turningOn ? 1 : 0
|
|
|
|
|
+ this.$message.success(turningOn ? '已开启' : '已关闭')
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(() => {})
|
|
|
|
|
+ },
|
|
|
|
|
+ submitAnnouncement() {
|
|
|
|
|
+ if (!this.form.title) { this.$message.warning('请输入公告标题'); return }
|
|
|
|
|
+ this.$refs.createDialog.close()
|
|
|
|
|
+ this.$message.success('提交成功')
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
|
+.operation-setting-page { height: 100%; padding: 16px; background: #f5f7fa; box-sizing: border-box; }
|
|
|
|
|
+.operation-setting-panel { display: flex; flex: 1; flex-direction: column; min-width: 0; min-height: 0; padding: 0 20px 12px; overflow: hidden; background: #fff; box-shadow: 0 1px 8px rgba(0, 0, 0, 0.08); }
|
|
|
|
|
+.operation-tabs { flex-shrink: 0; ::v-deep .el-tabs__header { margin: 0; } ::v-deep .el-tabs__item { height: 52px; line-height: 52px; font-weight: 500; } }
|
|
|
|
|
+.operation-search { display: flex; flex-wrap: wrap; align-items: center; flex-shrink: 0; padding-top: 16px; ::v-deep .el-form-item { display: flex; flex: 0 0 auto; align-items: center; margin-right: 28px !important; margin-bottom: 14px; white-space: nowrap; } ::v-deep .el-form-item__label { float: none; width: auto !important; padding: 0 8px 0 0; color: #303133; font-weight: 500; line-height: 32px; } ::v-deep .el-form-item__content { display: flex; align-items: center; margin-left: 0 !important; line-height: 32px; } ::v-deep .el-input { width: 180px; } ::v-deep .el-select { width: 180px; } ::v-deep .el-select .el-input { width: 100%; } ::v-deep .el-date-editor--daterange.el-input__inner { width: 300px; } .search-actions { margin-right: 0 !important; } }
|
|
|
|
|
+.operation-toolbar { display: flex; flex-shrink: 0; align-items: center; min-height: 42px; padding-bottom: 10px; }
|
|
|
|
|
+.operation-toolbar-title { color: #303133; font-size: 15px; font-weight: 500; }
|
|
|
|
|
+.operation-table-wrap { display: flex; flex: 1; min-height: 0; flex-direction: column; }
|
|
|
|
|
+.operation-table { flex: 1; ::v-deep th { height: 44px; background: #f5f7fa; } ::v-deep th .cell { color: #606266 !important; font-weight: 500; } ::v-deep td { height: 49px; } ::v-deep td .cell { color: #606266; font-size: 14px; } ::v-deep .el-table__fixed-right { height: 100% !important; } }
|
|
|
|
|
+.operation-link { margin: 0 4px; color: #3e7bfa; } .danger-link { color: #f56c6c; }
|
|
|
|
|
+.operation-pagination { flex-shrink: 0; padding-top: 12px; text-align: right; }
|
|
|
|
|
+.sender-cell { white-space: nowrap; } .sender-name { color: #3e7bfa; }
|
|
|
|
|
+.page-notes { flex-shrink: 0; padding: 16px 0 2px; p { margin: 0 0 2px; color: #f56c6c; font-size: 13px; line-height: 22px; } }
|
|
|
|
|
+.announcement-dialog-form { max-height: 580px; overflow-y: auto; padding: 12px 20px 0; ::v-deep .el-form-item { margin-bottom: 16px; } ::v-deep .el-input { width: 320px; } ::v-deep .el-select { width: 240px; } ::v-deep .el-select .el-input { width: 100%; } ::v-deep .el-textarea { width: 440px; } .inline-label { margin-left: 12px; color: #606266; } .inline-switch { margin-left: 6px; } .form-section-title { margin: 4px 0 16px 8px; color: #303133; font-size: 16px; font-weight: 600; } }
|
|
|
|
|
+.upload-placeholder { display: flex; flex-direction: column; justify-content: center; align-items: center; width: 300px; height: 190px; background: #eef0f4; border: 1px dashed #d9dce0; border-radius: 4px; color: #909399; cursor: pointer; overflow: hidden; p { margin: 2px 0; font-size: 13px; } .upload-plus { margin-bottom: 2px; color: #c0c4cc; font-size: 30px; line-height: 1; } &.has-image { position: relative; padding: 0; border-style: solid; } }
|
|
|
|
|
+.upload-thumb { width: 100%; height: 100%; object-fit: contain; }
|
|
|
|
|
+.upload-replace { position: absolute; bottom: 0; width: 100%; padding: 2px 0; background: rgba(0, 0, 0, 0.45); color: #fff; font-size: 12px; text-align: center; }
|
|
|
|
|
+.hidden-file { display: none; }
|
|
|
|
|
+.announcement-detail-form { padding: 4px 12px 0; ::v-deep .el-form-item { margin-bottom: 12px; } ::v-deep .el-form-item__label { line-height: 22px; } ::v-deep .el-form-item__content { color: #606266; line-height: 22px; } }
|
|
|
|
|
+.detail-text { color: #606266; line-height: 22px; word-break: break-all; }
|
|
|
|
|
+.detail-content { width: 100%; padding: 10px 12px; background: #f5f7fa; border-radius: 4px; line-height: 22px; white-space: pre-wrap; }
|
|
|
|
|
+.dialog-actions { padding: 8px 0 4px; text-align: center; }
|
|
|
|
|
+</style>
|