|
|
@@ -1,114 +1,120 @@
|
|
|
<template>
|
|
|
- <div style="padding: 5px">
|
|
|
- <el-card style="padding: 5px">
|
|
|
- <el-input
|
|
|
- v-model="textarea"
|
|
|
- type="textarea"
|
|
|
- maxlength="200"
|
|
|
- :rows="3"
|
|
|
- placeholder="有什么新鲜事想分享给大家?"
|
|
|
- style="padding: 5px"
|
|
|
- @blur="handleBlur"
|
|
|
- />
|
|
|
- <!-- <el-upload
|
|
|
- :action="actionUrl"
|
|
|
- style="padding: 5px"
|
|
|
+ <div class="publish-container">
|
|
|
+ <el-card class="publish-card shadow-sm" :body-style="{ padding: '15px' }">
|
|
|
+ <div class="input-wrapper">
|
|
|
+ <el-input
|
|
|
+ v-model="textarea"
|
|
|
+ type="textarea"
|
|
|
+ :autosize="{ minRows: 3, maxRows: 6 }"
|
|
|
+ maxlength="200"
|
|
|
+ show-word-limit
|
|
|
+ placeholder="有什么新鲜事想分享给大家?"
|
|
|
+ class="custom-textarea"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="publish-toolbar">
|
|
|
+ <div class="tool-left">
|
|
|
+ <el-button type="text" icon="el-icon-picture-outline" class="tool-btn" @click="onImage">
|
|
|
+ 图片
|
|
|
+ </el-button>
|
|
|
+ <el-button type="text" icon="el-icon-data-analysis" class="tool-btn" @click="createVote">
|
|
|
+ 投票
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ <div class="tool-right">
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ round
|
|
|
+ :disabled="!textarea.trim() && !vote"
|
|
|
+ class="send-btn"
|
|
|
+ @click="onSubmit"
|
|
|
>
|
|
|
- </el-upload>-->
|
|
|
- <el-button style="padding: 5px" icon="el-icon-picture" @click="onImage">图片</el-button>
|
|
|
- <el-button style="padding: 5px" icon="el-icon-tickets" @click="createVote">投票</el-button>
|
|
|
- <el-row style="text-align: right">
|
|
|
- <el-button round type="submit" @click="onSubmit">发送</el-button>
|
|
|
- </el-row>
|
|
|
+ 发布
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
|
|
|
- <el-dialog :visible.sync="dialogVisible">
|
|
|
- <img width="100%" :src="dialogImageUrl" alt="">
|
|
|
- </el-dialog>
|
|
|
- <el-dialog
|
|
|
- title="创建投票"
|
|
|
+ <transition name="el-zoom-in-top">
|
|
|
+ <div v-if="vote" class="vote-preview-box">
|
|
|
+ <div class="vote-preview-header">
|
|
|
+ <span class="vote-tag"><i class="el-icon-tickets"></i> 投票预设</span>
|
|
|
+ <el-button type="text" icon="el-icon-close" class="close-vote" @click="vote = null"></el-button>
|
|
|
+ </div>
|
|
|
+ <h4 class="vote-title">{{ vote.title }}</h4>
|
|
|
+ <div class="vote-options-list">
|
|
|
+ <div
|
|
|
+ v-for="(opt, idx) in vote.options"
|
|
|
+ :key="idx"
|
|
|
+ class="vote-option-item"
|
|
|
+ :class="{ 'is-selected': checkedRadio === opt.value }"
|
|
|
+ @click="checkedRadio = opt.value; singleCheckChange(opt)"
|
|
|
+ >
|
|
|
+ <el-radio v-model="checkedRadio" :label="opt.value">{{ opt.name }}</el-radio>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="vote-footer">
|
|
|
+ <span class="vote-info">截止日期: {{ formatDate(vote.endTime) }}</span>
|
|
|
+ <el-button type="primary" size="mini" plain @click="submit">测试提交</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </transition>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <el-dialog
|
|
|
+ title="新建投票"
|
|
|
:visible.sync="showVoteDialog"
|
|
|
+ width="480px"
|
|
|
+ custom-class="vote-dialog"
|
|
|
:close-on-click-modal="false"
|
|
|
- width="50%"
|
|
|
+ append-to-body
|
|
|
center
|
|
|
- @close="onCloseDialog"
|
|
|
- >
|
|
|
- <el-card>
|
|
|
- <el-form ref="voteForm" :model="voteForm" :rules="voteFormRules">
|
|
|
- <el-form-item label="投票名称" label-width="120px" prop="title">
|
|
|
- <el-input
|
|
|
- v-model="voteForm.title"
|
|
|
- style="margin-left: 5px"
|
|
|
- clearable
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="结束时间" label-width="120px" prop="endTime">
|
|
|
+ >
|
|
|
+ <el-form ref="voteForm" :model="voteForm" :rules="voteFormRules" label-position="top">
|
|
|
+ <el-form-item label="投票主题" prop="title">
|
|
|
+ <el-input v-model="voteForm.title" placeholder="请输入投票名称" maxlength="30" show-word-limit />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="截止日期" prop="endTime">
|
|
|
<el-date-picker
|
|
|
- v-model="voteForm.endTime"
|
|
|
- type="date"
|
|
|
- style="margin-left: 5px"
|
|
|
- placeholder="选择结束时间"
|
|
|
+ v-model="voteForm.endTime"
|
|
|
+ type="date"
|
|
|
+ placeholder="选择日期"
|
|
|
+ style="width: 100%"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="预期人数" label-width="120px" prop="expectNum">
|
|
|
- <el-input-number v-model="voteForm.expectNum" :min="2" :max="10000" style="margin-left: 5px" />
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="期望人数" prop="expectNum">
|
|
|
+ <el-input-number v-model="voteForm.expectNum" :min="2" style="width: 100%" />
|
|
|
</el-form-item>
|
|
|
- <el-button
|
|
|
- type="primary"
|
|
|
- plain
|
|
|
- size="small"
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-form-item label="投票选项 (至少2项)">
|
|
|
+ <div v-for="(item, index) in voteForm.options" :key="index" class="option-edit-item">
|
|
|
+ <el-input v-model="item.name" placeholder="输入选项内容">
|
|
|
+ <el-button slot="append" icon="el-icon-delete" @click="delVoteOption(index)" />
|
|
|
+ </el-input>
|
|
|
+ </div>
|
|
|
+ <el-button
|
|
|
+ type="dashed"
|
|
|
icon="el-icon-plus"
|
|
|
- style="margin-left: 40px"
|
|
|
+ class="add-option-btn"
|
|
|
+ block
|
|
|
@click="addVoteOption"
|
|
|
- >
|
|
|
- 添加投票选项
|
|
|
- </el-button>
|
|
|
- <!--存放答案表单的信息-->
|
|
|
- <el-form-item prop="options">
|
|
|
- <el-table :data="voteForm.options" border style="width: 96%;margin-left: 40px;margin-top: 10px">
|
|
|
- <el-table-column label="选项内容">
|
|
|
- <template slot-scope="scope">
|
|
|
- <el-input
|
|
|
- v-model="scope.row.name"
|
|
|
- style="margin-left: 5px"
|
|
|
- clearable
|
|
|
- />
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="操作">
|
|
|
- <template slot-scope="scope">
|
|
|
- <el-button type="danger" icon="el-icon-delete" size="mini" circle @click="delVoteOption(scope.row)" />
|
|
|
- <el-button type="danger" icon="el-icon-plus" size="mini" circle @click="addVoteOption" />
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
- </el-card>
|
|
|
- <div slot="footer" class="dialog-footer">
|
|
|
- <el-button type="primary" @click="addVote">添 加</el-button>
|
|
|
- <el-button @click="showVoteDialog = false">取 消</el-button>
|
|
|
- </div>
|
|
|
- </el-dialog>
|
|
|
- </el-card>
|
|
|
- <el-card v-if="vote !== null" style="padding: 5px">
|
|
|
- <div slot="header" class="clearfix">
|
|
|
- <span>{{ vote.title }}</span>
|
|
|
- <el-button style="float: right; padding: 5px; color: blue" type="text" @click="submit">提交投票</el-button>
|
|
|
- </div>
|
|
|
- <div class="text item">
|
|
|
- <el-radio-group
|
|
|
- v-for="(voteOption, index1) in vote.options"
|
|
|
- :key="index1"
|
|
|
- v-model="checkedRadio"
|
|
|
- class="movie-list"
|
|
|
- @change="singleCheckChange(voteOption)"
|
|
|
- >
|
|
|
- <el-radio :label="voteOption.value" border size="medium">
|
|
|
- <span>{{ voteOption.name }}</span>
|
|
|
- </el-radio>
|
|
|
- </el-radio-group>
|
|
|
- </div>
|
|
|
- </el-card>
|
|
|
+ >
|
|
|
+ 添加选项
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <span slot="footer">
|
|
|
+ <el-button @click="showVoteDialog = false">取 消</el-button>
|
|
|
+ <el-button type="primary" @click="addVote">确 定</el-button>
|
|
|
+ </span>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -117,119 +123,76 @@ export default {
|
|
|
name: 'TextCard',
|
|
|
data() {
|
|
|
return {
|
|
|
- actionUrl: process.env.VUE_APP_SERVER_URL + '/api/content/timeline',
|
|
|
textarea: '',
|
|
|
- dialogImageUrl: '',
|
|
|
- dialogVisible: false,
|
|
|
- // 表单
|
|
|
+ showVoteDialog: false,
|
|
|
+ vote: null,
|
|
|
+ checkedRadio: '',
|
|
|
+ selectedOption: null,
|
|
|
voteForm: {
|
|
|
title: '',
|
|
|
endTime: null,
|
|
|
- expectNum: 0,
|
|
|
- options: []
|
|
|
+ expectNum: 10,
|
|
|
+ options: [{ name: '' }, { name: '' }] // 默认给两项
|
|
|
},
|
|
|
- // 表单的验证规则
|
|
|
voteFormRules: {
|
|
|
- title: [
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: '请输入投票名称',
|
|
|
- trigger: 'blur'
|
|
|
- }
|
|
|
- ],
|
|
|
- endTime: [
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: '请选择投票的结束时间',
|
|
|
- trigger: 'blur'
|
|
|
- }
|
|
|
- ],
|
|
|
- expectNum: [
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: '请选择期望投票的人数',
|
|
|
- trigger: 'blur'
|
|
|
- }
|
|
|
- ]
|
|
|
- },
|
|
|
- showVoteDialog: false,
|
|
|
- vote: null,
|
|
|
- checkedRadio: '',
|
|
|
- selectedOption: null,
|
|
|
- showVoteCard: false
|
|
|
+ title: [{ required: true, message: '请输入投票标题', trigger: 'blur' }],
|
|
|
+ endTime: [{ required: true, message: '请选择截止时间', trigger: 'change' }]
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
- handleRemove(file, fileList) {
|
|
|
- console.log(file, fileList)
|
|
|
- },
|
|
|
- handlePictureCardPreview(file) {
|
|
|
- this.dialogImageUrl = file.url
|
|
|
- this.dialogVisible = true
|
|
|
- },
|
|
|
- handleBlur() {
|
|
|
- this.$message.info(this.textarea)
|
|
|
+ formatDate(date) {
|
|
|
+ if (!date) return '-'
|
|
|
+ return new Date(date).toLocaleDateString()
|
|
|
},
|
|
|
onSubmit() {
|
|
|
- console.log('发送状态')
|
|
|
+ this.$message.success('发布成功')
|
|
|
+ this.textarea = ''
|
|
|
+ this.vote = null
|
|
|
},
|
|
|
onImage() {
|
|
|
- this.$message.info('image')
|
|
|
+ this.$message.info('图片上传功能维护中')
|
|
|
},
|
|
|
createVote() {
|
|
|
this.showVoteDialog = true
|
|
|
},
|
|
|
- onCloseDialog() {
|
|
|
- this.showVoteDialog = false
|
|
|
- },
|
|
|
addVoteOption() {
|
|
|
- this.voteForm.options.push({
|
|
|
- optionId: this.voteForm.options.length,
|
|
|
- name: '',
|
|
|
- value: this.voteForm.options.length + 1,
|
|
|
- pos: this.voteForm.options.length
|
|
|
- })
|
|
|
+ this.voteForm.options.push({ name: '' })
|
|
|
},
|
|
|
- delVoteOption(row) {
|
|
|
- const id = row.optionId
|
|
|
- this.voteForm.options.map((item, index) => {
|
|
|
- if (item.pos === id) this.voteForm.options.splice(index, 1)
|
|
|
- })
|
|
|
+ delVoteOption(index) {
|
|
|
+ if (this.voteForm.options.length <= 2) {
|
|
|
+ this.$message.warning('至少需要两个选项')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.voteForm.options.splice(index, 1)
|
|
|
},
|
|
|
addVote() {
|
|
|
- console.log(this.voteForm)
|
|
|
- this.vote = this.voteForm
|
|
|
- this.showVoteDialog = false
|
|
|
- this.voteForm = {
|
|
|
- title: '',
|
|
|
- endTime: null,
|
|
|
- expectNum: 0,
|
|
|
- options: []
|
|
|
- }
|
|
|
+ this.$refs.voteForm.validate(valid => {
|
|
|
+ if (valid) {
|
|
|
+ const validOptions = this.voteForm.options.filter(o => o.name.trim())
|
|
|
+ if (validOptions.length < 2) {
|
|
|
+ this.$message.error('请至少填写两个有效选项')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 映射 value 以供预览时使用
|
|
|
+ this.vote = {
|
|
|
+ ...this.voteForm,
|
|
|
+ options: validOptions.map((o, index) => ({ ...o, value: index + 1 }))
|
|
|
+ }
|
|
|
+ this.showVoteDialog = false
|
|
|
+ // 重置表单
|
|
|
+ this.voteForm = { title: '', endTime: null, expectNum: 10, options: [{ name: '' }, { name: '' }] }
|
|
|
+ }
|
|
|
+ })
|
|
|
},
|
|
|
singleCheckChange(val) {
|
|
|
this.selectedOption = val
|
|
|
},
|
|
|
submit() {
|
|
|
- if (this.selectedOption === null) {
|
|
|
- this.$message.info('请先选择')
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- const confirmText = '确认选择 [' + this.selectedOption.name + ']?'
|
|
|
- this.$confirm(confirmText, '提示', {
|
|
|
- confirmButtonText: '确定',
|
|
|
- cancelButtonText: '取消',
|
|
|
- type: 'warning'
|
|
|
- }).then(() => {
|
|
|
- this.$message.info('已投票')
|
|
|
- console.log(this.selectedOption)
|
|
|
+ if (!this.selectedOption) return this.$message.warning('请选择一个选项')
|
|
|
+ this.$confirm(`确认选择 [${this.selectedOption.name}]?`, '提示').then(() => {
|
|
|
+ this.$message.success('投票成功')
|
|
|
this.vote = null
|
|
|
- }).catch(() => {
|
|
|
- this.$message({
|
|
|
- type: 'info',
|
|
|
- message: '已取消'
|
|
|
- })
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
@@ -237,21 +200,137 @@ export default {
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
-.el-button--submit.is-active,
|
|
|
-.el-button--submit:active {
|
|
|
- background: #20B2AA;
|
|
|
- border-color: #20B2AA;
|
|
|
- color: #fff;
|
|
|
+.publish-container {
|
|
|
+ max-width: 700px;
|
|
|
+ margin: 0 auto;
|
|
|
+}
|
|
|
+
|
|
|
+.shadow-sm {
|
|
|
+ box-shadow: 0 2px 12px 0 rgba(0,0,0,0.05) !important;
|
|
|
+ border: 1px solid #ebeef5;
|
|
|
+ border-radius: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 输入框优化 */
|
|
|
+.custom-textarea /deep/ .el-textarea__inner {
|
|
|
+ border: none;
|
|
|
+ resize: none;
|
|
|
+ font-size: 15px;
|
|
|
+ padding: 10px 5px;
|
|
|
+ background: transparent;
|
|
|
+ transition: all 0.3s;
|
|
|
+}
|
|
|
+
|
|
|
+.custom-textarea /deep/ .el-input__count {
|
|
|
+ background: transparent;
|
|
|
+ bottom: -5px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 工具栏 */
|
|
|
+.publish-toolbar {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-top: 10px;
|
|
|
+ padding-top: 10px;
|
|
|
+ border-top: 1px solid #f2f6fc;
|
|
|
+}
|
|
|
+
|
|
|
+.tool-btn {
|
|
|
+ color: #606266;
|
|
|
+ font-size: 14px;
|
|
|
+ margin-right: 15px;
|
|
|
+}
|
|
|
+.tool-btn:hover {
|
|
|
+ color: #409eff;
|
|
|
+}
|
|
|
+.tool-btn i {
|
|
|
+ font-size: 18px;
|
|
|
+ vertical-align: middle;
|
|
|
+ margin-right: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.send-btn {
|
|
|
+ padding: 10px 25px;
|
|
|
+ font-weight: bold;
|
|
|
}
|
|
|
-.el-button--submit:focus,
|
|
|
-.el-button--submit:hover {
|
|
|
- background: #48D1CC;
|
|
|
- border-color: #48D1CC;
|
|
|
- color: #fff;
|
|
|
+
|
|
|
+/* 投票预览样式 */
|
|
|
+.vote-preview-box {
|
|
|
+ margin-top: 15px;
|
|
|
+ padding: 15px;
|
|
|
+ background: #f9f9f9;
|
|
|
+ border-radius: 8px;
|
|
|
+ border: 1px dashed #dcdfe6;
|
|
|
+}
|
|
|
+
|
|
|
+.vote-preview-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.vote-tag {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+ background: #fff;
|
|
|
+ padding: 2px 8px;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid #e4e7ed;
|
|
|
+}
|
|
|
+
|
|
|
+.vote-title {
|
|
|
+ margin: 0 0 12px 0;
|
|
|
+ color: #303133;
|
|
|
+ font-size: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.vote-option-item {
|
|
|
+ background: #fff;
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+ padding: 10px 15px;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ border-radius: 6px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.2s;
|
|
|
+}
|
|
|
+
|
|
|
+.vote-option-item:hover {
|
|
|
+ border-color: #409eff;
|
|
|
+ background: #f0f7ff;
|
|
|
}
|
|
|
-.el-button--submit {
|
|
|
- color: #FFF;
|
|
|
- background-color: #20B2AA;
|
|
|
- border-color: #20B2AA;
|
|
|
+
|
|
|
+.vote-option-item.is-selected {
|
|
|
+ border-color: #409eff;
|
|
|
+ background: #ecf5ff;
|
|
|
+}
|
|
|
+
|
|
|
+.vote-footer {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-top: 12px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+}
|
|
|
+
|
|
|
+/* 对话框表单优化 */
|
|
|
+.option-edit-item {
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.add-option-btn {
|
|
|
+ width: 100%;
|
|
|
+ border-style: dashed;
|
|
|
+ margin-top: 5px;
|
|
|
+}
|
|
|
+
|
|
|
+.vote-dialog /deep/ .el-dialog__body {
|
|
|
+ padding: 10px 25px;
|
|
|
+}
|
|
|
+
|
|
|
+.vote-dialog /deep/ .el-dialog__header {
|
|
|
+ border-bottom: 1px solid #f2f6fc;
|
|
|
}
|
|
|
</style>
|