master
tianea 3 years ago
parent 442cecdc4d
commit f6b37bbe8c

@ -1,12 +1,26 @@
import request from '@/utils/request' import request from '@/utils/request'
let baseUrl = '/pc/competition/' let baseUrl = '/pc/competition/'
export function getList(query) { export function getList(query) {
return request({ return request({
url: baseUrl+'list', url: baseUrl+'list',
method: 'post', method: 'post',
data: query data: query
}) })
} }
export function getMemberLogList(query) {
return request({
url: baseUrl+'memberLogList',
method: 'post',
data: query
})
}
export function getMemberLogListAll(query) {
return request({
url: baseUrl+'memberLogListAll',
method: 'post',
data: query
})
}
export function add(cat) { export function add(cat) {
return request({ return request({
url: baseUrl+"add", url: baseUrl+"add",

@ -27,4 +27,12 @@ return request({
method: 'post', method: 'post',
data: fd data: fd
}) })
}
export function importTeamMember(data){
return request({
url: "/api/competition/upload/importTeamMember",
method: 'post',
data: data
})
} }

@ -37,6 +37,13 @@ export function getMember(query){
data: query data: query
}) })
} }
export function listByKey(query){
return request({
url: '/pc/user/listByKey',
method: 'post',
data: query
})
}
export function addUser(data){ export function addUser(data){
return request({ return request({
url: 'pc/user/addUser', url: 'pc/user/addUser',

@ -35,6 +35,14 @@ export default {
url: { url: {
type: String, type: String,
default: '' default: ''
},
w:{
type: Number,
default: 800
},
h:{
type: Number,
default: 600
} }
}, },
data() { data() {
@ -44,6 +52,10 @@ export default {
myHeaders: {'Tz-Token':getToken()} myHeaders: {'Tz-Token':getToken()}
} }
}, },
created(){
this.dataObj.w =this.w
this.dataObj.h = this.h
},
methods: { methods: {
rmImage() { rmImage() {
this.emitInput('') this.emitInput('')

@ -101,6 +101,12 @@ export const constantRoutes = [
path: 'edit', path: 'edit',
name: 'Edit', name: 'Edit',
component: () => import('@/views/competition/create') component: () => import('@/views/competition/create')
},
{
path: 'teamimport',
name: 'teamimprort',
component: () => import('@/views/competition/memberlog'),
meta: { title: '活跃会员日志', icon: 'dasai' }
} }
] ]
}, },

@ -6,7 +6,7 @@ import { getToken } from '@/utils/auth'
const service = axios.create({ const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests // withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout timeout: 20000 // request timeout
}) })
// request interceptor // request interceptor
@ -41,7 +41,7 @@ service.interceptors.response.use(
* You can also judge the status by HTTP Status Code * You can also judge the status by HTTP Status Code
*/ */
response => { response => {
console.log(response)
const res = response.data const res = response.data
// if the custom code is not 200, it is judged as an error. // if the custom code is not 200, it is judged as an error.
if (res.code !== 200) { if (res.code !== 200) {

@ -0,0 +1,165 @@
<template>
<div class="cs">
<ReadExcel @file-change="excelFileChange">
<div class="import-button">导入</div>
</ReadExcel>
<div>
<div>团队总量:{{teamCount}}</div>
<div>队员总量:{{memberCount}}</div>
</div>
<div>
<el-button @click="startImport" type="primary">开始导入</el-button>
</div>
<el-table :data="teamList">
<el-table-column v-for="(item,$index) in tableHeader" :key="$index" :label="item" align="center">
<template slot-scope="scope">
<span v-if="$index == 0">{{ scope.row.teamName}}</span>
<div v-if="$index == 1">
<div v-for="(member,$index2) in scope.row.memberList" :key="$index2">
{{member.memberName}}
</div>
</div>
<div v-if="$index == 2">
<div v-for="(member,$index2) in scope.row.memberList" :key="$index2">
{{member.studentNo}}
</div>
</div>
<div v-if="$index == 3">
<div v-for="(member,$index2) in scope.row.memberList" :key="$index2">
{{member.className}}
</div>
</div>
<span v-if="$index == 4">
{{scope.row.school}}
</span>
<span v-if="$index == 5">
{{scope.row.teacher}}
</span>
<span v-if="$index == 7">
{{scope.row.province}}
</span>
<span v-if="$index == 8">
{{scope.row.level}}
</span>
<span v-if="$index == 9">
{{scope.row.area}}
</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import * as competition from '@/api/competition'
import * as teamMemberApi from '@/api/teammember'
import ReadExcel from './components/teamImport.vue'
export default {
data(){
return {
teamInfo:{
teamName:'',
teacher: '',
province: '',
level: '',
area: '',
school: '',
memberList:[]
},
teamList: [],
tableHeader: [],
fileName: '',
teamCount: 0,
memberCount: 0
}
},
components: {
ReadExcel,
},
methods: {
excelFileChange(data) {
let { merges, body, name, header } = data
// console.log(merges, body, name, header)
this.fileName =name
this.tableHeader = header
this.dataToObj(body)
},
startImport(){
let item = this.teamList[0]
if(!item){
alert("导入完成")
return
}
teamMemberApi.importTeamMember({
compI: 3,
stageId: 1,
teamName: item.teamName,
province: item.province,
level: item.level,
school: item.school,
area: item.area,
teacher: item.teacher,
memberList: item.memberList
}).then(res=>{
if(res.code == 200){
this.teamList.splice(0,1)
this.startImport()
}else{
alert(res.msg)
}
})
},
dataToObj(data){
let rs = []
for(let i = 1;i<data.length;i++){
let teamInfo = null;
let item = data[i]
let teamName = item[0]
let member = item[1]
let studentNo = item[2]
let className = item[3]
let school = item[4]
let teacher1 = item[5]
if(!teacher1){
teacher1 = ''
}
let teacher2 = item[6]
let province = item[7]
let level = item[8]
let area = item[9]
if(!teamName){
teamInfo = rs[rs.length-1]
}else{
teamInfo = JSON.parse(JSON.stringify(this.teamInfo))
teamInfo.teamName = teamName
teamInfo.teacher = !!teacher2?teacher1+","+teacher2:teacher1
teamInfo.province = province
teamInfo.level = level
teamInfo.area = area
teamInfo.school = school
rs.push(teamInfo)
}
teamInfo.memberList.push({
memberName: member,
studentNo: studentNo,
className: className
})
this.memberCount +=1
}
// console.log(rs)
this.teamList = rs
this.teamCount = rs.length
},
},
}
</script>

@ -7,7 +7,7 @@
menubar: false, menubar: false,
language:'zh_CN', language:'zh_CN',
images_upload_url: '/api/upload/image/upload', images_upload_url: '/api/upload/image/upload',
images_upload_handler: handleUpload, images_upload_handler: handleUpload,
plugins: [ plugins: [
'advlist autolink lists link image charmap', 'advlist autolink lists link image charmap',
'searchreplace visualblocks code fullscreen', 'searchreplace visualblocks code fullscreen',
@ -17,7 +17,11 @@
toolbar: toolbar:
'undo redo | formatselect | bold italic | \ 'undo redo | formatselect | bold italic | \
alignleft aligncenter alignright | \ alignleft aligncenter alignright | \
bullist numlist outdent indent | image | help' fontselect fontsizeselect |\
forecolor backcolor|\
bullist numlist outdent indent | image | help',
font_formats: 'Arial=arial,helvetica,sans-serif; Courier New=courier new,courier,monospace; AkrutiKndPadmini=Akpdmi-n;宋体=宋体;黑体=黑体;仿宋=仿宋;微软雅黑=微软雅黑;楷体-GB2312=楷体-GB2312',
fontsize_formats: '8pt 10pt 12pt 14pt 16pt 18pt 20pt 22pt 24pt 26pt 28pt 30pt 32pt 34pt 36pt 38pt 40pt 42pt 46pt 48pt',
}" }"
> >
</editor> </editor>
@ -46,6 +50,11 @@ export default {
handler(nv,ob){ handler(nv,ob){
this.$emit("update:content",nv) this.$emit("update:content",nv)
} }
},
content:{
handler(nv,ov){
this.temp = nv
}
} }
}, },
components:{ 'editor':Editor}, components:{ 'editor':Editor},

@ -128,12 +128,12 @@ export default {
} }
}) })
}, },
handleScroll(e){ handleScroll(e){
let scrollHeight = e.target.scrollHeight - e.target.clientHeight
if(e.srcElement.scrollTopMax == e.srcElement.scrollTop&&!this.loading){ if(scrollHeight - e.target.scrollTop == 0){
this.$emit("pageDown") this.$emit("pageDown")
} }
} }
} }
} }

@ -10,18 +10,45 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="主办方名称" prop="sponser"> <el-form-item label="主办方名称" prop="sponser">
<el-input v-model="survey.sponsor" /> <div v-for="(item,$index) in sponsorList" :key="$index">
<div><span class="tz-sponsor"> {{item}}</span> <el-button size="small" type="danger" @click="deleteSponsor($index,1)"> </el-button></div>
</div>
<div>
<el-input v-model="sponsorTemp" style="width: 53%;" />
<el-button @click="addSponsor(1)"></el-button>
</div>
</el-form-item> </el-form-item>
<el-form-item label="团队人数范围"> <el-form-item label="承办方" prop="organizer">
<el-input-number v-model="survey.teamMinCount" /> <div v-for="(item,$index) in organizerList" :key="$index">
<div><span class="tz-sponsor"> {{item}}</span> <el-button size="small" type="danger" @click="deleteSponsor($index,2)"> </el-button></div>
</div>
<div>
<el-input v-model="organizerTemp" style="width: 53%;" />
<el-button @click="addSponsor(2)"></el-button>
</div>
</el-form-item>
<el-form-item label="团队人数">
<el-input-number v-model="survey.teamMaxCount" /> <el-input-number v-model="survey.teamMaxCount" />
</el-form-item> </el-form-item>
<el-form-item class="form-item-line" label="技术支持方"> <el-form-item class="form-item-line" label="技术支持方">
<el-input v-model="survey.supporter" style="width: 33%;" /> <div v-for="(item,$index) in supporterList" :key="$index">
<div><span class="tz-sponsor"> {{item}}</span> <el-button size="small" type="danger" @click="deleteSponsor($index,3)"> </el-button></div>
</div>
<div>
<el-input v-model="supporterTemp" style="width: 33%;" />
<el-button @click="addSponsor(3)"></el-button>
</div>
</el-form-item> </el-form-item>
<el-form-item class="form-item-line" label="承办方"> <el-form-item class="form-item-line" label="联合支持方">
<el-input v-model="survey.organizer" style="width: 33%;" /> <div v-for="(item,$index) in supporterList2" :key="$index">
<div><span class="tz-sponsor"> {{item}}</span> <el-button size="small" type="danger" @click="deleteSponsor2($index,4)"> </el-button></div>
</div>
<div>
<el-input v-model="supporterTemp2" style="width: 33%;" />
<el-button @click="addSponsor(4)"></el-button>
</div>
</el-form-item> </el-form-item>
<el-form-item v-for="(item ,$index) in survey.stageList" :key="item.name" :label="item.name" class="form-item-line"> <el-form-item v-for="(item ,$index) in survey.stageList" :key="item.name" :label="item.name" class="form-item-line">
<div> <div>
<el-date-picker v-model="item.startTime" placeholder="请选择开始时间" /> <el-date-picker v-model="item.startTime" placeholder="请选择开始时间" />
@ -35,23 +62,28 @@
<el-date-picker v-model="item.singUpEndTime" placeholder="请选择报名截止时间"/> <el-date-picker v-model="item.singUpEndTime" placeholder="请选择报名截止时间"/>
</div> </div>
</div> </div>
<div>
<el-checkbox label="开启证券投资赛项" v-model="item.enableFinance"/>
<el-checkbox label="开启投资者教育赛项" v-model="item.enableExam"/>
</div>
</el-form-item> </el-form-item>
<el-form-item class="form-item-line"> <el-form-item class="form-item-line">
<el-input v-model="stageTemp.name" style="width: 20%; margin-right: 20px;" placeholder="赛段名称" /> <el-input v-model="stageTemp.name" style="width: 20%; margin-right: 20px;" placeholder="赛段名称" />
<el-date-picker v-model="stageTemp.startTime" placeholder="请选择开始时间" /><el-date-picker v-model="stageTemp.endTime" placeholder="请选择结束时间" /> <el-date-picker v-model="stageTemp.startTime" placeholder="请选择开始时间" /><el-date-picker v-model="stageTemp.endTime" placeholder="请选择结束时间" />
<el-button type="primary" @click="addStage"></el-button> <el-button type="primary" @click="addStage"></el-button>
</el-form-item> </el-form-item>
<el-form-item class="form-item-line" label="大赛缩略图"> <el-form-item class="form-item-line" label="大赛缩略图(340*190)">
<upload-image :url.sync="survey.thumbnail" /> <upload-image :url.sync="survey.thumbnail" :w="340" :h="190" />
</el-form-item> </el-form-item>
<el-form-item v-for="(item,$index) in survey.bannerList" :label="'轮播'+($index+1)" :key="$index" class="form-item-line" > <el-form-item v-for="(item,$index) in survey.bannerList" :label="'轮播'+($index+1)" :key="$index" class="form-item-line" >
<el-popover trigger="hover"><el-image fit="fit" :src="item.img" />{{ item.link}}<el-button slot="reference">查看</el-button></el-popover> <el-button type="danger" @click="deleteBanner($index)" ></el-button> <el-popover trigger="hover"><el-image fit="fit" :src="item.img" />{{ item.link}}<el-button slot="reference">查看</el-button></el-popover> <el-button type="danger" @click="deleteBanner($index)" ></el-button>
</el-form-item> </el-form-item>
<el-form-item class="form-item-line" label="大赛轮播图"> <el-form-item class="form-item-line" label="大赛轮播图(1920*258)">
<el-input v-model="tempBanner.link" placeholder="链接地址" /> <el-input v-model="tempBanner.link" placeholder="链接地址" />
<upload-image :url.sync="tempBanner.img" /> <upload-image :url.sync="tempBanner.img" :w="1920" :h="258" />
<el-button @click="addBanner" type="primary">添加</el-button> <el-button @click="addBanner" type="primary">添加</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -76,8 +108,7 @@ export default {
}, },
props: { props: {
survey: { survey: {
type: Object, type: Object
default: function() { return {} }
} }
}, },
data() { data() {
@ -124,6 +155,14 @@ export default {
id: 1, id: 1,
name: '本科' name: '本科'
}], }],
sponsorTemp:'',
sponsorList:[],
supporterTemp:'',
supporterTemp2:'',
supporterList:[],
supporterList2:[],
organizerTemp:'',
organizerList:[],
dialogStatus: '', dialogStatus: '',
statusOptions: ['published', 'draft', 'deleted'], statusOptions: ['published', 'draft', 'deleted'],
temp: { temp: {
@ -147,6 +186,34 @@ export default {
}, },
created() { created() {
this.fetchData() this.fetchData()
if(this.survey.sponsor){
this.sponsorList = this.survey.sponsor.split('|')
}
if(this.survey.supporter){
this.supporterList = this.survey.supporter.split('|')
}
if(this.survey.organizer){
this.organizerList = this.survey.organizer.split('|')
}
if(this.survey.supporter2){
this.supporterList2 = this.survey.supporter2.split('|')
}
},
watch:{
survey:{
deep: true,
handler(nv,ov){
if(nv.sponsor){
this.sponsorList = this.survey.sponsor.split('|')
}
if(nv.supporter){
this.supporterList = this.survey.supporter.split('|')
}
if(nv.organizer){
this.organizerList = this.survey.organizer.split('|')
}
}
}
}, },
methods: { methods: {
fetchData() { fetchData() {
@ -161,9 +228,22 @@ export default {
this.$refs['dataForm'].clearValidate() this.$refs['dataForm'].clearValidate()
}) })
}, },
deleteSponsor(index,type){
if(type == 1){
this.sponsorList.splice(index,1)
this.survey.sponsor = this.sponsorList.join('|')
}else if(type == 2){
this.organizerList.splice(index,1)
this.survey.organizer = this.organizerList.join('|')
}else if(type ==3){
this.supporterList.splice(index,1)
this.survey.supporter = this.supporterList.join('|')
}else if(type ==4 ){
this.supporterList2.splice(index,1)
this.survey.supporter2 = this.supporterList.join('|')
}
},
addStage(){ addStage(){
console.log(this.stageTemp)
console.log()
if(this.stageTemp.startTime>this.stageTemp.endTime){ if(this.stageTemp.startTime>this.stageTemp.endTime){
this.$notify({ this.$notify({
title: '操作失败', title: '操作失败',
@ -195,16 +275,39 @@ export default {
deleteStage(id,index){ deleteStage(id,index){
this.survey.stageList.splice(index,1) this.survey.stageList.splice(index,1)
}, },
addBanner(){ addSponsor(type){
if(!this.tempBanner.link||this.tempBanner.link.length<=0){ if(type == 1){
this.$notify({
title: '操作失败', if(this.sponsorTemp.length>0){
message: "轮播链接地址不能为空", this.sponsorList.push(this.sponsorTemp)
type: 'error', this.sponsorTemp = ''
duration: 2000 this.survey.sponsor = this.sponsorList.join("|")
}) }
return
}else if(type == 2){
if(this.organizerTemp.length>0){
this.organizerList.push(this.organizerTemp)
this.organizerTemp = ''
this.survey.organizer = this.organizerList.join('|')
}
}else if(type == 3){
if(this.supporterTemp.length>0){
this.supporterList.push(this.supporterTemp)
this.supporterTemp = ''
this.survey.supporter = this.supporterList.join('|')
}
}else if(type==4){
if(this.supporterTemp2.length>0){
this.supporterList2.push(this.supporterTemp2)
this.supporterTemp2 = ''
this.survey.supporter2 = this.supporterList2.join('|')
}
} }
},
addBanner(){
if(!this.tempBanner.img||this.tempBanner.img.length<=0){ if(!this.tempBanner.img||this.tempBanner.img.length<=0){
this.$notify({ this.$notify({
title: '操作失败', title: '操作失败',
@ -257,4 +360,8 @@ export default {
.filter-item{ .filter-item{
width: 100%; width: 100%;
} }
.tz-sponsor{
display: inline-block;
width: 33%;
}
</style> </style>

@ -14,7 +14,10 @@
<div class="tabBox"> <div class="tabBox">
<div class="boxHeader">成绩权重设置</div> <div class="boxHeader">成绩权重设置</div>
<div> <div>
综合得分=证券投资×<el-input-number v-model="temp.financePower" />+金融实操×<el-input-number v-model="temp.examPower" /> 综合得分=证券投资×<el-input-number v-model="temp.financePower" />+金融实操×<el-input-number v-model="temp.examPower" />
<div class="tz-inline" v-for="item in filterStageList()" :key="item.id">
+ {{item.name}}×<el-input-number v-model="item.power" />
</div>
</div> </div>
</div> </div>
<div class="tabBox"> <div class="tabBox">
@ -36,9 +39,9 @@
</el-form-item> </el-form-item>
</div> </div>
<el-form-item label="赛项logo" style="width:90%"> <!-- <el-form-item label="赛项logo" style="width:90%">
<upload-image :url.sync ="temp.operationLogo" /> <upload-image :url.sync ="temp.operationLogo" />
</el-form-item> </el-form-item> -->
<el-form-item label="操作分"> <el-form-item label="操作分">
<el-input-number v-model="temp.financeProfitPower" />+[用户收益率基准收益率÷最高收益率基准收益率]×<el-input-number v-model="temp.financeBasePower" /> <el-input-number v-model="temp.financeProfitPower" />+[用户收益率基准收益率÷最高收益率基准收益率]×<el-input-number v-model="temp.financeBasePower" />
</el-form-item> </el-form-item>
@ -54,9 +57,9 @@
<el-form-item label="答题时长"> <el-form-item label="答题时长">
<el-input-number v-model="temp.examDuration" />小时 <el-input-number v-model="temp.examDuration" />小时
</el-form-item> </el-form-item>
<el-form-item label="赛项logo" style="width:90%"> <!-- <el-form-item label="赛项logo" style="width:90%">
<upload-image :url.sync ="temp.examLogo" /> <upload-image :url.sync ="temp.examLogo" />
</el-form-item> </el-form-item> -->
<el-form-item label="题目设置"> <el-form-item label="题目设置">
<el-table :data="singleTable"> <el-table :data="singleTable">
<el-table-column label="题型" align="center"> <el-table-column label="题型" align="center">
@ -175,7 +178,7 @@
</el-table> </el-table>
<el-pagination <el-pagination
:current-page.sync="questionTempQuery.pageNo" :current-page.sync="questionTempQuery.pageNo"
:page-sizes="[10,20,30]" :page-sizes="[10,20,30,40,50]"
:page-size.sync="questionTempQuery.pageSize" :page-size.sync="questionTempQuery.pageSize"
layout="total,prev,pager,next,jumper,sizes" layout="total,prev,pager,next,jumper,sizes"
:total="questionTempQuery.total" :total="questionTempQuery.total"
@ -227,7 +230,7 @@
</el-table> </el-table>
<el-pagination <el-pagination
:current-page.sync="multiQuestQuery.pageNo" :current-page.sync="multiQuestQuery.pageNo"
:page-sizes="[10,20,30]" :page-sizes="[10,20,30,40,50]"
:page-size.sync="multiQuestQuery.pageSize" :page-size.sync="multiQuestQuery.pageSize"
layout="total,prev,pager,next,jumper,sizes" layout="total,prev,pager,next,jumper,sizes"
:total="multiQuestQuery.total" :total="multiQuestQuery.total"
@ -382,7 +385,7 @@ export default {
courseId: null, courseId: null,
levelId: null , levelId: null ,
total: 0, total: 0,
score: 1, score: null,
questionType: null, questionType: null,
stem: '' stem: ''
}, },
@ -394,7 +397,7 @@ export default {
courseId: null, courseId: null,
levelId: null , levelId: null ,
total: 0, total: 0,
score: 1, score: null,
questionType: null, questionType: null,
stem: '' stem: ''
}, },
@ -404,6 +407,11 @@ export default {
} }
}, },
methods: { methods: {
filterStageList(){
let currentStage = this.survey.stageList[this.tabId]
let rs = this.survey.stageList.filter(stage=>stage.id<currentStage.id)
return rs
},
changeTab(val){ changeTab(val){
this.tabId = val this.tabId = val
this.temp = this.task[val] this.temp = this.task[val]
@ -586,6 +594,9 @@ export default {
} }
</script> </script>
<style scoped> <style scoped>
.tz-inline{
display: inline-block;
}
.tab { .tab {
display: flex; display: flex;
} }

@ -8,10 +8,10 @@
</div> </div>
<div v-if="teamTabId == 1" class="tbPanel"> <div v-if="teamTabId == 1" class="tbPanel">
<div class="filter-container"> <div class="filter-container">
<el-input v-model="teamQuery.teamName" placeholder="团队名称" /> <el-input v-model="teamQuery.teamName" placeholder="团队名称" />
<el-button @click="loadData"></el-button> <el-button @click="loadData"></el-button>
<el-button @click="dialogVisable = true">添加团队</el-button> <el-button @click="dialogVisable = true">添加团队</el-button>
<el-button @click="batchImport"><input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx" @change="handleClick"></el-button> <el-button @click="batchImport"><input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx" @change="handleClick"></el-button>
</div> </div>
<el-table :data.sync="tableData"> <el-table :data.sync="tableData">
@ -26,7 +26,7 @@
<el-table-column v-for="item in columnList" :key="item.id" :label="item.lable"> <el-table-column v-for="item in columnList" :key="item.id" :label="item.lable">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row[item.name].name }} <i v-if="scope.row[item.name].name" @click="deleteMember(scope.row,item.name)" class="el-icon-delete" /> {{ scope.row[item.name].name }} <i v-if="scope.row[item.name].name" @click="deleteMember(scope.row,item.name)" class="el-icon-delete" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="指导老师"> <el-table-column label="指导老师">
<template slot-scope="scope"> <template slot-scope="scope">
@ -109,7 +109,8 @@
<div class="filter-container"> <div class="filter-container">
<el-input v-model="createTeam.teamName" placeholder="输入团队名" class="small" /> <el-input v-model="createTeam.teamName" placeholder="输入团队名" class="small" />
<el-input v-model="createTeam.teacher" placeholder="输入指导老师" class="small"/> <el-input v-model="createTeam.teacher" placeholder="输入指导老师" class="small"/>
<el-input placeholder="输入学号/姓名检索"/> <el-input v-model="memberQuery.name" placeholder="输入学号/姓名检索"/>
<el-button @click="searchMemberForTeam"></el-button>
</div> </div>
<div class="app-container"> <div class="app-container">
<select-panel :list="userList" :selectedList.sync='userSelectList' :loading="memberLoading" @pageDown="pageDown" /> <select-panel :list="userList" :selectedList.sync='userSelectList' :loading="memberLoading" @pageDown="pageDown" />
@ -130,7 +131,7 @@
</el-dialog> </el-dialog>
<el-dialog title="添加成员" :visible.sync="addMemberVisable"> <el-dialog title="添加成员" :visible.sync="addMemberVisable">
<div class="filter-container"> <div class="filter-container">
<el-input v-model="userQuery2.name" placeholder="输入学号或姓名"/> <el-input v-model="memberQuery.name" placeholder="输入学号或姓名"/>
<el-button @click="searchMember"></el-button> <el-button @click="searchMember"></el-button>
</div> </div>
<el-table :data="addMemberList" <el-table :data="addMemberList"
@ -149,7 +150,7 @@
</el-table-column> </el-table-column>
<el-table-column label="层次"> <el-table-column label="层次">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.level}} {{ idToLevelName(scope.row.levelId)}}
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -176,7 +177,7 @@
</el-table-column> </el-table-column>
<el-table-column label="姓名"> <el-table-column label="姓名">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.name}} {{ idToLevelName(scope.row.levelId)}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="层次"> <el-table-column label="层次">
@ -410,6 +411,12 @@ export default {
} }
}) })
}, },
idToLevelName(id){
let items = this.levelOptions.filter((item)=>{ return item.id == id})
if(items&&items.length>0){
return items[0].name
}
},
batchImport(){ batchImport(){
this.$refs['excel-upload-input'].click() this.$refs['excel-upload-input'].click()
}, },
@ -518,12 +525,29 @@ export default {
this.willAddMemberList =val this.willAddMemberList =val
}, },
searchMember(){ searchMember(){
userApi.getMember(this.memberQuery).then(res=>{ userApi.listByKey(this.memberQuery).then(res=>{
if(res.code == 200){
this.addMemberList = res.data.list
// const tmp = this.addMemberList.find(item=>item.id == res.data.id)
// if(!tmp){
// this.addMemberList.push(res.data)
// }
}else{
this.$notify({
title: '操作失败',
message: res.msg,
type: 'warning',
duration: 2000
})
}
})
},
searchMemberForTeam(){
userApi.listByKey(this.memberQuery).then(res=>{
if(res.code == 200){ if(res.code == 200){
const tmp = this.addMemberList.find(item=>item.id == res.data.id) this.userList = []
if(!tmp){ this.userList = res.data.list
this.addMemberList.push(res.data)
}
}else{ }else{
this.$notify({ this.$notify({
@ -570,7 +594,7 @@ export default {
}) })
}, },
addTeam(){ addTeam(){
console.log(this.createTeam,this.userSelectList)
if(this.userSelectList.length>0){ if(this.userSelectList.length>0){
let ids = [] let ids = []
this.userSelectList.forEach(user => ids.push(user.id)) this.userSelectList.forEach(user => ids.push(user.id))

@ -0,0 +1,135 @@
<template>
<div class="read_excel_file">
<slot></slot>
<input
class="file-input"
ref="readexcel_input"
type="file"
:accept="SheetJSFT"
@change="change"
/>
</div>
</template>
<script>
import * as XLSX from 'xlsx/xlsx.mjs';
export default {
data(){
return {
SheetJSFT: '.xlsx'
}
},
mounted(){
//
if (this.$slots && this.$slots.default && this.$slots.default.length > 0) {
this.$slots.default[0].elm.addEventListener(
'click',
this.openExcel.bind(this),
)
}
},
methods:{
// excel
openExcel() {
let uploadBtn = this.$refs['readexcel_input']
uploadBtn.click()
},
change(evt) {
const files = evt.target.files
if (!/\.xlsx$/.test(files[0].name)) {
this.$emit('validate', false)
this.$emit('file-change', {
name: files[0].name,
})
console.error('请选择xlsx格式文件')
return false
} else {
this.$emit('validate', true)
}
if (files && files[0]) this.file(files[0])
},
//
file(file) {
const reader = new FileReader()
reader.onload = e => {
const bstr = e.target.result
const wb = XLSX.read(bstr, { type: 'binary' }) // 使typebinary
const wsname = wb.SheetNames[0]
const ws = wb.Sheets[wsname]
const data = XLSX.utils.sheet_to_json(ws, {
header: 1,
// blankrows: false,
}) // json
// console.log(data)
// this.formatData(data, file.name, ws['!merges'])
this.$emit('file-change', {
header: data[0],
body: data,
name: file.name,
merges: ws['!merges']
})
}
reader.readAsBinaryString(file)
},
//
formatData(list, name, merges) {
let arr = []
for (let i = 1; i < list.length; i++) {
if (list[i].length > 0) {
let obj = {}
list[i].map((v, j) => {
obj[list[0][j]] = v
})
arr.push(obj)
}
}
this.$emit('file-change', {
header: list[0],
body: arr,
name: name,
merges: merges,
})
// inputvaluechange
this.$refs['readexcel_input'].value = ''
}
}
}
</script>
<style scoped>
.read_excel_file {
display: inline-block;
}
.file-input{
height: 0px;
width: 0px;
}
</style>

@ -9,46 +9,55 @@
<div class="tz-content"> <div class="tz-content">
<survey v-if="tabId==0" :survey="comp.survey" /> <survey v-if="tabId==0" :survey="comp.survey" />
<group v-if="tabId==1" :group="comp.group" :cmpId="competitionId" @on-group-change="chgGroup" /> <group v-if="tabId==1" :group="comp.group" :cmpId="competitionId" @on-group-change="chgGroup" />
<task v-if="tabId==2" :survey="comp.survey" :group="comp.group" :task.sync="comp.task" :cmpId="competitionId"/> <task v-if="tabId==2" :survey.sync="comp.survey" :group="comp.group" :task.sync="comp.task" :cmpId="competitionId"/>
<team v-if="tabId==3" :survey="comp.survey" :team="comp.team" :competitionType="comp.type" :cmpId="competitionId" /> <team v-if="tabId==3" :survey.sync="comp.survey" :team="comp.team" :competitionType="comp.type" :cmpId="competitionId" />
<summary-editor ref="summary" v-if="tabId == 4" :content.sync="comp.survey.summary" /> <summary-editor ref="summary" v-if="tabId == 4" :content.sync="comp.survey.summary" />
<rule-editor ref="rule" v-if="tabId == 5" :content.sync="comp.survey.rule" /> <rule-editor ref="rule" v-if="tabId == 5" :content.sync="comp.survey.rule" />
<prize-editor ref="prize" v-if="tabId == 6" :content.sync="comp.survey.prize" /> <prize-editor ref="prize" v-if="tabId == 6" :content.sync="comp.survey.prize" />
<div v-if="tabId==7"> <div v-if="tabId==7">
<div class="tabBox"> <div class="tabBox">
<el-input v-model="news.title" placeholder="标题" />
<el-input type="textarea" v-model="news.plainText" placeholder="摘要"/>
<news-editor :content.sync="news.content" /> <news-editor :content.sync="news.content" />
<div class="news-line"> <div class="news-line">
<upload-image style="width:30%" :url.sync="news.img" /> <upload-image style="width:30%" :url.sync="news.img" />
<el-button type="primary" @click="addNews(1)"></el-button> <el-button type="primary" @click="addNews(1)"></el-button>
</div> </div>
</div> </div>
<div class="new-content" v-for="item in comp.survey.news" :key="item.id"> <div class="new-content" v-for="(item,$index) in comp.survey.news" :key="item.id">
<div class="news-header"> <div class="news-header">
<img width="20%" :src="item.img" /> <div>
<img width="20%" :src="item.img" /><span>{{item.title}}</span>
</div>
<div v-html="item.content" /> <div v-html="item.content" />
</div> </div>
<div> <div>
<el-button type="primary">编辑</el-button> <el-button type="primary" @click="editNews($index,1)"></el-button>
<el-button type="danger">删除</el-button> <el-button type="danger" @click="deleteNews($index,1)"></el-button>
</div> </div>
</div> </div>
</div> </div>
<div v-if="tabId==8"> <div v-if="tabId==8">
<div class="tabBox"> <div class="tabBox">
<el-input v-model="schoolNews.title" placeholder="标题" />
<el-input type="textarea" v-model="schoolNews.plainText" placeholder="摘要"/>
<news-editor :content.sync="schoolNews.content" /> <news-editor :content.sync="schoolNews.content" />
<div class="news-line"> <div class="news-line">
<upload-image style="width:30%" :url.sync="schoolNews.img" /> <upload-image style="width:30%" :url.sync="schoolNews.img" />
<el-button type="primary" @click="addNews(2)"></el-button> <el-button type="primary" @click="addNews(2)"></el-button>
</div> </div>
</div> </div>
<div class="new-content" v-for="item in comp.survey.schoolNews" :key="item.id"> <div class="new-content" v-for="(item,$index) in comp.survey.schoolNews" :key="item.id">
<div class="news-header"> <div class="news-header">
<img width="20%" :src="item.img" /> <div>
<img width="20%" :src="item.img" /><span>{{item.title}}</span>
</div>
<div v-html="item.content" /> <div v-html="item.content" />
</div> </div>
<div> <div>
<el-button type="primary">编辑</el-button> <el-button type="primary" @click="editNews($index,2)"></el-button>
<el-button type="danger">删除</el-button> <el-button type="danger" @click="deleteNews($index,2)" >删除</el-button>
</div> </div>
</div> </div>
</div> </div>
@ -72,14 +81,7 @@ import * as taskApi from '@/api/task'
export default { export default {
watch:{
comp:{
handler(nv,ov){
console.log(nv)
},
deep:true
}
},
components: { components: {
'survey': Survey, 'survey': Survey,
'group': Group , 'group': Group ,
@ -98,10 +100,14 @@ export default {
news: { news: {
content: '', content: '',
img: '', img: '',
title: '',
plainText: ''
}, },
schoolNews: { schoolNews: {
content: '', content: '',
img: '' img: '',
title: '',
plainText: ''
}, },
comp: { comp: {
survey: { survey: {
@ -112,6 +118,7 @@ export default {
teamMinCount: 2, teamMinCount: 2,
teamMaxCount: 5, teamMaxCount: 5,
supporter: '', supporter: '',
supporter2: '',
stageList: [], stageList: [],
bannerList: [], bannerList: [],
thumbnail: '', thumbnail: '',
@ -148,7 +155,7 @@ export default {
id: 4 id: 4
}, },
{ {
name: '交易规则', name: '竞赛方式',
id: 5 id: 5
}, },
{ {
@ -189,6 +196,14 @@ export default {
} }
}, },
methods: { methods: {
deleteNews(index,type){
if(type==1){
this.comp.survey.news.splice(index,1)
}else{
this.comp.survey.schoolNews.splice(index,1)
}
},
changeTab(val) { changeTab(val) {
this.tabId = val this.tabId = val
if(this.tabId == 2){ if(this.tabId == 2){
@ -271,6 +286,9 @@ export default {
} }
}) })
} else if(this.tabId == 2){ } else if(this.tabId == 2){
competition.add(this.comp.survey).then(res => {
})
taskApi.add({list: this.comp.task}).then(res=>{ taskApi.add({list: this.comp.task}).then(res=>{
if(res.code == 200) { if(res.code == 200) {
@ -299,20 +317,52 @@ export default {
chgGroup(val){ chgGroup(val){
this.comp.group = val this.comp.group = val
}, },
sortNews(){
this.comp.survey.news.sort((a,b)=>{
return b.createTime - a.createTime
})
this.comp.survey.schoolNews.sort((a,b)=>{
return b.createTime - a.createTime
})
},
editNews(index,type){
if(type == 1){
let news = this.comp.survey.news[index]
this.news.title = news.title
this.news.plainText = news.plainText
this.news.content = news.content
this.news.img = news.img
this.comp.survey.news.splice(index,1)
}else{
let news = this.comp.survey.schoolNews[index]
this.schoolNews.title = news.title
this.schoolNews.plainText = news.plainText
this.schoolNews.content = news.content
this.schoolNews.img = news.img
this.comp.survey.schoolNews.splice(index,1)
}
},
addNews(type){ addNews(type){
if(type == 1){ if(type == 1){
console.log(this.news)
if(!this.comp.survey.news){ if(!this.comp.survey.news){
this.comp.survey.news = [] this.comp.survey.news = []
} }
this.comp.survey.news.push(this.news) this.news.createTime = new Date().getTime()
this.comp.survey.news.push(Object.assign({}, this.news))
}else{ }else{
console.log(this.schoolNews)
this.schoolNews.createTime = new Date().getTime()
if(!this.comp.survey.schoolNews){ if(!this.comp.survey.schoolNews){
this.comp.survey.schoolNews = [] this.comp.survey.schoolNews = []
} }
this.comp.survey.schoolNews.push(this.schoolNews)
this.comp.survey.schoolNews.push(Object.assign({},this.schoolNews))
this.comp.survey.schoolNews = this.comp.survey.schoolNews.sort((a,b)=>{
return new Date(a.createTime) - new Date(b.createTime)
})
} }
this.sortNews()
} }
} }

@ -0,0 +1,139 @@
<template>
<div class="app-container">
<div class="tz-line">
<el-date-picker v-model="listQuery.shortDate" format="yyyy-MM-dd" value-format="yyyy-MM-dd" />
<el-button type="primary" @click="fetchData" icon="el-icon-search">查询</el-button>
<el-button type="primary" @click="exprot" icon="el-icon-searh">导出</el-button>
</div>
<el-table
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
border
fit
highlight-current-row
>
<el-table-column label="学号" align="center">
<template slot-scope="scope">
{{ scope.row.studentNo }}
</template>
</el-table-column>
<el-table-column label="姓名" align="center">
<template slot-scope="scope">
<span>{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column label="ip" align="center">
<template slot-scope="scope">
<span>{{ scope.row.ip }}</span>
</template>
</el-table-column>
<el-table-column label="学校" align="center">
<template slot-scope="scope">
<span>{{ scope.row.school }}</span>
</template>
</el-table-column>
<el-table-column label="更新时间" align="center">
<template slot-scope="scope">
<span>{{ new Date(scope.row.updateTime).Format('yyyy-MM-dd hh:mm:ss') }}</span>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="listQuery.pageNo"
:page-sizes="[10,15,20]"
:page-size="listQuery.pageSize"
layout="total,prev,pager,next,jumper,sizes"
:total="total"
@size-change="fetchData"
@current-change="fetchData"
/>
</div>
</template>
<script>
import * as competition from '@/api/competition'
export default {
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'info',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
return {
list: null,
listLoading: true,
listQuery: {
pageNo: 0,
pageSize: 20,
shortDate: ''
},
total: 0
}
},
created() {
this.fetchData()
},
methods: {
fetchData() {
this.listLoading = true
if(this.listQuery.shortDate.length==0){
this.listQuery.shortDate = new Date().Format("yyyy-MM-dd")
}
competition.getMemberLogList(this.listQuery).then(response => {
this.list = response.data.list
this.total = response.data.total
this.listLoading = false
})
},
formatJson(filterVal,jsonData){
return jsonData.map(v => filterVal.map(j => {
if(j=='updateTime'){
return new Date(v[j]).Format('yyyy-MM-dd hh:mm:ss')
}
return v[j]
}))
},
exprot(){
if(this.listQuery.shortDate.length==0){
this.listQuery.shortDate = new Date().Format("yyyy-MM-dd")
}
competition.getMemberLogListAll(this.listQuery).then(res => {
// this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = [ '学号','姓名','ip','学校','时间']
const filterVal = ['studentNo','name','ip','school','updateTime']
const list = res.data.list
const data = this.formatJson(filterVal, list)
console.log(data)
excel.export_json_to_excel({
header: tHeader,
data,
filename: 'member-log',
autoWidth: true,
bookType: 'xlsx'
})
// this.downloadLoading = false
})
})
}
}
}
</script>
<style scoped>
.tz-line{
display: flex;
width: 100%;
margin-bottom: 20px;
}
.tz-line button{
margin-left: 10px;
}
</style>

@ -110,7 +110,6 @@ export default {
this.$refs.loginForm.validate(valid => { this.$refs.loginForm.validate(valid => {
if (valid) { if (valid) {
this.loading = true this.loading = true
console.log("login1")
this.$store.dispatch('user/login', this.loginForm).then(() => { this.$store.dispatch('user/login', this.loginForm).then(() => {
this.$router.push({ path: this.redirect || '/' }) this.$router.push({ path: this.redirect || '/' })
this.loading = false this.loading = false
@ -118,7 +117,6 @@ export default {
this.loading = false this.loading = false
}) })
} else { } else {
console.log("login3")
return false return false
} }
}) })

@ -43,6 +43,7 @@
toolbar: toolbar:
' undo redo | formatselect | bold italic | \ ' undo redo | formatselect | bold italic | \
alignleft aligncenter alignright | \ alignleft aligncenter alignright | \
forecolor backcolor |\
bullist numlist outdent indent | image | help' bullist numlist outdent indent | image | help'
}" }"
> >

@ -34,6 +34,8 @@
menubar: false, menubar: false,
language:'zh_CN', language:'zh_CN',
images_upload_url: '/api/upload/image/upload', images_upload_url: '/api/upload/image/upload',
font_formats: '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif',
fontsize_formats: '11px 12px 14px 16px 18px 24px 36px 48px',
plugins: [ plugins: [
'advlist autolink lists link image charmap', 'advlist autolink lists link image charmap',
'searchreplace visualblocks code fullscreen', 'searchreplace visualblocks code fullscreen',
@ -43,6 +45,9 @@
toolbar: toolbar:
' undo redo | formatselect | bold italic | \ ' undo redo | formatselect | bold italic | \
alignleft aligncenter alignright | \ alignleft aligncenter alignright | \
forecolor backcolor |\
fontsizeselect |\
fontselect |\
bullist numlist outdent indent | image | help' bullist numlist outdent indent | image | help'
}" }"
> >

@ -53,6 +53,11 @@
<span>{{ courseToName(scope.row.courseId) }}</span> <span>{{ courseToName(scope.row.courseId) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="状态" align="center">
<template slot-scope="scope">
<span>{{ scope.row.status==1?'上架':'上架' }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="350" class-name="small-padding fixed-width"> <el-table-column align="center" label="操作" width="350" class-name="small-padding fixed-width">
<template slot-scope="{row,$index}"> <template slot-scope="{row,$index}">
<el-button type="primary" size="mini" @click="updateStatus(row,1)"> <el-button type="primary" size="mini" @click="updateStatus(row,1)">

@ -59,6 +59,11 @@
<span>{{ courseToName(scope.row.courseId) }}</span> <span>{{ courseToName(scope.row.courseId) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="状态" align="center">
<template slot-scope="scope">
<span>{{ scope.row.status == 1?'上架':'下架' }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="350" class-name="small-padding fixed-width"> <el-table-column align="center" label="操作" width="350" class-name="small-padding fixed-width">
<template slot-scope="{row,$index}"> <template slot-scope="{row,$index}">
<el-button type="primary" size="mini" @click="updateStatus(row,1)"> <el-button type="primary" size="mini" @click="updateStatus(row,1)">
@ -214,7 +219,9 @@ export default {
duration: 2000 duration: 2000
}) })
} }
this.fetchData()
} }
}) })
}, },
typeToName(type){ typeToName(type){

@ -23,7 +23,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="区域"> <el-form-item label="区域">
<el-select v-model="temp.regionId" class="filter-item" placeholder="请选择"> <el-select disabled v-model="temp.regionId" class="filter-item" placeholder="请选择">
<el-option v-for="item in regionOptions" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in regionOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>

@ -208,13 +208,12 @@ export default {
}, },
loginout(){ loginout(){
auth.loginout() auth.loginout()
this.$router.push({
memberApi.loginout().then(res=>{ path: '/'
}) })
this.$nextTick(()=>{
this.$router.push({ memberApi.loginout().then(res=>{
path: '/' })
}) })
}, },
convertLevel(id){ convertLevel(id){

@ -77,7 +77,11 @@ public class TeamBiz {
public Result<String> deleteMember(TeamMemberVO vo){ public Result<String> deleteMember(TeamMemberVO vo){
CompetitionMember member = memberDao.getById(vo.getId()); CompetitionMember member = memberDao.getById(vo.getId());
if(member!=null){ if(member!=null){
if(StringUtils.hasText(member.getAccountId())){
return Result.error("此账号已创建资金账号无法删除");
}
memberDao.deleteById(vo.getId()); memberDao.deleteById(vo.getId());
updatePeopleCount(member.getCompetitionId()); updatePeopleCount(member.getCompetitionId());
}else { }else {

@ -232,7 +232,7 @@ public class JueJinApi {
// api.createReport(accountId,"report"+ System.currentTimeMillis()); // api.createReport(accountId,"report"+ System.currentTimeMillis());
// api.getTenPosition("9d7f4856-cc11-11ec-9cd0-00163e0e6ad0"); // api.getTenPosition("9d7f4856-cc11-11ec-9cd0-00163e0e6ad0");
// api.getCashInfo("cbee8129-cae7-11ec-a4f7-00163e0e6ad0"); // api.getCashInfo("cbee8129-cae7-11ec-a4f7-00163e0e6ad0");
String content = api.getReport("57239410"); String content = api.getReport("57240003");
System.out.println(content); System.out.println(content);
// String reportDetail = api.reportDetail("55910953"); // String reportDetail = api.reportDetail("55910953");
// System.out.println(content); // System.out.println(content);

Loading…
Cancel
Save