完善券兑换码功能

This commit is contained in:
YeMingfei666 2025-11-21 14:33:11 +08:00
parent ef563a582b
commit 8269f619b8
8 changed files with 612 additions and 182 deletions

View File

@ -7,6 +7,7 @@
<up-icon size="18" name="close" @click="show = false"></up-icon> <up-icon size="18" name="close" @click="show = false"></up-icon>
</view> </view>
<scroll-view <scroll-view
ref="couponScroll"
:scroll-y="true" :scroll-y="true"
style="max-height: 50vh" style="max-height: 50vh"
@scroll="scroll" @scroll="scroll"
@ -21,21 +22,22 @@
> >
<view class="u-flex u-row-between"> <view class="u-flex u-row-between">
<view class="u-flex gap-20"> <view class="u-flex gap-20">
<view class="u-flex" @click.stop="preview(item)"> <!-- <view class="u-flex" @click.stop="preview(item)">
<up-image <up-image
:src="item.coverImg" :src="item.coverImg"
width="80rpx" width="80rpx"
height="80rpx" height="80rpx"
></up-image> ></up-image>
</view> </view> -->
<text class="u-font-32 color-333">{{ item.name }}</text> <text class="u-font-32 color-333">{{ item.title }}</text>
</view> </view>
<text class="u-font-32 color-red u-p-l-30" <text class="u-font-32 color-red u-p-l-30"
>¥{{ item.lowPrice }}</text ></text
> >
</view> </view>
</view> </view>
<up-empty v-if="list.length == 0" class="u-p-30" text="暂无数据"></up-empty>
</scroll-view> </scroll-view>
<view class="bottom"> <view class="bottom">
<view class="btn cancel" @click="close">{{ cancelText }}</view> <view class="btn cancel" @click="close">{{ cancelText }}</view>
@ -47,7 +49,6 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, watch } from "vue"; import { ref, onMounted, watch } from "vue";
import { getCouponList } from "@/http/api/coupon.js";
const modelValue = defineModel({ const modelValue = defineModel({
type: String, type: String,
default: "", default: "",
@ -56,7 +57,7 @@ const show = defineModel("show", {
type: String, type: String,
default: "", default: "",
}); });
const goodsName = defineModel("goodsName", { const couponName = defineModel("couponName", {
type: String, type: String,
default: "", default: "",
}); });
@ -74,6 +75,10 @@ const props = defineProps({
type: String, type: String,
default: "取消", default: "取消",
}, },
list: {
type: Array,
default: () => [],
},
}); });
const selGoods = ref(""); const selGoods = ref("");
@ -84,7 +89,6 @@ function itemClick(item) {
} }
selGoods.value = item; selGoods.value = item;
} }
const list = ref([]);
const scrollTop = ref(0); const scrollTop = ref(0);
function scroll(e) { function scroll(e) {
@ -99,22 +103,22 @@ watch(
() => modelValue.value, () => modelValue.value,
(newVal, oldVal) => { (newVal, oldVal) => {
console.log(newVal, oldVal); console.log(newVal, oldVal);
selGoods.value = list.value.find((item) => item.id == newVal); selGoods.value = props.list.find((item) => item.id == newVal);
console.log(selGoods.value); console.log(selGoods.value);
if (selGoods.value) { if (selGoods.value) {
goodsName.value = selGoods.value.name; couponName.value = selGoods.value.title;
} }
} }
); );
watch( watch(
() => list.value.length, () => props.list.length,
(newVal, oldVal) => { (newVal, oldVal) => {
selGoods.value = list.value.find((item) => item.id == modelValue.value); selGoods.value = props.list.find((item) => item.id == modelValue.value);
console.log(selGoods.value); console.log(selGoods.value);
if (selGoods.value) { if (selGoods.value) {
modelValue.value = selGoods.value.id; modelValue.value = selGoods.value.id;
goodsName.value = selGoods.value.name; couponName.value = selGoods.value.title;
} }
} }
); );
@ -122,6 +126,8 @@ watch(
function close() { function close() {
show.value = false; show.value = false;
} }
const emit = defineEmits(["confirm"]);
function confirm() { function confirm() {
if (!selGoods.value) { if (!selGoods.value) {
uni.showToast({ uni.showToast({
@ -132,12 +138,9 @@ function confirm() {
} }
modelValue.value = selGoods.value.id; modelValue.value = selGoods.value.id;
show.value = false; show.value = false;
emit("confirm", selGoods.value);
} }
onMounted(() => {
getCouponList().then((res) => {
list.value = res;
});
});
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@ -1,22 +1,92 @@
<template> <template>
<view> <view>
<view
class="u-flex u-row-between u-m-b-24"
style="gap: 40rpx"
v-for="(item, index) in modelValue"
:key="index"
>
<view
class="choose-coupon u-flex-1 u-flex u-row-between"
@click="showCoupon(item, index)"
>
<template v-if="item.title">
<text>{{ item.title }}</text>
<view class="u-flex" @click.stop="item.title = ''">
<up-icon name="close" size="14"></up-icon>
</view>
</template>
<template v-else>
<chooseCoupon v-model="chooseCouponData.couponId" :show="chooseCouponData.show"></chooseCoupon> <text class="color-999">选择赠送券</text>
<up-icon name="arrow-down" size="14"></up-icon>
</template>
</view>
<view class="u-flex-1 u-flex">
<view class="u-flex-1 choose-coupon u-flex">
<input
class="u-flex-1"
placeholder=""
type="number"
v-model="item.num"
placeholder-class="color-999 u-font-28"
/>
<text class="no-wrap color-999">/1个码</text>
</view>
<view class="u-m-l-20">
<up-icon name="minus-circle-fill" color="#EB4F4F" size="18" @click="removeCoupon(index)"></up-icon>
</view>
</view>
</view>
<chooseCoupon
v-model="chooseCouponData.couponId"
v-model:show="chooseCouponData.show"
@confirm="confirmCoupon"
:list="couponList"
></chooseCoupon>
</view> </view>
</template> </template>
<script setup> <script setup>
import { reactive } from "vue"; import { reactive, ref, onMounted } from "vue";
import chooseCoupon from "./choose-coupon.vue"; import chooseCoupon from "./choose-coupon.vue";
const chooseCouponData=reactive({ import { couponPage } from "@/http/api/market/index.js";
couponId:'',
show:true const chooseCouponData = reactive({
}) couponId: "",
show: false,
index: -1,
item: null,
});
const modelValue = defineModel({ const modelValue = defineModel({
type: Array, type: Array,
default: () => [], default: () => [],
}); });
const couponList = ref([]);
function showCoupon(item, index) {
chooseCouponData.couponId = item ? item.id : "";
chooseCouponData.show = true;
chooseCouponData.index = index;
chooseCouponData.item = item;
}
function confirmCoupon(e) {
modelValue.value[chooseCouponData.index].id = e.id;
modelValue.value[chooseCouponData.index].title = e.title;
}
function removeCoupon(index) {
modelValue.value.splice(index, 1);
}
onMounted(() => {
couponPage({ size: 999 }).then((res) => {
couponList.value = res.records;
});
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
</style> .choose-coupon {
padding: 10rpx 20rpx;
border-radius: 8rpx;
border: 1px solid #d9d9d9;
}
</style>

View File

@ -1,84 +1,84 @@
<template> <template>
<view> <view>
<up-popup :show="show" mode="center"> <up-popup :show="show" mode="center">
<view class="popup-content"> <view class="popup-content">
<view class="top u-flex u-row-between"> <view class="top u-flex u-row-between">
<text class="font-bold u-font-32 color-333">{{title}}</text> <text class="font-bold u-font-32 color-333">{{ title }}</text>
<up-icon size="18" name="close" @click="show=false"></up-icon> <up-icon size="18" name="close" @click="show = false"></up-icon>
</view> </view>
<up-line></up-line> <up-line></up-line>
<scroll-view style="max-height:50vh;"> <scroll-view style="max-height: 50vh" :scroll-y="true">
<slot></slot> <slot></slot>
</scroll-view> </scroll-view>
<up-line></up-line> <up-line></up-line>
<view class="bottom"> <view class="bottom">
<view class="btn success" @click="confirm">{{confirmText}}</view> <view class="btn cancel" @click="close">{{ cancelText }}</view>
<view class="btn cancel" @click="close">{{cancelText}}</view> <view class="btn success" @click="confirm">{{ confirmText }}</view>
</view> </view>
</view> </view>
</up-popup> </up-popup>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
const props = defineProps({ const props = defineProps({
title: { title: {
type: String, type: String,
default: "标题", default: "标题",
}, },
confirmText: { confirmText: {
type: String, type: String,
default: "保存", default: "保存",
}, },
cancelText: { cancelText: {
type: String, type: String,
default: "取消", default: "取消",
}, },
}); });
const show = defineModel({ const show = defineModel({
type: Boolean, type: Boolean,
default: false, default: false,
}) });
const emits=defineEmits(['close','confirm']) const emits = defineEmits(["close", "confirm"]);
function close(){ function close() {
show.value=false show.value = false;
emits('close') emits("close");
} }
function confirm(){ function confirm() {
emits('confirm') emits("confirm");
} }
</script> </script>
<style lang="scss"> <style lang="scss">
.popup-content{ .popup-content {
background: #fff; background: #fff;
width: 640rpx; width: 640rpx;
border-radius: 18rpx; border-radius: 18rpx;
} }
.top{ .top {
padding: 40rpx 48rpx; padding: 40rpx 48rpx;
} }
.bottom{ .bottom {
padding: 48rpx 52rpx; padding: 48rpx 52rpx;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
gap: 50rpx; gap: 50rpx;
.btn{ .btn {
flex:1; flex: 1;
text-align: center; text-align: center;
padding: 18rpx 60rpx; padding: 18rpx 60rpx;
border-radius: 100rpx; border-radius: 100rpx;
font-size: 32rpx; font-size: 32rpx;
border: 2rpx solid transparent; border: 2rpx solid transparent;
&.success{ &.success {
background-color: $my-main-color; background-color: $my-main-color;
color:#fff; color: #fff;
}
&.cancel{
border-color:#D9D9D9;
box-shadow: 0 4rpx 0 0 #00000005;
}
} }
&.cancel {
border-color: #d9d9d9;
box-shadow: 0 4rpx 0 0 #00000005;
}
}
} }
</style> </style>

View File

@ -6,32 +6,47 @@
<up-input <up-input
placeholder="请输入兑换码名称" placeholder="请输入兑换码名称"
border="none" border="none"
v-model="form.title" v-model="form.name"
placeholder-class="color-999 u-font-28" placeholder-class="color-999 u-font-28"
></up-input> ></up-input>
<view class="u-m-t-24"> <view class="u-m-t-24">
<up-line></up-line> <up-line></up-line>
</view> </view>
</view> </view>
<view class="u-m-t-24"> <view class="u-m-t-24">
<view class="font-bold u-m-b-16">活动日期</view> <view class="font-bold u-m-b-16">活动日期</view>
<DateTimePicker v-model:startTime="form.startTime" v-model:endTime="form.endTime"> </DateTimePicker> <DateTimePicker
v-model:startTime="form.startTime"
v-model:endTime="form.endTime"
>
</DateTimePicker>
</view>
<view class="u-m-t-24">
<view class="font-bold u-m-b-16">发行数量</view>
<view class="u-flex u-m-t-16">
<input
class="number-box"
placeholder="请输入"
placeholder-class="color-999 u-font-28"
type="number"
v-model="form.total"
/>
<view class="unit"></view>
</view>
</view> </view>
</view> </view>
<view class="default-box-padding bg-fff default-box-radius u-m-t-32"> <view class="default-box-padding bg-fff default-box-radius u-m-t-32">
<view class="font-bold">优惠券</view> <view class="font-bold">优惠券</view>
<view class="u-m-t-16 u-p-b-24"> <view class="u-m-t-16">
<CouponList v-model="form.couponInfoList"></CouponList> <CouponList v-model="form.couponInfoList"></CouponList>
</view> </view>
<up-line></up-line> <up-line></up-line>
<view class="font-bold u-m-t-24 u-m-b-16">指定时间段可用</view> <view class="u-m-t-16 u-flex">
<view class="my-hour-area"> <view class="u-flex" @click="addCoupon">
<my-hour-area <up-icon name="plus-circle-fill" color="#318AFE" size="18"></up-icon>
v-model:useTimeType="form.useTimeType" <text class="font-bold u-m-l-20">添加</text>
v-model:startValue="form.useStartTime" </view>
v-model:endValue="form.useEndTime"
></my-hour-area>
</view> </view>
</view> </view>
@ -47,7 +62,7 @@
import { reactive, onMounted } from "vue"; import { reactive, onMounted } from "vue";
import DateTimePicker from "@/pageMarket/components/date-time-picker.vue"; import DateTimePicker from "@/pageMarket/components/date-time-picker.vue";
import CouponList from "@/pageMarket/components/coupon-list.vue"; import CouponList from "@/pageMarket/components/coupon-list.vue";
import * as suggestApi from "@/http/api/market/suggest.js"; import * as couponRedemptionApi from "@/http/api/market/couponRedemption.js";
import { import {
onLoad, onLoad,
onReady, onReady,
@ -57,103 +72,106 @@ import {
onBackPress, onBackPress,
} from "@dcloudio/uni-app"; } from "@dcloudio/uni-app";
function cancel() {
uni.navigateBack({
delta: 1,
});
}
const form = reactive({ const form = reactive({
useStartTime: "", name: "",
useTimeType: "all", startTime: "",
useEndTime: "", endTime: "",
startTime:'', stock: "",
endTime:'', total: 0,
couponInfoList: [], couponInfoList: [
{
id: "",
num: "",
title: "",
},
],
}); });
function save() { function save() {
if (!form.title) { if (!form.name) {
uni.showToast({ uni.showToast({
title: "请输入模版名称", title: "请输入兑换码名称",
icon: "none", icon: "none",
}); });
return; return;
} }
if (form.useTimeType == "custom") { if (!form.startTime || !form.endTime) {
if (!form.useStartTime) {
uni.showToast({
title: "请选择开始时间",
icon: "none",
});
return;
}
if (!form.useEndTime) {
uni.showToast({
title: "请选择结束时间",
icon: "none",
});
return;
}
}
if (form.useDays.length == 0) {
uni.showToast({ uni.showToast({
title: "请选择可用周期", title: "请选择活动日期",
icon: "none", icon: "none",
}); });
return; return;
} }
if (!form.foods) {
if (!form.total) {
uni.showToast({ uni.showToast({
title: "请选择商品", title: "请输入发行数量",
icon: "none", icon: "none",
}); });
return; return;
} }
if(options.type=='edit'){ if (options.type == "edit") {
suggestApi couponRedemptionApi
.editSuggest({ .editSuggest({
title: form.title, title: form.title,
id: form.id, id: form.id,
foods: form.foods, foods: form.foods,
useDays: form.useDays.join(","), useDays: form.useDays.join(","),
useStartTime: form.useStartTime, useStartTime: form.useStartTime,
useTimeType: form.useTimeType, useTimeType: form.useTimeType,
useEndTime: form.useEndTime, useEndTime: form.useEndTime,
}) })
.then((res) => { .then((res) => {
uni.showToast({ uni.showToast({
title: "修改成功", title: "修改成功",
icon: "none", icon: "none",
});
setTimeout(() => {
uni.navigateBack({
delta: 1,
});
}, 1500);
}); });
setTimeout(() => { return;
uni.navigateBack({ }
console.log('form.couponInfoList',form.couponInfoList)
//
if (form.couponInfoList.some((item) => !item.id || !item.num)) {
uni.showToast({
title: "请选择优惠券并填写数量",
icon: "none",
});
return;
}
couponRedemptionApi.add(form).then((res) => {
uni.showToast({
title: "添加成功",
icon: "none",
});
setTimeout(() => {
uni.navigateBack({
delta: 1, delta: 1,
}); });
}, 1500); }, 1500);
});
});
return
}
suggestApi
.addSuggest({
title: form.title,
foods: form.foods,
useDays: form.useDays.join(","),
useStartTime: form.useStartTime,
useTimeType: form.useTimeType,
useEndTime: form.useEndTime,
})
.then((res) => {
uni.showToast({
title: "添加成功",
icon: "none",
});
setTimeout(() => {
uni.navigateBack({
delta: 1,
});
}, 1500);
});
} }
const options=reactive({}) function addCoupon() {
onLoad((opt) => { form.couponInfoList.push({
id: "",
}); num: "",
title: "",
});
}
const options = reactive({});
onLoad((opt) => {});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -0,0 +1,52 @@
<template>
<view class="u-flex">
<view @click="show = true">
<slot v-if="$slots.default"> </slot>
<view v-else class="choose-goods u-flex u-row-between">
<text class="color-333 u-font-28 font-bold">{{ statusText }}</text>
<up-icon size="14" name="arrow-down" color="#333" bold></up-icon>
</view>
</view>
<up-action-sheet
:show="show"
cancel-text="取消"
closeOnClickAction
@close="show = false"
:actions="actions"
@select="confirm"
></up-action-sheet>
</view>
</template>
<script setup>
import { ref ,computed } from "vue";
const show = ref(false);
const modelValue = defineModel({
type: String,
default: "",
});
function confirm(item) {
modelValue.value = item.value;
}
const actions = ref([
{
name: "全部",
value: "",
},
{
name: "已兑换",
value: "1",
},
{
name: "未兑换",
value: "0",
},
]);
const statusText = computed(() => {
if (modelValue.value === "") {
return "全部";
}
return modelValue.value === "1" ? "已兑换" : "未兑换";
});
</script>

View File

@ -0,0 +1,280 @@
<template>
<view class="min-page bg-f7 default-box-padding u-font-28 color-333">
<view class="bg-fff default-box-radius">
<view class="default-box-padding u-flex u-row-between">
<text class="font-bold">兑换码名称</text>
<text class="color-666">{{ form.name }}</text>
</view>
<up-line></up-line>
<view class="default-box-padding u-flex u-row-between">
<text class="font-bold">活动日期</text>
<text class="color-666 u-font-24"
>{{ form.startTime }} {{ form.endTime }}</text
>
</view>
<up-line></up-line>
<view class="default-box-padding u-flex u-row-between">
<text class="font-bold">总数</text>
<text class="color-666 u-font-24">{{ form.total }}</text>
</view>
<up-line></up-line>
<view class="default-box-padding u-flex u-row-between">
<text class="font-bold">库存</text>
<view style="width: 158rpx">
<up-input
v-model="form.stock"
type="number"
placeholder="库存"
placeholder-class="color-999 u-font-28"
></up-input>
</view>
</view>
<up-line></up-line>
<view class="default-box-padding u-flex u-row-between">
<text class="font-bold">优惠券</text>
<view>
<text class="u-p-l-30">{{ returnCoupon }}</text>
<text class="color-main u-font-32 u-m-l-20" @click="showModal"
>修改</text
>
</view>
</view>
<up-line></up-line>
<view class="u-p-b-24"></view>
</view>
<view class="u-p-t-48 u-p-b-48 u-p-l-60 u-p-r-60">
<my-button type="primary" shape="circle" @click="save">保存</my-button>
</view>
<view class="bg-fff default-box-radius">
<view class="default-box-x-padding u-p-t-32 u-flex u-row-between">
<couponStatus v-model="query.status"></couponStatus>
<view class="u-flex">
<view class="border u-flex default-box-radius search-box">
<up-icon name="search"></up-icon>
<input
style="width: 140rpx"
placeholder="输入兑换码"
class="u-font-28 u-m-l-20"
placeholder-class="color-999 u-font-28"
v-model="query.name"
/>
</view>
<view class="daochu u-m-l-24">导出</view>
</view>
</view>
<view class="list u-m-t-48">
<view
class="item default-box-padding"
v-for="(item, index) in list"
:key="index"
>
<view class="u-flex u-row-between">
<text class="status" :class="['status-' + item.status]">{{
item.status == 0 ? "未兑换" : "已兑换"
}}</text>
<view>
<text class="color-666">{{ item.code }}</text>
<text class="color-main u-m-l-20" @click="copyCode(item.code)"
>复制</text
>
</view>
</view>
<view class="u-m-t-16 u-flex u-row-between color-666">
<text>{{ item.redemptionTime }}</text>
<view>
<text>{{ item.nickName }}</text>
<text>{{ item.phone }}</text>
</view>
</view>
</view>
</view>
</view>
<up-loadmore :status="isEnd ? 'nomore' : 'loading'"></up-loadmore>
<Modal
:title="ModalData.title"
v-model="ModalData.show"
@confirm="modelConfirm"
>
<view class="default-box-padding">
<CouponList v-model="form.couponInfoList"></CouponList>
<view class="u-m-t-16 u-flex">
<view class="u-flex" @click="addCoupon">
<up-icon
name="plus-circle-fill"
color="#318AFE"
size="18"
></up-icon>
<text class="font-bold u-m-l-20">添加</text>
</view>
</view>
</view>
</Modal>
</view>
</template>
<script setup>
import {
onLoad,
onReady,
onShow,
onPageScroll,
onReachBottom,
onBackPress,
} from "@dcloudio/uni-app";
import couponStatus from "./components/status.vue";
import CouponList from "@/pageMarket/components/coupon-list.vue";
import Modal from "@/pageMarket/components/modal.vue";
import * as couponRedemptionApi from "@/http/api/market/couponRedemption.js";
import {
reactive,
toRefs,
computed,
watch,
onMounted,
onUnmounted,
ref,
} from "vue";
function addCoupon() {
form.couponInfoList.push({
id: "",
num: "",
title: "",
});
}
function modelConfirm() {
//
if (form.couponInfoList.some((item) => !item.id || !item.num)) {
uni.showToast({
title: "请选择优惠券并填写数量",
icon: "none",
});
return;
}
ModalData.show = false;
}
const ModalData = reactive({
show: false,
title: "修改优惠券",
});
function save() {
if (form.stock === "" || form.stock === null) {
uni.showToast({
title: "请填写库存",
icon: "none",
});
return;
}
couponRedemptionApi.edit(form).then((res) => {
uni.showToast({
title: "修改成功",
icon: "none",
});
ModalData.show = false;
refresh();
});
}
function showModal() {
ModalData.show = true;
}
const form = reactive({
couponInfoList: [],
});
onLoad((opt) => {
const item = uni.getStorageSync("couponRedemptionItem");
Object.assign(form, item);
});
const query = reactive({
status: "",
code: "",
page: 1,
size: 10,
});
function copyCode(code) {
uni.setClipboardData({
data: code,
success: () => {
uni.showToast({
title: "复制成功",
icon: "none",
});
},
});
}
const returnCoupon = computed(() => {
return form.couponInfoList
.reduce((prev, cur) => prev + cur.title + "*" + cur.num + "、", "")
.slice(0, -1);
});
const list = ref([]);
const isEnd = ref(false);
function getList() {
couponRedemptionApi
.codeList({ ...query, redemptionId: form.id })
.then((res) => {
if (query.page == 1) {
list.value = res.records;
} else {
list.value = [...list.value, ...res.records];
}
if (query.page >= res.totalPage * 1) {
isEnd.value = true;
}
});
}
function refresh() {
isEnd.value = false;
query.page = 1;
getList();
}
watch(() => query, refresh);
onMounted(() => {
getList();
});
onReachBottom(() => {
console.log("触底");
if (isEnd.value) {
return;
}
query.page++;
getList();
});
</script>
<style scoped lang="scss">
.border {
border: 1rpx solid #dddfe6;
}
.search-box {
padding: 18rpx 32rpx;
}
.daochu {
border: 1rpx solid $my-main-color;
padding: 12rpx 34rpx;
border-radius: 8rpx;
white-space: nowrap;
color: $my-main-color;
min-height: 72rpx;
}
.status {
font-weight: 700;
&.status-0 {
color: #5bbc6d;
}
&.status-1 {
color: #ff895c;
}
}
.item {
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
}
</style>

View File

@ -204,8 +204,8 @@ function refreshList() {
} }
function handleEdit(item) { function handleEdit(item) {
uni.setStorageSync("suggestItem", item); uni.setStorageSync("couponRedemptionItem", item);
go.to("PAGES_MARKET_ORDER_RECOMMENDATION_ADD", { go.to("PAGES_MARKET_COUPON_EXCHANGE_CODE_DETAIL", {
type: "edit", type: "edit",
}); });
} }

View File

@ -733,7 +733,14 @@
"style": { "style": {
"navigationBarTitleText": "添加券兑换码" "navigationBarTitleText": "添加券兑换码"
} }
} },
{
"pageId": "PAGES_MARKET_COUPON_EXCHANGE_CODE_DETAIL",
"path": "couponExchangeCode/detail",
"style": {
"navigationBarTitleText": "券兑换码详情"
}
},
] ]