| locales/zh_CN.json | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/router/routes.static.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/service/api/coupon.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/assetManagement/vehicleManagement/inventoryVehicle/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/userContent/active/coupon/add.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/userContent/active/coupon/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
locales/zh_CN.json
@@ -165,7 +165,7 @@ "inventoryVehicle": "在库车辆管理", "addInventoryVehicle": "新增车辆", "operatingVehicle": "运营车辆管理", "operatingVehicleDetail": "运营车辆详情", "operatingVehicleDetail": "车辆详情", "fleetManagement": "车队管理", "fleetManagementDetail": "车队详情", "ruleConfig": "运维规则配置", src/router/routes.static.ts
@@ -492,6 +492,19 @@ pid: 501, }, { name: 'inventoryVehicleDetail', path: '/assetManagement/vehicleManagement/inventoryVehicle/detail', title: '车辆详情', requiresAuth: true, icon: 'icon-park-outline:auto-focus', menuType: 'page', componentPath: '/assetManagement/vehicleManagement/operatingVehicle/detail.vue', id: 5014, pid: 501, hide: true, // 不在菜单中显示 activeMenu: '/assetManagement/vehicleManagement/inventoryVehicle', }, { name: 'operatingVehicleDetail', path: '/assetManagement/vehicleManagement/operatingVehicle/detail', title: '车辆详情', src/service/api/coupon.ts
@@ -36,3 +36,11 @@ }) { return request.Post<Service.ResponseResult<any>>('/account/api/v1/appUserCoupon/send', data) } export function fetchCouponDetail(id: number | string) { return request.Get<Service.ResponseResult<any>>('/operation/v1/api/xp-coupon/queryById', { params: { id } }) } export function deleteCouponById(id: number | string) { return request.Delete<Service.ResponseResult<any>>(`/operation/v1/api/xp-coupon/deleteById?id=${id}`) } src/views/assetManagement/vehicleManagement/inventoryVehicle/index.vue
@@ -513,7 +513,7 @@ function handleDetail(row: any) { router.push({ name: 'operatingVehicleDetail', name: 'inventoryVehicleDetail', query: { id: row.id, type: 'inventory', src/views/userContent/active/coupon/add.vue
@@ -1,13 +1,24 @@ <script setup lang="tsx"> import { ref } from 'vue' import { useRouter } from 'vue-router' import { computed, onMounted, ref } from 'vue' import { useRoute, useRouter } from 'vue-router' import { useMessage } from 'naive-ui' import RichTextEditor from '@/components/custom/Editor/RichTextEditor/index.vue' import { addCoupon } from '@/service/api/coupon' import { addCoupon, fetchCouponDetail } from '@/service/api/coupon' const route = useRoute() const router = useRouter() const message = useMessage() const loading = ref(false) const isReadonly = computed(() => route.query.mode === 'detail') const couponId = computed(() => { const raw = route.query.id const value = Array.isArray(raw) ? raw[0] : raw const num = Number(value) return Number.isFinite(num) ? num : null }) const pageTitle = computed(() => isReadonly.value ? '优惠券详情' : '添加优惠券') const formModel = ref({ name: '', @@ -23,6 +34,9 @@ ] const handleSave = async () => { if (isReadonly.value) return if (!formModel.value.name) { message.warning('请输入优惠券名称') return @@ -42,7 +56,7 @@ loading.value = true try { const { error } = await addCoupon({ const res = await addCoupon({ couponName: formModel.value.name, couponType: formModel.value.type, conditionalAmount: formModel.value.type === 1 ? 0 : (formModel.value.conditionAmount || 0), @@ -50,7 +64,7 @@ couponDescription: formModel.value.description }) if (!error) { if (res.code === 200) { message.success('保存成功') router.back() } @@ -62,13 +76,38 @@ const handleBack = () => { router.back() } const getDetail = async () => { if (!isReadonly.value || !couponId.value) return loading.value = true try { const res = await fetchCouponDetail(couponId.value) if (res.code === 200 && res.data) { formModel.value = { name: res.data.couponName || '', type: res.data.couponType ?? null, conditionAmount: res.data.conditionalAmount ?? null, amount: res.data.amount ?? null, description: res.data.couponDescription || '', } } } finally { loading.value = false } } onMounted(() => { getDetail() }) </script> <template> <div class="h-full flex flex-col bg-white rounded-lg relative"> <div class="flex items-center mb-4 pt-6 px-6"> <div class="w-1 h-4 bg-blue-500 mr-2 rounded-sm"></div> <div class="text-lg font-bold">添加优惠券</div> <div class="text-lg font-bold">{{ pageTitle }}</div> </div> <div class="flex-1 overflow-y-auto px-6 pb-20"> @@ -85,6 +124,7 @@ <n-form-item label="优惠券名称" path="name" required> <n-input v-model:value="formModel.name" :disabled="isReadonly" placeholder="最多20个字" maxlength="20" show-count @@ -96,6 +136,7 @@ <n-form-item label="优惠券类型" path="type" required> <n-select v-model:value="formModel.type" :disabled="isReadonly" :options="couponTypeOptions" placeholder="请选择优惠券类型" clearable @@ -106,6 +147,7 @@ <n-form-item v-if="formModel.type !== 1" label="条件金额" path="conditionAmount" required> <n-input-number v-model:value="formModel.conditionAmount" :disabled="isReadonly" placeholder="最多4位数字" :min="0" :max="9999" @@ -118,6 +160,7 @@ <n-form-item label="金额" path="amount" required> <n-input-number v-model:value="formModel.amount" :disabled="isReadonly" placeholder="最多4位数字" :min="0" :max="9999" @@ -129,7 +172,7 @@ <n-form-item label="优惠券说明" path="description" required class="w-full"> <div class="w-full"> <RichTextEditor v-model="formModel.description" style="height: 300px" /> <RichTextEditor v-model="formModel.description" :disabled="isReadonly" style="height: 300px" /> </div> </n-form-item> </n-space> @@ -138,7 +181,7 @@ <div class="absolute bottom-0 left-0 right-0 flex justify-end gap-3 bg-white px-6 py-4" style="box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1); z-index: 100"> <n-button @click="handleBack" style="width: 84px; height: 32px">返回</n-button> <n-button type="primary" @click="handleSave" style="width: 84px; height: 32px">保存</n-button> <n-button v-if="!isReadonly" type="primary" :loading="loading" @click="handleSave" style="width: 84px; height: 32px">保存</n-button> </div> </div> </template> src/views/userContent/active/coupon/index.vue
@@ -5,7 +5,7 @@ import type { DataTableColumns } from 'naive-ui' import SearchPanel from '@/components/custom/SearchPanel.vue' import BatchSendModal from './BatchSendModal.vue' import { fetchCouponList, sendCoupon } from '@/service/api/coupon' import { deleteCouponById, fetchCouponList, sendCoupon } from '@/service/api/coupon' const router = useRouter() const message = useMessage() @@ -44,6 +44,35 @@ const handleSend = (row: any) => { currentCouponId.value = row.id showBatchSendModal.value = true } const handleDetail = (row: any) => { router.push({ path: '/userContent/active/coupon/add', query: { mode: 'detail', id: String(row.id ?? ''), }, }) } const handleDelete = (row: any) => { dialog.warning({ title: '确认删除', content: '删除后不可恢复,确定要删除该优惠券吗?', positiveText: '确定', negativeText: '取消', onPositiveClick: async () => { const res = await deleteCouponById(row.id) if (res.code === 200) { message.success('删除成功') if (list.value.length <= 1 && currentPage.value > 1) { currentPage.value -= 1 } getList() } }, }) } const handleBatchSendAll = () => { @@ -158,12 +187,20 @@ { title: '操作', key: 'actions', width: 120, width: 220, fixed: 'right', render: (row) => ( <NButton v-permission="302313" text type="primary" onClick={() => handleSend(row)}> 批量发券 </NButton> <n-space size={12}> <NButton v-permission="302313" text type="primary" onClick={() => handleSend(row)}> 批量发券 </NButton> {/* <NButton text type="primary" onClick={() => handleDetail(row)}> 详情 </NButton> <NButton text type="error" onClick={() => handleDelete(row)}> 删除 </NButton> */} </n-space> ) } ])