赛事分配等

dev_202412
yujialong 9 months ago
parent 212b51d209
commit 5faaded976
  1. 1
      src/api/index.js
  2. 402
      src/libs/util.js
  3. 35
      src/pages/match/add/step3.vue
  4. 2
      src/pages/match/manage/abnormalTeam.vue
  5. 113
      src/pages/match/manage/matchSignup.vue

@ -176,6 +176,7 @@ export default {
automaticAllocation: `competition/competition/automaticAllocation/automaticAllocation`,
checkTeamStatus: `competition/teamAbnormalInformation/checkTeamStatus`,
queryAbnormalTeam: `competition/teamAbnormalInformation/queryAbnormalTeam`,
viewEventAllocationInformation: `competition/competitionAutomaticAllocationRecord/viewEventAllocationInformation`,
// 赛事内容
addCompetitionContent: `competition/competition/content/addCompetitionContent`,

@ -16,210 +16,210 @@ const exts = {
compress: 'zip,rar,7z,tar,gz,bz2',
}
const util = {
cookies,
local: _local,
session: _session,
// 传入身份证获取生日
getBirth(idCard) {
var birthday = "";
if (idCard != null && idCard != "") {
if (idCard.length == 15) {
birthday = "19" + idCard.slice(6, 12);
} else if (idCard.length == 18) {
birthday = idCard.slice(6, 14);
}
birthday = birthday.replace(/(.{4})(.{2})/, "$1-$2-");
//通过正则表达式来指定输出格式为:1990-01-01
}
return birthday;
},
// new Date('2020-11-12 00:00:00') 在IE下失效,因此把-替换成/
dateCompatible(date) {
return date.replace(/\-/g, "/");
},
// 日期时间前面补零
formateTime(num) {
return num < 10 ? `0${num}` : num;
},
//返回格式化时间,传参例如:"yyyy-MM-dd hh:mm:ss"
formatDate(fmt, date) {
var date = date ? date : new Date();
var o = {
"M+": date.getMonth() + 1, //月份
"d+": date.getDate(), //日
"h+": date.getHours(), //小时
"m+": date.getMinutes(), //分
"s+": date.getSeconds(), //秒
"q+": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
},
// 移除数组中指定值
removeByValue(arr, val) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == val) {
arr.splice(i, 1);
break;
}
}
},
// 传入文件后缀判断是否是视频
isVideo(ext) {
if (exts.video.includes(ext)) return true;
return false;
},
// 传入文件后缀判断是否是音频
isAudio(ext) {
if (exts.audio.includes(ext)) return true;
return false;
},
// 传入文件后缀判断是否是图片
isImg(ext) {
if (exts.img.includes(ext)) return true;
return false;
},
// 传入文件后缀判断是否是pdf以外的文档
isDoc(ext) {
if (exts.doc.includes(ext)) return true;
return false;
},
// 传入文件后缀判断是否是压缩包
isCompress(ext) {
if (exts.compress.includes(ext)) return true;
return false;
},
// 判断是否能够预览
canPreview(ext) {
if (!util.isVideo(ext) && !util.isAudio(ext) && !util.isImg(ext) && !util.isDoc(ext)) return false
return true
},
// 循环去除html标签
removeHtmlTag(list, attr) {
list.map(n => {
n[attr] = n[attr].replace(/<\/?.+?>/gi, "");
});
return list;
},
// 传入文件名获取文件后缀
getFileExt(fileName) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
},
// 传入文件名和路径,下载图片视频,支持跨域,a标签加download不支持跨域
downloadFile(fileName, url) {
var x = new XMLHttpRequest();
x.open("GET", url, true);
x.responseType = "blob";
x.onload = function(e) {
var url = window.URL.createObjectURL(x.response);
var a = document.createElement("a");
a.href = url;
a.download = fileName;
a.click();
};
x.send();
},
// 传入文件名和数据,下载文件
downloadFileDirect(fileName, data) {
if ("download" in document.createElement("a")) { // 非IE下载
const elink = document.createElement("a");
elink.download = fileName;
elink.style.display = "none";
elink.href = URL.createObjectURL(data);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink);
} else { // IE10+下载
navigator.msSaveBlob(data, fileName);
}
},
// 传入字符串,返回去除[]后的字符串,因为通过get请求带入方括号的话会有问题
encodeStr(str) {
if (str.includes("[") || str.includes("]")) {
let newStr = "";
for (let i of str) {
if (i == "[" || i == "]") {
newStr += encodeURI(i);
} else {
newStr += i;
}
}
return newStr;
}
return str;
},
// 成功提示
successMsg(message, duration = 3000) {
Message.closeAll();
return Message.success({ message, showClose: true, offset: (document.documentElement.clientHeight - 40) / 2, duration });
},
// 警告提示
warningMsg(message, duration = 3000) {
Message.closeAll();
return Message.warning({ message, showClose: true, offset: (document.documentElement.clientHeight - 40) / 2, duration });
},
// 错误提示
errorMsg(message, duration = 3000) {
Message.closeAll();
return Message.error({ message, showClose: true, offset: (document.documentElement.clientHeight - 40) / 2, duration });
},
debounce(fn, delay) { // 防抖
let timeout = null;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => {
fn.apply(context, args);
}, delay);
};
},
deepCopy(obj) { // 深拷贝
if (obj == null) {
return null;
}
if (typeof obj !== "object") return obj;
let result;
if (Array.isArray(obj)) {
result = [];
obj.forEach(item => {
result.push(
typeof item === "object" && !(item instanceof Date)
? util.deepCopy(item)
: item
);
});
cookies,
local: _local,
session: _session,
// 传入身份证获取生日
getBirth (idCard) {
var birthday = "";
if (idCard != null && idCard != "") {
if (idCard.length == 15) {
birthday = "19" + idCard.slice(6, 12);
} else if (idCard.length == 18) {
birthday = idCard.slice(6, 14);
}
birthday = birthday.replace(/(.{4})(.{2})/, "$1-$2-");
//通过正则表达式来指定输出格式为:1990-01-01
}
return birthday;
},
// new Date('2020-11-12 00:00:00') 在IE下失效,因此把-替换成/
dateCompatible (date) {
return date.replace(/\-/g, "/");
},
// 日期时间前面补零
formateTime (num) {
return num < 10 ? `0${num}` : num;
},
//返回格式化时间,传参例如:"yyyy-MM-dd hh:mm:ss"
formatDate (fmt, date) {
var date = date ? date : new Date();
var o = {
"M+": date.getMonth() + 1, //月份
"d+": date.getDate(), //日
"h+": date.getHours(), //小时
"m+": date.getMinutes(), //分
"s+": date.getSeconds(), //秒
"q+": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
},
// 移除数组中指定值
removeByValue (arr, val) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == val) {
arr.splice(i, 1);
break;
}
}
},
// 传入文件后缀判断是否是视频
isVideo (ext) {
if (exts.video.includes(ext)) return true;
return false;
},
// 传入文件后缀判断是否是音频
isAudio (ext) {
if (exts.audio.includes(ext)) return true;
return false;
},
// 传入文件后缀判断是否是图片
isImg (ext) {
if (exts.img.includes(ext)) return true;
return false;
},
// 传入文件后缀判断是否是pdf以外的文档
isDoc (ext) {
if (exts.doc.includes(ext)) return true;
return false;
},
// 传入文件后缀判断是否是压缩包
isCompress (ext) {
if (exts.compress.includes(ext)) return true;
return false;
},
// 判断是否能够预览
canPreview (ext) {
if (!util.isVideo(ext) && !util.isAudio(ext) && !util.isImg(ext) && !util.isDoc(ext)) return false
return true
},
// 循环去除html标签
removeHtmlTag (list, attr) {
list.map(n => {
n[attr] = n[attr].replace(/<\/?.+?>/gi, "");
});
return list;
},
// 传入文件名获取文件后缀
getFileExt (fileName) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
},
// 传入文件名和路径,下载图片视频,支持跨域,a标签加download不支持跨域
downloadFile (fileName, url) {
var x = new XMLHttpRequest();
x.open("GET", url, true);
x.responseType = "blob";
x.onload = function (e) {
var url = window.URL.createObjectURL(x.response);
var a = document.createElement("a");
a.href = url;
a.download = fileName;
a.click();
};
x.send();
},
// 传入文件名和数据,下载文件
downloadFileDirect (fileName, data) {
if ("download" in document.createElement("a")) { // 非IE下载
const elink = document.createElement("a");
elink.download = fileName;
elink.style.display = "none";
elink.href = URL.createObjectURL(data);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink);
} else { // IE10+下载
navigator.msSaveBlob(data, fileName);
}
},
// 传入字符串,返回去除[]后的字符串,因为通过get请求带入方括号的话会有问题
encodeStr (str) {
if (str.includes("[") || str.includes("]")) {
let newStr = "";
for (let i of str) {
if (i == "[" || i == "]") {
newStr += encodeURI(i);
} else {
result = {};
Object.keys(obj).forEach(key => {
result[key] =
typeof obj[key] === "object" && !(obj[key] instanceof Date)
? util.deepCopy(obj[key])
: obj[key];
});
newStr += i;
}
}
return newStr;
}
return str;
},
// 成功提示
successMsg (message, duration = 3000) {
Message.closeAll();
return Message.success({ message, showClose: true, offset: (document.documentElement.clientHeight - 40) / 2, duration });
},
// 警告提示
warningMsg (message, duration = 3000) {
Message.closeAll();
return Message.warning({ message, showClose: true, offset: (document.documentElement.clientHeight - 40) / 2, duration });
},
// 错误提示
errorMsg (message, duration = 3000) {
Message.closeAll();
return Message.error({ message, showClose: true, offset: (document.documentElement.clientHeight - 40) / 2, duration });
},
debounce (fn, delay) { // 防抖
let timeout = null;
return function () {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => {
fn.apply(context, args);
}, delay);
};
},
deepCopy (obj) { // 深拷贝
if (obj == null) {
return null;
}
if (typeof obj !== "object") return obj;
let result;
if (Array.isArray(obj)) {
result = [];
obj.forEach(item => {
result.push(
typeof item === "object" && !(item instanceof Date)
? util.deepCopy(item)
: item
);
});
} else {
result = {};
Object.keys(obj).forEach(key => {
result[key] =
typeof obj[key] === "object" && !(obj[key] instanceof Date)
? util.deepCopy(obj[key])
: obj[key];
});
}
return result;
},
// 获取当前时间
getNow () {
return new Promise(async (resolve, reject) => {
const { data } = await axios.get(Setting.apiBaseURL + api.getCurrentTime, {
headers: {
token: _local.get(Setting.tokenKey)
}
return result;
},
// 获取当前时间
getNow () {
return new Promise(async (resolve, reject) => {
const { data } = await axios.get(Setting.apiBaseURL + api.getCurrentTime, {
headers: {
token: _local.get(Setting.tokenKey)
}
})
resolve(new Date(data.currentTime))
})
},
resolve(new Date(data.currentTime))
})
},
};
export default util;

@ -310,29 +310,40 @@ export default {
},
//
async autoAllocationConfirm (next) {
//
if (this.form[0].contentId) {
//
const res = await this.$post(`${this.api.editWhetherPopUpsAppear}?competitionId=${this.id}`)
if (res.popupState) {
this.$confirm('报名的团队将按照新设置的规则进行自动分配阶段参赛人员,当前已分配的阶段参赛人员是否需要保留?', '提示', {
cancelButtonText: '已分配的保留',
confirmButtonText: '全部重新分配',
// >
if (new Date(this.$parent.$refs.step1.form.signUpEndTime) > Date.now()) {
this.$confirm('<p>团队赛发布成功,是否要重新自动分配阶段参赛人员?</p><p style="margin-top: 10px;color: #a9a9a9;">(点击“是”将会<span style="color: #f00;">在报名结束后</span>给报名的团队自动分配阶段参赛人员</p>', '提示', {
confirmButtonText: '是',
cancelButtonText: '否',
type: 'success',
closeOnClickModal: false,
showClose: false,
dangerouslyUseHTMLString: true,
}).then(async () => {
await this.$post(`${this.api.automaticAllocation}?competitionId=${this.id}`)
this.$emit('next', next)
this.automaticAllocation(1, next)
}).catch(() => {
this.automaticAllocation(0, next)
})
} else {
this.$confirm('<p>团队赛发布成功,是否要重新自动分配阶段参赛人员?</p><p style="margin-top: 10px;color: #a9a9a9;">(点击“是”将会<span style="color: #f00;">立即</span>给报名的团队自动分配阶段参赛人员</p>', '提示', {
confirmButtonText: '是',
cancelButtonText: '否',
type: 'success',
closeOnClickModal: false,
showClose: false,
dangerouslyUseHTMLString: true,
}).then(async () => {
await this.$post(`${this.api.automaticAllocation}?competitionId=${this.id}`) //
this.$emit('next', next)
// this.automaticAllocation(0, next)
}).catch(() => {
this.automaticAllocation(0, next)
});
} else {
this.$emit('next', next)
}
} else {
//
this.$confirm('<p>团队赛已发布,是否要自动分配阶段人员?</p><p style="margin-top: 10px;color: #a9a9a9;">(点击“是”将会在报名结束后给报名的团队自动分配阶段参赛人员</p>', '提示', {
this.$confirm('<p>团队赛发布成功,是否要自动分配阶段参赛人员?</p><p style="margin-top: 10px;color: #a9a9a9;">(点击“是”将会在报名结束后给报名的团队自动分配阶段参赛人员</p>', '提示', {
confirmButtonText: '是',
cancelButtonText: '否',
type: 'success',

@ -59,7 +59,7 @@
</el-table-column>
<el-table-column prop="captain" label="团队状态" min-width="80" align="center">
<template slot-scope="scope">
<p style="font-size: 16px;color: #f00;">异常</p>
<el-link type="danger" style="font-size: 16px" @click="toInfo(scope.row)">异常</el-link>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="270">

@ -17,7 +17,8 @@
</li>
</ul>
<div>
<el-button type="primary" round @click="autoAllocation">自动分配阶段成员</el-button>
<el-button type="primary" round @click="autoAllocationConfirm">{{ !notBeginSign && allocated ? '取消' : ''
}}自动分配阶段成员</el-button>
<el-button type="primary" round @click="batchImport">导入</el-button>
<el-button type="primary" round @click="add" v-auth="'/match/list:管理:报名人员:新增'">新增</el-button>
<el-button type="primary" round :loading="exporting" @click="exportAll"
@ -183,14 +184,14 @@
</template>
<script>
import util from "@/libs/util";
import Util from "@/libs/util";
import axios from 'axios'
import Setting from "@/setting";
export default {
name: "matchSignup",
data () {
return {
token: util.local.get(Setting.tokenKey),
token: Util.local.get(Setting.tokenKey),
schoolId: this.$store.state.user.schoolId,
id: +this.$route.query.id,
info: {
@ -275,12 +276,16 @@ export default {
uploadTips: '',
exportCode: '',
headers: {
token: util.local.get(Setting.tokenKey)
token: Util.local.get(Setting.tokenKey)
},
diffSchool: false,
uploading: false,
exporting: false,
loading: false,
timer: null,
now: '',
notBeginSign: true,
allocated: true,
};
},
watch: {
@ -302,6 +307,7 @@ export default {
this.getData()
this.getInfo()
this.getTeam()
this.getAutomaticAllocation()
},
methods: {
init () {
@ -333,18 +339,57 @@ export default {
this.$refs.table.clearSelection();
},
//
getInfo () {
this.$post(`${this.api.getCompetition}?competitionId=${this.id}`).then(({ competition }) => {
this.info = competition
this.getSchool()
//
if (competition.competitionScope) {
this.getClient()
} else {
this.schoolDisable = true
this.form.schoolId = this.$store.state.user.schoolId
}
}).catch(err => { })
async getInfo () {
const { competition } = await this.$post(`${this.api.getCompetition}?competitionId=${this.id}`)
this.info = competition
this.getSchool()
//
if (competition.competitionScope) {
this.getClient()
} else {
this.schoolDisable = true
this.form.schoolId = this.$store.state.user.schoolId
}
// /
clearInterval(this.timer)
this.now = await Util.getNow()
this.timer = setInterval(() => {
this.now = new Date(this.now.setSeconds(this.now.getSeconds() + 1))
this.notBeginSign = this.now > new Date(this.info.signUpEndTime) //
}, 1000)
},
//
async getAutomaticAllocation () {
const res = await this.$post(`${this.api.viewEventAllocationInformation}?competitionId=${this.id}`)
this.allocated = res.data && res.data.assignOrNot
},
//
async automaticAllocation (assignOrNot) {
await this.$post(this.api.updateEventAllocationRecord, {
assignOrNot,
competitionId: this.id,
})
this.getAutomaticAllocation()
},
//
async autoAllocationConfirm () {
//
if (this.notBeginSign) {
this.$confirm('确定立即自动分配阶段成员?', '提示', {
type: 'success',
closeOnClickModal: false,
}).then(async () => {
await this.$post(`${this.api.automaticAllocation}?competitionId=${this.id}`) //
}).catch(() => { })
} else {
this.$confirm(`确定${this.allocated ? '取消' : '开启'}自动分配阶段成员?`, {
type: 'success',
closeOnClickModal: false,
}).then(async () => {
this.automaticAllocation(this.allocated ? 0 : 1)
}).catch(() => { })
}
},
initData () {
this.handleCurrentChange(1)
@ -401,7 +446,7 @@ export default {
},
//
handleExceed (files, fileList) {
util.warningMsg(
Util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
)
},
@ -413,7 +458,7 @@ export default {
}).then((res) => {
console.log("🚀 ~ showFaild ~ res:", res)
const name = res.headers['content-disposition']
util.downloadFileDirect(name ? decodeURI(name) : '批量导入报名人员失败数据导出.xlsx', new Blob([res.data]))
Util.downloadFileDirect(name ? decodeURI(name) : '批量导入报名人员失败数据导出.xlsx', new Blob([res.data]))
}).catch(res => { })
},
uploadSuccess ({ data, status }) {
@ -428,11 +473,11 @@ export default {
this.uploadFaild = true
this.uploadTips = tip
} else {
util[tip.includes('5000') ? 'errorMsg' : 'successMsg'](tip, 3000)
Util[tip.includes('5000') ? 'errorMsg' : 'successMsg'](tip, 3000)
this.importVisible = false
}
} else {
util.errorMsg(res.message || '上传失败,请检查数据', 3000)
Util.errorMsg(res.message || '上传失败,请检查数据', 3000)
}
},
uploadError (err, file, fileList) {
@ -484,7 +529,7 @@ export default {
})
.then(() => {
this.$post(this.api.batchDeleteApplicants, { registrationVOS: [row] }).then(res => {
util.successMsg("删除成功");
Util.successMsg("删除成功");
this.init()
}).catch(res => {
});
@ -548,7 +593,7 @@ export default {
this.addVisible = false
this.init()
this.submiting = false
util.successMsg('编辑成功!')
Util.successMsg('编辑成功!')
}).catch(res => {
this.submiting = false
})
@ -556,7 +601,7 @@ export default {
this.addVisible = false
this.init()
this.submiting = false
util.successMsg('编辑成功!')
Util.successMsg('编辑成功!')
}
}).catch(res => {
this.submiting = false
@ -575,7 +620,7 @@ export default {
this.addVisible = false
this.init()
this.submiting = false
util.successMsg('报名成功!')
Util.successMsg('报名成功!')
}).catch(res => {
this.submiting = false
})
@ -593,13 +638,13 @@ export default {
form.account = `${Setting.platformId}-3-${form.schoolId}-${form.workNumber}`
const { phone, email } = form
if (phone && !/^1[3456789]\d{9}$/.test(phone)) {
return util.errorMsg("请输入正确的手机号")
return Util.errorMsg("请输入正确的手机号")
} else if (email && !/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(email)) {
return util.errorMsg("请输入正确的邮箱")
return Util.errorMsg("请输入正确的邮箱")
} else if (this.notExit) {
return util.errorMsg('学生不存在,无法添加!')
return Util.errorMsg('学生不存在,无法添加!')
} else if (this.exitMember) {
return util.errorMsg('学生已存在')
return Util.errorMsg('学生已存在')
} else {
this.submiting = true
this.submitForm()
@ -676,8 +721,8 @@ export default {
//
teamSubmit () {
const form = this.teamForm
if (!form.teamName) return util.errorMsg('请输入团队名称')
if (form.invitationCode.length !== 6) return util.errorMsg('请输入6位数团队邀请码')
if (!form.teamName) return Util.errorMsg('请输入团队名称')
if (form.invitationCode.length !== 6) return Util.errorMsg('请输入6位数团队邀请码')
form.accountId = this.form.id
form.schoolId = this.form.schoolId
form.studentAffiliatedInstitutionId = this.form.studentAffiliatedInstitutionId
@ -685,7 +730,7 @@ export default {
this.teamVisible = false
this.addVisible = false
this.init()
util.successMsg('报名成功!')
Util.successMsg('报名成功!')
}).catch(res => { })
},
//
@ -705,7 +750,7 @@ export default {
responseType: 'blob'
}).then((res) => {
const name = res.headers['content-disposition']
util.downloadFileDirect(name ? decodeURI(name) : '报名人员.xlsx', new Blob([res.data]))
Util.downloadFileDirect(name ? decodeURI(name) : '报名人员.xlsx', new Blob([res.data]))
this.exporting = false
}).catch(res => {
this.exporting = false
@ -718,7 +763,7 @@ export default {
responseType: 'blob'
}).then((res) => {
const name = res.headers['content-disposition']
util.downloadFileDirect(name ? decodeURI(name) : '报名人员.xlsx', new Blob([res.data]))
Util.downloadFileDirect(name ? decodeURI(name) : '报名人员.xlsx', new Blob([res.data]))
this.exporting = false
}).catch(res => {
this.exporting = false
@ -740,7 +785,7 @@ export default {
await this.$post(`${this.api.deleteAllData}?competitionId=${this.id}`)
}
this.init()
util.successMsg('删除成功')
Util.successMsg('删除成功')
this.$refs.table.clearSelection()
}).catch(() => { });
},

Loading…
Cancel
Save