全部接口加密

master
yujialong 9 months ago
parent 8ba50079cc
commit e0cbcb37d0
  1. 5
      package-lock.json
  2. 1
      package.json
  3. 11
      src/api/index.js
  4. 7
      src/libs/util.js
  5. 354
      src/pages/account/login/index.vue
  6. 420
      src/pages/annex/list/index.vue
  7. 69
      src/pages/article/add/index.vue
  8. 38
      src/pages/article/list/index.vue
  9. 6
      src/pages/column/add/index.vue
  10. 36
      src/pages/column/list/index.vue
  11. 492
      src/pages/role/list/index.vue
  12. 204
      src/pages/setting/list/index.vue
  13. 797
      src/pages/setting/list/info.vue
  14. 1679
      src/pages/user/list/index.vue
  15. 400
      src/pages/userGroup/list/index.vue
  16. 13
      src/setting.js
  17. 2
      src/store/modules/user.js
  18. 3
      vue.config.js

5
package-lock.json generated

@ -7450,6 +7450,11 @@
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
"jsencrypt": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/jsencrypt/-/jsencrypt-3.3.2.tgz",
"integrity": "sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A=="
},
"jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",

@ -16,6 +16,7 @@
"element-ui": "^2.13.0",
"image-conversion": "^2.1.1",
"js-cookie": "^2.2.1",
"jsencrypt": "^3.3.2",
"mavon-editor": "^2.6.17",
"postcss-px2rem": "^0.3.0",
"px2rem-loader": "^0.1.9",

@ -9,10 +9,15 @@ export default {
delFile: `iasf/sysFiles/delete`,
updateFile: `iasf/sysFiles/update`,
dept: `iasf/sys/dept`,
deleteDept: `iasf/sys/deleteDept`,
updateDept: `iasf/sys/updateDept`,
deptTree: `iasf/sys/dept/tree`,
depts: `iasf/sys/dept/tree`,
users: `iasf/sys/users`,
user: `iasf/sys/user`,
updateUser: `iasf/sys/updateUser`,
queryUser: `iasf/sys/queryUser`,
deletedUser: `iasf/sys/deletedUser`,
sendPhoneOrEmailCode: `iasf/sys/sendPhoneOrEmailCode`,
updatePhoneOrEmail: `iasf/sys/updatePhoneOrEmail`,
updateUserAvatars: `${host}iasf/sys/updateUserAvatars`,
@ -25,12 +30,14 @@ export default {
importStaff: `${host}iasf/sys/importStaff`,
roles: `iasf/sys/roles`,
role: `iasf/sys/role`,
addRole: `iasf/sys/addRole`,
updateRole: `iasf/sys/updateRole`,
deleteRole: `iasf/sys/role/deleted`,
perTree: `iasf/sys/permission/tree/all`,
groupAdd: `iasf/sys/userGroup/add`,
groupDel: `iasf/sys/userGroup/delete`,
groupDel: `iasf/sys/userGroup/deleteUserGroup`,
groupList: `iasf/sys/userGroup/list`,
groupUpdate: `iasf/sys/userGroup/update`,
groupUpdate: `iasf/sys/userGroup/updateUserGroup`,
site: `iasf/sys/site/list`,
updateSite: `iasf/sys/site/update`,
listWithTree: `iasf/sysColumn/listWithTree`,

@ -2,6 +2,7 @@ import { _local } from "./util.db";
import { Message } from "element-ui";
import store from "@/store";
import Setting from '@/setting'
import JSEncrypt from "jsencrypt"
// 文件后缀集合
const exts = {
@ -112,6 +113,12 @@ const util = {
Message.closeAll();
return Message.error({ message, showClose: true, offset: (document.documentElement.clientHeight - 40) / 2, duration });
},
// rsa加密
rsa(data) {
const jse = new JSEncrypt(); // 实例化一个 jsEncrypt 对象
jse.setPublicKey(Setting.publicKey); //配置公钥
return jse.encrypt(JSON.stringify(data))
},
};
export default util;

@ -2,7 +2,8 @@
<div class="wrap">
<div class="left-bg">
<div class="logo">
<img src="@/assets/images/logo.png" alt="">
<img src="@/assets/images/logo.png"
alt="">
网站管理后台
</div>
</div>
@ -10,43 +11,46 @@
<p class="title">欢迎登录</p>
<div class="item">
<label class="phone"></label>
<el-input v-model.trim="loginForm.username" placeholder="请输入账号"></el-input>
<el-input v-model.trim="loginForm.username"
placeholder="请输入账号"></el-input>
</div>
<div class="item">
<label class="pw"></label>
<el-input
type="password"
placeholder="请输入密码"
v-model.trim="loginForm.password"
>
<el-input type="password"
placeholder="请输入密码"
v-model.trim="loginForm.password">
</el-input>
</div>
<div class="item">
<label class="code"></label>
<el-input
placeholder="请输入验证码"
v-model.trim="loginForm.captcha"
@keyup.enter.native="submit"
>
<el-input placeholder="请输入验证码"
v-model.trim="loginForm.captcha"
@keyup.enter.native="submit">
</el-input>
<img @click="getVerImg" :src="verificationIMG" class="verification" alt="">
<img @click="getVerImg"
:src="verificationIMG"
class="verification"
alt="">
</div>
<!-- <div class="forget">忘记密码</div> -->
<el-button class="submit" type="primary" @click="submit">登录</el-button>
<el-button class="submit"
type="primary"
@click="submit">登录</el-button>
</div>
<div class="home">
<img src="@/assets/images/home.png" alt="">
<img src="@/assets/images/home.png"
alt="">
回到官网
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import util from '@/libs/util'
import Util from '@/libs/util'
import Setting from '@/setting'
import addRoutes from '@/libs/route/addRoutes'
export default {
data: function() {
data: function () {
return {
loginForm: {
username: "",
@ -66,10 +70,10 @@ export default {
phoneBtnText: "发送验证码"
};
},
mounted() {
mounted () {
this.getVerImg()
//
this.$once("hook:beforeDestroy", function() {
this.$once("hook:beforeDestroy", function () {
clearInterval(this.phoneTimer)
this.phoneTimer = null
})
@ -79,15 +83,15 @@ export default {
'setUserId', 'setUserName', 'setAvatar'
]),
//
getVerImg() {
getVerImg () {
this.loginForm.random = Math.floor(Math.random() * 999999999);
this.verificationIMG = this.api.verification + "?random=" + `${this.loginForm.random}`;
},
submit() {
this.$post(this.api.logins, this.loginForm).then(({ data }) => {
util.local.set(Setting.tokenKey, data.accessToken, Setting.tokenExpires)
submit () {
this.$post(this.api.logins, Util.rsa(this.loginForm)).then(({ data }) => {
Util.local.set(Setting.tokenKey, data.accessToken, Setting.tokenExpires)
addRoutes(data.permissionList[0].children)
util.successMsg('登录成功')
Util.successMsg('登录成功')
this.setUserId(data.id || 1)
this.setUserName(data.username)
this.setAvatar(data.userAvatars)
@ -97,176 +101,176 @@ export default {
this.loginForm.captcha = ''
})
},
phoneCountdown() {
let count = 60;
if (!this.phoneTimer) {
this.phoneDisabled = true;
this.phoneTimer = setInterval(() => {
console.log("倒计时中");
if (count > 0) {
count--;
this.phoneBtnText = `${count}秒后重试`;
} else {
this.phoneDisabled = false;
clearInterval(this.phoneTimer);
this.phoneTimer = null;
this.phoneBtnText = `发送验证码`;
}
}, 1000);
}
phoneCountdown () {
let count = 60;
if (!this.phoneTimer) {
this.phoneDisabled = true;
this.phoneTimer = setInterval(() => {
console.log("倒计时中");
if (count > 0) {
count--;
this.phoneBtnText = `${count}秒后重试`;
} else {
this.phoneDisabled = false;
clearInterval(this.phoneTimer);
this.phoneTimer = null;
this.phoneBtnText = `发送验证码`;
}
}, 1000);
}
},
sendPhoneCode() {
if (!this.phone) return util.warningMsg("请输入手机号");
if (!/^1[3456789]\d{9}$/.test(this.phone)) return util.warningMsg("请输入正确的手机号");
let data = {
platform: Setting.platformId,
phone: this.phone,
types: 2
};
this.$post(this.api.sendPhoneOrEmailCode, data).then(res => {
if (res.message.opener) {
this.phoneCountdown();
this.phoneOpener = res.message.opener;
} else {
util.errorMsg(res.message);
}
}).catch(res => {});
sendPhoneCode () {
if (!this.phone) return Util.warningMsg("请输入手机号");
if (!/^1[3456789]\d{9}$/.test(this.phone)) return Util.warningMsg("请输入正确的手机号");
let data = {
platform: Setting.platformId,
phone: this.phone,
types: 2
};
this.$post(this.api.sendPhoneOrEmailCode, data).then(res => {
if (res.message.opener) {
this.phoneCountdown();
this.phoneOpener = res.message.opener;
} else {
Util.errorMsg(res.message);
}
}).catch(res => { });
},
phoneSubmit() {
if (!this.phone) return util.warningMsg("请输入手机号");
if (!/^1[3456789]\d{9}$/.test(this.phone)) return util.warningMsg("请输入正确的手机号");
if (!this.phoneCode) return util.warningMsg("请输入验证码");
let data = {
phone: this.phone,
types: 2,
captcha: this.phoneCode,
opener: this.phoneOpener,
platform: Setting.platformId,
username: this.loginForm.username
};
this.$post(this.api.bindPhoneOrEmail, data).then(res => {
util.successMsg("绑定成功");
this.loginForm.phone = this.phone;
this.phoneVisible = false;
phoneSubmit () {
if (!this.phone) return Util.warningMsg("请输入手机号");
if (!/^1[3456789]\d{9}$/.test(this.phone)) return Util.warningMsg("请输入正确的手机号");
if (!this.phoneCode) return Util.warningMsg("请输入验证码");
let data = {
phone: this.phone,
types: 2,
captcha: this.phoneCode,
opener: this.phoneOpener,
platform: Setting.platformId,
username: this.loginForm.username
};
this.$post(this.api.bindPhoneOrEmail, data).then(res => {
Util.successMsg("绑定成功");
this.loginForm.phone = this.phone;
this.phoneVisible = false;
util.local.set(Setting.tokenKey, res.token, Setting.tokenExpires);
let redirect = this.$route.query.redirect ? decodeURIComponent(this.$route.query.redirect) : "/index";
this.$router.replace(redirect);
util.successMsg("登录成功");
this.queryCustomer();
}).catch(res => {
});
Util.local.set(Setting.tokenKey, res.token, Setting.tokenExpires);
let redirect = this.$route.query.redirect ? decodeURIComponent(this.$route.query.redirect) : "/index";
this.$router.replace(redirect);
Util.successMsg("登录成功");
this.queryCustomer();
}).catch(res => {
});
}
}
};
</script>
<style lang="scss" scoped>
.wrap {
position: relative;
width: 100%;
height: 100%;
background: url(../../../assets/images/login-bg2.png) top right/auto no-repeat;
position: relative;
width: 100%;
height: 100%;
background: url(../../../assets/images/login-bg2.png) top right/auto no-repeat;
}
.left-bg {
width: 420px;
height: 100%;
background: url(../../../assets/images/login-bg1.png) 0 0/cover no-repeat;
.logo {
display: flex;
align-items: center;
padding: 20px 25px;
font-size: 20px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #FFFFFF;
}
img {
margin-right: 10px;
}
width: 420px;
height: 100%;
background: url(../../../assets/images/login-bg1.png) 0 0 / cover no-repeat;
.logo {
display: flex;
align-items: center;
padding: 20px 25px;
font-size: 20px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #ffffff;
}
img {
margin-right: 10px;
}
}
/deep/.form {
position: absolute;
top: 50%;
right: 25%;
width: 420px;
padding: 75px 30px 85px;
transform: translateY(-50%);
background-color: #fff;
box-shadow: 0px 4px 20px 0px rgba(203,209,218,0.15);
border-radius: 8px;
.title {
margin-bottom: 36px;
font-size: 24px;
font-family: AppleSystemUIFont;
text-align: center;
color: #333;
line-height: 28px;
}
.item {
position: relative;
margin-bottom: 23px;
border-radius: 4px;
border: 1px solid #D9DDEB;
label {
z-index: 2;
position: absolute;
left: 0;
width: 46px;
height: 100%;
border-radius: 4px 0px 0px 4px;
border-right: 1px solid #D9DDEB;
background: #F7F9FC url(../../../assets/images/phone.png) center center/auto no-repeat;
position: absolute;
top: 50%;
right: 25%;
width: 420px;
padding: 75px 30px 85px;
transform: translateY(-50%);
background-color: #fff;
box-shadow: 0px 4px 20px 0px rgba(203, 209, 218, 0.15);
border-radius: 8px;
.title {
margin-bottom: 36px;
font-size: 24px;
font-family: AppleSystemUIFont;
text-align: center;
color: #333;
line-height: 28px;
}
.pw {
background-image: url(../../../assets/images/pw.png);
.item {
position: relative;
margin-bottom: 23px;
border-radius: 4px;
border: 1px solid #d9ddeb;
label {
z-index: 2;
position: absolute;
left: 0;
width: 46px;
height: 100%;
border-radius: 4px 0px 0px 4px;
border-right: 1px solid #d9ddeb;
background: #f7f9fc url(../../../assets/images/phone.png) center center/auto no-repeat;
}
.pw {
background-image: url(../../../assets/images/pw.png);
}
.code {
background-image: url(../../../assets/images/code.png);
}
}
.code {
background-image: url(../../../assets/images/code.png);
.el-input .el-input__inner {
height: 46px;
padding-left: 58px;
border: 0;
}
}
.el-input .el-input__inner {
height: 46px;
padding-left: 58px;
border: 0;
}
.verification {
.verification {
position: absolute;
top: 0;
right: 1px;
width: 160px;
height: 46px;
cursor: pointer;
}
.forget {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
color: #333;
text-align: right;
cursor: pointer;
}
.submit {
width: 100%;
height: 46px;
margin-top: 23px;
font-size: 18px;
font-family: PingFangSC-Regular, PingFang SC;
border: 0;
border-radius: 4px;
}
}
.home {
position: absolute;
top: 0;
right: 1px;
width: 160px;
height: 46px;
cursor: pointer;
}
.forget {
top: 33px;
right: 43px;
display: flex;
align-items: center;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
color: #333;
text-align: right;
font-weight: 400;
color: #666666;
cursor: pointer;
}
.submit {
width: 100%;
height: 46px;
margin-top: 23px;
font-size: 18px;
font-family: PingFangSC-Regular, PingFang SC;
border: 0;
border-radius: 4px;
}
}
.home {
position: absolute;
top: 33px;
right: 43px;
display: flex;
align-items: center;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
cursor: pointer;
img {
margin-right: 5px;
}
img {
margin-right: 5px;
}
}
</style>

@ -1,237 +1,283 @@
<template>
<div class="page">
<div class="tool">
<ul class="filter">
<li>
<label>站点选择</label>
<el-select v-model="form.site" @change="initData">
<el-option label="不限" value=""></el-option>
<el-option
v-for="item in sites"
:key="item.id"
:label="item.siteName"
:value="item.siteName">
</el-option>
</el-select>
</li>
<li>
<label>文件类型</label>
<el-select v-model="form.type" @change="initData">
<el-option
v-for="item in types"
:key="item.name"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
</li>
</ul>
<ul class="filter">
<li>
<label>站点选择</label>
<el-select v-model="form.site"
@change="initData">
<el-option label="不限"
value=""></el-option>
<el-option v-for="item in sites"
:key="item.id"
:label="item.siteName"
:value="item.siteName">
</el-option>
</el-select>
</li>
<li>
<label>文件类型</label>
<el-select v-model="form.type"
@change="initData">
<el-option v-for="item in types"
:key="item.name"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
</li>
</ul>
</div>
<div class="tool">
<div class="search-wrap">
<el-select v-model="field" @change="initData">
<el-option
v-for="(item, i) in keywords"
:key="i"
:label="item.name"
:value="item.id">
<el-select v-model="field"
@change="initData">
<el-option v-for="(item, i) in keywords"
:key="i"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-input class="keyword" :placeholder="'请输入' + keywords.find(e => e.id === field).name" v-model.trim="keyword" clearable></el-input>
<el-input class="keyword"
:placeholder="'请输入' + keywords.find(e => e.id === field).name"
v-model.trim="keyword"
clearable></el-input>
</div>
<div class="actions">
<el-button v-auth @click="batchDel">删除</el-button>
<el-button v-auth
@click="batchDel">删除</el-button>
</div>
</div>
<el-table ref="table" :data="list" class="table" header-align="center" @selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="50" align="center" :reserve-selection="true" :selectable="row => !row.quote"></el-table-column>
<el-table-column type="index" width="60" label="ID"></el-table-column>
<el-table-column prop="site" label="站点" min-width="180"></el-table-column>
<el-table-column prop="quote" label="文章名称" min-width="180" show-overflow-tooltip>
<el-table ref="table"
:data="list"
class="table"
header-align="center"
@selection-change="handleSelectionChange"
row-key="id">
<el-table-column type="selection"
width="50"
align="center"
:reserve-selection="true"
:selectable="row => !row.quote"></el-table-column>
<el-table-column type="index"
width="60"
label="ID"></el-table-column>
<el-table-column prop="site"
label="站点"
min-width="180"></el-table-column>
<el-table-column prop="quote"
label="文章名称"
min-width="180"
show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.quote || '--' }}
</template>
</el-table-column>
<el-table-column prop="fileName" label="名称" min-width="180" show-overflow-tooltip></el-table-column>
<el-table-column prop="type" label="文件类型" min-width="80"></el-table-column>
<el-table-column prop="format" label="格式" min-width="80"></el-table-column>
<el-table-column prop="fileSize" label="大小" min-width="80">
<el-table-column prop="fileName"
label="名称"
min-width="180"
show-overflow-tooltip></el-table-column>
<el-table-column prop="type"
label="文件类型"
min-width="80"></el-table-column>
<el-table-column prop="format"
label="格式"
min-width="80"></el-table-column>
<el-table-column prop="fileSize"
label="大小"
min-width="80">
<template slot-scope="scope">
{{ (scope.row.fileSize / 1000).toFixed(2) }}kb
</template>
</el-table-column>
<el-table-column prop="createDate" label="上传时间" min-width="150"></el-table-column>
<el-table-column prop="uploader" label="上传人" min-width="100"></el-table-column>
<el-table-column prop="deleted" label="是否使用" min-width="100">
<el-table-column prop="createDate"
label="上传时间"
min-width="150"></el-table-column>
<el-table-column prop="uploader"
label="上传人"
min-width="100"></el-table-column>
<el-table-column prop="deleted"
label="是否使用"
min-width="100">
<template slot-scope="scope">
{{ scope.row.quote ? '是' : '否' }}
</template>
</el-table-column>
<el-table-column label="操作" width="150">
<el-table-column label="操作"
width="150">
<template slot-scope="scope">
<el-button type="text" @click="show(scope.row, 'edit')">查看</el-button>
<el-button v-auth type="text" :disabled="scope.row.quote !== ''" @click="del(scope.row)">删除</el-button>
<el-button v-auth type="text" @click="download(scope.row)">下载</el-button>
<el-button type="text"
@click="show(scope.row, 'edit')">查看</el-button>
<el-button v-auth
type="text"
:disabled="scope.row.quote !== ''"
@click="del(scope.row)">删除</el-button>
<el-button v-auth
type="text"
@click="download(scope.row)">下载</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page"></el-pagination>
<el-pagination background
layout="total, prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
:current-page="page"></el-pagination>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import util from '@/libs/util'
import Util from '@/libs/util'
export default {
data() {
return {
sites: [],
types: [
{
name: '不限'
},
{
name: '图片'
},
{
name: '视频'
},
{
name: '文档'
}
],
field: 'fileName',
keywords: [
{
id: 'fileName',
name: '文件名称'
},
{
id: 'uploader',
name: '上传人'
},
{
id: 'quote',
name: '文章名称'
}
],
keyword: '',
form: {
site: '',
type: '不限'
},
page: +this.$route.query.page || 1,
pageSize: 10,
total: 0,
list: [],
multipleSelection: [],
};
},
computed: {
...mapState('auth', [
'btns'
])
},
watch: {
keyword: function(val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
}
},
mounted() {
this.$store.commit('user/setCrumbs', [
data () {
return {
sites: [],
types: [
{
name: '不限'
},
{
name: '图片'
},
{
name: '附件管理'
name: '视频'
},
{
name: '文档'
}
],
field: 'fileName',
keywords: [
{
id: 'fileName',
name: '文件名称'
},
{
id: 'uploader',
name: '上传人'
},
{
id: 'quote',
name: '文章名称'
}
])
],
keyword: '',
form: {
site: '',
type: '不限'
},
page: +this.$route.query.page || 1,
pageSize: 10,
total: 0,
list: [],
multipleSelection: [],
};
},
computed: {
...mapState('auth', [
'btns'
])
},
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
}
},
mounted () {
this.$store.commit('user/setCrumbs', [
{
name: '附件管理'
}
])
this.getData()
this.getSite()
},
methods: {
getData () {
const { form } = this
this.$post(this.api.listByPage, {
page: this.page,
limit: this.pageSize,
quote: this.field === 'quote' ? this.keyword : '',
fileName: this.field === 'fileName' ? this.keyword : '',
uploader: this.field === 'uploader' ? this.keyword : '',
site: form.site,
type: form.type === '不限' ? '' : form.type
}).then(({ data }) => {
this.list = data.records
this.total = +data.total
}).catch(err => { })
},
//
getSite () {
this.$post(this.api.site, {
page: 1,
limit: 1000,
siteName: ''
}).then(({ data }) => {
this.sites = Util.getSite(data.records)
}).catch(e => { })
},
initData () {
this.$refs.table.clearSelection()
this.page = 1
this.getData()
this.getSite()
},
methods: {
getData() {
const { form } = this
this.$post(this.api.listByPage, {
page: this.page,
limit: this.pageSize,
quote: this.field === 'quote' ? this.keyword : '',
fileName: this.field === 'fileName' ? this.keyword : '',
uploader: this.field === 'uploader' ? this.keyword : '',
site: form.site,
type: form.type === '不限' ? '' : form.type
}).then(({ data }) => {
this.list = data.records
this.total = +data.total
}).catch(err => {})
},
//
getSite() {
this.$post(this.api.site, {
page: 1,
limit: 1000,
siteName: ''
}).then(({ data }) => {
this.sites = util.getSite(data.records)
}).catch(e => {})
},
initData() {
this.$refs.table.clearSelection()
this.page = 1
this.getData()
},
//
show(row) {
const format = row.format
window.open((util.isDoc(format) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + row.url)
},
//
download(row) {
util.downloadFile(row.fileName, row.url)
},
//
del(row) {
//
show (row) {
const format = row.format
window.open((Util.isDoc(format) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + row.url)
},
//
download (row) {
Util.downloadFile(row.fileName, row.url)
},
//
del (row) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(this.api.delFile, Util.rsa([row.id])).then(res => {
Util.successMsg('删除成功')
this.getData()
}).catch(res => { })
}).catch(() => { })
},
//
batchDel () {
const list = this.multipleSelection
if (list.length) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$del(`${this.api.delFile}`, [row.id]).then(res => {
util.successMsg('删除成功')
this.$del(this.api.delFile, Util.rsa(list.map(e => e.id))).then(res => {
this.$refs.table.clearSelection()
Util.successMsg('删除成功')
this.getData()
}).catch(res => {})
}).catch(() => {})
},
//
batchDel() {
const list = this.multipleSelection
if (list.length) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$del(`${this.api.delFile}`, list.map(e => e.id)).then(res => {
this.$refs.table.clearSelection()
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
}).catch(() => {})
} else {
util.errorMsg('请先选择数据 !')
}
},
handleSelectionChange(val) {
this.multipleSelection = val
},
handleCurrentChange(val) {
this.page = val
this.$router.push(`list?page=${val}`)
this.getData()
},
}
}).catch(res => { })
}).catch(() => { })
} else {
Util.errorMsg('请先选择数据 !')
}
},
handleSelectionChange (val) {
this.multipleSelection = val
},
handleCurrentChange (val) {
this.page = val
this.$router.push(`list?page=${val}`)
this.getData()
},
}
};
</script>
<style lang="scss" scoped>
</style>

@ -893,7 +893,8 @@ export default {
labels: [],
labelVisible: false,
originalName: '',
originColumnId: ''
originColumnId: '',
repeatMsg: '',
};
},
computed: {
@ -1011,13 +1012,13 @@ export default {
},
//
getList () {
this.$post(this.api.listWithTree, {
this.$post(this.api.listWithTree, Util.rsa({
siteId: this.site.id,
columnName: '',
templateId: '',
typeId: '',
isSort: 1
}).then(({ data }) => {
})).then(({ data }) => {
this.columns = data
let { columnId } = this.$route.query
// idid
@ -1049,20 +1050,20 @@ export default {
const inner = this.form.connectionType === 1
const id = inner ? this.links[this.links.length - 1] : this.otherLink[this.otherLink.length - 1]
this[inner ? 'article' : 'otherArticle'] = ''
this.$post(this.api.queryArticle, {
this.$post(this.api.queryArticle, Util.rsa({
siteId: inner ? this.site.id : this.form.siteSelection,
columnIds: [id],
pageNum: 1,
pageSize: 1000,
title: '',
isDisable: 0
}).then(({ data }) => {
})).then(({ data }) => {
this[inner ? 'articles' : 'otherArticles'] = data.records.filter(e => e.isRelease) //
}).catch(err => { })
},
//
getData () {
this.$post(`${this.api.findArticle}?id=${this.form.id}`).then(({ data }) => {
this.$post(this.api.findArticle, Util.rsa(this.form.id)).then(({ data }) => {
data.lableId = data.lableId ? data.lableId.split(',').map(e => +e) : []
// if (data.activityStartTime && data.activityEndTime) data.time = [data.activityStartTime, data.activityEndTime]
//
@ -1079,14 +1080,14 @@ export default {
const article = columnArticle[1] || '' // ididlinkAddress-
const { connectionType } = data
//
this.$post(this.api.queryArticle, {
this.$post(this.api.queryArticle, Util.rsa({
siteId: connectionType === 1 ? this.site.id : data.siteSelection,
columnIds: [column[column.length - 1]], // ididid
pageNum: 1,
pageSize: 1000,
title: '',
isDisable: 0
}).then(res => {
})).then(res => {
this[connectionType === 1 ? 'articles' : 'otherArticles'] = res.data.records
// /
if (connectionType === 1) {
@ -1118,7 +1119,7 @@ export default {
},
//
getColumn () {
this.$post(`${this.api.findColumn}?id=${this.$route.query.columnId}`).then(({ data }) => {
this.$post(this.api.findColumn, Util.rsa(this.$route.query.columnId)).then(({ data }) => {
this.columnInfo = data
const { form } = this
// /23
@ -1181,13 +1182,13 @@ export default {
},
//
getOtherColumn (val) {
this.$post(this.api.listWithTree, {
this.$post(this.api.listWithTree, Util.rsa({
siteId: this.form.siteSelection,
columnName: '',
templateId: '',
typeId: '',
isSort: 1
}).then(({ data }) => {
})).then(({ data }) => {
if (val) {
this.otherArticles = []
this.otherArticle = ''
@ -1208,7 +1209,10 @@ export default {
},
//
getClassification () {
this.$post(`${this.api.queryClassif}?siteId=${this.site.id}&templateId=${this.columnInfo.templateId}`).then(({ data }) => {
this.$post(this.api.queryClassif, Util.rsa({
siteId: this.site.id,
templateId: this.columnInfo.templateId
})).then(({ data }) => {
this.classifications = data
}).catch(err => { })
},
@ -1234,7 +1238,7 @@ export default {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.delClassif}?id=${row.id}`).then(res => {
this.$post(this.api.delClassif, Util.rsa(row.id)).then(res => {
Util.successMsg('删除成功')
this.getClassification()
}).catch(res => { })
@ -1246,15 +1250,19 @@ export default {
//
submitClass (row, showMsg = 1) {
if (!row.classificationName) return Util.errorMsg('请输入分类名称')
this.$post(`${this.api.checkClassif}?classificationName=${row.classificationName}&siteId=${this.site.id}&classificationId=${row.id}`).then(res => {
this.$post(this.api[row.id ? 'updateClassif' : 'saveClassif'], {
this.$post(this.api.checkClassif, Util.rsa({
classificationName: row.classificationName,
siteId: this.site.id,
classificationId: row.id
})).then(res => {
this.$post(this.api[row.id ? 'updateClassif' : 'saveClassif'], Util.rsa({
classificationName: row.classificationName,
templateId: this.columnInfo.templateId,
id: row.id,
siteId: this.site.id,
editorId: this.userId,
founderId: this.userId
}).then(res => {
})).then(res => {
showMsg && Util.successMsg((row.id ? '修改' : '新增') + '成功')
this.getClassification()
}).catch(res => { })
@ -1282,7 +1290,7 @@ export default {
//
getLabel () {
this.$post(`${this.api.queryLabel}?siteId=${this.site.id}`).then(({ data }) => {
this.$post(this.api.queryLabel, Util.rsa(this.site.id)).then(({ data }) => {
this.labels = data
}).catch(err => { })
},
@ -1308,7 +1316,7 @@ export default {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.delLabel}?id=${row.id}`).then(res => {
this.$post(this.api.delLabel, Util.rsa(row.id)).then(res => {
Util.successMsg('删除成功')
this.getLabel()
}).catch(res => { })
@ -1320,14 +1328,18 @@ export default {
//
submitLabel (row, showMsg = 1) {
if (!row.labelName) return Util.errorMsg('请输入主题名称')
this.$post(`${this.api.checkLabel}?labelName=${row.labelName}&siteId=${this.site.id}&labelId=${row.id}`).then(res => {
this.$post(this.api[row.id ? 'updateLabel' : 'saveLabel'], {
this.$post(this.api.checkLabel, Util.rsa({
labelName: row.labelName,
siteId: this.site.id,
labelId: row.id,
})).then(res => {
this.$post(this.api[row.id ? 'updateLabel' : 'saveLabel'], Util.rsa({
labelName: row.labelName,
id: row.id,
siteId: this.site.id,
editorId: this.userId,
founderId: this.userId
}).then(res => {
})).then(res => {
showMsg && Util.successMsg((row.id ? '修改' : '新增') + '成功')
this.getLabel()
}).catch(res => { })
@ -1356,16 +1368,19 @@ export default {
nameChange () {
const { title, level, id } = this.form
if (title && title !== this.originalName) {
this.$post(this.api.checkIfTheTitleIsRepeat, {
this.$post(this.api.checkIfTheTitleIsRepeat, Util.rsa({
siteId: this.site.id,
title,
id: id || ''
}).then(res => {
})).then(res => {
this.repeatMsg = ''
this.nameRepeat = false
}).catch(res => {
if (res.msg) this.repeatMsg = res.msg
this.nameRepeat = true
})
} else {
this.repeatMsg = ''
this.nameRepeat = false
}
},
@ -1454,7 +1469,7 @@ export default {
},
//
handleRemove (e, fileList) {
e.id ? this.$post(`${this.api.delContentFile}?id=${e.id}`).then(res => {
e.id ? this.$post(this.api.delContentFile, Util.rsa(e.id)).then(res => {
this.form.fileList = fileList
}).catch(res => { }) : (this.form.fileList = fileList)
},
@ -1497,14 +1512,14 @@ export default {
uploadSuccessFile (res) {
this.uploading--
this.form.id ?
this.$post(this.api.saveContentFile, {
this.$post(this.api.saveContentFile, Util.rsa({
contentId: this.form.id,
editorId: this.userId,
founderId: this.userId,
id: '',
fileName: res.original,
filePath: res.url
}).then(({ data }) => {
})).then(({ data }) => {
this.form.fileList.push({
name: res.original,
url: res.url,
@ -1554,7 +1569,7 @@ export default {
if (this.submiting) return false
const form = JSON.parse(JSON.stringify(this.form))
if (!form.title) return Util.errorMsg('请填写标题')
if (this.nameRepeat) return Util.errorMsg('该标题已重复!')
if (this.nameRepeat) return Util.errorMsg(this.repeatMsg)
if (typeof form.fatherId === 'object') form.fatherId = form.fatherId[form.fatherId.length - 1]
const tId = form.articleTemplate
//

@ -193,7 +193,7 @@
<script>
import Setting from '@/setting'
import util from '@/libs/util'
import Util from '@/libs/util'
import { mapMutations } from 'vuex'
import ColumnConst from '@/const/column'
export default {
@ -319,13 +319,13 @@ export default {
]),
//
getColumn () {
this.$post(this.api.listWithTree, {
this.$post(this.api.listWithTree, Util.rsa({
siteId: this.$store.state.content.site.id,
columnName: '',
templateId: '',
typeId: '',
isSort: 1
}).then(({ data }) => {
})).then(({ data }) => {
this.columns = data
this.$nextTick(() => {
this.$refs.column.setCurrentKey(this.$route.query.columnId || data[0].id)
@ -351,7 +351,7 @@ export default {
}
if (this.modifiedTimeSort !== '') data.modifiedTimeSort = this.modifiedTimeSort
if (this.publicationTimeSort !== '') data.publicationTimeSort = this.publicationTimeSort
this.$post(this.api.queryArticle, data).then(({ data }) => {
this.$post(this.api.queryArticle, Util.rsa(data)).then(({ data }) => {
data.records.map(e => {
e.editing = false
e.releaseTime = e.releaseTime.split(' ')[0]
@ -388,8 +388,8 @@ export default {
//
submitSequence (row) {
const { sequence } = row
if (!sequence) return util.errorMsg('请输入排序')
if (isNaN(sequence)) return util.errorMsg('请输入数字')
if (!sequence) return Util.errorMsg('请输入排序')
if (isNaN(sequence)) return Util.errorMsg('请输入数字')
this.$post(`${this.api.modifiedSort}?articleId=${row.id}&sequenceNumber=${sequence > this.total ? this.total : sequence}`).then(res => {
this.initData()
}).catch(res => { })
@ -408,18 +408,14 @@ export default {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
const data = []
list.map(e => {
data.push('ids=' + e.id)
})
this.$post(`${this.api.deleteArticle}?${data.join('&')}`).then(res => {
this.$post(this.api.deleteArticle, Util.rsa(list.map(e => e.id))).then(res => {
this.$refs.table.clearSelection()
util.successMsg("删除成功")
Util.successMsg("删除成功")
this.getData()
}).catch(res => { })
}).catch(() => { })
} else {
util.errorMsg('请先选择数据 !')
Util.errorMsg('请先选择数据 !')
}
},
//
@ -427,19 +423,22 @@ export default {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.deleteArticle}?ids=${row.id}`).then(res => {
util.successMsg('删除成功')
this.$post(this.api.deleteArticle, Util.rsa([row.id])).then(res => {
Util.successMsg('删除成功')
this.getData()
}).catch(res => { })
}).catch(() => { })
},
//
switchOff (val, row) {
this.$post(`${this.api.articleEnableOrDisable}?id=${row.id}&isDisable=${val}`).then(res => { }).catch((res) => { })
this.$post(this.api.articleEnableOrDisable, Util.rsa({
id: row.id,
isDisable: val
})).then(res => { }).catch((res) => { })
},
//
add () {
if (!this.columns.length) return util.errorMsg('请添加栏目')
if (!this.columns.length) return Util.errorMsg('请添加栏目')
this.setColumn(this.$refs.column.getCurrentNode())
this.$router.push(`add?columnId=${this.$refs.column.getCurrentKey()}&columnName=${this.$refs.column.getCurrentNode().columnName}`)
},
@ -474,7 +473,10 @@ export default {
},
//
sticky (row) {
this.$post(`${this.api.articleTopOperation}?articleId=${row.id}&isTop=${row.isTop ? 0 : 1}`).then(res => {
this.$post(this.api.articleTopOperation, Util.rsa({
articleId: row.id,
isTop: row.isTop ? 0 : 1
})).then(res => {
this.initData()
}).catch(res => { })
},

@ -439,20 +439,20 @@ export default {
const inner = this.form.connectionType === 1
const id = inner ? this.links[this.links.length - 1] : this.otherLink[this.otherLink.length - 1]
this[inner ? 'article' : 'otherArticle'] = ''
this.$post(this.api.queryArticle, {
this.$post(this.api.queryArticle, Util.rsa({
siteId: inner ? this.site.id : this.form.siteSelection,
columnIds: [id],
pageNum: 1,
pageSize: 1000,
title: '',
isDisable: 0
}).then(({ data }) => {
})).then(({ data }) => {
this[inner ? 'articles' : 'otherArticles'] = data.records.filter(e => e.isRelease) //
}).catch(err => { })
},
//
getData () {
this.$post(`${this.api.findColumn}?id=${this.form.id}`).then(({ data }) => {
this.$post(this.api.findColumn, Util.rsa(this.form.id)).then(({ data }) => {
this.form = data
if (data.typeId === 1 || data.typeId === 4) this.getStyle(0)
this.originTypeId = data.typeId

@ -216,7 +216,7 @@
<script>
import Setting from '@/setting'
import ColumnConst from '@/const/column'
import util from '@/libs/util'
import Util from '@/libs/util'
export default {
data () {
return {
@ -311,13 +311,13 @@ export default {
},
methods: {
getData () {
this.$post(this.api.listWithTree, {
this.$post(this.api.listWithTree, Util.rsa({
siteId: this.siteId,
columnName: this.keyword,
templateId: '',
typeId: '',
isSort: 1
}).then(({ data }) => {
})).then(({ data }) => {
this.list = data
this.listLoading = false
}).catch(err => {
@ -326,7 +326,7 @@ export default {
},
// id
getStyle () {
this.$post(`${this.api.theTemplateIdGetsTheStyle}?templateId=${this.form.templateId}`).then(({ data }) => {
this.$post(this.api.theTemplateIdGetsTheStyle, Util.rsa(this.form.templateId)).then(({ data }) => {
this.listStyle = data.listingTemplateTypes
this.detailStyle = data.detailsTypeOfTheTemplate
}).catch(err => { })
@ -351,8 +351,8 @@ export default {
this.$confirm("删除栏目将会同时把栏目下的文章一并删除,是否确认删除栏目?", "提示", {
type: "warning"
}).then(() => {
this.$post(`${this.api.deleteColumn}?ids=${row.id}`).then(res => {
util.successMsg("删除成功")
this.$post(this.api.deleteColumn, Util.rsa([row.id])).then(res => {
Util.successMsg("删除成功")
this.getData()
}).catch(res => { })
}).catch(() => { })
@ -377,18 +377,14 @@ export default {
this.$confirm('删除栏目将会同时把栏目下的文章一并删除,是否确认删除栏目?', '提示', {
type: 'warning'
}).then(() => {
const data = []
list.map(e => {
data.push('ids=' + e.id)
})
this.$post(`${this.api.deleteColumn}?${data.join('&')}`).then(res => {
this.$post(this.api.deleteColumn, Util.rsa(list.map(e => e.id))).then(res => {
this.$refs.table.clearSelection()
util.successMsg("删除成功")
Util.successMsg("删除成功")
this.getData()
}).catch(res => { })
}).catch(() => { })
} else {
util.errorMsg('请先选择数据 !')
Util.errorMsg('请先选择数据 !')
}
},
handleSelectionChange (val) {
@ -414,13 +410,13 @@ export default {
sort () {
this.$post(this.api.deleteUselessData).then(res => { }).catch(err => { })
this.$post(this.api.listWithTree, {
this.$post(this.api.listWithTree, Util.rsa({
siteId: this.siteId,
columnName: '',
templateId: '',
typeId: '',
isSort: 1
}).then(({ data }) => {
})).then(({ data }) => {
this.sortColumns = data
}).catch(err => { })
this.sortVisible = true
@ -445,8 +441,8 @@ export default {
sortSubmit () {
const result = []
this.sortList(this.sortColumns, result)
this.$post(this.api.sortByColumn, result).then(({ data }) => {
util.successMsg('修改成功')
this.$post(this.api.sortByColumn, Util.rsa(result)).then(({ data }) => {
Util.successMsg('修改成功')
this.sortVisible = false
this.getData()
}).catch(err => { })
@ -454,13 +450,13 @@ export default {
//
styleSet () {
this.styleVisible = true
this.$post(`${this.api.searchAllBySite}?siteId=${this.siteId}`).then(({ data }) => {
this.$post(this.api.searchAllBySite, Util.rsa(this.siteId)).then(({ data }) => {
// id
if (data.length) {
this.form = data[0]
} else {
this.$post(this.api.saveStyle, this.form).then(res => {
this.$post(`${this.api.searchAllBySite}?siteId=${this.siteId}`).then(({ data }) => {
this.$post(this.api.searchAllBySite, Util.rsa(this.siteId)).then(({ data }) => {
this.form = data[0]
}).catch(res => { })
}).catch(res => { })
@ -470,7 +466,7 @@ export default {
//
styleSubmit () {
this.$post(this.api.updateStyle, this.form).then(res => {
util.successMsg('修改成功')
Util.successMsg('修改成功')
this.styleVisible = false
}).catch(res => { })
}

@ -2,254 +2,306 @@
<div class="page">
<div class="tool">
<div class="search-wrap">
<el-input placeholder="请输入角色名称" v-model.trim="keyword" clearable></el-input>
<el-input placeholder="请输入角色名称"
v-model.trim="keyword"
clearable></el-input>
</div>
<div class="actions">
<el-button v-auth type="primary" @click="addRole">新增</el-button>
<el-button v-auth="'批量删除'" @click="batchDel">删除</el-button>
<el-button v-auth
type="primary"
@click="addRole">新增</el-button>
<el-button v-auth="'批量删除'"
@click="batchDel">删除</el-button>
</div>
</div>
<el-table :data="list" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true" :selectable="row => row.name !== '超级管理员'"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="角色名称" align="center" min-width="250" show-overflow-tooltip></el-table-column>
<el-table-column prop="description" label="角色描述" min-width="400" align="center"></el-table-column>
<el-table-column label="操作" align="center" width="200">
<el-table :data="list"
class="table"
ref="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
row-key="id">
<el-table-column type="selection"
width="55"
align="center"
:reserve-selection="true"
:selectable="row => row.name !== '超级管理员'"></el-table-column>
<el-table-column type="index"
width="60"
label="序号"
align="center"></el-table-column>
<el-table-column prop="name"
label="角色名称"
align="center"
min-width="250"
show-overflow-tooltip></el-table-column>
<el-table-column prop="description"
label="角色描述"
min-width="400"
align="center"></el-table-column>
<el-table-column label="操作"
align="center"
width="200">
<template slot-scope="scope">
<el-button v-auth type="text" @click="showRole(scope.row)">查看</el-button>
<el-button v-auth v-if="scope.row.name !== '超级管理员'" type="text" @click="editRole(scope.row)">编辑</el-button>
<el-button v-auth v-if="scope.row.name !== '超级管理员'" type="text" @click="handleDelete(scope.row)">删除</el-button>
<el-button v-auth
type="text"
@click="showRole(scope.row)">查看</el-button>
<el-button v-auth
type="text"
@click="editRole(scope.row)">编辑</el-button>
<el-button v-auth
v-if="scope.row.name !== '超级管理员'"
type="text"
@click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination>
<el-pagination background
@current-change="currentChange"
:current-page="page"
layout="total, prev, pager, next"
:total="total"></el-pagination>
</div>
<el-dialog :title="isDetail ? '查看角色' : (isAdd ? '新增角色' : '编辑角色')" :visible.sync="roleVisible" width="30%" @close="closeRole" class="dialog" :close-on-click-modal="false">
<el-form ref="form" label-width="80px" :disabled="isDetail">
<el-form-item label="角色名称">
<el-input v-model="form.name" placeholder="请输入角色名称"></el-input>
</el-form-item>
<el-form-item label="角色描述">
<el-input v-model="form.description" placeholder="请输入角色描述" type="textarea" rows="5"></el-input>
</el-form-item>
<el-form-item prop="role" label="角色权限">
<div style="max-height: 300px; overflow: auto">
<el-tree
ref="per"
:data="permissions"
show-checkbox
default-expand-all
node-key="id"
:default-expanded-keys="checkedIds"
:default-checked-keys="checkedIds"
:props="defaultProps">
</el-tree>
</div>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer" v-if="!isDetail">
<el-button @click="roleVisible = false"> </el-button>
<el-button type="primary" @click="saveData"> </el-button>
</span>
<el-dialog :title="isDetail ? '查看角色' : (isAdd ? '新增角色' : '编辑角色')"
:visible.sync="roleVisible"
width="30%"
@close="closeRole"
class="dialog"
:close-on-click-modal="false">
<el-form ref="form"
label-width="80px"
:disabled="isDetail">
<el-form-item label="角色名称">
<el-input v-model="form.name"
placeholder="请输入角色名称"></el-input>
</el-form-item>
<el-form-item label="角色描述">
<el-input v-model="form.description"
placeholder="请输入角色描述"
type="textarea"
rows="5"></el-input>
</el-form-item>
<el-form-item prop="role"
label="角色权限">
<div style="max-height: 300px; overflow: auto">
<el-tree ref="per"
:data="permissions"
show-checkbox
default-expand-all
node-key="id"
:default-expanded-keys="checkedIds"
:default-checked-keys="checkedIds"
:props="defaultProps">
</el-tree>
</div>
</el-form-item>
</el-form>
<span slot="footer"
class="dialog-footer"
v-if="!isDetail">
<el-button @click="roleVisible = false"> </el-button>
<el-button type="primary"
@click="saveData"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import util from "@/libs/util";
import Util from "@/libs/util";
import Setting from "@/setting";
export default {
data() {
return {
keyword: "",
isDetail: false,
form: {
id: "",
name: "",
description: "",
permissions: []
},
list: [],
defaultProps: {
label: 'name'
},
page: 1,
pageSize: 10,
total: 0,
multipleSelection: [],
isAdd: true,
roleVisible: false,
permissions: [],
checkedIds: [],
roleNameReapeat: false //
};
},
watch: {
keyword: function(val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
data () {
return {
keyword: "",
isDetail: false,
form: {
id: "",
name: "",
description: "",
permissions: []
},
list: [],
defaultProps: {
label: 'name'
},
page: 1,
pageSize: 10,
total: 0,
multipleSelection: [],
isAdd: true,
roleVisible: false,
permissions: [],
checkedIds: [],
roleNameReapeat: false //
};
},
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
}
},
mounted () {
this.$store.commit('user/setCrumbs', [
{
name: '用户管理'
},
{
name: '角色管理'
}
])
this.getData()
},
methods: {
getData () {
this.$post(this.api.roles, Util.rsa({
page: this.page,
limit: this.pageSize,
name: this.keyword,
})).then(({ data }) => {
// const list = data.records.filter(e => e.id !== 1) //
const list = data.records
this.list = list
this.total = data.total == 0 ? 0 : +data.total - 1
}).catch(res => { })
},
mounted() {
this.$store.commit('user/setCrumbs', [
{
name: '用户管理'
},
{
name: '角色管理'
}
])
initData () {
this.$refs.table.clearSelection()
this.page = 1
this.getData()
},
methods: {
getData() {
this.$post(this.api.roles, {
page: this.page,
limit: this.pageSize,
name: this.keyword,
}).then(({ data }) => {
const list = data.records.filter(e => e.id !== 1) //
this.list = list
this.total = data.total == 0 ? 0 : +data.total - 1
}).catch(res => {})
},
initData() {
this.$refs.table.clearSelection()
this.page = 1
this.getData()
},
currentChange(val) {
this.page = val
currentChange (val) {
this.page = val
this.getData()
},
handleDelete (row) {
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
this.$post(this.api.deleteRole, Util.rsa([row.id])).then(res => {
Util.successMsg("删除成功");
this.getData()
},
handleDelete(row) {
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
this.$del(this.api.deleteRole, [row.id]).then(res => {
util.successMsg("删除成功");
this.getData()
}).catch(res => {})
}).catch(() => {})
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
batchDel() {
if (this.multipleSelection.length) {
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
this.$del(this.api.deleteRole, this.multipleSelection.map(e => e.id)).then(res => {
this.$refs.table.clearSelection();
util.successMsg("删除成功");
this.getData();
}).catch(res => {});
if(this.multipleSelection.length === this.list.length && this.page>1) {
this.handleCurrentChange(this.page - 1)
}
}).catch(() => {});
} else {
util.errorMsg("请先选择数据!");
}
},
closeRole() {
this.isDetail = false;
this.form = {
id: "",
name: "",
description: "",
permissions: []
};
this.checkedIds = [];
this.permissions = [];
},
//
getPer(row) {
if (!this.permissions.length) {
this.$get(this.api.perTree).then(({ data }) => {
this.permissions = data
row && this.getDetail(row)
}).catch(res => {})
}
},
addRole() {
this.isAdd = true
this.getPer()
this.checkedIds = []
this.permissions.length && this.$refs.per.setCheckedNodes([])
this.roleVisible = true
},
//
handleRolePer(data, permissions) {
let result = data
if (permissions.length) {
permissions.map(e => {
if (result.includes(e.id) && e.children) {
// ,idid,,,
e.children.every(n => result.includes(n)) || result.splice(result.indexOf(e.id), 1)
}
e.children && e.children.length && this.handleRolePer(data, e.children)
})
}
return result
},
//
async getDetail(row) {
this.$get(`${this.api.role}/${row.id}`).then(({ data }) => {
const { role } = data
this.form.name = role.name
this.form.description = role.description
this.form.id = role.id
const list = data.permissionList
// list[0] === '1' && list.shift() // 11
this.checkedIds = this.handleRolePer(list, this.permissions)
this.$refs.per.setCheckedNodes(this.checkedIds)
}).catch(err => {})
},
showRole(row) {
this.isDetail = true
this.isAdd = false
this.getPer(row)
this.roleVisible = true
},
editRole(row) {
this.isAdd = false
this.getPer(row)
this.roleVisible = true
},
async saveData() {
const { form } = this
if (!form.name) return util.warningMsg("请填写角色名称")
if (!form.description) return util.warningMsg("请填写角色描述")
const checked = [...this.$refs.per.getHalfCheckedKeys(), ...this.$refs.per.getCheckedKeys()]
if (!checked.length) return util.warningMsg("请选择角色权限")
let data = {
...form,
permissions: checked
}).catch(res => { })
}).catch(() => { })
},
handleSelectionChange (val) {
this.multipleSelection = val;
},
batchDel () {
if (this.multipleSelection.length) {
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
this.$post(this.api.deleteRole, Util.rsa(this.multipleSelection.map(e => e.id))).then(res => {
this.$refs.table.clearSelection();
Util.successMsg("删除成功");
this.getData();
}).catch(res => { });
if (this.multipleSelection.length === this.list.length && this.page > 1) {
this.handleCurrentChange(this.page - 1)
}
if (form.id) {
this.$put(this.api.role, data).then(res => {
util.successMsg("修改成功")
this.getData()
this.roleVisible = false
}).catch(res => {})
} else {
this.$post(this.api.role, data).then(res => {
util.successMsg("新增成功")
this.getData()
this.roleVisible = false
}).catch(res => {})
}).catch(() => { });
} else {
Util.errorMsg("请先选择数据!");
}
},
closeRole () {
this.isDetail = false;
this.form = {
id: "",
name: "",
description: "",
permissions: []
};
this.checkedIds = [];
this.permissions = [];
},
//
getPer (row) {
if (!this.permissions.length) {
this.$get(this.api.perTree).then(({ data }) => {
this.permissions = data
row && this.getDetail(row)
}).catch(res => { })
}
},
addRole () {
this.isAdd = true
this.getPer()
this.checkedIds = []
this.permissions.length && this.$refs.per.setCheckedNodes([])
this.roleVisible = true
},
//
handleRolePer (data, permissions) {
let result = data
if (permissions.length) {
permissions.map(e => {
if (result.includes(e.id) && e.children) {
// ,idid,,,
e.children.every(n => result.includes(n)) || result.splice(result.indexOf(e.id), 1)
}
}
e.children && e.children.length && this.handleRolePer(data, e.children)
})
}
return result
},
//
async getDetail (row) {
this.$post(this.api.role, Util.rsa(row.id)).then(({ data }) => {
const { role } = data
this.form.name = role.name
this.form.description = role.description
this.form.id = role.id
const list = data.permissionList
// list[0] === '1' && list.shift() // 11
this.checkedIds = this.handleRolePer(list, this.permissions)
this.$refs.per.setCheckedNodes(this.checkedIds)
}).catch(err => { })
},
showRole (row) {
this.isDetail = true
this.isAdd = false
this.getPer(row)
this.roleVisible = true
},
editRole (row) {
this.isAdd = false
this.getPer(row)
this.roleVisible = true
},
async saveData () {
const { form } = this
if (!form.name) return Util.warningMsg("请填写角色名称")
if (!form.description) return Util.warningMsg("请填写角色描述")
const checked = [...this.$refs.per.getHalfCheckedKeys(), ...this.$refs.per.getCheckedKeys()]
if (!checked.length) return Util.warningMsg("请选择角色权限")
let data = {
...form,
permissions: checked
}
if (form.id) {
this.$post(this.api.updateRole, Util.rsa(data)).then(res => {
Util.successMsg("修改成功")
this.getData()
this.roleVisible = false
}).catch(res => { })
} else {
this.$post(this.api.addRole, Util.rsa(data)).then(res => {
Util.successMsg("新增成功")
this.getData()
this.roleVisible = false
}).catch(res => { })
}
}
}
};
</script>
<style lang="scss" scoped>
</style>

@ -3,129 +3,151 @@
<div class="left">
<div class="inner">
<div class="text-center">
<img :src="avatar" class="avatar" />
<el-upload :action="this.api.updateUserAvatars" name="file" :data="{ userId }" :limit="10" :show-file-list="false" :headers="headers" :on-success="changeAvatar">
<el-button type="text" size="small">点击更换头像</el-button>
<img :src="avatar"
class="avatar" />
<el-upload :action="this.api.updateUserAvatars"
name="file"
:limit="10"
accept="image/*"
:show-file-list="false"
:headers="headers"
:before-upload="beforeUpload"
:on-success="changeAvatar">
<el-button type="text"
size="small">点击更换头像</el-button>
</el-upload>
</div>
<ul class="menu">
<li v-for="item in typeList" :key="item.index" :class="{active: item.index == active}">
<li v-for="item in typeList"
:key="item.index"
:class="{active: item.index == active}">
{{ item.title }}
</li>
</ul>
</div>
</div>
<info class="flex-1" ref="info" @updateStatus="updateStatus" @back="back"></info>
<info class="flex-1"
ref="info"
@updateStatus="updateStatus"
@back="back"></info>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
import Setting from '@/setting'
import util from '@/libs/util'
import Util from '@/libs/util'
import info from './info'
export default {
data() {
return {
headers: {
token: util.local.get(Setting.tokenKey)
},
typeList: [
{
index: '1',
title: '用户信息'
}
],
active: '1',
edited: false
};
data () {
return {
headers: {
token: Util.local.get(Setting.tokenKey)
},
typeList: [
{
index: '1',
title: '用户信息'
}
],
active: '1',
edited: false
};
},
components: { info },
computed: {
...mapState('user', [
'avatar', 'userId'
]),
},
// ,
beforeRouteLeave (to, from, next) {
if (this.edited) {
this.$confirm(`您所更改的内容未更新,是否更新?`, '提示', {
type: 'warning'
}).then(() => {
this.$refs.info.submit()
next()
}).catch(() => {
next()
})
} else {
next()
}
},
mounted () {
},
methods: {
...mapMutations('user', [
'setAvatar'
]),
//
beforeUpload (file) {
if (!Util.isImg(file.name.split('.').pop())) {
Util.warningMsg(`请上传图片!`)
return false
}
return true
},
components: { info },
computed: {
...mapState('user', [
'avatar', 'userId'
]),
changeAvatar (res) {
this.setAvatar(res.data)
},
// ,
beforeRouteLeave(to, from, next) {
if(this.edited){
updateStatus (status) {
this.edited = status
},
//
back () {
if (this.edited) {
this.edited = false
this.$confirm(`您所更改的内容未更新,是否更新?`, '提示', {
type: 'warning'
}).then(() => {
this.$refs.info.submit()
next()
this.$router.back()
}).catch(() => {
next()
})
}else{
next()
}
},
mounted() {
},
methods: {
...mapMutations('user', [
'setAvatar'
]),
changeAvatar(res) {
this.setAvatar(res.data)
},
updateStatus(status){
this.edited = status
},
//
back() {
if(this.edited){
this.edited = false
this.$confirm(`您所更改的内容未更新,是否更新?`, '提示', {
type: 'warning'
}).then(() => {
this.$refs.info.submit()
this.$router.back()
}).catch(() => {
this.$router.back()
})
}else{
this.$router.back()
}
})
} else {
this.$router.back()
}
}
}
};
</script>
<style lang="scss" scoped>
.main{
display: flex;
margin: 0 auto;
.left{
margin-right: 12px;
background-color: #fff;
box-shadow: 2px 0px 6px 0px #EEEEEE;
.inner{
width: 170px;
padding: 20px 0;
}
.avatar{
width: 80px;
height: 80px;
border-radius: 50%;
}
.menu{
margin-top: 32px;
li{
padding: 0 20px;
color: #303133;
font-size: 14px;
line-height: 38px;
cursor: pointer;
&.active{
color: #fff;
background-color: $main-color;
.main {
display: flex;
margin: 0 auto;
.left {
margin-right: 12px;
background-color: #fff;
box-shadow: 2px 0px 6px 0px #eeeeee;
.inner {
width: 170px;
padding: 20px 0;
}
.avatar {
width: 80px;
height: 80px;
border-radius: 50%;
}
.menu {
margin-top: 32px;
li {
padding: 0 20px;
color: #303133;
font-size: 14px;
line-height: 38px;
cursor: pointer;
&.active {
color: #fff;
background-color: $main-color;
}
}
}
}
}
}
}
</style>

@ -1,127 +1,193 @@
<template>
<div class="relative" v-loading="loading">
<div class="relative"
v-loading="loading">
<div class="page">
<h6 class="l-title"><img src="@/assets/images/info1.png" alt=""> 基本信息</h6>
<h6 class="l-title"><img src="@/assets/images/info1.png"
alt=""> 基本信息</h6>
<div class="page-content">
<ul class="list">
<li>
<label>姓名</label>
<el-input placeholder="请输入姓名" type="text" v-model="form.realName" />
<el-input placeholder="请输入姓名"
type="text"
v-model="form.realName" />
</li>
<li>
<label>性别</label>
<el-select size="small" v-model="form.sex">
<el-option v-for="item in sexList" :key="item.value" :label="item.name" :value="item.value"></el-option>
<el-select size="small"
v-model="form.sex">
<el-option v-for="item in sexList"
:key="item.value"
:label="item.name"
:value="item.value"></el-option>
</el-select>
</li>
<li>
<label>账号</label>
<el-input class="m-r-10" type="text" size="small" v-model="form.username"></el-input>
<el-input class="m-r-10"
type="text"
size="small"
v-model="form.username"></el-input>
<!-- <el-button type="text" size="small" @click="showAccount">修改</el-button> -->
</li>
<li>
<label>工号</label>
<el-input size="small" v-model="form.jobNumber" clearable></el-input>
<el-input size="small"
v-model="form.jobNumber"
clearable></el-input>
</li>
<li>
<label>邮箱</label>
<el-input class="m-r-10" size="small" v-model="form.email"></el-input>
<el-input class="m-r-10"
size="small"
v-model="form.email"></el-input>
<!-- <el-button v-if="form.email" type="text" size="small" @click="bindEmail">更换</el-button>
<el-button v-else type="text" size="small" @click="bindEmail">添加</el-button> -->
</li>
<li>
<label>手机号</label>
<el-input class="m-r-10" type="text" size="small" maxlength="11" v-model="form.phone"></el-input>
<el-input class="m-r-10"
type="text"
size="small"
maxlength="11"
v-model="form.phone"></el-input>
<!-- <el-button type="text" size="small" @click="bindPhone">{{ form.phone ? '更换' : '绑定' }}</el-button>
<el-button v-if="form.phone" type="text" size="small" @click="unbind">解绑</el-button> -->
</li>
<li>
<label>密码</label>
<el-input class="m-r-10" size="small" value="******" disabled></el-input>
<el-button type="text" size="small" @click="bindPassword">修改</el-button>
<el-input class="m-r-10"
size="small"
value="******"
disabled></el-input>
<el-button type="text"
size="small"
@click="bindPassword">修改</el-button>
</li>
</ul>
</div>
<div class="btn-wrap">
<el-button size="small" v-throttle @click="$emit('back')">取消</el-button>
<el-button type="primary" size="small" v-throttle @click="submit">更新</el-button>
<el-button size="small"
@click="$emit('back')">取消</el-button>
<el-button type="primary"
size="small"
@click="submit">更新</el-button>
</div>
</div>
<el-dialog
:title="form.email ? '更换邮箱' : '绑定邮箱'"
:visible.sync="emailVisible"
:close-on-click-modal="false"
@close="closeEmail"
width="30%">
<el-form ref="form" :model="form" label-width="60px">
<el-dialog :title="form.email ? '更换邮箱' : '绑定邮箱'"
:visible.sync="emailVisible"
:close-on-click-modal="false"
@close="closeEmail"
width="30%">
<el-form ref="form"
:model="form"
label-width="60px">
<el-form-item label="邮箱">
<el-input placeholder="请输入邮箱" v-model="email"></el-input>
<el-input placeholder="请输入邮箱"
v-model="email"></el-input>
</el-form-item>
<el-form-item label="验证码">
<div class="flex-between">
<el-input v-model="emailCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left: 10px" type="text" @click="sendEmailCode" :disabled="emailDisabled">{{ emailBtnText }}</el-button>
<el-input v-model="emailCode"
placeholder="请输入验证码"
maxlength="6"></el-input>
<el-button style="margin-left: 10px"
type="text"
@click="sendEmailCode"
:disabled="emailDisabled">{{ emailBtnText }}</el-button>
</div>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<span slot="footer"
class="dialog-footer">
<el-button @click="emailVisible = false"> </el-button>
<el-button type="primary" @click="emailSubmit"> </el-button>
<el-button type="primary"
@click="emailSubmit"> </el-button>
</span>
</el-dialog>
<el-dialog
:title="form.phone ? '更换手机号' : '绑定手机号'"
:visible.sync="phoneVisible"
:close-on-click-modal="false"
@close="closePhone"
width="30%">
<el-form ref="form" :model="form" label-width="60px">
<el-dialog :title="form.phone ? '更换手机号' : '绑定手机号'"
:visible.sync="phoneVisible"
:close-on-click-modal="false"
@close="closePhone"
width="30%">
<el-form ref="form"
:model="form"
label-width="60px">
<el-form-item label="手机号">
<el-input style="width: 404px;" placeholder="请输入手机号" v-model="phone" maxlength="11"></el-input>
<el-input style="width: 404px;"
placeholder="请输入手机号"
v-model="phone"
maxlength="11"></el-input>
</el-form-item>
<el-form-item label="验证码">
<div class="flex-between">
<el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left: 10px" type="text" @click="sendPhoneCode" :disabled="phoneDisabled">{{ phoneBtnText }}</el-button>
<el-input v-model="phoneCode"
placeholder="请输入验证码"
maxlength="6"></el-input>
<el-button style="margin-left: 10px"
type="text"
@click="sendPhoneCode"
:disabled="phoneDisabled">{{ phoneBtnText }}</el-button>
</div>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<span slot="footer"
class="dialog-footer">
<el-button @click="phoneVisible = false"> </el-button>
<el-button type="primary" @click="phoneSubmit"> </el-button>
<el-button type="primary"
@click="phoneSubmit"> </el-button>
</span>
</el-dialog>
<el-dialog
title="更换密码"
:visible.sync="pwdVisible"
:close-on-click-modal="false"
@close="closePassword"
width="30%">
<el-form ref="pwdForm" :model="form" label-width="60px">
<el-dialog title="更换密码"
:visible.sync="pwdVisible"
:close-on-click-modal="false"
@close="closePassword"
width="30%">
<el-form ref="pwdForm"
:model="form"
label-width="60px">
<el-form-item label="原密码">
<el-input type="password" v-model="pwdForm.password" placeholder="请输入原密码"></el-input>
<el-input type="password"
v-model="pwdForm.password"
placeholder="请输入原密码"></el-input>
</el-form-item>
<el-form-item label="新密码">
<el-input type="password" v-model="pwdForm.newPassword" placeholder="请输入新密码" @keyup.enter.native="editPassword"></el-input>
<el-input type="password"
v-model="pwdForm.newPassword"
placeholder="请输入新密码"
@keyup.enter.native="editPassword"></el-input>
</el-form-item>
<el-form-item label="新密码">
<el-input type="password" v-model="pwdForm.reNewPassword" placeholder="请确认新密码" @keyup.enter.native="editPassword"></el-input>
<el-input type="password"
v-model="pwdForm.reNewPassword"
placeholder="请确认新密码"
@keyup.enter.native="editPassword"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<span slot="footer"
class="dialog-footer">
<el-button @click="pwdVisible = false"> </el-button>
<el-button type="primary" @click="editPassword"> </el-button>
<el-button type="primary"
@click="editPassword"> </el-button>
</span>
</el-dialog>
<el-dialog title="修改账号" :visible.sync="accountVisible" :close-on-click-modal="false" width="30%">
<el-dialog title="修改账号"
:visible.sync="accountVisible"
:close-on-click-modal="false"
width="30%">
<el-form label-width="70px">
<el-form-item label="账号">
<el-input v-model="editUsername" placeholder="请输入账号"></el-input>
<el-input v-model="editUsername"
placeholder="请输入账号"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="small" @click="accountVisible = false"> </el-button>
<el-button size="small" type="primary" @click="confirmAccount"> </el-button>
<span slot="footer"
class="dialog-footer">
<el-button size="small"
@click="accountVisible = false"> </el-button>
<el-button size="small"
type="primary"
@click="confirmAccount"> </el-button>
</span>
</el-dialog>
</div>
@ -129,344 +195,345 @@
<script>
import Setting from '@/setting'
import util from '@/libs/util'
import Util from '@/libs/util'
import { mapState, mapMutations } from 'vuex'
export default {
data() {
return {
loading: false,
editUsername: '',
accountVisible: false,
updateTime: 0,
token: util.local.get(Setting.tokenKey),
form: {
userName: "",
name: "",
jobNumber: "",
password: "",
phone: "",
email: "",
sex: 1,
},
emailVisible: false,
pwdVisible: false,
phoneVisible: false,
showArch: false,
pwdForm: {
password: "",
newPassword: "",
reNewPassword: ""
},
sexList: [
{
name: "男",
value: 1
},
{
name: "女",
value: 2
}
],
email: "",
emailBtnText: "发送验证码",
emailCode: "",
emailDisabled: false,
emailTimer: null,
data () {
return {
loading: false,
editUsername: '',
accountVisible: false,
updateTime: 0,
token: Util.local.get(Setting.tokenKey),
form: {
userName: "",
name: "",
jobNumber: "",
password: "",
phone: "",
phoneBtnText: "发送验证码",
phoneCode: "",
phoneDisabled: false,
phoneTimer: null,
emailOpener: "",
phoneOpener: "",
originAccount: "",
accountReapeat: false
};
email: "",
sex: 1,
},
emailVisible: false,
pwdVisible: false,
phoneVisible: false,
showArch: false,
pwdForm: {
password: "",
newPassword: "",
reNewPassword: ""
},
sexList: [
{
name: "男",
value: 1
},
{
name: "女",
value: 2
}
],
email: "",
emailBtnText: "发送验证码",
emailCode: "",
emailDisabled: false,
emailTimer: null,
phone: "",
phoneBtnText: "发送验证码",
phoneCode: "",
phoneDisabled: false,
phoneTimer: null,
emailOpener: "",
phoneOpener: "",
originAccount: "",
accountReapeat: false
};
},
computed: {
...mapState("user", [
"userId", "avatar"
])
},
watch: {
// ,
form: {
handler () {
this.updateTime++
if (this.updateTime > 1) this.$emit('updateStatus', this.updateTime > 1)
},
deep: true
}
},
mounted () {
this.getData()
},
methods: {
...mapMutations('user', [
'setUserName'
]),
//
getData () {
this.loading = true
this.$post(this.api.queryUser, Util.rsa(this.userId)).then(({ data }) => {
this.form = data
this.loading = false
}).catch(err => { })
},
computed: {
...mapState("user", [
"userId", "avatar"
])
//
showAccount () {
this.accountVisible = true
},
watch: {
// ,
form: {
handler(){
this.updateTime++
if(this.updateTime > 1) this.$emit('updateStatus', this.updateTime > 1)
},
deep:true
//
confirmAccount () {
if (this.editUsername) {
form.username = this.editUsername
this.accountVisible = false
const { form } = this
this.$post(this.api.updateUser, Util.rsa(form)).then(res => {
this.setUserName(form.username)
this.$message.success("提交成功!")
}).catch(res => { })
} else {
Util.errorMsg('请输入账号')
}
},
mounted() {
this.getData()
bindEmail () {
this.email = this.form.email
this.emailVisible = true
},
methods: {
...mapMutations('user', [
'setUserName'
]),
//
getData() {
this.loading = true
this.$get(`${this.api.user}/${this.userId}`).then(({ data }) => {
this.form = data
this.loading = false
}).catch(err => {})
},
//
showAccount() {
this.accountVisible = true
},
//
confirmAccount() {
if (this.editUsername) {
form.username = this.editUsername
this.accountVisible = false
const { form } = this
this.$put(this.api.user, form).then(res => {
this.setUserName(form.username)
this.$message.success("提交成功!")
}).catch(res => {})
bindPhone () {
this.phone = this.form.phone
this.phoneVisible = true
},
//
unbind () {
this.$confirm('确定要解绑该手机号吗?', '提示', {
type: 'warning'
}).then(() => {
this.$get(this.api.unbindMobilePhone).then(res => {
this.$message.success('解绑成功')
this.getData()
}).catch(res => { })
}).catch(() => { })
},
bindPassword () {
this.pwdVisible = true
},
editPassword () {
const data = this.pwdForm
if (!data.password) return Util.warningMsg("请输入原密码")
if (!data.newPassword) return Util.warningMsg("请输入新密码")
if (!data.reNewPassword) return Util.warningMsg("请确认新密码")
if (data.newPassword.length < 6 || data.reNewPassword.length < 6) return Util.warningMsg("请输入6位数以上的密码")
if (data.newPassword !== data.reNewPassword) return Util.warningMsg("输入的新密码不一致,请重新确认")
if (data.password === data.newPassword) return Util.warningMsg("原密码跟新密码不能一致")
this.$put(this.api.pwd, {
id: this.form.id,
oldPwd: data.password,
newPwd: data.newPassword
}).then(res => {
Util.successMsg("更换成功")
this.pwdVisible = false
}).catch(err => { })
},
closePassword () {
this.pwdForm = {
password: "",
newPassword: "",
reNewPassword: ""
}
},
submit () {
const { form } = this
this.$post(this.api.updateUser, Util.rsa({
id: form.id,
jobNumber: form.jobNumber,
phone: form.phone,
realName: form.realName,
username: form.username,
email: form.email,
sex: form.sex,
})).then(res => {
this.$emit('updateStatus', false)
this.setUserName(form.realName)
this.$message.success("提交成功!")
}).catch(res => { })
},
emailCountdown () {
let count = 60;
if (!this.emailTimer) {
this.emailDisabled = true;
this.emailTimer = setInterval(() => {
console.log("倒计时中");
if (count > 0) {
count--;
this.emailBtnText = `${count}秒后重试`;
} else {
util.errorMsg('请输入账号')
this.emailDisabled = false;
clearInterval(this.emailTimer);
this.emailTimer = null;
this.emailBtnText = `发送验证码`;
}
},
bindEmail() {
this.email = this.form.email
this.emailVisible = true
},
bindPhone() {
this.phone = this.form.phone
this.phoneVisible = true
},
//
unbind() {
this.$confirm('确定要解绑该手机号吗?', '提示', {
type: 'warning'
}).then(() => {
this.$get(this.api.unbindMobilePhone).then(res => {
this.$message.success('解绑成功')
this.getData()
}).catch(res => {})
}).catch(() => {})
},
bindPassword() {
this.pwdVisible = true
},
editPassword() {
const data = this.pwdForm
if (!data.password) return util.warningMsg("请输入原密码")
if (!data.newPassword) return util.warningMsg("请输入新密码")
if (!data.reNewPassword) return util.warningMsg("请确认新密码")
if (data.newPassword.length < 6 || data.reNewPassword.length < 6) return util.warningMsg("请输入6位数以上的密码")
if (data.newPassword !== data.reNewPassword) return util.warningMsg("输入的新密码不一致,请重新确认")
if (data.password === data.newPassword) return util.warningMsg("原密码跟新密码不能一致")
this.$put(this.api.pwd, {
id: this.form.id,
oldPwd: data.password,
newPwd: data.newPassword
}).then(res => {
util.successMsg("更换成功")
this.pwdVisible = false
}).catch(err => {})
},
closePassword() {
this.pwdForm = {
password: "",
newPassword: "",
reNewPassword: ""
}, 1000);
}
},
phoneCountdown () {
let count = 60;
if (!this.phoneTimer) {
this.phoneDisabled = true;
this.phoneTimer = setInterval(() => {
console.log("倒计时中");
if (count > 0) {
count--;
this.phoneBtnText = `${count}秒后重试`;
} else {
this.phoneDisabled = false;
clearInterval(this.phoneTimer);
this.phoneTimer = null;
this.phoneBtnText = `发送验证码`;
}
},
submit() {
const { form } = this
this.$put(this.api.user, {
id: form.id,
jobNumber: form.jobNumber,
phone: form.phone,
realName: form.realName,
username: form.username,
email: form.email,
sex: form.sex,
}).then(res => {
this.$emit('updateStatus', false)
this.setUserName(form.realName)
this.$message.success("提交成功!")
}).catch(res => {})
},
emailCountdown() {
let count = 60;
if (!this.emailTimer) {
this.emailDisabled = true;
this.emailTimer = setInterval(() => {
console.log("倒计时中");
if (count > 0) {
count--;
this.emailBtnText = `${count}秒后重试`;
} else {
this.emailDisabled = false;
clearInterval(this.emailTimer);
this.emailTimer = null;
this.emailBtnText = `发送验证码`;
}
}, 1000);
}
},
phoneCountdown() {
let count = 60;
if (!this.phoneTimer) {
this.phoneDisabled = true;
this.phoneTimer = setInterval(() => {
console.log("倒计时中");
if (count > 0) {
count--;
this.phoneBtnText = `${count}秒后重试`;
} else {
this.phoneDisabled = false;
clearInterval(this.phoneTimer);
this.phoneTimer = null;
this.phoneBtnText = `发送验证码`;
}
}, 1000);
}
},
closeEmail() {
if (!this.emailDisabled) {
this.emailCode = "";
}
},
sendEmailCode() {
if (!this.email) return util.warningMsg("请输入邮箱")
if (!/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(this.email)) return util.warningMsg("请输入正确的邮箱")
this.$post(this.api.sendPhoneOrEmailCode, {
email: this.email,
types: 1
}).then(res => {
if (res.message.opener) {
this.emailCountdown();
this.emailOpener = res.message.opener;
} else {
util.errorMsg(res.message);
}
}).catch(res => {})
},
emailSubmit() {
if (!this.email) return util.warningMsg("请输入邮箱")
if (!/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(this.email)) return util.warningMsg("请输入正确的邮箱")
if (!this.emailCode) return util.warningMsg("请输入验证码")
this.$put(this.api.bindPhoneOrEmail, {
userId: this.userId,
email: this.email,
types: 1,
code: this.emailCode,
opener: this.emailOpener
}).then(res => {
util.successMsg("绑定成功")
this.form.email = this.email
this.emailVisible = false
}).catch(res => {})
},
closePhone() {
if (!this.emailDisabled) {
this.emailCode = "";
}
},
sendPhoneCode() {
if (!this.phone) return util.warningMsg("请输入手机号");
if (!/^1[3456789]\d{9}$/.test(this.phone)) return util.warningMsg("请输入正确的手机号");
let data = {
userId: this.userId,
phone: this.phone,
types: 2
};
this.$post(this.api.sendPhoneOrEmailCode, data).then(res => {
if (res.message.opener) {
this.phoneCountdown();
this.phoneOpener = res.message.opener;
} else {
util.errorMsg(res.message);
}
}).catch(res => {
});
},
phoneSubmit() {
if (!this.phone) return util.warningMsg("请输入手机号");
if (!/^1[3456789]\d{9}$/.test(this.phone)) return util.warningMsg("请输入正确的手机号");
if (!this.phoneCode) return util.warningMsg("请输入验证码");
let data = {
userId: this.userId,
phone: this.phone,
types: 2,
code: this.phoneCode,
opener: this.phoneOpener
};
this.$post(this.api.bindPhoneOrEmail, data).then(res => {
util.successMsg("绑定成功");
this.form.phone = this.phone;
this.phoneVisible = false;
}).catch(res => {
});
}, 1000);
}
},
closeEmail () {
if (!this.emailDisabled) {
this.emailCode = "";
}
},
sendEmailCode () {
if (!this.email) return Util.warningMsg("请输入邮箱")
if (!/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(this.email)) return Util.warningMsg("请输入正确的邮箱")
this.$post(this.api.sendPhoneOrEmailCode, {
email: this.email,
types: 1
}).then(res => {
if (res.message.opener) {
this.emailCountdown();
this.emailOpener = res.message.opener;
} else {
Util.errorMsg(res.message);
}
}).catch(res => { })
},
emailSubmit () {
if (!this.email) return Util.warningMsg("请输入邮箱")
if (!/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(this.email)) return Util.warningMsg("请输入正确的邮箱")
if (!this.emailCode) return Util.warningMsg("请输入验证码")
this.$put(this.api.bindPhoneOrEmail, {
userId: this.userId,
email: this.email,
types: 1,
code: this.emailCode,
opener: this.emailOpener
}).then(res => {
Util.successMsg("绑定成功")
this.form.email = this.email
this.emailVisible = false
}).catch(res => { })
},
closePhone () {
if (!this.emailDisabled) {
this.emailCode = "";
}
},
sendPhoneCode () {
if (!this.phone) return Util.warningMsg("请输入手机号");
if (!/^1[3456789]\d{9}$/.test(this.phone)) return Util.warningMsg("请输入正确的手机号");
let data = {
userId: this.userId,
phone: this.phone,
types: 2
};
this.$post(this.api.sendPhoneOrEmailCode, data).then(res => {
if (res.message.opener) {
this.phoneCountdown();
this.phoneOpener = res.message.opener;
} else {
Util.errorMsg(res.message);
}
}).catch(res => {
});
},
phoneSubmit () {
if (!this.phone) return Util.warningMsg("请输入手机号");
if (!/^1[3456789]\d{9}$/.test(this.phone)) return Util.warningMsg("请输入正确的手机号");
if (!this.phoneCode) return Util.warningMsg("请输入验证码");
let data = {
userId: this.userId,
phone: this.phone,
types: 2,
code: this.phoneCode,
opener: this.phoneOpener
};
this.$post(this.api.bindPhoneOrEmail, data).then(res => {
Util.successMsg("绑定成功");
this.form.phone = this.phone;
this.phoneVisible = false;
}).catch(res => {
});
}
}
};
</script>
<style lang="scss" scoped>
.page {
min-height: 100%;
min-height: 100%;
}
.l-title {
display: flex;
align-items: center;
margin-bottom: 12px;
font-size: 14px;
color: #333;
img {
margin-right: 5px;
}
}
.list{
.line {
display: flex;
margin-bottom: 24px;
}
.el-input, .el-select {
width: 220px;
.el-input__inner{
border-color: #CACFDB;
}
}
li {
display: flex;
align-items: center;
margin-bottom: 20px;
&>label {
width: 100px;
margin-bottom: 12px;
font-size: 14px;
color: #333;
img {
margin-right: 5px;
text-align: right;
font-size: 14px;
color: #4c4c4c;
white-space: nowrap;
}
.el-select .el-input.is-disabled .el-input__inner {
border-color: #ddd;
}
.list {
.line {
display: flex;
margin-bottom: 24px;
}
.el-input,
.el-select {
width: 220px;
.el-input__inner {
border-color: #cacfdb;
}
}
.val {
margin-right: 15px;
color: #606266;
font-size: 14px;
li {
display: flex;
align-items: center;
margin-bottom: 20px;
& > label {
width: 100px;
margin-right: 5px;
text-align: right;
font-size: 14px;
color: #4c4c4c;
white-space: nowrap;
}
.el-select .el-input.is-disabled .el-input__inner {
border-color: #ddd;
}
.val {
margin-right: 15px;
color: #606266;
font-size: 14px;
}
}
}
}
.btn-wrap {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 12px 0;
text-align: center;
background-color: #fff;
.el-button{
width: 80px;
}
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 12px 0;
text-align: center;
background-color: #fff;
.el-button {
width: 80px;
}
}
</style>

File diff suppressed because it is too large Load Diff

@ -2,220 +2,264 @@
<div class="page">
<div class="tool">
<div class="search-wrap">
<el-input placeholder="请输入用户组名称" v-model.trim="keyword" clearable></el-input>
<el-input placeholder="请输入用户组名称"
v-model.trim="keyword"
clearable></el-input>
</div>
<div class="actions">
<el-button v-auth type="primary" @click="add" >新增</el-button>
<el-button v-auth @click="batchDel">删除</el-button>
<el-button v-auth
type="primary"
@click="add">新增</el-button>
<!-- <el-button v-auth
@click="batchDel">删除</el-button> -->
</div>
</div>
<el-table ref="table" :data="list" class="table" header-align="center" @selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column prop="groupName" label="名称" align="center" min-width="250" show-overflow-tooltip></el-table-column>
<el-table-column prop="description" label="角色描述" min-width="400" align="center"></el-table-column>
<el-table-column label="操作" width="170">
<el-table ref="table"
:data="list"
class="table"
header-align="center"
@selection-change="handleSelectionChange"
row-key="id">
<el-table-column type="selection"
width="55"
align="center"
:reserve-selection="true"></el-table-column>
<el-table-column prop="groupName"
label="名称"
align="center"
min-width="250"
show-overflow-tooltip></el-table-column>
<el-table-column prop="description"
label="角色描述"
min-width="400"
align="center"></el-table-column>
<el-table-column label="操作"
width="170">
<template slot-scope="scope">
<el-button v-auth type="text" @click="edit(scope.row)">编辑</el-button>
<el-button v-auth type="text" @click="del(scope.row)">删除</el-button>
<el-button v-auth
type="text"
@click="edit(scope.row)">编辑</el-button>
<el-button v-auth
type="text"
@click="del(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination>
<el-pagination background
@current-change="currentChange"
:current-page="page"
layout="total, prev, pager, next"
:total="total"></el-pagination>
</div>
<el-dialog :title="form.id ? '编辑' : '新增' + '用户组'" :visible.sync="formVisible" width="640px" class="dialog" :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item prop="groupName" label="名称">
<el-input v-model="form.groupName" placeholder="请输入名称"></el-input>
<el-dialog :title="form.id ? '编辑' : '新增' + '用户组'"
:visible.sync="formVisible"
width="640px"
class="dialog"
:close-on-click-modal="false">
<el-form ref="form"
:model="form"
:rules="rules"
label-width="80px">
<el-form-item prop="groupName"
label="名称">
<el-input v-model="form.groupName"
placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item prop="description" label="描述">
<el-input v-model="form.description" placeholder="请输入描述" type="textarea" rows="5"></el-input>
<el-form-item prop="description"
label="描述">
<el-input v-model="form.description"
placeholder="请输入描述"
type="textarea"
rows="5"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<span slot="footer"
class="dialog-footer">
<el-button @click="formVisible = false"> </el-button>
<el-button type="primary" @click="submit"> </el-button>
<el-button type="primary"
@click="submit"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import util from '@/libs/util'
import Util from '@/libs/util'
export default {
data() {
return {
keyword: '',
list: [],
page: 1,
pageSize: 10,
total: 0,
multipleSelection: [],
form: {
id: '',
groupName: '',
description: ''
},
rules: {
groupName: [
{ required: true, message: "请输入名称", trigger: "blur" }
],
description: [
{ required: true, message: "请输入描述", trigger: "blur" }
]
},
formVisible: false
};
},
watch: {
keyword: function(val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
data () {
return {
keyword: '',
list: [],
page: 1,
pageSize: 10,
total: 0,
multipleSelection: [],
form: {
id: '',
groupName: '',
description: ''
},
rules: {
groupName: [
{ required: true, message: "请输入名称", trigger: "blur" }
],
description: [
{ required: true, message: "请输入描述", trigger: "blur" }
]
},
formVisible: false
};
},
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
}
},
mounted () {
this.$store.commit('user/setCrumbs', [
{
name: '用户管理'
},
{
name: '用户组管理'
}
])
this.getData()
},
methods: {
getData () {
this.$post(this.api.groupList, Util.rsa({
groupName: this.keyword,
page: this.page,
limit: this.pageSize
})).then(({ data }) => {
this.list = data.records
this.total = +data.total
}).catch(err => { })
},
mounted() {
this.$store.commit('user/setCrumbs', [
{
name: '用户管理'
},
{
name: '用户组管理'
}
])
initData () {
this.$refs.table.clearSelection()
this.page = 1
this.getData()
},
methods: {
getData() {
this.$post(this.api.groupList, {
groupName: this.keyword,
page: this.page,
limit : this.pageSize
}).then(({ data }) => {
this.list = data.records
this.total = +data.total
}).catch(err => {})
},
initData() {
this.$refs.table.clearSelection()
this.page = 1
this.getData()
},
del(row) {
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
del (row) {
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
this.$post(this.api.groupDel, Util.rsa(row.id)).then(res => {
Util.successMsg("删除成功")
this.getData()
}).catch(res => { })
}).catch(() => { })
},
//
batchDel () {
const list = this.multipleSelection
if (list.length) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$del(`${this.api.groupDel}/${row.id}`).then(res => {
util.successMsg("删除成功")
this.getData()
}).catch(res => {})
}).catch(() => {})
},
//
batchDel() {
const list = this.multipleSelection
if (list.length) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$del(`${this.api.user}`, list.map(e => e.id)).then(res => {
this.$refs.table.clearSelection()
util.successMsg('删除成功')
this.getStaff()
}).catch(res => {})
}).catch(() => {})
} else {
util.errorMsg('请先选择数据 !')
}
},
handleSelectionChange(val) {
this.multipleSelection = val
},
currentChange(val) {
this.page = val
this.getData()
},
this.$post(this.api.groupDel, Util.rsa(list.map(e => e.id))).then(res => {
this.$refs.table.clearSelection()
Util.successMsg('删除成功')
this.getStaff()
}).catch(res => { })
}).catch(() => { })
} else {
Util.errorMsg('请先选择数据 !')
}
},
handleSelectionChange (val) {
this.multipleSelection = val
},
currentChange (val) {
this.page = val
this.getData()
},
//
add() {
this.form = {
id: '',
groupName: '',
description: ''
}
this.formVisible = true
this.$nextTick(() => {
this.$refs.form.clearValidate()
})
},
//
edit(row) {
this.form = {
id: row.id,
groupName: row.groupName,
description: row.description
}
this.formVisible = true
},
// /
submit() {
this.$refs.form.validate((valid) => {
if (valid) {
if (this.submiting) return false
this.submiting = true
const { form } = this
if (form.id) {
this.$put(this.api.groupUpdate, form).then(res => {
util.successMsg("编辑成功!")
this.formVisible = false
this.getData()
setTimeout(() => {
this.submiting = false
}, 2000)
}).catch(res => {
setTimeout(() => {
this.submiting = false
}, 2000)
})
} else {
this.$post(this.api.groupAdd, form).then(res => {
util.successMsg("新增成功!")
this.formVisible = false
this.getData()
setTimeout(() => {
this.submiting = false
}, 2000)
}).catch(res => {
setTimeout(() => {
this.submiting = false
}, 2000)
})
}
}
})
//
add () {
this.form = {
id: '',
groupName: '',
description: ''
}
this.formVisible = true
this.$nextTick(() => {
this.$refs.form.clearValidate()
})
},
//
edit (row) {
this.form = {
id: row.id,
groupName: row.groupName,
description: row.description
}
this.formVisible = true
},
// /
submit () {
this.$refs.form.validate((valid) => {
if (valid) {
if (this.submiting) return false
this.submiting = true
const { form } = this
if (form.id) {
this.$post(this.api.groupUpdate, Util.rsa(form)).then(res => {
Util.successMsg("编辑成功!")
this.formVisible = false
this.getData()
setTimeout(() => {
this.submiting = false
}, 2000)
}).catch(res => {
setTimeout(() => {
this.submiting = false
}, 2000)
})
} else {
this.$post(this.api.groupAdd, Util.rsa(form)).then(res => {
Util.successMsg("新增成功!")
this.formVisible = false
this.getData()
setTimeout(() => {
this.submiting = false
}, 2000)
}).catch(res => {
setTimeout(() => {
this.submiting = false
}, 2000)
})
}
}
})
}
}
};
</script>
<style lang="scss" scoped>
.styles {
display: inline-flex;
li {
margin-right: 20px;
text-align: center;
&:hover .review {
border-color: #2962FF;
display: inline-flex;
li {
margin-right: 20px;
text-align: center;
&:hover .review {
border-color: #2962ff;
}
}
.review {
padding: 18px;
margin-bottom: 10px;
border: 1px solid #dcdee0;
border-radius: 2px;
}
}
.review {
padding: 18px;
margin-bottom: 10px;
border: 1px solid #DCDEE0;
border-radius: 2px;
}
}
</style>

@ -1,14 +1,10 @@
/**
* 业务配置
* */
const url = location.host;
const isDev = process.env.NODE_ENV === 'development' // 开发环境
let host = `${location.origin}/`
if (isDev) {
// host = 'http://192.168.31.52:10000/'
host = 'http://192.168.31.136:10000/'
// host = 'http://10.10.11.7/'
host = 'http://192.168.31.51:10000/'
}
const Setting = {
@ -36,10 +32,6 @@ const Setting = {
* localStorage里保存的vuex的key
*/
storeKey: "IASF_server_store",
/**
* 默认密码
*/
initialPassword: "111aaa",
/**
* 多语言配置
* */
@ -59,7 +51,8 @@ const Setting = {
// 相同路由,不同参数间进行切换,是否强力更新
sameRouteForceUpdate: false,
// 是否使用动态路由(即角色权限,开启了的话就会取后端返回的权限树来显示头部导肮和页面按钮)
dynamicRoute: false
dynamicRoute: true,
publicKey: 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA08Nz0zscnWtddmaNylIPt9v5ZO6U6pYyGochRrbpI+ocwoyV4E1uUu3J9/mmR8pyMBcYzE5KkBytlaiLnd6dMqo4R60aihN/TqfuI/03LzgAS/egT/Q4VB9yZSyZCmJhrgTtSX5kxotAbewp0gqsWpi+6BUYDuiwJ0WNlhDVV4FOQIppmvHh0RqYDhjiPNAuy7fEtytT+IY4rxm6LggvmNtIq5k2oLbDxEeI1GOyFHT6sLGMkmBLmHu7JYcrlyUGyGWsxh8hVame1zQsScivrZu757BTGhN4xObTivIdAbR7uFeeX4lp0X1JNtIe9TwB/aZzKJjZMPXeV7BJ01g3MQIDAQAB',
};
export default Setting;

@ -15,7 +15,7 @@ export default {
},
mutations: {
setAvatar: (state, avatar) => {
state.avatar = avatar
if (avatar) state.avatar = avatar
},
setUserId: (state, userId) => {
state.userId = userId

@ -15,5 +15,6 @@ module.exports = {
assetsDir: Setting.assetsDir,
devServer: {
port: 8088 // 固定端口
}
},
productionSourceMap: false,
}
Loading…
Cancel
Save