提交 dfa42d0e authored 作者: lihuihui's avatar lihuihui

update: 新增短信模板

上级 40eb9cc5
module.exports = {
domain: 'dev.ezijing.com',
url: 'https://x-training2.ezijing.com/api',
url: 'https://msg.ezijing.com/api',
webpack: {
externals: {
CKEDITOR: 'window.CKEDITOR',
......
......@@ -108,6 +108,36 @@ export function addLog(data) {
export function getLogList(params) {
return httpRequest.get('/api/message/v1/system/logs', { params })
}
/**
* 短信模板列表
*/
export function getSmsTempList(params) {
return httpRequest.get('/api/message/admin/v1/sms/templates', { params })
}
/**
* 短信模板创建
*/
export function creatSmsTemp(params) {
return httpRequest.post('/api/message/admin/v1/sms/template', params)
}
/**
* 删除消息模板列表
*/
export function deleteSmsTemp(id) {
return httpRequest.delete(`/api/message/admin/v1/sms/${id}/template`)
}
/**
* 消息模板详情
*/
export function getSmsTempDetail(id) {
return httpRequest.get(`/api/message/admin/v1/sms/${id}/template`)
}
/**
* 消息模板编辑
*/
export function editSmsTemp(id, params) {
return httpRequest.put(`/api/message/admin/v1/sms/${id}/template`, params)
}
// export function uploadFile(data) {
// return httpRequest.post('/api/lms/util/upload-file', data, {
// headers: { 'Content-Type': 'multipart/form-data' }
......
<template>
<div class="app-aside">
<img src="http://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/static/ezijing/logo/ezijing-logo.svg" alt="" class="logo">
<img src="http://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/static/ezijing/logo/ezijing-logo.svg" class="logo" />
<el-menu :router="true" :default-active="$route.path" class="menu">
<template v-for="(item, index) in defaultMenus">
<el-submenu :index="item.path" :key="index" v-if="item.children">
<el-submenu v-if="item.children" :index="item.path" :key="index">
<template slot="title">
<i :class="item.icon"></i>
<span>{{ item.title }}</span>
</template>
<el-menu-item v-for="(subitem, index) in item.children" :index="subitem.path" :key="index">
{{ subitem.title }}
</el-menu-item>
</el-submenu>
<el-menu-item :key="index" :index="item.path" v-else class="menu-box"><div class="icon"></div><span>{{ item.title }}</span></el-menu-item>
<el-menu-item v-else :key="index" :index="item.path" class="menu-box"
><div class="icon"></div>
<span><i :class="item.icon"></i>{{ item.title }}</span></el-menu-item
>
</template>
</el-menu>
</div>
......@@ -28,19 +32,38 @@ export default {
defaultMenus: [
{
title: '消息看板',
path: '/msgView'
path: '/msgView',
icon: 'el-icon-menu'
},
{
title: '消息模板',
path: '/msgTemplate'
path: '/msgTemplate',
icon: 'el-icon-s-order'
},
{
title: '短信管理',
path: '/sms',
icon: 'el-icon-s-promotion',
children: [
{
title: '短信模板',
path: '/sms/smsTemplate'
},
{
title: '分发短信记录',
path: '/sms/smsRecord'
}
]
},
{
title: '用户群组',
path: '/userGroup'
path: '/userGroup',
icon: 'el-icon-s-custom'
},
{
title: '日志',
path: '/log'
path: '/log',
icon: 'el-icon-s-management'
}
]
}
......@@ -62,84 +85,96 @@ export default {
</script>
<style lang="scss">
.logo{
.logo {
width: 156px;
display: block;
margin: 30px auto;
}
.menu-box{
.menu-box {
display: flex;
align-items: center;
.icon{
margin-right: 20px;
width: 16px;
height: 16px;
}
&.is-active{
&:nth-child(1){
.icon{
background: url(https://zws-imgs-pub.ezijing.com/static/public/ead012c5b38a59a49aced67a5c43712c.png);
background-size: 100% 100%;
}
}
&:nth-child(2){
.icon{
background: url(https://zws-imgs-pub.ezijing.com/static/public/9b7a03ac5fb386c2f4fae65faf9fd11d.png);
background-size: 100% 100%;
}
}
&:nth-child(3){
.icon{
background: url(https://zws-imgs-pub.ezijing.com/static/public/468a25489daba5a8b265bf50a96f4613.png);
background-size: 100% 100%;
}
}
&:nth-child(4){
.icon{
background: url(https://zws-imgs-pub.ezijing.com/static/public/b7770ce952088e4c6e011f132c6c5f7a.png);
background-size: 100% 100%;
}
}
}
&:nth-child(1){
.icon{
background: url(https://zws-imgs-pub.ezijing.com/static/public/74304dd0f8dd0f6d25411314bab951d2.png);
background-size: 100% 100%;
}
}
&:nth-child(2){
.icon{
background: url(https://zws-imgs-pub.ezijing.com/static/public/02d90bc10b8f413cd8bc07e935cd25e4.png);
background-size: 100% 100%;
}
}
&:nth-child(3){
.icon{
background: url(https://zws-imgs-pub.ezijing.com/static/public/910468f96b35d76679aa1480561f2c4b.png);
background-size: 100% 100%;
}
}
&:nth-child(4){
.icon{
background: url(https://zws-imgs-pub.ezijing.com/static/public/470a37dc41a32ee58fa08e8da97cb666.png);
background-size: 100% 100%;
}
}
// .icon{
// margin-right: 20px;
// width: 16px;
// height: 16px;
// }
// &.is-active{
// &:nth-child(1){
// .icon{
// background: url(https://zws-imgs-pub.ezijing.com/static/public/ead012c5b38a59a49aced67a5c43712c.png);
// background-size: 100% 100%;
// }
// }
// &:nth-child(2){
// .icon{
// background: url(https://zws-imgs-pub.ezijing.com/static/public/9b7a03ac5fb386c2f4fae65faf9fd11d.png);
// background-size: 100% 100%;
// }
// }
// &:nth-child(3){
// .icon{
// background: url(https://zws-imgs-pub.ezijing.com/static/public/468a25489daba5a8b265bf50a96f4613.png);
// background-size: 100% 100%;
// }
// }
// &:nth-child(4){
// .icon{
// background: url(https://zws-imgs-pub.ezijing.com/static/public/b7770ce952088e4c6e011f132c6c5f7a.png);
// background-size: 100% 100%;
// }
// }
// &:nth-child(5){
// .icon{
// background: url(https://zws-imgs-pub.ezijing.com/static/public/b7770ce952088e4c6e011f132c6c5f7a.png);
// background-size: 100% 100%;
// }
// }
// }
// &:nth-child(1){
// .icon{
// background: url(https://zws-imgs-pub.ezijing.com/static/public/74304dd0f8dd0f6d25411314bab951d2.png);
// background-size: 100% 100%;
// }
// }
// &:nth-child(2){
// .icon{
// background: url(https://zws-imgs-pub.ezijing.com/static/public/02d90bc10b8f413cd8bc07e935cd25e4.png);
// background-size: 100% 100%;
// }
// }
// &:nth-child(3){
// .icon{
// background: url(https://zws-imgs-pub.ezijing.com/static/public/910468f96b35d76679aa1480561f2c4b.png);
// background-size: 100% 100%;
// }
// }
// &:nth-child(4){
// .icon{
// background: url(https://zws-imgs-pub.ezijing.com/static/public/470a37dc41a32ee58fa08e8da97cb666.png);
// background-size: 100% 100%;
// }
// }
// &:nth-child(5){
// .icon{
// background: url(https://zws-imgs-pub.ezijing.com/static/public/470a37dc41a32ee58fa08e8da97cb666.png);
// background-size: 100% 100%;
// }
// }
}
.app-aside {
padding-top: 16px;
width: 250px;
background-color: #F3F7FC;
background-color: #f3f7fc;
.menu {
border: 0;
}
}
.el-menu-item{
&.is-active{
.el-menu-item {
&.is-active {
font-weight: bold !important;
}
}
.el-menu{
.el-menu {
background: none !important;
}
</style>
......@@ -15,69 +15,29 @@
</div>
</div>
<div class="table-box">
<el-table
@selection-change="handleSelectionChange"
:data="tableData"
tooltip-effect="dark"
style="width: 100%">
<el-table-column
type="selection"
width="55">
<el-table @selection-change="handleSelectionChange" :data="tableData" tooltip-effect="dark" style="width: 100%">
<el-table-column type="selection" width="55"> </el-table-column>
<el-table-column align="center" header-align="center" prop="id" label="id" width="180"> </el-table-column>
<el-table-column align="center" header-align="center" prop="name" label="名称" width="180"> </el-table-column>
<el-table-column align="center" header-align="center" prop="created_at" label="创建时间" width="180">
</el-table-column>
<el-table-column
align="center"
header-align="center"
prop="id"
label="id"
width="180">
</el-table-column>
<el-table-column
align="center"
header-align="center"
prop="name"
label="名称"
width="180">
</el-table-column>
<el-table-column
align="center"
header-align="center"
prop="created_at"
label="创建时间"
width="180">
</el-table-column>
<el-table-column
align="center"
header-align="center"
label="通道">
<el-table-column align="center" header-align="center" label="通道">
<template slot-scope="scope">
<span v-for="(items, index) in scope.row.templates" :key="index">
{{ channelValue(items.channel) }}
</span>
</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
header-align="center">
<el-table-column label="操作" align="center" header-align="center">
<template slot-scope="scope">
<el-button
class="btn-color"
type="text"
@click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button
class="btn-color"
type="text"
@click="handleDelete(scope.row)">删除</el-button>
<el-button class="btn-color" type="text" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button class="btn-color" type="text" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="page-box">
<el-pagination
layout="prev, pager, next"
@current-change="changePage"
:total="totals">
</el-pagination>
<el-pagination layout="prev, pager, next" @current-change="changePage" :total="totals"> </el-pagination>
</div>
</div>
</app-container>
......@@ -98,8 +58,7 @@ export default {
limit: 10
},
totals: 1,
tableData: [
],
tableData: [],
selectItem: []
}
},
......@@ -130,8 +89,7 @@ export default {
this.page.page = response.data.current_page
// this.page.lastPage = response.data.last_page
})
.finally(() => {
})
.finally(() => {})
},
handleDelete(data) {
api
......@@ -139,8 +97,7 @@ export default {
.then(response => {
this.getMsgTempList()
})
.finally(() => {
})
.finally(() => {})
},
handleEdit(i, obj) {
this.$router.push({
......@@ -167,10 +124,8 @@ export default {
addLogs(msg) {
api
.addLog({ description: msg })
.then(response => {
})
.finally(() => {
})
.then(response => {})
.finally(() => {})
},
deleteTampList() {
const arr = []
......@@ -183,8 +138,7 @@ export default {
this.getMsgTempList()
this.addLogs('删除模板')
})
.finally(() => {
})
.finally(() => {})
},
handleSelectionChange(val) {
this.selectItem = val
......@@ -194,39 +148,39 @@ export default {
}
</script>
<style lang="scss" scoped>
.temp-box{
.temp-box {
padding: 0 30px;
.temp-title{
.temp-title {
height: 100px;
align-items: center;
border-bottom: 1px solid #f1f1f1;
display: flex;
.search{
.search {
display: flex;
align-items: center;
span{
span {
font-size: 14px;
color: #333333;
}
.input{
.input {
width: 240px;
margin: 0 40px 0 20px;
}
}
}
.tool-btn{
.tool-btn {
margin-left: auto;
}
.btn{
.btn {
font-weight: normal;
font-size: 14px;
}
.btn-color{
.btn-color {
font-size: 14px;
color: #666 ;
color: #666;
}
}
.page-box{
.page-box {
display: flex;
justify-content: center;
margin: 20px 0;
......
<template>
<app-container>
<div class="temp-box">
<div class="temp-title">
<div class="search">
<span>名称</span>
<el-input v-model="input" placeholder="请输入模板名称" class="input"></el-input>
<el-button type="primary" class="btn" @click="searchList">搜索</el-button>
</div>
<div class="tool-btn">
<el-button class="btn" @click="createTamp">创建</el-button>
<!-- <el-button class="btn">编辑</el-button> -->
<el-button v-if="selectItem.length" class="btn" @click="deleteTampList">删除</el-button>
<el-button v-else disabled class="btn">删除</el-button>
</div>
</div>
<div class="table-box">
<el-table @selection-change="handleSelectionChange" :data="tableData" tooltip-effect="dark" style="width: 100%">
<el-table-column type="selection" width="55"> </el-table-column>
<el-table-column align="center" header-align="center" prop="id" label="id" width="180"> </el-table-column>
<el-table-column align="center" header-align="center" prop="name" label="名称" width="180"> </el-table-column>
<el-table-column align="center" header-align="center" prop="created_at" label="创建时间" width="180">
</el-table-column>
<el-table-column align="center" header-align="center" label="通道">
<template slot-scope="scope">
<span v-for="(items, index) in scope.row.templates" :key="index">
{{ channelValue(items.channel) }}
</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" header-align="center">
<template slot-scope="scope">
<el-button class="btn-color" type="text" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button class="btn-color" type="text" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="page-box">
<el-pagination layout="prev, pager, next" @current-change="changePage" :total="totals"> </el-pagination>
</div>
</div>
</app-container>
</template>
<script>
import AppContainer from '@/components/AppContainer'
import * as api from '@/api/common.js'
export default {
components: {
AppContainer
},
data() {
return {
input: '',
page: {
page: 1,
limit: 10
},
totals: 1,
tableData: [],
selectItem: []
}
},
mounted() {
this.getMsgTempList(this.page)
},
methods: {
channelValue(n) {
const json = {
0: '默认',
1: '邮件',
2: '短信',
3: '钉钉',
4: '公众号'
}
return json[n]
},
searchList() {
this.getMsgTempList({ name: this.input })
},
getMsgTempList(params) {
api
.getMsgTempList(params)
.then(response => {
this.tableData = response.data.data
this.totals = response.data.total
this.page.page = response.data.current_page
// this.page.page = response.data.current_page
// this.page.lastPage = response.data.last_page
})
.finally(() => {})
},
handleDelete(data) {
api
.deleteTemp(data.id)
.then(response => {
this.getMsgTempList()
})
.finally(() => {})
},
handleEdit(i, obj) {
this.$router.push({
path: '/msgTemplate/detail',
query: {
id: obj.id
}
})
console.log(i, obj)
},
createTamp() {
this.$router.push({
path: '/smsTemplate/detail'
})
},
changePage(n) {
this.page.page = n
this.getMsgTempList(this.page)
},
prevPage() {
this.page.page--
this.getMsgTempList(this.page)
},
addLogs(msg) {
api
.addLog({ description: msg })
.then(response => {})
.finally(() => {})
},
deleteTampList() {
const arr = []
this.selectItem.map(item => {
arr.push(item.id)
})
api
.deleteTampList({ ids: arr.toString() })
.then(response => {
this.getMsgTempList()
this.addLogs('删除模板')
})
.finally(() => {})
},
handleSelectionChange(val) {
this.selectItem = val
console.log(val)
}
}
}
</script>
<style lang="scss" scoped>
.temp-box {
padding: 0 30px;
.temp-title {
height: 100px;
align-items: center;
border-bottom: 1px solid #f1f1f1;
display: flex;
.search {
display: flex;
align-items: center;
span {
font-size: 14px;
color: #333333;
}
.input {
width: 240px;
margin: 0 40px 0 20px;
}
}
}
.tool-btn {
margin-left: auto;
}
.btn {
font-weight: normal;
font-size: 14px;
}
.btn-color {
font-size: 14px;
color: #666;
}
}
.page-box {
display: flex;
justify-content: center;
margin: 20px 0;
}
</style>
<template>
<app-container class="relative">
<div class="detail-box">
<div class="flex">
<div class="title-steps">
<el-steps :active="active" finish-status="success">
<el-step title="发送什么内容"></el-step>
<el-step title="概览"></el-step>
</el-steps>
</div>
</div>
<div class="detail-content" v-if="this.$route.query.id">
<template v-if="Object.keys(form).length">
<send-content
:form="form"
@clickPrev="clickPrev"
@clickNext="clickNext"
></send-content>
</template>
</div>
<template v-else>
<send-content
:form="form"
@clickPrev="clickPrev"
@clickNext="clickNext"
></send-content>
</template>
</div>
</app-container>
</template>
<script>
import AppContainer from '@/components/AppContainer'
import sendContent from './components/sendContent'
import * as api from '@/api/common.js'
export default {
components: {
AppContainer,
sendContent
},
data() {
return {
step1: '111',
form: {},
active: 3,
data: {}
}
},
mounted() {
if (this.$route.query.id) {
this.initData()
}
},
methods: {
// in
initData() {
api
.getSmsTempDetail(this.$route.query.id)
.then(response => {
if (response.code === 0) {
this.form = response.data
}
})
.finally(() => {})
},
clickNext() {
this.active++
},
clickPrev() {
this.active--
},
prevBtn() {
console.log(this.active)
if (this.active > 0) {
this.active--
} else {
this.$router.go(-1)
}
},
nextBtn() {
if (this.active === 0) {
this.form.step1 === '' ? this.$message('请填写') : this.active++
} else if (this.active === 1) {
this.form.step2 === '' ? this.$message('请选择') : this.active++
} else if (this.active === 2) {
console.log(this.form.step3.length)
this.form.step3.length === 0 ? this.$message('请选择') : this.active++
}
}
}
}
</script>
<style lang="scss" scoped>
::v-deep {
.app-container-bd {
position: relative;
}
}
.detail-box {
padding: 0 30px 0;
.foot-btn-box {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 100%;
height: 100px;
padding: 0 30px;
box-sizing: border-box;
.content {
display: flex;
height: 100%;
align-items: center;
border-top: 1px solid #f1f1f1;
}
}
}
.flex {
display: flex;
align-items: center;
height: 80px;
border-bottom: 1px solid #f1f1f1;
}
.title-steps {
width: 100%;
}
</style>
<template>
<app-container>
<div class="temp-box">
<div class="temp-title">
<!-- <div class="search">
<span>名称</span>
<el-input v-model="input" placeholder="请输入模板名称" class="input"></el-input>
<el-button type="primary" class="btn" @click="searchList">搜索</el-button>
</div> -->
<div>
<el-button class="btn" @click="createTamp">创建</el-button>
</div>
</div>
<div class="table-box">
<el-table @selection-change="handleSelectionChange" :data="tableData" tooltip-effect="dark" style="width: 100%">
<el-table-column align="center" header-align="center" prop="id" label="id"> </el-table-column>
<el-table-column align="center" header-align="center" prop="title" label="标题">
</el-table-column>
<el-table-column align="center" header-align="center" prop="created_at" label="创建时间">
</el-table-column>
<el-table-column align="center" header-align="center" label="短信类型">
<template slot-scope="scope">
{{ templateTypeValue(scope.row.template_type) }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" header-align="center">
<template slot-scope="scope">
<el-button class="btn-color" type="text" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button class="btn-color" type="text" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="page-box">
<el-pagination layout="prev, pager, next" @current-change="changePage" :total="totals"> </el-pagination>
</div>
</div>
</app-container>
</template>
<script>
import AppContainer from '@/components/AppContainer'
import * as api from '@/api/common.js'
export default {
components: {
AppContainer
},
data() {
return {
input: '',
page: {
page: 1,
limit: 10
},
totals: 1,
tableData: [],
selectItem: []
}
},
mounted() {
this.getMsgTempList(this.page)
},
methods: {
channelValue(n) {
const json = {
0: '默认',
1: '邮件',
2: '短信',
3: '钉钉',
4: '公众号'
}
return json[n]
},
templateTypeValue(n) {
const val = {
0: '验证码',
1: '短信通知',
2: '推广短信',
3: '国际/港澳台消息'
}
return val[n]
},
searchList() {
this.getMsgTempList({ name: this.input })
},
getMsgTempList(params) {
api
.getSmsTempList(params)
.then(response => {
this.tableData = response.data.data
this.totals = response.data.total
this.page.page = response.data.current_page
this.page.page = response.data.current_page
// this.page.lastPage = response.data.last_page
})
.finally(() => {})
},
handleDelete(data) {
api
.deleteSmsTemp(data.id)
.then(response => {
this.getMsgTempList()
})
.finally(() => {})
},
handleEdit(i, obj) {
this.$router.push({
path: '/smsTemplate/detail',
query: {
id: obj.id
}
})
console.log(i, obj)
},
createTamp() {
this.$router.push({
path: '/smsTemplate/detail'
})
},
changePage(n) {
this.page.page = n
this.getMsgTempList(this.page)
},
prevPage() {
this.page.page--
this.getMsgTempList(this.page)
},
addLogs(msg) {
api
.addLog({ description: msg })
.then(response => {})
.finally(() => {})
},
deleteTampList() {
const arr = []
this.selectItem.map(item => {
arr.push(item.id)
})
api
.deleteTampList({ ids: arr.toString() })
.then(response => {
this.getMsgTempList()
this.addLogs('删除模板')
})
.finally(() => {})
},
handleSelectionChange(val) {
this.selectItem = val
console.log(val)
}
}
}
</script>
<style lang="scss" scoped>
.temp-box {
padding: 0 30px;
.temp-title {
height: 100px;
align-items: center;
border-bottom: 1px solid #f1f1f1;
display: flex;
.search {
display: flex;
align-items: center;
span {
font-size: 14px;
color: #333333;
}
.input {
width: 240px;
margin: 0 40px 0 20px;
}
}
}
.tool-btn {
margin-left: auto;
}
.btn {
font-weight: normal;
font-size: 14px;
}
.btn-color {
font-size: 14px;
color: #666;
}
}
.page-box {
display: flex;
justify-content: center;
margin: 20px 0;
}
</style>
......@@ -16,7 +16,11 @@ export default [
/* 用户群组 */
{ path: '/userGroup', component: () => import(/* webpackChunkName: "feedback" */ '@/pages/userGroup/index') },
/* 日志 */
{ path: '/log', component: () => import(/* webpackChunkName: "feedback" */ '@/pages/log/index') }
{ path: '/log', component: () => import(/* webpackChunkName: "feedback" */ '@/pages/log/index') },
/* 短信管理 */
{ path: '/sms/smsTemplate', component: () => import(/* webpackChunkName: "feedback" */ '@/pages/sms/smsTemplate/index') },
{ path: '/sms/smsRecord', component: () => import(/* webpackChunkName: "feedback" */ '@/pages/sms/smsRecord/index') },
{ path: '/smsTemplate/detail', component: () => import(/* webpackChunkName: "feedback" */ '@/pages/sms/smsTemplate/detail') }
// /* 修改密码 */
// {
// path: '/account/password',
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论