yujialong 5 months ago
parent a13172fa20
commit 44463f31c5
  1. 4
      src/api/index.js
  2. 104
      src/layouts/home/index.vue
  3. 5
      src/pages/account/login/index.vue
  4. 185
      src/pages/data/list/index.vue
  5. 251
      src/pages/user/list/index.vue
  6. 5
      src/setting.js

@ -10,6 +10,8 @@ export default {
getOtherAccountByPhone: `users/users/user/getOtherAccountByPhone`,
unbindAccounts: `users/users/user/unbindAccounts`,
logout: `users/users/user/logout`,
checkUserNameOrWorkNumber: `users/users/batchProcessing/checkUserNameOrWorkNumber`,
updateUserNameOrWorkNumber: `users/users/batchProcessing/updateUserNameOrWorkNumber`,
// 加密货币
market: `/topic/market`,
@ -54,7 +56,7 @@ export default {
deleteProfile: `users/users/userInfo/deleteProfile`,
checkEmailOrPhone: `occupationlab/occupationlab/architecture/checkEmailOrPhone`,
accountIsDisabled: `users/users/user/accountIsDisabled`,
userTemplate: `http://121.37.12.51/template/%E6%95%B0%E6%8D%AE%E5%B9%B3%E5%8F%B0%E7%94%A8%E6%88%B7%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx`,
userTemplate: `https://www.dataforward.cn/template/%E6%95%B0%E6%8D%AE%E5%B9%B3%E5%8F%B0%E7%94%A8%E6%88%B7%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx`,
// 角色管理
batchRemove: `users/users/role/batchRemove`,

@ -21,7 +21,9 @@
<img v-if="item.coverUrl" :src="item.coverUrl" alt="" class="cover">
<ul class="detail">
<li v-for="(item, i) in item.logContents" :key="i">
<p class="name"><img :src="require('@/assets/img/' + funcList.find(e => e.id === item.type).icon + '.png')" alt=""> {{ funcList.find(e => e.id === item.type).name }}</p>
<p class="name"><img
:src="require('@/assets/img/' + funcList.find(e => e.id === item.type).icon + '.png')" alt=""> {{
funcList.find(e => e.id === item.type).name }}</p>
<div class="val">
<p v-for="(item, i) in item.content" :key="i">{{ i + 1 }}{{ item }}</p>
</div>
@ -35,6 +37,21 @@
</div>
</div>
</div>
<el-dialog title="" :visible.sync="realNameVisible" :close-on-click-modal="false" :close-on-press-escape="false"
:show-close="false" width="300px" custom-class="name-dia">
<el-form ref="realNameForm" :model="realNameForm" :rules="realNameRules" label-width="80px">
<el-form-item label="真实姓名" prop="userName">
<el-input v-model.trim="realNameForm.userName" placeholder="请输入真实姓名"></el-input>
</el-form-item>
<el-form-item label="学号" prop="workNumber">
<el-input v-model.trim="realNameForm.workNumber" placeholder="请输入学号"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="realNameSubmit"> </el-button>
</span>
</el-dialog>
</div>
</template>
@ -45,7 +62,7 @@ import { mapState, mapMutations, mapActions } from 'vuex'
import Setting from '@/setting'
import util from '@/libs/util'
export default {
data() {
data () {
return {
logVisible: false,
list: [],
@ -66,7 +83,18 @@ export default {
name: '优化',
icon: 'optimize'
}
]
],
realNameVisible: false,
realNameForm: {
userName: '',
workNumber: '',
},
realNameRules: {
userName: [
{ required: true, message: '请输入真实姓名', trigger: 'blur' }
],
},
};
},
components: {
@ -78,9 +106,10 @@ export default {
'logView'
])
},
mounted() {
mounted () {
this.autoLogout()
this.logView || this.getLogStatus() // logViewfalse
this.handleRealName()
},
methods: {
...mapMutations("user", [
@ -89,8 +118,16 @@ export default {
...mapActions('user', [
'logout'
]),
//
async handleRealName () {
const res = await this.$post(this.api.checkUserNameOrWorkNumber)
//
if (res.hasName) {
this.realNameVisible = true
}
},
//
getLog() {
getLog () {
this.$get(`${this.api.platformLogList}?platformId=${Setting.platformId}&port=1&versionName=`).then(({ logList }) => {
logList.map((e, i) => {
e.logContents.map(n => {
@ -98,10 +135,10 @@ export default {
})
})
this.list = logList
}).catch(res => {})
}).catch(res => { })
},
//
getLogStatus() {
getLogStatus () {
util.local.get(Setting.tokenKey) && this.$get(this.api.logNotification, {
platformId: Setting.platformId
}).then(({ notification }) => {
@ -110,10 +147,10 @@ export default {
this.logVisible = true // true
this.getLog()
}
}).catch(res => {})
}).catch(res => { })
},
// ,退
autoLogout() {
autoLogout () {
let lastTime = new Date().getTime()
document.onmousedown = () => {
lastTime = new Date().getTime()
@ -126,17 +163,31 @@ export default {
setTimeout(this.logout, 1500)
}
}, 1000)
},
//
realNameSubmit () {
this.$refs.realNameForm.validate(async (valid) => {
if (valid) {
const form = this.realNameForm
await this.$post(`${this.api.updateUserNameOrWorkNumber}?userName=${form.userName}&workNumber=${form.workNumber}`)
this.realNameVisible = false
} else {
return false
}
})
},
}
};
</script>
<style lang="scss" scoped>
.main{
.main {
min-height: calc(100% - 64px);
.layout{
.layout {
padding-top: 64px;
}
.view{
.view {
min-width: $min-width;
min-height: calc(100vh - 134px);
padding: 12px 80px 0;
@ -148,10 +199,12 @@ export default {
url(../../assets/img/shapes/shape9.png) right 645px no-repeat,
url(../../assets/img/shapes/shape6.png) 0 1074px no-repeat;
}
.index{
.index {
padding: 0;
}
}
.log-mask {
position: fixed;
top: 0;
@ -160,6 +213,7 @@ export default {
right: 0;
background-color: rgba(0, 0, 0, .4);
}
/deep/.log-dia {
z-index: 11;
position: absolute;
@ -169,10 +223,12 @@ export default {
transform: translateX(-50%);
background-color: #fff;
border-radius: 6px;
.bg1 {
width: 100%;
height: 140px;
}
.bg2 {
position: absolute;
top: -130px;
@ -180,6 +236,7 @@ export default {
max-width: 100%;
height: 250px;
}
.log-title {
position: absolute;
top: 65px;
@ -190,53 +247,64 @@ export default {
color: #fff;
font-weight: 600;
}
.log-wrap {
padding-bottom: 30px;
}
.logs {
max-height: 250px;
padding: 0 100px;
margin: 30px 0;
overflow: auto;
}
h6 {
margin-bottom: 15px;
font-size: 16px;
color: #333;
line-height: 1;
}
.more-wrap {
padding: 0 60px;
font-size: 14px;
color: #333;
text-align: center;
}
.know {
margin-top: 15px;
}
.cover {
max-width: 250px;
max-height: 160px;
margin: 10px 0 20px;
}
.detail {
li {
margin-bottom: 20px;
}
.name {
display: flex;
align-items: center;
margin-bottom: 5px;
font-size: 14px;
img {
width: 20px;
margin-right: 8px;
}
}
.val {
font-size: 15px;
line-height: 1.8;
white-space: pre-wrap;
p {
position: relative;
font-size: 13px;
@ -245,4 +313,14 @@ export default {
}
}
}
/deep/.name-dia {
.el-dialog__header {
display: none;
}
.el-dialog__body {
padding-bottom: 10px;
}
}
</style>

@ -12,8 +12,7 @@
<div v-show="!form.distinguish && !verCodeLogin" class="items">
<el-form-item class="flex-1" prop="workNumber">
<label class="label account"></label>
<el-input v-model.trim="form.workNumber" placeholder="请输入学号/工号/手机号/邮箱"
@keyup.enter.native="submit"></el-input>
<el-input v-model.trim="form.workNumber" placeholder="请输入学号/工号" @keyup.enter.native="submit"></el-input>
</el-form-item>
</div>
<!-- 手机号登录 -->
@ -52,7 +51,7 @@
</template>
<div class="bottom">
<el-link :underline="false" type="primary" @click="switchType">{{ verCodeLogin ? '密码' : '验证码' }}登录</el-link>
<el-link :underline="false" type="primary" @click="toAccount">没有账号点击申请</el-link>
<!-- <el-link :underline="false" type="primary" @click="toAccount">没有账号点击申请</el-link> -->
</div>
<el-button class="submit" type="primary" @click="submit">登录</el-button>
</el-form>

@ -1,7 +1,8 @@
<template>
<div class="wrap">
<div class="left">
<el-menu class="menu" ref="type" @open="selectType" @select="selectType" unique-opened :default-active="defaultType" :default-openeds="defaultOpenType">
<el-menu class="menu" ref="type" @open="selectType" @select="selectType" unique-opened
:default-active="defaultType" :default-openeds="defaultOpenType">
<menuTree :menuList="typeList"></menuTree>
</el-menu>
</div>
@ -14,17 +15,19 @@
<img src="../../../assets/img/search-gray.png" alt="" class="search-icon">
</div>
</div>
<div class="desc">{{introduce}}</div>
<div class="source"><img src="@/assets/img/data2.png" alt=""> 数据来源{{dataSource}}</div>
<div class="desc">{{ introduce }}</div>
<div class="source"><img src="@/assets/img/data2.png" alt=""> 数据来源{{ dataSource }}</div>
<div class="page-content">
<el-table :data="listData" class="table" ref="table" stripe header-align="center" row-key="id" highlight-current-row @current-change="previewCurrentChange">
<el-table :data="listData" class="table" ref="table" stripe header-align="center" row-key="id"
highlight-current-row @current-change="previewCurrentChange">
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="showName" label="数据表名称" min-width="220" align="center" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="showName" label="数据表名称" min-width="220" align="center"
:show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="dataTotal" label="数据总量" width="90" align="center"></el-table-column>
<el-table-column prop="timeRange" label="起止时间" width="175" align="center"></el-table-column>
<el-table-column prop="dataSize" label="数据大小" width="90" align="center">
<template slot-scope="scope">
{{scope.row.dataSize}}M
{{ scope.row.dataSize }}M
</template>
</el-table-column>
<el-table-column prop="updateTime" label="更新时间" width="155" align="center"></el-table-column>
@ -36,31 +39,38 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next, jumper" :total="total"></el-pagination>
<el-pagination background @current-change="handleCurrentChange" :current-page="page"
layout="total, prev, pager, next, jumper" :total="total"></el-pagination>
</div>
</div>
</div>
</div>
<el-dialog title="下载" :visible.sync="downloadVisible" width="540px" @close="closeDownload" :close-on-click-modal="false">
<el-dialog title="下载" :visible.sync="downloadVisible" width="540px" @close="closeDownload"
:close-on-click-modal="false">
<el-form ref="form" label-width="100px" label-suffix="">
<el-form-item label="数据筛选">
<div class="checkboxs">
<el-checkbox v-model="checkAllFields" @change="checkAllFieldsChange">全选</el-checkbox>
<el-checkbox-group v-model="fields">
<el-checkbox v-for="(item,index) in fieldsList" :key="index" :label="item.comment"></el-checkbox>
<el-checkbox v-for="(item, index) in fieldsList" :key="index" :label="item.comment"></el-checkbox>
</el-checkbox-group>
</div>
</el-form-item>
<el-form-item label="开始时间">
<el-date-picker v-model="startTime" type="date" placeholder="请选择开始时间" size="small" format="yyyy-MM-dd" value-format="yyyy-MM-dd" :picker-options="timeOptions" :disabled="startTimeDisabled" :default-value="startTimeDefault" @change="timeChange"></el-date-picker>
<el-date-picker v-model="startTime" type="date" placeholder="请选择开始时间" size="small" format="yyyy-MM-dd"
value-format="yyyy-MM-dd" :picker-options="timeOptions" :disabled="startTimeDisabled"
:default-value="startTimeDefault" @change="timeChange"></el-date-picker>
</el-form-item>
<el-form-item label="结束时间">
<el-date-picker v-model="endTime" type="date" placeholder="请选择结束时间" size="small" format="yyyy-MM-dd" value-format="yyyy-MM-dd" :picker-options="timeOptions" :disabled="endTimeDisabled" :default-value="endTimeDefault" @change="timeChange"></el-date-picker>
<el-date-picker v-model="endTime" type="date" placeholder="请选择结束时间" size="small" format="yyyy-MM-dd"
value-format="yyyy-MM-dd" :picker-options="timeOptions" :disabled="endTimeDisabled"
:default-value="endTimeDefault" @change="timeChange"></el-date-picker>
</el-form-item>
<el-form-item label="数据频率">
<el-select v-model="frequency" placeholder="请选择数据频率" size="small">
<el-option v-for="(item,index) in frequencyList" :key="index" :label="item.name" :value="item.id"></el-option>
<el-option v-for="(item, index) in frequencyList" :key="index" :label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-form>
@ -71,11 +81,7 @@
</span>
</el-dialog>
<el-drawer
custom-class="preview-dia"
size="950px"
:with-header="false"
:visible.sync="previewVisible">
<el-drawer custom-class="preview-dia" size="950px" :with-header="false" :visible.sync="previewVisible">
<div class="flex j-between">
<div class="l-title" style="margin-bottom: 0">
<img src="@/assets/img/data3.png" alt="">
@ -86,7 +92,8 @@
<div class="preview-wrap">
<el-table :data="previewData" class="table" id="previewTable" stripe header-align="center" row-key="id">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column v-for="(item,index) in previewHead" :prop="item.field" :key="index" :label="item.comment" align="center"></el-table-column>
<el-table-column v-for="(item, index) in previewHead" :prop="item.field" :key="index" :label="item.comment"
align="center"></el-table-column>
</el-table>
</div>
</el-drawer>
@ -105,7 +112,7 @@ export default {
components: {
menuTree
},
data() {
data () {
return {
that: this,
token: util.local.get(Setting.tokenKey),
@ -140,7 +147,7 @@ export default {
startTimeDefault: '',
endTimeDefault: '',
timeOptions: {
disabledDate(time) {
disabledDate (time) {
return time.getTime() < startTimeLimit || time.getTime() > endTimeLimit
},
},
@ -173,7 +180,7 @@ export default {
]),
},
watch: {
keyword: function(val) {
keyword: function (val) {
clearTimeout(this.searchTimer)
if (!this.rendered) {
this.searchTimer = setTimeout(() => {
@ -183,7 +190,7 @@ export default {
this.rendered = false
},
},
mounted() {
mounted () {
this.getType()
// ,
if (this.$route.query.download) {
@ -195,7 +202,7 @@ export default {
}
},
methods: {
getType() {
getType () {
//
this.$post(this.api.getTableByClassification).then(res => {
let typeId = this.typeId // id
@ -204,7 +211,7 @@ export default {
let action
let isFirst = true //
//
function actionId(arr) {//res
function actionId (arr) {//res
arr && arr.map((e, i) => {
e.id = String(e.id)
if (!i && isFirst) {
@ -237,7 +244,7 @@ export default {
this.getData()
}).catch(res => { })
},
getData() {
getData () {
this.$post(`${this.api.getIdQueryTable}?categoryId=${this.defaultType}&showName=${this.keyword}&pageNum=${this.page}&pageSize=${this.pageSize}&updateTime=`).then(res => {
const list = res.pageList.records
list.map(e => {
@ -262,26 +269,26 @@ export default {
})
this.$router.replace('list')
}
}).catch(res => {})
}).catch(res => { })
},
initData() {
initData () {
this.page = 1
this.getData()
},
handleCurrentChange(val) {
handleCurrentChange (val) {
this.page = val
this.$refs.table.clearSelection()
this.getData()
},
//
selectType(index, indexPath) {
selectType (index, indexPath) {
let introduce = ''
let dataSource = ''
this.keyword = ''
let list = this.typeList
let select = ''
// id
function getDeepest(data) {
function getDeepest (data) {
if (data[0].children && data[0].children.length) {
getDeepest(data[0].children)
} else {
@ -290,7 +297,7 @@ export default {
if (data[0].dataSource) dataSource = data[0].dataSource
}
}
function handleData(data) {
function handleData (data) {
data.map((n, i) => {
//
if (n.id == index) {
@ -317,10 +324,10 @@ export default {
this.previewData = []
this.initData()
},
previewCurrentChange(val) {
previewCurrentChange (val) {
this.currentRow = val
},
preview(row) {
preview (row) {
this.$get(`${this.api.previewData}?tableName=${row.name}&tableId=${row.id}`).then(res => {
// +1
this.$post(this.api.saveRecord, {
@ -347,11 +354,11 @@ export default {
this.previewVisible = true
}).catch(res => { })
},
checkAllFieldsChange(val) {
checkAllFieldsChange (val) {
this.fields = val ? this.fieldsList.map(n => n.comment) : []
},
//
download(row) {
download (row) {
// ,
this.$get(`${this.api.isDownload}`, {
tableId: row.id,
@ -386,11 +393,11 @@ export default {
}).catch(res => { })
},
//
timeChange() {
timeChange () {
//
if (this.startTime && this.endTime && new Date(this.startTime) > new Date(this.endTime)) util.warningMsg('结束时间不能小于开始时间')
},
closeDownload() {
closeDownload () {
this.checkAllFields = false
this.fields = []
this.startTime = ''
@ -398,7 +405,7 @@ export default {
this.frequency = ''
this.$router.push('/data').catch(err => { })
},
confirmDown() {
confirmDown () {
let fields = this.fields
if (!fields.length) return util.warningMsg('请选择字段')
if (!this.startTime) return util.warningMsg('请选择开始时间')
@ -483,69 +490,85 @@ export default {
</script>
<style lang="scss" scoped>
.wrap{
.wrap {
display: flex;
padding-bottom: 20px !important;
/deep/.left{
/deep/.left {
width: 239px;
height: calc(100vh - 190px);
margin-right: 20px;
overflow: auto;
&::-webkit-scrollbar {
display: none;
width: 8px;
height: 8px;
}
&::-webkit-scrollbar-thumb {
display: none;
width: 5px;
border-radius: 6px;
background: rgba(173,173,173,.7);
background: rgba(173, 173, 173, .7);
}
.menu{
.menu {
width: 240px;
overflow: hidden;
&>.el-menu-item,.el-submenu__title{
span{
&>.el-menu-item,
.el-submenu__title {
span {
font-size: 15px;
color: #3381d2;
}
}
&>.el-submenu>.el-menu{
&>.el-submenu>.el-menu {
background-color: #FAFAFA !important;
}
.el-submenu__title i{
.el-submenu__title i {
font-size: 14px;
}
.el-submenu .el-menu{
.el-submenu .el-menu {
background-color: #fff;
}
.el-submenu.is-active{
.el-submenu__title{
&+.el-menu .el-submenu__title{
.el-submenu.is-active {
.el-submenu__title {
&+.el-menu .el-submenu__title {
height: 50px;
line-height: 50px;
background-color: rgba(147,184,255,.15);
background-color: rgba(147, 184, 255, .15);
}
i{
i {
color: #006EFF;
}
}
}
.el-menu-item{
.el-menu-item {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&.is-active{
&.is-active {
color: #fff;
background-color: #0070FF;
span {
color: #fff;
}
}
}
.level-6 {
padding-right: 0;
.el-submenu__title {
padding-left: 10px !important;
color: #fff;
@ -553,28 +576,34 @@ export default {
}
}
}
.right{
.right {
width: calc(100% - 260px);
.page{
.page {
margin-bottom: 20px;
.source {
margin-bottom: 12px;
color: #7EB1F3;
}
}
}
/deep/.el-table__body tr.current-row > td{
/deep/.el-table__body tr.current-row>td {
background-color: #daeaff;
}
.desc{
.desc {
padding: 9px 12px;
margin: 20px 0 10px;
font-size: 12px;
color: #333;
background-color: #FAFAFA;
}
}
.search{
}
.search {
z-index: 2;
position: absolute;
top: 10px;
@ -590,32 +619,46 @@ export default {
border: 1px solid #e6e6e6;
border-radius: 5px;
input{
input {
width: 260px;
margin-left: 10px;
font-size: 14px;
color: #333;
background-color: transparent;
border: 0;
&::-webkit-input-placeholder{color: #999}
&::-moz-placeholder{color: #999}
&:-moz-placeholder{color: #999}
&:focus{
&::-webkit-input-placeholder {
color: #999
}
&::-moz-placeholder {
color: #999
}
&:-moz-placeholder {
color: #999
}
&:focus {
outline: none;
}
}
.remove{
.remove {
cursor: pointer;
}
.search-icon{
.search-icon {
width: 18px;
}
}
/deep/.preview-dia{
}
/deep/.preview-dia {
padding: 20px;
.preview-wrap{
.preview-wrap {
height: calc(100vh - 80px);
overflow: auto;
}
}
}
</style>

@ -8,26 +8,31 @@
<li>
<label>创建时间</label>
<el-select v-model="month" placeholder="请选择创建时间" size="small" clearable class="flex-1">
<el-option v-for="(item,index) in monthList" :key="index" :label="item.label" :value="item.id"></el-option>
<el-option v-for="(item, index) in monthList" :key="index" :label="item.label"
:value="item.id"></el-option>
</el-select>
</li>
<li>
<label>时间范围</label>
<el-date-picker v-model="date" align="right" unlink-panels type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable size="small"></el-date-picker>
<el-date-picker v-model="date" align="right" unlink-panels type="daterange" start-placeholder="开始日期"
end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable
size="small"></el-date-picker>
</li>
<li>
<label>角色</label>
<el-select v-model="role" placeholder="请选择角色" size="small" clearable class="flex-1" @change="initData">
<el-option label="不限" value=""></el-option>
<template v-for="(item, index) in roleList">
<el-option v-if="item.roleName != '超级管理员'" :key="index" :label="item.roleName" :value="item.id"></el-option>
<el-option v-if="item.roleName != '超级管理员'" :key="index" :label="item.roleName"
:value="item.id"></el-option>
</template>
</el-select>
</li>
<li>
<label>状态</label>
<el-select v-model="status" placeholder="请选择状态" size="small" clearable class="flex-1" @change="initData">
<el-option v-for="(item,index) in statusList" :key="index" :label="item.label" :value="item.id"></el-option>
<el-option v-for="(item, index) in statusList" :key="index" :label="item.label"
:value="item.id"></el-option>
</el-select>
</li>
</ul>
@ -41,7 +46,8 @@
<ul class="filter">
<li style="margin-bottom: 0">
<label>搜索</label>
<el-input style="width: 250px" placeholder="请输入员工姓名/工号" v-model="keyword" suffix-icon="el-icon-search" clearable size="small"></el-input>
<el-input style="width: 250px" placeholder="请输入员工姓名/工号" v-model="keyword" suffix-icon="el-icon-search"
clearable size="small"></el-input>
</li>
</ul>
<div>
@ -52,7 +58,8 @@
</div>
</div>
<el-table :data="listData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table :data="listData" class="table" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="80" align="center"></el-table-column>
<el-table-column type="index" label="序号" width="55" align="center">
</el-table-column>
@ -60,13 +67,13 @@
<el-table-column prop="workNumber" label="工号/学号" align="center"></el-table-column>
<el-table-column label="权限状态" align="center">
<template slot-scope="scope">
{{scope.row.isEnable ? '启用' : '禁用'}}
{{ scope.row.isEnable ? '启用' : '禁用' }}
</template>
</el-table-column>
<el-table-column prop="roleName" label="账号角色" align="center"></el-table-column>
<el-table-column prop="loginNumber" label="登录次数" align="center">
<template slot-scope="scope">
{{scope.row.loginNumber ? scope.row.loginNumber : 0}}
{{ scope.row.loginNumber ? scope.row.loginNumber : 0 }}
</template>
</el-table-column>
<el-table-column prop="lastLoginTime" label="上次登录时间" width="160" align="center"></el-table-column>
@ -76,16 +83,20 @@
<el-button type="text" @click="edit(scope.row)" v-auth>编辑</el-button>
<el-button type="text" @click="resetPassword(scope.row)" v-auth>重置密码</el-button>
<el-button type="text" @click="handleDelete(scope.row)" v-auth>删除</el-button>
<el-switch v-model="scope.row.isEnable" :active-value="1" :inactive-value="0" style="margin: 0 10px 0 5px" :active-text="scope.row.isEnable ? '开' : '关'" @change="switchOff($event,scope.row,scope.$index)" v-auth="'/user/list:禁用'"></el-switch>
<el-switch v-model="scope.row.isEnable" :active-value="1" :inactive-value="0" style="margin: 0 10px 0 5px"
:active-text="scope.row.isEnable ? '开' : '关'" @change="switchOff($event, scope.row, scope.$index)"
v-auth="'/user/list:禁用'"></el-switch>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total,prev, pager, next" :current-page="page" @current-change="handleCurrentChange" :total="total"></el-pagination>
<el-pagination background layout="total,prev, pager, next" :current-page="page"
@current-change="handleCurrentChange" :total="total"></el-pagination>
</div>
</div>
<el-dialog :title="isDetail ? '查看账号' : (form.userId ? '编辑账号' : '新增账号')" :visible.sync="userVisible" width="576px" @close="closeUser" class="dialog" :close-on-click-modal="false">
<el-dialog :title="isDetail ? '查看账号' : (form.userId ? '编辑账号' : '新增账号')" :visible.sync="userVisible" width="576px"
@close="closeUser" class="dialog" :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="110px" label-suffix="" :disabled="isDetail">
<el-form-item prop="workNumber" label="工号/学号">
<el-input v-model="form.workNumber" placeholder="请输入工号/学号" @change="workNumberChange"></el-input>
@ -96,8 +107,9 @@
<el-form-item prop="roleIds" label="账号角色">
<div class="role-wrap">
<el-checkbox-group v-model="form.roleIds">
<template v-for="(item,index) in roleList">
<el-checkbox v-if="item.roleName != '超级管理员'" :key="index" :label="item.id" :title="item.roleName">{{item.roleName}}</el-checkbox>
<template v-for="(item, index) in roleList">
<el-checkbox v-if="item.roleName != '超级管理员'" :key="index" :label="item.id"
:title="item.roleName">{{ item.roleName }}</el-checkbox>
</template>
</el-checkbox-group>
</div>
@ -118,10 +130,14 @@
</span>
</el-dialog>
<el-dialog title="批量导入" :visible.sync="importVisible" width="400px" @close="closeImport" :close-on-click-modal="false">
<div class="upload-wrap" :class="{lg: uploadFaild}">
<el-button class="download" size="small" @click="downLoad"><img src="../../../assets/img/download.png" alt=""> 模板下载</el-button>
<el-upload ref="import" accept=".xls,.xlsx" :headers="{token}" :on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed" :action="this.api.uploadFile" :file-list="uploadList" :data="{schoolId: this.schoolId}" name="file">
<el-dialog title="批量导入" :visible.sync="importVisible" width="400px" @close="closeImport"
:close-on-click-modal="false">
<div class="upload-wrap" :class="{ lg: uploadFaild }">
<el-button class="download" size="small" @click="downLoad"><img src="../../../assets/img/download.png" alt="">
模板下载</el-button>
<el-upload ref="import" accept=".xls,.xlsx" :headers="{ token }" :on-remove="handleRemove" :on-error="uploadError"
:on-success="uploadSuccess" :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed"
:action="this.api.uploadFile" :file-list="uploadList" :data="{ schoolId: this.schoolId }" name="file">
<el-button size="small"><img src="../../../assets/img/upload.png" alt=""> 上传文件</el-button>
</el-upload>
<div class="link" v-if="uploadFaild">
@ -141,7 +157,7 @@ import { mapState } from 'vuex'
import util from '@/libs/util'
import axios from 'axios'
export default {
data() {
data () {
return {
token: util.local.get(Setting.tokenKey),
month: '',
@ -149,13 +165,13 @@ export default {
{
id: '',
label: '不限'
},{
}, {
id: 3,
label: '近3个月'
},{
}, {
id: 6,
label: '近6个月'
},{
}, {
id: 12,
label: '近1年'
}
@ -169,10 +185,10 @@ export default {
{
id: '',
label: '不限'
},{
}, {
id: 1,
label: '启用'
},{
}, {
id: 0,
label: '禁用'
}
@ -253,39 +269,39 @@ export default {
]),
},
watch: {
keyword: function(val) {
keyword: function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
},500)
}, 500)
},
month: function(val){
if(val){
month: function (val) {
if (val) {
let unit = 24 * 60 * 60 * 1000
this.date = [util.formatDate('yyyy-MM-dd',new Date(new Date().getTime() - unit * 30 * val)),util.formatDate('yyyy-MM-dd',new Date(new Date().getTime() + unit))]
}else{
this.date = [util.formatDate('yyyy-MM-dd', new Date(new Date().getTime() - unit * 30 * val)), util.formatDate('yyyy-MM-dd', new Date(new Date().getTime() + unit))]
} else {
this.date = []
}
},
date: function(val){
if(val && val.length){
date: function (val) {
if (val && val.length) {
this.startTime = val[0]
this.endTime = val[1]
}else{
} else {
this.startTime = ''
this.endTime = ''
}
this.initData()
}
},
mounted(){
mounted () {
this.form.schoolId = this.schoolId
this.getData()
this.getRole()
},
methods: {
getData(){
this.$post(this.api.getUserList,{
getData () {
this.$post(this.api.getUserList, {
createTime: this.startTime,
isEnable: this.status,
endTime: this.endTime,
@ -298,82 +314,82 @@ export default {
const { records, total } = pageList
this.listData = records
this.total = total
if(!records.length && total){
if (!records.length && total) {
this.page--
this.getData()
}
}).catch(res => {})
}).catch(res => { })
},
initData(){
initData () {
this.page = 1
this.getData()
},
//
getRole(){
getRole () {
this.$get(`${this.api.listRole}?page=1&size=1000&name=&platformId=${Setting.platformId}&port=0`).then(res => {
const list = res.rolePage.records
this.roleList = list
}).catch(res => {})
}).catch(res => { })
},
resetPassword(row){
resetPassword (row) {
this.$confirm(`重置后的密码为:${Setting.initialPassword},确定重置?`, '提示', {
type: 'info',
customClass: 'normal'
}).then(() => {
this.$get(this.api.resetPwd,{
this.$get(this.api.resetPwd, {
newPwd: Setting.initialPassword,
userId: row.userId,
}).then(res => {
if(res.message == 'success'){
if (res.message == 'success') {
this.$message.success('重置成功')
}else{
} else {
this.$message.error('重置失败')
}
}).catch(res => {})
}).catch(() => {})
}).catch(res => { })
}).catch(() => { })
},
//
renderAccount() {
renderAccount () {
const form = this.form
// id-id-schoolId-workNumber
form.account = `${Setting.platformId}-${Setting.platformType}-${this.schoolId}-${form.workNumber}`
},
workNumberChange(){
if(this.form.workNumber && this.form.workNumber !== this.originalWorkNumber){
workNumberChange () {
if (this.form.workNumber && this.form.workNumber !== this.originalWorkNumber) {
this.$post(`${this.api.checkAccount}?workNumber=${this.form.workNumber}&type=2&platformId=${Setting.platformId}`).then(res => {
this.workNumberRepeat = false
this.renderAccount()
}).catch(res => {
this.workNumberRepeat = true
})
}else{
} else {
this.workNumberRepeat = false
this.renderAccount()
}
},
phoneChange(){
if(this.form.phone && this.form.phone !== this.originalPhone){
phoneChange () {
if (this.form.phone && this.form.phone !== this.originalPhone) {
this.$post(`${this.api.checkEmailOrPhone}?phone=${this.form.phone}${this.form.accountId ? '&accountId=' + this.form.accountId : ''}`).then(res => {
this.phoneRepeat = false
}).catch(res => {
this.phoneRepeat = true
})
}else{
} else {
this.phoneRepeat = false
}
},
emailChange(){
if(this.form.email && this.form.email !== this.originalEmail){
emailChange () {
if (this.form.email && this.form.email !== this.originalEmail) {
this.$post(`${this.api.checkEmailOrPhone}?email=${this.form.email}${this.form.accountId ? '&accountId=' + this.form.accountId : ''}`).then(res => {
this.emailRepeat = false
}).catch(res => {
this.emailRepeat = true
})
}else{
} else {
this.emailRepeat = false
}
},
closeUser(){
closeUser () {
this.$refs.form.resetFields()
this.form.userId = ''
this.form.accountId = ''
@ -381,11 +397,11 @@ export default {
this.accountRepeat = false
this.workNumberRepeat = false
},
add(){
add () {
this.isDetail = false
this.userVisible = true
},
getDetail(accountId){
getDetail (accountId) {
this.userVisible = true
this.$post(`${this.api.getDetail}?accountId=${accountId}`).then(res => {
let data = res.data
@ -407,33 +423,33 @@ export default {
this.originalWorkNumber = data.workNumber
this.originalPhone = data.phone
this.originalEmail = data.email
}).catch(res => {})
}).catch(res => { })
},
edit(row){
edit (row) {
this.isDetail = false
this.getDetail(row.accountId)
},
show(row){
show (row) {
this.isDetail = true
this.getDetail(row.accountId)
},
confirm(){
confirm () {
this.$refs.form.validate((valid) => {
if (valid) {
if (this.submiting) return false
if(this.accountRepeat) return util.errorMsg('该账号已存在!')
if(this.workNumberRepeat) return util.errorMsg('该学号/工号已存在!')
if(this.phoneRepeat) return util.errorMsg('该手机号已存在!')
if(this.emailRepeat) return util.errorMsg('该邮箱已存在!')
if (this.accountRepeat) return util.errorMsg('该账号已存在!')
if (this.workNumberRepeat) return util.errorMsg('该学号/工号已存在!')
if (this.phoneRepeat) return util.errorMsg('该手机号已存在!')
if (this.emailRepeat) return util.errorMsg('该邮箱已存在!')
let data = this.form
// ,schoolId
data.schoolId = data.schoolId ? data.schoolId : this.schoolId
// ,
if(!data.userId) data.uniqueIdentification = new Date().getTime()
if(!data.roleIds.length) return util.errorMsg('请至少选择一个角色')
if (!data.userId) data.uniqueIdentification = new Date().getTime()
if (!data.roleIds.length) return util.errorMsg('请至少选择一个角色')
this.submiting = true
if(this.form.userId){
this.$post(this.api.modifyUser,data).then(res => {
if (this.form.userId) {
this.$post(this.api.modifyUser, data).then(res => {
this.userVisible = false
util.successMsg('编辑成功')
this.getData()
@ -441,8 +457,8 @@ export default {
}).catch(res => {
this.submiting = false
})
}else{
this.$post(this.api.saveUser,data).then(res => {
} else {
this.$post(this.api.saveUser, data).then(res => {
this.userVisible = false
util.successMsg('添加成功')
this.getData()
@ -454,20 +470,20 @@ export default {
}
})
},
handleDelete(row){
handleDelete (row) {
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.deleteUser}?accountIds=${row.accountId}`).then(res => {
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
}).catch(() => {})
}).catch(res => { })
}).catch(() => { })
},
switchOff(val,row,index) {
switchOff (val, row, index) {
this.$post(`${this.api.getDetail}?accountId=${row.accountId}`).then(res => {
const { data } = res
this.$post(this.api.modifyUser,{
this.$post(this.api.modifyUser, {
account: row.account,
accountId: row.accountId,
isEnable: val,
@ -484,13 +500,13 @@ export default {
}).catch((res) => {
row.isEnable = val == 1 ? 0 : 1
})
}).catch(res => {})
}).catch(res => { })
},
handleSelectionChange(val) {
handleSelectionChange (val) {
this.multipleSelection = val
},
delAllSelection() {
if(this.multipleSelection.length != ''){
delAllSelection () {
if (this.multipleSelection.length != '') {
let newArr = this.multipleSelection
let delList = newArr.map(item => {
return `accountIds=${item.accountId}`
@ -502,71 +518,71 @@ export default {
this.$refs.table.clearSelection()
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
}).catch(() => {})
}else{
}).catch(res => { })
}).catch(() => { })
} else {
util.errorMsg('请先选择数据 !')
}
},
batchImport(){
batchImport () {
this.importVisible = true
this.uploadList = []
this.uploadFaild = false
},
handleCurrentChange(val) {
handleCurrentChange (val) {
this.page = val
this.$refs.table.clearSelection()
this.getData()
},
downLoad(){
downLoad () {
location.href = `${this.api.userTemplate}?id=${Math.random()}`
},
showFaild(){
showFaild () {
this.importVisible = false
axios.get(`${this.api.export_failure}?token=${this.importToken}`,{
axios.get(`${this.api.export_failure}?token=${this.importToken}`, {
headers: {
token: this.token
},
responseType: 'blob'
}).then((res) => {
util.downloadFileDirect(`导入失败原因.xlsx`,new Blob([res.data]))
}).catch(res => {})
util.downloadFileDirect(`导入失败原因.xlsx`, new Blob([res.data]))
}).catch(res => { })
},
handleExceed(files, fileList) {
handleExceed (files, fileList) {
util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
);
},
uploadSuccess(res, file, fileList) {
uploadSuccess (res, file, fileList) {
this.uploadFaild = false
if(res.status == 200){
if(res.data.token){
if (res.status == 200) {
if (res.data.token) {
util.errorMsg('导入失败,请下载失败模板查看原因')
this.importToken = res.data.token
this.uploadFaild = true
}
}else{
} else {
res.data.message ? util.errorMsg(res.data.message) : util.errorMsg('上传失败,请检查数据')
}
},
uploadError(err, file, fileList) {
uploadError (err, file, fileList) {
this.$message({
message: "上传出错,请重试!",
type: "error",
center: true
});
},
beforeRemove(file, fileList) {
beforeRemove (file, fileList) {
return this.$confirm(`确定移除 ${file.name}`);
},
handleRemove(file, fileList) {
handleRemove (file, fileList) {
this.uploadList = fileList
this.uploadFaild = false
},
closeImport(){
closeImport () {
this.uploadList = []
},
confirmImport(){
confirmImport () {
this.importVisible = false
this.initData()
}
@ -574,29 +590,36 @@ export default {
};
</script>
<style lang="scss" scoped>
.l-title{
.l-title {
margin-bottom: 24px;
}
.filter{
}
.filter {
flex-wrap: wrap;
li{
li {
width: 22%;
}
}
/deep/.dialog{
.el-form-item{
.el-form-item__label{
}
/deep/.dialog {
.el-form-item {
.el-form-item__label {
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
&:before{
&:before {
margin-right: 0;
color: #CC221C;
}
}
}
.el-input,.el-select{
.el-input,
.el-select {
width: 100%;
}
.role-wrap {
max-height: 130px;
padding: 10px 12px 0;
@ -604,16 +627,18 @@ export default {
border-radius: 4px;
overflow: auto;
}
.el-checkbox {
display: inline-flex;
width: 33.33%;
margin-right: 0;
}
.el-checkbox__label {
max-width: 108px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
</style>

@ -11,8 +11,9 @@ const url = location.host
const dev = process.env.NODE_ENV === 'development' // 本地
let host = `${location.origin}/`
if (dev) {
host = 'https://www.dataforward.cn/'
// host = 'http://192.168.31.51:9000/'
// host = 'https://www.dataforward.cn/'
// host = 'http://118.31.167.228/'
host = 'http://192.168.31.217:9000/'
}
const Setting = {

Loading…
Cancel
Save