增加邮件相关功能

This commit is contained in:
zhl 2020-05-18 18:49:46 +08:00
parent 0ad1ec430b
commit 5fd498905c
8 changed files with 752 additions and 4 deletions

View File

@ -1 +0,0 @@
[0730/194221.616:ERROR:http_transport_win.cc(276)] WinHttpSendRequest: 操作成功完成。 (0x0)

31
src/api/mail.js Normal file
View File

@ -0,0 +1,31 @@
import request from '@/utils/request'
// ---------------------------------------------- //
// 获取邮件列表
export function getMails(params) {
return request({
url: '/games/mail',
method: 'get',
params
})
}
// 保存邮件
export function saveMail(data) {
return request({
url: '/games/mail',
method: 'post',
data
})
}
// 删除邮件
export function delMails(data) {
return request({
url: '/games/mail',
method: 'delete',
data
})
}

View File

@ -136,6 +136,12 @@ const gamesRouter = {
name: 'GameDetailsReward',
meta: { title: '客服奖励' }
},
{
path: 'mail',
component: () => import('@/views/games/details/mail'),
name: 'GameDetailsMail',
meta: { title: '邮件' }
},
{
path: 'ad/ad-pos',
component: () => import('@/views/games/details/ad/adPos'),

View File

@ -1,6 +1,5 @@
/* 面板 */
#app {
min-width: 1800px;
}
.app-main {

View File

@ -30,6 +30,10 @@
v-if="uid !== 'new'"
:index="`/games/details/${uid}/reward`"
>客服奖励</el-menu-item>
<el-menu-item
v-if="uid !== 'new'"
:index="`/games/details/${uid}/mail`"
>邮件</el-menu-item>
<el-menu-item
v-if="uid !== 'new'"
:index="`/games/details/${uid}/recommendation`"

View File

@ -0,0 +1,709 @@
<template>
<div class="main-content">
<!-- toolbar -->
<div class="toolbar clearfix">
<div
class="l fl"
v-if="permEdit"
>
<el-button
type="primary"
@click="addMail"
>新增</el-button>
<el-button
@click="switchData"
type="success"
>{{ switchText }}</el-button>
<el-button
v-if="batch.show && ((isDev && permEdit) || (!isDev && permPublish))"
type="danger"
@click="batchDel"
>批量删除</el-button>
<el-button @click="batchOpt"> {{ batch.txt }} </el-button>
</div>
<div class="r fr">
<el-button
type="primary"
@click="refreshData"
>刷新</el-button>
</div>
</div>
<!-- table -->
<el-alert
title="当前数据为【正式】数据!"
type="warning"
class="mgt-20 mgb-20"
effect="dark"
v-if="!isDev"
/>
<el-table
v-loading="isLoaded"
:data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize)"
style="width: 100%"
stripe
class="table mgt-20 mgb-20"
@row-click="rowClick"
@selection-change="tableSelectionChange"
>
<el-table-column
v-if="batch.show"
type="selection"
width="55"
/>
<el-table-column
type="index"
:index="indexMethod">
</el-table-column>
<el-table-column
prop="mailtype"
label="类型"
sortable
show-overflow-tooltip
:formatter="formType"
/>
<el-table-column
prop="subject"
label="邮件主题"
sortable
show-overflow-tooltip
/>
<el-table-column
prop="attachments"
label="物品"
sortable
show-overflow-tooltip
:formatter="formItems"
/>
<el-table-column
prop="sendtime"
label="发送时间"
sortable
show-overflow-tooltip
:formatter="formdate"
/>
<el-table-column
prop="expiretime"
label="过期时间"
sortable
show-overflow-tooltip
:formatter="formdate"
/>
<el-table-column
label="操作"
fixed="right"
width="170"
>
<template slot-scope="scope">
<el-button
type="text"
size="small"
@click.stop="editReward(scope.row)"
>详情</el-button>
<el-button
v-if=" (isDev && permEdit) || (!isDev && permPublish)"
type="text"
size="small"
@click.stop="delMail(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- pagination -->
<el-pagination
class="al-r"
layout="total, sizes, prev, pager, next, jumper"
:hide-on-single-page="true"
:current-page="currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
:total="total"
@size-change="sizeChange"
@current-change="pageChange"
/>
<!-- Modal1 -->
<el-dialog
title="编辑邮件"
:visible.sync="modalVisible"
:before-close="closeModal"
width="700px"
>
<el-form
ref="modalForm"
:model="modalForm"
:rules="modalRules"
label-width="100px"
>
<el-form-item
label="发件人"
prop="mailFrom"
>
<el-input v-model="modalForm.from" :disabled="!isNew"/>
<span class="ipt-tip">发件人</span>
</el-form-item>
<el-form-item
label="邮件类型"
prop="mailtype"
>
<el-radio-group v-model="modalForm.mailtype">
<el-radio :label="1" :disabled="!isNew">个人邮件</el-radio>
<el-radio :label="2" :disabled="!isNew">群发邮件</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-if="modalForm.mailtype == 2"
label="用户类型"
prop="usertype"
>
<el-radio-group v-model="modalForm.usertype">
<el-radio :label="0" :disabled="!isNew">全体用户</el-radio>
<el-radio :label="1" :disabled="!isNew">邮件发送时间之前注册的用户</el-radio>
<el-radio :label="2" :disabled="!isNew">邮件发送之后注册的用户</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-if="modalForm.mailtype == 1"
label="发件人"
prop="mailTo"
>
<el-input v-model="modalForm.to" :disabled="!isNew"/>
<span class="ipt-tip">收件人</span>
</el-form-item>
<el-form-item
label="邮件子类型"
prop="mailsubtype"
>
<el-input v-model="modalForm.mailsubtype" :disabled="!isNew"/>
</el-form-item>
<el-form-item
label="邮件主题"
prop="subject"
>
<el-input v-model="modalForm.subject"/>
<span class="ipt-tip">邮件主题</span>
</el-form-item>
<el-form-item
label="邮件正文"
prop="content"
>
<el-input
type="textarea"
v-model="modalForm.content"
/>
</el-form-item>
<el-form-item
label="扩展字段"
prop="ext"
>
<el-input v-model="modalForm.ext"/>
</el-form-item>
<el-form-item
class="ipt-tip"
label="发送时间"
prop="sendtime"
>
<el-date-picker
v-model="modalForm.sendtime"
type="datetime"
placeholder="选择发送时间"/>
</el-form-item>
<el-form-item
class="ipt-tip"
label="过期时间"
prop="expiretime"
>
<el-date-picker
v-model="modalForm.expiretime"
type="datetime"
placeholder="选择过期时间"/>
</el-form-item>
<el-form-item
label="物品"
prop="items"
>
<el-table
:data="modalForm.attachments"
style="width: 100%"
size="mini"
>
<el-table-column
prop="itemid"
label="物品"
show-overflow-tooltip
/>
<el-table-column
prop="itemnum"
label="数量"
show-overflow-tooltip
/>
<el-table-column
label="操作"
fixed="right"
>
<template slot-scope="scope">
<el-button
type="text"
size="small"
@click="editItem(scope.$index,scope.row)"
v-if="permEdit"
>编辑</el-button>
<el-button
v-if="permEdit"
type="text"
size="small"
@click="delItem(scope.$index)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<el-button
type="primary"
size="mini"
@click="addItem"
v-if="permEdit"
>添加</el-button>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="closeModal"> </el-button>
<el-button
type="primary"
@click="save"
v-if="permEdit"
> </el-button>
</div>
</el-dialog>
<!-- Modal2 -->
<el-dialog
title="编辑附件"
:visible.sync="innerModalVisible"
append-to-body
:before-close="closeInnerModal"
width="700px"
>
<el-form
ref="innerModalForm"
:model="innerModalForm"
:rules="innerModalRules"
label-width="100px"
>
<el-form-item
label="物品ID"
prop="itemid"
>
<el-input v-model="innerModalForm.itemid"/>
</el-form-item>
<el-form-item
label="数量"
prop="itemnum"
>
<el-input v-model.number="innerModalForm.itemnum"/>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="closeInnerModal"> </el-button>
<el-button
type="primary"
@click="saveItem"
v-if="permEdit"
> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { getGame } from '@/api/games'
import getPageTitle from '@/utils/get-page-title'
import {
getMails,
saveMail,
delMails,
getOpsToken
} from '@/api/mail'
import moment from 'moment'
export default {
name: 'GameDetailsMail',
data() {
return {
// common
uid: '',
gameInfo: {},
permEdit: false,
permPublish: false,
isNew: false,
isNewItem: false,
isDev: true,
uploadUrl: '',
// toolbar
batch: {
show: false,
txt: '批量操作'
},
switchText: '获取正式数据',
// table
tableData: [],
isLoaded: false,
multipleSelection: [],
// pagination
currentPage: 1,
pageSize: 10,
total: 0,
// modal1
modalVisible: false,
modalForm: {
subject: '',
actived: true,
attachments: [],
content: '',
to: '',
from: '',
sendtime: '',
expiretime: '',
mailtype: 1,
mailsubtype: 0,
usertype: 0,
gameid: '',
ext: ''
},
modalRules: {
subject: [{ required: true, message: '请输入关键字', trigger: 'blur' }],
sendtime: [{ required: true, message: '请选择发送时间', trigger: 'blur' }],
expiretime: [{ required: true, message: '请选择过期时间', trigger: 'blur' }],
},
modalItemList: [],
// modal2
innerModalVisible: false,
innerModalForm: {
itemid: '',
itemnum: 1
},
innerModalRules: {
itemnid: [
{ required: true, message: '请输入物品 id', trigger: 'blur' }
],
itemnum: [
{ required: true, message: '请输入物品数量', trigger: 'blur' },
{
type: 'number',
message: '物品数量只能为数字',
trigger: 'blur'
}
]
},
curItem: 0,
}
},
computed: {
...mapGetters(['userInfo'])
},
mounted() {
this.uid = this.$route.params.uid
this.permEdit =
this.userInfo.permissions.includes(`${this.uid}-edit`) ||
this.userInfo.permissions.includes(`${this.uid}-publish`) ||
this.userInfo.permissions.includes(`games-writeable`)
this.permPublish =
this.userInfo.permissions.includes(`${this.uid}-publish`) ||
this.userInfo.permissions.includes(`games-writeable`)
this.uploadUrl = process.env.VUE_APP_OPS_API + '/upload/'
this.getGameInfo(this.queryMails)
},
methods: {
switchData() {
this.isDev = !this.isDev
this.isDev
? (this.switchText = '获取正式数据')
: (this.switchText = '获取测试数据')
this.currentPage = 1
this.queryMails()
},
getGameInfo(cb) {
getGame({ uid: this.uid })
.then(res => {
const { data } = res
if (data.errcode === 0) {
this.gameInfo = data.gameInfo
this.$route.meta.title = this.gameInfo.game_name
document.title = getPageTitle(this.gameInfo.game_name)
}
if (cb && cb instanceof Function) cb()
})
.catch(err => {
console.log(err)
})
},
queryMails() {
this.isLoaded = true
getMails({
uid: this.gameInfo._id,
gameid: this.gameInfo.game_id,
currentPage: this.currentPage,
pageSize: this.pageSize,
isDev: this.isDev
})
.then(res => {
const data = res.data
if (data.errcode === 0) {
this.tableData = data.maillist
this.total = data.maillist.length;
this.isLoaded = false
}
})
.catch(err => {
console.log(err)
this.isLoaded = false;
})
},
getOpsToken() {
return new Promise((resolve, reject) => {
getOpsToken()
.then(res => {
const data = res.data
data.errcode === 0 ? resolve(data.result) : reject(data.errmsg)
})
.catch(err => {
reject(err)
})
})
},
validateForm(formName) {
return new Promise((resolve, reject) => {
this.$refs[formName].validate(valid => {
valid ? resolve(valid) : reject(valid)
})
})
},
clearValidate(formName) {
this.$refs[formName].clearValidate()
},
// toolbar
addMail() {
this.openModal()
this.isNew = true
this.modalForm = {
subject: '',
actived: true,
attachments: [],
content: '',
to: '',
from: '',
sendtime: new Date(Date.now() + 86400000),
expiretime: new Date(Date.now() + 86400000),
mailtype: 1,
mailsubtype: 0,
usertype: 0,
ext: ''
}
},
batchOpt() {
this.batch.show = !this.batch.show
this.batch.txt = this.batch.show ? '关闭' : '批量操作'
},
refreshData() {
this.queryMails()
},
// table
editReward(row) {
this.isNew = false
this.modalForm = JSON.parse(JSON.stringify(row))
this.openModal()
},
addItem() {
this.isNewItem = true
this.openInnerModal()
this.innerModalForm = {
itemid: '',
itemnum: 1
}
},
editItem(index, row) {
this.isNewItem = false
this.innerModalForm = JSON.parse(JSON.stringify(row))
this.curItem = index
this.openInnerModal()
},
delItem(index) {
this.modalForm.attachments.splice(index, 1)
},
save() {
this.validateForm('modalForm')
.then(() => {
this.modalForm.gameid = this.gameInfo.game_id
this.saveMail({ data: this.modalForm, isDev: this.isDev })
.then(res => {
this.$message.success('保存成功!')
this.queryMails()
this.closeModal()
})
.catch(err => {
console.log(err)
})
})
.catch(() => {
this.$message.error('请按要求填写表单!')
})
},
delMail(row) {
this.$confirm('是否确认删除该邮件?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
delMails({
uid: this.gameInfo._id,
ids: [row.mailid],
gameid: this.gameInfo.game_id,
isDev: this.isDev
})
.then(res => {
const data = res.data
if (data.errcode === 0) {
this.$message.success('已成功删除该邮件!')
this.queryMails()
}
})
.catch(err => {
console.log(err)
})
})
.catch(() => {
this.$message.info('已取消删除!')
})
},
batchDel() {
if (this.multipleSelection.length === 0) {
this.$message.error('无选中邮件!')
return
}
const ids = this.multipleSelection.map(item => {
return item.mailid
})
this.$confirm(
`是否要删除选中的${this.multipleSelection.length}条邮件`,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
)
.then(() => {
delMails({
uid: this.gameInfo._id,
ids: ids,
gameid: this.gameInfo.game_id,
isDev: this.isDev
})
.then(res => {
const data = res.data
if (data.errcode === 0) {
this.$message.success('已成功删除选中邮件!')
this.queryMails()
}
})
.catch(err => {
console.log(err)
})
})
.catch(() => {
this.$message.info('已取消删除!')
})
},
indexMethod(index) {
return (this.currentPage - 1) * this.pageSize + index + 1
},
formType(row, column, cellValue, index) {
if (cellValue == 1) {
return '个人邮件'
} else {
return '群发邮件'
}
},
formItems(row, column, cellValue, index) {
if (cellValue) {
const items = cellValue.map(item => {
return `${item.itemid}×${item.itemnum}`
})
return items.join('')
} else {
return '-'
}
},
formdate(row, column, cellValue, index) {
return cellValue ? moment(cellValue).format('YYYY-MM-DD HH:MM:SS') : '-'
},
rowClick(row, column, event) {
this.editReward(row)
},
tableSelectionChange(val) {
this.multipleSelection = val
},
// pagination
sizeChange(val) {
this.pageSize = val
// this.queryMails()
},
pageChange(val) {
this.currentPage = val
// this.queryMails()
},
// modal
openModal() {
this.modalVisible = true
},
closeModal() {
this.clearValidate('modalForm')
this.modalVisible = false
},
saveMail(data) {
return new Promise((resolve, reject) => {
saveMail(data)
.then(res => {
const data = res.data
data.errcode === 0 ? resolve(data) : reject()
})
.catch(err => {
console.log(err)
})
})
},
openInnerModal() {
this.innerModalVisible = true
},
closeInnerModal() {
this.clearValidate('innerModalForm')
this.innerModalVisible = false
},
saveItem() {
const self = this
this.validateForm('innerModalForm')
.then(() => {
if (self.isNewItem) {
self.modalForm.attachments.push(self.innerModalForm)
} else {
self.modalForm.attachments.splice(self.curItem, 1, self.innerModalForm)
}
self.$message.success('已成功保存附件物品!')
self.closeInnerModal()
})
.catch((err) => {
console.error(err)
self.$message.error('请按要求填写表单!')
})
},
}
}
</script>
<style lang="sass" scoped>
</style>

View File

@ -554,7 +554,6 @@ export default {
comment: ''
}
},
batchDel() {},
batchOpt() {
this.batch.show = !this.batch.show
this.batch.txt = this.batch.show ? '关闭' : '批量操作'

View File

@ -95,7 +95,8 @@ module.exports = {
config
// https://webpack.js.org/configuration/devtool/#development
.when(process.env.NODE_ENV === 'development', config =>
config.devtool('cheap-source-map')
// config.devtool('cheap-source-map')
config.devtool('source-map')
)
config.when(process.env.NODE_ENV !== 'development', config => {