Commit 24fed907 authored by Davve's avatar Davve

解决图片上传

parent 1f233f9b
......@@ -15,14 +15,67 @@ class PushListView(APIView):
data = self.rpc['venus/community/push/get'](offset=page, limit=limit, filters=filter).unwrap()
except Exception as e:
data = {
'total': 200,
'data': [
{'id': 1, 'title': '测试1', 'content': '测试2', 'push_time': '2018-08-09','create_time':'2019-08-07', 'creator_id':22, },
{'id': 2, 'title': '测试1', 'content': '测试2', 'push_time': '2018-08-09', 'create_time': '2019-08-07',
'creator_id': 22, },
{'id': 3, 'title': '测试1', 'content': '测试2', 'push_time': '2018-08-09', 'create_time': '2019-08-07',
'creator_id': 22, },
]
}
'total': 200,
'data': [
{
'id': 1,
'title': '测试1',
'content': '测试2',
'push_time': '2018-08-09 23:89:09',
'create_time': '2019-08-07 23:89:09',
'creator_id': 22,
},
{
'id': 2,
'title': '测试1',
'content': '测试2',
'push_time': '2018-08-09 23:89:09',
'create_time': '2019-08-07 23:89:09',
'creator_id': 22,
},
{
'id': 3,
'title': '测试1',
'content': '测试2',
'push_time': '2018-08-09 23:89:09',
'create_time': '2019-08-07 23:89:09',
'creator_id': 22,
},
]
}
return data
return data
\ No newline at end of file
class PushUpdateOrCreateView(APIView):
def get(self, request):
id = request.GET.get('id')
try:
data = self.rpc['venus/community/push/detail'](id=id).unwrap()
except Exception as e:
# raise e
data = {
'id': 1,
'create_time': '2018-09-08 23:34:34',
'push_time': 24121273912739, # 返回时间戳
'content': '这是推送内容',
'url': 'http:www.baidu.com',
'icon': 'https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=846134627,633122759&fm=173&app=49&f=JPEG?w=600&h=400&s=84C5D14ADEA4A2575042FFAA0300F005',
'title': '这是一个推送标题',
}
return {'data': data}
def post(self, request):
# TODO 图片icon上传到七牛
data = {
'url': request.POST.get('url', ''),
'push_time': request.POST.get('push_time', ''),
'icon': request.POST.get('icon', ''),
'content': request.POST.get('content', ''),
'title': request.POST.get('title', ''),
}
print(data, '--------------------')
# try:
# self.rpc['venus/community/push/create'](data=data).unwrap()
# except Exception as e:
# raise e
......@@ -14,13 +14,5 @@ class StarListView(APIView):
try:
data = self.rpc['venus/community/star/get'](offset=page, limit=limit, filters=filter).unwrap()
except Exception as e:
data = {
'total': 200,
'data': [
{'id': 1, 'name': '测试1', 'region': '测试2', 'group_nums': 22, 'gender': 1},
{'id': 2, 'name': '测试1', 'region': '测试2', 'group_nums': 13, 'gender': 1},
{'id': 3, 'name': '测试1', 'region': '测试2', 'group_nums': 18, 'gender': 0},
]
}
raise e
return data
\ No newline at end of file
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "chenwei"
# Date: 2018/11/19
from utils.base import APIView
from gm_upload import upload
class FileUpload(APIView):
args_POST = {
'img_type': {
'access': int,
},
}
def post(self, request):
image = request.FILES.get('file')
data = image.read()
full_image_url = upload(data, img_type=self.args_post.get('type')) + '-w'
return {
'file_url': full_image_url
}
......@@ -15,6 +15,7 @@ from .star import *
from .account import *
from .search import *
from .tag import *
from .upload import *
urlpatterns = [
# 登陆,注销相关
......@@ -41,6 +42,8 @@ urlpatterns = [
# push相关
url(r'push/list$', PushListView.as_view()),
url(r'push/create', PushUpdateOrCreateView.as_view()),
url(r'push/detail', PushUpdateOrCreateView.as_view()),
# pick相关
url(r'pick/list$', PickListView.as_view()),
......@@ -55,11 +58,16 @@ urlpatterns = [
url(r'tag/detail', TagUpdateOrCreateView.as_view()),
]
searchurlpatterns = [
search_urlpatterns = [
url(r'search/group$', GroupSearchView.as_view()),
url(r'search/region', RegionSearchView.as_view()),
url(r'search/user', UserSearchView.as_view()),
url(r'search/tag', TagSearchView.as_view()),
]
urlpatterns += searchurlpatterns
common_urlpatterns = [
url(r"^file/upload$", FileUpload.as_view()),
]
urlpatterns += search_urlpatterns
urlpatterns += common_urlpatterns
var api = require('./api')
//
// const target = 'http://doctor.test.env'
// const target = 'http://172.30.8.231:8000'
const target = 'http://192.168.1.6:8000'
const target = 'http://172.30.8.231:8000'
// const target = 'http://192.168.1.6:8000'
// 可以修改请求内容
const onProxyReq = proxyReq => {}
......
......@@ -8,3 +8,27 @@ export function fetchList(query) {
})
}
export function OffLineOrOnLine(data) {
console.log(data)
return request({
url: '/api/push/list/update',
method: 'post',
data
})
}
export function CreatePush(data) {
return request({
url: '/api/push/create',
method: 'post',
data
})
}
export function fetchPushDetail(id) {
return request({
url: '/api/push/detail',
method: 'get',
params: { id }
})
}
......@@ -7,18 +7,18 @@
:on-success="handleImageSuccess"
class="image-uploader"
drag
action="https://httpbin.org/post">
action="/api/file/upload">
<i class="el-icon-upload"/>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
</el-upload>
<div class="image-preview image-app-preview">
<div v-show="imageUrl.length>1" class="image-preview-wrapper">
<img :src="imageUrl">
<div class="image-preview-action">
<i class="el-icon-delete" @click="rmImage"/>
</div>
</div>
</div>
<!--<div class="image-preview image-app-preview">-->
<!--<div v-show="imageUrl.length>1" class="image-preview-wrapper">-->
<!--<img :src="imageUrl">-->
<!--<div class="image-preview-action">-->
<!--<i class="el-icon-delete" @click="rmImage"/>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<div class="image-preview">
<div v-show="imageUrl.length>1" class="image-preview-wrapper">
<img :src="imageUrl">
......@@ -39,12 +39,16 @@ export default {
value: {
type: String,
default: ''
},
type: {
type: String,
default: ''
}
},
data() {
return {
tempUrl: '',
dataObj: { token: '', key: '' }
dataObj: { type: this.type }
}
},
computed: {
......@@ -60,7 +64,7 @@ export default {
this.$emit('input', val)
},
handleImageSuccess(file) {
this.emitInput(file.files.file)
this.emitInput(file.data.file_url)
},
beforeUpload() {
const _self = this
......
......@@ -100,37 +100,5 @@ export const asyncRouterMap = [
PushRouter,
PickRouter,
TagRouter,
{
path: '/example',
component: Layout,
redirect: '/example/list',
name: 'Example',
meta: {
title: 'example',
icon: 'example'
},
children: [
{
path: 'create',
component: () => import('@/views/example/create'),
name: 'CreateArticle',
meta: { title: 'createArticle', icon: 'edit' }
},
{
path: 'edit/:id(\\d+)',
component: () => import('@/views/example/edit'),
name: 'EditArticle',
meta: { title: 'editArticle', noCache: true },
hidden: true
},
{
path: 'list',
component: () => import('@/views/example/list'),
name: 'ArticleList',
meta: { title: 'articleList', icon: 'list' }
}
]
},
{ path: '*', redirect: '/404', hidden: true }
]
......@@ -9,7 +9,7 @@ const AccountRouter = {
name: 'Account',
meta: {
title: '账号管理',
icon: 'example'
icon: 'component'
},
children: [
{
......
......@@ -9,7 +9,7 @@ const GroupRouter = {
name: 'Group',
meta: {
title: '小组管理',
icon: 'example'
icon: 'component'
},
children: [
{
......
......@@ -9,7 +9,7 @@ const PickRouter = {
name: 'Pick',
meta: {
title: 'Pick管理',
icon: 'example'
icon: 'component'
},
children: [
{
......
......@@ -9,7 +9,7 @@ const PushRouter = {
name: 'Push',
meta: {
title: 'Push管理',
icon: 'example'
icon: 'component'
},
children: [
{
......
......@@ -9,7 +9,7 @@ const StarRouter = {
name: 'Star',
meta: {
title: '明星管理',
icon: 'example'
icon: 'component'
},
children: [
{
......
......@@ -7,7 +7,7 @@ const TagRouter = {
name: 'Tag',
meta: {
title: '标签管理',
icon: 'example'
icon: 'component'
},
children: [
{
......
......@@ -9,7 +9,7 @@ const TopicRouter = {
name: 'Topic',
meta: {
title: '帖子管理',
icon: 'example'
icon: 'component'
},
children: [
{
......
......@@ -9,7 +9,7 @@ const GroupRouter = {
name: 'User',
meta: {
title: '用户管理',
icon: 'example'
icon: 'component'
},
children: [
{
......
......@@ -5,63 +5,136 @@
<sticky :class-name="'sub-navbar '+postForm.status">
<el-button v-loading="loading" style="margin-left: 10px;" type="success" @click="submitForm">发布
</el-button>
<el-button v-loading="loading" type="warning" @click="draftForm">草稿</el-button>
</sticky>
<div class="createPost-main-container">
<el-row>
<el-row :gutter="20">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>小组相关</span>
</div>
<div style="margin-bottom:50px;">
<el-col :span="24">
<el-form-item style="margin-bottom: 20px;" prop="title">
<MDinput v-model="postForm.name" :maxlength="100" name="name" required>
小组名称
</MDinput>
</el-form-item>
<el-col :span="24">
<el-form-item style="margin-bottom: 40px;" prop="title">
<MDinput v-model="postForm.title" :maxlength="100" name="name" required>
标题
</MDinput>
<div class="postInfo-container">
<el-row>
<el-col :span="8">
<el-form-item label-width="75px" label="明星称号:" class="postInfo-container-item">
<el-select v-model="postForm.star_name" :placeholder="'明星称号'" clearable
class="postInfo-container-item"
style="width: 220px">
<el-option v-for="item in []" :key="item.key" :label="item.display_name"
:value="item.key"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label-width="75px" label="小组组长:" class="postInfo-container-item">
<el-select v-model="postForm.pick_type" :placeholder="'性别:'" clearable
class="postInfo-container-item" style="width:220px">
<el-option v-for="item in []" :key="item.key" :label="item.display_name"
:value="item.key"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item style="margin-bottom: 20px;" label-width="75px" label="组员数量:" prop="desc">
<el-input v-model="postForm.user_nums" type="number" placeholder="请输入内容" style="width: 230px;"
readonly/>
</el-form-item>
</el-col>
</el-row>
</div>
</el-col>
</div>
<el-form-item style="margin-bottom: 20px;" label-width="75px" label="下线小组:">
<el-radio-group v-model="postForm.is_online">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item style="margin-bottom: 20px;" label-width="75px" label="推荐小组:">
<el-radio-group v-model="postForm.is_recommend">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item style="margin-bottom: 20px;" label-width="75px" label="小组简介:">
<el-input :rows="1" v-model="postForm.description" type="textarea" class="article-textarea" autosize
placeholder="请输入内容"/>
<span v-show="contentShortLength" class="word-counter">{{ contentShortLength }}</span>
</el-form-item>
<div class="postInfo-container">
<el-row>
<el-col :span="8">
<el-form-item label-width="45px" label="作者:" class="postInfo-container-item">
<el-select v-model="postForm.author" :remote-method="getRemoteUserList" filterable remote placeholder="搜索用户">
<el-option v-for="(item,index) in userListOptions" :key="item+index" :label="item" :value="item"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label-width="80px" label="发布时间:" class="postInfo-container-item">
<el-date-picker v-model="postForm.display_time" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期时间"/>
</el-form-item>
</el-col>
</el-card>
</el-row>
<el-col :span="6">
<el-form-item label-width="60px" label="重要性:" class="postInfo-container-item">
<el-rate
v-model="postForm.importance"
:max="3"
:colors="['#99A9BF', '#F7BA2A', '#FF9900']"
:low-threshold="1"
:high-threshold="3"
style="margin-top:8px;"/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" style="margin-top:50px;">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>组员相关</span>
</div>
</el-col>
</el-row>
<div style="margin-bottom:50px;">
<div class="filter-container">
<el-input :placeholder="'添加用户'" v-model="listQuery.filter.value" style="width: 180px;"
class="filter-item"
@keyup.enter.native="appendUser"/>
<el-button v-waves class="filter-item" type="primary" icon="el-icon-edit" @click="appendUser">添加
</el-button>
<el-button v-waves class="filter-item" type="primary" icon="el-icon-delete" @click="delUser">移除
</el-button>
</div>
<el-table :data="list" border fit highlight-current-row style="width: 100%"
ref="multipleTable" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="76" align="center"></el-table-column>
<el-table-column align="center" label="用户ID " width="80">
<template slot-scope="scope">
<router-link :to="'/push/edit/'+scope.row.id" class="link-type">
<span>{{ scope.row.id }}</span>
</router-link>
</template>
</el-table-column>
<el-table-column width="190px" align="center" label="用户名">
<template slot-scope="scope">
<span>{{ scope.row.username }}</span>
</template>
</el-table-column>
<el-table-column width="300px" align="center" label="联系电话">
<template slot-scope="scope">
<span>{{ scope.phone }}</span>
</template>
</el-table-column>
<el-table-column width="120px" align="center" label="发布帖子数">
<template slot-scope="scope">
<span>{{ scope.row.topic_nums }}</span>
</template>
</el-table-column>
<el-table-column width="180px" align="center" label="用户身份">
<template slot-scope="scope">
<span>{{ scope.row.user_identity }}</span>
</template>
</el-table-column>
<el-table-column width="180px" align="center" label="组内身份">
<template slot-scope="scope">
<span>{{ scope.row.internal_identity }}</span>
</template>
</el-table-column>
</el-table>
<el-form-item style="margin-bottom: 40px;" label-width="45px" label="摘要:">
<el-input :rows="1" v-model="postForm.content_short" type="textarea" class="article-textarea" autosize placeholder="请输入内容"/>
<span v-show="contentShortLength" class="word-counter">{{ contentShortLength }}</span>
</el-form-item>
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit"
style="margin-left: 250px;" @pagination="getList"/>
</div>
</el-card>
</el-row>
<div class="editor-container">
<Tinymce ref="editor" :height="400" v-model="postForm.content" />
</div>
<div style="margin-bottom: 20px;">
<Upload v-model="postForm.image_uri" />
</div>
</div>
</el-form>
......@@ -69,194 +142,205 @@
</template>
<script>
import Tinymce from '@/components/Tinymce'
import Upload from '@/components/Upload/singleImage3'
import MDinput from '@/components/MDinput'
import Sticky from '@/components/Sticky' // 粘性header组件
import { validateURL } from '@/utils/validate'
import { fetchArticle } from '@/api/article'
import { userSearch } from '@/api/remoteSearch'
import MDinput from '@/components/MDinput'
import Sticky from '@/components/Sticky' // 粘性header组件
import waves from '@/directive/waves'
import Pagination from '@/components/Pagination'
const defaultForm = {
status: 'draft',
title: '', // 文章题目
content: '', // 文章内容
content_short: '', // 文章摘要
source_uri: '', // 文章外链
image_uri: '', // 文章图片
display_time: undefined, // 前台展示时间
id: undefined,
platforms: ['a-platform'],
comment_disabled: false,
importance: 0
}
import {validateURL} from '@/utils/validate'
import {fetchList} from '@/api/user'
import {userSearch} from '@/api/remoteSearch'
export default {
name: 'GroupDetail',
components: { Tinymce, MDinput, Upload, Sticky},
props: {
isEdit: {
type: Boolean,
default: false
}
},
data() {
const validateRequire = (rule, value, callback) => {
if (value === '') {
this.$message({
message: rule.field + '为必传项',
type: 'error'
})
callback(new Error(rule.field + '为必传项'))
} else {
callback()
const defaultForm = {
status: 'draft',
title: '', // 文章题目
name: '', // 文章内容
description: '', // 文章摘要
source_uri: '', // 文章外链
image_uri: '', // 文章图片
display_time: undefined, // 前台展示时间
id: undefined,
platforms: ['a-platform'],
comment_disabled: false,
importance: 0
}
export default {
name: 'GroupDetail',
components: {MDinput, Sticky, Pagination},
directives: {waves},
props: {
isEdit: {
type: Boolean,
default: false
}
}
const validateSourceUri = (rule, value, callback) => {
if (value) {
if (validateURL(value)) {
callback()
} else {
},
data() {
const validateRequire = (rule, value, callback) => {
if (value === '') {
this.$message({
message: '外链url填写不正确',
message: rule.field + '为必传项',
type: 'error'
})
callback(new Error('外链url填写不正确'))
callback(new Error(rule.field + '为必传项'))
} else {
callback()
}
} else {
callback()
}
}
return {
postForm: Object.assign({}, defaultForm),
loading: false,
userListOptions: [],
rules: {
image_uri: [{ validator: validateRequire }],
title: [{ validator: validateRequire }],
content: [{ validator: validateRequire }],
source_uri: [{ validator: validateSourceUri, trigger: 'blur' }]
},
tempRoute: {}
}
},
computed: {
contentShortLength() {
return this.postForm.content_short.length
},
lang() {
return this.$store.getters.language
}
},
created() {
if (this.isEdit) {
const id = this.$route.params && this.$route.params.id
this.fetchData(id)
} else {
this.postForm = Object.assign({}, defaultForm)
}
// Why need to make a copy of this.$route here?
// Because if you enter this page and quickly switch tag, may be in the execution of the setTagsViewTitle function, this.$route is no longer pointing to the current page
// https://github.com/PanJiaChen/vue-element-admin/issues/1221
this.tempRoute = Object.assign({}, this.$route)
},
methods: {
fetchData(id) {
fetchArticle(id).then(response => {
this.postForm = response.data
// Just for test
this.postForm.title += ` Article Id:${this.postForm.id}`
this.postForm.content_short += ` Article Id:${this.postForm.id}`
const validateSourceUri = (rule, value, callback) => {
if (value) {
if (validateURL(value)) {
callback()
} else {
this.$message({
message: '外链url填写不正确',
type: 'error'
})
callback(new Error('外链url填写不正确'))
}
} else {
callback()
}
}
return {
postForm: Object.assign({}, defaultForm),
loading: false,
userListOptions: [],
rules: {
title: [{validator: validateRequire}],
content: [{validator: validateRequire}],
},
tempRoute: {},
// Set tagsview title
this.setTagsViewTitle()
}).catch(err => {
console.log(err)
})
// 小组相关
list: null,
total: 1,
listLoading: true,
multipleSelection: [],
del_list: [],
listQuery: {
page: 0,
limit: 10,
filter: {
value: '',
key: '',
},
},
}
},
setTagsViewTitle() {
const title = this.lang === 'zh' ? '编辑文章' : 'Edit Article'
const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.postForm.id}` })
this.$store.dispatch('updateVisitedView', route)
computed: {
contentShortLength() {
return this.postForm.content_short.length
},
},
submitForm() {
this.postForm.display_time = parseInt(this.display_time / 1000)
console.log(this.postForm)
this.$refs.postForm.validate(valid => {
if (valid) {
this.loading = true
this.$notify({
title: '成功',
message: '发布文章成功',
type: 'success',
duration: 2000
})
this.postForm.status = 'published'
this.loading = false
} else {
console.log('error submit!!')
return false
}
})
created() {
if (this.isEdit) {
const id = this.$route.params && this.$route.params.id
this.fetchData(id)
this.getList()
} else {
this.postForm = Object.assign({}, defaultForm)
}
this.tempRoute = Object.assign({}, this.$route)
},
draftForm() {
if (this.postForm.content.length === 0 || this.postForm.title.length === 0) {
this.$message({
message: '请填写必要的标题和内容',
type: 'warning'
methods: {
fetchData(id) {
fetchArticle(id).then(response => {
this.postForm = response.data
}).catch(err => {
console.log(err)
})
},
submitForm() {
this.postForm.display_time = parseInt(this.display_time / 1000)
console.log(this.postForm)
this.$refs.postForm.validate(valid => {
if (valid) {
this.loading = true
this.$notify({
title: '成功',
message: '发布文章成功',
type: 'success',
duration: 2000
})
this.postForm.status = 'published'
this.loading = false
} else {
console.log('error submit!!')
return false
}
})
},
getRemoteUserList(query) {
userSearch(query).then(response => {
if (!response.data.items) return
this.userListOptions = response.data.items.map(v => v.name)
})
},
// 添加组员相关
handleSelectionChange(val) {
this.multipleSelection = val;
},
handleSizeChange(val) {
this.listQuery.limit = val
this.getList()
},
handleCurrentChange(val) {
this.listQuery.page = val
this.getList()
},
appendUser() {
},
delUser() {
},
getList() {
this.listLoading = true
fetchList(this.listQuery).then(response => {
this.list = []
this.total = 100
this.listLoading = false
})
return
}
this.$message({
message: '保存成功',
type: 'success',
showClose: true,
duration: 1000
})
this.postForm.status = 'draft'
},
getRemoteUserList(query) {
userSearch(query).then(response => {
if (!response.data.items) return
this.userListOptions = response.data.items.map(v => v.name)
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
.createPost-container {
position: relative;
.createPost-main-container {
padding: 40px 45px 20px 50px;
.postInfo-container {
position: relative;
@include clearfix;
margin-bottom: 10px;
.postInfo-container-item {
float: left;
@import "src/styles/mixin.scss";
.createPost-container {
position: relative;
.createPost-main-container {
padding: 40px 45px 20px 50px;
.postInfo-container {
position: relative;
@include clearfix;
margin-bottom: 10px;
.postInfo-container-item {
float: left;
}
}
}
.editor-container {
min-height: 500px;
margin: 0 0 30px;
.editor-upload-btn-container {
text-align: right;
margin-right: 10px;
.editor-upload-btn {
display: inline-block;
.editor-container {
min-height: 500px;
margin: 0 0 30px;
.editor-upload-btn-container {
text-align: right;
margin-right: 10px;
.editor-upload-btn {
display: inline-block;
}
}
}
}
.word-counter {
width: 40px;
position: absolute;
right: -10px;
top: 0px;
}
}
.word-counter {
width: 40px;
position: absolute;
right: -10px;
top: 0px;
}
}
</style>
......@@ -5,75 +5,44 @@
<el-select v-model="listQuery.filter.key" :placeholder="'搜索字段'" clearable class="filter-item" style="width: 110px">
<el-option v-for="item in SearchTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
</el-select>
<el-select v-model="listQuery.filter.is_online" :placeholder="'上线'" clearable class="filter-item" style="width: 100px">
<el-option v-for="item in BooleanTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
</el-select>
<el-select v-model="listQuery.filter.is_recommend" :placeholder="'推荐'" clearable class="filter-item" style="width: 100px">
<el-option v-for="item in ReBooleanTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
</el-select>
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">搜索</el-button>
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">创建</el-button>
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleOfflineOrOnline('offline')">下线</el-button>
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleOfflineOrOnline('online')">上线</el-button>
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleOfflineOrOnline('recommend')">推荐</el-button>
</div>
<el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%" ref="multipleTable" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column align="center" label="小组ID " width="80">
<el-table-column align="center" label="推送ID " width="80">
<template slot-scope="scope">
<router-link :to="'/pick/edit/'+scope.row.id" class="link-type">
<router-link :to="'/push/edit/'+scope.row.id" class="link-type">
<span>{{ scope.row.id }}</span>
</router-link>
</template>
</el-table-column>
<el-table-column width="190px" align="center" label="小组名称">
<el-table-column width="190px" align="center" label="推送内容">
<template slot-scope="scope">
<span>{{ scope.row.name }}</span>
<span>{{ scope.row.content }}</span>
</template>
</el-table-column>
<el-table-column width="300px" align="center" label="小组简介">
<el-table-column width="300px" align="center" label="推送时间">
<template slot-scope="scope">
<span>{{ scope.row.desc }}</span>
<span>{{ scope.row.push_time }}</span>
</template>
</el-table-column>
<el-table-column width="120px" align="center" label="明星名称">
<el-table-column width="120px" align="center" label="创建时间">
<template slot-scope="scope">
<span>{{ scope.row.star.name }}</span>
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column width="80px" align="center" label="用户数">
<el-table-column width="80px" align="center" label="创建用户">
<template slot-scope="scope">
<span>{{ scope.row.user_nums }}</span>
<span>{{ scope.row.creator }}</span>
</template>
</el-table-column>
<el-table-column width="80px" align="center" label="帖子数">
<template slot-scope="scope">
<span>{{ scope.row.topic_nums }}</span>
</template>
</el-table-column>
<el-table-column width="140px" align="center" label="组长">
<template slot-scope="scope">
<span>{{ scope.row.creator.name }}</span>
</template>
</el-table-column>
<el-table-column width="80px" align="center" label="下线">
<template slot-scope="scope">
<el-tag :type="scope.row.is_online | isOnlineFilter">{{ scope.row.is_online==1 ? '是' : '否' }}</el-tag>
</template>
</el-table-column>
<el-table-column width="80px" align="center" label="推荐">
<template slot-scope="scope">
<el-tag :type="scope.row.is_recommend | isOnlineFilter">{{ scope.row.is_recommend==1 ? '是' : '否' }}</el-tag>
</template>
</el-table-column>is_recommend
</el-table>
......@@ -90,30 +59,12 @@ import waves from '@/directive/waves'
export default {
name: 'GroupList',
components: { Pagination },
filters: {
isOnlineFilter(status) {
const statusMap = {
1: 'success',
0: 'info',
}
return statusMap[status]
},
genderFilter(status) {
const statusMap = {
'男': 'success',
'女': 'info',
'全部': 'danger'
}
return statusMap[status]
},
},
directives: { waves },
data() {
return {
list: null,
total: 0,
listLoading: true,
multipleSelection: [],
del_list: [],
listQuery: {
page: 0,
......@@ -121,22 +72,11 @@ export default {
filter: {
value: '',
key: '',
is_online: '',
is_recommend: '',
},
},
BooleanTypeOptions: [
{'key': 1, 'display_name': '是'},
{'key': 0, 'display_name': '否'}
],
ReBooleanTypeOptions: [
{'key': 1, 'display_name': '是'},
{'key': 0, 'display_name': '否'}
],
SearchTypeOptions:[
{'key': 'id', 'display_name': '小组ID'},
{'key': 'name', 'display_name': '小组名称'},
{'key': 'star_name', 'display_name': '明星名称'},
{'key': 'id', 'display_name': '推送ID'},
{'key': 'content', 'display_name': '推送内容'},
]
}
},
......@@ -152,9 +92,6 @@ export default {
this.listLoading = false
})
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
handleSizeChange(val) {
this.listQuery.limit = val
this.getList()
......@@ -163,31 +100,12 @@ export default {
this.listQuery.page = val
this.getList()
},
handleOfflineOrOnline(val){
const length = this.multipleSelection.length;
let str = '';
this.del_list = this.del_list.concat(this.multipleSelection);
for (let i = 0; i < length; i++) {
if (val === 'offline'){
this.multipleSelection[i].is_online = 0
} else if(val === 'recommend'){
this.multipleSelection[i].is_recommend = 1
} else{
this.multipleSelection[i].is_online = 1
}
str += this.multipleSelection[i].id + ' ';
}
OffLineOrOnLine({type:val, ids:str}).then(response => {
this.multipleSelection = [];
this.$message.success(response.data.data.message);
})
},
handleFilter() {
this.listQuery.page = 0
this.getList()
},
handleCreate() {
this.$router.push('/pick/create')
this.$router.push('/push/create')
}
}
}
......
......@@ -16,7 +16,7 @@
<size-select class="international right-menu-item"/>
</el-tooltip>
<lang-select class="international right-menu-item"/>
<el-tooltip :content="$t('navbar.theme')" effect="dark" placement="bottom">
<theme-picker class="theme-switch right-menu-item"/>
</el-tooltip>
......@@ -56,6 +56,7 @@ import ErrorLog from '@/components/ErrorLog'
import Screenfull from '@/components/Screenfull'
import SizeSelect from '@/components/SizeSelect'
import ThemePicker from '@/components/ThemePicker'
import LangSelect from '@/components/LangSelect'
export default {
components: {
......@@ -64,7 +65,8 @@ export default {
ErrorLog,
Screenfull,
SizeSelect,
ThemePicker
ThemePicker,
LangSelect
},
computed: {
...mapGetters([
......
......@@ -3,9 +3,8 @@
<el-form ref="postForm" :model="postForm" :rules="rules" class="form-container">
<sticky :class-name="'sub-navbar '+postForm.status">
<el-button v-loading="loading" style="margin-left: 10px;" type="success" @click="submitForm">发布
<el-button v-loading="loading" style="margin-left: 10px;" type="success" @click="submitForm">保存
</el-button>
<el-button v-loading="loading" type="warning" @click="draftForm">草稿</el-button>
</sticky>
<div class="createPost-main-container">
......@@ -14,35 +13,44 @@
<el-col :span="24">
<el-form-item style="margin-bottom: 40px;" prop="title">
<MDinput v-model="postForm.title" :maxlength="100" name="name" required>
标题
推送标题
</MDinput>
</el-form-item>
<div class="postInfo-container">
<el-row>
<el-col :span="8">
<el-form-item label-width="45px" label="作者:" class="postInfo-container-item">
<el-select v-model="postForm.author" :remote-method="getRemoteUserList" filterable remote placeholder="搜索用户">
<el-option v-for="(item,index) in userListOptions" :key="item+index" :label="item" :value="item"/>
</el-select>
<el-col :span="12">
<el-form-item style="margin-bottom: 40px;" label-width="75px" label="推送ID:" prop="id" v-if="isEdit">
<el-input :rows="1" v-model="postForm.id" type="text" class="article-textarea"
style="width: 300px" readonly v-if="isEdit"/>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label-width="80px" label="发布时间:" class="postInfo-container-item">
<el-date-picker v-model="postForm.display_time" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期时间"/>
<el-form-item style="margin-bottom: 40px;" label-width="75px" label="创建时间:" prop="create_time" v-if="isEdit">
<el-input :rows="1" v-model="postForm.create_time" type="text" class="article-textarea"
style="width: 300px" readonly v-if="isEdit"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item style="margin-bottom: 40px;" label-width="75px" label="推送落地:" prop="url" >
<el-input :rows="1" v-model="postForm.url" type="text" class="article-textarea"
style="width: 300px"/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label-width="60px" label="重要性:" class="postInfo-container-item">
<el-rate
v-model="postForm.importance"
:max="3"
:colors="['#99A9BF', '#F7BA2A', '#FF9900']"
:low-threshold="1"
:high-threshold="3"
style="margin-top:8px;"/>
<el-col :span="10">
<el-form-item label-width="80px" label="推送时间:" class="postInfo-container-item" prop="push_time" >
<el-date-picker
v-model="postForm.push_time"
type="datetime"
format="yyyy-MM-dd HH:mm:ss"
placeholder="选择日期时间"
style="width: 300px"
:picker-options="expireTimeOption"
/>
</el-form-item>
</el-col>
</el-row>
......@@ -50,17 +58,16 @@
</el-col>
</el-row>
<el-form-item style="margin-bottom: 40px;" label-width="45px" label="摘要:">
<el-input :rows="1" v-model="postForm.content_short" type="textarea" class="article-textarea" autosize placeholder="请输入内容"/>
<el-form-item style="margin-bottom: 40px;" label-width="75px" label="推送内容:" prop="content">
<el-input :rows="1" v-model="postForm.content" type="textarea" class="article-textarea" autosize placeholder="请输入内容"/>
<span v-show="contentShortLength" class="word-counter">{{ contentShortLength }}</span>
</el-form-item>
<div class="editor-container">
<Tinymce ref="editor" :height="400" v-model="postForm.content" />
</div>
<div style="margin-bottom: 20px;">
<Upload v-model="postForm.image_uri" />
<el-form-item style="margin-bottom: 40px;" label-width="75px" label="推送头像:" prop="icon">
<span v-model="type"></span>
<Upload v-model="postForm.icon" :type="type"/>
</el-form-item>
</div>
</div>
</el-form>
......@@ -69,31 +76,24 @@
</template>
<script>
import Tinymce from '@/components/Tinymce'
import Upload from '@/components/Upload/singleImage3'
import MDinput from '@/components/MDinput'
import Sticky from '@/components/Sticky' // 粘性header组件
import { validateURL } from '@/utils/validate'
import { fetchArticle } from '@/api/article'
import { userSearch } from '@/api/remoteSearch'
import { fetchPushDetail, CreatePush } from '@/api/push'
const defaultForm = {
status: 'draft',
title: '', // 文章题目
content: '', // 文章内容
content_short: '', // 文章摘要
source_uri: '', // 文章外链
image_uri: '', // 文章图片
display_time: undefined, // 前台展示时间
id: undefined,
platforms: ['a-platform'],
comment_disabled: false,
importance: 0
title: '',
content: '',
icon: '',
push_time: '',
url: '',
}
export default {
name: 'ArticleDetail',
components: { Tinymce, MDinput, Upload, Sticky},
name: 'PushDetail',
components: { MDinput, Upload, Sticky},
props: {
isEdit: {
type: Boolean,
......@@ -112,41 +112,31 @@ export default {
callback()
}
}
const validateSourceUri = (rule, value, callback) => {
if (value) {
if (validateURL(value)) {
callback()
} else {
this.$message({
message: '外链url填写不正确',
type: 'error'
})
callback(new Error('外链url填写不正确'))
}
} else {
callback()
}
}
return {
postForm: Object.assign({}, defaultForm),
loading: false,
userListOptions: [],
expireTimeOption: {
disabledDate(date){
return date.getTime() <= Date.now();
}
},
rules: {
image_uri: [{ validator: validateRequire }],
title: [{ validator: validateRequire }],
content: [{ validator: validateRequire }],
source_uri: [{ validator: validateSourceUri, trigger: 'blur' }]
title: [{ validator: validateRequire, trigger: 'blur'}],
content: [{ validator: validateRequire, trigger: 'blur'}],
url: [{ validator: validateRequire, trigger: 'blur'}],
icon: [{ validator: validateRequire, trigger: 'blur'}],
push_time: [{ validator: validateRequire, trigger: 'blur'}],
},
tempRoute: {}
tempRoute: {},
dataObj: { token: 'fahsdfiwqehfkajsdhfjkasdhfkj', key: 'fasdhfkasdhfkjashdfkjhasdfads' },
type: '1' // 图片类型
}
},
computed: {
contentShortLength() {
return this.postForm.content_short.length
return this.postForm.content.length
},
lang() {
return this.$store.getters.language
}
},
created() {
if (this.isEdit) {
......@@ -156,72 +146,48 @@ export default {
this.postForm = Object.assign({}, defaultForm)
}
// Why need to make a copy of this.$route here?
// Because if you enter this page and quickly switch tag, may be in the execution of the setTagsViewTitle function, this.$route is no longer pointing to the current page
// https://github.com/PanJiaChen/vue-element-admin/issues/1221
this.tempRoute = Object.assign({}, this.$route)
},
methods: {
fetchData(id) {
fetchArticle(id).then(response => {
this.postForm = response.data
// Just for test
this.postForm.title += ` Article Id:${this.postForm.id}`
this.postForm.content_short += ` Article Id:${this.postForm.id}`
// Set tagsview title
this.setTagsViewTitle()
}).catch(err => {
fetchPushDetail(id).then(response => {
this.postForm = response.data.data.data
}).catch(err => {
console.log(err)
})
},
setTagsViewTitle() {
const title = this.lang === 'zh' ? '编辑文章' : 'Edit Article'
const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.postForm.id}` })
this.$store.dispatch('updateVisitedView', route)
},
submitForm() {
this.postForm.display_time = parseInt(this.display_time / 1000)
console.log(this.postForm)
this.$refs.postForm.validate(valid => {
if (valid) {
this.loading = true
this.$notify({
title: '成功',
message: '发布文章成功',
type: 'success',
duration: 2000
})
this.postForm.status = 'published'
this.loading = false
CreatePush(this.postForm).then(response => {
this.$notify({
title: '成功',
message: response.data.data.message,
type: 'success',
duration: 2000
})
setTimeout(() => {
this.$router.push('/push/list')
}, 1000)
}).catch(err => {
this.$notify({
title: '失败',
message: '操作失败',
type: 'danger',
duration: 2000
})
});
this.postForm.status = 'published'
this.loading = false
} else {
console.log('error submit!!')
return false
}
})
},
draftForm() {
if (this.postForm.content.length === 0 || this.postForm.title.length === 0) {
this.$message({
message: '请填写必要的标题和内容',
type: 'warning'
})
return
}
this.$message({
message: '保存成功',
type: 'success',
showClose: true,
duration: 1000
})
this.postForm.status = 'draft'
},
getRemoteUserList(query) {
userSearch(query).then(response => {
if (!response.data.items) return
this.userListOptions = response.data.items.map(v => v.name)
})
}
}
}
</script>
......
......@@ -47,7 +47,7 @@
<el-table-column width="150px" align="center" label="小组数量">
<template slot-scope="scope">
<router-link :to="'/pick/edit/'+scope.row.id" class="link-type">
<span>{{ scope.row.group_nums }}</span>
<span>{{ scope.row.group_counts }}</span>
</router-link>
</template>
</el-table-column>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment