feat: 7月迭代
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m21s

This commit is contained in:
luo
2026-07-28 14:00:22 +08:00
parent f0a2b84e53
commit 2706c52a47
63 changed files with 4113 additions and 3945 deletions

View File

@@ -10,7 +10,11 @@
</div>
<div class="card-header-right">
<ElButton
v-if="cardInfo?.asset_type === 'card' && hasAuth(JULY_PERMISSIONS.speedTier.view)"
v-if="
cardInfo?.asset_type === 'card' &&
hasAuth(JULY_PERMISSIONS.speedTier.view) &&
hasAuth(JULY_PERMISSIONS.speedTier.update)
"
type="primary"
link
@click="emit('showSpeedLimit')"

View File

@@ -270,6 +270,7 @@
v-model="createRefundDialogVisible"
:initial-order-id="currentRefundOrderId"
:initial-order-no="currentRefundOrderNo"
:initial-package-usage-id="currentRefundPackageUsageId"
@success="handleRefundSuccess"
/>
@@ -279,12 +280,7 @@
width="30%"
@closed="resetUsedDataForm"
>
<ElForm
ref="usedDataFormRef"
:model="usedDataForm"
:rules="usedDataRules"
label-width="90px"
>
<ElForm ref="usedDataFormRef" :model="usedDataForm" :rules="usedDataRules" label-width="90px">
<ElFormItem label="套餐名称">
<span>{{ selectedPackage?.package_name || '-' }}</span>
</ElFormItem>
@@ -416,6 +412,7 @@
const createRefundDialogVisible = ref(false)
const currentRefundOrderId = ref<number | undefined>(undefined)
const currentRefundOrderNo = ref<string | undefined>(undefined)
const currentRefundPackageUsageId = ref<number | undefined>(undefined)
const selectedPackage = ref<PackageInfo>()
const usedDataDialogVisible = ref(false)
const expiresAtDialogVisible = ref(false)
@@ -474,10 +471,12 @@
}
currentRefundOrderId.value = row.order_id
currentRefundOrderNo.value = row.order_no
currentRefundPackageUsageId.value = row.package_usage_id ?? row.id
createRefundDialogVisible.value = true
}
const handleRefundSuccess = () => {
currentRefundPackageUsageId.value = undefined
emit('refresh')
}

View File

@@ -1,39 +1,66 @@
<template>
<ElDialog v-model="visible" title="设置限速" width="500px">
<ElDialog
v-model="visible"
title="设置限速"
width="500px"
:lock-scroll="true"
:z-index="4000"
modal-class="speed-limit-modal"
>
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
<ElFormItem label="固定档位" prop="code">
<ElSelect v-model="form.code" style="width: 100%">
<ElOption v-for="tier in speedTiers" :key="tier.code" :label="tier.label" :value="tier.code" />
<ElSelect
v-model="form.code"
style="width: 100%"
:teleported="true"
append-to="body"
popper-class="speed-limit-select-popper"
:popper-style="{ zIndex: 4001 }"
>
<ElOption
v-for="tier in speedTiers"
:key="tier.code"
:label="tier.label"
:value="tier.code"
/>
</ElSelect>
</ElFormItem>
</ElForm>
<template #footer>
<ElButton @click="handleCancel">取消</ElButton>
<ElButton type="primary" @click="handleConfirm" :loading="loading"> 确认设置 </ElButton>
<ElButton
type="primary"
@click="handleConfirm"
:loading="confirmLoading"
:disabled="confirmLoading"
>
确认设置
</ElButton>
</template>
</ElDialog>
</template>
<script setup lang="ts">
import { ref, reactive, computed, watch } from 'vue'
import { ref, reactive, computed, onUnmounted, watch } from 'vue'
import { ElDialog, ElForm, ElFormItem, ElSelect, ElOption, ElButton } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
interface Props {
modelValue: boolean
confirmLoading?: boolean
}
interface Emits {
(e: 'update:modelValue', value: boolean): void
(e: 'confirm', data: { code: -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 }): void
(e: 'confirm', data: { code: -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 }): void
}
const props = defineProps<Props>()
const props = withDefaults(defineProps<Props>(), {
confirmLoading: false
})
const emit = defineEmits<Emits>()
const formRef = ref<FormInstance>()
const loading = ref(false)
const speedTiers = [
{ code: -1, label: '不限速' },
{ code: 0, label: '0kbps' },
@@ -59,10 +86,25 @@
})
// 监听对话框打开,重置表单
watch(visible, (newVal) => {
if (newVal) {
form.code = 3
}
const setLayoutScrollLock = (locked: boolean) => {
document
.querySelector<HTMLElement>('.layouts')
?.classList.toggle('speed-limit-scroll-locked', locked)
}
watch(
visible,
(newVal) => {
setLayoutScrollLock(newVal)
if (newVal) {
form.code = 3
}
},
{ immediate: true }
)
onUnmounted(() => {
setLayoutScrollLock(false)
})
const handleCancel = () => {
@@ -70,6 +112,7 @@
}
const handleConfirm = async () => {
if (props.confirmLoading) return
if (!formRef.value) return
try {
@@ -83,4 +126,28 @@
}
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.speed-limit-modal .el-dialog__body {
overflow: visible;
}
.speed-limit-select-popper {
z-index: 4001 !important;
overscroll-behavior: contain;
}
.speed-limit-select-popper .el-select-dropdown__wrap,
.speed-limit-select-popper .el-scrollbar__wrap {
max-height: none !important;
overflow-y: visible !important;
}
.speed-limit-modal {
overflow: hidden;
overscroll-behavior: contain;
}
.layouts.speed-limit-scroll-locked {
overflow: hidden !important;
}
</style>