data
This commit is contained in:
parent
06b55ff886
commit
ff00a718ea
|
@ -0,0 +1,254 @@
|
|||
<template>
|
||||
<div class="">
|
||||
<el-form ref="article" :model="article" :rules="rules">
|
||||
<div style="z-index: 1; height: 50px;">
|
||||
<div class="sub-navbar draft" style="top: 0px; z-index: 1;height: 45px;margin-top:-5px;">
|
||||
<button type="button" class="el-button el-button--success el-button--mini" style="margin-left: 10px;"><!----><!---->
|
||||
<span>发布</span>
|
||||
</button>
|
||||
<button type="button" class="el-button el-button--warning el-button--mini" @click="saveUEContent">
|
||||
<span>保存</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<el-form-item label="标题" label-width="120px" prop="title" style="margin-top:-5px">
|
||||
<el-input v-model="article.title" :rows="1" :minlength="4" :maxlength="50" type="text" placeholder="请输入标题(少于50字)" style="width:95%;"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="收件人" label-width="120px" style="margin-bottom:12px;">
|
||||
<el-button type="success" size="mini" @click="showSelectUser">收件人</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户上传附件:" label-width="120px" prop="upload" style="margin-top:-12px;">
|
||||
<el-radio-group v-model="article.upload">
|
||||
<el-radio :label="0">不支持上传</el-radio>
|
||||
<el-radio :label="1">支持上传</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="content" style="margin-top:-10px;">
|
||||
<div style="margin-left:15px;margin-right:25px;line-height:0px;">
|
||||
<vue-ueditor-wrap ref="ueditor" v-model="article.content" @ready="ready"/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-dialog :visible.sync="dialogFormVisible" title="收件人">
|
||||
<el-button type="success" size="mini" style="margin-top:-150px;" @click="selectUser">
|
||||
添加收件人
|
||||
</el-button>
|
||||
<el-table
|
||||
:data="article.receiverList"
|
||||
:height="300"
|
||||
border
|
||||
style="width:100%;overflow:auto;">
|
||||
<el-table-column :label="$t('id')" align="center" min-width="10%">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.$index + 1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="名称" min-width="30%" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="类型" min-width="30%" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.roles[0]==1">教师</span>
|
||||
<span v-if="scope.row.roles[0]==2">班级</span>
|
||||
<span v-if="scope.row.roles[0]==3">群组</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="!disabled" :label="$t('table.actions')" align="center" min-width="30%" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="danger" size="mini" @click="handleDeleteUser(scope.$index)">{{ $t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="dialogFormVisible = false">{{ $t('table.confirm') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<showUser v-if="hackReset" ref="showUser" @listenToChildEvent="getSelectUser"/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import VueUeditorWrap from 'vue-ueditor-wrap'
|
||||
import { saveArticle, fetchArticle } from '@/api/article'
|
||||
import { fetchTeacherList, fetchGroupList } from '@/api/user'
|
||||
import showUser from '@/views/notice/showUser'
|
||||
|
||||
export default {
|
||||
name: 'CreateForm',
|
||||
components: { VueUeditorWrap, showUser },
|
||||
data() {
|
||||
return {
|
||||
hackReset: false,
|
||||
disabled: false,
|
||||
dialogFormVisible: false,
|
||||
userList: [],
|
||||
articleId: this.$route.params.id,
|
||||
article: {
|
||||
id: undefined,
|
||||
fid: this.$store.state.user.fid,
|
||||
title: undefined,
|
||||
upload: 0,
|
||||
type: '',
|
||||
content: '',
|
||||
group: undefined,
|
||||
attachmentList: [],
|
||||
receiverList: [],
|
||||
status: 'published'
|
||||
},
|
||||
receiverList: [],
|
||||
listQuery: {
|
||||
fid: this.$store.state.user.fid,
|
||||
importance: undefined,
|
||||
name: undefined,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
input: '',
|
||||
users: undefined,
|
||||
groups: undefined,
|
||||
value7: '',
|
||||
rules: {
|
||||
title: [
|
||||
{ required: true, message: '请输入标题', trigger: 'blur' },
|
||||
{ min: 4, max: 50, message: '长度必须在4到50个字符之间', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchArticle()
|
||||
this.tempRoute = Object.assign({}, this.$route)
|
||||
},
|
||||
methods: {
|
||||
handleDeleteUser(index) {
|
||||
this.article.receiverList.splice(index, 1)
|
||||
},
|
||||
fetchArticle() {
|
||||
if (this.articleId) {
|
||||
fetchArticle(this.articleId).then(response => {
|
||||
if (response.data.code === 200) {
|
||||
this.article = response.data.result
|
||||
const route = Object.assign({}, this.tempRoute, { title: this.article.title })
|
||||
this.$store.dispatch('updateVisitedView', route)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
getSelectUser: function(data) {
|
||||
var tempList = []
|
||||
var userList = data.get('user')
|
||||
for (var index in userList) {
|
||||
var userReceiver = {}
|
||||
userReceiver.uid = userList[index].uid
|
||||
userReceiver.name = userList[index].name
|
||||
userReceiver.roles = [1]
|
||||
tempList.push(userReceiver)
|
||||
}
|
||||
var groupList = data.get('group')
|
||||
for (var i in groupList) {
|
||||
var groupReceiver = {}
|
||||
groupReceiver.uid = groupList[i].groupId
|
||||
groupReceiver.name = groupList[i].name
|
||||
groupReceiver.roles = [3]
|
||||
tempList.push(groupReceiver)
|
||||
}
|
||||
for (const v of tempList) {
|
||||
var flag = true
|
||||
for (const userData of this.article.receiverList) {
|
||||
if (v.uid === userData.uid && v.roles[0] === userData.roles[0]) {
|
||||
flag = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
this.article.receiverList.push(v)
|
||||
}
|
||||
}
|
||||
},
|
||||
showSelectUser() {
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
selectUser() {
|
||||
this.hackReset = false
|
||||
if (this.$refs.showUser) {
|
||||
this.$refs.showUser.handleModifyStatus()
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.hackReset = true
|
||||
})
|
||||
},
|
||||
getReceivers(name) {
|
||||
if (name !== '') {
|
||||
this.listQuery.name = name
|
||||
fetchTeacherList(this.listQuery).then(response => {
|
||||
var data = response.data
|
||||
if (data.code === 200 && data.result.total > 0) {
|
||||
this.users = [{
|
||||
label: '用户',
|
||||
options: data.result.list
|
||||
}]
|
||||
} else {
|
||||
this.users = []
|
||||
}
|
||||
})
|
||||
fetchGroupList(this.listQuery).then(response => {
|
||||
var data = response.data
|
||||
if (data.code === 200 && data.result.total > 0) {
|
||||
this.groups = [{
|
||||
label: '组名',
|
||||
options: response.data.result.list
|
||||
}]
|
||||
} else {
|
||||
this.groups = []
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.users = []
|
||||
this.groups = []
|
||||
}
|
||||
},
|
||||
ready(editorInstance) {
|
||||
console.log(`编辑器实例${editorInstance.key}: `, editorInstance)
|
||||
// setInterval(this.getUEContent,10000)
|
||||
},
|
||||
|
||||
getUEContent: function() {
|
||||
console.log(this.msg)
|
||||
},
|
||||
|
||||
draft: function() {
|
||||
console.log(this.msg)
|
||||
},
|
||||
|
||||
saveUEContent: function() {
|
||||
this.$refs['article'].validate((valid) => {
|
||||
if (valid) {
|
||||
saveArticle(this.article).then(() => {
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '保存成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
var path = this.$route
|
||||
var allOpenViews = this.$store.state.tagsView.visitedViews
|
||||
for (var index in allOpenViews) {
|
||||
if (allOpenViews[index].fullPath === path.fullPath) {
|
||||
this.$store.dispatch('delView', allOpenViews[index]).then(({ visitedViews }) => {
|
||||
this.$router.push({ path: '/notice/list' })
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
|
||||
</style>
|
|
@ -1,50 +1,95 @@
|
|||
<template>
|
||||
<el-row :gutter="40" class="panel-group">
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel" @click="handleSetLineChartData('newVisitis')">
|
||||
<div class="card-panel-icon-wrapper icon-people">
|
||||
<svg-icon icon-class="peoples" class-name="card-panel-icon" />
|
||||
<div>
|
||||
<el-row :gutter="50" class="panel-group">
|
||||
<el-col :lg="24" class="card-panel-col">
|
||||
<el-card class="box-card" style="background-color:#d9e8fb">
|
||||
<el-tabs type="border-card" style="margin-top:-10px;">
|
||||
<el-tab-pane label="教务通知">
|
||||
<div v-for="o in 20" :key="o" class="text item separatorLine">
|
||||
<a href="www.baidu.com">{{ '列表内容 ' + o }}</a>
|
||||
<span style="float:right">2018-11-22</span>
|
||||
<span style="color: #a7a7a7;float:right; margin-right:20px;">[ 其他 ]</span>
|
||||
</div>
|
||||
<div class="pagination-container" style="margin-top:10px;">
|
||||
<el-pagination :current-page="1" :page-sizes="[10,20,30, 50]" :page-size="1" :total="20" background layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange"/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane is-dot label="办事指南(教师)">配置管理</el-tab-pane>
|
||||
<el-tab-pane label="文件下载(学生)">角色管理</el-tab-pane>
|
||||
<el-tab-pane label="定时任务补偿">定时任务补偿</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-tabs type="border-card" style="margin-top:20px;">
|
||||
<el-tab-pane label="教师通知">
|
||||
<div v-for="o in 20" :key="o" class="text item separatorLine">
|
||||
<a href="www.baidu.com">{{ '列表内容 ' + o }}</a>
|
||||
<span style="float:right">2018-11-22</span>
|
||||
<span v-if="o != 10 " style="color: #a7a7a7;float:right; margin-right:20px;">[ 张三 - 其他 ]</span>
|
||||
<span v-if="o === 10 " style="color: #a7a7a7;float:right; margin-right:20px;">[ 张三1234 - 其他 ]</span>
|
||||
</div>
|
||||
<div class="pagination-container" style="margin-top:10px;">
|
||||
<el-pagination :current-page="1" :page-sizes="[10,20,30, 50]" :page-size="1" :total="20" background layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange"/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-tabs type="border-card" style="margin-top:20px;">
|
||||
<el-tab-pane name="more" class="more-btn">
|
||||
<span slot="label">
|
||||
<el-badge is-dot class="item">教务通知</el-badge>
|
||||
</span>
|
||||
测试
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="40" class="panel-group">
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel" @click="handleSetLineChartData('purchases')">
|
||||
<div class="card-panel-icon-wrapper icon-money">
|
||||
<svg-icon icon-class="money" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">天气预报</div>
|
||||
<count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">New Visits</div>
|
||||
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num"/>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel" @click="handleSetLineChartData('shoppings')">
|
||||
<div class="card-panel-icon-wrapper icon-shoppingCard">
|
||||
<svg-icon icon-class="shoppingCard" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">新闻</div>
|
||||
<count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel" @click="handleSetLineChartData('messages')">
|
||||
<div class="card-panel-icon-wrapper icon-message">
|
||||
<svg-icon icon-class="message" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">Messages</div>
|
||||
<count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel" @click="handleSetLineChartData('purchases')">
|
||||
<div class="card-panel-icon-wrapper icon-money">
|
||||
<svg-icon icon-class="money" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">Purchases</div>
|
||||
<count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel" @click="handleSetLineChartData('shoppings')">
|
||||
<div class="card-panel-icon-wrapper icon-shopping">
|
||||
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">Shoppings</div>
|
||||
<count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix panel-group">
|
||||
<span>最新公告</span>
|
||||
<a href="#/example/list">
|
||||
<el-button style="float: right; padding: 3px 0" type="text">更多...</el-button></a>
|
||||
</div>
|
||||
<div v-for="o in 8" :key="o" class="text item">
|
||||
<a href="#/example/list">{{ '列表内容afassdfsaffsdf列表内容列表内容列表内容列表内容列表内容列表内容 ' + o }}</a>[17/08/29]
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix panel-group">
|
||||
<span>资源管理</span>
|
||||
<el-button style="float: right; padding: 3px 0" type="text">更多...</el-button>
|
||||
</div>
|
||||
<div v-for="o in 8" :key="o" class="text item">
|
||||
<a href="www.baidu.com">{{ '列表内容 ' + o }}</a>[17/08/29]
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -55,6 +100,18 @@ export default {
|
|||
CountTo
|
||||
},
|
||||
methods: {
|
||||
handleSizeChange(val) {
|
||||
this.$emit('pagination', { page: this.currentPage, limit: val })
|
||||
if (this.autoScroll) {
|
||||
scrollTo(0, 800)
|
||||
}
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.$emit('pagination', { page: val, limit: this.pageSize })
|
||||
if (this.autoScroll) {
|
||||
scrollTo(0, 800)
|
||||
}
|
||||
},
|
||||
handleSetLineChartData(type) {
|
||||
this.$emit('handleSetLineChartData', type)
|
||||
}
|
||||
|
@ -63,6 +120,44 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.text {
|
||||
font-size: 15px;
|
||||
}
|
||||
a{color:#333;text-decoration:none;}
|
||||
a:hover{ color:#C81F1A; text-decoration:none;}
|
||||
.item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.clearfix:before,
|
||||
.clearfix:after {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
.clearfix:after {
|
||||
clear: both
|
||||
}
|
||||
.card-header {
|
||||
font-family: STKaiti;
|
||||
font-size: 20px;
|
||||
padding: 5px 0px;
|
||||
color: #333;
|
||||
}
|
||||
.separatorLine {
|
||||
/* clear: both; */
|
||||
/* height: 1px; */
|
||||
padding-bottom: 2px;
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
border-width: 1px;
|
||||
border-style: dashed;
|
||||
border-color: #34bfa3;
|
||||
border-top: 0;
|
||||
font-size: 14px;
|
||||
font-family: "microsoft yahei", arial, sans-serif;
|
||||
border-left: none;
|
||||
border-right: 0;
|
||||
}
|
||||
.panel-group {
|
||||
margin-top: 18px;
|
||||
.card-panel-col{
|
||||
|
@ -91,7 +186,7 @@ export default {
|
|||
.icon-money {
|
||||
background: #f4516c;
|
||||
}
|
||||
.icon-shopping {
|
||||
.icon-shoppingCard {
|
||||
background: #34bfa3
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +199,7 @@ export default {
|
|||
.icon-money {
|
||||
color: #f4516c;
|
||||
}
|
||||
.icon-shopping {
|
||||
.icon-shoppingCard {
|
||||
color: #34bfa3
|
||||
}
|
||||
.card-panel-icon-wrapper {
|
||||
|
|
|
@ -23,7 +23,7 @@ export default {
|
|||
])
|
||||
},
|
||||
created() {
|
||||
if (!this.roles.includes('admin')) {
|
||||
if (!this.roles.includes(0) && !this.roles.includes(1)) {
|
||||
this.currentRole = 'editorDashboard'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,11 @@
|
|||
<h1 class="text-jumbo text-ginormous">Oops!</h1>
|
||||
gif来源<a href="https://zh.airbnb.com/" target="_blank">airbnb</a> 页面
|
||||
<h2>你没有权限去该页面</h2>
|
||||
<h6>如有不满请联系你领导</h6>
|
||||
<ul class="list-unstyled">
|
||||
<li>或者你可以去:</li>
|
||||
<li class="link-type">
|
||||
<router-link to="/dashboard">回首页</router-link>
|
||||
</li>
|
||||
<li class="link-type"><a href="https://www.taobao.com/">随便看看</a></li>
|
||||
<li><a href="#" @click.prevent="dialogVisible=true">点我看图</a></li>
|
||||
</ul>
|
||||
</el-col>
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<span>sfasf</span>
|
||||
<fm-making-form>
|
||||
<template slot="action"/>
|
||||
</fm-making-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
import 'form-making/dist/FormMaking.css'
|
||||
export default {
|
||||
name: 'CreateForm',
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.fm-header{
|
||||
height: 50px;
|
||||
box-shadow: 0 2px 10px rgba(70,160,252, 0.6);
|
||||
padding: 0 10px;
|
||||
background-image: linear-gradient(to right,#1278f6,#00b4aa);
|
||||
position: relative;
|
||||
|
||||
.fm-logo{
|
||||
height: 26px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.fm-title{
|
||||
display: inline-block;
|
||||
line-height: 50px;
|
||||
vertical-align: middle;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
opacity: 0.8;
|
||||
margin-left: 6px;
|
||||
}
|
||||
.fm-link{
|
||||
height: 50px;
|
||||
float: right;
|
||||
|
||||
a{
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
line-height: 50px;
|
||||
font-weight: 500;
|
||||
margin-left: 10px;
|
||||
|
||||
&:hover{
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.fm-container{
|
||||
height: calc(100% - 50px);
|
||||
}
|
||||
*, :after, :before {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,body{
|
||||
height: 100%;
|
||||
}
|
||||
#app {
|
||||
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: #2c3e50;
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
<template>
|
||||
<el-dialog :visible.sync="dialogFormVisible" title="请假" width="40%">
|
||||
<el-form ref="ruleForm" :model="ruleForm" :rules="rules" style="magin-top:-100px;" label-width="100px" class="demo-ruleForm">
|
||||
<el-form-item label="请假类型">
|
||||
<el-select v-model="ruleForm.type" class="filter-item" style="width:90%;">
|
||||
<el-option v-for="item in leaveTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" required>
|
||||
<el-col style="width:60%;">
|
||||
<el-form-item prop="date1">
|
||||
<el-date-picker v-model="ruleForm.date1" type="date" placeholder="选择日期" style="width: 100%;"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col style="width:30%;">
|
||||
<el-form-item>
|
||||
<el-select v-model="ruleForm.region" placeholder="请选择活动区域" style="magin-left:20px;">
|
||||
<el-option label="上午" value="0"/>
|
||||
<el-option label="下午" value="1/"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" required>
|
||||
<el-col style="width:60%;">
|
||||
<el-form-item prop="date1">
|
||||
<el-date-picker v-model="ruleForm.date1" type="date" placeholder="选择日期" style="width: 100%;"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col style="width:30%;">
|
||||
<el-form-item>
|
||||
<el-select v-model="ruleForm.region" placeholder="请选择活动区域">
|
||||
<el-option label="上午" value="0"/>
|
||||
<el-option label="下午" value="1/"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="时长" prop="name">
|
||||
<el-input v-model="ruleForm.name" style="width:90%;"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="请假事由" prop="desc">
|
||||
<el-input v-model="ruleForm.desc" type="textarea" style="width:90%;"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
|
||||
<el-button @click="resetForm('ruleForm')">重置</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
|
||||
const leaveTypeOptions = [
|
||||
{ key: 0, display_name: '事假' },
|
||||
{ key: 1, display_name: '年假' },
|
||||
{ key: 2, display_name: '病假' },
|
||||
{ key: 3, display_name: '产假' },
|
||||
{ key: 4, display_name: '陪产假' },
|
||||
{ key: 5, display_name: '婚假' },
|
||||
{ key: 6, display_name: '丧假' }
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogFormVisible: false,
|
||||
leaveTypeOptions,
|
||||
ruleForm: {
|
||||
name: '',
|
||||
region: '0',
|
||||
date1: '',
|
||||
date2: '',
|
||||
delivery: false,
|
||||
type: 0,
|
||||
resource: '',
|
||||
desc: ''
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: '请输入活动名称', trigger: 'blur' },
|
||||
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
|
||||
],
|
||||
region: [
|
||||
{ required: true, message: '请选择活动区域', trigger: 'change' }
|
||||
],
|
||||
date1: [
|
||||
{ type: 'date', required: true, message: '请选择日期', trigger: 'change' }
|
||||
],
|
||||
date2: [
|
||||
{ type: 'date', required: true, message: '请选择时间', trigger: 'change' }
|
||||
],
|
||||
type: [
|
||||
{ type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }
|
||||
],
|
||||
resource: [
|
||||
{ required: true, message: '请选择活动资源', trigger: 'change' }
|
||||
],
|
||||
desc: [
|
||||
{ required: true, message: '请填写活动形式', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitForm(formName) {
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
alert('submit!')
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields()
|
||||
},
|
||||
showEditDialog() {
|
||||
this.dialogFormVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,234 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container" style="float:right; margin-top:-10px;">
|
||||
<el-button class="filter-item" style="margin-right: 10px;" type="primary" icon="el-icon-edit" @click="createLeave()">新建</el-button>
|
||||
</div>
|
||||
<div style="margin-top:-10px">
|
||||
<el-table v-loading.body="listLoading" :show-overflow-tooltip="true" :data="list" border fit highlight-current-row style="width: 100%">
|
||||
<el-table-column align="center" label="ID" width="80">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.$index + 1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" width="150px" label="发布者">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="200px" align="center" label="发布时间">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.modifyTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" max-width="500px" align="left" label="标题">
|
||||
<template slot-scope="scope">
|
||||
<router-link :to="'/leave/'+scope.row.id" class="link-type" target="_blank">
|
||||
<span>{{ scope.row.title }}</span>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="300px" align="left" label="附件">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.articleAttachment && scope.row.articleAttachment.attachmentName" class="el-tag el-tag--info el-tag--small">
|
||||
<a class="link-type" @click="download(scope.row.articleAttachment.url, scope.row.articleAttachment.attachmentName)">{{ scope.row.articleAttachment.attachmentName }}</a>
|
||||
<i class="el-tag__close el-icon-close" @click="deleteAttachment(scope.row)"/>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('action')" align="center" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button style="margin:5px;float:right">
|
||||
<el-dropdown class="avatar-container right-menu-item" trigger="click">
|
||||
<i style="cursor:pointer" class="el-icon-caret-bottom"/>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<router-link :to="'/leave/edit/'+scope.row.id">
|
||||
<el-dropdown-item>
|
||||
{{ $t('edit') }}
|
||||
</el-dropdown-item>
|
||||
</router-link>
|
||||
<el-dropdown-item v-if="scope.row.upload===1" divided>
|
||||
<span style="display:block;" @click="showUploadData(scope.row)">查 看</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided>
|
||||
<span style="display:block;" @click="deleteArticle(scope.row)">{{ $t('delete') }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-button>
|
||||
<el-upload
|
||||
v-if="scope.row.upload===1"
|
||||
:action="importFileUrl"
|
||||
:on-remove="handleRemove"
|
||||
:data="uploadData"
|
||||
:on-preview="handlePreview"
|
||||
:on-exceed="handleExceed"
|
||||
:on-success="handleSuccess"
|
||||
:file-list="scope.row.attachmentList"
|
||||
:show-file-list="false"
|
||||
style="float:left;margin:5px;"
|
||||
name="file"
|
||||
><el-button size="mini" @click="handleUpdate(scope.row)"><i class="el-icon-upload el-icon--right"/>上传</el-button>
|
||||
|
||||
</el-upload>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
:current-page="listQuery.page"
|
||||
:page-sizes="[10,20,30, 50]"
|
||||
:page-size="listQuery.limit"
|
||||
:total="total"
|
||||
background
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"/>
|
||||
</div>
|
||||
</div>
|
||||
<leaveEdit ref="leaveEdit"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList, deleteArticle } from '@/api/article'
|
||||
import { downloadFile, deleteAttachment } from '@/api/user'
|
||||
import leaveEdit from '@/views/leave/leaveEdit'
|
||||
|
||||
export default {
|
||||
name: 'ArticleList',
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
},
|
||||
components: {
|
||||
leaveEdit
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
importFileUrl: window.UEDITOR_HOME_URL + 'ueditor/importFile',
|
||||
uploadData: {
|
||||
noticeId: undefined
|
||||
},
|
||||
attachmentList: [
|
||||
{ name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100' }],
|
||||
list: null,
|
||||
total: 0,
|
||||
limit: 1,
|
||||
flag: false,
|
||||
count: 123,
|
||||
rowIndex: undefined,
|
||||
showReviewer: false,
|
||||
dialogPvVisible: false,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
fid: this.$store.getters.user.fid,
|
||||
page: 1,
|
||||
limit: 20
|
||||
},
|
||||
selectRow: undefined
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
createLeave() {
|
||||
this.$refs.leaveEdit.showEditDialog()
|
||||
},
|
||||
deleteArticle(row) {
|
||||
deleteArticle(row.id).then(() => {
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
this.listLoading = false
|
||||
}).catch((error) => {
|
||||
alert(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
download(url, name) {
|
||||
downloadFile(url, name)
|
||||
},
|
||||
showUploadData(item) {
|
||||
this.$refs.leaveEdit.handleModifyStatus(item)
|
||||
},
|
||||
deleteAttachment(row) {
|
||||
this.$confirm('您确定删除吗?').then(_ => {
|
||||
deleteAttachment(row.articleAttachment).then(() => {
|
||||
row.articleAttachment = undefined
|
||||
})
|
||||
}).catch(_ => {
|
||||
})
|
||||
},
|
||||
handleUpdate(row) {
|
||||
this.uploadData.noticeId = row.id
|
||||
this.selectRow = row
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
this.listLoading = false
|
||||
}).catch((error) => {
|
||||
alert(error)
|
||||
})
|
||||
},
|
||||
handleRemove(file, attachmentList) {
|
||||
alert(file, attachmentList)
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
showDetail() {
|
||||
this.flag = !this.flag
|
||||
},
|
||||
handlePreview(file) {
|
||||
this.$message.warning(`file url = ` + file.url)
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleSuccess(response, file, attachmentList) {
|
||||
if (response == null) {
|
||||
return
|
||||
}
|
||||
this.selectRow.attachmentList = []
|
||||
this.selectRow.articleAttachment = response
|
||||
this.showReviewer = true
|
||||
},
|
||||
handleExceed(files, attachmentList) {
|
||||
this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + attachmentList.length} 个文件`)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.edit-input {
|
||||
padding-right: 100px;
|
||||
}
|
||||
.cancel-btn {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
.demo-block {
|
||||
border: 1px solid #ebebeb;
|
||||
border-radius: 3px;
|
||||
transition: .2s;
|
||||
margin:20px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,228 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<span v-html="message"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { fetchArticle } from '@/api/article'
|
||||
|
||||
export default {
|
||||
name: 'Show',
|
||||
data() {
|
||||
return {
|
||||
message: undefined
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchArticle()
|
||||
},
|
||||
methods: {
|
||||
fetchArticle() {
|
||||
this.listLoading = true
|
||||
fetchArticle(this.$route.params.id).then(response => {
|
||||
if (response.data.code === 200) {
|
||||
this.message = response.data.result.content
|
||||
}
|
||||
this.listLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.wscn-http404-container{
|
||||
transform: translate(-50%,-50%);
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
}
|
||||
.wscn-http404 {
|
||||
position: relative;
|
||||
width: 1200px;
|
||||
padding: 0 50px;
|
||||
overflow: hidden;
|
||||
.pic-404 {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 600px;
|
||||
overflow: hidden;
|
||||
&__parent {
|
||||
width: 100%;
|
||||
}
|
||||
&__child {
|
||||
position: absolute;
|
||||
&.left {
|
||||
width: 80px;
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
animation-name: cloudLeft;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
&.mid {
|
||||
width: 46px;
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
animation-name: cloudMid;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
&.right {
|
||||
width: 62px;
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
animation-name: cloudRight;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
@keyframes cloudLeft {
|
||||
0% {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 33px;
|
||||
left: 188px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
top: 81px;
|
||||
left: 92px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 97px;
|
||||
left: 60px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes cloudMid {
|
||||
0% {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 40px;
|
||||
left: 360px;
|
||||
opacity: 1;
|
||||
}
|
||||
70% {
|
||||
top: 130px;
|
||||
left: 180px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 160px;
|
||||
left: 120px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes cloudRight {
|
||||
0% {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 120px;
|
||||
left: 460px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
top: 180px;
|
||||
left: 340px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 200px;
|
||||
left: 300px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.bullshit {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 300px;
|
||||
padding: 30px 0;
|
||||
overflow: hidden;
|
||||
&__oops {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
line-height: 40px;
|
||||
color: #1482f0;
|
||||
opacity: 0;
|
||||
margin-bottom: 20px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__headline {
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
color: #222;
|
||||
font-weight: bold;
|
||||
opacity: 0;
|
||||
margin-bottom: 10px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__info {
|
||||
font-size: 13px;
|
||||
line-height: 21px;
|
||||
color: grey;
|
||||
opacity: 0;
|
||||
margin-bottom: 30px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__return-home {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 110px;
|
||||
height: 36px;
|
||||
background: #1482f0;
|
||||
border-radius: 100px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
opacity: 0;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
cursor: pointer;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.3s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
@keyframes slideUp {
|
||||
0% {
|
||||
transform: translateY(60px);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,270 @@
|
|||
<template>
|
||||
<el-dialog :visible.sync="dialogFormVisible" title="收件人" width="60%" height="2200">
|
||||
<el-tabs type="border-card" style="height: 630px;margin-top:-30px;margin-bottom:10px;" >
|
||||
<el-tab-pane label="教师">
|
||||
<teacherComplexTable ref="teacherComplexTable" :table-height="450 + 'px'" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="false" label="班级">
|
||||
<gradeComplexTable ref="gradeComplexTable" :table-height="450 + 'px'" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="false" label="群组">
|
||||
<groupComplexTable ref="groupComplexTable" :table-height="450 + 'px'" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="addUser">{{ $t('table.add') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList, fetchPv, createArticle, updateArticle } from '@/api/article'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
import { parseTime } from '@/utils'
|
||||
import groupComplexTable from '@/views/group/index'
|
||||
import studentComplexTable from '@/views/student/complexTable'
|
||||
import teacherComplexTable from '@/views/teacher/complexTable'
|
||||
import gradeComplexTable from '@/views/grade/complexTable'
|
||||
|
||||
const calendarTypeOptions = [
|
||||
{ key: 'CN', display_name: 'China' },
|
||||
{ key: 'US', display_name: 'USA' },
|
||||
{ key: 'JP', display_name: 'Japan' },
|
||||
{ key: 'EU', display_name: 'Eurozone' }
|
||||
]
|
||||
|
||||
// arr to obj ,such as { CN : "China", US : "USA" }
|
||||
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
|
||||
acc[cur.key] = cur.display_name
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
export default {
|
||||
name: 'ShowUser',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
},
|
||||
typeFilter(type) {
|
||||
return calendarTypeKeyValue[type]
|
||||
}
|
||||
},
|
||||
components: {
|
||||
groupComplexTable,
|
||||
studentComplexTable,
|
||||
teacherComplexTable,
|
||||
gradeComplexTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
totalStuCount: 0,
|
||||
tableKey: 0,
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
importance: undefined,
|
||||
title: undefined,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
classId: undefined,
|
||||
teacherName: undefined,
|
||||
importanceOptions: [1, 2, 3],
|
||||
calendarTypeOptions,
|
||||
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
||||
statusOptions: ['published', 'draft', 'deleted'],
|
||||
showReviewer: false,
|
||||
temp: {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
type: '',
|
||||
status: 'published'
|
||||
},
|
||||
dialogFormVisible: true,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
type: [{ required: true, message: 'type is required', trigger: 'change' }],
|
||||
timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
|
||||
title: [{ required: true, message: 'title is required', trigger: 'blur' }]
|
||||
},
|
||||
downloadLoading: false,
|
||||
userList: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
addUser() {
|
||||
var map = new Map()
|
||||
map.set('user', this.$refs.teacherComplexTable.getSelectUser())
|
||||
// map.set('class', this.$refs.gradeComplexTable.getSelectClass())
|
||||
// map.set('group', this.$refs.groupComplexTable.getSelectGroup())
|
||||
|
||||
// this.userList = this.$refs.teacherComplexTable.getSelectUser().concat(this.$refs.studentComplexTable.getSelectUser())
|
||||
this.dialogFormVisible = false
|
||||
this.$emit('listenToChildEvent', map)
|
||||
},
|
||||
getTotalStu: function(data) {
|
||||
this.totalStuCount = data
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.items
|
||||
this.total = response.data.total
|
||||
|
||||
// Just to simulate the time of the request
|
||||
setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 1.5 * 1000)
|
||||
})
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus() {
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
resetTemp() {
|
||||
this.temp = {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
status: 'published',
|
||||
type: ''
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp()
|
||||
this.dialogStatus = 'create'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
createData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
|
||||
this.temp.author = 'vue-element-admin'
|
||||
createArticle(this.temp).then(() => {
|
||||
this.list.unshift(this.temp)
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleUpdate(row) {
|
||||
this.temp = Object.assign({}, row) // copy obj
|
||||
this.temp.timestamp = new Date(this.temp.timestamp)
|
||||
this.dialogStatus = 'update'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
updateData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
|
||||
updateArticle(tempData).then(() => {
|
||||
for (const v of this.list) {
|
||||
if (v.id === this.temp.id) {
|
||||
const index = this.list.indexOf(v)
|
||||
this.list.splice(index, 1, this.temp)
|
||||
break
|
||||
}
|
||||
}
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
const index = this.list.indexOf(row)
|
||||
this.list.splice(index, 1)
|
||||
},
|
||||
handleFetchPv(pv) {
|
||||
fetchPv(pv).then(response => {
|
||||
this.pvData = response.data.pvData
|
||||
this.dialogPvVisible = true
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const data = this.formatJson(filterVal, this.list)
|
||||
excel.export_json_to_excel({
|
||||
header: tHeader,
|
||||
data,
|
||||
filename: 'table-list'
|
||||
})
|
||||
this.downloadLoading = false
|
||||
})
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,331 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input v-model="listQuery.name" placeholder="年级名称" style="width: 250px;" class="filter-item" @keyup.enter.native="handleFilter"/>
|
||||
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">{{ $t('table.search') }}</el-button>
|
||||
<el-button v-if="$store.state.user.admin" class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleUpdate()">{{ $t('table.add') }}</el-button>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:key="tableKey"
|
||||
:data="list"
|
||||
border
|
||||
fit
|
||||
highlight-current-row
|
||||
style="width: 100%;min-height:300px;">
|
||||
<el-table-column :label="$t('table.id')" align="center" width="65">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.$index+1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="年级名称" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip placement="left" effect="light">
|
||||
<div slot="content">{{ scope.row.showName }}</div>
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="班级信息" min-width="150px">
|
||||
<template slot-scope="scope">
|
||||
<span v-for="item in scope.row.clazzList" :key="item.id" class="el-tag el-tag--info el-tag--small" style="margin-left:5px;">
|
||||
<span class="link-type" @click="handleEditClass(item)">{{ item.name }}(班主任:{{ item.teacher.name }})</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.graduationStatus==1" type="info"> 已毕业</el-tag>
|
||||
<el-tag v-else>在读</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.actions')" align="center" width="230" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-if="$store.state.user.admin" type="primary" size="mini" @click="handleUpdate(scope.row, scope.$index, false)">{{ $t('table.edit') }}</el-button>
|
||||
<el-button size="mini" type="success" @click="handleUpdate(scope.row, scope.$index, true)">查看</el-button>
|
||||
<el-button v-if="$store.state.user.admin" size="mini" type="danger" @click="deleteGrade(scope.row)">{{ $t('table.delete') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-container">
|
||||
<el-pagination :current-page="listQuery.page" :page-sizes="[10,20,30, 50]" :page-size="listQuery.limit" :total="total" background layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange"/>
|
||||
</div>
|
||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
|
||||
<el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="70px" style="width: 400px; margin-left:50px;">
|
||||
<el-form-item :label="$t('table.type')" prop="type">
|
||||
<el-select v-model="temp.type" class="filter-item" placeholder="Please select">
|
||||
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.date')" prop="timestamp">
|
||||
<el-date-picker v-model="temp.timestamp" type="datetime" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.title')" prop="title">
|
||||
<el-input v-model="temp.title"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.status')">
|
||||
<el-select v-model="temp.status" class="filter-item" >
|
||||
<el-option v-for="item in statusOptions" :key="item" :label="item" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.importance')">
|
||||
<el-rate v-model="temp.importance" :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :max="3" style="margin-top:8px;"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.remark')">
|
||||
<el-input :autosize="{ minRows: 2, maxRows: 4}" v-model="temp.remark" type="textarea"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
|
||||
<el-button v-if="dialogStatus=='create'" type="primary" @click="createData">{{ $t('table.confirm') }}</el-button>
|
||||
<el-button v-else type="primary" @click="updateData">{{ $t('table.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :visible.sync="dialogPvVisible" title="Reading statistics">
|
||||
<el-table :data="pvData" border fit highlight-current-row style="width: 100%">
|
||||
<el-table-column prop="key" label="Channel"/>
|
||||
<el-table-column prop="pv" label="Pv"/>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="dialogPvVisible = false">{{ $t('table.confirm') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<edit-grade ref="editGrade" @listenToChildEvent="updateGradeRow"/>
|
||||
<edit-class ref="showClass"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { createArticle, updateArticle } from '@/api/article'
|
||||
import { fetchGradeList, deleteGrade } from '@/api/user'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
import editClass from '@/views/grade/editClass'
|
||||
import editGrade from '@/views/grade/editGrade'
|
||||
import { parseTime } from '@/utils'
|
||||
|
||||
const calendarTypeOptions = [
|
||||
{ key: 'CN', display_name: 'China' },
|
||||
{ key: 'US', display_name: 'USA' },
|
||||
{ key: 'JP', display_name: 'Japan' },
|
||||
{ key: 'EU', display_name: 'Eurozone' }
|
||||
]
|
||||
|
||||
// arr to obj ,such as { CN : "China", US : "USA" }
|
||||
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
|
||||
acc[cur.key] = cur.display_name
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
},
|
||||
typeFilter(type) {
|
||||
return calendarTypeKeyValue[type]
|
||||
}
|
||||
},
|
||||
components: {
|
||||
editClass,
|
||||
editGrade
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hackReset: true,
|
||||
tableKey: 0,
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
fid: this.$store.state.user.fid,
|
||||
name: undefined,
|
||||
importance: undefined,
|
||||
title: undefined,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
importanceOptions: [1, 2, 3],
|
||||
calendarTypeOptions,
|
||||
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
||||
statusOptions: ['published', 'draft', 'deleted'],
|
||||
showReviewer: false,
|
||||
temp: {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
type: '',
|
||||
status: 'published'
|
||||
},
|
||||
dialogFormVisible: false,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
type: [{ required: true, message: 'type is required', trigger: 'change' }],
|
||||
timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
|
||||
title: [{ required: true, message: 'title is required', trigger: 'blur' }]
|
||||
},
|
||||
classId: undefined,
|
||||
downloadLoading: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
updateGradeRow: function(rowData, index) {
|
||||
if (index > -1) {
|
||||
this.list.splice(index, 1, rowData)
|
||||
} else {
|
||||
this.list.unshift(rowData)
|
||||
}
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchGradeList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
this.listLoading = false
|
||||
})
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus(row, status) {
|
||||
this.$message({
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
row.status = status
|
||||
},
|
||||
deleteGrade(row) {
|
||||
deleteGrade(row.id).then(response => {
|
||||
fetchGradeList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
})
|
||||
})
|
||||
},
|
||||
resetTemp() {
|
||||
this.temp = {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
status: 'published',
|
||||
type: ''
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp()
|
||||
this.dialogStatus = 'create'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
createData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
|
||||
this.temp.author = 'vue-element-admin'
|
||||
createArticle(this.temp).then(response => {
|
||||
this.list.unshift(this.temp)
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleUpdate(row, index, disabled) {
|
||||
this.$refs.editGrade.handleModifyStatus(row, index, disabled)
|
||||
},
|
||||
handleEditClass(item) {
|
||||
if (this.$refs.showClass) {
|
||||
this.$refs.showClass.handleModifyStatus(item)
|
||||
}
|
||||
},
|
||||
updateData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
|
||||
updateArticle(tempData).then(() => {
|
||||
for (const v of this.list) {
|
||||
if (v.id === this.temp.id) {
|
||||
const index = this.list.indexOf(v)
|
||||
this.list.splice(index, 1, this.temp)
|
||||
break
|
||||
}
|
||||
}
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
const index = this.list.indexOf(row)
|
||||
this.list.splice(index, 1)
|
||||
},
|
||||
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,57 @@
|
|||
<template>
|
||||
<el-dialog :visible.sync="dialogFormVisible" title="班级信息" width="60%" >
|
||||
<el-tabs type="border-card" style="height: 600px;">
|
||||
<el-tab-pane label="班级学生">
|
||||
<studentComplexTable v-if="hackReset" :table-height="420 + 'px'" :class-id="classId" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="任课老师">
|
||||
<teacherComplexTable v-if="hackReset" :table-height="500 + 'px'" :class-id="classId" :class-name="className" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="课程表">
|
||||
<scheduleTab v-if="hackReset" :class-id="classId" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">确认</el-button>
|
||||
</div>
|
||||
</el-dialog></template>
|
||||
|
||||
<script>
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
import teacherComplexTable from '@/views/teacher/complexTable'
|
||||
import studentComplexTable from '@/views/student/complexTable'
|
||||
import scheduleTab from '@/views/grade/scheduleTab'
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
components: {
|
||||
teacherComplexTable,
|
||||
studentComplexTable,
|
||||
scheduleTab
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hackReset: false,
|
||||
classId: undefined,
|
||||
className: undefined,
|
||||
dialogFormVisible: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
handleModifyStatus(clazz) {
|
||||
this.classId = clazz.id
|
||||
this.className = clazz.name
|
||||
this.dialogFormVisible = true
|
||||
this.hackReset = false
|
||||
this.$nextTick(() => {
|
||||
this.hackReset = true
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,366 @@
|
|||
<template>
|
||||
<el-dialog :visible.sync="dialogFormVisible" title="编辑">
|
||||
<el-form ref="dataForm" :disabled="disabled" :rules="rules" :model="temp" label-position="right" label-width="90px" style="width: 90%; margin-left:10px;">
|
||||
<el-form-item label="年级名称" prop="name">
|
||||
<el-input v-model="temp.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="年级别名">
|
||||
<el-input v-model="temp.showName"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="graduationStatus">
|
||||
<el-select v-model="temp.graduationStatus" filterable class="filter-item" placeholder="Please select" style="width: 100%;">
|
||||
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级">
|
||||
<el-row v-for="(item,index) in temp.clazzList" :gutter="10" :key="item.id" type="flex" class="row-bg" justify="left" style="margin-top:5px;">
|
||||
<el-col :span="12">
|
||||
<el-popover
|
||||
v-model="temp.clazzList[index].visiblePopover"
|
||||
:disabled="disabled"
|
||||
placement="top"
|
||||
width="300"
|
||||
trigger="click">
|
||||
<el-form :rules="rules" :model="formLabelAlign" label-position="right" label-width="80px">
|
||||
<el-form-item label="班级名称" prop="name">
|
||||
<el-input v-model="formLabelAlign.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="班主任">
|
||||
<el-select v-model="formLabelAlign.teacher" value-key="uid" filterable class="filter-item" placeholder="Please select" style="width: 100%;">
|
||||
<el-option v-for="item in teacherList" :key="item.uid" :label="item.name" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button size="mini" type="text" @click="temp.clazzList[index].visiblePopover = false">取消</el-button>
|
||||
<el-button type="primary" size="mini" @click="updateParent(index)">确定</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
<div slot="reference">
|
||||
<span class="el-tag el-tag--info el-tag--small" style="float:left;">
|
||||
<span class="link-type" @click="editParent(item)">{{ item.name }} (班主任: {{ item.teacher.name }})</span>
|
||||
<i v-if="!disabled" class="el-tag__close el-icon-close" @click="deleteParent(index)"/>
|
||||
</span>
|
||||
</div>
|
||||
</el-popover>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-popover
|
||||
v-model="formLabelAlign.visiblePopover"
|
||||
placement="top"
|
||||
width="300"
|
||||
trigger="click">
|
||||
<el-form ref="popoverForm" :rules="rules" :model="formLabelAlign" label-position="right" label-width="80px">
|
||||
<el-form-item label="班级名称" prop="name">
|
||||
<el-input v-model="formLabelAlign.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="班主任">
|
||||
<el-select v-model="formLabelAlign.teacher" value-key="uid" filterable class="filter-item" style="width: 100%;">
|
||||
<el-option v-for="item in teacherList" :key="item.uid" :label="item.name" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button size="mini" type="text" @click="formLabelAlign.visiblePopover = false">取消</el-button>
|
||||
<el-button type="primary" size="mini" @click="updateParent(-1)">确定</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
<el-button slot="reference" icon="el-icon-circle-plus-outline" size="mini" round @click="createParent()">添加</el-button>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述">
|
||||
<el-input :autosize="{ minRows: 3, maxRows: 5}" v-model="temp.remark" type="textarea"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
|
||||
<el-button v-if="dialogStatus=='create'" type="primary" @click="createData">{{ $t('table.confirm') }}</el-button>
|
||||
<el-button v-else type="primary" @click="updateData">{{ $t('table.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList, fetchPv } from '@/api/article'
|
||||
import { fetchTeacherList, updateGrade, fetchCourseList } from '@/api/user'
|
||||
import { isvalidStr } from '@/utils/validate'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
import { parseTime } from '@/utils'
|
||||
|
||||
const calendarTypeOptions = [
|
||||
{ key: 0, display_name: '在读' },
|
||||
{ key: 1, display_name: '已毕业' }
|
||||
]
|
||||
|
||||
// arr to obj ,such as { CN : "China", US : "USA" }
|
||||
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
|
||||
acc[cur.key] = cur.display_name
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
},
|
||||
typeFilter(type) {
|
||||
return calendarTypeKeyValue[type]
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
disabled: true,
|
||||
tableKey: 0,
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: undefined,
|
||||
fid: this.$store.state.user.fid,
|
||||
importance: undefined,
|
||||
title: undefined,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
teacherList: [],
|
||||
courseList: [],
|
||||
formLabelAlign: {
|
||||
name: '',
|
||||
teacher: {
|
||||
uid: undefined,
|
||||
name: undefined
|
||||
},
|
||||
course: {
|
||||
id: undefined,
|
||||
name: undefined
|
||||
}
|
||||
},
|
||||
index: undefined,
|
||||
calendarTypeOptions,
|
||||
temp: {
|
||||
id: undefined,
|
||||
name: '',
|
||||
clazzList: [],
|
||||
graduationStatus: 0
|
||||
},
|
||||
dialogFormVisible: false,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
name: [{ required: true, message: '名称必填', trigger: 'blur' }],
|
||||
teacherName1: [{ required: true, message: '班主任必填', trigger: 'change' }],
|
||||
teacherName: [{ validate: isvalidStr, trigger: 'change' }],
|
||||
title: [{ required: true, message: 'title is required', trigger: 'blur' }]
|
||||
},
|
||||
downloadLoading: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
updateParent(index) {
|
||||
this.$refs['popoverForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
if (index > -1) {
|
||||
this.formLabelAlign.visiblePopover = false
|
||||
this.temp.clazzList.splice(index, 1, this.formLabelAlign)
|
||||
} else {
|
||||
this.formLabelAlign.visiblePopover = false
|
||||
this.temp.clazzList.push(this.formLabelAlign)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
deleteParent(index) {
|
||||
this.temp.clazzList.splice(index, 1)
|
||||
},
|
||||
editParent(item) {
|
||||
this.formLabelAlign = JSON.parse(JSON.stringify(item))
|
||||
item.visiblePopover = !this.disabled
|
||||
},
|
||||
resetParent() {
|
||||
this.formLabelAlign = {
|
||||
name: undefined,
|
||||
teacher: {
|
||||
uid: undefined,
|
||||
name: undefined
|
||||
},
|
||||
visiblePopover: true
|
||||
}
|
||||
},
|
||||
createParent() {
|
||||
this.resetParent()
|
||||
this.$nextTick(() => {
|
||||
this.$refs['popoverForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.items
|
||||
this.total = response.data.total
|
||||
this.listLoading = false
|
||||
})
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus(row, index, disabled) {
|
||||
this.resetTemp()
|
||||
this.dialogFormVisible = true
|
||||
this.index = index
|
||||
this.disabled = disabled
|
||||
if (row) {
|
||||
this.temp = JSON.parse(JSON.stringify(row))
|
||||
}
|
||||
this.getTeacherList()
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
getTeacherList() {
|
||||
this.listLoading = true
|
||||
fetchTeacherList(this.listQuery).then(response => {
|
||||
this.teacherList = response.data.result.list
|
||||
})
|
||||
},
|
||||
getCourseList() {
|
||||
this.listLoading = true
|
||||
fetchCourseList(this.listQuery).then(response => {
|
||||
this.courseList = response.data.result.list
|
||||
})
|
||||
},
|
||||
resetTemp() {
|
||||
this.temp = {
|
||||
id: undefined,
|
||||
clazzList: [],
|
||||
fid: this.$store.state.user.fid,
|
||||
name: undefined,
|
||||
graduationStatus: 0
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp()
|
||||
this.dialogStatus = 'create'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
createData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
updateGrade(this.temp).then(response => {
|
||||
this.list.unshift(this.temp)
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleUpdate(row) {
|
||||
this.temp = Object.assign({}, row) // copy obj
|
||||
this.temp.timestamp = new Date(this.temp.timestamp)
|
||||
this.dialogStatus = 'update'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
updateData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
|
||||
updateGrade(tempData).then(response => {
|
||||
if (response.data.code === 200 && response.data.result) {
|
||||
this.$emit('listenToChildEvent', response.data.result, this.index)
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
} else {
|
||||
this.$notify({
|
||||
title: '失败',
|
||||
message: response.data.message,
|
||||
type: 'error',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
const index = this.list.indexOf(row)
|
||||
this.list.splice(index, 1)
|
||||
},
|
||||
handleFetchPv(pv) {
|
||||
fetchPv(pv).then(response => {
|
||||
this.pvData = response.data.pvData
|
||||
this.dialogPvVisible = true
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const data = this.formatJson(filterVal, this.list)
|
||||
excel.export_json_to_excel({
|
||||
header: tHeader,
|
||||
data,
|
||||
filename: 'table-list'
|
||||
})
|
||||
this.downloadLoading = false
|
||||
})
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,259 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<!--周-->
|
||||
<div class="tr_top">
|
||||
<div class="td_top_title">{{ getMonth() }}月</div>
|
||||
<div v-for="(value, key, index) in ['周一','周二','周三','周四','周五','周六','周日']" :key="index">
|
||||
<div :class="{td_top_data_change:setWeeks(value)}" class="td_top_data">{{ value }}({{ time[key] }}日)</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--课程-->
|
||||
<div class="content" style="padding-bottom: 20px;">
|
||||
<!--节-->
|
||||
<div class="tr_week">
|
||||
<div class="td_week_title">
|
||||
<div class="td_week_title_content">早自习</div>
|
||||
<div v-for="n in 8" :key="n" class="td_week_title_content">{{ n }}</div>
|
||||
<div class="td_week_title_content">晚自习1</div>
|
||||
<div class="td_week_title_content">晚自习2</div>
|
||||
<div class="td_week_title_content">晚自习3</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--课程内容-->
|
||||
<div v-for="(value, key, index) in schedule" :key="index" class="tr_week">
|
||||
<div class="td_week_data">
|
||||
<div v-for="(value1, key1, index1) in value" :key="index1">
|
||||
<span v-if="value1" @click="updateParent(key, key1, value1)">
|
||||
<div class="td_week_data_content" style="justify-content: center;display: flex;align-items: center;font-size: 10px;">
|
||||
<span> {{ value1.courseName }}<span v-if="classId"> ({{ value1.teacherName }})</span><br><span v-if="!classId">{{ value1.className }}</span></span>
|
||||
</div>
|
||||
</span>
|
||||
<div v-if="!value1" class="td_week_data_content" @click="updateParent(key, key1, value1)">
|
||||
<span v-if="!value1"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
:visible.sync="dialogVisible"
|
||||
width="20%"
|
||||
append-to-body
|
||||
center>
|
||||
<el-form ref="ruleForm" :model="formLabelAlign" :rules="rules" label-position="right" label-width="60px">
|
||||
<el-form-item label="课程" prop="course">
|
||||
<el-select v-model="formLabelAlign.course" value-key="id" class="filter-item" style="width: 100%;">
|
||||
<el-option v-for="item in courseList" :key="item.id" :label="item.courseName + '(' + item.teacherName + ')'" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="saveParent()">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { formatMonth, getWeeks, formatDay, getDays } from '@/utils'
|
||||
import { fetchScheduleList, fetchCourseByClassId, updateSchedule } from '@/api/user'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
tableHeight: {
|
||||
type: String,
|
||||
default: window.innerHeight - 240 + 'px'
|
||||
},
|
||||
classId: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
},
|
||||
teacherId: {
|
||||
type: String,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
disabled: true,
|
||||
dialogVisible: false,
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
fid: this.$store.state.user.fid,
|
||||
year: 2018,
|
||||
semester: 2,
|
||||
classId: this.classId,
|
||||
teacherId: this.teacherId,
|
||||
importance: undefined,
|
||||
title: undefined,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
importanceOptions: [1, 2, 3],
|
||||
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
||||
statusOptions: [{ name: '在读', id: 1 }, { name: '转学', id: 0 }],
|
||||
showReviewer: false,
|
||||
dialogFormVisible: false,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
gradeList: undefined,
|
||||
classList: undefined,
|
||||
props: {
|
||||
label: 'name',
|
||||
value: 'id',
|
||||
children: 'clazzList'
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
|
||||
stuNo: [{ required: true, message: '学号不能为空', trigger: 'blur' }],
|
||||
course: [{ required: true, message: '必须选择一门课程', trigger: 'change' }]
|
||||
},
|
||||
downloadLoading: false,
|
||||
time: [],
|
||||
schedule: [[], [], [], [], [], [], []],
|
||||
courseList: [],
|
||||
formLabelAlign: {
|
||||
class: {},
|
||||
classId: [],
|
||||
course: {},
|
||||
courseName: undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getTimes()
|
||||
if (this.classId) {
|
||||
this.fetchCourseByClassId()
|
||||
}
|
||||
this.get('2018', '2')
|
||||
},
|
||||
methods: {
|
||||
resetParent() {
|
||||
this.formLabelAlign = {
|
||||
class: {},
|
||||
course: undefined,
|
||||
fid: this.$store.state.user.fid,
|
||||
id: undefined,
|
||||
year: 2018,
|
||||
semester: 2,
|
||||
teacherId: undefined,
|
||||
week: undefined,
|
||||
courseId: undefined,
|
||||
sequence: undefined
|
||||
}
|
||||
},
|
||||
updateParent(week, sequence, item) {
|
||||
if (this.classId) {
|
||||
this.resetParent()
|
||||
if (item) {
|
||||
this.formLabelAlign.id = item.id
|
||||
|
||||
this.formLabelAlign.course = item.courseName + '(' + item.teacherName + ')'
|
||||
}
|
||||
this.formLabelAlign.week = week
|
||||
this.formLabelAlign.sequence = sequence
|
||||
this.dialogVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['ruleForm'].clearValidate()
|
||||
})
|
||||
}
|
||||
},
|
||||
saveParent(item) {
|
||||
this.$refs['ruleForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.formLabelAlign.courseId = this.formLabelAlign.course.id
|
||||
if (this.formLabelAlign.courseId) {
|
||||
this.formLabelAlign.teacherId = this.formLabelAlign.course.teacherId
|
||||
updateSchedule(this.formLabelAlign).then(response => {
|
||||
this.get('2018', '2')
|
||||
this.dialogVisible = false
|
||||
})
|
||||
} else {
|
||||
this.dialogVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
fetchCourseByClassId: function() {
|
||||
fetchCourseByClassId(this.classId).then(response => {
|
||||
this.courseList = response.data.result
|
||||
})
|
||||
},
|
||||
get: function(year, semester) {
|
||||
fetchScheduleList(this.listQuery)
|
||||
.then(response => {
|
||||
var tempSchedule = [[], [], [], [], [], [], []]
|
||||
var result = response.data.result
|
||||
tempSchedule[0][11] = undefined
|
||||
tempSchedule[1][11] = undefined
|
||||
tempSchedule[2][11] = undefined
|
||||
tempSchedule[3][11] = undefined
|
||||
tempSchedule[4][11] = undefined
|
||||
tempSchedule[5][11] = undefined
|
||||
tempSchedule[6][11] = undefined
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
var week = result[i].week
|
||||
var sequence = result[i].sequence
|
||||
if (week === 0) {
|
||||
tempSchedule[0][sequence] = result[i]
|
||||
} else if (week === 1) {
|
||||
tempSchedule[1][sequence] = result[i]
|
||||
} else if (week === 2) {
|
||||
tempSchedule[2][sequence] = result[i]
|
||||
} else if (week === 3) {
|
||||
tempSchedule[3][sequence] = result[i]
|
||||
} else if (week === 4) {
|
||||
tempSchedule[4][sequence] = result[i]
|
||||
}
|
||||
}
|
||||
this.schedule = tempSchedule
|
||||
})
|
||||
},
|
||||
getDate: function(data) {
|
||||
return formatDay(data)
|
||||
},
|
||||
getTimes: function() {
|
||||
// this.time=getDays();
|
||||
var day = getDays()
|
||||
for (var i = 0; i < 7; i++) {
|
||||
this.time[i] = day[i]
|
||||
}
|
||||
},
|
||||
setWeeks: function(data) {
|
||||
return getWeeks(data)
|
||||
},
|
||||
getMonth: function() {
|
||||
return formatMonth()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,435 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container" style="float: right;">
|
||||
<el-button v-if="type" class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">{{ $t('group.add') }}</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="list"
|
||||
:height="tableHeight"
|
||||
:row-key="getRowKeys"
|
||||
max-height="700px"
|
||||
border
|
||||
fit
|
||||
highlight-current-row
|
||||
style="width:100%;overflow:auto;"
|
||||
@selection-change="handleSelectionChange">
|
||||
<el-table-column :label="$t('id')" align="center" width="60px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ (listQuery.page-1) * listQuery.limit + scope.$index + 1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('group.name')" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('createDate')" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('comment')" min-width="30%" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.comment }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.actions')" align="center" width="80px" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button>
|
||||
<el-dropdown class="avatar-container right-menu-item" trigger="click">
|
||||
<i style="cursor:pointer" class="el-icon-caret-bottom"/>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item>
|
||||
<span style="display:block;" @click="handleUpdate(scope.row, false)">查 看</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="type" divided>
|
||||
<span style="display:block;" @click="handleUpdate(scope.row, true)">{{ $t('edit') }}</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="type" divided>
|
||||
<span style="display:block;" @click="handleDeleteGroup(scope.row)">{{ $t('delete') }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-container">
|
||||
<el-pagination :current-page="listQuery.page" :page-sizes="[10,20,30,50]" :page-size="listQuery.limit" :total="total" background layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange"/>
|
||||
</div>
|
||||
|
||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" append-to-body width="40%">
|
||||
<el-form ref="dataForm" :rules="rules" :model="temp" :disabled="disabled" label-position="right">
|
||||
<el-form-item label="组名" label-width="60px">
|
||||
<el-input v-model="temp.name" :rows="1" :minlength="4" :maxlength="50" type="text" placeholder="请输入标题(少于50字)" style="width:95%;"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('comment')" label-width="60px">
|
||||
<el-input :autosize="{ minRows: 2, maxRows: 4}" v-model="temp.comment" type="textarea" placeholder="描述..." style="width:95%;"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button v-if="!disabled" type="success" size="mini" @click="selectUser">添加成员</el-button>
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="temp.userList"
|
||||
:height="300"
|
||||
border
|
||||
style="width:100%;overflow:auto;">
|
||||
<el-table-column :label="$t('id')" align="center" min-width="10%">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.$index + 1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="姓名" min-width="30%" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="角色" min-width="30%" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.roles.includes(1)? "教师" : "学生" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="!disabled" :label="$t('table.actions')" align="center" min-width="30%" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="danger" size="mini" @click="handleDeleteUser(scope.row)">{{ $t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="updateData">{{ $t('table.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<showUser v-if="hackReset" ref="showUser" @listenToChildEvent="getSelectUser"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchGroupList, fetchPv, fetchMemberList, updateArticle, deleteGroup } from '@/api/group'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
import { parseTime } from '@/utils'
|
||||
import showUser from '@/views/group/showUser'
|
||||
|
||||
const calendarTypeOptions = [
|
||||
{ key: '1', display_name: '老师' },
|
||||
{ key: '2', display_name: '学生' },
|
||||
{ key: '3', display_name: '家长' }
|
||||
]
|
||||
|
||||
// arr to obj ,such as { CN : "China", US : "USA" }
|
||||
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
|
||||
acc[cur.key] = cur.display_name
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
components: { showUser },
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
},
|
||||
typeFilter(type) {
|
||||
return calendarTypeKeyValue[type]
|
||||
}
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
tableHeight: {
|
||||
type: String,
|
||||
default: window.innerHeight - 240 + 'px'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
disabled: true,
|
||||
hackReset: false,
|
||||
tableKey: 0,
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
importance: undefined,
|
||||
title: undefined,
|
||||
fid: this.$store.state.user.fid,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
userList: null,
|
||||
importanceOptions: [1, 2, 3],
|
||||
calendarTypeOptions,
|
||||
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
||||
statusOptions: ['published', 'draft', 'deleted'],
|
||||
showReviewer: false,
|
||||
temp: {
|
||||
groupId: undefined,
|
||||
name: undefined,
|
||||
userList: [],
|
||||
fid: this.$store.state.user.fid,
|
||||
comment: ''
|
||||
},
|
||||
dialogFormVisible: false,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
type: [{ required: true, message: 'type is required', trigger: 'change' }],
|
||||
timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
|
||||
title: [{ required: true, message: 'title is required', trigger: 'blur' }]
|
||||
},
|
||||
downloadLoading: false,
|
||||
groupList: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
handleSelectionChange(val) {
|
||||
this.groupList = val
|
||||
},
|
||||
getRowKeys(row) {
|
||||
return row.groupId
|
||||
},
|
||||
getSelectGroup() {
|
||||
return this.groupList
|
||||
},
|
||||
selectUser() {
|
||||
this.hackReset = false
|
||||
if (this.$refs.showUser) {
|
||||
this.$refs.showUser.handleModifyStatus()
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.hackReset = true
|
||||
})
|
||||
},
|
||||
getSelectUser: function(data) {
|
||||
for (const v of data) {
|
||||
var flag = true
|
||||
for (const userData of this.temp.userList) {
|
||||
if (v.uid === userData.uid) {
|
||||
flag = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
this.temp.userList.push(v)
|
||||
}
|
||||
}
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchGroupList(this.listQuery).then(response => {
|
||||
if (response.data.code === 200) {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
this.dialogFormVisible = false
|
||||
this.listLoading = false
|
||||
} else {
|
||||
this.$notify({
|
||||
title: '失败',
|
||||
message: response.data.message,
|
||||
type: 'error',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getMemberList() {
|
||||
this.listLoading = true
|
||||
fetchMemberList(this.listQuery).then(response => {
|
||||
if (response.data.code === 200) {
|
||||
this.memberList.push(response.data.result)
|
||||
this.dialogFormVisible = false
|
||||
this.listLoading = false
|
||||
} else {
|
||||
this.$notify({
|
||||
title: '失败',
|
||||
message: response.data.message,
|
||||
type: 'error',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus(row, status) {
|
||||
this.$message({
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
row.status = status
|
||||
},
|
||||
resetTemp() {
|
||||
this.temp = {
|
||||
groupId: undefined,
|
||||
name: undefined,
|
||||
userList: [],
|
||||
fid: this.$store.state.user.fid,
|
||||
comment: ''
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.disabled = false
|
||||
this.resetTemp()
|
||||
this.dialogStatus = 'create'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
createData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
|
||||
this.temp.author = 'vue-element-admin'
|
||||
}
|
||||
})
|
||||
},
|
||||
handleUpdate(row, disabled) {
|
||||
this.disabled = !disabled
|
||||
fetchMemberList(row.groupId).then(response => {
|
||||
if (response.data.code === 200) {
|
||||
this.temp.userList = response.data.result
|
||||
} else {
|
||||
this.$notify({
|
||||
title: '失败',
|
||||
message: response.data.message,
|
||||
type: 'error',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
})
|
||||
this.temp = Object.assign({}, row) // copy obj
|
||||
this.temp.timestamp = new Date(this.temp.timestamp)
|
||||
this.dialogStatus = 'update'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
updateData() {
|
||||
if (!this.disabled) {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
|
||||
updateArticle(tempData).then(response => {
|
||||
if (tempData.groupId) {
|
||||
for (const v of this.list) {
|
||||
if (v.groupId === this.temp.groupId) {
|
||||
const index = this.list.indexOf(v)
|
||||
this.list.splice(index, 1, this.temp)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.list.unshift(response.data.result)
|
||||
}
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.dialogFormVisible = false
|
||||
}
|
||||
},
|
||||
handleDeleteUser(row) {
|
||||
var index = this.temp.userList.indexOf(row)
|
||||
this.temp.userList.splice(index, 1)
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
},
|
||||
handleDeleteGroup(row) {
|
||||
deleteGroup(row.groupId).then(response => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
handleFetchPv(pv) {
|
||||
fetchPv(pv).then(response => {
|
||||
this.pvData = response.data.pvData
|
||||
this.dialogPvVisible = true
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const data = this.formatJson(filterVal, this.list)
|
||||
excel.export_json_to_excel({
|
||||
header: tHeader,
|
||||
data,
|
||||
filename: 'table-list'
|
||||
})
|
||||
this.downloadLoading = false
|
||||
})
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style rel="stylesheet/scss" lang="scss">
|
||||
.el-table .cell {
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
/** style (注意不要设为scoped) */
|
||||
/** configurationTable和afterRenderClass都是为了标记仅这个组件内修改 */
|
||||
.configurationTable .el-table__body-wrapper {
|
||||
overflow: auto;
|
||||
}
|
||||
.afterRenderClass {
|
||||
.el-table__body-wrapper {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,258 @@
|
|||
<template>
|
||||
<el-dialog :visible.sync="dialogFormVisible" title="收件人" width="60%" height="2200">
|
||||
<el-tabs type="border-card" style="height: 610px;margin-top:-10px;margin-bottom:10px;" >
|
||||
<el-tab-pane label="教师">
|
||||
<teacherComplexTable ref="teacherComplexTable" :table-height="520 + 'px'" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="学生">
|
||||
<studentComplexTable ref="studentComplexTable" :table-height="480 + 'px'" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="addUser">{{ $t('table.add') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList, fetchPv, createArticle, updateArticle } from '@/api/article'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
import { parseTime } from '@/utils'
|
||||
import studentComplexTable from '@/views/student/complexTable'
|
||||
import teacherComplexTable from '@/views/teacher/complexTable'
|
||||
|
||||
const calendarTypeOptions = [
|
||||
{ key: 'CN', display_name: 'China' },
|
||||
{ key: 'US', display_name: 'USA' },
|
||||
{ key: 'JP', display_name: 'Japan' },
|
||||
{ key: 'EU', display_name: 'Eurozone' }
|
||||
]
|
||||
|
||||
// arr to obj ,such as { CN : "China", US : "USA" }
|
||||
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
|
||||
acc[cur.key] = cur.display_name
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
export default {
|
||||
name: 'ShowUser',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
},
|
||||
typeFilter(type) {
|
||||
return calendarTypeKeyValue[type]
|
||||
}
|
||||
},
|
||||
components: {
|
||||
studentComplexTable,
|
||||
teacherComplexTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
totalStuCount: 0,
|
||||
tableKey: 0,
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
importance: undefined,
|
||||
title: undefined,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
classId: undefined,
|
||||
teacherName: undefined,
|
||||
importanceOptions: [1, 2, 3],
|
||||
calendarTypeOptions,
|
||||
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
||||
statusOptions: ['published', 'draft', 'deleted'],
|
||||
showReviewer: false,
|
||||
temp: {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
type: '',
|
||||
status: 'published'
|
||||
},
|
||||
dialogFormVisible: true,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
type: [{ required: true, message: 'type is required', trigger: 'change' }],
|
||||
timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
|
||||
title: [{ required: true, message: 'title is required', trigger: 'blur' }]
|
||||
},
|
||||
downloadLoading: false,
|
||||
userList: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
addUser() {
|
||||
this.userList = this.$refs.teacherComplexTable.getSelectUser().concat(this.$refs.studentComplexTable.getSelectUser())
|
||||
this.dialogFormVisible = false
|
||||
this.$emit('listenToChildEvent', this.userList)
|
||||
},
|
||||
getTotalStu: function(data) {
|
||||
this.totalStuCount = data
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.items
|
||||
this.total = response.data.total
|
||||
|
||||
// Just to simulate the time of the request
|
||||
setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 1.5 * 1000)
|
||||
})
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus() {
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
resetTemp() {
|
||||
this.temp = {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
status: 'published',
|
||||
type: ''
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp()
|
||||
this.dialogStatus = 'create'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
createData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
|
||||
this.temp.author = 'vue-element-admin'
|
||||
createArticle(this.temp).then(() => {
|
||||
this.list.unshift(this.temp)
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleUpdate(row) {
|
||||
this.temp = Object.assign({}, row) // copy obj
|
||||
this.temp.timestamp = new Date(this.temp.timestamp)
|
||||
this.dialogStatus = 'update'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
updateData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
|
||||
updateArticle(tempData).then(() => {
|
||||
for (const v of this.list) {
|
||||
if (v.id === this.temp.id) {
|
||||
const index = this.list.indexOf(v)
|
||||
this.list.splice(index, 1, this.temp)
|
||||
break
|
||||
}
|
||||
}
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
const index = this.list.indexOf(row)
|
||||
this.list.splice(index, 1)
|
||||
},
|
||||
handleFetchPv(pv) {
|
||||
fetchPv(pv).then(response => {
|
||||
this.pvData = response.data.pvData
|
||||
this.dialogPvVisible = true
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const data = this.formatJson(filterVal, this.list)
|
||||
excel.export_json_to_excel({
|
||||
header: tHeader,
|
||||
data,
|
||||
filename: 'table-list'
|
||||
})
|
||||
this.downloadLoading = false
|
||||
})
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -3,47 +3,31 @@
|
|||
<hamburger :toggle-click="toggleSideBar" :is-active="sidebar.opened" class="hamburger-container"/>
|
||||
|
||||
<breadcrumb class="breadcrumb-container"/>
|
||||
|
||||
<div class="right-menu">
|
||||
<template v-if="device!=='mobile'">
|
||||
<error-log class="errLog-container right-menu-item"/>
|
||||
|
||||
<el-tooltip :content="$t('navbar.screenfull')" effect="dark" placement="bottom">
|
||||
<screenfull class="screenfull right-menu-item"/>
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip :content="$t('navbar.size')" effect="dark" placement="bottom">
|
||||
<size-select class="international right-menu-item"/>
|
||||
</el-tooltip>
|
||||
|
||||
<lang-select class="international right-menu-item"/>
|
||||
|
||||
<el-tooltip :content="$t('navbar.theme')" effect="dark" placement="bottom">
|
||||
<theme-picker class="theme-switch right-menu-item"/>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
<el-dropdown class="avatar-container right-menu-item" trigger="click">
|
||||
<div class="avatar-wrapper">
|
||||
<img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">
|
||||
<i class="el-icon-caret-bottom"/>
|
||||
<div>
|
||||
<span style="color: slategray;">{{ $store.state.user.name }}</span>
|
||||
<el-dropdown class="avatar-container right-menu-item" trigger="click">
|
||||
<i style="cursor:pointer" class="el-icon-caret-bottom"/>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<router-link to="/">
|
||||
<el-dropdown-item>
|
||||
{{ $t('navbar.dashboard') }}
|
||||
</el-dropdown-item>
|
||||
</router-link>
|
||||
<router-link to="/">
|
||||
<el-dropdown-item>
|
||||
个人中心
|
||||
</el-dropdown-item>
|
||||
</router-link>
|
||||
<el-dropdown-item divided>
|
||||
<span style="display:block;" @click="logout">{{ $t('navbar.logOut') }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<router-link to="/">
|
||||
<el-dropdown-item>
|
||||
{{ $t('navbar.dashboard') }}
|
||||
</el-dropdown-item>
|
||||
</router-link>
|
||||
<a target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">
|
||||
<el-dropdown-item>
|
||||
{{ $t('navbar.github') }}
|
||||
</el-dropdown-item>
|
||||
</a>
|
||||
<el-dropdown-item divided>
|
||||
<span style="display:block;" @click="logout">{{ $t('navbar.logOut') }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -90,6 +74,31 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.Botton {
|
||||
display: inline-block;
|
||||
text-align:center;
|
||||
color: slategray;
|
||||
}
|
||||
.title {
|
||||
position:absolute;
|
||||
left:40%;
|
||||
}
|
||||
.item {
|
||||
margin-top: -30px;
|
||||
margin-right: 1px;
|
||||
}
|
||||
.el-badge__content.is-dot {
|
||||
height: 10px !important;
|
||||
width: 10px !important;
|
||||
top: 12px !important;
|
||||
}
|
||||
.el-badge__content.is-fixed {
|
||||
position: absolute;
|
||||
top: 12px !important;
|
||||
right: 10px;
|
||||
-webkit-transform: translateY(-50%) translateX(100%);
|
||||
transform: translateY(-50%) translateX(100%);
|
||||
}
|
||||
.navbar {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<div class="fm-header">
|
||||
<img class="fm-logo" src="./assets/logo.png">
|
||||
<div class="fm-title">表单设计器</div>
|
||||
|
||||
<div style="color: #fff; font-size: 13px; position: absolute; top: 24px; left: 200px;">
|
||||
QQ交流群:902048874
|
||||
</div>
|
||||
|
||||
<div class="fm-link">
|
||||
<a href="https://github.com/GavinZhuLei/vue-form-making">GitHub</a>
|
||||
<a href="https://gitee.com/gavinzhulei/vue-form-making">码云</a>
|
||||
<a href="http://www.xiaoyaoji.cn" target="_blank">小幺鸡接口文档</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fm-container"><router-view/></div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import FormMaking from 'form-making'
|
||||
import 'form-making/dist/FormMaking.css'
|
||||
|
||||
export default {
|
||||
name: 'CreateForm',
|
||||
components: { FormMaking },
|
||||
data() {
|
||||
return {
|
||||
hackReset: false,
|
||||
disabled: false,
|
||||
dialogFormVisible: false,
|
||||
userList: [],
|
||||
articleId: this.$route.params.id,
|
||||
article: {
|
||||
id: undefined,
|
||||
fid: this.$store.state.user.fid,
|
||||
title: undefined,
|
||||
upload: 0,
|
||||
type: '',
|
||||
content: '',
|
||||
group: undefined,
|
||||
attachmentList: [],
|
||||
receiverList: [],
|
||||
status: 'published'
|
||||
},
|
||||
receiverList: [],
|
||||
listQuery: {
|
||||
fid: this.$store.state.user.fid,
|
||||
importance: undefined,
|
||||
name: undefined,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
input: '',
|
||||
users: undefined,
|
||||
groups: undefined,
|
||||
value7: '',
|
||||
rules: {
|
||||
title: [
|
||||
{ required: true, message: '请输入标题', trigger: 'blur' },
|
||||
{ min: 4, max: 50, message: '长度必须在4到50个字符之间', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchArticle()
|
||||
},
|
||||
methods: {
|
||||
handleDeleteUser(index) {
|
||||
this.article.receiverList.splice(index, 1)
|
||||
},
|
||||
getSelectUser: function(data) {
|
||||
var tempList = []
|
||||
var userList = data.get('user')
|
||||
for (var index in userList) {
|
||||
var userReceiver = {}
|
||||
userReceiver.uid = userList[index].uid
|
||||
userReceiver.name = userList[index].name
|
||||
userReceiver.roles = [1]
|
||||
tempList.push(userReceiver)
|
||||
}
|
||||
var groupList = data.get('group')
|
||||
for (var i in groupList) {
|
||||
var groupReceiver = {}
|
||||
groupReceiver.uid = groupList[i].groupId
|
||||
groupReceiver.name = groupList[i].name
|
||||
groupReceiver.roles = [3]
|
||||
tempList.push(groupReceiver)
|
||||
}
|
||||
for (const v of tempList) {
|
||||
var flag = true
|
||||
for (const userData of this.article.receiverList) {
|
||||
if (v.uid === userData.uid && v.roles[0] === userData.roles[0]) {
|
||||
flag = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
this.article.receiverList.push(v)
|
||||
}
|
||||
}
|
||||
},
|
||||
showSelectUser() {
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
selectUser() {
|
||||
this.hackReset = false
|
||||
if (this.$refs.showUser) {
|
||||
this.$refs.showUser.handleModifyStatus()
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.hackReset = true
|
||||
})
|
||||
},
|
||||
ready(editorInstance) {
|
||||
console.log(`编辑器实例${editorInstance.key}: `, editorInstance)
|
||||
// setInterval(this.getUEContent,10000)
|
||||
},
|
||||
|
||||
getUEContent: function() {
|
||||
console.log(this.msg)
|
||||
},
|
||||
|
||||
draft: function() {
|
||||
console.log(this.msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
<template>
|
||||
<el-dialog :visible.sync="dialogFormVisible" title="请假" width="40%">
|
||||
<el-form ref="ruleForm" :model="ruleForm" :rules="rules" style="magin-top:-100px;" label-width="100px" class="demo-ruleForm">
|
||||
<el-form-item label="请假类型">
|
||||
<el-select v-model="ruleForm.type" class="filter-item" style="width:90%;">
|
||||
<el-option v-for="item in leaveTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" required>
|
||||
<el-col style="width:60%;">
|
||||
<el-form-item prop="date1">
|
||||
<el-date-picker v-model="ruleForm.date1" type="date" placeholder="选择日期" style="width: 100%;"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col style="width:30%;">
|
||||
<el-form-item>
|
||||
<el-select v-model="ruleForm.region" placeholder="请选择活动区域" style="magin-left:20px;">
|
||||
<el-option label="上午" value="0"/>
|
||||
<el-option label="下午" value="1/"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" required>
|
||||
<el-col style="width:60%;">
|
||||
<el-form-item prop="date1">
|
||||
<el-date-picker v-model="ruleForm.date1" type="date" placeholder="选择日期" style="width: 100%;"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col style="width:30%;">
|
||||
<el-form-item>
|
||||
<el-select v-model="ruleForm.region" placeholder="请选择活动区域">
|
||||
<el-option label="上午" value="0"/>
|
||||
<el-option label="下午" value="1/"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="时长" prop="name">
|
||||
<el-input v-model="ruleForm.name" style="width:90%;"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="请假事由" prop="desc">
|
||||
<el-input v-model="ruleForm.desc" type="textarea" style="width:90%;"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
|
||||
<el-button @click="resetForm('ruleForm')">重置</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
|
||||
const leaveTypeOptions = [
|
||||
{ key: 0, display_name: '事假' },
|
||||
{ key: 1, display_name: '年假' },
|
||||
{ key: 2, display_name: '病假' },
|
||||
{ key: 3, display_name: '产假' },
|
||||
{ key: 4, display_name: '陪产假' },
|
||||
{ key: 5, display_name: '婚假' },
|
||||
{ key: 6, display_name: '丧假' }
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogFormVisible: false,
|
||||
leaveTypeOptions,
|
||||
ruleForm: {
|
||||
name: '',
|
||||
region: '0',
|
||||
date1: '',
|
||||
date2: '',
|
||||
delivery: false,
|
||||
type: 0,
|
||||
resource: '',
|
||||
desc: ''
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: '请输入活动名称', trigger: 'blur' },
|
||||
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
|
||||
],
|
||||
region: [
|
||||
{ required: true, message: '请选择活动区域', trigger: 'change' }
|
||||
],
|
||||
date1: [
|
||||
{ type: 'date', required: true, message: '请选择日期', trigger: 'change' }
|
||||
],
|
||||
date2: [
|
||||
{ type: 'date', required: true, message: '请选择时间', trigger: 'change' }
|
||||
],
|
||||
type: [
|
||||
{ type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }
|
||||
],
|
||||
resource: [
|
||||
{ required: true, message: '请选择活动资源', trigger: 'change' }
|
||||
],
|
||||
desc: [
|
||||
{ required: true, message: '请填写活动形式', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitForm(formName) {
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
alert('submit!')
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields()
|
||||
},
|
||||
showEditDialog() {
|
||||
this.dialogFormVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,234 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container" style="float:right; margin-top:-10px;">
|
||||
<el-button class="filter-item" style="margin-right: 10px;" type="primary" icon="el-icon-edit" @click="createLeave()">新建</el-button>
|
||||
</div>
|
||||
<div style="margin-top:-10px">
|
||||
<el-table v-loading.body="listLoading" :show-overflow-tooltip="true" :data="list" border fit highlight-current-row style="width: 100%">
|
||||
<el-table-column align="center" label="ID" width="80">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.$index + 1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" width="150px" label="发布者">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="200px" align="center" label="发布时间">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.modifyTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" max-width="500px" align="left" label="标题">
|
||||
<template slot-scope="scope">
|
||||
<router-link :to="'/leave/'+scope.row.id" class="link-type" target="_blank">
|
||||
<span>{{ scope.row.title }}</span>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="300px" align="left" label="附件">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.articleAttachment && scope.row.articleAttachment.attachmentName" class="el-tag el-tag--info el-tag--small">
|
||||
<a class="link-type" @click="download(scope.row.articleAttachment.url, scope.row.articleAttachment.attachmentName)">{{ scope.row.articleAttachment.attachmentName }}</a>
|
||||
<i class="el-tag__close el-icon-close" @click="deleteAttachment(scope.row)"/>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('action')" align="center" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button style="margin:5px;float:right">
|
||||
<el-dropdown class="avatar-container right-menu-item" trigger="click">
|
||||
<i style="cursor:pointer" class="el-icon-caret-bottom"/>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<router-link :to="'/leave/edit/'+scope.row.id">
|
||||
<el-dropdown-item>
|
||||
{{ $t('edit') }}
|
||||
</el-dropdown-item>
|
||||
</router-link>
|
||||
<el-dropdown-item v-if="scope.row.upload===1" divided>
|
||||
<span style="display:block;" @click="showUploadData(scope.row)">查 看</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided>
|
||||
<span style="display:block;" @click="deleteArticle(scope.row)">{{ $t('delete') }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-button>
|
||||
<el-upload
|
||||
v-if="scope.row.upload===1"
|
||||
:action="importFileUrl"
|
||||
:on-remove="handleRemove"
|
||||
:data="uploadData"
|
||||
:on-preview="handlePreview"
|
||||
:on-exceed="handleExceed"
|
||||
:on-success="handleSuccess"
|
||||
:file-list="scope.row.attachmentList"
|
||||
:show-file-list="false"
|
||||
style="float:left;margin:5px;"
|
||||
name="file"
|
||||
><el-button size="mini" @click="handleUpdate(scope.row)"><i class="el-icon-upload el-icon--right"/>上传</el-button>
|
||||
|
||||
</el-upload>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
:current-page="listQuery.page"
|
||||
:page-sizes="[10,20,30, 50]"
|
||||
:page-size="listQuery.limit"
|
||||
:total="total"
|
||||
background
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"/>
|
||||
</div>
|
||||
</div>
|
||||
<leaveEdit ref="leaveEdit"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList, deleteArticle } from '@/api/article'
|
||||
import { downloadFile, deleteAttachment } from '@/api/user'
|
||||
import leaveEdit from '@/views/leave/leaveEdit'
|
||||
|
||||
export default {
|
||||
name: 'ArticleList',
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
},
|
||||
components: {
|
||||
leaveEdit
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
importFileUrl: window.UEDITOR_HOME_URL + 'ueditor/importFile',
|
||||
uploadData: {
|
||||
noticeId: undefined
|
||||
},
|
||||
attachmentList: [
|
||||
{ name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100' }],
|
||||
list: null,
|
||||
total: 0,
|
||||
limit: 1,
|
||||
flag: false,
|
||||
count: 123,
|
||||
rowIndex: undefined,
|
||||
showReviewer: false,
|
||||
dialogPvVisible: false,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
fid: this.$store.getters.user.fid,
|
||||
page: 1,
|
||||
limit: 20
|
||||
},
|
||||
selectRow: undefined
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
createLeave() {
|
||||
this.$refs.leaveEdit.showEditDialog()
|
||||
},
|
||||
deleteArticle(row) {
|
||||
deleteArticle(row.id).then(() => {
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
this.listLoading = false
|
||||
}).catch((error) => {
|
||||
alert(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
download(url, name) {
|
||||
downloadFile(url, name)
|
||||
},
|
||||
showUploadData(item) {
|
||||
this.$refs.leaveEdit.handleModifyStatus(item)
|
||||
},
|
||||
deleteAttachment(row) {
|
||||
this.$confirm('您确定删除吗?').then(_ => {
|
||||
deleteAttachment(row.articleAttachment).then(() => {
|
||||
row.articleAttachment = undefined
|
||||
})
|
||||
}).catch(_ => {
|
||||
})
|
||||
},
|
||||
handleUpdate(row) {
|
||||
this.uploadData.noticeId = row.id
|
||||
this.selectRow = row
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
this.listLoading = false
|
||||
}).catch((error) => {
|
||||
alert(error)
|
||||
})
|
||||
},
|
||||
handleRemove(file, attachmentList) {
|
||||
alert(file, attachmentList)
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
showDetail() {
|
||||
this.flag = !this.flag
|
||||
},
|
||||
handlePreview(file) {
|
||||
this.$message.warning(`file url = ` + file.url)
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleSuccess(response, file, attachmentList) {
|
||||
if (response == null) {
|
||||
return
|
||||
}
|
||||
this.selectRow.attachmentList = []
|
||||
this.selectRow.articleAttachment = response
|
||||
this.showReviewer = true
|
||||
},
|
||||
handleExceed(files, attachmentList) {
|
||||
this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + attachmentList.length} 个文件`)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.edit-input {
|
||||
padding-right: 100px;
|
||||
}
|
||||
.cancel-btn {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
.demo-block {
|
||||
border: 1px solid #ebebeb;
|
||||
border-radius: 3px;
|
||||
transition: .2s;
|
||||
margin:20px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,228 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<span v-html="message"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { fetchArticle } from '@/api/article'
|
||||
|
||||
export default {
|
||||
name: 'Show',
|
||||
data() {
|
||||
return {
|
||||
message: undefined
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchArticle()
|
||||
},
|
||||
methods: {
|
||||
fetchArticle() {
|
||||
this.listLoading = true
|
||||
fetchArticle(this.$route.params.id).then(response => {
|
||||
if (response.data.code === 200) {
|
||||
this.message = response.data.result.content
|
||||
}
|
||||
this.listLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.wscn-http404-container{
|
||||
transform: translate(-50%,-50%);
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
}
|
||||
.wscn-http404 {
|
||||
position: relative;
|
||||
width: 1200px;
|
||||
padding: 0 50px;
|
||||
overflow: hidden;
|
||||
.pic-404 {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 600px;
|
||||
overflow: hidden;
|
||||
&__parent {
|
||||
width: 100%;
|
||||
}
|
||||
&__child {
|
||||
position: absolute;
|
||||
&.left {
|
||||
width: 80px;
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
animation-name: cloudLeft;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
&.mid {
|
||||
width: 46px;
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
animation-name: cloudMid;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
&.right {
|
||||
width: 62px;
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
animation-name: cloudRight;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
@keyframes cloudLeft {
|
||||
0% {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 33px;
|
||||
left: 188px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
top: 81px;
|
||||
left: 92px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 97px;
|
||||
left: 60px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes cloudMid {
|
||||
0% {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 40px;
|
||||
left: 360px;
|
||||
opacity: 1;
|
||||
}
|
||||
70% {
|
||||
top: 130px;
|
||||
left: 180px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 160px;
|
||||
left: 120px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes cloudRight {
|
||||
0% {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 120px;
|
||||
left: 460px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
top: 180px;
|
||||
left: 340px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 200px;
|
||||
left: 300px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.bullshit {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 300px;
|
||||
padding: 30px 0;
|
||||
overflow: hidden;
|
||||
&__oops {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
line-height: 40px;
|
||||
color: #1482f0;
|
||||
opacity: 0;
|
||||
margin-bottom: 20px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__headline {
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
color: #222;
|
||||
font-weight: bold;
|
||||
opacity: 0;
|
||||
margin-bottom: 10px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__info {
|
||||
font-size: 13px;
|
||||
line-height: 21px;
|
||||
color: grey;
|
||||
opacity: 0;
|
||||
margin-bottom: 30px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__return-home {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 110px;
|
||||
height: 36px;
|
||||
background: #1482f0;
|
||||
border-radius: 100px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
opacity: 0;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
cursor: pointer;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.3s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
@keyframes slideUp {
|
||||
0% {
|
||||
transform: translateY(60px);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,270 @@
|
|||
<template>
|
||||
<el-dialog :visible.sync="dialogFormVisible" title="收件人" width="60%" height="2200">
|
||||
<el-tabs type="border-card" style="height: 630px;margin-top:-30px;margin-bottom:10px;" >
|
||||
<el-tab-pane label="教师">
|
||||
<teacherComplexTable ref="teacherComplexTable" :table-height="450 + 'px'" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="false" label="班级">
|
||||
<gradeComplexTable ref="gradeComplexTable" :table-height="450 + 'px'" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="false" label="群组">
|
||||
<groupComplexTable ref="groupComplexTable" :table-height="450 + 'px'" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="addUser">{{ $t('table.add') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList, fetchPv, createArticle, updateArticle } from '@/api/article'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
import { parseTime } from '@/utils'
|
||||
import groupComplexTable from '@/views/group/index'
|
||||
import studentComplexTable from '@/views/student/complexTable'
|
||||
import teacherComplexTable from '@/views/teacher/complexTable'
|
||||
import gradeComplexTable from '@/views/grade/complexTable'
|
||||
|
||||
const calendarTypeOptions = [
|
||||
{ key: 'CN', display_name: 'China' },
|
||||
{ key: 'US', display_name: 'USA' },
|
||||
{ key: 'JP', display_name: 'Japan' },
|
||||
{ key: 'EU', display_name: 'Eurozone' }
|
||||
]
|
||||
|
||||
// arr to obj ,such as { CN : "China", US : "USA" }
|
||||
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
|
||||
acc[cur.key] = cur.display_name
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
export default {
|
||||
name: 'ShowUser',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
},
|
||||
typeFilter(type) {
|
||||
return calendarTypeKeyValue[type]
|
||||
}
|
||||
},
|
||||
components: {
|
||||
groupComplexTable,
|
||||
studentComplexTable,
|
||||
teacherComplexTable,
|
||||
gradeComplexTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
totalStuCount: 0,
|
||||
tableKey: 0,
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
importance: undefined,
|
||||
title: undefined,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
classId: undefined,
|
||||
teacherName: undefined,
|
||||
importanceOptions: [1, 2, 3],
|
||||
calendarTypeOptions,
|
||||
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
||||
statusOptions: ['published', 'draft', 'deleted'],
|
||||
showReviewer: false,
|
||||
temp: {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
type: '',
|
||||
status: 'published'
|
||||
},
|
||||
dialogFormVisible: true,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
type: [{ required: true, message: 'type is required', trigger: 'change' }],
|
||||
timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
|
||||
title: [{ required: true, message: 'title is required', trigger: 'blur' }]
|
||||
},
|
||||
downloadLoading: false,
|
||||
userList: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
addUser() {
|
||||
var map = new Map()
|
||||
map.set('user', this.$refs.teacherComplexTable.getSelectUser())
|
||||
// map.set('class', this.$refs.gradeComplexTable.getSelectClass())
|
||||
// map.set('group', this.$refs.groupComplexTable.getSelectGroup())
|
||||
|
||||
// this.userList = this.$refs.teacherComplexTable.getSelectUser().concat(this.$refs.studentComplexTable.getSelectUser())
|
||||
this.dialogFormVisible = false
|
||||
this.$emit('listenToChildEvent', map)
|
||||
},
|
||||
getTotalStu: function(data) {
|
||||
this.totalStuCount = data
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.items
|
||||
this.total = response.data.total
|
||||
|
||||
// Just to simulate the time of the request
|
||||
setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 1.5 * 1000)
|
||||
})
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus() {
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
resetTemp() {
|
||||
this.temp = {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
status: 'published',
|
||||
type: ''
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp()
|
||||
this.dialogStatus = 'create'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
createData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
|
||||
this.temp.author = 'vue-element-admin'
|
||||
createArticle(this.temp).then(() => {
|
||||
this.list.unshift(this.temp)
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleUpdate(row) {
|
||||
this.temp = Object.assign({}, row) // copy obj
|
||||
this.temp.timestamp = new Date(this.temp.timestamp)
|
||||
this.dialogStatus = 'update'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
updateData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
|
||||
updateArticle(tempData).then(() => {
|
||||
for (const v of this.list) {
|
||||
if (v.id === this.temp.id) {
|
||||
const index = this.list.indexOf(v)
|
||||
this.list.splice(index, 1, this.temp)
|
||||
break
|
||||
}
|
||||
}
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
const index = this.list.indexOf(row)
|
||||
this.list.splice(index, 1)
|
||||
},
|
||||
handleFetchPv(pv) {
|
||||
fetchPv(pv).then(response => {
|
||||
this.pvData = response.data.pvData
|
||||
this.dialogPvVisible = true
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const data = this.formatJson(filterVal, this.list)
|
||||
excel.export_json_to_excel({
|
||||
header: tHeader,
|
||||
data,
|
||||
filename: 'table-list'
|
||||
})
|
||||
this.downloadLoading = false
|
||||
})
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,15 +1,26 @@
|
|||
<template>
|
||||
<div class="login-container">
|
||||
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form card-box" auto-complete="on" label-position="left">
|
||||
|
||||
<div class="title-container">
|
||||
<h3 class="title">{{ $t('login.title') }}</h3>
|
||||
<lang-select class="set-language"/>
|
||||
<h3 class="title">登录</h3>
|
||||
</div>
|
||||
|
||||
<el-form-item v-if="false">
|
||||
<span class="svg-container svg-container_login">
|
||||
<svg-icon icon-class="school" />
|
||||
</span>
|
||||
<el-input
|
||||
v-model="loginForm.fid"
|
||||
placeholder="学校名称"
|
||||
name="fid"
|
||||
type="text"
|
||||
auto-complete="on"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item prop="username">
|
||||
<span class="svg-container">
|
||||
<span class="svg-container svg-container_login">
|
||||
<svg-icon icon-class="user" />
|
||||
</span>
|
||||
<el-input
|
||||
|
@ -39,21 +50,9 @@
|
|||
|
||||
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">{{ $t('login.logIn') }}</el-button>
|
||||
|
||||
<div style="position:relative">
|
||||
<div class="tips">
|
||||
<span>{{ $t('login.username') }} : admin</span>
|
||||
<span>{{ $t('login.password') }} : {{ $t('login.any') }}</span>
|
||||
</div>
|
||||
<div class="tips">
|
||||
<span style="margin-right:18px;">{{ $t('login.username') }} : editor</span>
|
||||
<span>{{ $t('login.password') }} : {{ $t('login.any') }}</span>
|
||||
</div>
|
||||
|
||||
<el-button class="thirdparty-button" type="primary" @click="showDialog=true">{{ $t('login.thirdparty') }}</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<el-dialog :title="$t('login.thirdparty')" :visible.sync="showDialog">
|
||||
<el-dialog :title="$t('login.thirdparty')" :visible.sync="showDialog" append-to-body>
|
||||
{{ $t('login.thirdpartyTips') }}
|
||||
<br>
|
||||
<br>
|
||||
|
@ -65,7 +64,6 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { isvalidUsername } from '@/utils/validate'
|
||||
import LangSelect from '@/components/LangSelect'
|
||||
import SocialSign from './socialsignin'
|
||||
|
||||
|
@ -74,23 +72,24 @@ export default {
|
|||
components: { LangSelect, SocialSign },
|
||||
data() {
|
||||
const validateUsername = (rule, value, callback) => {
|
||||
if (!isvalidUsername(value)) {
|
||||
callback(new Error('Please enter the correct user name'))
|
||||
if (value.match(/^[ ]*$/)) {
|
||||
callback(new Error('用户名错误'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
const validatePassword = (rule, value, callback) => {
|
||||
if (value.length < 6) {
|
||||
callback(new Error('The password can not be less than 6 digits'))
|
||||
if (value.length < 6 || value.match(/^[ ]*$/)) {
|
||||
callback(new Error('密码错误'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
loginForm: {
|
||||
username: 'admin',
|
||||
password: '1111111'
|
||||
username: undefined,
|
||||
password: undefined,
|
||||
fid: undefined
|
||||
},
|
||||
loginRules: {
|
||||
username: [{ required: true, trigger: 'blur', validator: validateUsername }],
|
||||
|
@ -129,6 +128,7 @@ export default {
|
|||
if (valid) {
|
||||
this.loading = true
|
||||
this.$store.dispatch('LoginByUsername', this.loginForm).then(() => {
|
||||
sessionStorage.setItem('store', JSON.stringify(this.$store.state))
|
||||
this.loading = false
|
||||
this.$router.push({ path: this.redirect || '/' })
|
||||
}).catch(() => {
|
||||
|
@ -166,9 +166,9 @@ export default {
|
|||
/* 修复input 背景不协调 和光标变色 */
|
||||
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
|
||||
|
||||
$bg:#283443;
|
||||
$light_gray:#eee;
|
||||
$cursor: #fff;
|
||||
$bg:#f4f3f3;
|
||||
$light_gray:#8e928d;
|
||||
$cursor: #050505;
|
||||
|
||||
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
|
||||
.login-container .el-input input{
|
||||
|
@ -193,7 +193,7 @@ export default {
|
|||
padding: 12px 5px 12px 15px;
|
||||
color: $light_gray;
|
||||
height: 47px;
|
||||
caret-color: $cursor;
|
||||
// caret-color: $cursor;
|
||||
&:-webkit-autofill {
|
||||
-webkit-box-shadow: 0 0 0px 1000px $bg inset !important;
|
||||
-webkit-text-fill-color: $cursor !important;
|
||||
|
@ -204,7 +204,7 @@ export default {
|
|||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 5px;
|
||||
color: #454545;
|
||||
// color: #454545;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -217,7 +217,7 @@ $light_gray:#eee;
|
|||
.login-container {
|
||||
min-height: 100%;
|
||||
width: 100%;
|
||||
background-color: $bg;
|
||||
background: left top #f4f3f3;
|
||||
overflow: hidden;
|
||||
.login-form {
|
||||
position: relative;
|
||||
|
@ -248,7 +248,7 @@ $light_gray:#eee;
|
|||
position: relative;
|
||||
.title {
|
||||
font-size: 26px;
|
||||
color: $light_gray;
|
||||
color: #333333;
|
||||
margin: 0px auto 40px auto;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
|
@ -274,5 +274,18 @@ $light_gray:#eee;
|
|||
right: 0;
|
||||
bottom: 6px;
|
||||
}
|
||||
|
||||
.card-box {
|
||||
padding:20px;
|
||||
margin-top: 200px !important;
|
||||
box-shadow:0 0px 8px 0 rgba(0,0,0,0.06),0 1px 0px 0 rgba(0,0,0,0.02);
|
||||
-webkit-border-radius:5px;
|
||||
border-radius:5px;
|
||||
-moz-border-radius:5px;
|
||||
background-clip:padding-box;
|
||||
margin-bottom:20px;
|
||||
background-color:#ffffff;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
发发发
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
</script>
|
|
@ -0,0 +1,300 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:key="tableKey"
|
||||
:data="list"
|
||||
border
|
||||
fit
|
||||
highlight-current-row
|
||||
style="width: 100%;min-height:300px;">
|
||||
<el-table-column :label="$t('table.id')" align="center" width="65">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.$index+1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="年级名称" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip placement="left" effect="light">
|
||||
<div slot="content">{{ scope.row.showName }}</div>
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="执教班级" min-width="150px">
|
||||
<template slot-scope="scope">
|
||||
<span v-for="item in scope.row.clazzList" :key="item.id" class="el-tag el-tag--info el-tag--small" style="margin-left:5px;">
|
||||
<span class="link-type" @click="handleEditClass(item)">{{ item.name }}(班主任:{{ item.teacher.name }})</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="执教科目" min-width="200px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.graduationStatus==1" type="info"> 已毕业</el-tag>
|
||||
<el-tag v-else>在读</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.actions')" align="center" width="230" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-if="$store.state.user.admin" type="primary" size="mini" @click="handleUpdate(scope.row, scope.$index, false)">{{ $t('table.edit') }}</el-button>
|
||||
<el-button size="mini" type="success" @click="handleUpdate(scope.row, scope.$index, true)">查看</el-button>
|
||||
<el-button v-if="$store.state.user.admin" size="mini" type="danger" @click="deleteGrade(scope.row)">{{ $t('table.delete') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
|
||||
<el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="70px" style="width: 400px; margin-left:50px;">
|
||||
<el-form-item :label="$t('table.type')" prop="type">
|
||||
<el-select v-model="temp.type" class="filter-item" placeholder="Please select">
|
||||
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.date')" prop="timestamp">
|
||||
<el-date-picker v-model="temp.timestamp" type="datetime" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.title')" prop="title">
|
||||
<el-input v-model="temp.title"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.status')">
|
||||
<el-select v-model="temp.status" class="filter-item" >
|
||||
<el-option v-for="item in statusOptions" :key="item" :label="item" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.importance')">
|
||||
<el-rate v-model="temp.importance" :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :max="3" style="margin-top:8px;"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.remark')">
|
||||
<el-input :autosize="{ minRows: 2, maxRows: 4}" v-model="temp.remark" type="textarea"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
|
||||
<el-button v-if="dialogStatus=='create'" type="primary" @click="createData">{{ $t('table.confirm') }}</el-button>
|
||||
<el-button v-else type="primary" @click="updateData">{{ $t('table.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :visible.sync="dialogPvVisible" title="Reading statistics">
|
||||
<el-table :data="pvData" border fit highlight-current-row style="width: 100%">
|
||||
<el-table-column prop="key" label="Channel"/>
|
||||
<el-table-column prop="pv" label="Pv"/>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="dialogPvVisible = false">{{ $t('table.confirm') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<edit-grade ref="editGrade" @listenToChildEvent="updateGradeRow"/>
|
||||
<edit-class ref="showClass"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { createArticle, updateArticle } from '@/api/article'
|
||||
import { fetchGradeList, deleteGrade } from '@/api/user'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
import editClass from '@/views/grade/editClass'
|
||||
import editGrade from '@/views/grade/editGrade'
|
||||
import { parseTime } from '@/utils'
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
components: {
|
||||
editClass,
|
||||
editGrade
|
||||
},
|
||||
props: {
|
||||
teacherId: {
|
||||
type: String,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hackReset: true,
|
||||
tableKey: 0,
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
fid: this.$store.state.user.fid,
|
||||
name: undefined,
|
||||
importance: undefined,
|
||||
title: undefined,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
importanceOptions: [1, 2, 3],
|
||||
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
||||
statusOptions: ['published', 'draft', 'deleted'],
|
||||
showReviewer: false,
|
||||
temp: {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
type: '',
|
||||
status: 'published'
|
||||
},
|
||||
dialogFormVisible: false,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
type: [{ required: true, message: 'type is required', trigger: 'change' }],
|
||||
timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
|
||||
title: [{ required: true, message: 'title is required', trigger: 'blur' }]
|
||||
},
|
||||
classId: undefined,
|
||||
downloadLoading: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
updateGradeRow: function(rowData, index) {
|
||||
if (index > -1) {
|
||||
this.list.splice(index, 1, rowData)
|
||||
} else {
|
||||
this.list.unshift(rowData)
|
||||
}
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchGradeList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
this.listLoading = false
|
||||
})
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus(row, status) {
|
||||
this.$message({
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
row.status = status
|
||||
},
|
||||
deleteGrade(row) {
|
||||
deleteGrade(row.id).then(response => {
|
||||
fetchGradeList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
})
|
||||
})
|
||||
},
|
||||
resetTemp() {
|
||||
this.temp = {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
status: 'published',
|
||||
type: ''
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp()
|
||||
this.dialogStatus = 'create'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
createData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
|
||||
this.temp.author = 'vue-element-admin'
|
||||
createArticle(this.temp).then(response => {
|
||||
this.list.unshift(this.temp)
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleUpdate(row, index, disabled) {
|
||||
this.$refs.editGrade.handleModifyStatus(row, index, disabled)
|
||||
},
|
||||
handleEditClass(item) {
|
||||
if (this.$refs.showClass) {
|
||||
this.$refs.showClass.handleModifyStatus(item)
|
||||
}
|
||||
},
|
||||
updateData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
|
||||
updateArticle(tempData).then(() => {
|
||||
for (const v of this.list) {
|
||||
if (v.id === this.temp.id) {
|
||||
const index = this.list.indexOf(v)
|
||||
this.list.splice(index, 1, this.temp)
|
||||
break
|
||||
}
|
||||
}
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
const index = this.list.indexOf(row)
|
||||
this.list.splice(index, 1)
|
||||
},
|
||||
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,71 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<complexTable ref="complexTable" :type="false" :table-height="600 + 'px'" :class-id="classId" @listenToChildEvent="getTotalStu"/>
|
||||
<div>
|
||||
<el-tag>班主任 :{{ teacherName }}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import complexTable from '@/views/student/complexTable'
|
||||
|
||||
export default {
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
},
|
||||
components: {
|
||||
complexTable
|
||||
},
|
||||
props: {
|
||||
classId: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
},
|
||||
teacherName: {
|
||||
type: String,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
total: null,
|
||||
importanceOptions: [1, 2, 3],
|
||||
calendarTypeOptions: [
|
||||
{ key: '1', display_name: '县外' },
|
||||
{ key: '2', display_name: '镇外' },
|
||||
{ key: '3', display_name: '凉森村' },
|
||||
{ key: '4', display_name: '跃进村' }
|
||||
],
|
||||
listQuery: {
|
||||
classId: this.classId,
|
||||
fid: this.$store.state.user.fid,
|
||||
sort: '+id'
|
||||
},
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// this.getList()
|
||||
},
|
||||
methods: {
|
||||
getTotalStu: function(data) {
|
||||
this.total = data
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleCreate() {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<template>
|
||||
<div class="tab-container">
|
||||
<el-tabs v-model="activeName" style="margin-top:15px;" type="border-card">
|
||||
<el-tab-pane label="执教班级" name="first">
|
||||
<complexTable :teacher-id="uid"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="课程表" name="second">
|
||||
<scheduleTab :teacher-id="uid" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import tabPane from './components/tabPane'
|
||||
import complexTable from './components/complexTable'
|
||||
import scheduleTab from '@/views/grade/scheduleTab'
|
||||
|
||||
export default {
|
||||
name: 'Tab',
|
||||
components: {
|
||||
tabPane,
|
||||
scheduleTab,
|
||||
complexTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
classList: '',
|
||||
activeName: 'first',
|
||||
uid: this.$store.getters.user.uid,
|
||||
listQuery: {
|
||||
uid: this.$store.getters.user.uid
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tab-container{
|
||||
margin: 15px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,50 @@
|
|||
<template>
|
||||
<div class="bdsharebuttonbox bdshare-button-style0-16">
|
||||
<a href="#" class="bds_more" data-cmd="more"/>
|
||||
<a href="#" class="bds_qzone" data-cmd="qzone"/>
|
||||
<a href="#" class="bds_tsina" data-cmd="tsina"/>
|
||||
<a href="#" class="bds_tqq" data-cmd="tqq"/>
|
||||
<a href="#" class="bds_renren" data-cmd="renren"/>
|
||||
<a href="#" class="bds_weixin" data-cmd="weixin"/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
beforeCreate() {
|
||||
const _this = this
|
||||
setTimeout(() => {
|
||||
_this.setup()
|
||||
}, 0)
|
||||
},
|
||||
methods: {
|
||||
setup() {
|
||||
window._bd_share_config = {
|
||||
common: {
|
||||
bdSnsKey: {},
|
||||
bdText: '',
|
||||
bdMini: '2',
|
||||
bdPic: '',
|
||||
bdStyle: '0',
|
||||
bdSize: '16'
|
||||
},
|
||||
share: {},
|
||||
image: {
|
||||
viewList: ['qzone', 'tsina', 'tqq', 'renren', 'weixin'],
|
||||
viewText: '分享到:',
|
||||
viewSize: '16'
|
||||
},
|
||||
selectShare: {
|
||||
bdContainerClass: null,
|
||||
bdSelectMiniList: ['qzone', 'tsina', 'tqq', 'renren', 'weixin']
|
||||
}
|
||||
}
|
||||
const s = document.createElement('script')
|
||||
s.type = 'text/javascript'
|
||||
s.src =
|
||||
'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion=' +
|
||||
~(-new Date() / 36e5)
|
||||
document.body.appendChild(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,236 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<div v-if="flag">
|
||||
<div id="dg" style="position: fixed;right: 20px;bottom: 50px;">
|
||||
<el-button style="margin-left: 10px;" type="mini" size="small" @click="showDetail">返回</el-button>
|
||||
</div>
|
||||
<div style="margin-top:-20px;">
|
||||
<span v-html="list[2].content"/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!flag">
|
||||
<el-table v-loading.body="listLoading" :show-overflow-tooltip="true" :data="list" border fit highlight-current-row style="width: 100%">
|
||||
<el-table-column align="center" label="ID" width="80">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.$index + 1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" width="150px" label="发布者">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="200px" align="center" label="发布时间">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.modifyTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" max-width="500px" align="left" label="标题">
|
||||
<template slot-scope="scope">
|
||||
<router-link :to="{path: '/notice/'+scope.row.articleId}" class="link-type" target="_blank">
|
||||
<span>{{ scope.row.title }}</span>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="300px" align="left" label="附件">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.articleAttachment && scope.row.articleAttachment.attachmentName" class="el-tag el-tag--info el-tag--small">
|
||||
<a class="link-type" @click="download(scope.row.articleAttachment.url, scope.row.articleAttachment.attachmentName)">{{ scope.row.articleAttachment.attachmentName }}</a>
|
||||
<i class="el-tag__close el-icon-close" @click="deleteAttachment(scope.row)"/>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('action')" align="center" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button style="margin:5px;float:right">
|
||||
<el-dropdown class="avatar-container right-menu-item" trigger="click">
|
||||
<i style="cursor:pointer" class="el-icon-caret-bottom"/>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<router-link :to="'/notice/edit/'+scope.row.articleId">
|
||||
<el-dropdown-item>
|
||||
{{ $t('edit') }}
|
||||
</el-dropdown-item>
|
||||
</router-link>
|
||||
<el-dropdown-item divided>
|
||||
<span style="display:block;" @click="showUploadData(scope.row)">查 看</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided>
|
||||
<span style="display:block;" @click="deleteArticle(scope.row)">{{ $t('delete') }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-button>
|
||||
<el-upload
|
||||
v-if="scope.row.upload===1"
|
||||
:action="importFileUrl"
|
||||
:on-remove="handleRemove"
|
||||
:data="uploadData"
|
||||
:on-preview="handlePreview"
|
||||
:on-exceed="handleExceed"
|
||||
:on-success="handleSuccess"
|
||||
:file-list="scope.row.attachmentList"
|
||||
:show-file-list="false"
|
||||
style="float:left;margin:5px;"
|
||||
name="file"
|
||||
><el-button size="mini" @click="handleUpdate(scope.row)"><i class="el-icon-upload el-icon--right"/>上传</el-button>
|
||||
|
||||
</el-upload>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
:current-page="listQuery.page"
|
||||
:page-sizes="[10,20,30, 50]"
|
||||
:page-size="listQuery.limit"
|
||||
:total="total"
|
||||
background
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"/>
|
||||
</div>
|
||||
</div>
|
||||
<uploadUser ref="uploadUser"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList, deleteArticle } from '@/api/article'
|
||||
import { downloadFile, deleteAttachment } from '@/api/user'
|
||||
import uploadUser from '@/views/notice/uploadUser'
|
||||
|
||||
export default {
|
||||
name: 'ArticleList',
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
},
|
||||
components: {
|
||||
uploadUser
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
importFileUrl: window.UEDITOR_HOME_URL + 'ueditor/importFile',
|
||||
uploadData: {
|
||||
noticeId: undefined
|
||||
},
|
||||
attachmentList: [
|
||||
{ name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100' }],
|
||||
list: null,
|
||||
total: 0,
|
||||
limit: 1,
|
||||
flag: false,
|
||||
count: 123,
|
||||
rowIndex: undefined,
|
||||
showReviewer: false,
|
||||
dialogPvVisible: false,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
fid: this.$store.getters.user.fid,
|
||||
page: 1,
|
||||
limit: 20
|
||||
},
|
||||
selectRow: undefined
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
deleteArticle(row) {
|
||||
deleteArticle(row.id).then(() => {
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
this.listLoading = false
|
||||
}).catch((error) => {
|
||||
alert(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
download(url, name) {
|
||||
downloadFile(url, name)
|
||||
},
|
||||
showUploadData(item) {
|
||||
this.$refs.uploadUser.handleModifyStatus(item)
|
||||
},
|
||||
deleteAttachment(row) {
|
||||
this.$confirm('您确定删除吗?').then(_ => {
|
||||
deleteAttachment(row.articleAttachment).then(() => {
|
||||
row.articleAttachment = undefined
|
||||
})
|
||||
}).catch(_ => {
|
||||
})
|
||||
},
|
||||
handleUpdate(row) {
|
||||
this.uploadData.noticeId = row.id
|
||||
this.selectRow = row
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
this.listLoading = false
|
||||
}).catch((error) => {
|
||||
alert(error)
|
||||
})
|
||||
},
|
||||
handleRemove(file, attachmentList) {
|
||||
alert(file, attachmentList)
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
showDetail() {
|
||||
this.flag = !this.flag
|
||||
},
|
||||
handlePreview(file) {
|
||||
this.$message.warning(`file url = ` + file.url)
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleSuccess(response, file, attachmentList) {
|
||||
if (response == null) {
|
||||
return
|
||||
}
|
||||
this.selectRow.attachmentList = []
|
||||
this.selectRow.articleAttachment = response
|
||||
this.showReviewer = true
|
||||
},
|
||||
handleExceed(files, attachmentList) {
|
||||
this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + attachmentList.length} 个文件`)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.edit-input {
|
||||
padding-right: 100px;
|
||||
}
|
||||
.cancel-btn {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
.demo-block {
|
||||
border: 1px solid #ebebeb;
|
||||
border-radius: 3px;
|
||||
transition: .2s;
|
||||
margin:20px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,266 @@
|
|||
<template>
|
||||
<div class="app-container cuhksz-detail">
|
||||
<div class="caption-3_nUnnKX">
|
||||
<h1 class="topic-_XJ6ViSR">{{ notice.title }}</h1>
|
||||
<p><span class="date-3fxruanH">发布时间: {{ notice.createTime }}</span><span class="source-1Pn6hUH2"> 发布人: {{ notice.name }}</span></p>
|
||||
</div>
|
||||
<span v-html="message"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { fetchArticle } from '@/api/article'
|
||||
|
||||
export default {
|
||||
name: 'Show',
|
||||
data() {
|
||||
return {
|
||||
notice: {
|
||||
title: undefined,
|
||||
createTime: undefined,
|
||||
name: undefined
|
||||
},
|
||||
message: undefined
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchArticle()
|
||||
},
|
||||
methods: {
|
||||
fetchArticle() {
|
||||
this.listLoading = true
|
||||
fetchArticle(this.$route.params.id).then(response => {
|
||||
if (response.data.code === 200) {
|
||||
this.notice = response.data.result
|
||||
this.message = response.data.result.content
|
||||
}
|
||||
this.listLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.date-3fxruanH, .source-1Pn6hUH2 {
|
||||
font: 14px Microsoft YaHei;
|
||||
color: #999;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.topic-_XJ6ViSR {
|
||||
text-align: center;
|
||||
font: 32px Microsoft YaHei;
|
||||
color: #222;
|
||||
}
|
||||
p {
|
||||
display: block;
|
||||
margin-block-start: 1em;
|
||||
margin-block-end: 1em;
|
||||
margin-inline-start: 0px;
|
||||
margin-inline-end: 0px;
|
||||
}
|
||||
.caption-3_nUnnKX {
|
||||
position: relative;
|
||||
padding: 40px 0 10px;
|
||||
border-bottom: 1px solid #e2e2e2;
|
||||
}
|
||||
.cuhksz-detail {
|
||||
max-width:1000px;
|
||||
margin:0 auto;
|
||||
position:relative;
|
||||
overflow:visible;
|
||||
}
|
||||
.wscn-http404-container{
|
||||
transform: translate(-50%,-50%);
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
}
|
||||
.wscn-http404 {
|
||||
position: relative;
|
||||
width: 1200px;
|
||||
padding: 0 50px;
|
||||
overflow: hidden;
|
||||
.pic-404 {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 600px;
|
||||
overflow: hidden;
|
||||
&__parent {
|
||||
width: 100%;
|
||||
}
|
||||
&__child {
|
||||
position: absolute;
|
||||
&.left {
|
||||
width: 80px;
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
animation-name: cloudLeft;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
&.mid {
|
||||
width: 46px;
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
animation-name: cloudMid;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
&.right {
|
||||
width: 62px;
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
animation-name: cloudRight;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
@keyframes cloudLeft {
|
||||
0% {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 33px;
|
||||
left: 188px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
top: 81px;
|
||||
left: 92px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 97px;
|
||||
left: 60px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes cloudMid {
|
||||
0% {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 40px;
|
||||
left: 360px;
|
||||
opacity: 1;
|
||||
}
|
||||
70% {
|
||||
top: 130px;
|
||||
left: 180px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 160px;
|
||||
left: 120px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes cloudRight {
|
||||
0% {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 120px;
|
||||
left: 460px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
top: 180px;
|
||||
left: 340px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 200px;
|
||||
left: 300px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.bullshit {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 300px;
|
||||
padding: 30px 0;
|
||||
overflow: hidden;
|
||||
&__oops {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
line-height: 40px;
|
||||
color: #1482f0;
|
||||
opacity: 0;
|
||||
margin-bottom: 20px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__headline {
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
color: #222;
|
||||
font-weight: bold;
|
||||
opacity: 0;
|
||||
margin-bottom: 10px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__info {
|
||||
font-size: 13px;
|
||||
line-height: 21px;
|
||||
color: grey;
|
||||
opacity: 0;
|
||||
margin-bottom: 30px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__return-home {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 110px;
|
||||
height: 36px;
|
||||
background: #1482f0;
|
||||
border-radius: 100px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
opacity: 0;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
cursor: pointer;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.3s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
@keyframes slideUp {
|
||||
0% {
|
||||
transform: translateY(60px);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,270 @@
|
|||
<template>
|
||||
<el-dialog :visible.sync="dialogFormVisible" title="收件人" width="60%" height="2200">
|
||||
<el-tabs type="border-card" style="height: 610px;margin-top:-10px;margin-bottom:10px;" >
|
||||
<el-tab-pane label="教师">
|
||||
<teacherComplexTable ref="teacherComplexTable" :table-height="520 + 'px'" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="false" label="班级">
|
||||
<gradeComplexTable ref="gradeComplexTable" :table-height="450 + 'px'" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="群组">
|
||||
<groupComplexTable ref="groupComplexTable" :table-height="430 + 'px'" :type="false" style="margin-top:-20px;"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="addUser">{{ $t('table.add') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList, fetchPv, createArticle, updateArticle } from '@/api/article'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
import { parseTime } from '@/utils'
|
||||
import groupComplexTable from '@/views/group/index'
|
||||
import studentComplexTable from '@/views/student/complexTable'
|
||||
import teacherComplexTable from '@/views/teacher/complexTable'
|
||||
import gradeComplexTable from '@/views/grade/complexTable'
|
||||
|
||||
const calendarTypeOptions = [
|
||||
{ key: 'CN', display_name: 'China' },
|
||||
{ key: 'US', display_name: 'USA' },
|
||||
{ key: 'JP', display_name: 'Japan' },
|
||||
{ key: 'EU', display_name: 'Eurozone' }
|
||||
]
|
||||
|
||||
// arr to obj ,such as { CN : "China", US : "USA" }
|
||||
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
|
||||
acc[cur.key] = cur.display_name
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
export default {
|
||||
name: 'ShowUser',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
},
|
||||
typeFilter(type) {
|
||||
return calendarTypeKeyValue[type]
|
||||
}
|
||||
},
|
||||
components: {
|
||||
groupComplexTable,
|
||||
studentComplexTable,
|
||||
teacherComplexTable,
|
||||
gradeComplexTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
totalStuCount: 0,
|
||||
tableKey: 0,
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
importance: undefined,
|
||||
title: undefined,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
classId: undefined,
|
||||
teacherName: undefined,
|
||||
importanceOptions: [1, 2, 3],
|
||||
calendarTypeOptions,
|
||||
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
||||
statusOptions: ['published', 'draft', 'deleted'],
|
||||
showReviewer: false,
|
||||
temp: {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
type: '',
|
||||
status: 'published'
|
||||
},
|
||||
dialogFormVisible: true,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
type: [{ required: true, message: 'type is required', trigger: 'change' }],
|
||||
timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
|
||||
title: [{ required: true, message: 'title is required', trigger: 'blur' }]
|
||||
},
|
||||
downloadLoading: false,
|
||||
userList: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
addUser() {
|
||||
var map = new Map()
|
||||
map.set('user', this.$refs.teacherComplexTable.getSelectUser())
|
||||
// map.set('class', this.$refs.gradeComplexTable.getSelectClass())
|
||||
map.set('group', this.$refs.groupComplexTable.getSelectGroup())
|
||||
|
||||
// this.userList = this.$refs.teacherComplexTable.getSelectUser().concat(this.$refs.studentComplexTable.getSelectUser())
|
||||
this.dialogFormVisible = false
|
||||
this.$emit('listenToChildEvent', map)
|
||||
},
|
||||
getTotalStu: function(data) {
|
||||
this.totalStuCount = data
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.items
|
||||
this.total = response.data.total
|
||||
|
||||
// Just to simulate the time of the request
|
||||
setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 1.5 * 1000)
|
||||
})
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus() {
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
resetTemp() {
|
||||
this.temp = {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
status: 'published',
|
||||
type: ''
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp()
|
||||
this.dialogStatus = 'create'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
createData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
|
||||
this.temp.author = 'vue-element-admin'
|
||||
createArticle(this.temp).then(() => {
|
||||
this.list.unshift(this.temp)
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleUpdate(row) {
|
||||
this.temp = Object.assign({}, row) // copy obj
|
||||
this.temp.timestamp = new Date(this.temp.timestamp)
|
||||
this.dialogStatus = 'update'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
updateData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
|
||||
updateArticle(tempData).then(() => {
|
||||
for (const v of this.list) {
|
||||
if (v.id === this.temp.id) {
|
||||
const index = this.list.indexOf(v)
|
||||
this.list.splice(index, 1, this.temp)
|
||||
break
|
||||
}
|
||||
}
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
const index = this.list.indexOf(row)
|
||||
this.list.splice(index, 1)
|
||||
},
|
||||
handleFetchPv(pv) {
|
||||
fetchPv(pv).then(response => {
|
||||
this.pvData = response.data.pvData
|
||||
this.dialogPvVisible = true
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const data = this.formatJson(filterVal, this.list)
|
||||
excel.export_json_to_excel({
|
||||
header: tHeader,
|
||||
data,
|
||||
filename: 'table-list'
|
||||
})
|
||||
this.downloadLoading = false
|
||||
})
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,435 @@
|
|||
<template>
|
||||
<el-dialog :visible.sync="dialogFormVisible" title="上传信息">
|
||||
<el-tabs tab-position="top" style="height: 500px;margin-top:-30px;">
|
||||
<el-tab-pane :label="'已上传('+submittedtotal + '人)'">
|
||||
<div class="filter-container">
|
||||
<el-input v-model="listQuery.name" placeholder="姓名" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter"/>
|
||||
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">{{ $t('table.search') }}</el-button>
|
||||
<el-button v-waves class="filter-item" type="primary" icon="el-icon-download" @click="downloadZip">批量下载</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:key="tableKey"
|
||||
:data="submittedlist"
|
||||
:show-overflow-tooltip="true"
|
||||
:height="400"
|
||||
border
|
||||
style="width:100%; 100px;"
|
||||
highlight-current-row>
|
||||
<el-table-column :label="$t('table.id')" align="center" width="60px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.$index+1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="姓名" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.userName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上传时间" width="180px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="附件" min-width="250px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.attachmentName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'未上传('+uncommittedtotal + '人)'">
|
||||
<div class="filter-container">
|
||||
<el-input v-model="listQuery.name" placeholder="姓名" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter"/>
|
||||
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">{{ $t('table.search') }}</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:key="tableKey"
|
||||
:data="uncommittedlist"
|
||||
:show-overflow-tooltip="true"
|
||||
:height="400"
|
||||
border
|
||||
style="width:100%; 100px;"
|
||||
highlight-current-row>
|
||||
<el-table-column :label="$t('table.id')" align="center" width="60px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.$index+1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="姓名" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.userName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上传时间" width="180px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="附件" min-width="250px">
|
||||
<template slot-scope="scope">
|
||||
<span/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="dialogFormVisible = false">{{ $t('table.confirm') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchPv } from '@/api/article'
|
||||
import { fetchUploadUserList, updateStudent, createStudent, downloadZip } from '@/api/user'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
import { parseTime } from '@/utils'
|
||||
|
||||
const calendarTypeOptions = [
|
||||
{ key: 'CN', display_name: 'China' },
|
||||
{ key: 'US', display_name: 'USA' },
|
||||
{ key: 'JP', display_name: 'Japan' },
|
||||
{ key: 'EU', display_name: 'Eurozone' }
|
||||
]
|
||||
|
||||
// arr to obj ,such as { CN : "China", US : "USA" }
|
||||
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
|
||||
acc[cur.key] = cur.display_name
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
},
|
||||
typeFilter(type) {
|
||||
return calendarTypeKeyValue[type]
|
||||
}
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
tableHeight: {
|
||||
type: String,
|
||||
default: '100%'
|
||||
},
|
||||
classId: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableKey: 0,
|
||||
submittedlist: [],
|
||||
uncommittedlist: [],
|
||||
submittedtotal: 0,
|
||||
uncommittedtotal: 0,
|
||||
fid: this.$store.state.user.fid,
|
||||
listLoading: true,
|
||||
articleName: undefined,
|
||||
listQuery: {
|
||||
id: undefined
|
||||
},
|
||||
formLabelAlign: {
|
||||
name: '',
|
||||
tel: '',
|
||||
role: ''
|
||||
},
|
||||
importanceOptions: [1, 2, 3],
|
||||
calendarTypeOptions,
|
||||
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
||||
statusOptions: [{ name: '在读', id: 1 }, { name: '转学', id: 0 }],
|
||||
showReviewer: true,
|
||||
temp: {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
class: undefined,
|
||||
name: undefined,
|
||||
user: undefined,
|
||||
parentStuList: [],
|
||||
selectedOptions2: undefined,
|
||||
status: undefined
|
||||
},
|
||||
dialogFormVisible: false,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
gradeList: undefined,
|
||||
props: {
|
||||
label: 'name',
|
||||
value: 'id',
|
||||
children: 'clazzList'
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
|
||||
stuNo: [{ required: true, message: '学号不能为空', trigger: 'blur' }]
|
||||
},
|
||||
downloadLoading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
resetParent() {
|
||||
this.formLabelAlign = {
|
||||
name: undefined,
|
||||
role: undefined,
|
||||
tel: undefined,
|
||||
fid: this.fid,
|
||||
visiblePopover: true
|
||||
}
|
||||
},
|
||||
createParent() {
|
||||
this.resetParent()
|
||||
},
|
||||
updateParent(index) {
|
||||
this.$refs['popoverForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
if (index > -1) {
|
||||
this.formLabelAlign.visiblePopover = false
|
||||
this.temp.parentStuList.splice(index, 1, this.formLabelAlign)
|
||||
} else {
|
||||
this.formLabelAlign.visiblePopover = false
|
||||
this.temp.parentStuList.push(this.formLabelAlign)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
editParent(item) {
|
||||
this.formLabelAlign = JSON.parse(JSON.stringify(item))
|
||||
item.visiblePopover = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['popoverForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
downloadZip() {
|
||||
downloadZip(this.submittedlist[0].noticeId, this.articleName)
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchUploadUserList(this.listQuery).then(response => {
|
||||
this.submittedlist = []
|
||||
this.uncommittedlist = []
|
||||
if (response.data.code === 200) {
|
||||
var result = response.data.result
|
||||
for (var index in response.data.result) {
|
||||
if (result[index].attachmentName) {
|
||||
this.submittedlist.push(result[index])
|
||||
} else {
|
||||
this.uncommittedlist.push(result[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
this.submittedtotal = this.submittedlist.length
|
||||
this.uncommittedtotal = this.uncommittedlist.length
|
||||
this.listLoading = false
|
||||
})
|
||||
},
|
||||
deleteParent(index) {
|
||||
this.temp.parentStuList.splice(index, 1)
|
||||
},
|
||||
handleChange(value) {
|
||||
if (this.temp.clazz == null) {
|
||||
this.temp.clazz = {}
|
||||
}
|
||||
if (value != null && value.length > 1) {
|
||||
this.temp.clazz.id = value[1]
|
||||
} else {
|
||||
this.temp.clazz.id = null
|
||||
}
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus(row) {
|
||||
this.listQuery.id = row.id
|
||||
this.articleName = row.title
|
||||
this.getList()
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
resetTemp() {
|
||||
this.temp = {
|
||||
id: undefined,
|
||||
graduationStatus: 1,
|
||||
enrollmentDate: new Date(),
|
||||
user: undefined,
|
||||
name: undefined,
|
||||
status: 1,
|
||||
parentStuList: [],
|
||||
address: undefined
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp()
|
||||
this.dialogStatus = 'create'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
createData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
if (this.temp.user == null) {
|
||||
this.temp.user = {}
|
||||
}
|
||||
if (this.temp.clazz == null) {
|
||||
this.temp.clazz = {}
|
||||
}
|
||||
this.temp.enrollmentDate = parseTime(this.temp.enrollmentDate, '{y}-{m}-{d}')
|
||||
this.temp.user.name = this.temp.name
|
||||
this.temp.user.loginName = this.temp.name
|
||||
this.temp.user.sex = this.temp.sex
|
||||
this.temp.user.fid = this.fid
|
||||
this.temp.user.status = 1
|
||||
this.temp.user.address = this.temp.address
|
||||
this.temp.user.roles = 2
|
||||
createStudent(this.temp).then(response => {
|
||||
if (response.data.code === 200) {
|
||||
this.list.unshift(response.data.result)
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
} else {
|
||||
this.$notify({
|
||||
title: '失败',
|
||||
message: response.data.message,
|
||||
type: 'error',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleUpdate(row) {
|
||||
this.temp = Object.assign({}, row) // copy obj
|
||||
var clazz = ''
|
||||
var grade = ''
|
||||
if (this.temp.clazz != null) {
|
||||
clazz = this.temp.clazz.id
|
||||
if (this.temp.clazz != null) {
|
||||
grade = this.temp.clazz.grade.id
|
||||
}
|
||||
}
|
||||
this.temp.selectedOptions2 = [grade, clazz]
|
||||
this.temp.enrollmentDate = new Date(this.temp.enrollmentDate)
|
||||
// 避免数组浅拷贝,修改之前数据。
|
||||
this.temp.parentStuList = JSON.parse(JSON.stringify(this.temp.parentStuList))
|
||||
this.temp.user = JSON.parse(JSON.stringify(this.temp.user))
|
||||
this.temp.address = this.temp.user.address
|
||||
this.dialogStatus = 'update'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
updateData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.temp.user.name = this.temp.name
|
||||
this.temp.user.address = this.temp.address
|
||||
this.temp.enrollmentDate = parseTime(this.temp.enrollmentDate, '{y}-{m}-{d}')
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
updateStudent(tempData).then(response => {
|
||||
if (response.data.code === 200) {
|
||||
for (const v of this.list) {
|
||||
if (v.id === response.data.result.id) {
|
||||
const index = this.list.indexOf(v)
|
||||
this.list.splice(index, 1, response.data.result)
|
||||
break
|
||||
}
|
||||
}
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
} else {
|
||||
this.$notify({
|
||||
title: '失败',
|
||||
message: response.data.message,
|
||||
type: 'error',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
const index = this.list.indexOf(row)
|
||||
this.list.splice(index, 1)
|
||||
},
|
||||
handleFetchPv(pv) {
|
||||
fetchPv(pv).then(response => {
|
||||
this.pvData = response.data.pvData
|
||||
this.dialogPvVisible = true
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const data = this.formatJson(filterVal, this.list)
|
||||
excel.export_json_to_excel({
|
||||
header: tHeader,
|
||||
data,
|
||||
filename: 'table-list'
|
||||
})
|
||||
this.downloadLoading = false
|
||||
})
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,630 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container" style="margin-top:-10px;">
|
||||
<el-input v-model="listQuery.name" placeholder="学生姓名" style="width: 100px;" class="filter-item" @keyup.enter.native="handleFilter"/>
|
||||
<el-input v-model="listQuery.address" placeholder="地址" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter"/>
|
||||
<el-select v-model="listQuery.sex" placeholder="性别" clearable class="filter-item" style="width: 75px">
|
||||
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
|
||||
</el-select>
|
||||
<el-select v-if="!classId" v-model="listQuery.gradeId" placeholder="年级" clearable class="filter-item" style="width: 130px" @change="updateClass">
|
||||
<el-option v-for="item in gradeList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
<el-select v-if="!classId" v-model="listQuery.classId" placeholder="班级" clearable class="filter-item" style="width: 150px">
|
||||
<el-option v-for="item in classList" :key="item.id" :label="item.name" :value="item.id"/>
|
||||
</el-select>
|
||||
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">{{ $t('table.search') }}</el-button>
|
||||
<el-button v-if="$store.state.user.admin && type" class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">{{ $t('table.add') }}</el-button>
|
||||
<el-checkbox v-model="showReviewer" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">显示家长</el-checkbox>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:key="tableKey"
|
||||
:data="list"
|
||||
:show-overflow-tooltip="true"
|
||||
:row-key="getRowKeys"
|
||||
:height="tableHeight"
|
||||
border
|
||||
fit
|
||||
highlight-current-row
|
||||
style="width: 100%;min-height:300px;ellipsis;margin-top:-10px;"
|
||||
@selection-change="handleSelectionChange">
|
||||
<el-table-column
|
||||
:reserve-selection="true"
|
||||
type="selection"
|
||||
width="35"/>
|
||||
<el-table-column :label="$t('table.id')" align="center" width="50px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.$index+1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="学生姓名" width="100px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" label="学籍号" width="180px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.stuNo }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" label="身份证号" width="180px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.idCard }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="性别" width="50px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.sex == 0 ? '男' : '女' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" label="籍贯" width="120px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.nativePlace }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" label="民族" width="60px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.folk }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="false" :show-overflow-tooltip="true" label="角色" width="60px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.position }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" label="家庭地址" min-width="220px">
|
||||
<template slot-scope="scope">
|
||||
<span class="link-type" style="text-overflow:ellipsis;" @click="handleUpdate(scope.row, true)">{{ scope.row.address }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" label="联系电话" width="110px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.tel }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="!classId" label="入学时间" width="95px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.enrollmentDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="!classId" :show-overflow-tooltip="true" label="年级" width="100px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>
|
||||
{{ scope.row.clazz == null ? '' : (scope.row.clazz.grade == null ? '' : scope.row.clazz.grade.name) }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="!classId" :show-overflow-tooltip="true" label="班级" width="120px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.clazz == null ? '' : scope.row.clazz.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="showReviewer" label="家长" align="center" min-width="120px">
|
||||
<template slot-scope="scope">
|
||||
<div v-for="(item) in scope.row.parentStuList" :gutter="1" :key="item.id" type="flex" class="row-bg" justify="left" style="margin-top:2px;">
|
||||
<div :span="12" style="float:left;margin:2px;">
|
||||
<div class="grid-content "/>
|
||||
<el-tooltip placement="left-start">
|
||||
<div slot="content">电话: {{ item.tel== null? '无' : item.tel }}</div>
|
||||
<span class="el-tag el-tag--info el-tag--small" style="float:left;">
|
||||
<span class="link-type" @click="handleEditClass(scope.row)"><svg-icon v-if="item.openid" icon-class="weixin"/>{{ item.name }} {{ item.role ? '(' + item.role + ')' : '' }} </span>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.actions')" align="center" width="60">
|
||||
<template slot-scope="scope">
|
||||
<el-dropdown class="avatar-container right-menu-item" trigger="click">
|
||||
<el-button style="cursor:pointer" class="el-icon-caret-bottom"/>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-if="$store.state.user.admin">
|
||||
<span style="display:block;" @click="handleUpdate(scope.row, false)">{{ $t('edit') }}</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided>
|
||||
<span v-if="!classId" style="display:block;" @click="handleDelete(scope.row,'deleted')">{{ $t('delete') }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-container" style="margin-top:10px;">
|
||||
<el-pagination :current-page="listQuery.page" :page-sizes="[10,20,30, 50]" :page-size="listQuery.limit" :total="total" background layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange"/>
|
||||
</div>
|
||||
|
||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" append-to-body width="40%">
|
||||
<el-form ref="dataForm" :rules="rules" :model="temp" :disabled="disabled" label-position="right" label-width="20%" style="width: 90%; margin-left:10px;">
|
||||
<el-form-item label="学生姓名" prop="name">
|
||||
<el-input v-model="temp.name" :maxlength="20"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="学籍号" prop="stuNo">
|
||||
<el-input v-model="temp.stuNo"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证件号" prop="idCard">
|
||||
<el-input v-model="temp.idCard"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别">
|
||||
<el-select v-model="temp.sex" class="filter-item">
|
||||
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="籍贯" prop="stuNo">
|
||||
<el-input v-model="temp.nativePlace"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="民族" prop="stuNo">
|
||||
<el-input v-model="temp.folk"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="code">
|
||||
<el-cascader
|
||||
v-model="temp.selectedOptions2"
|
||||
:options="gradeList"
|
||||
:props="props"
|
||||
clearable
|
||||
expand-trigger="hover"
|
||||
style="width: 100%;"
|
||||
@change="handleChange"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="家庭地址" prop="address">
|
||||
<el-input v-model="temp.address"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话" prop="address">
|
||||
<el-input v-model="temp.tel"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="入学时间">
|
||||
<el-date-picker v-model="temp.enrollmentDate" type="date" placeholder="入学时间" style="width: 100%;"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="家长" prop="address">
|
||||
<el-row v-for="(item,index) in temp.parentStuList" :gutter="10" :key="item.id" type="flex" class="row-bg" justify="left" style="margin-top:5px;">
|
||||
<el-col :span="12">
|
||||
<el-popover
|
||||
:disabled="disabled || item.openid"
|
||||
v-model="item.visiblePopover"
|
||||
placement="top"
|
||||
width="300"
|
||||
trigger="click">
|
||||
<el-form :model="formLabelAlign" label-position="right" label-width="60px">
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="formLabelAlign.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色">
|
||||
<el-input v-model="formLabelAlign.role"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号">
|
||||
<el-input v-model="formLabelAlign.tel"/>
|
||||
</el-form-item>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button size="mini" type="text" @click="item.visiblePopover = false">取消</el-button>
|
||||
<el-button type="primary" size="mini" @click="updateParent(index)">确定</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
<div slot="reference">
|
||||
<span class="el-tag el-tag--info el-tag--small" style="float:left;">
|
||||
<span class="link-type" @click="editParent(item)"><svg-icon v-if="item.openid" icon-class="weixin"/>{{ item.role }} ({{ item.name }}-{{ item.tel }})</span>
|
||||
<i v-if="!disabled" class="el-tag__close el-icon-close" @click="deleteParent(index)"/>
|
||||
</span>
|
||||
</div>
|
||||
</el-popover>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-popover
|
||||
v-model="formLabelAlign.visiblePopover"
|
||||
placement="top"
|
||||
width="300"
|
||||
trigger="click">
|
||||
<el-form ref="popoverForm" :rules="rules" :model="formLabelAlign" label-position="right" label-width="60px">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="formLabelAlign.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色">
|
||||
<el-input v-model="formLabelAlign.role"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号">
|
||||
<el-input v-model="formLabelAlign.tel"/>
|
||||
</el-form-item>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button size="mini" type="text" @click="formLabelAlign.visiblePopover = false">取消</el-button>
|
||||
<el-button type="primary" size="mini" @click="updateParent(-1)">确定</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
<el-button slot="reference" icon="el-icon-circle-plus-outline" size="mini" round @click="createParent()">添加</el-button>
|
||||
</el-popover>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.status')">
|
||||
<el-select v-model="temp.graduationStatus" value-key="id" class="filter-item" style="width: 100%;">
|
||||
<el-option v-for="item in statusOptions" :key="item.id" :label="item.name" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="说明">
|
||||
<el-input :autosize="{ minRows: 3, maxRows: 6}" v-model="temp.comment" type="textarea"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
|
||||
<el-button v-if="dialogStatus=='create' && !disabled" type="primary" @click="createData">{{ $t('table.confirm') }}</el-button>
|
||||
<el-button v-else-if="!disabled" type="primary" @click="updateData">{{ $t('table.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchPv } from '@/api/article'
|
||||
import { fetchStuList, fetchGradeList, updateStudent, createStudent, deleteStudent } from '@/api/user'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
import { parseTime } from '@/utils'
|
||||
|
||||
const calendarTypeOptions = [
|
||||
{ key: 0, display_name: '男' },
|
||||
{ key: 1, display_name: '女' }
|
||||
]
|
||||
|
||||
const areaTypeOptions = [
|
||||
{ key: '1', display_name: '外县' },
|
||||
{ key: '2', display_name: '外镇' },
|
||||
{ key: '3', display_name: '凉森村' },
|
||||
{ key: '4', display_name: '跃进村' }
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
tableHeight: {
|
||||
type: String,
|
||||
default: window.innerHeight - 200 + 'px'
|
||||
},
|
||||
classId: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
disabled: true,
|
||||
tableKey: 0,
|
||||
list: null,
|
||||
total: null,
|
||||
fid: this.$store.state.user.fid,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
fid: this.$store.state.user.fid,
|
||||
limit: 20,
|
||||
status: 1,
|
||||
address: undefined,
|
||||
gradeId: undefined,
|
||||
classId: this.classId,
|
||||
importance: undefined,
|
||||
title: undefined,
|
||||
type: undefined,
|
||||
name: undefined,
|
||||
area: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
formLabelAlign: {
|
||||
name: '',
|
||||
tel: '',
|
||||
role: ''
|
||||
},
|
||||
importanceOptions: [1, 2, 3],
|
||||
calendarTypeOptions,
|
||||
areaTypeOptions,
|
||||
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
||||
statusOptions: [{ name: '在读', id: 1 }, { name: '转学', id: 0 }],
|
||||
showReviewer: false,
|
||||
temp: {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
class: undefined,
|
||||
name: undefined,
|
||||
sex: 0,
|
||||
parentStuList: [],
|
||||
selectedOptions2: undefined,
|
||||
status: undefined
|
||||
},
|
||||
dialogFormVisible: false,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
gradeList: undefined,
|
||||
classList: undefined,
|
||||
props: {
|
||||
label: 'name',
|
||||
value: 'id',
|
||||
children: 'clazzList'
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
|
||||
stuNo: [{ required: true, message: '学号不能为空', trigger: 'blur' }]
|
||||
},
|
||||
downloadLoading: false,
|
||||
userList: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
this.fetchGradeList()
|
||||
},
|
||||
methods: {
|
||||
getSelectUser() {
|
||||
return this.userList
|
||||
},
|
||||
updateClass() {
|
||||
for (const index in this.gradeList) {
|
||||
const grade = this.gradeList[index]
|
||||
if (grade.id === this.listQuery.gradeId) {
|
||||
this.classList = grade.clazzList
|
||||
}
|
||||
}
|
||||
},
|
||||
fetchGradeList() {
|
||||
fetchGradeList(this.listQuery).then(response => {
|
||||
this.gradeList = response.data.result.list
|
||||
})
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.userList = val
|
||||
},
|
||||
getRowKeys(row) {
|
||||
return row.uid
|
||||
},
|
||||
resetParent() {
|
||||
this.formLabelAlign = {
|
||||
name: undefined,
|
||||
role: undefined,
|
||||
tel: undefined,
|
||||
fid: this.fid,
|
||||
visiblePopover: true
|
||||
}
|
||||
},
|
||||
createParent() {
|
||||
this.resetParent()
|
||||
},
|
||||
updateParent(index) {
|
||||
this.$refs['popoverForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
if (index > -1) {
|
||||
this.temp.parentStuList.splice(index, 1, this.formLabelAlign)
|
||||
} else {
|
||||
this.temp.parentStuList.push(this.formLabelAlign)
|
||||
}
|
||||
this.formLabelAlign.visiblePopover = false
|
||||
}
|
||||
})
|
||||
},
|
||||
editParent(item) {
|
||||
if (!item.openid) {
|
||||
this.formLabelAlign = JSON.parse(JSON.stringify(item))
|
||||
item.visiblePopover = !this.disabled
|
||||
this.$nextTick(() => {
|
||||
this.$refs['popoverForm'].clearValidate()
|
||||
})
|
||||
}
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchStuList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
this.listLoading = false
|
||||
})
|
||||
},
|
||||
deleteParent(index) {
|
||||
this.temp.parentStuList.splice(index, 1)
|
||||
},
|
||||
handleChange(value) {
|
||||
if (this.temp.clazz == null) {
|
||||
this.temp.clazz = {}
|
||||
}
|
||||
if (value != null && value.length > 1) {
|
||||
this.temp.clazz.id = value[1]
|
||||
} else {
|
||||
this.temp.clazz.id = null
|
||||
}
|
||||
},
|
||||
handleFilter() {
|
||||
this.multipleSelection = []
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus(row, status) {
|
||||
this.$message({
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
row.status = status
|
||||
},
|
||||
resetTemp() {
|
||||
this.temp = {
|
||||
id: undefined,
|
||||
graduationStatus: 1,
|
||||
enrollmentDate: '',
|
||||
sex: 0,
|
||||
name: undefined,
|
||||
status: 1,
|
||||
parentStuList: [],
|
||||
address: undefined
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp()
|
||||
this.disabled = false
|
||||
this.dialogStatus = 'create'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
createData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
if (this.temp.clazz == null) {
|
||||
this.temp.clazz = {}
|
||||
}
|
||||
this.temp.enrollmentDate = parseTime(this.temp.enrollmentDate, '{y}-{m}-{d}')
|
||||
this.temp.username = this.temp.name
|
||||
this.temp.fid = this.fid
|
||||
this.temp.graduationStatus = 1
|
||||
this.temp.address = this.temp.address
|
||||
this.temp.roles = [2]
|
||||
createStudent(this.temp).then(response => {
|
||||
if (response.data.code === 200) {
|
||||
fetchStuList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
})
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
} else {
|
||||
this.$notify({
|
||||
title: '失败',
|
||||
message: response.data.message,
|
||||
type: 'error',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleUpdate(row, disabled) {
|
||||
this.disabled = disabled
|
||||
this.temp = Object.assign({}, row) // copy obj
|
||||
var clazz = ''
|
||||
var grade = ''
|
||||
if (this.temp.clazz != null) {
|
||||
clazz = this.temp.clazz.id
|
||||
if (this.temp.clazz != null) {
|
||||
grade = this.temp.clazz.grade.id
|
||||
}
|
||||
}
|
||||
this.temp.selectedOptions2 = [grade, clazz]
|
||||
if (this.temp.enrollmentDate) {
|
||||
this.temp.enrollmentDate = new Date(this.temp.enrollmentDate)
|
||||
}
|
||||
// 避免数组浅拷贝,修改之前数据。
|
||||
this.temp.parentStuList = JSON.parse(JSON.stringify(this.temp.parentStuList))
|
||||
this.dialogStatus = 'update'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
updateData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.temp.enrollmentDate = parseTime(this.temp.enrollmentDate, '{y}-{m}-{d}')
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
updateStudent(tempData).then(response => {
|
||||
if (response.data.code === 200) {
|
||||
fetchStuList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
})
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '添加成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
} else {
|
||||
this.$notify({
|
||||
title: '失败',
|
||||
message: response.data.message,
|
||||
type: 'error',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
deleteStudent(row).then(response => {
|
||||
fetchStuList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
})
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
},
|
||||
handleFetchPv(pv) {
|
||||
fetchPv(pv).then(response => {
|
||||
this.pvData = response.data.pvData
|
||||
this.dialogPvVisible = true
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const data = this.formatJson(filterVal, this.list)
|
||||
excel.export_json_to_excel({
|
||||
header: tHeader,
|
||||
data,
|
||||
filename: 'table-list'
|
||||
})
|
||||
this.downloadLoading = false
|
||||
})
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -5,6 +5,12 @@
|
|||
</a>
|
||||
</p>
|
||||
<div class="icons-wrapper">
|
||||
<i class="iconfont icon-weixin"/>
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-weixin"/>
|
||||
</svg>
|
||||
<svg-icon icon-class="school" />
|
||||
<svg-icon icon-class="nianjiguanli" />年级管理
|
||||
<div v-for="item of iconsMap" :key="item" @click="handleClipboard(generateIconCode(item),$event)">
|
||||
<el-tooltip placement="top">
|
||||
<div slot="content">
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<div style="z-index: 1; height: 50px;">
|
||||
<div class="draft" style="top: 0px; z-index: 1;height: 45px;margin-top:-5px;">
|
||||
<el-button class="filter-item" style="margin-right: 10px;float:right;" @click="cancelSchoolData()">取消</el-button>
|
||||
<el-button v-if="!disabled" type="primary" class="filter-item el-button--mini" style="margin-right: 10px;float:right;" icon="el-icon-edit" @click="updateSchoolData()">{{ $t('save') }}</el-button>
|
||||
<el-button v-if="disabled" class="filter-item el-button--mini el-button--success" style="margin-right: 10px;float:right;" icon="el-icon-edit" @click="disabled = false">{{ $t('edit') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-form ref="form" :model="form" :disabled="disabled" :rules="rules" label-width="150px">
|
||||
<el-form-item label="学校名称" prop="schoolName">
|
||||
<el-input v-model="form.schoolName"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="地区编号" prop="areaCode">
|
||||
<el-input v-model="form.areaCode"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="学校代码" prop="schoolCode">
|
||||
<el-input v-model="form.schoolCode"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="微信公众号应用ID">
|
||||
<el-input v-model="form.appid"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="微信公众号应用密钥">
|
||||
<el-input v-model="form.appsecret"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { fetchSchool, updateSchool } from '@/api/user'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
disabled: true,
|
||||
listQuery: {
|
||||
fid: this.$store.state.user.fid
|
||||
},
|
||||
data: null,
|
||||
form: {
|
||||
schoolName: '',
|
||||
areaCode: '',
|
||||
schoolCode: '',
|
||||
appid: '',
|
||||
appsecret: ''
|
||||
},
|
||||
rules: {
|
||||
schoolName: [{ required: true, message: '学校名称必填', trigger: 'change' }],
|
||||
areaCode: [{ required: true, message: '学校地区编号必填', trigger: 'blur' }],
|
||||
schoolCode: [{ required: true, message: '学校代码必填', trigger: 'blur' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getSchoolData()
|
||||
},
|
||||
methods: {
|
||||
getSchoolData() {
|
||||
fetchSchool(this.listQuery).then(response => {
|
||||
this.data = response.data.result
|
||||
this.form = JSON.parse(JSON.stringify(this.data))
|
||||
})
|
||||
},
|
||||
updateSchoolData() {
|
||||
updateSchool(this.form).then(response => {
|
||||
this.data = response.data.result
|
||||
this.disabled = true
|
||||
this.form = JSON.parse(JSON.stringify(this.data))
|
||||
})
|
||||
},
|
||||
cancelSchoolData() {
|
||||
this.form = JSON.parse(JSON.stringify(this.data))
|
||||
this.disabled = true
|
||||
},
|
||||
onSubmit() {
|
||||
console.log('submit!')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,87 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container" style="margin-top:-10px;">
|
||||
<el-button class="filter-item" icon="el-icon-refresh" style="float:right;margin-left:15px;">拉取模板</el-button>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:data="list"
|
||||
:show-overflow-tooltip="true"
|
||||
border
|
||||
fit
|
||||
highlight-current-row
|
||||
style="width: 100%;min-height:300px;ellipsis;margin-top:-10px;">
|
||||
<el-table-column :label="$t('table.id')" align="center" width="50px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.$index+1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="模板ID" width="200px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.templateId }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" label="模板标题" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.title }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" label="模板格式" min-width="250px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span><div v-html="$options.filters.msg(scope.row.content)"/></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" label="模板所属应用ID" width="200px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.appid }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.actions')" align="center" width="300" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="primary" size="mini">编辑用户</el-button>
|
||||
<el-button size="mini" type="success" >查看</el-button>
|
||||
<el-button size="mini" type="danger" >{{ $t('table.delete') }}</el-button>
|
||||
<el-button size="mini" type="success" >禁用</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchTemplateList } from '@/api/user'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
filters: {
|
||||
msg: function(msg) {
|
||||
// .replace(/\{[^}]+}}/g, 'abc')
|
||||
return msg.replace(/\\n/gm, '<br/>')
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
total: null,
|
||||
listQuery: {
|
||||
fid: this.$store.state.user.fid
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
fetchTemplateList(this.listQuery).then(response => {
|
||||
this.list = response.data.result
|
||||
this.total = response.data.result.total
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -91,13 +91,13 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.date')" prop="timestamp">
|
||||
<el-date-picker v-model="temp.timestamp" type="datetime" placeholder="Please pick a date"/>
|
||||
<el-date-picker v-model="temp.timestamp" type="datetime"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.title')" prop="title">
|
||||
<el-input v-model="temp.title"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.status')">
|
||||
<el-select v-model="temp.status" class="filter-item" placeholder="Please select">
|
||||
<el-select v-model="temp.status" class="filter-item" >
|
||||
<el-option v-for="item in statusOptions" :key="item" :label="item" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
@ -105,7 +105,7 @@
|
|||
<el-rate v-model="temp.importance" :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :max="3" style="margin-top:8px;"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.remark')">
|
||||
<el-input :autosize="{ minRows: 2, maxRows: 4}" v-model="temp.remark" type="textarea" placeholder="Please input"/>
|
||||
<el-input :autosize="{ minRows: 2, maxRows: 4}" v-model="temp.remark" type="textarea"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
|
@ -194,8 +194,8 @@ export default {
|
|||
dialogFormVisible: false,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: 'Edit',
|
||||
create: 'Create'
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
|
@ -227,6 +227,14 @@ export default {
|
|||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus(row, status) {
|
||||
this.$message({
|
||||
message: '操作成功',
|
||||
|
|
|
@ -0,0 +1,701 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container" style="margin-top:-10px;">
|
||||
<el-input v-model="listQuery.name" placeholder="姓名" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter"/>
|
||||
<el-select v-model="listQuery.sex" placeholder="性别" clearable class="filter-item" style="width: 130px">
|
||||
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
|
||||
</el-select>
|
||||
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">{{ $t('table.search') }}</el-button>
|
||||
<el-button v-if="$store.state.user.admin && !classId" class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">{{ $t('table.add') }}</el-button>
|
||||
<el-popover
|
||||
v-model="courseData.visiblePopover"
|
||||
placement="top"
|
||||
width="300"
|
||||
trigger="click">
|
||||
<el-form ref="popoverForm" :rules="rules" :model="courseData" label-position="right" label-width="120px">
|
||||
<el-form-item label="课程" prop="name">
|
||||
<el-select v-model="courseData.course" value-key="id" filterable class="filter-item" style="width: 100%;">
|
||||
<el-option v-for="item in courseList" :key="item.id" :label="item.name" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="教师名称" prop="name">
|
||||
<el-select v-model="courseData.teacher" value-key="uid" filterable class="filter-item" style="width: 100%;">
|
||||
<el-option v-for="item in allList" :key="item.uid" :label="item.name" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button size="mini" type="text" @click="courseData.visiblePopover = false">取消</el-button>
|
||||
<el-button type="primary" size="mini" @click="updateCourse()">确定</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
<el-button v-if="classId" slot="reference" class="filter-item" icon="el-icon-edit" style="margin-left: 10px;" type="primary" @click="addCourseForTeacher()">添加任课老师</el-button>
|
||||
</el-popover>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:key="tableKey"
|
||||
:data="list"
|
||||
:height="tableHeight"
|
||||
:row-key="getRowKeys"
|
||||
border
|
||||
fit
|
||||
highlight-current-row
|
||||
style="width: 100%;min-height:300px;margin-top:-10px;"
|
||||
@selection-change="handleSelectionChange">
|
||||
<el-table-column
|
||||
:reserve-selection="true"
|
||||
type="selection"
|
||||
width="35"/>
|
||||
<el-table-column :label="$t('table.id')" align="center" width="60">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.$index + 1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="姓名" width="160px" align="left">
|
||||
<template slot-scope="scope">
|
||||
<span class="link-type" style="text-overflow:ellipsis;" @click="handleUpdate(scope.row, true)">{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="编号" width="200px">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.code }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="!classId" label="入职时间" width="160px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.enrollmentDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="!classId" label="性别" align="center" width="70">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.sex == 0 ? "男" : "女" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="电话号码" width="150px" align="left">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.tel }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="false" :label="$t('table.status')" class-name="status-col" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.teacherStatus==1"> 在职</el-tag>
|
||||
<el-tag v-if="scope.row.teacherStatus==2" type="warning">离职</el-tag>
|
||||
<el-tag v-if="scope.row.teacherStatus==3" type="info"> 退休</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="执教班级" min-width="250" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div v-for="(item,index) in scope.row.classMap" v-if="index%2 != 1" :gutter="1" :key="item.id" class="link-type row-bg" style="text-overflow:ellipsis;" type="flex" justify="left" @click="handleUpdate(scope.row, false)">
|
||||
<el-tag v-if="index%2 != 1" style="float:left;margin:2px;" >{{ item.className }}({{ item.courseName }})</el-tag>
|
||||
<el-tag v-if="scope.row.classMap[index+1] != null" style="float:left;margin:2px;">{{ scope.row.classMap[index+1].className }}({{ scope.row.classMap[index+1].courseName }})</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.actions')" align="center" width="70" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-dropdown trigger="click">
|
||||
<!-- <svg-icon icon-class="action" style="width: 1.2em;height: 1.2em;cursor:pointer"/> -->
|
||||
<el-button style="cursor:pointer" class="el-icon-caret-bottom"/>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-if="$store.state.user.admin">
|
||||
<span style="display:block;" @click="handleUpdate(scope.row, false)">{{ $t('edit') }}</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="$store.state.user.admin" divided>
|
||||
<span style="display:block;" @click="handleModifyStatus(scope.row,scope.$index)">{{ $t('delete') }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog :visible.sync="dialogFormVisible" :title="textMap[dialogStatus]" append-to-body width="40%">
|
||||
<el-form ref="dataForm" :disabled="disabled" :rules="rules" :model="temp" label-position="left" label-width="70px" style="width: 400px; margin-left:50px;">
|
||||
<el-form-item label="编号" prop="code">
|
||||
<el-input v-model="temp.code"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="temp.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="登录名" prop="username">
|
||||
<el-input v-model="temp.username" placeholder="默认为姓名"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号码" prop="tel">
|
||||
<el-input v-model="temp.tel"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="sex">
|
||||
<el-select v-model="temp.sex" class="filter-item" placeholder="Please select">
|
||||
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="执教课程">
|
||||
<el-row v-for="(item,index) in temp.classMap" :gutter="10" :key="item.id" type="flex" class="row-bg" justify="left" style="margin-top:5px;">
|
||||
<el-col :span="12">
|
||||
<el-popover
|
||||
:disabled="disabled"
|
||||
v-model="temp.classMap[index].visiblePopover"
|
||||
placement="top"
|
||||
width="300"
|
||||
trigger="click">
|
||||
<el-form :model="formLabelAlign" label-position="left" label-width="60px">
|
||||
<el-form-item label="班级">
|
||||
<el-cascader
|
||||
v-model="formLabelAlign.classId"
|
||||
:options="gradeList"
|
||||
:props="props"
|
||||
clearable
|
||||
expand-trigger="hover"
|
||||
style="width: 100%;"
|
||||
@change="handleChange"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="课程">
|
||||
<el-select v-model="formLabelAlign.course" value-key="id" filterable class="filter-item" style="width: 100%;">
|
||||
<el-option v-for="item in courseList" :key="item.id" :label="item.name" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button size="mini" type="text" @click="temp.classMap[index].visiblePopover = false">取消</el-button>
|
||||
<el-button type="primary" size="mini" @click="updateParent(index)">确定</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
<div slot="reference">
|
||||
<span class="el-tag el-tag--info el-tag--small" style="float:left;">
|
||||
<span class="link-type" @click="editParent(item)">{{ item.className }} ({{ item.courseName }})</span>
|
||||
<i v-if="!disabled" class="el-tag__close el-icon-close" @click="deleteParent(index)"/>
|
||||
</span>
|
||||
</div>
|
||||
</el-popover>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-popover
|
||||
v-model="formLabelAlign.visiblePopover"
|
||||
placement="top"
|
||||
width="300"
|
||||
trigger="click">
|
||||
<el-form ref="popoverForm" :model="formLabelAlign" label-position="right" label-width="60px">
|
||||
<el-form-item label="班级">
|
||||
<el-cascader
|
||||
v-model="formLabelAlign.classId"
|
||||
:options="gradeList"
|
||||
:props="props"
|
||||
clearable
|
||||
expand-trigger="hover"
|
||||
style="width: 100%;"
|
||||
@change="handleChange"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="课程">
|
||||
<el-select v-model="formLabelAlign.course" value-key="id" filterable class="filter-item" style="width: 100%;">
|
||||
<el-option v-for="item in courseList" :key="item.id" :label="item.name" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button size="mini" type="text" @click="formLabelAlign.visiblePopover = false">取消</el-button>
|
||||
<el-button type="primary" size="mini" @click="updateParent(-1)">确定</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
<el-button slot="reference" icon="el-icon-circle-plus-outline" size="mini" round @click="createParent()">添加</el-button>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.date')">
|
||||
<el-date-picker v-model="temp.enrollmentDate" type="date"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.status')">
|
||||
<el-select v-model="temp.teacherStatus" class="filter-item">
|
||||
<el-option v-for="item in statusOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
|
||||
<el-button v-if="dialogStatus=='create' && !disabled" type="primary" @click="createData">{{ $t('table.confirm') }}</el-button>
|
||||
<el-button v-else-if="!disabled" type="primary" @click="updateData">{{ $t('table.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchTeacherList, fetchPv, updateTeacher, deleteTeacher, fetchGradeList, fetchCourseList, addCourseClass } from '@/api/user'
|
||||
import waves from '@/directive/waves' // 水波纹指令
|
||||
import { parseTime } from '@/utils'
|
||||
|
||||
const calendarTypeOptions = [
|
||||
{ key: 0, display_name: '男' },
|
||||
{ key: 1, display_name: '女' }
|
||||
]
|
||||
|
||||
const statusOptions = [
|
||||
{ key: 1, display_name: '在职' },
|
||||
{ key: 2, display_name: '离职' },
|
||||
{ key: 3, display_name: '退休' }
|
||||
]
|
||||
|
||||
// arr to obj ,such as { CN : "China", US : "USA" }
|
||||
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
|
||||
acc[cur.key] = cur.display_name
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
},
|
||||
typeFilter(type) {
|
||||
return calendarTypeKeyValue[type]
|
||||
}
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
tableHeight: {
|
||||
type: String,
|
||||
default: window.innerHeight - 160 + 'px'
|
||||
},
|
||||
classId: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableKey: 0,
|
||||
list: null,
|
||||
allList: [],
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
courseId: undefined,
|
||||
gradeId: undefined,
|
||||
classId: this.classId,
|
||||
fid: this.$store.state.user.fid,
|
||||
sex: undefined,
|
||||
name: undefined,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
gradeQuery: {
|
||||
page: 1,
|
||||
fid: this.$store.state.user.fid
|
||||
},
|
||||
importanceOptions: [1, 2, 3],
|
||||
calendarTypeOptions,
|
||||
statusOptions,
|
||||
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
||||
showReviewer: false,
|
||||
formLabelAlign: {
|
||||
class: {},
|
||||
classId: [],
|
||||
course: {}
|
||||
},
|
||||
courseData: {
|
||||
class: {},
|
||||
classId: [],
|
||||
course: {}
|
||||
},
|
||||
props: {
|
||||
label: 'name',
|
||||
value: 'id',
|
||||
children: 'clazzList'
|
||||
},
|
||||
classList: [],
|
||||
courseList: [],
|
||||
temp: {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
enrollmentDate: '',
|
||||
title: '',
|
||||
sex: 0,
|
||||
classMap: [],
|
||||
loginName: undefined,
|
||||
type: ''
|
||||
|
||||
},
|
||||
dialogFormVisible: false,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: this.$t('edit'),
|
||||
create: this.$t('create')
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
type: [{ required: true, message: 'type is required', trigger: 'change' }],
|
||||
code: [{ required: true, message: '教师编号必填', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '教师姓名必填', trigger: 'blur' }]
|
||||
},
|
||||
downloadLoading: false,
|
||||
multipleSelection: [],
|
||||
gradeList: [],
|
||||
userList: [],
|
||||
disabled: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
if (this.classId) {
|
||||
var tempQuery = {
|
||||
fid: this.$store.state.user.fid
|
||||
}
|
||||
fetchTeacherList(tempQuery).then(response => {
|
||||
this.allList = response.data.result.list
|
||||
}
|
||||
)
|
||||
}
|
||||
this.fetchGradeList()
|
||||
this.fetchCourseList()
|
||||
},
|
||||
methods: {
|
||||
deleteParent(index) {
|
||||
this.temp.classMap.splice(index, 1)
|
||||
},
|
||||
editParent(item) {
|
||||
this.formLabelAlign = JSON.parse(JSON.stringify(item))
|
||||
this.formLabelAlign.classId = [item.gradeId, item.classId]
|
||||
this.formLabelAlign.course = {}
|
||||
this.formLabelAlign.course.name = this.formLabelAlign.courseName
|
||||
this.formLabelAlign.course.id = this.formLabelAlign.courseId
|
||||
item.visiblePopover = !this.disabled
|
||||
},
|
||||
updateParent(index) {
|
||||
if (index > -1) {
|
||||
this.formLabelAlign.visiblePopover = false
|
||||
const courseMap = {}
|
||||
for (const index in this.gradeList) {
|
||||
const grade = this.gradeList[index]
|
||||
if (grade.id === this.formLabelAlign.classId[0]) {
|
||||
const classList = grade.clazzList
|
||||
for (const i in classList) {
|
||||
const clazz = classList[i]
|
||||
if (clazz.id === this.formLabelAlign.classId[1]) {
|
||||
courseMap.className = clazz.name
|
||||
courseMap.classId = clazz.id
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
courseMap.courseName = this.formLabelAlign.course.name
|
||||
courseMap.courseId = this.formLabelAlign.course.id
|
||||
this.temp.classMap.splice(index, 1, courseMap)
|
||||
} else {
|
||||
this.formLabelAlign.visiblePopover = false
|
||||
const courseMap = {}
|
||||
for (const index in this.gradeList) {
|
||||
var grade = this.gradeList[index]
|
||||
if (grade.id === this.formLabelAlign.classId[0]) {
|
||||
var classList = grade.clazzList
|
||||
for (var i in classList) {
|
||||
var clazz = classList[i]
|
||||
if (clazz.id === this.formLabelAlign.classId[1]) {
|
||||
courseMap.className = clazz.name
|
||||
courseMap.classId = clazz.id
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
courseMap.courseName = this.formLabelAlign.course.name
|
||||
courseMap.courseId = this.formLabelAlign.course.id
|
||||
this.temp.classMap.push(courseMap)
|
||||
}
|
||||
},
|
||||
updateCourse() {
|
||||
const courseMap = {}
|
||||
courseMap.courseName = this.courseData.course.name
|
||||
courseMap.className = this.className
|
||||
courseMap.courseId = this.courseData.course.id
|
||||
courseMap.classId = this.classId
|
||||
this.temp = this.courseData.teacher
|
||||
this.temp.classMap = []
|
||||
this.temp.classMap.push(courseMap)
|
||||
this.updateCourseData()
|
||||
},
|
||||
resetParent() {
|
||||
this.formLabelAlign = {
|
||||
class: {},
|
||||
classId: undefined,
|
||||
course: {},
|
||||
visiblePopover: true
|
||||
}
|
||||
},
|
||||
createParent() {
|
||||
this.resetParent()
|
||||
},
|
||||
addCourseForTeacher() {
|
||||
this.courseData = {
|
||||
class: {},
|
||||
classId: [],
|
||||
course: {},
|
||||
visiblePopover: true
|
||||
}
|
||||
},
|
||||
handleChange(value) {
|
||||
if (this.formLabelAlign.class == null) {
|
||||
this.formLabelAlign.class = {}
|
||||
}
|
||||
if (value != null && value.length > 1) {
|
||||
this.formLabelAlign.class.id = value[1]
|
||||
} else {
|
||||
this.formLabelAlign.class.id = null
|
||||
}
|
||||
},
|
||||
getSelectUser() {
|
||||
return this.userList
|
||||
},
|
||||
updateClass() {
|
||||
for (const index in this.gradeList) {
|
||||
const grade = this.gradeList[index]
|
||||
if (grade.id === this.listQuery.gradeId) {
|
||||
this.classList = grade.clazzList
|
||||
}
|
||||
}
|
||||
},
|
||||
fetchGradeList() {
|
||||
fetchGradeList(this.gradeQuery).then(response => {
|
||||
this.gradeList = response.data.result.list
|
||||
})
|
||||
},
|
||||
fetchCourseList() {
|
||||
fetchCourseList(this.gradeQuery).then(response => {
|
||||
this.courseList = response.data.result
|
||||
})
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.userList = val
|
||||
},
|
||||
getRowKeys(row) {
|
||||
return row.uid
|
||||
},
|
||||
getList() {
|
||||
this.multipleSelection = []
|
||||
this.listLoading = true
|
||||
fetchTeacherList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
this.listLoading = false
|
||||
}
|
||||
)
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus(row, index) {
|
||||
deleteTeacher({ id: row.teacherId }).then(() => {
|
||||
fetchTeacherList(this.listQuery).then(response => {
|
||||
this.list = response.data.result.list
|
||||
this.total = response.data.result.total
|
||||
})
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
}).catch(function(error) {
|
||||
console.log(error)
|
||||
})
|
||||
},
|
||||
resetTemp() {
|
||||
this.temp = {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
enrollmentDate: '',
|
||||
title: '',
|
||||
fid: this.$store.state.user.fid,
|
||||
teacherStatus: 1,
|
||||
uid: undefined,
|
||||
classMap: [],
|
||||
sex: 0,
|
||||
loginName: undefined
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp()
|
||||
this.disabled = false
|
||||
this.dialogStatus = 'create'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
createData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.updateTeacherData()
|
||||
}
|
||||
})
|
||||
},
|
||||
updateTeacherData() {
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
tempData.enrollmentDate = parseTime(tempData.enrollmentDate, '{y}-{m}-{d}')
|
||||
this.temp.enrollmentDate = tempData.enrollmentDate
|
||||
if (!this.temp.username) {
|
||||
this.temp.username = this.temp.name
|
||||
}
|
||||
updateTeacher(this.temp).then(response => {
|
||||
this.list.unshift(response.data.result)
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
)
|
||||
},
|
||||
updateCourseData() {
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
tempData.enrollmentDate = parseTime(tempData.enrollmentDate, '{y}-{m}-{d}')
|
||||
this.temp.enrollmentDate = tempData.enrollmentDate
|
||||
if (!this.temp.username) {
|
||||
this.temp.username = this.temp.name
|
||||
}
|
||||
addCourseClass(this.temp).then(response => {
|
||||
if (this.classId) {
|
||||
this.getList()
|
||||
this.courseData.visiblePopover = false
|
||||
}
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
)
|
||||
},
|
||||
handleUpdate(row, disabled) {
|
||||
this.disabled = disabled
|
||||
this.temp = Object.assign({}, row) // copy obj
|
||||
// 避免数组浅拷贝,修改之前数据。
|
||||
this.temp.classMap = JSON.parse(JSON.stringify(this.temp.classMap))
|
||||
if (this.temp.enrollmentDate != null) {
|
||||
this.temp.enrollmentDate = new Date(this.temp.enrollmentDate)
|
||||
}
|
||||
this.dialogStatus = 'update'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
updateData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
if (this.temp.enrollmentDate != null) {
|
||||
this.temp.enrollmentDate = new Date(this.temp.enrollmentDate)
|
||||
}
|
||||
if (!this.temp.username) {
|
||||
this.temp.username = this.temp.name
|
||||
}
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
tempData.enrollmentDate = parseTime(tempData.enrollmentDate, '{y}-{m}-{d}')
|
||||
this.temp.enrollmentDate = tempData.enrollmentDate
|
||||
updateTeacher(tempData).then(response => {
|
||||
if (response.data.code === 200) {
|
||||
if (this.classId) {
|
||||
this.getList()
|
||||
} else {
|
||||
for (const v of this.list) {
|
||||
if (v.id === this.temp.id) {
|
||||
const index = this.list.indexOf(v)
|
||||
this.list.splice(index, 1, this.temp)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
} else {
|
||||
this.$notify({
|
||||
title: '失败',
|
||||
message: response.data.message,
|
||||
type: 'error',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
}).catch(function(error) {
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
const index = this.list.indexOf(row)
|
||||
this.list.splice(index, 1)
|
||||
},
|
||||
handleFetchPv(pv) {
|
||||
fetchPv(pv).then(response => {
|
||||
this.pvData = response.data.pvData
|
||||
this.dialogPvVisible = true
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const data = this.formatJson(filterVal, this.list)
|
||||
excel.export_json_to_excel({
|
||||
header: tHeader,
|
||||
data,
|
||||
filename: 'table-list'
|
||||
})
|
||||
this.downloadLoading = false
|
||||
})
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue