Commit 7f1b017b by liuchenxi

Merge branch 'feature/12月迭代'

parents d3a0a1a0 1a97529c
......@@ -7,6 +7,7 @@
<link rel="icon" href="<%= BASE_URL %>favicon2.ico">
<link rel="stylesheet" type="text/css" href="//web-1251519181.file.myqcloud.com/lib/element-ui/2.15.6/index.css" />
<link rel="stylesheet" type="text/css" href="//web-1251519181.file.myqcloud.com/custom-element/custom-element.1.0.68.css" />
<link rel="stylesheet" href="//at.alicdn.com/t/font_2995156_rf810o69kh.css">
<title>实施运维</title>
</head>
<body class="damolish">
......
......@@ -30,13 +30,15 @@ let marketingApi = {
url: '/sms/update-sms-setting',
// useFormData: true
},
getSystemTemplate: '/sms/page-system-template',
// 生成appid
getAppid: '/sms/default-appid',
};
let authApi = {
/** 登录信息 */
getUserInfo: '/loginuser'
getUserInfo: '/loginuser',
getLoginOut: '/logout',
};
marketingApi = getFetch(marketingApi, '/marketing-operation');
......
<template>
<el-aside width="200px">
<el-menu
class="aside-menu"
style="height:100%"
router
:default-active="$route.query.tabId">
<template v-for="item in menuList">
<el-menu-item v-if="item.children.length === 0" :route="{path: item.uri, query: {tabId:item.code}}" :key="item.code" :index="item.code"><i class="iconfont" style="margin-right:6px" :class="item.iconUrl"></i>{{item.menuName}}</el-menu-item>
<el-submenu v-else :key="item.code" :index="item.uri">
<template slot="title"><i class="iconfont" style="margin-right:6px" :class="item.iconUrl"></i>{{item.menuName}}</template>
<template v-for="item2 in item.children">
<el-menu-item v-if="item2.children.length === 0" :route="{path: item2.uri, query: {tabId:item2.code}}" :key="item2.code" :index="item2.code">{{item2.menuName}}</el-menu-item>
<el-submenu v-else :key="item2.code" :index="item.uri">
<template slot="title">{{item2.menuName}}</template>
<el-menu-item v-for="item3 in item2.children" :route="{path: item3.uri, query: {tabId:item3.code}}" :key="item3.code" :index="item3.code">{{item3.menuName}}</el-menu-item>
</el-submenu>
</template>
</el-submenu>
</template>
</el-menu>
</el-aside>
</template>
<script>
export default {
name: 'BaseAside',
props: {
menuList: {
type: Array,
required: true,
}
},
};
</script>
<style lang="scss" scoped>
.aside-menu /deep/ {
background-color: #F5F7FA94;
border-right: 1px solid #E4E7ED !important;
.el-submenu__title {
height: 36px;
line-height: 36px;
padding: 0 30px;
color: #606266;
}
.el-menu-item {
position: relative;
height: 36px;
line-height: 36px;
padding: 0 30px;
color: #606266;
&.is-active {
background-color: #F0F5FF ;
color: #1890ff;
&::before {
content: '';
position: absolute;
left: 0;
top: 1px;
width: 2px;
bottom: 1px;
background-color: #1890ff;
}
}
}
.el-menu-item {
background-color: #F5F7FA;
}
}
</style>
<template>
<el-header class="base-header">
<div class="base-header__left">
<i class="iconfont icon-fenleishezhi" style="font-size:24px" @click="drawerVisible = true"></i>
<span class="title">{{currentModule.menuName}}</span>
</div>
<div class="base-header__right">
<el-dropdown @command="onCommand" trigger="click">
<span style="color:#909399;cursor:pointer">
{{ userInfoForm.realName }}<i class="el-icon-arrow-down arrowico" style="margin-left:10px"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="info">账号信息</el-dropdown-item>
<el-dropdown-item command="loginOut">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<!-- 修改用户信息 -->
<el-dialog title="账户信息" class="user-form-dialog" :visible.sync="userFormVisible" width="425px">
<el-form :model="userInfoForm" :rules="userFormRules" ref="userForm" label-width="100px">
<el-form-item label="姓名" prop="realName">
<el-input v-model="userInfoForm.realName"></el-input>
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-radio-group v-model="userInfoForm.gender">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="工号" prop="clerkCode">
<el-input disabled v-model="userInfoForm.clerkCode"></el-input>
</el-form-item>
<el-form-item label="手机号码" prop="phoneNumber">
<el-input v-model="userInfoForm.phoneNumber" type="text" :maxlength="11"></el-input>
</el-form-item>
<el-form-item label="职位" prop="positionName">
<el-input v-model="userInfoForm.positionName"></el-input>
</el-form-item>
</el-form>
</el-dialog>
<el-drawer
:modal="false"
custom-class="header-drawer"
size="300px"
:show-close="false"
append-to-body
:visible.sync="drawerVisible"
direction="ltr">
<div class="header-drawer__container">
<div class="header-drawer__header">
<i class="iconfont icon-fenleishezhi" style="font-size:24px" @click="drawerVisible = true"></i>
<span class="title">{{currentModule.menuName}}</span>
</div>
<el-menu :default-active="currentModule.code">
<el-menu-item v-for="item in moduleList" :key="item.code" :index="item.code" @click="onSelectMenu(item)"><i style="width:20px;display:inline-block" :class="item.iconUrl"></i>{{item.menuName}}</el-menu-item>
</el-menu>
<div class="operation-log" @click="openLog">
<span>操作日志</span>
<i class="iconfont icon-right"></i>
</div>
</div>
</el-drawer>
</el-header>
</template>
<script>
import fetch from '@/api/operation.js';
const { getUserInfo, getLoginOut } = fetch;
export default {
name: 'BaseHeader',
props: {
currentModule: {
type: Object,
required: true
},
moduleList: {
type: Array,
required: true
}
},
data() {
return {
requestProject: 'gic-authcenter',
drawerVisible: false,
// 修改密码
dialogPawVisible: false,
pawForm: {
oldPaw: '',
newPaw: '',
surePaw: ''
},
rules: {
oldPaw: [ { required: true, message: '请输入旧密码', trigger: 'blur' } ],
newPaw: [ { required: true, message: '请输入新密码', trigger: 'blur' } ],
surePaw: [ { required: true, message: '请输入确认密码', trigger: 'blur' } ]
},
// 用户信息 form
userFormVisible: false,
userInfoForm: {
realName: '',
gender: 0, // 1男0女
clerkCode: '',
phoneNumber: '',
positionName: ''
},
userFormRules: {
realName: [ { required: true, message: '请输入姓名', trigger: 'blur' } ],
gender: [ { required: true, message: '请选择性别', trigger: 'change' } ],
clerkCode: [ { required: true, message: '请输入员工代码', trigger: 'blur' } ],
phoneNumber: [ { required: true, message: '请输入手机号', trigger: 'blur' }, { pattern: /^1[34578]\d{9}$/, message: '手机号码格式不正确' } ],
positionName: [ { required: true, message: '请输入职位', trigger: 'blur' } ]
},
loginName: '',
// 是否显示操作日志和权限
// menuAllCode: [],
// isLogBool: true,
// isAuthorityBool: true,
// 判断权限管理的挑转路由
// authorityUrl: ''
};
},
// watch: {
// linkType(newVal) {
// this.entranceType = newVal;
// }
// },
mounted() {
this.getUserInfo();
},
methods: {
openLog() {
window.location.href = window.location.origin + '/operation-platform/#/log?tabId=system_log';
this.drawerVisible = false;
},
onSelectMenu(item) {
if(this.currentModule.code === item.code) return;
window.location.href = window.location.origin + '/' + item.projectCode + '/#' + item.uri;
this.drawerVisible = false;
},
onCommand(cmd) {
switch(cmd) {
case 'info': this.toModifyUser();
break;
case 'loginOut': this.toLoginOut();
break;
}
},
// 获取用户信息
getUserInfo() {
getUserInfo()
.then(res => {
let _result = res.result;
this.userInfoForm.realName = _result.realName;
this.userInfoForm.gender = parseInt(_result.sex);
this.userInfoForm.clerkCode = _result.employeeNumber;
this.userInfoForm.phoneNumber = _result.userMobile;
this.userInfoForm.positionName = _result.position;
this.loginName = _result.loginName;
});
},
// 账户信息
toModifyUser() {
this.userFormVisible = true;
},
// 退出登录
toLoginOut() {
this.$confirm('确认退出吗?', '提示', {
type: 'warning'
})
.then(() => {
getLoginOut()
.then(res => {
this.$message.success('退出成功');
window.location.href = window.location.origin + '/operation-platform/#/';
})
.catch(function(error) {
console.log(error);
});
})
.catch(() => {});
},
}
};
</script>
<style lang="scss">
.header-drawer {
&__container {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
.operation-log {
position: absolute;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
padding: 20px;
bottom: 30px;
left: 0;
right: 0;
color: #909399;
font-size: 14px;
}
.el-menu-item {
height: 36px;
line-height: 36px;
padding: 0 30px;
color: #606266;
&.is-active {
background-color: #F5F7FA ;
color: #1890ff;
}
}
}
&__header {
padding: 0 20px;
height: 60px;
line-height: 60px;
border-bottom: 1px solid #E4E7ED;
i {
vertical-align: middle;
}
.title {
color: #303133;
font-size: 16px;
font-weight: bold;
margin-left: 30px;
vertical-align: middle;
}
}
}
</style>
<style lang="scss" scoped>
.base-header {
border-bottom: 1px solid #E4E7ED;
display: flex;
justify-content: space-between;
align-items: center;
&__left {
i {
cursor: pointer;
vertical-align: middle;
}
.title {
color: #303133;
font-size: 16px;
font-weight: bold;
margin-left: 40px;
vertical-align: middle;
}
}
}
</style>
<template>
<el-container style="height:100vh;background:#fff" direction="vertical">
<base-header :current-module="currentModule" :module-list="moduleList"></base-header>
<el-container>
<base-aside :menu-list="menuList"></base-aside>
<el-main style="padding:0;max-height:calc(100vh - 60px)">
<el-main style="padding:0">
<router-view></router-view>
</el-main>
</el-main>
</el-container>
</el-container>
</template>
<script>
import baseHeader from './header';
import baseAside from './aside';
import fetch from '@/api/operation.js';
const { getUserInfo } = fetch;
import { generatorMenuList, getFirstMenu } from '@/utils';
export default {
name: 'BaseLayout',
components: {
baseHeader,
baseAside
},
props: {
moduleName: {
type: String,
required: true,
}
},
data() {
return {
menuList: [],
currentModule: {},
moduleList: []
};
},
created() {
this.getMenuList();
},
methods: {
getMenuList() {
getUserInfo().then(res => {
console.log(res);
this.entranceList = [];
let entranceList = res.result.menuList ? generatorMenuList(res.result.menuList) : [];
console.log(entranceList);
let menu = entranceList.find(el => el.code === this.moduleName);
this.menuList = menu.children;
this.currentModule = menu;
this.moduleList = entranceList;
let firstMenu = getFirstMenu(this.menuList);
console.log(firstMenu);
if(this.$route.path === '/') {
this.$router.replace({ path: firstMenu.uri, query: { tabId: firstMenu.code } });
}
});
}
}
};
</script>
<style lang="less" scoped>
</style>
<template>
<base-layout module-name="marketing_operation"></base-layout>
</template>
<script>
import BaseLayout from '@/components/layout.vue';
export default {
components: { BaseLayout }
};
</script>
import Layout from '@/layout/layout.vue';
// import Layout from '@/layout/layout.vue';
import Layout from '@/layout/new-layout.vue';
import _import from './import';
export const routes = [
{
path: '/',
name: '短信管理',
redirect: '/messageTemplate',
component: Layout,
children: [
{
......@@ -23,6 +23,11 @@ export const routes = [
name: '短信通道管理',
component: _import('message', 'pass-manage')
},
{
path: 'systemMessageTemplate',
name: '系统短信管理',
component: _import('message', 'system-message')
},
]
}
];
export function generatorMenuList(list) {
let treeData = list.filter(el => !el.parentCode);
treeData = treeData.filter(el => el.isShow === 1);
treeData.sort((a, b) => a.sort - b.sort);
const travel = (root, allData) => {
root.forEach(item => {
let children = allData.filter(el => el.parentCode === item.code);
item.children = children.filter(el => el.isShow === 1);
item.children.sort((a, b) => a.sort - b.sort);
item.nodeChildren = item.children;
item.indexSort = item.sort;
travel(item.children, allData);
});
};
travel(treeData, list);
return treeData;
}
export function getFirstMenu(list) {
const travel = (root) => {
for (let i of root) {
if (i.children.length === 0) {
return i;
} else {
return travel(i.children);
}
}
};
return travel(list);
}
......@@ -6,13 +6,18 @@
<span class="tip">保存后不可编辑,请谨慎填写;如需变更,请提交数据工单处理</span>
</el-form-item>
<el-form-item label="短信签名" prop="smsSignText">
<el-input v-model="form.smsSignText" class="w180" :disabled="disabledSignText" />
<span class="tip">保存后不可编辑,请谨慎填写;如需变更,请提交数据工单处理</span>
<div class="flex">
<el-input v-model="form.smsSignText" class="w180" :disabled="disabledSignText" />
<span class="tip" style="height: 32px">
保存后不可编辑,请谨慎填写;<br />
如需变更,请提交数据工单处理,修改签名后,请删除历史短信模板,重新创建提审后再发送,确保新签名生效。
</span>
</div>
</el-form-item>
<el-form-item label="签名应用通道" prop="channelSignList">
<el-checkbox-group v-model="form.channelSignList">
<el-checkbox v-for="v in channelList" :key="v.channelId" :label="v.channelId" :disabled="disabledCheckBox.includes(v.channelId)">{{ v.channelName }}</el-checkbox>
<span span class="tip">请完善短信通道的短信签名后再勾选</span>
<span class="tip">请完善短信通道的短信签名后再勾选</span>
</el-checkbox-group>
</el-form-item>
<el-form-item label="短信模板数量" prop="maxTemplateCount">
......@@ -198,4 +203,7 @@ export default {
margin-left: 18px;
}
}
.flex {
display: flex;
}
</style>
<template>
<div class="container right_content">
<div class="search">
<el-input v-model="search.searchText" @change="searchTypeChange" prefix-icon="el-icon-search" placeholder="请输入短信模板ID、模板名称、模板内容" style="width: 320px" clearable/>
<el-select v-model="search.channelId" @change="searchTypeChange" placeholder="选择发送通道" class="ml10">
<el-option v-for="item in channelList" :key="item.channelId" :value="item.channelId" :label="item.channelName">{{ item.channelName }}</el-option>
</el-select>
</div>
<div class="mt20">
<el-table :data="tableData.data" element-loading-text="拼命加载中" v-loading="loading">
<el-table-column v-for="(v, i) in tableData.tableHeader" :key="i" :prop="v.prop" :min-width="v.minWidth" :label="v.label" :formatter="v.formatter" :fixed="v.fixed" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="v.formatter" v-html="v.formatter(scope.row)"></span>
<span v-else>{{ scope.row[v.prop] || '--' }}</span>
</template>
</el-table-column>
</el-table>
<!-- <el-pagination background class="dm-pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="tableData.currentPage" :page-sizes="tableData.pageSizeList" :page-size="tableData.pageSize" layout="total, sizes, prev, pager, next" :total="tableData.total" hide-on-single-page /> -->
</div>
</div>
</template>
<script>
import requestApi from '@/api/operation';
const { getAllChannel, getSystemTemplate } = requestApi;
export default {
data() {
return {
loading: false,
channelList: [],
search: {
searchText: '',
channelId: 1
},
tableData: {
data: [],
currentPage: 1,
pageSizeList: [ 20, 40, 60, 80 ],
pageSize: 20,
tableHeader: [],
total: 0
}
};
},
created() {
this.getTableHeader();
this.getChannelList();
this.getTableData();
},
methods: {
// table methods
getTableHeader() {
this.tableData.tableHeader = [
{ label: '短信模板ID', prop: 'smsTemplateId' },
{ label: '模板名称', prop: 'title' },
{ label: '模板内容', prop: 'content' },
{ label: '应用场景', prop: 'remark', formatter: (row) => {
if(row.systemInfo == 2) {
switch(row.systemType) {
case 3: return '好办会话提醒';
case 6: return '商户余额不足短信通知';
case 4: return '运维后台验证码';
case 2: return '好办注册验证码';
case 7: return '微商城支付异常通知 ';
case 5: return '业务变动通知';
case 101: return '服务到期提醒';
case 1: return '商户欠费短信通知';
case 100: return '达摩中台密码重置 ';
}
} else if(row.systemInfo == 1) {
switch(row.systemType) {
case 0: return 'GIC会员小程序';
case 1: return '观云台小程序';
}
}
return '';
} },
{ label: '通道模板ID', prop: 'templateId' },
];
},
async getTableData() {
this.loading = true;
// const { currentPage, pageSize } = this.tableData;
const { searchText, channelId } = this.search;
const para = {
// pageNum: currentPage,
// pageSize,
smsSendType: channelId,
searchParams: searchText
};
const result = await getSystemTemplate(para);
this.loading = false;
this.tableData.data = result.result.result || [];
this.tableData.total = result.result.totalCount || 0;
},
handleSizeChange(val) {
this.tableData.pageSize = val;
this.tableData.currentPage = 1;
this.getTableData();
},
handleCurrentChange(val) {
this.tableData.currentPage = val;
this.getTableData();
},
// others
async getChannelList() {
const { result } = await getAllChannel();
this.channelList = result || [];
},
searchTypeChange() {
this.tableData.currentPage = 1;
this.getTableData();
},
}
};
</script>
<style scoped lang="scss"></style>
......@@ -110,7 +110,7 @@ export default {
this.getTableData();
},
toDetail(row) {
this.$router.push(`/messageTemplateDetail?id=${row.enterpriseId}`);
this.$router.push(`/messageTemplateDetail?id=${row.enterpriseId}&tabId=${this.$route.query.tabId}`);
},
// others
async getChannelList() {
......
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