feat:添加赛果赔率

This commit is contained in:
lz-ui 2025-09-30 15:30:18 +08:00
parent 7789db2f7d
commit 19078a32ce
8 changed files with 604 additions and 7 deletions

View File

@ -44,4 +44,14 @@ export function bbInfoSelectDistinctLeagueAbbNames(data) {
method: 'post', method: 'post',
data: data data: data
}) })
} }
/** 报告更新 */
export function reportUpdate(data) {
return request({
url: '/tc/report/update',
method: 'post',
data: data
})
}

8
src/enums/tc.js Normal file
View File

@ -0,0 +1,8 @@
export const MatchResults = {
HAD: '胜平负',
HHAD: '让球胜平负',
CRS: '比分',
TTG: '总进球',
HAFU: '半全场胜平负',
}

View File

@ -1,3 +1,5 @@
import { MatchResults } from '@/enums/tc'
export function jumpLink(mid, matchType) { export function jumpLink(mid, matchType) {
/** matchType 1足球 2篮球 */ /** matchType 1足球 2篮球 */
const url = matchType === 1 ? const url = matchType === 1 ?
@ -5,3 +7,28 @@ export function jumpLink(mid, matchType) {
`https://www.sporttery.cn/jc/lqdz/index.html?showType=3&mid=${mid}` `https://www.sporttery.cn/jc/lqdz/index.html?showType=3&mid=${mid}`
window.open(url) window.open(url)
} }
export function processMatchResults(data) {
// 获取MatchResults的key值并按字母顺序排序
const sortedKeys = Object.keys(MatchResults)
// 创建一个新数组,用于存储处理后的结果
const result = [];
// 遍历排序后的key值
for (const key of sortedKeys) {
// 在原始数据中查找匹配的code
const item = data.find(item => item.code === key);
// 如果找到匹配的item则添加codeName属性并添加到结果数组中
if (item) {
result.push({
...item,
codeName: MatchResults[key]
});
}
}
return result;
}

View File

@ -0,0 +1,212 @@
<template>
<div class="app-container">
<!-- 搜索区域 -->
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" :inline="true" label-width="80px">
<el-form-item label="赛事编号" prop="matchNumStr">
<el-input v-model="queryParams.matchNumStr" placeholder="请输入赛事编号" clearable style="width: 240px"
@keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="联赛类型" prop="leagueAbbName">
<el-select v-model="queryParams.leagueAbbName" @change="handleQuery" style="width: 240px" clearable placeholder="请选择联赛类型">
<el-option
v-for="item in dataScopeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="时间">
<el-date-picker v-model="dateRange" value-format="YYYY-MM-DD" type="daterange" range-separator="-"
start-placeholder="开始日期" end-placeholder="结束日期" style="width: 240px"></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery" :loading="loading">查询</el-button>
<el-button icon="Refresh" @click="resetQuery" :loading="loading">重置</el-button>
</el-form-item>
</el-form>
<!--loading-->
<div
v-if="loading"
v-loading="loading"
class="loading-page"
element-loading-text="正在加载..."
style="width: 100%; height: calc(100vh - 250px)"
></div>
<div v-else-if="pageList.length && !loading">
<!-- 表格数据 -->
<el-table v-loading="loading" :data="pageList">
<el-table-column label="赛事编号" prop="matchNumStr" />
<el-table-column label="联赛" prop="leagueAllName" :show-overflow-tooltip="true" />
<el-table-column label="主队" prop="homeTeamAllName" :show-overflow-tooltip="true" />
<el-table-column label="客队" prop="awayTeamAbbName" />
<el-table-column label="报告状态" prop="reportSatus">
<template #default="scope">
<el-tag v-if="scope.row.reportSatus === 1" type="success">已生成</el-tag>
<el-tag v-else>未生成</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="编辑" placement="top" v-if="scope.row.reportSatus === 1">
<el-button link type="primary" icon="Edit" @click="openDialog(scope.row)">编辑</el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<!-- 分页区域 -->
<pagination
:show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList" />
</div>
<lz-page-empty v-else-if="!loading" :type="'2'">
<lz-svg-icon icon-class="empty2" style="font-size: 312px;"/>
</lz-page-empty>
<!-- 修改对话框 -->
<el-dialog :title="dialogTitle" v-model="dialogOpen" width="600px" append-to-body>
<EditHad :data="dialogForm" type="edit" v-if="dialogOpen" @submit="submitForm" ref="editHadRef"/>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="OperationReport">
import { Info, infoSelectDistinctLeagueAbbNames, reportUpdate } from "@/api/tc/eventAnalysisReport"
import { jumpLink } from "@/utils/tc"
import { processMatchResults } from "@/utils/tc"
import EditHad from "@/views/tc/eventAnalysisReport/components/EditHad.vue"
import { ref } from "vue"
const router = useRouter()
const { proxy } = getCurrentInstance()
const pageList = ref([])
const loading = ref(false)
const showSearch = ref(true)
const total = ref(0)
const dateRange = ref([])
const editHadRef = ref(null)
const dialogOpen = ref(false)
const dialogTitle = ref('编辑')
const dialogForm = ref({})
/** 数据范围选项*/
const dataScopeOptions = ref([])
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
matchNumStr: undefined,
leagueAbbName: undefined,
},
rules: {},
})
const { queryParams } = toRefs(data)
/** 提交表单 */
function submitForm() {
const data = editHadRef.value.getFormData()
reportUpdate(data).then(response => {
proxy.$message.success(response.msg)
getList()
}).finally(() => {
dialogOpen.value = false
})
}
/** 取消按钮 */
function cancel() {
dialogOpen.value = false
dialogForm.value = {}
}
function openDialog(row) {
dialogForm.value = row
dialogOpen.value = true
}
/** 获取联赛类型 */
function getLeagueAbbNames() {
infoSelectDistinctLeagueAbbNames().then(response => {
dataScopeOptions.value = response.rows ? response.rows.map(item => ({ value: item, label: item })) : []
})
}
/** 跳转链接 */
function handleJumpLink(row) {
jumpLink(row.matchId, 1)
}
/** 查看详情 */
function handleView(row) {
if (row.reportSatus != 1) {
return
}
// window.open(window.location.origin + '/#/tc/eventAnalysisReport/detail?id=' + row.matchId)
router.push({
path: '/tc/eventAnalysisReport/detail',
query: {
id: row.matchId
}
})
}
/** 查询列表 */
function getList() {
loading.value = true
const data = { ...queryParams.value }
if (dateRange.value && dateRange.value[0] && dateRange.value[1]) {
data.beginTime = dateRange.value[0]
data.endTime = dateRange.value[1]
} else {
data.beginTime = undefined
data.endTime = undefined
}
Info(data).then(response => {
const res = response.rows.map(item => ({
...item,
matchResults: item.matchResults ? processMatchResults(item.matchResults): null
}));
pageList.value = res
total.value = response.total
}).finally(() => {
loading.value = false
})
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
function resetQuery() {
dateRange.value = []
proxy.resetForm("queryRef")
handleQuery()
}
onMounted(() => {
//
getLeagueAbbNames()
//
getList()
})
</script>

View File

@ -0,0 +1,161 @@
<template>
<div class="had">
<div class="had-content flex" v-for="(item,index) in data.matchSpfDetails" :key="item.id" :data-goalType="item.goalType">
<!-- <span>{{ item.goalLine || 0 }}</span> -->
<span class="had-content-item-left flex-center">
<el-badge :value="item.goalLine||0" :color="index === 0 ?'#666' : '#f56c6c'" />
</span>
<div class="had-content-table flex">
<div :class="['had-content-table-item', {'is-active': item.isActive === 'h'}]" data-id="h" @click="handleClick(item, 'h')">
<span></span>
<span>{{ item.win || 0 }}</span>
</div>
<div :class="['had-content-table-item', {'is-active': item.isActive === 'a'}]" data-id="a" @click="handleClick(item, 'a')">
<span></span>
<span>{{ item.draw || 0 }}</span>
</div>
<div :class="['had-content-table-item', {'is-active': item.isActive === 'd'}]" data-id="d" @click="handleClick(item, 'd')">
<span></span>
<span>{{ item.debt || 0 }}</span>
</div>
</div>
</div>
<!--编辑模式-->
<div class="had-content flex had-content-edit">
<span class="had-content-item-left flex-center"></span>
<div class="had-content-table flex">
<div :class="['had-content-table-item', {'is-active': ttgFlag === 'aover'}]" style="width: 50%; text-align: center;" @click="handleTtgClick('aover')">
<span>大球</span>
</div>
<div :class="['had-content-table-item', {'is-active': ttgFlag === 'under'}]" style="width: 50%; text-align: center;"@click="handleTtgClick('under')">
<span>小球</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue';
//
const props = defineProps({
data: {
type: Object,
default: () => ({})
},
type: {
type: String,
default: 'view' // edit view
}
});
//
const { data } = toRefs(props);
const ttgFlag = ref('');
function handleClick(item, type) {
if(props.type === 'edit'){
item.isActive = item.isActive === type ? '' : type;
}
}
function handleTtgClick(type) {
if(props.type === 'edit'){
ttgFlag.value = ttgFlag.value === type ? '' : type;
}
}
function getFormData() {
const res = {
matchId: data.value.matchId,
ttgFlag: ttgFlag.value
}
data.value.matchSpfDetails.forEach(el => {
if(el.goalType === 'HAD') {
res.hadFlag = el.isActive || '';
}
if(el.goalType === 'HHAD') {
res.hhadFlag = el.isActive || '';
}
});
return res;
}
onMounted(() => {
if(data.value.reportDetail && data.value.matchSpfDetails){
const reportDetail = data.value.reportDetail;
console.log(reportDetail.hadFlag, reportDetail.hhadFlag, reportDetail.ttgFlag);
ttgFlag.value = reportDetail.ttgFlag;
data.value.matchSpfDetails.forEach(el => {
if(el.goalType === 'HAD') {
el.isActive = reportDetail.hadFlag || '';
}
if(el.goalType === 'HHAD') {
el.isActive = reportDetail.hhadFlag || '';
}
});
}
})
defineExpose({
getFormData
});
</script>
<style lang="scss" scoped>
.had {
.had-content:nth-child(2) {
.had-content-table{
.had-content-table-item{
border-top: none
}
}
}
}
.had-content-item-left{
width: 60px;
text-align: center;
}
.had-content-table{
display: flex;
justify-content: space-between;
width: 100%;
}
.had-content-table-item {
padding: 12px;
border: 1px solid #ccc;
width: 33.33%;
cursor: pointer;
display: flex;
justify-content: space-between;
background-color: #f2f2f2;
}
.had-content-table .had-content-table-item:nth-child(2) {
border-left: none;
border-right: none;
}
.is-active {
background-color: #f56c6c;
color: #fff;
}
/** 编辑模式 */
.had-content-edit {
.had-content-table-item {
border-top: none;
}
.had-content-table-item:nth-child(2) {
border-right: 1px solid #ccc;
}
}
</style>

View File

@ -45,6 +45,32 @@
<el-table-column label="固定奖金" prop="matchId" > <el-table-column label="固定奖金" prop="matchId" >
<template #default="scope"> <template #default="scope">
<el-button link type="primary" @click="handleJumpLink(scope.row)">查看</el-button> <el-button link type="primary" @click="handleJumpLink(scope.row)">查看</el-button>
<!-- <el-popover placement="bottom" :width="360">
<template #reference>
<el-button link type="primary" @dblclick="handleJumpLink(scope.row)">查看</el-button>
</template>
<template #default>
<div>
<el-table border :data="scope.row.matchResults">
<el-table-column label="游戏" prop="matchNumStr">
<template #default="item">
{{ item.row.code }}
</template>
</el-table-column>
<el-table-column label="开赛结果" prop="reportSatus">
<template #default="item">
<el-tag type="error">{{ item.row.combinationDesc }}</el-tag>
</template>
</el-table-column>
<el-table-column label="奖金" prop="matchNumStr">
<template #default="item">
{{ item.row.odds }}
</template>
</el-table-column>
</el-table>
</div>
</template>
</el-popover> -->
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="比赛开始时间" align="center" prop="matchDateTime"> <el-table-column label="比赛开始时间" align="center" prop="matchDateTime">
@ -177,4 +203,9 @@ onMounted(() => {
getList() getList()
}) })
onActivated(() => {
getList()
})
</script> </script>

View File

@ -0,0 +1,98 @@
<template>
<div class="had">
<div class="had-content flex" v-for="(item,index) in data.matchSpfDetails" :key="item.id">
<!-- <span>{{ item.goalLine || 0 }}</span> -->
<span class="had-content-item-left flex-center">
<el-badge :value="item.goalLine||0" :color="index === 0 ?'#666' : '#f56c6c'" />
</span>
<div class="had-content-table flex">
<div :class="['had-content-table-item', {'is-active': item.isActive === 'h'}]">
<span></span>
<span>{{ item.win || 0 }}</span>
</div>
<div :class="['had-content-table-item', {'is-active': item.isActive === 'a'}]">
<span></span>
<span>{{ item.draw || 0 }}</span>
</div>
<div :class="['had-content-table-item', {'is-active': item.isActive === 'd'}]">
<span></span>
<span>{{ item.debt || 0 }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue';
//
const props = defineProps({
data: {
type: Object,
default: () => ({})
},
});
//
const { data } = toRefs(props);
onMounted(() => {
if(data.value.reportDetail && data.value.matchSpfDetails){
const reportDetail = data.value.reportDetail;
data.value.matchSpfDetails.forEach(el => {
if(el.goalType === 'HAD') {
el.isActive = reportDetail.hadFlag || '';
}
if(el.goalType === 'HHAD') {
el.isActive = reportDetail.hhadFlag || '';
}
});
}
})
</script>
<style lang="scss" scoped>
.had {
.had-content:nth-child(2) {
.had-content-table{
.had-content-table-item{
border-top: none
}
}
}
}
.had-content-item-left{
width: 60px;
text-align: center;
}
.had-content-table{
display: flex;
justify-content: space-between;
width: 100%;
}
.had-content-table-item {
padding: 12px;
border: 1px solid #ccc;
width: 33.33%;
cursor: pointer;
display: flex;
justify-content: space-between;
background-color: #f2f2f2;
}
.had-content-table .had-content-table-item:nth-child(2) {
border-left: none;
border-right: none;
}
.is-active {
background-color: #f56c6c;
color: #fff;
}
</style>

View File

@ -34,16 +34,54 @@
element-loading-text="正在加载..." element-loading-text="正在加载..."
style="width: 100%; height: calc(100vh - 250px)" style="width: 100%; height: calc(100vh - 250px)"
></div> ></div>
<div v-else-if="roleList.length && !loading"> <div v-else-if="pageList.length && !loading">
<!-- 表格数据 --> <!-- 表格数据 -->
<el-table v-loading="loading" :data="roleList"> <el-table v-loading="loading" :data="pageList">
<el-table-column label="赛事编号" prop="matchNumStr" /> <el-table-column label="赛事编号" prop="matchNumStr" />
<el-table-column label="联赛" prop="leagueAllName" :show-overflow-tooltip="true" /> <el-table-column label="联赛" prop="leagueAllName" :show-overflow-tooltip="true" />
<el-table-column label="主队" prop="homeTeamAllName" :show-overflow-tooltip="true" /> <el-table-column label="主队" prop="homeTeamAllName" :show-overflow-tooltip="true" />
<el-table-column label="客队" prop="awayTeamAbbName" /> <el-table-column label="客队" prop="awayTeamAbbName" />
<el-table-column label="固定奖金" prop="matchId"> <el-table-column label="固定奖金" prop="matchId">
<template #default="scope"> <template #default="scope">
<el-button link type="primary" @click="handleJumpLink(scope.row)">查看</el-button> <!-- <el-button link type="primary" @click="handleJumpLink(scope.row)">查看</el-button> -->
<el-popover placement="bottom" :width="360">
<template #reference>
<el-button link type="primary" @dblclick="handleJumpLink(scope.row)">查看</el-button>
</template>
<template #default>
<div>
<el-table border :data="scope.row.matchResults">
<el-table-column label="游戏" prop="matchNumStr">
<template #default="item">
{{ item.row.codeName }}
</template>
</el-table-column>
<el-table-column label="开赛结果" prop="reportSatus">
<template #default="item">
<el-tag type="error">{{ item.row.combinationDesc }}</el-tag>
</template>
</el-table-column>
<el-table-column label="奖金" prop="matchNumStr">
<template #default="item">
{{ item.row.odds }}
</template>
</el-table-column>
</el-table>
</div>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column label="赛果赔率" prop="matchId">
<template #default="scope">
<el-popover placement="bottom" :width="360">
<template #reference>
<el-button link type="primary">查看</el-button>
</template>
<template #default>
<EditHad :data="scope.row" />
</template>
</el-popover>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="比赛开始时间" align="center" prop="matchDateTime"> <el-table-column label="比赛开始时间" align="center" prop="matchDateTime">
@ -84,14 +122,17 @@
</div> </div>
</template> </template>
<script setup name="Role"> <script setup>
import { Info, infoSelectDistinctLeagueAbbNames } from "@/api/tc/eventAnalysisReport" import { Info, infoSelectDistinctLeagueAbbNames } from "@/api/tc/eventAnalysisReport"
import { jumpLink } from "@/utils/tc" import { jumpLink } from "@/utils/tc"
import { timerToStr } from "@/utils/timer" import { timerToStr } from "@/utils/timer"
import { processMatchResults } from "@/utils/tc"
import EditHad from "@/views/tc/eventAnalysisReport/components/EditHad.vue"
import { onActivated } from "vue"
const router = useRouter() const router = useRouter()
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
const roleList = ref([]) const pageList = ref([])
const loading = ref(false) const loading = ref(false)
const showSearch = ref(true) const showSearch = ref(true)
const total = ref(0) const total = ref(0)
@ -151,7 +192,11 @@ function getList() {
data.endTime = undefined data.endTime = undefined
} }
Info(data).then(response => { Info(data).then(response => {
roleList.value = response.rows const res = response.rows.map(item => ({
...item,
matchResults: item.matchResults ? processMatchResults(item.matchResults): null
}));
pageList.value = res
total.value = response.total total.value = response.total
}).finally(() => { }).finally(() => {
loading.value = false loading.value = false
@ -177,4 +222,9 @@ onMounted(() => {
// //
getList() getList()
}) })
onActivated(() => {
getList()
})
</script> </script>