feat(coupon, directService): 新增优惠券编辑功能,优化车辆选择组件及相关API
完善优惠券管理全流程,添加编辑按钮与编辑页面逻辑,支持提交优惠券ID完成编辑操作。新增定向服务车辆分页查询接口,重构车辆选择弹窗组件以支持自定义列表查询接口并复用至定向服务页面。同时优化优惠券编辑页的提示文案与交互判断逻辑。
| | |
| | | return request.Post<Service.ResponseResult<any>>('/operation/v1/api/xp-coupon/add', data) |
| | | } |
| | | |
| | | export function editCoupon(data: { |
| | | id: number | string |
| | | amount?: number // 金额 |
| | | conditionalAmount?: number // 条件金额 |
| | | couponDescription: string // 描述 |
| | | couponName: string // 优惠券名称 |
| | | couponType: number // 类型 1=抵扣 2=满减 3=抹零 |
| | | }) { |
| | | return request.Post<Service.ResponseResult<any>>('/v1/api/xp-coupon/editCoupon', data) |
| | | } |
| | | |
| | | /** |
| | | * 发放优惠券 |
| | | * @param data - 发放参数 |
| | |
| | | return request.Post<Service.ResponseResult<any>>(`/operation/api/v1/targetedService/deleteByIds`, { ids }) |
| | | } |
| | | |
| | | /** 定向服务选择车辆分页 */ |
| | | export function getTargetedVehiclePageList(params: any) { |
| | | return request.Post<Service.ResponseResult<any>>('/api/v1/vehicle/getTargetedVehiclePageList', params) |
| | | } |
| | | |
| | | /** 启用/禁用定向服务 */ |
| | | export function toggleDirectServiceStatus(id: any, status: any) { |
| | | return request.Post<Service.ResponseResult<any>>(`/operation/api/v1/targetedService/updateStatus?id=${id}&status=${status}`) |
| | |
| | | |
| | | interface Props { |
| | | existingVehicles?: VehicleItem[] |
| | | requestList?: (params: { |
| | | vehicleCode?: string |
| | | plateNumber?: string |
| | | fleetName?: string |
| | | pageNum: number |
| | | pageSize: number |
| | | }) => Promise<any> |
| | | } |
| | | |
| | | const props = withDefaults(defineProps<Props>(), { |
| | | existingVehicles: () => [], |
| | | requestList: undefined, |
| | | }) |
| | | |
| | | const emit = defineEmits<{ |
| | |
| | | async function getVehicleList() { |
| | | startLoading() |
| | | try { |
| | | const res = await fetchVehiclePageList({ |
| | | const requestList = props.requestList || fetchVehiclePageList |
| | | const res = await requestList({ |
| | | vehicleCode: searchModel.value.vehicleCode, |
| | | fleetName: searchModel.value.fleetName, |
| | | plateNumber: searchModel.value.plateNumber, |
| | | pageNum: currentPage.value, |
| | |
| | | import { useRoute, useRouter } from 'vue-router' |
| | | import { NButton, NCascader, NCheckbox, NDataTable, NDatePicker, NForm, NGrid, NInput, NSpace, NTag, useDialog, useMessage } from 'naive-ui' |
| | | import { getRegionCascader } from '@/service/api/operations' |
| | | import { addDirectService, editDirectService, getDirectServiceDetail } from '@/service/api/directService' |
| | | import { addDirectService, editDirectService, getDirectServiceDetail, getTargetedVehiclePageList } from '@/service/api/directService' |
| | | import { useTabStore } from '@/store' |
| | | import { useBoolean } from '@/hooks' |
| | | import VehicleSelectModal from '@/views/assetManagement/fleetManagement/components/VehicleSelectModal.vue' |
| | |
| | | |
| | | <VehicleSelectModal |
| | | v-model:visible="vehicleSelectModalVisible" :existing-vehicles="selectedVehicles" |
| | | :request-list="getTargetedVehiclePageList" |
| | | @confirm="handleVehicleSelectConfirm" |
| | | /> |
| | | |
| | |
| | | import type { FormInst, FormRules } from 'naive-ui' |
| | | import { useDialog, useMessage } from 'naive-ui' |
| | | import AiRichTextEditor from '@/components/custom/Editor/AiRichTextEditor/index.vue' |
| | | import { addCoupon, fetchCouponDetail } from '@/service/api/coupon' |
| | | import { addCoupon, editCoupon, fetchCouponDetail } from '@/service/api/coupon' |
| | | import { useTabStore } from '@/store' |
| | | |
| | | const tabStore = useTabStore() |
| | |
| | | const isSelectOpen = ref(false) |
| | | |
| | | const isReadonly = computed(() => route.query.mode === 'detail') |
| | | const isEditMode = computed(() => route.query.mode === 'edit') |
| | | const couponId = computed(() => { |
| | | const raw = route.query.id |
| | | const value = Array.isArray(raw) ? raw[0] : raw |
| | |
| | | |
| | | loading.value = true |
| | | try { |
| | | const res = await addCoupon({ |
| | | const submitParams = { |
| | | couponName: formModel.value.name, |
| | | couponType: formModel.value.type as unknown as number, |
| | | conditionalAmount: Number(formModel.value.conditionAmount || 0), |
| | |
| | | : formModel.value.amount || 0, |
| | | ), |
| | | couponDescription: encodeURIComponent(formModel.value.description || ''), |
| | | }) |
| | | } |
| | | const res = isEditMode.value && couponId.value |
| | | ? await editCoupon({ |
| | | id: couponId.value, |
| | | ...submitParams, |
| | | }) |
| | | : await addCoupon(submitParams) |
| | | |
| | | if (res.code === 200) { |
| | | message.success('保存成功') |
| | | message.success(isEditMode.value ? '编辑成功' : '保存成功') |
| | | window.sessionStorage.setItem('couponListNeedRefresh', '1') |
| | | tabStore.closeTab(route.fullPath) |
| | | router.back() |
| | |
| | | } |
| | | |
| | | dialog.warning({ |
| | | title: '确定保存该优惠券?', |
| | | title: isEditMode.value ? '确定保存优惠券修改?' : '确定保存该优惠券?', |
| | | content: '', |
| | | positiveText: '确定', |
| | | negativeText: '取消', |
| | |
| | | } |
| | | |
| | | dialog.warning({ |
| | | title: '确认取消创建吗?', |
| | | content: '当前优惠券未保存,确认取消创建吗?', |
| | | title: isEditMode.value ? '确认取消编辑吗?' : '确认取消创建吗?', |
| | | content: isEditMode.value ? '当前优惠券修改未保存,确认取消编辑吗?' : '当前优惠券未保存,确认取消创建吗?', |
| | | positiveText: '确定取消', |
| | | negativeText: '继续编辑', |
| | | maskClosable: false, |
| | |
| | | } |
| | | |
| | | async function getDetail() { |
| | | if (!isReadonly.value || !couponId.value) |
| | | if ((!isReadonly.value && !isEditMode.value) || !couponId.value) |
| | | return |
| | | |
| | | loading.value = true |
| | |
| | | }) |
| | | } |
| | | |
| | | function handleEdit(row: any) { |
| | | router.push({ |
| | | path: '/userContent/active/coupon/add', |
| | | query: { |
| | | mode: 'edit', |
| | | id: String(row.id ?? ''), |
| | | }, |
| | | }) |
| | | } |
| | | |
| | | function handleDelete(row: any) { |
| | | dialog.warning({ |
| | | title: '确认删除', |
| | |
| | | 详情 |
| | | </NButton> |
| | | {status === 1 && ( |
| | | <NButton text type="primary" onClick={() => handleEdit(row)}> |
| | | 编辑 |
| | | </NButton> |
| | | )} |
| | | {status === 1 && ( |
| | | <NButton text type="primary" v-permission="202642906" onClick={() => handlePublish(row)}> |
| | | 发布 |
| | | </NButton> |