Commit 872dc7c4 authored by daniel's avatar daniel

fix(gunRule): 发枪预约联调

parent 91debcea
......@@ -111,7 +111,7 @@
</n-card>
<!-- 搜索框 -->
<div class="w-full flex flex-row items-start gap-x-3">
<div class="bg-white flex flex-col gap-y-2 p-3">
<div class="bg-white flex flex-col gap-y-2 p-3" style="min-width:200px;max-width:250px;">
<h4 class="flex flex-row items-center justify-between w-full">
分类列表
<n-button type="primary" @click="onEditCategory(null)" size="tiny">
......@@ -138,7 +138,8 @@
</div>
<div class="flex-1">
<n-data-table :columns="columns" :loading="loading" :data="feedbacks" :pagination="pagination"
:bordered="false" @update:page="handlePageChange"/>
:bordered="false"
:remote="true"/>
</div>
</div>
<n-modal :mask-closable="false" :loading="loading" style="width: 400px" :title="categoryFormValue.id?'编辑分类':'新增分类'"
......@@ -382,7 +383,9 @@
if (data.code === 200) {
feedbackCategories.value = data.content.content
showCategoryModal.value = false
getFeedBacks()
if (data.content.content.length) {
getFeedBacks()
}
} else {
message.error(data.msg)
}
......@@ -512,7 +515,25 @@
}
}
]
const pagination = ref({ pageSize: 20, page: 1 })
// 分页
const pagination = reactive({
pageSize: 20,
page: 1,
pageCount: 0,
showSizePicker: true,
itemCount: 0,
pageSizes: [20, 50, 200, 500],
prefix: (info) => "共" + info.itemCount + "条数据",
onChange: (page) => {
pagination.page = page
getFeedBacks()
},
onUpdatePageSize: (pageSize) => {
pagination.pageSize = pageSize
pagination.page = 1
getFeedBacks()
}
})
const keyword = ref('')
// 文件列表
const fileList = ref([])
......@@ -569,7 +590,7 @@
const status = ref('')
// 状态更新
const updateStatus = (value) => {
pagination.value.page = 1
pagination.page = 1
status.value = value
getFeedBacks()
}
......@@ -708,7 +729,14 @@
}
// 获取反馈分页列表
const getFeedBacks = async () => {
if (!feedbackCategories.value.length) {
pagination.itemCount = 0
pagination.page = 1
feedbacks.value = []
return;
}
loading.value = true
// 发起请求
const [err, data] = await to(fetch(F_BASE_URL + '/page', {
method: "POST",
......@@ -718,8 +746,8 @@
body: JSON.stringify({
cmptId: getCId(),
currentStatus: status.value ? undefined : status.value,
pageNum: pagination.value.page,
pageSize: pagination.value.pageSize,
pageNum: pagination.page,
pageSize: pagination.pageSize,
keyword: keyword.value,
categoryId: feedbackCategories.value[categoryIndex.value].id
})
......@@ -727,16 +755,11 @@
loading.value = false
if (data.code === 200) {
feedbacks.value = data.content.content
pagination.itemCount = res.data.total
} else {
message.error(data.msg)
}
}
// 分页切换
const handlePageChange = (page) => {
pagination.value.page = page
getFeedBacks()
}
// 日期处理
const updateFormattedValue = (val) => {
feedbackFormValue.resolvedAt = val
......@@ -762,7 +785,6 @@
fileList,
feedbacks,
pagination,
handlePageChange,
columns,
deleteFeedback,
editFeedback,
......
......@@ -132,7 +132,7 @@
<!-- 搜索框 -->
<div class="w-full flex flex-row items-start gap-x-3" >
<div class="bg-white flex flex-col gap-y-2 p-3" style="min-width:250px;max-width:300px;">
<div class="bg-white flex flex-col gap-y-2 p-3" style="min-width:200px;max-width:250px;">
<div class="flex flex-row items-center justify-between w-full gap-x-2">
<h4>组别列表</h4>
<n-button v-if="activeMenu==menuOptions[0].value" type="primary" size="small" @click="onAddGunRule" >
......@@ -144,7 +144,7 @@
</span>
</div>
</div>
<div class="flex-1 flex flex-col gap-y-2">
<div class="flex-1 flex flex-col gap-y-3">
<n-card :bordered="false">
<div class="w-full flex flex-row items-center gap-x-2">
<div style="width: 200px">
......@@ -152,13 +152,41 @@
<n-tab-pane v-for="item in menuOptions" :name="item.value" :tab="item.name"></n-tab-pane>
</n-tabs>
</div>
<div class="ml-auto" v-if="activeMenu!=menuOptions[0].value"><n-input v-model:value="keyword" placeholder="请输入搜索内容" /></div>
<n-button type="primary" v-if="activeMenu!=menuOptions[0].value">
<div class="ml-auto" v-if="activeMenu!=menuOptions[0].value">
<n-input
@clear="search(true)"
@keyup.enter="search(false)"
v-model:value="keyword"
:clearable="true"
placeholder="请输入参赛号/姓名" />
</div>
<n-button type="primary" @click="search(false)" v-if="activeMenu!=menuOptions[0].value">
搜索
</n-button>
</div>
</n-card>
<n-card v-if="gunRuleValue.details.length>0" :bordered="false">
<n-descriptions :column="gunRuleValue.details.length" label-align="center"
content-class="text-center" label-placement="top" title="预约统计(预约/总)">
<n-descriptions-item v-for="item in gunRuleValue.details" :key="item.value" :label="item.waveName">
<div class="flex mx-auto flex-row items-center w-full justify-center font-bold">
<n-gradient-text :size="24" type="success">
<n-number-animation
:active="true"
:from="0" :to="item?.totalReservations??0" />
</n-gradient-text>
<span class="text-xl mx-1">/</span>
<n-gradient-text :size="24" type="warning">
<n-number-animation
:active="true"
ref="numberAnimationInstRef" :from="0" :to="item.capacity" />
</n-gradient-text>
</div>
</n-descriptions-item>
</n-descriptions>
</n-card>
<!-- 顶部的搜索框 -->
<n-card title="组别信息" :bordered="false" v-if="activeMenu==menuOptions[0].value">
<n-form
......@@ -170,13 +198,16 @@
size="small"
>
<n-form-item label="组别名称" path="roadName">
<div class="flex flex-col w-full">
<div class="flex flex-col">
<n-input v-model:value="gunRuleValue.roadName" placeholder="请输入组别名称" />
<span class="text-red">组别名仅支持数字和字母</span>
<n-gradient-text type="warning">组别名仅支持数字和字母,并且不可重复</n-gradient-text>
</div>
</n-form-item>
<n-form-item label="出发日期" path="startTime">
<n-date-picker value-format="yyyy-MM-dd HH:mm:ss" date-format="yyyy-MM-dd HH:mm:ss" :value="gunRuleValue.startTime" type="datetime" clearable @update:formatted-value="updateFormattedValue" />
<n-date-picker value-format="yyyy-MM-dd HH:mm:ss" date-format="yyyy-MM-dd HH:mm:ss" :value="gunRuleValue.startTime"
type="datetime"
clearable
@update:formatted-value="updateFormattedValue" />
</n-form-item>
<n-form-item label="关门时间" path="cutOffTime">
<n-input-number :min="1"
......@@ -192,36 +223,51 @@
<template #header-extra>
<n-button type='primary' :loading="loading" @click="addWave">新增</n-button>
</template>
<n-data-table size="small" :columns="waveColumns" :loading="loading" :data="gunRuleValue.details" :pagination="false"
:bordered="false"/>
<n-data-table
size="small"
:columns="waveColumns"
:loading="loading"
:data="gunRuleValue.details"
:pagination="false"
:bordered="true"/>
</n-card>
<n-card title="人员列表" :bordered="false" v-if="activeMenu!=menuOptions[0].value">
<n-card title="'选手列表" :bordered="false" v-if="activeMenu!=menuOptions[0].value">
<template #header-extra>
<n-space>
<!-- <n-button type="error">
清空名单
</n-button> -->
<n-button type="primary" @click="downloadImportList">
下载导入名单模板
<n-button @click="exportEnroll">
导出名单
</n-button>
<n-button @click="randomAssign">
随机分配
</n-button>
<n-button @click="downloadImportList">
下载导入模板
</n-button>
<n-upload
v-if="gunRuleValue?.id"
@change="onFileUpload"
v-model:file-list="fileList"
>
<n-button>上传文件</n-button>
<n-button type="primary">
上传文件
</n-button>
</n-upload>
</n-space>
</template>
<n-data-table :columns="columns" :loading="loading" :data="players" :pagination="pagination"
:bordered="false" @update:page="handlePageChange" @update:page-size="onUpdatePageSize" />
:bordered="false" :remote="true" />
</n-card>
<div class="flex flex-row items-center gap-x-2 w-full" v-if="activeMenu==menuOptions[0].value">
<div class="flex-1">
<n-button :loading="loading" :block="true" @click="submit" type="primary">保存规则</n-button>
<n-button :disabled="loading" :loading="loading" :block="true" @click="submit" type="primary">
{{gunRuleValue.id?'更新规则':'新增规则'}}
</n-button>
</div>
<div class="flex-1" v-if="gunRuleValue.id">
<n-button :loading="loading" :block="true" @click="showDeleteModal=true" type="error">删除规则</n-button>
<n-button :disabled="loading" :loading="loading" :block="true" @click="showDeleteModal=true" type="error">删除规则</n-button>
</div>
</div>
</div>
......@@ -250,11 +296,8 @@
<n-form-item label="姓名" path="name">
<n-input v-model:value="playerFormValue.name" placeholder="请输入姓名" />
</n-form-item>
<n-form-item label="参赛号" path="markNo">
<n-input v-model:value="playerFormValue.markNo" placeholder="请输入参赛号" />
</n-form-item>
<n-form-item label="枪次" path="gunNo">
<n-select :options="gunRuleValue.waves.map(v=>({label:v.name,value:v.name}))" v-model:value="playerFormValue.gunNo"></n-select>
<n-form-item label="枪次" path="waveNumber">
<n-select :options="gunRuleValue.details.map(v=>({label:v.waveName,value:v.waveNumber}))" v-model:value="playerFormValue.waveNumber"></n-select>
</n-form-item>
</n-form>
<template #footer>
......@@ -411,7 +454,10 @@
const downloadWeChatImgUrl = window.location.origin + '/api-common/v1/download-wechat-image'
// 添加全局 loading 指令
const ECC_BASE_URL = "https://ecc.geexek.com"
// const ECC_BASE_URL = "http://localhost:8081"
const SAVE_OR_UPDATE = ECC_BASE_URL + "/api-pick/v1/save-or-update-wave"
// 更新名单
const UPDATE_ENROLL_WAVE = ECC_BASE_URL + "/api-pick/v1/update-enroll-wave"
const RULE_LIST = ECC_BASE_URL + "/api-pick/v1/wave-reserve-list?"
const ENROLL_PAGE = ECC_BASE_URL + "/api-pick/v1/enroll-page?"
const DELETE_RULE = ECC_BASE_URL + "/api-pick/v1/delete-rule?"
......@@ -449,8 +495,8 @@
// 编辑选手的信息
const playerFormValue = ref({
name: '',
mobile: '',
gunNo: '',
markNo: '',
waveNumber: null,
roadName: '',
})
// 规则
......@@ -459,11 +505,7 @@
required: true,
message: '请输入姓名',
},
markNo: {
required: true,
message: '请输入参赛号',
},
gunNo: {
waveNumber: {
required: true,
message: '请输入枪次',
},
......@@ -475,17 +517,36 @@
// 保存选手
const onPlayerSubmit = async (e) => {
e.preventDefault()
gunRuleRef.value?.validate(async (errors) => {
playerFormRef.value?.validate(async (errors) => {
if (errors) return message.error('请检查表单是否填写完整')
loading.value = true
const messageReactive = message.loading('选手信息更新中', {
duration: 0
})
const [err, data] = await to(fetch(UPDATE_ENROLL_WAVE, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
cmptId: playerFormValue.value.cmptId,
identityNo: playerFormValue.value.identityNo,
markNo: playerFormValue.value.markNo,
wave: playerFormValue.value.waveNumber,
roadName: playerFormValue.value.roadName,
}),
}).then(res => res.json()))
loading.value = false
messageReactive.destroy()
if (err) {
message.error(err.message)
return
}
getPlayers()
// 保存
onPlayerModalCancel()
})
// const [err,data]=await to(validate(playerFormValue.value,playerRules))
// if(err){
// message.error(err.message)
// return
// }
// showPlayerModal.value=false
}
/***---------------- 人员弹框 end -----------------*/
......@@ -493,8 +554,23 @@
const keyword = ref('')
const fileList = ref([])
// 分页
const pagination = ref({
pageSize: 10, page: 1, itemCount: 0, showQuickJumper: true, showSizePicker: true, pageSizes: [10, 50, 200, 500],
const pagination = reactive({
pageSize: 20,
page: 1,
pageCount: 0,
showSizePicker: true,
itemCount: 0,
pageSizes: [20, 50, 200, 500],
prefix: (info) => "共" + info.itemCount + "选手",
onChange: (page) => {
pagination.page = page
getPlayers()
},
onUpdatePageSize: (pageSize) => {
pagination.pageSize = pageSize
pagination.page = 1
getPlayers()
}
})
// seg
const menuOptions = [
......@@ -502,9 +578,7 @@
{ name: '选手列表', value: 'players' },
]
// 人员列表
const players = ref([
])
const players = ref([])
const columns = [
{
title: '姓名',
......@@ -544,7 +618,7 @@
size: 'small',
onClick: () => {
// 编辑
playerFormValue.value = row
playerFormValue.value = { ...row, waveNumber: row.waveNumber ? row.waveNumber.toString() : null }
showPlayerModal.value = true
}
}, '编辑'),
......@@ -559,17 +633,13 @@
activeMenu.value = value
}
// 分页切换
const handlePageChange = (page) => {
pagination.value.page = page
// 搜索
const search = async (clear = false) => {
if (clear) keyword.value = ''
pagination.page = 1
getPlayers()
}
// 分页大小切换
const onUpdatePageSize = (pageSize) => {
pagination.value.pageSize = pageSize
getPlayers()
}
// 获取分枪组别列表
const getPlayers = async () => {
if (!gunRuleValue.value.roadName) {
......@@ -580,8 +650,9 @@
const params = {
cmptId: getCId(),
roadName: gunRuleValue.value.roadName,
current: pagination.value.page,
size: pagination.value.pageSize,
current: pagination.page,
size: pagination.pageSize,
keyword: keyword.value ? keyword.value.trim() : undefined,
}
loading.value = true;
......@@ -599,7 +670,8 @@
}
if (res.code === 200) {
players.value = res.data.records
pagination.value.itemCount = res.data.total
pagination.pageCount = res.data.pages
pagination.itemCount = res.data.total
} else {
message.error(res.msg)
}
......@@ -635,17 +707,30 @@
// 在新窗口打卡
window.open(DOWNLOAD_IMPORT_LIST)
}
// 随机分配
const randomAssign = async () => {
// 调用浏览器自带的confirm弹框
const confirm = window.confirm('确定随机分配吗?')
if (!confirm) {
return
}
}
// 导出名单
const exportEnroll = async () => {
// 调用浏览器自带的confirm弹框
}
/***---------------- 人员列表 end -----------------*/
/***---------------- 发枪规则 start -----------------*/
const gunRuleRef = ref(null)
const gunRules = ref([])
// 规则初始化
const initialValue = {
startTime: undefined, // 组别开始时间
startTime: null, // 组别开始时间
roadName: "", // 组别名
details: [], // 枪次
id: undefined,
cutOffTime: undefined // 关门时间
cutOffTime: 10 // 关门时间
}
// 选号规则
const gunRuleValue = ref(initialValue)
......@@ -697,16 +782,7 @@
message.error(err.message)
}
if (res.code === 200) {
gunRules.value = res.data.map(v => ({
...v,
startTime: v.startTime.slice(0, -2),
details: v.details.map(d => ({
...d,
// 移除最后的两位 .0 我需要移除的是最后两位
waveStart: d.waveStart.slice(0, -2),
waveEnd: d.waveStart.slice(0, -2),
}))
}))
gunRules.value = res.data
if (res.data.length) {
changeGunRule(ruleIndex.value === -1 ? 0 : ruleIndex.value)
} else {
......@@ -721,15 +797,27 @@
// 提交
const submit = (e) => {
e.preventDefault()
if (!gunRuleValue.value.details.length) {
message.error('请先配置枪次')
return
}
gunRuleRef.value?.validate(async (errors) => {
if (errors) return message.error('请检查表单是否填写完整')
const roadName = gunRuleValue.value.roadName
const isUpdate = !!gunRuleValue.value.id
// 排查是否存在相同组别名的
const isExit = gunRules.value.find(item => isUpdate ? (item.roadName === roadName && item.id !== gunRuleValue.value.id) : item.roadName === roadName)
if (isExit) {
message.error('组别名称不能重复')
return
}
// 使用fetch发起请求
const params = {
...gunRuleValue.value,
gtCmptId: getCId(),
}
loading.value = true
const messageReactive = message.loading(gunRuleValue.value.id ? '规则更新中...' : '规则添加中...', {
const messageReactive = message.loading(isUpdate ? '规则更新中...' : '规则添加中...', {
duration: 0
})
// 发起请求
......@@ -756,7 +844,10 @@
}
// 新增规则
const onAddGunRule = () => {
gunRuleValue.value = initialValue
gunRuleValue.value = {
...initialValue,
}
// 强制更新视图
ruleIndex.value = -1
}
// 删除规则
......@@ -766,13 +857,12 @@
duration: 0
})
// 发起请求
const [err, data] = await to(fetch(DELETE_RULE + 'ruleId=' + gunRuleValue.value.id, {
const [err, data] = await to(fetch(DELETE_WAVE_RULE + 'reserveId=' + gunRuleValue.value.id, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
}).then(res => res.json()))
loading.value = false
messageReactive.destroy()
if (data.code === 200) {
message.success('操作成功')
......@@ -780,6 +870,7 @@
} else {
message.error(data.message)
}
loading.value = false
}
/***---------------- 号码簿规则 end-----------------*/
......@@ -805,7 +896,7 @@
align: 'center',
render(row, index) {
return h(NDatePicker, {
defaultValue: row.waveStart,
value: row.waveStart,
'value-format': "yyyy-MM-dd HH:mm:ss",
'date-format': "yyyy-MM-dd HH:mm:ss",
type: "datetime",
......@@ -822,7 +913,7 @@
align: 'center',
render(row, index) {
return h(NDatePicker, {
defaultValue: row.waveEnd,
value: row.waveEnd,
'value-format': "yyyy-MM-dd HH:mm:ss",
'date-format': "yyyy-MM-dd HH:mm:ss",
type: "datetime",
......@@ -858,30 +949,7 @@
type: 'error',
size: 'small',
onClick: async () => {
if (row.reserveId) {
// 删除规则
loading.value = true
const messageReactive = message.loading('删除中...', {
duration: 0
})
// 发起请求
const [err, data] = await to(fetch(DELETE_WAVE_RULE + 'reserveId=' + row.reserveId, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
}).then(res => res.json()))
loading.value = false
messageReactive.destroy()
if (data.code === 200) {
message.success('操作成功')
gunRuleValue.value.details.splice(index, 1)
} else {
message.error(data.message)
}
} else {
gunRuleValue.value.details.splice(index, 1)
}
gunRuleValue.value.details.splice(index, 1)
}
}, '删除')
}
......@@ -917,13 +985,14 @@
// 人员列表
keyword,
pagination,
handlePageChange,
columns,
players,
onUpdatePageSize,
randomAssign,
exportEnroll,
// 枪次表相关
waveColumns,
addWave,
search,
// 发枪规则
gunRules,
ruleIndex,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment