mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-06-21 09:30:24 +08:00
Merge remote-tracking branch 'origin/master' into allinone-lite-mysql-redis
This commit is contained in:
@@ -92,6 +92,21 @@ export function selectCoupon (params) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择礼品卡
|
||||
* @param way 购物车购买:CART/立即购买:BUY_NOW/拼团购买:PINTUAN / 积分购买:POINT
|
||||
* @param credentialId 礼品卡凭证 id;used=false 且不传则清空全部
|
||||
* @param used 使用 true / 弃用 false
|
||||
*/
|
||||
export function selectGiftCard (params) {
|
||||
return request({
|
||||
url: '/buyer/trade/carts/select/giftCard',
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 可用优惠券数量
|
||||
*/
|
||||
|
||||
@@ -57,3 +57,50 @@ export function pointGoodsDetail (id) {
|
||||
id
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询当前客户礼品卡
|
||||
*/
|
||||
export function getGiftCardCashMemberCardPage (params) {
|
||||
return request({
|
||||
url: '/buyer/promotion/giftCardCash/memberCard',
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定礼品卡(卡号 + 兑换码/卡密)
|
||||
*/
|
||||
export function bindGiftCardCashMemberCard (data) {
|
||||
return request({
|
||||
url: '/buyer/promotion/giftCardCash/memberCard/bind',
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 激活礼品卡
|
||||
*/
|
||||
export function activateGiftCardCashMemberCard (memberCardId) {
|
||||
return request({
|
||||
url: `/buyer/promotion/giftCardCash/memberCard/${memberCardId}/activate`,
|
||||
method: Method.POST,
|
||||
needToken: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 下单页可用礼品卡列表
|
||||
*/
|
||||
export function getAvailableGiftCardCashMemberCards () {
|
||||
return request({
|
||||
url: '/buyer/promotion/giftCardCash/memberCard/available',
|
||||
method: Method.GET,
|
||||
needToken: true
|
||||
});
|
||||
}
|
||||
|
||||
@@ -231,6 +231,14 @@
|
||||
}}</span
|
||||
>
|
||||
</div>
|
||||
<div v-if="order.order.priceDetailDTO.giftCardPrice">
|
||||
<span>礼品卡抵扣:</span
|
||||
><span
|
||||
>-{{
|
||||
order.order.priceDetailDTO.giftCardPrice || 0 | unitPrice("¥")
|
||||
}}</span
|
||||
>
|
||||
</div>
|
||||
<div v-if="order.order.discountPrice">
|
||||
<span>活动优惠:</span
|
||||
><span>-{{ order.order.discountPrice | unitPrice("¥") }}</span>
|
||||
|
||||
461
buyer/src/pages/home/userCenter/MyGiftCards.vue
Normal file
461
buyer/src/pages/home/userCenter/MyGiftCards.vue
Normal file
@@ -0,0 +1,461 @@
|
||||
<template>
|
||||
<div class="wrapper my-gift-cards">
|
||||
<card _Title="我的礼品卡" />
|
||||
|
||||
<div class="bind-section mb_20">
|
||||
<div class="section-title">兑换礼品卡</div>
|
||||
<Form ref="bindForm" :model="bindForm" :rules="bindRules" inline class="bind-form">
|
||||
<FormItem label="卡号" prop="cardNo" :label-width="60">
|
||||
<Input v-model="bindForm.cardNo" placeholder="请输入卡号" maxlength="64" style="width: 220px" />
|
||||
</FormItem>
|
||||
<FormItem label="兑换码" prop="cardSecret" :label-width="70">
|
||||
<Input
|
||||
v-model="bindForm.cardSecret"
|
||||
type="password"
|
||||
placeholder="请输入兑换码(卡密)"
|
||||
maxlength="128"
|
||||
style="width: 220px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem :label-width="0">
|
||||
<Button type="primary" :loading="bindSubmitting" @click="submitBind">兑换</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</div>
|
||||
|
||||
<Tabs v-model="statusTab" class="status-tabs mb_16" @on-click="onStatusTab">
|
||||
<TabPane label="可用" name="AVAILABLE" />
|
||||
<TabPane label="不可用" name="UNAVAILABLE" />
|
||||
<TabPane label="待激活" name="PENDING_ACTIVATION" />
|
||||
</Tabs>
|
||||
|
||||
<div class="card-list-wrap">
|
||||
<Spin v-if="loading" fix />
|
||||
<template v-if="!loading">
|
||||
<empty v-if="list.length === 0" />
|
||||
<div v-else class="gift-card-grid">
|
||||
<div v-for="item in list" :key="item.id || item.cardNo" class="gcc-card-item">
|
||||
<div class="gcc-card-header">
|
||||
<div class="gcc-header-pattern" aria-hidden="true" />
|
||||
<div class="gcc-header-inner">
|
||||
<div class="gcc-header-left">
|
||||
<div class="gcc-title">{{ item.giftCardName || "礼品卡" }}</div>
|
||||
<div class="gcc-face">面值{{ formatYuan(item.faceValue) }}元</div>
|
||||
<div class="gcc-cardno">{{ item.cardNo }}</div>
|
||||
</div>
|
||||
<div class="gcc-header-right">
|
||||
<div class="gcc-type">现金卡</div>
|
||||
<div class="gcc-expire">{{ formatValidity(item) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gcc-card-body">
|
||||
<div class="gcc-row">
|
||||
当前余额:<span class="gcc-strong" v-if="item.balance != null">¥{{ item.balance | unitPrice }}</span><span class="gcc-strong" v-else>—</span>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="gcc-action"
|
||||
:class="{
|
||||
'is-disabled': primaryActionDisabled || pendingActivateLocked || isActivating(item),
|
||||
}"
|
||||
:disabled="primaryActionDisabled || pendingActivateLocked || isActivating(item)"
|
||||
@click="onCardPrimaryAction(item)"
|
||||
>
|
||||
<span v-if="isActivating(item)">提交中...</span>
|
||||
<span v-else>{{ primaryActionLabel }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="page-size">
|
||||
<Page
|
||||
:current="params.pageNumber"
|
||||
:page-size="params.pageSize"
|
||||
:page-size-opts="[10, 20, 50]"
|
||||
:total="total"
|
||||
show-sizer
|
||||
show-total
|
||||
size="small"
|
||||
transfer
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Modal v-model="noticeModal" title="使用须知" footer-hide width="520">
|
||||
<p class="gcc-notice-text">
|
||||
请在有效期内使用本礼品卡;消费时将优先使用卡内余额。具体使用范围以活动规则为准。如有疑问请联系客服。
|
||||
</p>
|
||||
<div class="gcc-notice-footer">
|
||||
<Button type="primary" @click="noticeModal = false">我知道了</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getGiftCardCashMemberCardPage,
|
||||
bindGiftCardCashMemberCard,
|
||||
activateGiftCardCashMemberCard,
|
||||
} from "@/api/promotion.js";
|
||||
|
||||
export default {
|
||||
name: "MyGiftCards",
|
||||
data() {
|
||||
return {
|
||||
statusTab: "AVAILABLE",
|
||||
loading: false,
|
||||
total: 0,
|
||||
list: [],
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
memberCardStatus: "AVAILABLE",
|
||||
},
|
||||
bindSubmitting: false,
|
||||
bindForm: {
|
||||
cardNo: "",
|
||||
cardSecret: "",
|
||||
},
|
||||
bindRules: {
|
||||
cardNo: [{ required: true, message: "请输入卡号", trigger: "blur" }],
|
||||
cardSecret: [{ required: true, message: "请输入兑换码", trigger: "blur" }],
|
||||
},
|
||||
noticeModal: false,
|
||||
serviceHotline: "12221111",
|
||||
activatingId: "",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
primaryActionLabel() {
|
||||
if (this.statusTab === "PENDING_ACTIVATION") {
|
||||
return "激活自用";
|
||||
}
|
||||
if (this.statusTab === "AVAILABLE") {
|
||||
return "去使用";
|
||||
}
|
||||
return "不可用";
|
||||
},
|
||||
primaryActionDisabled() {
|
||||
return this.statusTab === "UNAVAILABLE";
|
||||
},
|
||||
pendingActivateLocked() {
|
||||
return this.statusTab === "PENDING_ACTIVATION" && !!this.activatingId;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
formatYuan(val) {
|
||||
if (val == null || val === "") {
|
||||
return "—";
|
||||
}
|
||||
const n = Number(val);
|
||||
if (Number.isNaN(n)) {
|
||||
return String(val);
|
||||
}
|
||||
return Number.isInteger(n) ? String(n) : n.toFixed(2).replace(/\.?0+$/, "");
|
||||
},
|
||||
formatValidity(row) {
|
||||
const t = row && row.expireTime;
|
||||
if (!t) {
|
||||
return "长期有效";
|
||||
}
|
||||
const d = new Date(t);
|
||||
if (Number.isNaN(d.getTime())) {
|
||||
return "长期有效";
|
||||
}
|
||||
if (d.getFullYear() >= 2099) {
|
||||
return "长期有效";
|
||||
}
|
||||
const y = d.getFullYear();
|
||||
const m = String(d.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(d.getDate()).padStart(2, "0");
|
||||
return `${y}-${m}-${day} 到期`;
|
||||
},
|
||||
onStatusTab(name) {
|
||||
this.statusTab = name;
|
||||
this.params.memberCardStatus = name;
|
||||
this.params.pageNumber = 1;
|
||||
this.getList();
|
||||
},
|
||||
getList() {
|
||||
this.loading = true;
|
||||
const p = { ...this.params };
|
||||
if (p.memberCardStatus) {
|
||||
p.memberCardStatus = String(p.memberCardStatus);
|
||||
}
|
||||
getGiftCardCashMemberCardPage(p)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success && res.result) {
|
||||
this.list = res.result.records || [];
|
||||
this.total = res.result.total || 0;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
changePage(val) {
|
||||
this.params.pageNumber = val;
|
||||
this.getList();
|
||||
},
|
||||
changePageSize(val) {
|
||||
this.params.pageNumber = 1;
|
||||
this.params.pageSize = val;
|
||||
this.getList();
|
||||
},
|
||||
resetBindForm() {
|
||||
this.bindForm = { cardNo: "", cardSecret: "" };
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.bindForm) {
|
||||
this.$refs.bindForm.resetFields();
|
||||
}
|
||||
});
|
||||
},
|
||||
submitBind() {
|
||||
this.$refs.bindForm.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
this.bindSubmitting = true;
|
||||
bindGiftCardCashMemberCard({
|
||||
cardNo: String(this.bindForm.cardNo).trim(),
|
||||
cardSecret: String(this.bindForm.cardSecret).trim(),
|
||||
})
|
||||
.then((res) => {
|
||||
this.bindSubmitting = false;
|
||||
if (res.success) {
|
||||
this.$Message.success(res.message || "兑换成功");
|
||||
this.resetBindForm();
|
||||
this.params.pageNumber = 1;
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.bindSubmitting = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
onCardPrimaryAction(item) {
|
||||
if (this.primaryActionDisabled) {
|
||||
return;
|
||||
}
|
||||
if (this.statusTab === "PENDING_ACTIVATION") {
|
||||
const memberCardId = this.resolveMemberCardId(item);
|
||||
if (!memberCardId) {
|
||||
this.$Message.error("卡片信息异常,无法激活");
|
||||
return;
|
||||
}
|
||||
this.activatingId = memberCardId;
|
||||
activateGiftCardCashMemberCard(memberCardId)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success(res.message || "激活成功");
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
this.activatingId = "";
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (this.statusTab === "AVAILABLE") {
|
||||
this.$router.push({ path: "/goodsList" });
|
||||
}
|
||||
},
|
||||
resolveMemberCardId(row) {
|
||||
if (!row) {
|
||||
return "";
|
||||
}
|
||||
return row.memberCardId != null && row.memberCardId !== ""
|
||||
? String(row.memberCardId)
|
||||
: row.id != null && row.id !== ""
|
||||
? String(row.id)
|
||||
: "";
|
||||
},
|
||||
isActivating(item) {
|
||||
const id = this.resolveMemberCardId(item);
|
||||
return !!this.activatingId && this.activatingId === id;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.my-gift-cards {
|
||||
.bind-section {
|
||||
padding: 16px 18px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e8eaec;
|
||||
@include white_background_color();
|
||||
}
|
||||
.section-title {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 14px;
|
||||
@include title_color($light_title_color);
|
||||
}
|
||||
.bind-form {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
gap: 4px 8px;
|
||||
}
|
||||
.status-tabs {
|
||||
::v-deep .ivu-tabs-bar {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.card-list-wrap {
|
||||
position: relative;
|
||||
min-height: 200px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
.gift-card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 20px 18px;
|
||||
align-items: start;
|
||||
}
|
||||
.gcc-card-item {
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
|
||||
@include white_background_color();
|
||||
}
|
||||
.gcc-card-header {
|
||||
position: relative;
|
||||
min-height: 128px;
|
||||
padding: 0;
|
||||
background: linear-gradient(125deg, #ff9a4a 0%, #ff7729 42%, #ff8f3d 100%);
|
||||
}
|
||||
.gcc-header-pattern {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
opacity: 0.22;
|
||||
pointer-events: none;
|
||||
background-image: repeating-linear-gradient(
|
||||
-36deg,
|
||||
transparent,
|
||||
transparent 5px,
|
||||
rgba(255, 255, 255, 0.45) 5px,
|
||||
rgba(255, 255, 255, 0.45) 6px
|
||||
);
|
||||
}
|
||||
.gcc-header-inner {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
padding: 16px 14px 14px;
|
||||
color: #fff;
|
||||
}
|
||||
.gcc-header-left {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding-right: 8px;
|
||||
}
|
||||
.gcc-title {
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
.gcc-face {
|
||||
margin-top: 8px;
|
||||
font-size: 13px;
|
||||
opacity: 0.95;
|
||||
}
|
||||
.gcc-cardno {
|
||||
margin-top: 22px;
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.02em;
|
||||
opacity: 0.75;
|
||||
word-break: break-all;
|
||||
}
|
||||
.gcc-header-right {
|
||||
text-align: right;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.gcc-type {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.gcc-expire {
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
opacity: 0.9;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.gcc-card-body {
|
||||
padding: 14px 14px 16px;
|
||||
}
|
||||
.gcc-row {
|
||||
font-size: 13px;
|
||||
line-height: 1.85;
|
||||
@include title_color($light_title_color);
|
||||
}
|
||||
.gcc-muted {
|
||||
color: #999;
|
||||
}
|
||||
.gcc-strong {
|
||||
color: #ff6b22;
|
||||
font-weight: 600;
|
||||
}
|
||||
.gcc-link {
|
||||
color: $theme_color;
|
||||
cursor: pointer;
|
||||
}
|
||||
.gcc-service {
|
||||
color: #515a6e;
|
||||
}
|
||||
.gcc-action {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-top: 14px;
|
||||
padding: 10px 16px;
|
||||
border: none;
|
||||
border-radius: 999px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
color: #e95b6c;
|
||||
background: #faf4f5;
|
||||
transition: opacity 0.2s, background 0.2s;
|
||||
}
|
||||
.gcc-action:hover:not(.is-disabled) {
|
||||
background: #f5e8ea;
|
||||
}
|
||||
.gcc-action.is-disabled {
|
||||
color: #c5c8ce;
|
||||
cursor: not-allowed;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
.page-size {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
.gcc-notice-text {
|
||||
line-height: 1.7;
|
||||
color: #515a6e;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.gcc-notice-footer {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
@@ -195,6 +195,60 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- 礼品卡 -->
|
||||
<div class="invoice pay-gcc-module">
|
||||
<div class="pay-gcc-head">
|
||||
<div class="pay-gcc-title">
|
||||
使用礼品卡
|
||||
<span class="pay-gcc-deduct">
|
||||
(已抵扣 <span class="pay-gcc-deduct-num">{{ giftCardDeductAmount | unitPrice("¥") }}</span
|
||||
>)
|
||||
</span>
|
||||
</div>
|
||||
<a href="javascript:void(0)" class="pay-gcc-help" @click.prevent="giftCardNoticeModal = true">
|
||||
使用说明 <Icon type="ios-help-circle-outline" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="pay-gcc-body">
|
||||
<div class="pay-gcc-panel">
|
||||
<div class="pay-gcc-grid-wrap">
|
||||
<div v-if="giftCardList.length === 0" class="pay-gcc-empty">暂无可用礼品卡</div>
|
||||
<div v-else class="pay-gcc-cards">
|
||||
<div
|
||||
v-for="(item, index) in giftCardList"
|
||||
:key="item.id || index"
|
||||
class="pay-gcc-item"
|
||||
@click="toggleGiftCard(item)"
|
||||
>
|
||||
<div class="pay-gcc-item-inner">
|
||||
<div class="pay-gcc-pattern" aria-hidden="true" />
|
||||
<div class="pay-gcc-item-main">
|
||||
<div class="pay-gcc-top-row">
|
||||
<div class="pay-gcc-left">
|
||||
<div class="pay-gcc-name">{{ item.giftCardName || "礼品卡" }}</div>
|
||||
<div class="pay-gcc-face">面值{{ formatGiftFaceValue(item.faceValue) }}元</div>
|
||||
</div>
|
||||
<div class="pay-gcc-right-meta">
|
||||
<div class="pay-gcc-type">现金卡</div>
|
||||
<div class="pay-gcc-valid">{{ formatGiftExpire(item) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pay-gcc-balance-row">
|
||||
<span class="pay-gcc-amt">¥{{ item.balance != null ? (item.balance | unitPrice) : "0.00" }}</span>
|
||||
<span class="pay-gcc-bal-label">余额</span>
|
||||
</div>
|
||||
<div class="pay-gcc-no">{{ item.cardNo }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isGiftCardSelected(item)" class="pay-gcc-corner">
|
||||
<Icon type="md-checkmark" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 订单价格 -->
|
||||
<div class="order-price">
|
||||
<div>
|
||||
@@ -209,6 +263,9 @@
|
||||
<div v-if="priceDetailDTO.couponPrice > 0">
|
||||
<span>优惠券金额:</span><span>-{{ priceDetailDTO.couponPrice | unitPrice("¥") }}</span>
|
||||
</div>
|
||||
<div v-if="giftCardDeductAmount > 0">
|
||||
<span>礼品卡抵扣:</span><span>-{{ giftCardDeductAmount | unitPrice("¥") }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="$route.query.way === 'POINTS'">
|
||||
<span>应付积分:</span><span class="actrual-price">{{ priceDetailDTO.payPoint }}</span>
|
||||
@@ -238,6 +295,14 @@
|
||||
<invoice-modal ref="invModal" :invoiceData="invoiceData" @change="getInvMsg" />
|
||||
<!-- 选择地址模态框 -->
|
||||
<address-manage ref="address" :id="addrId" @change="addrChange"></address-manage>
|
||||
<Modal v-model="giftCardNoticeModal" title="礼品卡使用说明" footer-hide width="520">
|
||||
<p class="pay-gcc-notice-p">
|
||||
请在礼品卡有效期内使用;结算时勾选礼品卡即可按规则抵扣订单金额,可与优惠券等活动叠加规则以平台说明为准。放弃勾选或取消抵扣将恢复对应余额。
|
||||
</p>
|
||||
<div class="pay-gcc-notice-foot">
|
||||
<Button type="primary" @click="giftCardNoticeModal = false">我知道了</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -250,6 +315,7 @@ import {
|
||||
createTrade,
|
||||
selectAddr,
|
||||
selectCoupon,
|
||||
selectGiftCard,
|
||||
setShipMethod,
|
||||
setStoreAddressId,
|
||||
shippingMethodList,
|
||||
@@ -282,6 +348,30 @@ export default {
|
||||
""
|
||||
);
|
||||
},
|
||||
giftCardDeductAmount() {
|
||||
if (this.tradeGiftCardDeductTotal != null && Number(this.tradeGiftCardDeductTotal) > 0) {
|
||||
return Number(this.tradeGiftCardDeductTotal);
|
||||
}
|
||||
const items = this.giftCardDeductItems || [];
|
||||
let sum = 0;
|
||||
items.forEach((it) => {
|
||||
sum += Number(it.deductAmount || 0);
|
||||
});
|
||||
if (sum > 0) {
|
||||
return sum;
|
||||
}
|
||||
const p = this.priceDetailDTO || {};
|
||||
const n = Number(
|
||||
p.giftCardPrice != null
|
||||
? p.giftCardPrice
|
||||
: p.giftCardDiscountPrice != null
|
||||
? p.giftCardDiscountPrice
|
||||
: p.memberCardPrice != null
|
||||
? p.memberCardPrice
|
||||
: 0
|
||||
);
|
||||
return Number.isFinite(n) ? n : 0;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -326,6 +416,11 @@ export default {
|
||||
usedCouponId: [], // 已使用优惠券id
|
||||
selectedCoupon: {}, // 已选优惠券对象
|
||||
storeId: '', //店铺Id
|
||||
giftCardList: [], // TradeDTO.canUseGiftCards
|
||||
giftCardNoticeModal: false,
|
||||
giftCardDeductItems: [], // 已选礼品卡抵扣明细(TradeDTO.giftCardDeductItems)
|
||||
tradeGiftCardDeductTotal: null, // TradeDTO.giftCardDeductTotal
|
||||
selectedGiftCardCredentialIds: [], // 已选凭证 id,与 deductItems 同步
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
@@ -476,12 +571,110 @@ export default {
|
||||
this.$forceUpdate();
|
||||
});
|
||||
}
|
||||
this.giftCardDeductItems = Array.isArray(res.result.giftCardDeductItems)
|
||||
? res.result.giftCardDeductItems
|
||||
: [];
|
||||
this.tradeGiftCardDeductTotal =
|
||||
res.result.giftCardDeductTotal != null && res.result.giftCardDeductTotal !== ""
|
||||
? Number(res.result.giftCardDeductTotal)
|
||||
: null;
|
||||
this.giftCardList = Array.isArray(res.result.canUseGiftCards) ? res.result.canUseGiftCards : [];
|
||||
this.syncGiftCardSelectionFromCart(res.result);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.$Spin.hide();
|
||||
});
|
||||
},
|
||||
syncGiftCardSelectionFromCart(result) {
|
||||
if (!result) {
|
||||
this.selectedGiftCardCredentialIds = [];
|
||||
return;
|
||||
}
|
||||
const selectedIds = result.selectedGiftCardIds;
|
||||
if (Array.isArray(selectedIds) && selectedIds.length) {
|
||||
this.selectedGiftCardCredentialIds = selectedIds
|
||||
.map((id) => (id != null && id !== "" ? String(id) : ""))
|
||||
.filter(Boolean);
|
||||
return;
|
||||
}
|
||||
const items = Array.isArray(result.giftCardDeductItems) ? result.giftCardDeductItems : [];
|
||||
if (items.length) {
|
||||
this.selectedGiftCardCredentialIds = items
|
||||
.map((it) => (it.credentialId != null && it.credentialId !== "" ? String(it.credentialId) : ""))
|
||||
.filter(Boolean);
|
||||
return;
|
||||
}
|
||||
const pd = result.priceDetailDTO || {};
|
||||
const id =
|
||||
result.selectedGiftCardCredentialId ||
|
||||
result.usedGiftCardCredentialId ||
|
||||
pd.selectedGiftCardCredentialId ||
|
||||
pd.usedGiftCardCredentialId ||
|
||||
(result.selectedGiftCard && (result.selectedGiftCard.id || result.selectedGiftCard.credentialId)) ||
|
||||
(result.giftCardCashSelected && result.giftCardCashSelected.id) ||
|
||||
null;
|
||||
this.selectedGiftCardCredentialIds =
|
||||
id != null && id !== "" ? [String(id)] : [];
|
||||
},
|
||||
formatGiftFaceValue(val) {
|
||||
if (val == null || val === "") {
|
||||
return "—";
|
||||
}
|
||||
const n = Number(val);
|
||||
if (Number.isNaN(n)) {
|
||||
return String(val);
|
||||
}
|
||||
return Number.isInteger(n) ? String(n) : n.toFixed(2).replace(/\.?0+$/, "");
|
||||
},
|
||||
formatGiftExpire(row) {
|
||||
const t = row && row.expireTime;
|
||||
if (!t) {
|
||||
return "长期有效";
|
||||
}
|
||||
const d = new Date(t);
|
||||
if (Number.isNaN(d.getTime())) {
|
||||
return "长期有效";
|
||||
}
|
||||
if (d.getFullYear() >= 2099) {
|
||||
return "长期有效";
|
||||
}
|
||||
const y = d.getFullYear();
|
||||
const m = String(d.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(d.getDate()).padStart(2, "0");
|
||||
return `${y}-${m}-${day} 到期`;
|
||||
},
|
||||
toggleGiftCard(item) {
|
||||
if (!item || item.id == null || item.id === "") {
|
||||
return;
|
||||
}
|
||||
if (this.isGiftCardSelected(item)) {
|
||||
this.useGiftCard(item.id, false);
|
||||
} else {
|
||||
this.useGiftCard(item.id, true);
|
||||
}
|
||||
},
|
||||
isGiftCardSelected(item) {
|
||||
if (!item || !this.selectedGiftCardCredentialIds.length) {
|
||||
return false;
|
||||
}
|
||||
const id = item.id != null ? String(item.id) : "";
|
||||
return id && this.selectedGiftCardCredentialIds.includes(id);
|
||||
},
|
||||
useGiftCard(credentialId, used) {
|
||||
const params = {
|
||||
way: this.$route.query.way,
|
||||
used,
|
||||
};
|
||||
if (credentialId != null && credentialId !== "") {
|
||||
params.credentialId = String(credentialId);
|
||||
}
|
||||
selectGiftCard(params).then((res) => {
|
||||
if (res.success) {
|
||||
this.init();
|
||||
}
|
||||
});
|
||||
},
|
||||
getCouponNum() {
|
||||
// 获取可用优惠券数量
|
||||
couponNum({ way: this.$route.query.way }).then((res) => {
|
||||
@@ -1189,4 +1382,189 @@ export default {
|
||||
max-height: 260px;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.pay-gcc-module {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.pay-gcc-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.pay-gcc-title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
.pay-gcc-deduct {
|
||||
margin-left: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
color: #666;
|
||||
}
|
||||
.pay-gcc-deduct-num {
|
||||
color: #e54d42;
|
||||
font-weight: 600;
|
||||
}
|
||||
.pay-gcc-help {
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
.pay-gcc-help:hover {
|
||||
color: $theme_color;
|
||||
}
|
||||
.pay-gcc-body {
|
||||
min-height: 120px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
.pay-gcc-panel {
|
||||
position: relative;
|
||||
}
|
||||
.pay-gcc-grid-wrap {
|
||||
position: relative;
|
||||
min-height: 100px;
|
||||
}
|
||||
.pay-gcc-empty {
|
||||
padding: 24px 0;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
.pay-gcc-cards {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px 18px;
|
||||
}
|
||||
.pay-gcc-item {
|
||||
position: relative;
|
||||
width: 280px;
|
||||
max-width: 100%;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
cursor: pointer;
|
||||
transition: transform 0.15s, box-shadow 0.15s;
|
||||
}
|
||||
.pay-gcc-item:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
.pay-gcc-item-inner {
|
||||
position: relative;
|
||||
min-height: 150px;
|
||||
background: linear-gradient(135deg, #ff9a4a 0%, #ff7729 48%, #e86a1f 100%);
|
||||
}
|
||||
.pay-gcc-pattern {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
opacity: 0.2;
|
||||
pointer-events: none;
|
||||
background-image: repeating-linear-gradient(
|
||||
-32deg,
|
||||
transparent,
|
||||
transparent 5px,
|
||||
rgba(255, 255, 255, 0.45) 5px,
|
||||
rgba(255, 255, 255, 0.45) 6px
|
||||
);
|
||||
}
|
||||
.pay-gcc-item-main {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 14px 14px 12px;
|
||||
color: #fff;
|
||||
}
|
||||
.pay-gcc-top-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
}
|
||||
.pay-gcc-name {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.pay-gcc-face {
|
||||
margin-top: 6px;
|
||||
font-size: 12px;
|
||||
opacity: 0.92;
|
||||
}
|
||||
.pay-gcc-right-meta {
|
||||
text-align: right;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pay-gcc-type {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.pay-gcc-valid {
|
||||
margin-top: 6px;
|
||||
font-size: 11px;
|
||||
opacity: 0.9;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.pay-gcc-balance-row {
|
||||
margin-top: 14px;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 6px;
|
||||
}
|
||||
.pay-gcc-amt {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
.pay-gcc-bal-label {
|
||||
font-size: 13px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.pay-gcc-no {
|
||||
margin-top: 10px;
|
||||
font-size: 11px;
|
||||
opacity: 0.75;
|
||||
word-break: break-all;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.pay-gcc-corner {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
.pay-gcc-corner::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: -22px;
|
||||
bottom: -22px;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
background: #e54d42;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.pay-gcc-corner .ivu-icon {
|
||||
position: absolute;
|
||||
right: 3px;
|
||||
bottom: 3px;
|
||||
color: #fff;
|
||||
font-size: 15px;
|
||||
z-index: 1;
|
||||
}
|
||||
.pay-gcc-notice-p {
|
||||
line-height: 1.75;
|
||||
color: #515a6e;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.pay-gcc-notice-foot {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
theme="light"
|
||||
width="auto"
|
||||
:active-name="$route.name"
|
||||
:open-names="['订单中心', '会员中心', '账户中心']"
|
||||
:open-names="['订单中心', '会员中心']"
|
||||
@on-select="onSelect"
|
||||
>
|
||||
<div class="user-icon">
|
||||
|
||||
@@ -81,27 +81,25 @@ const member = [{
|
||||
icon: '',
|
||||
title: '我的等级',
|
||||
path: 'MemberGrade'
|
||||
}
|
||||
],
|
||||
display: true
|
||||
}];
|
||||
|
||||
// 账户中心
|
||||
const user = [{
|
||||
icon: '',
|
||||
title: '账户中心',
|
||||
menus: [{
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
title: '我的优惠券',
|
||||
path: 'Coupons'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
title: '资金管理',
|
||||
title: '我的余额',
|
||||
path: 'MoneyManagement'
|
||||
}],
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
title: '我的礼品卡',
|
||||
path: 'MyGiftCards'
|
||||
}
|
||||
],
|
||||
display: true
|
||||
}]
|
||||
}];
|
||||
|
||||
// 活动中心
|
||||
// const activity = [{
|
||||
@@ -171,6 +169,6 @@ const user = [{
|
||||
// ]
|
||||
// wholesale[0], shop[0]
|
||||
let menuList = []
|
||||
menuList.push(order[0], member[0], user[0])
|
||||
menuList.push(order[0], member[0])
|
||||
|
||||
export default menuList
|
||||
|
||||
@@ -76,15 +76,16 @@ const MsgDetail = (resolve) =>
|
||||
require(["@/pages/home/memberCenter/memberMsg/MsgDetail"], resolve);
|
||||
|
||||
/*
|
||||
* 会员中心
|
||||
* 账户中心
|
||||
* */
|
||||
* 会员中心(我的优惠券、我的余额等)
|
||||
*/
|
||||
const Coupons = (resolve) =>
|
||||
require(["@/pages/home/userCenter/Coupons"], resolve);
|
||||
const MyTracks = (resolve) =>
|
||||
require(["@/pages/home/userCenter/MyTracks"], resolve);
|
||||
const MoneyManagement = (resolve) =>
|
||||
require(["@/pages/home/userCenter/MoneyManagement"], resolve);
|
||||
const MyGiftCards = (resolve) =>
|
||||
require(["@/pages/home/userCenter/MyGiftCards"], resolve);
|
||||
|
||||
const Home = (resolve) => require(["@/pages/user/Home"], resolve);
|
||||
|
||||
@@ -261,6 +262,13 @@ export default new Router({
|
||||
path: "MoneyManagement",
|
||||
name: "MoneyManagement",
|
||||
component: MoneyManagement,
|
||||
meta: { title: "我的余额" },
|
||||
},
|
||||
{
|
||||
path: "MyGiftCards",
|
||||
name: "MyGiftCards",
|
||||
component: MyGiftCards,
|
||||
meta: { title: "我的礼品卡" },
|
||||
},
|
||||
{
|
||||
path: "Complain",
|
||||
@@ -271,6 +279,7 @@ export default new Router({
|
||||
path: "Coupons",
|
||||
name: "Coupons",
|
||||
component: Coupons,
|
||||
meta: { title: "我的优惠券" },
|
||||
},
|
||||
{
|
||||
path: "CommentList",
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
"style-resources-loader": "^1.3.2",
|
||||
"uglifyjs-webpack-plugin": "^2.2.0",
|
||||
"vue-cli-plugin-style-resources-loader": "^0.1.4",
|
||||
"vue-template-compiler": "^2.6.10"
|
||||
"vue-template-compiler": "2.6.14"
|
||||
},
|
||||
"resolutions": {
|
||||
"minimatch": "^3.1.2",
|
||||
|
||||
@@ -3,7 +3,8 @@ import {
|
||||
getRequest,
|
||||
postRequest,
|
||||
putRequest,
|
||||
deleteRequest
|
||||
deleteRequest,
|
||||
importRequest
|
||||
} from "@/libs/axios";
|
||||
|
||||
// 获取秒杀活动申请列表
|
||||
@@ -280,4 +281,72 @@ export const deletePointsGoodsCategoryById = id => {
|
||||
// 获取优惠券领取记录
|
||||
export const getCouponReceiveList = (params) => {
|
||||
return getRequest("/promotion/coupon/received", params);
|
||||
};
|
||||
|
||||
// 现金礼品卡活动分页
|
||||
export const getGiftCardCashActivityPage = (params) => {
|
||||
return getRequest("/promotion/giftCardCash/activity", params);
|
||||
};
|
||||
|
||||
// 新建礼品卡活动
|
||||
export const saveGiftCardCashActivity = (params) => {
|
||||
return postRequest("/promotion/giftCardCash/activity", params, {
|
||||
"Content-type": "application/json",
|
||||
});
|
||||
};
|
||||
|
||||
// 礼品卡活动详情
|
||||
export const getGiftCardCashActivity = (id) => {
|
||||
return getRequest(`/promotion/giftCardCash/activity/${id}`);
|
||||
};
|
||||
|
||||
// 更新礼品卡活动
|
||||
export const updateGiftCardCashActivity = (id, params) => {
|
||||
return putRequest(`/promotion/giftCardCash/activity/${id}`, params, {
|
||||
"Content-type": "application/json",
|
||||
});
|
||||
};
|
||||
|
||||
// 活动下批量制卡
|
||||
export const giftCardCashBatchCreate = (activityId, params) => {
|
||||
return postRequest(
|
||||
`/promotion/giftCardCash/activity/${activityId}/batchCreate`,
|
||||
params,
|
||||
{
|
||||
"Content-type": "application/json",
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// 下载批量发卡 Excel 模板
|
||||
export const downloadGiftCardCashIssueTemplate = () => {
|
||||
return getRequest("/promotion/giftCardCash/issue/template", {}, "blob");
|
||||
};
|
||||
|
||||
// 按活动上传 Excel 批量发卡(multipart:file)
|
||||
export const giftCardCashIssueImportByActivity = (activityId, formData) => {
|
||||
return importRequest(
|
||||
`/promotion/giftCardCash/activity/${activityId}/issueImport`,
|
||||
formData
|
||||
);
|
||||
};
|
||||
|
||||
// 制卡批次分页
|
||||
export const getGiftCardCashCreateBatchPage = (params) => {
|
||||
return getRequest("/promotion/giftCardCash/createBatch", params);
|
||||
};
|
||||
|
||||
// 发卡/发送记录分页
|
||||
export const getGiftCardCashIssueBatchPage = (params) => {
|
||||
return getRequest("/promotion/giftCardCash/issueBatch", params);
|
||||
};
|
||||
|
||||
// 礼品卡使用记录分页
|
||||
export const getGiftCardCashUsageRecordPage = (params) => {
|
||||
return getRequest("/promotion/giftCardCash/usageRecord", params);
|
||||
};
|
||||
|
||||
// 卡密凭证分页(平台库存+会员资产)
|
||||
export const getGiftCardCashCredentialPage = (params) => {
|
||||
return getRequest("/promotion/giftCardCash/credential", params);
|
||||
};
|
||||
@@ -224,6 +224,41 @@ export const otherRouter = {
|
||||
name: "manager-coupon",
|
||||
component: () => import("@/views/promotions/coupon/coupon.vue")
|
||||
},
|
||||
{
|
||||
path: "promotions/gift-card-cash",
|
||||
title: "礼品卡",
|
||||
name: "manager-gift-card-cash",
|
||||
component: () =>
|
||||
import("@/views/promotions/gift-card-cash/gift-card-cash-activity.vue")
|
||||
},
|
||||
{
|
||||
path: "promotions/add-gift-card-cash-activity",
|
||||
title: "添加礼品卡",
|
||||
name: "add-gift-card-cash-activity",
|
||||
component: () =>
|
||||
import("@/views/promotions/gift-card-cash/gift-card-cash-activity-add.vue")
|
||||
},
|
||||
{
|
||||
path: "promotions/edit-gift-card-cash-activity",
|
||||
title: "编辑礼品卡",
|
||||
name: "edit-gift-card-cash-activity",
|
||||
component: () =>
|
||||
import("@/views/promotions/gift-card-cash/gift-card-cash-activity-add.vue")
|
||||
},
|
||||
{
|
||||
path: "promotions/gift-card-cash-records",
|
||||
title: "礼品卡记录",
|
||||
name: "gift-card-cash-records",
|
||||
component: () =>
|
||||
import("@/views/promotions/gift-card-cash/gift-card-cash-records.vue")
|
||||
},
|
||||
{
|
||||
path: "promotions/gift-card-cash-batch-credentials",
|
||||
title: "制卡批次卡密",
|
||||
name: "gift-card-cash-batch-credentials",
|
||||
component: () =>
|
||||
import("@/views/promotions/gift-card-cash/gift-card-cash-batch-credentials.vue")
|
||||
},
|
||||
{
|
||||
path: "promotions/coupon-receive",
|
||||
title: "优惠券领取记录",
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input type="text" v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="审核状态" prop="applyStatus">
|
||||
<Form-item label="提现状态" prop="applyStatus">
|
||||
<Select v-model="searchForm.applyStatus" clearable style="width: 240px">
|
||||
<Option value="APPLY">申请中</Option>
|
||||
<Option value="VIA_AUDITING">审核通过</Option>
|
||||
<Option value="WAIT_USER_CONFIRM">用户确认</Option>
|
||||
<Option value="FAIL_AUDITING">审核拒绝</Option>
|
||||
<Option value="SUCCESS">提现成功</Option>
|
||||
<Option value="ERROR">提现失败</Option>
|
||||
@@ -165,6 +166,8 @@ export default {
|
||||
return h("Tag", { props: { color: "volcano" } }, "申请中");
|
||||
} else if (params.row.applyStatus == "VIA_AUDITING") {
|
||||
return h("Tag", { props: { color: "green" } }, "审核通过");
|
||||
} else if (params.row.applyStatus == "WAIT_USER_CONFIRM") {
|
||||
return h("Tag", { props: { color: "gold" } }, "用户确认");
|
||||
} else if (params.row.applyStatus == "SUCCESS") {
|
||||
return h("Tag", { props: { color: "blue" } }, "提现成功");
|
||||
} else if (params.row.applyStatus == "ERROR") {
|
||||
@@ -251,8 +254,12 @@ export default {
|
||||
return "申请中";
|
||||
} else if (val === "VIA_AUDITING") {
|
||||
return "审核通过(提现成功)";
|
||||
} else if (val === "WAIT_USER_CONFIRM") {
|
||||
return "用户确认";
|
||||
} else if (val === "FAIL_AUDITING") {
|
||||
return "审核拒绝";
|
||||
} else if (val === "SUCCESS") {
|
||||
return "提现成功";
|
||||
} else if (val === "ERROR") {
|
||||
return "提现失败";
|
||||
} else {
|
||||
@@ -270,14 +277,22 @@ export default {
|
||||
this.$Message.error("审核备注不能为空");
|
||||
return;
|
||||
}
|
||||
withdrawApply(params).then((res) => {
|
||||
this.loading = false;
|
||||
if (res == true) {
|
||||
this.$Message.success("操作成功");
|
||||
this.roleModalVisible = false;
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
this.submitLoading = true;
|
||||
withdrawApply(params)
|
||||
.then((result) => {
|
||||
const success = result === true || (result && result.success === true);
|
||||
if (success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.roleModalVisible = false;
|
||||
this.queryModalVisible = false;
|
||||
this.audit = "";
|
||||
this.showList = {};
|
||||
this.getDataList();
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.submitLoading = false;
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
|
||||
@@ -288,7 +288,9 @@ export default {
|
||||
key: "paymentMethod",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.paymentMethod == "WECHAT") {
|
||||
if (params.row.paymentMethod == "NOT_ACTUALLY_PAID") {
|
||||
return h("div", {}, "-");
|
||||
} else if (params.row.paymentMethod == "WECHAT") {
|
||||
return h("div", {}, "微信支付");
|
||||
} else if (params.row.paymentMethod == "ALIPAY") {
|
||||
return h("div", {}, "支付宝");
|
||||
|
||||
@@ -0,0 +1,401 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card :loading="detailLoading">
|
||||
<Form ref="form" :model="form" :label-width="130" :rules="onlyView ? {} : formRule">
|
||||
<div class="base-info-item">
|
||||
<h4>{{ pageTitle }}</h4>
|
||||
<div class="form-item-view gift-card-activity-form">
|
||||
<FormItem label="礼品卡名称" prop="giftCardName">
|
||||
<Input
|
||||
v-model="form.giftCardName"
|
||||
type="text"
|
||||
placeholder="请输入礼品卡名称"
|
||||
clearable
|
||||
maxlength="64"
|
||||
show-word-limit
|
||||
style="width: 360px"
|
||||
:disabled="onlyView"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="礼品卡类型" prop="cardType" class="gift-card-type-form-item">
|
||||
<RadioGroup v-model="form.cardType" class="gift-card-type-group">
|
||||
<Radio label="CASH" :disabled="onlyView">现金卡</Radio>
|
||||
<Radio label="PICKUP" disabled>提货卡</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem label="面值" prop="faceValue">
|
||||
<Input
|
||||
v-model="form.faceValue"
|
||||
type="text"
|
||||
placeholder="面值"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
:disabled="onlyView"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="总库存" prop="stockTotal">
|
||||
<InputNumber
|
||||
v-model="form.stockTotal"
|
||||
:min="1"
|
||||
:precision="0"
|
||||
placeholder="最多可制发凭证张数"
|
||||
style="width: 200px"
|
||||
:disabled="onlyView"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem prop="validityType" :label-width="0" class="gift-card-validity-form-item">
|
||||
<div class="gift-card-validity-outer">
|
||||
<div class="gift-card-validity-label-col">
|
||||
<span v-if="!onlyView" class="gift-card-validity-required">*</span>
|
||||
<span>有效期</span>
|
||||
</div>
|
||||
<div class="gift-card-validity-radios">
|
||||
<RadioGroup v-model="form.validityType" vertical class="gift-card-validity-group">
|
||||
<Radio label="LONG_TERM" class="gift-card-validity-row" :disabled="onlyView"
|
||||
>长期有效</Radio
|
||||
>
|
||||
<Radio label="AFTER_ACTIVATE_MONTHS" class="gift-card-validity-row" :disabled="onlyView">
|
||||
<span>自激活后</span>
|
||||
<InputNumber
|
||||
v-model="form.validMonthsAfterActivate"
|
||||
:min="1"
|
||||
:max="99"
|
||||
:precision="0"
|
||||
placeholder="请输入1-99的整数"
|
||||
:disabled="onlyView || form.validityType !== 'AFTER_ACTIVATE_MONTHS'"
|
||||
class="gift-card-validity-input-gap"
|
||||
/>
|
||||
<span>月内有效</span>
|
||||
</Radio>
|
||||
<Radio label="FIXED_UNTIL" class="gift-card-validity-row" :disabled="onlyView">
|
||||
<span>指定有效期至</span>
|
||||
<DatePicker
|
||||
v-model="form.validEndTime"
|
||||
type="datetime"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
placeholder="选择结束时间"
|
||||
clearable
|
||||
transfer
|
||||
:disabled="onlyView || form.validityType !== 'FIXED_UNTIL'"
|
||||
class="gift-card-validity-date-gap"
|
||||
style="width: 220px"
|
||||
/>
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
</div>
|
||||
</FormItem>
|
||||
</div>
|
||||
<div class="foot-btn">
|
||||
<Button style="margin-right: 8px" @click="closeCurrentPage">返回</Button>
|
||||
<Button
|
||||
v-if="!onlyView"
|
||||
type="primary"
|
||||
:loading="submitLoading"
|
||||
@click="handleSubmit"
|
||||
>提交</Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
saveGiftCardCashActivity,
|
||||
getGiftCardCashActivity,
|
||||
updateGiftCardCashActivity,
|
||||
} from "@/api/promotion";
|
||||
import { regular } from "@/utils";
|
||||
|
||||
export default {
|
||||
name: "addGiftCardCashActivity",
|
||||
data() {
|
||||
const checkFaceValue = (rule, value, callback) => {
|
||||
if (!value && value !== 0) {
|
||||
return callback(new Error("面额不能为空"));
|
||||
}
|
||||
if (!regular.money.test(value)) {
|
||||
callback(new Error("请输入正整数或者两位小数"));
|
||||
} else if (parseFloat(value) > 99999999) {
|
||||
callback(new Error("面额设置超过上限值"));
|
||||
} else if (parseFloat(value) < 0.01) {
|
||||
callback(new Error("面值必须大于 0"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
const validateStock = (rule, value, callback) => {
|
||||
if (value === null || value === undefined || value === "") {
|
||||
callback(new Error("请填写总库存"));
|
||||
return;
|
||||
}
|
||||
if (Number(value) < 1) {
|
||||
callback(new Error("活动库存至少为 1"));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
};
|
||||
return {
|
||||
detailLoading: false,
|
||||
submitLoading: false,
|
||||
form: {
|
||||
giftCardName: "",
|
||||
cardType: "CASH",
|
||||
faceValue: "",
|
||||
stockTotal: null,
|
||||
validityType: "LONG_TERM",
|
||||
validEndTime: null,
|
||||
validMonthsAfterActivate: null,
|
||||
},
|
||||
formRule: {
|
||||
giftCardName: [
|
||||
{ required: true, message: "活动名称不能为空", trigger: "blur" },
|
||||
{ type: "string", max: 64, message: "活动名称过长", trigger: "blur" },
|
||||
],
|
||||
faceValue: [{ required: true, message: "请输入面额" }, { validator: checkFaceValue }],
|
||||
stockTotal: [{ required: true, validator: validateStock, trigger: "blur" }],
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
onlyView() {
|
||||
const q = this.$route.query.onlyView;
|
||||
return q === "true" || q === true;
|
||||
},
|
||||
isEditMode() {
|
||||
return !!this.$route.query.id && !this.onlyView;
|
||||
},
|
||||
pageTitle() {
|
||||
if (this.onlyView) {
|
||||
return "查看礼品卡";
|
||||
}
|
||||
if (this.isEditMode) {
|
||||
return "编辑礼品卡";
|
||||
}
|
||||
return "添加礼品卡";
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (this.$route.query.id) {
|
||||
this.loadDetail(this.$route.query.id);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
"form.validityType"(v) {
|
||||
if (v !== "FIXED_UNTIL") {
|
||||
this.form.validEndTime = null;
|
||||
}
|
||||
if (v !== "AFTER_ACTIVATE_MONTHS") {
|
||||
this.form.validMonthsAfterActivate = null;
|
||||
}
|
||||
},
|
||||
"$route.query.id"(id) {
|
||||
if (id) {
|
||||
this.loadDetail(id);
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
parseDetailDate(val) {
|
||||
if (!val) {
|
||||
return null;
|
||||
}
|
||||
if (val instanceof Date) {
|
||||
return val;
|
||||
}
|
||||
const d = new Date(val);
|
||||
return Number.isNaN(d.getTime()) ? null : d;
|
||||
},
|
||||
loadDetail(id) {
|
||||
this.detailLoading = true;
|
||||
getGiftCardCashActivity(id)
|
||||
.then((res) => {
|
||||
this.detailLoading = false;
|
||||
if (!res.success || !res.result) {
|
||||
return;
|
||||
}
|
||||
const d = res.result;
|
||||
this.form.giftCardName = d.giftCardName || "";
|
||||
this.form.cardType = d.cardType || "CASH";
|
||||
this.form.faceValue =
|
||||
d.faceValue !== null && d.faceValue !== undefined ? String(d.faceValue) : "";
|
||||
this.form.stockTotal =
|
||||
d.stockTotal !== null && d.stockTotal !== undefined ? d.stockTotal : null;
|
||||
this.form.validityType = d.validityType || "LONG_TERM";
|
||||
this.form.validEndTime = this.parseDetailDate(d.validEndTime);
|
||||
this.form.validMonthsAfterActivate =
|
||||
d.validMonthsAfterActivate !== null &&
|
||||
d.validMonthsAfterActivate !== undefined &&
|
||||
d.validMonthsAfterActivate !== ""
|
||||
? d.validMonthsAfterActivate
|
||||
: null;
|
||||
})
|
||||
.catch(() => {
|
||||
this.detailLoading = false;
|
||||
});
|
||||
},
|
||||
closeCurrentPage() {
|
||||
const name = this.$route.name;
|
||||
if (name) {
|
||||
this.$store.commit("removeTag", name);
|
||||
}
|
||||
localStorage.pageOpenedList = JSON.stringify(this.$store.state.app.pageOpenedList);
|
||||
this.$router.go(-1);
|
||||
},
|
||||
validateByValidityType() {
|
||||
const t = this.form.validityType;
|
||||
if (t === "FIXED_UNTIL") {
|
||||
if (!this.form.validEndTime) {
|
||||
this.$Message.warning("请选择结束时间");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (t === "AFTER_ACTIVATE_MONTHS") {
|
||||
const m = this.form.validMonthsAfterActivate;
|
||||
if (m === null || m === undefined || m === "" || Number(m) < 1 || Number(m) > 99) {
|
||||
this.$Message.warning("请输入1-99的整数");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
buildPayload() {
|
||||
const payload = {
|
||||
giftCardName: (this.form.giftCardName || "").trim(),
|
||||
cardType: this.form.cardType || "CASH",
|
||||
faceValue: parseFloat(this.form.faceValue),
|
||||
validityType: this.form.validityType || "LONG_TERM",
|
||||
stockTotal: this.form.stockTotal,
|
||||
};
|
||||
if (payload.validityType === "FIXED_UNTIL") {
|
||||
payload.validEndTime = this.form.validEndTime;
|
||||
}
|
||||
if (payload.validityType === "AFTER_ACTIVATE_MONTHS") {
|
||||
payload.validMonthsAfterActivate = this.form.validMonthsAfterActivate;
|
||||
}
|
||||
return payload;
|
||||
},
|
||||
handleSubmit() {
|
||||
if (this.onlyView) {
|
||||
return;
|
||||
}
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
if (!this.validateByValidityType()) {
|
||||
return;
|
||||
}
|
||||
this.submitLoading = true;
|
||||
const req = this.isEditMode
|
||||
? updateGiftCardCashActivity(this.$route.query.id, this.buildPayload())
|
||||
: saveGiftCardCashActivity(this.buildPayload());
|
||||
req
|
||||
.then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success(
|
||||
this.isEditMode ? "礼品卡活动已更新" : "礼品卡活动创建成功"
|
||||
);
|
||||
this.closeCurrentPage();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.submitLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.gift-card-activity-form >>> .ivu-form-item {
|
||||
margin-bottom: 26px;
|
||||
}
|
||||
.gift-card-type-form-item >>> .ivu-form-item-label {
|
||||
line-height: 32px;
|
||||
padding-top: 1px;
|
||||
}
|
||||
.gift-card-type-form-item >>> .ivu-form-item-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 32px;
|
||||
}
|
||||
.gift-card-type-group >>> .ivu-radio-wrapper {
|
||||
margin-right: 32px;
|
||||
line-height: 32px;
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.gift-card-validity-form-item >>> .ivu-form-item-content {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.gift-card-validity-outer {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
}
|
||||
.gift-card-validity-label-col {
|
||||
flex: 0 0 130px;
|
||||
width: 130px;
|
||||
padding-right: 12px;
|
||||
box-sizing: border-box;
|
||||
text-align: right;
|
||||
line-height: 32px;
|
||||
min-height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding-top: 1px;
|
||||
}
|
||||
.gift-card-validity-required {
|
||||
color: #ed4014;
|
||||
margin-right: 4px;
|
||||
font-family: SimSun, serif;
|
||||
}
|
||||
.gift-card-validity-radios {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding-top: 1px;
|
||||
}
|
||||
.gift-card-validity-group {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.gift-card-type-group >>> .ivu-radio {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
}
|
||||
.gift-card-validity-group >>> .ivu-radio {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
}
|
||||
.gift-card-validity-group >>> .ivu-radio-wrapper:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.gift-card-validity-group >>> .ivu-radio-wrapper {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
line-height: 32px;
|
||||
min-height: 32px;
|
||||
}
|
||||
.gift-card-validity-group >>> .ivu-radio-wrapper:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.gift-card-validity-input-gap {
|
||||
width: 168px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
.gift-card-validity-date-gap {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,712 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="80"
|
||||
class="search-form mb_10"
|
||||
>
|
||||
<Form-item label="礼品卡名称" prop="giftCardName">
|
||||
<Input
|
||||
v-model="searchForm.giftCardName"
|
||||
type="text"
|
||||
placeholder="模糊搜索礼品卡名称"
|
||||
clearable
|
||||
style="width: 260px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Button type="primary" icon="ios-search" class="search-btn" @click="handleSearch"
|
||||
>搜索</Button
|
||||
>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button type="primary" @click="addActivity">添加礼品卡</Button>
|
||||
</Row>
|
||||
<Table :loading="loading" :columns="columns" :data="data" ref="table">
|
||||
<template slot-scope="{ row }" slot="action">
|
||||
<template v-if="canEdit(row)">
|
||||
<a :style="linkStyle" @click.prevent="goEdit(row)">编辑</a>
|
||||
<span :style="sepStyle">|</span>
|
||||
</template>
|
||||
<a :style="linkStyle" @click.prevent="goView(row)">查看</a>
|
||||
<template v-if="canBatchCreate(row)">
|
||||
<span :style="sepStyle">|</span>
|
||||
<a :style="linkStyle" @click.prevent="openBatchCreate(row)">批量制卡</a>
|
||||
</template>
|
||||
<template v-if="canBatchIssue(row)">
|
||||
<span :style="sepStyle">|</span>
|
||||
<a :style="linkStyle" @click.prevent="openBatchIssue(row)">批量发卡</a>
|
||||
</template>
|
||||
<span :style="sepStyle">|</span>
|
||||
<a :style="linkStyle" @click.prevent="goRecords(row)">查看记录</a>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
/>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal
|
||||
v-model="batchCreateVisible"
|
||||
title="批量制卡"
|
||||
:mask-closable="false"
|
||||
width="520"
|
||||
@on-visible-change="onBatchCreateVisible"
|
||||
>
|
||||
<Form ref="batchForm" :model="batchForm" :rules="batchFormRule" :label-width="100">
|
||||
<FormItem label="礼品卡名称">
|
||||
<span>{{ batchCtx.giftCardName || "-" }}</span>
|
||||
</FormItem>
|
||||
<FormItem label="面值">
|
||||
<template v-if="batchCtx.faceValue != null && batchCtx.faceValue !== ''">
|
||||
<priceColorScheme
|
||||
:value="batchCtx.faceValue"
|
||||
:color="$mainColor"
|
||||
></priceColorScheme>
|
||||
</template>
|
||||
<span v-else>-</span>
|
||||
</FormItem>
|
||||
<FormItem label="当前库存">
|
||||
<span>{{ fmtInt(batchCtx.headroom) }}</span>
|
||||
</FormItem>
|
||||
<FormItem label="制卡张数" prop="quantity">
|
||||
<InputNumber
|
||||
v-model="batchForm.quantity"
|
||||
:min="1"
|
||||
:max="batchQuantityMax"
|
||||
:precision="0"
|
||||
placeholder="请输入制卡张数"
|
||||
style="width: 220px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="本批备注" prop="batchRemark">
|
||||
<Input
|
||||
v-model="batchForm.batchRemark"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
maxlength="64"
|
||||
show-word-limit
|
||||
placeholder="选填,最多64字"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button @click="batchCreateVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="batchCreateSubmitting" @click="submitBatchCreate"
|
||||
>确定</Button
|
||||
>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal
|
||||
v-model="batchIssueVisible"
|
||||
title="批量发卡"
|
||||
:mask-closable="false"
|
||||
width="560"
|
||||
@on-visible-change="onBatchIssueVisible"
|
||||
>
|
||||
<div class="gcc-batch-issue-body">
|
||||
<Form :label-width="100">
|
||||
<FormItem label="礼品卡名称">
|
||||
<span>{{ issueCtx.giftCardName || "-" }}</span>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<Alert type="info" show-icon class="mb_10">
|
||||
请先下载模板,按列填写<strong>手机号</strong>、<strong>发卡数量</strong>后上传;发卡不区分制卡批次。
|
||||
</Alert>
|
||||
<div class="gcc-batch-issue-actions">
|
||||
<Button
|
||||
type="primary"
|
||||
ghost
|
||||
icon="md-download"
|
||||
:loading="issueTemplateDownloading"
|
||||
@click="downloadIssueTemplate"
|
||||
>
|
||||
下载 Excel 模板
|
||||
</Button>
|
||||
</div>
|
||||
<div class="gcc-batch-issue-upload">
|
||||
<span class="gcc-batch-issue-upload-label">上传已填写的 Excel</span>
|
||||
<Upload
|
||||
:before-upload="onIssueImportBeforeUpload"
|
||||
accept=".xls,.xlsx,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
:show-upload-list="false"
|
||||
>
|
||||
<Button type="dashed" icon="ios-cloud-upload-outline">选择文件</Button>
|
||||
</Upload>
|
||||
<span v-if="issueFileName" class="gcc-batch-issue-filename">{{ issueFileName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<Button @click="batchIssueVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="issueImportSubmitting" @click="submitIssueImport"
|
||||
>开始发卡</Button
|
||||
>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getGiftCardCashActivityPage,
|
||||
giftCardCashBatchCreate,
|
||||
downloadGiftCardCashIssueTemplate,
|
||||
giftCardCashIssueImportByActivity,
|
||||
} from "@/api/promotion";
|
||||
|
||||
export default {
|
||||
name: "GiftCardCashActivity",
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
giftCardName: "",
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "礼品卡名称",
|
||||
key: "giftCardName",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "礼品卡类型",
|
||||
key: "cardType",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
const t = params.row.cardType;
|
||||
const map = { CASH: "现金卡", PICKUP: "提货卡" };
|
||||
return h("span", map[t] || t || "-");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "面值",
|
||||
key: "faceValue",
|
||||
width: 200,
|
||||
align: "right",
|
||||
render: (h, params) => {
|
||||
const v = params.row.faceValue;
|
||||
if (v === null || v === undefined || v === "") {
|
||||
return h("span", "-");
|
||||
}
|
||||
return h("priceColorScheme", {
|
||||
props: { value: v, color: this.$mainColor },
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "有效期",
|
||||
key: "validityType",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("span", this.formatValidity(params.row));
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "总库存",
|
||||
key: "stockTotal",
|
||||
width: 200,
|
||||
align: "center",
|
||||
render: (h, params) =>
|
||||
h("span", this.fmtInt(params.row.stockTotal)),
|
||||
},
|
||||
{
|
||||
title: "批量制卡数",
|
||||
key: "producedQuantity",
|
||||
width: 200,
|
||||
align: "center",
|
||||
render: (h, params) =>
|
||||
h("span", this.fmtInt(params.row.producedQuantity)),
|
||||
},
|
||||
{
|
||||
title: "批量发卡数",
|
||||
key: "issuedCardQuantity",
|
||||
width: 200,
|
||||
align: "center",
|
||||
render: (h, params) =>
|
||||
h("span", this.fmtInt(params.row.issuedCardQuantity)),
|
||||
},
|
||||
{
|
||||
title: "剩余库存",
|
||||
key: "remainingStock",
|
||||
width: 200,
|
||||
align: "center",
|
||||
render: (h, params) =>
|
||||
h("span", this.fmtInt(params.row.remainingStock)),
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "status",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
if (this.isFixedValidityExpired(params.row)) {
|
||||
return h("div", [
|
||||
h(
|
||||
"Tag",
|
||||
{
|
||||
props: { color: "red" },
|
||||
},
|
||||
"已过期"
|
||||
),
|
||||
]);
|
||||
}
|
||||
return h("div", [
|
||||
h(
|
||||
"Tag",
|
||||
{
|
||||
props: { color: "green" },
|
||||
},
|
||||
"正常"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
key: "createTime",
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slot: "action",
|
||||
align: "right",
|
||||
width: 380,
|
||||
},
|
||||
],
|
||||
data: [],
|
||||
total: 0,
|
||||
linkStyle: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
disabledLinkStyle: {
|
||||
color: "#c5c8ce",
|
||||
cursor: "not-allowed",
|
||||
},
|
||||
sepStyle: { margin: "0 8px", color: "#dcdee2" },
|
||||
batchCreateVisible: false,
|
||||
batchCreateSubmitting: false,
|
||||
batchCtx: {
|
||||
id: "",
|
||||
giftCardName: "",
|
||||
faceValue: null,
|
||||
remainingStock: null,
|
||||
headroom: null,
|
||||
},
|
||||
batchForm: {
|
||||
quantity: null,
|
||||
batchRemark: "",
|
||||
},
|
||||
batchFormRule: {},
|
||||
batchIssueVisible: false,
|
||||
issueTemplateDownloading: false,
|
||||
issueImportSubmitting: false,
|
||||
issueCtx: {
|
||||
id: "",
|
||||
giftCardName: "",
|
||||
},
|
||||
issueFile: null,
|
||||
issueFileName: "",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
batchQuantityMax() {
|
||||
const cap = 10000;
|
||||
const h = this.batchCtx.headroom;
|
||||
if (h !== null && h !== undefined && h !== "" && Number(h) >= 1) {
|
||||
return Math.min(cap, Number(h));
|
||||
}
|
||||
return cap;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.batchFormRule = {
|
||||
quantity: [{ validator: this.validateBatchQuantity, trigger: "change" }],
|
||||
batchRemark: [{ type: "string", max: 64, message: "备注过长", trigger: "blur" }],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getDataList();
|
||||
},
|
||||
methods: {
|
||||
validateBatchQuantity(rule, value, callback) {
|
||||
if (value === null || value === undefined || value === "") {
|
||||
callback(new Error("请填写制卡张数"));
|
||||
return;
|
||||
}
|
||||
const n = Number(value);
|
||||
if (Number.isNaN(n) || n < 1) {
|
||||
callback(new Error("制卡张数至少为 1"));
|
||||
return;
|
||||
}
|
||||
const maxQ = this.batchQuantityMax;
|
||||
if (n > maxQ) {
|
||||
callback(new Error(`制卡张数不能超过 ${maxQ}(可制卡上限与单次上限)`));
|
||||
return;
|
||||
}
|
||||
if (n > 10000) {
|
||||
callback(new Error("单次制卡不超过 10000 张"));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
},
|
||||
fmtInt(n) {
|
||||
if (n === null || n === undefined || n === "") {
|
||||
return "-";
|
||||
}
|
||||
return n;
|
||||
},
|
||||
/** 固定到期类有效期且到期时间早于当前时间,列表状态展示为「已过期」 */
|
||||
isFixedValidityExpired(row) {
|
||||
if (!row || !row.validityType || row.validEndTime == null || row.validEndTime === "") {
|
||||
return false;
|
||||
}
|
||||
const type = String(row.validityType).toUpperCase();
|
||||
const fixedEndTypes = [
|
||||
"FIXED_UNTIL",
|
||||
"FIXED_END",
|
||||
"FIXED",
|
||||
"BY_END_TIME",
|
||||
"FIXED_DATE",
|
||||
];
|
||||
if (!fixedEndTypes.includes(type)) {
|
||||
return false;
|
||||
}
|
||||
const end = new Date(row.validEndTime);
|
||||
if (Number.isNaN(end.getTime())) {
|
||||
return false;
|
||||
}
|
||||
return end.getTime() < Date.now();
|
||||
},
|
||||
formatValidity(row) {
|
||||
if (!row || !row.validityType) {
|
||||
return "-";
|
||||
}
|
||||
const type = String(row.validityType).toUpperCase();
|
||||
if (type === "LONG_TERM") {
|
||||
return "长期有效";
|
||||
}
|
||||
if (type === "FIXED_UNTIL") {
|
||||
return row.validEndTime ? String(row.validEndTime) : "固定到期";
|
||||
}
|
||||
if (type === "AFTER_ACTIVATE_MONTHS") {
|
||||
const m = row.validMonthsAfterActivate;
|
||||
return m != null && m !== "" ? `激活后${m}个月有效` : "激活后按月";
|
||||
}
|
||||
if (
|
||||
type === "FIXED_END" ||
|
||||
type === "FIXED" ||
|
||||
type === "BY_END_TIME" ||
|
||||
type === "FIXED_DATE"
|
||||
) {
|
||||
return row.validEndTime ? String(row.validEndTime) : type;
|
||||
}
|
||||
if (
|
||||
type === "AFTER_ACTIVATE" ||
|
||||
type === "MONTHS_AFTER_ACTIVATE" ||
|
||||
type === "RELATIVE"
|
||||
) {
|
||||
const m = row.validMonthsAfterActivate;
|
||||
return m != null && m !== "" ? `激活后${m}个月有效` : type;
|
||||
}
|
||||
const parts = [row.validityType];
|
||||
if (row.validEndTime) {
|
||||
parts.push(String(row.validEndTime));
|
||||
}
|
||||
if (row.validMonthsAfterActivate != null && row.validMonthsAfterActivate !== "") {
|
||||
parts.push(`激活后${row.validMonthsAfterActivate}个月`);
|
||||
}
|
||||
return parts.join(" ");
|
||||
},
|
||||
addActivity() {
|
||||
this.$router.push({ name: "add-gift-card-cash-activity" });
|
||||
},
|
||||
goEdit(row) {
|
||||
if (!this.canEdit(row)) {
|
||||
return;
|
||||
}
|
||||
this.$router.push({
|
||||
name: "edit-gift-card-cash-activity",
|
||||
query: { id: row.id },
|
||||
});
|
||||
},
|
||||
goView(row) {
|
||||
this.$router.push({
|
||||
name: "edit-gift-card-cash-activity",
|
||||
query: { id: row.id, onlyView: "true" },
|
||||
});
|
||||
},
|
||||
goRecords(row) {
|
||||
this.$router.push({
|
||||
name: "gift-card-cash-records",
|
||||
query: {
|
||||
activityId: row.id,
|
||||
giftCardName: row.giftCardName || "",
|
||||
},
|
||||
});
|
||||
},
|
||||
getRemainingStock(row) {
|
||||
if (!row || row.remainingStock === null || row.remainingStock === undefined || row.remainingStock === "") {
|
||||
return 0;
|
||||
}
|
||||
const n = Number(row.remainingStock);
|
||||
if (Number.isNaN(n)) {
|
||||
return 0;
|
||||
}
|
||||
return Math.max(0, Math.floor(n));
|
||||
},
|
||||
hasRemainingStock(row) {
|
||||
return this.getRemainingStock(row) >= 1;
|
||||
},
|
||||
canEdit(row) {
|
||||
return this.hasRemainingStock(row);
|
||||
},
|
||||
/** 本次批量制卡允许的最大张数:以剩余库存为准 */
|
||||
getBatchCreateHeadroom(row) {
|
||||
return this.getRemainingStock(row);
|
||||
},
|
||||
canBatchCreate(row) {
|
||||
return this.hasRemainingStock(row);
|
||||
},
|
||||
/** 可发卡余量:与制卡独立,以剩余库存为准 */
|
||||
getBatchIssuePool(row) {
|
||||
return this.getRemainingStock(row);
|
||||
},
|
||||
canBatchIssue(row) {
|
||||
if (this.isFixedValidityExpired(row)) {
|
||||
return false;
|
||||
}
|
||||
return this.hasRemainingStock(row);
|
||||
},
|
||||
openBatchIssue(row) {
|
||||
if (!this.canBatchIssue(row)) {
|
||||
return;
|
||||
}
|
||||
this.issueCtx = {
|
||||
id: row.id,
|
||||
giftCardName: row.giftCardName,
|
||||
};
|
||||
this.issueFile = null;
|
||||
this.issueFileName = "";
|
||||
this.batchIssueVisible = true;
|
||||
},
|
||||
onBatchIssueVisible(open) {
|
||||
if (!open) {
|
||||
this.issueFile = null;
|
||||
this.issueFileName = "";
|
||||
}
|
||||
},
|
||||
downloadIssueTemplate() {
|
||||
this.issueTemplateDownloading = true;
|
||||
downloadGiftCardCashIssueTemplate()
|
||||
.then((res) => {
|
||||
this.issueTemplateDownloading = false;
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
if (res instanceof Blob && res.type && res.type.indexOf("json") !== -1) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
try {
|
||||
const j = JSON.parse(reader.result);
|
||||
if (j && j.message) {
|
||||
this.$Message.error(j.message);
|
||||
} else {
|
||||
this.$Message.error("模板下载失败");
|
||||
}
|
||||
} catch (e) {
|
||||
this.$Message.error("模板下载失败");
|
||||
}
|
||||
};
|
||||
reader.readAsText(res);
|
||||
return;
|
||||
}
|
||||
const blob =
|
||||
res instanceof Blob
|
||||
? res
|
||||
: new Blob([res], {
|
||||
type:
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8",
|
||||
});
|
||||
const name = "批量发卡模板.xlsx";
|
||||
if ("download" in document.createElement("a")) {
|
||||
const link = document.createElement("a");
|
||||
link.download = name;
|
||||
link.style.display = "none";
|
||||
link.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
URL.revokeObjectURL(link.href);
|
||||
document.body.removeChild(link);
|
||||
} else if (navigator.msSaveBlob) {
|
||||
navigator.msSaveBlob(blob, name);
|
||||
}
|
||||
this.$Message.success("模板已开始下载");
|
||||
})
|
||||
.catch(() => {
|
||||
this.issueTemplateDownloading = false;
|
||||
});
|
||||
},
|
||||
onIssueImportBeforeUpload(file) {
|
||||
this.issueFile = file;
|
||||
this.issueFileName = file.name;
|
||||
return false;
|
||||
},
|
||||
submitIssueImport() {
|
||||
if (!this.issueCtx.id) {
|
||||
return;
|
||||
}
|
||||
if (!this.issueFile) {
|
||||
this.$Message.warning("请先选择要上传的 Excel 文件");
|
||||
return;
|
||||
}
|
||||
const fd = new FormData();
|
||||
fd.append("file", this.issueFile);
|
||||
this.issueImportSubmitting = true;
|
||||
giftCardCashIssueImportByActivity(this.issueCtx.id, fd)
|
||||
.then((res) => {
|
||||
this.issueImportSubmitting = false;
|
||||
if (res && res.success) {
|
||||
this.$Message.success(
|
||||
res.result ? `发卡任务已提交,发卡批次号:${res.result}` : "发卡任务已提交"
|
||||
);
|
||||
this.batchIssueVisible = false;
|
||||
this.issueFile = null;
|
||||
this.issueFileName = "";
|
||||
this.getDataList();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.issueImportSubmitting = false;
|
||||
});
|
||||
},
|
||||
openBatchCreate(row) {
|
||||
if (!this.canBatchCreate(row)) {
|
||||
return;
|
||||
}
|
||||
const headroom = this.getBatchCreateHeadroom(row);
|
||||
this.batchCtx = {
|
||||
id: row.id,
|
||||
giftCardName: row.giftCardName,
|
||||
faceValue: row.faceValue,
|
||||
remainingStock: row.remainingStock,
|
||||
headroom,
|
||||
};
|
||||
this.batchForm.quantity = null;
|
||||
this.batchForm.batchRemark = "";
|
||||
this.batchCreateVisible = true;
|
||||
},
|
||||
onBatchCreateVisible(open) {
|
||||
if (!open && this.$refs.batchForm && typeof this.$refs.batchForm.resetFields === "function") {
|
||||
this.$refs.batchForm.resetFields();
|
||||
}
|
||||
},
|
||||
submitBatchCreate() {
|
||||
if (!this.$refs.batchForm) {
|
||||
return;
|
||||
}
|
||||
this.$refs.batchForm.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
const q = this.batchForm.quantity;
|
||||
const payload = { quantity: q };
|
||||
const remark = (this.batchForm.batchRemark || "").trim();
|
||||
if (remark) {
|
||||
payload.batchRemark = remark;
|
||||
}
|
||||
this.batchCreateSubmitting = true;
|
||||
giftCardCashBatchCreate(this.batchCtx.id, payload)
|
||||
.then((res) => {
|
||||
this.batchCreateSubmitting = false;
|
||||
if (res.success) {
|
||||
this.$Message.success(
|
||||
res.result ? `制卡成功,批次号:${res.result}` : "制卡成功"
|
||||
);
|
||||
this.batchCreateVisible = false;
|
||||
this.getDataList();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.batchCreateSubmitting = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
const params = { ...this.searchForm };
|
||||
if (!params.giftCardName) {
|
||||
delete params.giftCardName;
|
||||
}
|
||||
getGiftCardCashActivityPage(params)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success && res.result) {
|
||||
this.data = res.result.records || [];
|
||||
this.total = res.result.total || 0;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.gcc-batch-issue-body {
|
||||
padding: 0 4px;
|
||||
}
|
||||
.gcc-batch-issue-actions {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.gcc-batch-issue-upload {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.gcc-batch-issue-upload-label {
|
||||
color: #515a6e;
|
||||
font-size: 14px;
|
||||
}
|
||||
.gcc-batch-issue-filename {
|
||||
color: #2d8cf0;
|
||||
font-size: 13px;
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,531 @@
|
||||
<template>
|
||||
<div class="search gcc-batch-credentials">
|
||||
<Card>
|
||||
<div class="gcc-records-toolbar">
|
||||
<Button type="primary" class="gcc-records-back" @click="closePage">
|
||||
返回
|
||||
</Button>
|
||||
</div>
|
||||
<div v-if="giftCardName" class="gcc-records-meta mb_10">
|
||||
<strong>礼品卡:</strong>{{ giftCardName }}
|
||||
</div>
|
||||
<div class="gcc-records-meta mb_10">
|
||||
<strong>{{ batchTypeLabel }}:</strong>{{ batchIdDisplay || "—" }}
|
||||
<span v-if="batchRemark" style="margin-left: 12px"><strong>本批备注:</strong>{{ batchRemark }}</span>
|
||||
</div>
|
||||
<Alert v-if="!activityId || !hasBatchId" type="warning">
|
||||
缺少活动或批次参数,请从{{ batchSourceLabel }}进入。
|
||||
</Alert>
|
||||
<template v-else>
|
||||
<div class="gcc-status-tabs">
|
||||
<span
|
||||
v-for="t in statusTabList"
|
||||
:key="t.key"
|
||||
:class="{ active: lifecycleTab === t.key }"
|
||||
@click="onLifecycleTab(t.key)"
|
||||
>{{ t.label }}</span
|
||||
>
|
||||
</div>
|
||||
<Form ref="searchForm" :model="searchForm" inline class="search-form mb_10 gcc-filter-form">
|
||||
<FormItem label="卡号" prop="cardNo" :label-width="60">
|
||||
<Input v-model="searchForm.cardNo" placeholder="请输入卡号" clearable style="width: 160px" />
|
||||
</FormItem>
|
||||
<FormItem :label-width="0" class="gcc-combo-item">
|
||||
<span class="gcc-combo-label">兑换会员</span>
|
||||
<Select v-model="searchForm.redeemMemberField" style="width: 130px">
|
||||
<Option value="nickName">兑换会员昵称</Option>
|
||||
<Option value="mobile">兑换会员手机</Option>
|
||||
</Select>
|
||||
<Input
|
||||
v-model="searchForm.redeemMemberKeyword"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
style="width: 140px; margin-left: 4px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="兑换时间" prop="redeemDateRange" :label-width="72">
|
||||
<DatePicker
|
||||
v-model="redeemDateRange"
|
||||
type="daterange"
|
||||
clearable
|
||||
format="yyyy-MM-dd"
|
||||
placeholder="开始日期"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem :label-width="0" class="gcc-combo-item">
|
||||
<span class="gcc-combo-label">激活会员</span>
|
||||
<Select v-model="searchForm.activateMemberField" style="width: 130px">
|
||||
<Option value="nickName">激活会员昵称</Option>
|
||||
<Option value="mobile">激活会员手机</Option>
|
||||
</Select>
|
||||
<Input
|
||||
v-model="searchForm.activateMemberKeyword"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
style="width: 140px; margin-left: 4px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="激活时间" prop="activateDateRange" :label-width="72">
|
||||
<DatePicker
|
||||
v-model="activateDateRange"
|
||||
type="daterange"
|
||||
clearable
|
||||
format="yyyy-MM-dd"
|
||||
placeholder="开始日期"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</FormItem>
|
||||
<Button type="primary" icon="ios-search" class="search-btn" @click="handleSearch">搜索</Button>
|
||||
</Form>
|
||||
<Table :loading="loading" :columns="tableColumns" :data="data" />
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
/>
|
||||
</Row>
|
||||
</template>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getGiftCardCashCredentialPage } from "@/api/promotion";
|
||||
|
||||
const STATUS_LABEL = {
|
||||
UNISSUED: "未兑换",
|
||||
UNREDEEMED: "未兑换",
|
||||
UNACTIVATED: "未激活",
|
||||
BOUND: "已激活",
|
||||
ACTIVATED: "已激活",
|
||||
VOIDED: "已销卡",
|
||||
EXPIRED: "已过期",
|
||||
};
|
||||
|
||||
const ISSUE_STATUS_LABEL = {
|
||||
ISSUED: "已发卡",
|
||||
UNISSUED: "未发卡",
|
||||
PENDING: "待处理",
|
||||
PENDING_ACTIVATION: "待激活",
|
||||
ACTIVATED: "已激活",
|
||||
FAILED: "发卡失败",
|
||||
SUCCESS: "发卡成功",
|
||||
};
|
||||
|
||||
export default {
|
||||
name: "GiftCardCashBatchCredentials",
|
||||
data() {
|
||||
return {
|
||||
activityId: "",
|
||||
createBatchId: "",
|
||||
issueBatchId: "",
|
||||
giftCardName: "",
|
||||
batchRemark: "",
|
||||
lifecycleTab: "all",
|
||||
statusTabList: [
|
||||
{ key: "all", label: "全部", status: "" },
|
||||
{ key: "unredeemed", label: "未兑换", status: "UNISSUED" },
|
||||
{ key: "unactivated", label: "未激活", status: "UNACTIVATED" },
|
||||
{ key: "activated", label: "已激活", status: "BOUND" },
|
||||
{ key: "cancelled", label: "已销卡", status: "VOIDED" },
|
||||
{ key: "expired", label: "已过期", status: "EXPIRED" },
|
||||
],
|
||||
redeemDateRange: [],
|
||||
activateDateRange: [],
|
||||
loading: false,
|
||||
total: 0,
|
||||
data: [],
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
cardNo: "",
|
||||
redeemMemberField: "nickName",
|
||||
redeemMemberKeyword: "",
|
||||
activateMemberField: "nickName",
|
||||
activateMemberKeyword: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isIssueBatchMode() {
|
||||
return !!this.issueBatchId;
|
||||
},
|
||||
hasBatchId() {
|
||||
return !!(this.createBatchId || this.issueBatchId);
|
||||
},
|
||||
batchTypeLabel() {
|
||||
return this.isIssueBatchMode ? "发卡批次" : "制卡批次";
|
||||
},
|
||||
batchSourceLabel() {
|
||||
return this.isIssueBatchMode ? "发卡记录" : "制卡记录";
|
||||
},
|
||||
batchIdDisplay() {
|
||||
return this.isIssueBatchMode ? this.issueBatchId : this.createBatchId;
|
||||
},
|
||||
createBatchColumns() {
|
||||
return [
|
||||
{ title: "卡号", key: "cardNo", minWidth: 140, tooltip: true },
|
||||
{ title: "卡密", key: "cardSecret", minWidth: 120, tooltip: true },
|
||||
{ title: "面额", key: "faceValue", width: 90, align: "right" },
|
||||
{ title: "余额", key: "balance", width: 90, align: "right" },
|
||||
{
|
||||
title: "状态",
|
||||
key: "status",
|
||||
width: 90,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
const s = params.row.status;
|
||||
return h("span", STATUS_LABEL[s] || s || "—");
|
||||
},
|
||||
},
|
||||
{ title: "会员手机", key: "memberMobile", width: 120, tooltip: true },
|
||||
{ title: "会员昵称", key: "memberNickName", minWidth: 100, tooltip: true },
|
||||
{ title: "绑定时间", key: "bindTime", width: 165 },
|
||||
{ title: "到期时间", key: "expireTime", width: 165 },
|
||||
{ title: "创建时间", key: "createTime", width: 165 },
|
||||
];
|
||||
},
|
||||
issueBatchColumns() {
|
||||
return [
|
||||
{ title: "卡号", key: "cardNo", minWidth: 140, tooltip: true },
|
||||
{
|
||||
title: "发卡批次ID",
|
||||
key: "issueBatchId",
|
||||
minWidth: 160,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
const id = params.row.issueBatchId ?? this.issueBatchId;
|
||||
return h("span", id != null && id !== "" ? String(id) : "—");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "发卡会员",
|
||||
key: "issueMember",
|
||||
minWidth: 150,
|
||||
render: (h, params) => h("span", this.formatIssueMember(params.row)),
|
||||
},
|
||||
{
|
||||
title: "发卡状态",
|
||||
key: "issueStatus",
|
||||
width: 110,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
const s = params.row.issueStatus;
|
||||
return h("span", ISSUE_STATUS_LABEL[s] || s || "—");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "激活会员",
|
||||
key: "activationMember",
|
||||
minWidth: 150,
|
||||
render: (h, params) => h("span", this.formatActivationMember(params.row)),
|
||||
},
|
||||
{
|
||||
title: "激活时间",
|
||||
key: "activationTime",
|
||||
width: 165,
|
||||
render: (h, params) => {
|
||||
const t =
|
||||
params.row.activationTime ||
|
||||
params.row.activateTime ||
|
||||
params.row.bindTime;
|
||||
return h("span", t != null && t !== "" ? String(t) : "—");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "status",
|
||||
width: 90,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
const s = params.row.status;
|
||||
return h("span", STATUS_LABEL[s] || s || "—");
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
tableColumns() {
|
||||
return this.isIssueBatchMode ? this.issueBatchColumns : this.createBatchColumns;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.initFromRoute();
|
||||
if (this.activityId && this.hasBatchId) {
|
||||
this.loadList();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
"$route.query.createBatchId"() {
|
||||
this.onRouteQueryChange();
|
||||
},
|
||||
"$route.query.issueBatchId"() {
|
||||
this.onRouteQueryChange();
|
||||
},
|
||||
"$route.query.activityId"() {
|
||||
this.onRouteQueryChange();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onRouteQueryChange() {
|
||||
this.initFromRoute();
|
||||
if (this.activityId && this.hasBatchId) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.loadList();
|
||||
}
|
||||
},
|
||||
initFromRoute() {
|
||||
const q = this.$route.query || {};
|
||||
this.activityId = (q.activityId && String(q.activityId)) || "";
|
||||
this.createBatchId = (q.createBatchId && String(q.createBatchId)) || "";
|
||||
this.issueBatchId = (q.issueBatchId && String(q.issueBatchId)) || "";
|
||||
this.giftCardName = (q.giftCardName && String(q.giftCardName)) || "";
|
||||
this.batchRemark = (q.batchRemark && String(q.batchRemark)) || "";
|
||||
},
|
||||
closePage() {
|
||||
this.$store.commit("removeTag", "gift-card-cash-batch-credentials");
|
||||
localStorage.pageOpenedList = JSON.stringify(this.$store.state.app.pageOpenedList);
|
||||
this.$router.go(-1);
|
||||
},
|
||||
formatMemberText(name, mobile) {
|
||||
const n = name != null && name !== "" ? String(name) : "";
|
||||
const m = mobile != null && mobile !== "" ? String(mobile) : "";
|
||||
if (n && m) {
|
||||
return `${n} / ${m}`;
|
||||
}
|
||||
return n || m || "—";
|
||||
},
|
||||
formatIssueMember(row) {
|
||||
return this.formatMemberText(
|
||||
row.issueMemberNickName ||
|
||||
row.issueMemberName ||
|
||||
row.exchangeMemberNickName ||
|
||||
row.exchangeMemberName ||
|
||||
row.memberNickName,
|
||||
row.issueMemberMobile || row.exchangeMemberMobile || row.memberMobile
|
||||
);
|
||||
},
|
||||
formatActivationMember(row) {
|
||||
return this.formatMemberText(
|
||||
row.activationMemberNickName ||
|
||||
row.activationMemberName ||
|
||||
row.activateMemberNickName ||
|
||||
row.activateMemberName,
|
||||
row.activationMemberMobile || row.activateMemberMobile
|
||||
);
|
||||
},
|
||||
onLifecycleTab(key) {
|
||||
if (this.lifecycleTab === key) {
|
||||
return;
|
||||
}
|
||||
this.lifecycleTab = key;
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.loadList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.loadList();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.loadList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.loadList();
|
||||
},
|
||||
formatDayStart(d) {
|
||||
if (!d) {
|
||||
return "";
|
||||
}
|
||||
const x = d instanceof Date ? d : new Date(d);
|
||||
if (Number.isNaN(x.getTime())) {
|
||||
return "";
|
||||
}
|
||||
const y = x.getFullYear();
|
||||
const m = String(x.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(x.getDate()).padStart(2, "0");
|
||||
return `${y}-${m}-${day} 00:00:00`;
|
||||
},
|
||||
formatDayEnd(d) {
|
||||
if (!d) {
|
||||
return "";
|
||||
}
|
||||
const x = d instanceof Date ? d : new Date(d);
|
||||
if (Number.isNaN(x.getTime())) {
|
||||
return "";
|
||||
}
|
||||
const y = x.getFullYear();
|
||||
const m = String(x.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(x.getDate()).padStart(2, "0");
|
||||
return `${y}-${m}-${day} 23:59:59`;
|
||||
},
|
||||
appendMemberSearch(params, kind, field, keyword) {
|
||||
const kw = (keyword || "").trim();
|
||||
if (!kw) {
|
||||
return;
|
||||
}
|
||||
if (kind === "exchange") {
|
||||
if (field === "mobile") {
|
||||
params.exchangeMemberMobile = kw;
|
||||
} else {
|
||||
params.exchangeMemberNickName = kw;
|
||||
}
|
||||
} else {
|
||||
if (field === "mobile") {
|
||||
params.activationMemberMobile = kw;
|
||||
} else {
|
||||
params.activationMemberNickName = kw;
|
||||
}
|
||||
}
|
||||
},
|
||||
appendDateRange(params, kind, range) {
|
||||
if (!range || !range[0] || !range[1]) {
|
||||
return;
|
||||
}
|
||||
const start = this.formatDayStart(range[0]);
|
||||
const end = this.formatDayEnd(range[1]);
|
||||
if (kind === "exchange") {
|
||||
if (start) {
|
||||
params.exchangeTimeStart = start;
|
||||
}
|
||||
if (end) {
|
||||
params.exchangeTimeEnd = end;
|
||||
}
|
||||
} else {
|
||||
if (start) {
|
||||
params.activationTimeStart = start;
|
||||
}
|
||||
if (end) {
|
||||
params.activationTimeEnd = end;
|
||||
}
|
||||
}
|
||||
},
|
||||
loadList() {
|
||||
if (!this.activityId || !this.hasBatchId) {
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
const params = {
|
||||
activityId: this.activityId,
|
||||
pageNumber: this.searchForm.pageNumber,
|
||||
pageSize: this.searchForm.pageSize,
|
||||
sort: this.searchForm.sort,
|
||||
order: this.searchForm.order,
|
||||
};
|
||||
if (this.isIssueBatchMode) {
|
||||
params.issueBatchId = this.issueBatchId;
|
||||
} else {
|
||||
params.createBatchId = this.createBatchId;
|
||||
}
|
||||
const tabCfg = this.statusTabList.find((t) => t.key === this.lifecycleTab);
|
||||
if (tabCfg && tabCfg.status) {
|
||||
params.status = tabCfg.status;
|
||||
}
|
||||
const cardNo = (this.searchForm.cardNo || "").trim();
|
||||
if (cardNo) {
|
||||
params.cardNo = cardNo;
|
||||
}
|
||||
this.appendMemberSearch(
|
||||
params,
|
||||
"exchange",
|
||||
this.searchForm.redeemMemberField,
|
||||
this.searchForm.redeemMemberKeyword
|
||||
);
|
||||
this.appendMemberSearch(
|
||||
params,
|
||||
"activation",
|
||||
this.searchForm.activateMemberField,
|
||||
this.searchForm.activateMemberKeyword
|
||||
);
|
||||
this.appendDateRange(params, "exchange", this.redeemDateRange);
|
||||
this.appendDateRange(params, "activation", this.activateDateRange);
|
||||
getGiftCardCashCredentialPage(params)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success && res.result) {
|
||||
this.data = res.result.records || [];
|
||||
this.total = res.result.total || 0;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.gcc-batch-credentials .gcc-records-toolbar {
|
||||
margin-bottom: 22px;
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 1px solid #e8eaec;
|
||||
}
|
||||
.gcc-batch-credentials .gcc-records-back {
|
||||
font-weight: 500;
|
||||
}
|
||||
.gcc-batch-credentials .gcc-records-meta {
|
||||
line-height: 1.6;
|
||||
color: #515a6e;
|
||||
}
|
||||
.gcc-batch-credentials .gcc-status-tabs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #e8eaec;
|
||||
margin-bottom: 16px;
|
||||
gap: 4px 8px;
|
||||
}
|
||||
.gcc-batch-credentials .gcc-status-tabs span {
|
||||
padding: 10px 14px 12px;
|
||||
cursor: pointer;
|
||||
color: #808695;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
}
|
||||
.gcc-batch-credentials .gcc-status-tabs span:hover {
|
||||
color: #515a6e;
|
||||
}
|
||||
.gcc-batch-credentials .gcc-status-tabs span.active {
|
||||
color: #ff6600;
|
||||
font-weight: 500;
|
||||
}
|
||||
.gcc-batch-credentials .gcc-status-tabs span.active::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
bottom: 0;
|
||||
height: 3px;
|
||||
background: #ff6600;
|
||||
border-radius: 2px 2px 0 0;
|
||||
}
|
||||
.gcc-batch-credentials .gcc-filter-form {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
}
|
||||
.gcc-batch-credentials .gcc-combo-item {
|
||||
margin-right: 12px;
|
||||
}
|
||||
.gcc-batch-credentials .gcc-combo-label {
|
||||
display: inline-block;
|
||||
margin-right: 6px;
|
||||
color: #515a6e;
|
||||
font-size: 14px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,952 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<div class="gcc-records-toolbar">
|
||||
<Button type="primary" class="gcc-records-back" @click="closePage">
|
||||
返回
|
||||
</Button>
|
||||
</div>
|
||||
<div v-if="giftCardName" class="gcc-records-meta mb_10">
|
||||
<strong>礼品卡:</strong>{{ giftCardName }}
|
||||
</div>
|
||||
<div v-else-if="activityId" class="gcc-records-meta mb_10">
|
||||
<strong>活动ID:</strong>{{ activityId }}
|
||||
</div>
|
||||
<Alert v-if="!activityId" type="warning">缺少活动参数,请从礼品卡列表进入。</Alert>
|
||||
<Tabs v-else v-model="activeTab" @on-click="onTabClick">
|
||||
<TabPane label="制卡记录" name="createBatch">
|
||||
<Card :bordered="false" dis-hover>
|
||||
<Form
|
||||
ref="createFilterForm"
|
||||
:model="createSearchForm"
|
||||
inline
|
||||
label-position="left"
|
||||
class="search-form mb_10 gcc-create-batch-search"
|
||||
:label-width="100"
|
||||
>
|
||||
<FormItem label="卡号" prop="cardNo">
|
||||
<Input
|
||||
v-model="createSearchForm.cardNo"
|
||||
clearable
|
||||
style="width: 150px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="制卡批次ID" prop="createBatchId">
|
||||
<Input
|
||||
v-model="createSearchForm.createBatchId"
|
||||
clearable
|
||||
style="width: 170px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="卡名称" prop="giftCardName">
|
||||
<Input
|
||||
v-model="createSearchForm.giftCardName"
|
||||
clearable
|
||||
style="width: 160px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="制卡人名称" prop="createUserName">
|
||||
<Input
|
||||
v-model="createSearchForm.createUserName"
|
||||
clearable
|
||||
style="width: 140px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="制卡时间" prop="createTimeRange">
|
||||
<DatePicker
|
||||
v-model="createSearchForm.createTimeRange"
|
||||
type="daterange"
|
||||
clearable
|
||||
format="yyyy-MM-dd"
|
||||
style="width: 220px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="过期时间" prop="expireTimeRange">
|
||||
<DatePicker
|
||||
v-model="createSearchForm.expireTimeRange"
|
||||
type="daterange"
|
||||
clearable
|
||||
format="yyyy-MM-dd"
|
||||
style="width: 220px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem :label-width="0">
|
||||
<Button type="primary" icon="ios-search" class="search-btn" @click="handleCreateSearch">
|
||||
搜索
|
||||
</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<Table :loading="createLoading" :columns="createColumns" :data="createData" />
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="createSearchForm.pageNumber"
|
||||
:total="createTotal"
|
||||
:page-size="createSearchForm.pageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
@on-change="createChangePage"
|
||||
@on-page-size-change="createChangePageSize"
|
||||
/>
|
||||
</Row>
|
||||
</Card>
|
||||
</TabPane>
|
||||
<TabPane label="发卡记录" name="issue">
|
||||
<Card :bordered="false" dis-hover>
|
||||
<Form
|
||||
ref="issueFilterForm"
|
||||
:model="issueSearchForm"
|
||||
inline
|
||||
label-position="left"
|
||||
class="search-form mb_10 gcc-create-batch-search"
|
||||
:label-width="100"
|
||||
>
|
||||
<FormItem label="卡号" prop="cardNo">
|
||||
<Input
|
||||
v-model="issueSearchForm.cardNo"
|
||||
clearable
|
||||
style="width: 150px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="发卡批次ID" prop="issueBatchId">
|
||||
<Input
|
||||
v-model="issueSearchForm.issueBatchId"
|
||||
clearable
|
||||
style="width: 170px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="现金卡名称" prop="giftCardName">
|
||||
<Input
|
||||
v-model="issueSearchForm.giftCardName"
|
||||
clearable
|
||||
style="width: 160px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="发卡人名称" prop="issueUserName">
|
||||
<Input
|
||||
v-model="issueSearchForm.issueUserName"
|
||||
clearable
|
||||
style="width: 140px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="发卡时间" prop="createTimeRange">
|
||||
<DatePicker
|
||||
v-model="issueSearchForm.createTimeRange"
|
||||
type="daterange"
|
||||
clearable
|
||||
format="yyyy-MM-dd"
|
||||
style="width: 220px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="过期时间" prop="expireTimeRange">
|
||||
<DatePicker
|
||||
v-model="issueSearchForm.expireTimeRange"
|
||||
type="daterange"
|
||||
clearable
|
||||
format="yyyy-MM-dd"
|
||||
style="width: 220px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem :label-width="0">
|
||||
<Button type="primary" icon="ios-search" class="search-btn" @click="handleIssueSearch">
|
||||
搜索
|
||||
</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<Table :loading="issueLoading" :columns="issueColumns" :data="issueData" />
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="issueSearchForm.pageNumber"
|
||||
:total="issueTotal"
|
||||
:page-size="issueSearchForm.pageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
@on-change="issueChangePage"
|
||||
@on-page-size-change="issueChangePageSize"
|
||||
/>
|
||||
</Row>
|
||||
</Card>
|
||||
</TabPane>
|
||||
<TabPane label="使用记录" name="usage">
|
||||
<Card :bordered="false" dis-hover>
|
||||
<Form
|
||||
ref="usageFilterForm"
|
||||
:model="usageSearchForm"
|
||||
inline
|
||||
label-position="left"
|
||||
class="search-form mb_10 gcc-create-batch-search"
|
||||
:label-width="90"
|
||||
>
|
||||
<FormItem label="订单号" prop="orderSn">
|
||||
<Input
|
||||
v-model="usageSearchForm.orderSn"
|
||||
clearable
|
||||
style="width: 160px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="客户名称" prop="memberName">
|
||||
<Input
|
||||
v-model="usageSearchForm.memberName"
|
||||
clearable
|
||||
style="width: 150px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="卡号" prop="cardNo">
|
||||
<Input
|
||||
v-model="usageSearchForm.cardNo"
|
||||
clearable
|
||||
style="width: 150px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="交易时间" prop="transactionTimeRange">
|
||||
<DatePicker
|
||||
v-model="usageSearchForm.transactionTimeRange"
|
||||
type="daterange"
|
||||
clearable
|
||||
format="yyyy-MM-dd"
|
||||
style="width: 220px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="交易类型" prop="transactionType">
|
||||
<Select
|
||||
v-model="usageSearchForm.transactionType"
|
||||
clearable
|
||||
style="width: 150px"
|
||||
>
|
||||
<Option value="ORDER_DEDUCT">订单抵扣</Option>
|
||||
<Option value="ORDER_REFUND">订单退款</Option>
|
||||
<Option value="ORDER_CANCEL">订单取消</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem :label-width="0">
|
||||
<Button type="primary" icon="ios-search" class="search-btn" @click="handleUsageSearch">
|
||||
搜索
|
||||
</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<Table :loading="usageLoading" :columns="usageColumns" :data="usageData" />
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="usageSearchForm.pageNumber"
|
||||
:total="usageTotal"
|
||||
:page-size="usageSearchForm.pageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
@on-change="usageChangePage"
|
||||
@on-page-size-change="usageChangePageSize"
|
||||
/>
|
||||
</Row>
|
||||
</Card>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getGiftCardCashCreateBatchPage,
|
||||
getGiftCardCashIssueBatchPage,
|
||||
getGiftCardCashUsageRecordPage,
|
||||
} from "@/api/promotion";
|
||||
|
||||
export default {
|
||||
name: "GiftCardCashRecords",
|
||||
data() {
|
||||
return {
|
||||
activeTab: "createBatch",
|
||||
activityId: "",
|
||||
giftCardName: "",
|
||||
createLoading: false,
|
||||
createTotal: 0,
|
||||
createData: [],
|
||||
createSearchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
cardNo: "",
|
||||
createBatchId: "",
|
||||
giftCardName: "",
|
||||
createUserName: "",
|
||||
createTimeRange: [],
|
||||
expireTimeRange: [],
|
||||
},
|
||||
issueLoading: false,
|
||||
issueTotal: 0,
|
||||
issueData: [],
|
||||
issueSearchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
cardNo: "",
|
||||
issueBatchId: "",
|
||||
giftCardName: "",
|
||||
issueUserName: "",
|
||||
createTimeRange: [],
|
||||
expireTimeRange: [],
|
||||
},
|
||||
usageLoading: false,
|
||||
usageTotal: 0,
|
||||
usageData: [],
|
||||
usageSearchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
orderSn: "",
|
||||
memberName: "",
|
||||
cardNo: "",
|
||||
transactionType: "",
|
||||
transactionTimeRange: [],
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
createColumns() {
|
||||
return [
|
||||
{
|
||||
title: "制卡批次ID",
|
||||
key: "createBatchId",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
align: "left",
|
||||
render: (h, p) => {
|
||||
const id = p.row.createBatchId ?? p.row.id;
|
||||
return h("span", id != null && id !== "" ? String(id) : "-");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "卡号范围",
|
||||
key: "cardNoRange",
|
||||
minWidth: 160,
|
||||
tooltip: true,
|
||||
align: "left",
|
||||
render: (h, p) => {
|
||||
const t = p.row.cardNoRange;
|
||||
return h("span", t != null && t !== "" ? String(t) : "-");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "面值",
|
||||
key: "faceValue",
|
||||
width: 150,
|
||||
align: "left",
|
||||
render: (h, p) => {
|
||||
const v = p.row.faceValue;
|
||||
if (v === null || v === undefined || v === "") {
|
||||
return h("span", "-");
|
||||
}
|
||||
return h("priceColorScheme", {
|
||||
props: { value: v, color: this.$mainColor },
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "礼品卡名称",
|
||||
key: "giftCardName",
|
||||
width: 150,
|
||||
tooltip: true,
|
||||
align: "left",
|
||||
render: (h, p) => {
|
||||
const t = p.row.giftCardName ?? this.giftCardName;
|
||||
return h("span", t != null && t !== "" ? String(t) : "-");
|
||||
},
|
||||
},
|
||||
{ title: "制卡人", key: "createUserName", width: 150, tooltip: true ,align: "left"},
|
||||
{ title: "制卡时间", key: "createTime", width: 200,align: "left" },
|
||||
{
|
||||
title: "制卡数量",
|
||||
key: "quantity",
|
||||
width: 200,
|
||||
align: "left",
|
||||
render: (h, p) => {
|
||||
const v = p.row.quantity;
|
||||
if (v === null || v === undefined || v === "") {
|
||||
return h("span", "-");
|
||||
}
|
||||
return h("span", String(v));
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "过期时间",
|
||||
key: "expireTime",
|
||||
width: 200,
|
||||
align: "left",
|
||||
render: (h, p) => {
|
||||
const t = p.row.expireTime;
|
||||
return h("span", t != null && t !== "" ? String(t) : "长期有效");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 150,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"Button",
|
||||
{
|
||||
props: { type: "primary", size: "small" },
|
||||
on: { click: () => this.goBatchCredentials(params.row) },
|
||||
},
|
||||
"查看"
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
issueColumns() {
|
||||
return [
|
||||
{
|
||||
title: "发卡批次ID",
|
||||
key: "issueBatchId",
|
||||
minWidth: 160,
|
||||
tooltip: true,
|
||||
render: (h, p) => {
|
||||
const id = p.row.issueBatchId ?? p.row.id;
|
||||
return h("span", id != null && id !== "" ? String(id) : "-");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "卡号范围",
|
||||
key: "cardNoRange",
|
||||
minWidth: 160,
|
||||
tooltip: true,
|
||||
render: (h, p) => {
|
||||
const t = p.row.cardNoRange;
|
||||
return h("span", t != null && t !== "" ? String(t) : "-");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "面值",
|
||||
key: "faceValue",
|
||||
width: 120,
|
||||
align: "right",
|
||||
render: (h, p) => {
|
||||
const v = p.row.faceValue;
|
||||
if (v === null || v === undefined || v === "") {
|
||||
return h("span", "-");
|
||||
}
|
||||
return h("priceColorScheme", {
|
||||
props: { value: v, color: this.$mainColor },
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "卡名称",
|
||||
key: "giftCardName",
|
||||
minWidth: 120,
|
||||
tooltip: true,
|
||||
render: (h, p) => {
|
||||
const t = p.row.giftCardName ?? this.giftCardName;
|
||||
return h("span", t != null && t !== "" ? String(t) : "-");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "发卡人",
|
||||
key: "issueUserName",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
render: (h, p) => {
|
||||
const t = p.row.issueUserName;
|
||||
return h("span", t != null && t !== "" ? String(t) : "-");
|
||||
},
|
||||
},
|
||||
{ title: "发卡时间", key: "createTime", width: 170 },
|
||||
{
|
||||
title: "发卡数量",
|
||||
key: "totalCards",
|
||||
width: 100,
|
||||
align: "center",
|
||||
render: (h, p) => {
|
||||
const v = p.row.totalCards;
|
||||
if (v === null || v === undefined || v === "") {
|
||||
return h("span", "-");
|
||||
}
|
||||
return h("span", String(v));
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "过期时间",
|
||||
key: "expireTime",
|
||||
width: 170,
|
||||
render: (h, p) => {
|
||||
const t = p.row.expireTime;
|
||||
return h("span", t != null && t !== "" ? String(t) : "长期有效");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 150,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"Button",
|
||||
{
|
||||
props: { type: "primary", size: "small" },
|
||||
on: { click: () => this.goIssueBatchCredentials(params.row) },
|
||||
},
|
||||
"查看"
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
usageColumns() {
|
||||
return [
|
||||
{ title: "订单号", key: "orderSn", minWidth: 160, tooltip: true },
|
||||
{
|
||||
title: "交易类型",
|
||||
key: "transactionType",
|
||||
minWidth: 120,
|
||||
render: (h, p) => h("span", this.formatUsageBizType(p.row.transactionType || p.row.bizType)),
|
||||
},
|
||||
{ title: "卡号", key: "cardNo", minWidth: 150, tooltip: true },
|
||||
{
|
||||
title: "现金卡信息",
|
||||
key: "giftCardName",
|
||||
minWidth: 180,
|
||||
render: (h, p) => {
|
||||
const name = p.row.giftCardName || this.giftCardName || "-";
|
||||
const faceValue = p.row.faceValue;
|
||||
return h("div", [
|
||||
h("div", String(name)),
|
||||
h(
|
||||
"div",
|
||||
{ style: { color: "#808695", marginTop: "4px" } },
|
||||
`面额:${faceValue != null && faceValue !== "" ? faceValue : "-"}`
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "金额",
|
||||
key: "changeAmount",
|
||||
width: 130,
|
||||
align: "right",
|
||||
render: (h, p) => {
|
||||
const display = this.getUsageAmountDisplay(p.row);
|
||||
if (!display) {
|
||||
return h("span", "-");
|
||||
}
|
||||
return h("priceColorScheme", {
|
||||
props: { value: display.amount, color: display.color },
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "余额",
|
||||
key: "balanceAfter",
|
||||
width: 130,
|
||||
align: "right",
|
||||
render: (h, p) => {
|
||||
const v = p.row.balanceAfter;
|
||||
if (v === null || v === undefined || v === "") {
|
||||
return h("span", "-");
|
||||
}
|
||||
return h("priceColorScheme", {
|
||||
props: { value: v, color: this.$mainColor },
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "交易时间",
|
||||
key: "transactionTime",
|
||||
width: 170,
|
||||
render: (h, p) => {
|
||||
const t = p.row.transactionTime || p.row.createTime;
|
||||
return h("span", t != null && t !== "" ? String(t) : "-");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "客户信息",
|
||||
key: "memberName",
|
||||
minWidth: 150,
|
||||
render: (h, p) => {
|
||||
const name = p.row.memberName || "-";
|
||||
const mobile = p.row.memberMobile || "-";
|
||||
return h("div", [
|
||||
h("div", String(name)),
|
||||
h("div", { style: { color: "#808695", marginTop: "4px" } }, String(mobile)),
|
||||
]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 100,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h, p) => {
|
||||
const orderSn = p.row.orderSn;
|
||||
if (!orderSn) {
|
||||
return h("span", { style: { color: "#c5c8ce" } }, "详情");
|
||||
}
|
||||
return h(
|
||||
"Button",
|
||||
{
|
||||
props: { type: "primary", size: "small" },
|
||||
on: { click: () => this.goOrderDetail(orderSn) },
|
||||
},
|
||||
"详情"
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.initFromRoute();
|
||||
if (this.activityId) {
|
||||
this.loadCreateBatchList();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
"$route.query.activityId"(id) {
|
||||
this.initFromRoute();
|
||||
if (id && this.activeTab === "createBatch") {
|
||||
this.loadCreateBatchList();
|
||||
}
|
||||
if (id && this.activeTab === "issue") {
|
||||
this.issueSearchForm.pageNumber = 1;
|
||||
this.loadIssueBatchList();
|
||||
}
|
||||
if (id && this.activeTab === "usage") {
|
||||
this.usageSearchForm.pageNumber = 1;
|
||||
this.loadUsageRecordList();
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
initFromRoute() {
|
||||
this.activityId = (this.$route.query.activityId && String(this.$route.query.activityId)) || "";
|
||||
this.giftCardName = (this.$route.query.giftCardName && String(this.$route.query.giftCardName)) || "";
|
||||
},
|
||||
closePage() {
|
||||
this.$store.commit("removeTag", "gift-card-cash-records");
|
||||
localStorage.pageOpenedList = JSON.stringify(this.$store.state.app.pageOpenedList);
|
||||
this.$router.go(-1);
|
||||
},
|
||||
goBatchCredentials(row) {
|
||||
const batchId = row.createBatchId != null && row.createBatchId !== "" ? row.createBatchId : row.id;
|
||||
this.$router.push({
|
||||
name: "gift-card-cash-batch-credentials",
|
||||
query: {
|
||||
activityId: this.activityId,
|
||||
createBatchId: batchId,
|
||||
giftCardName: row.giftCardName || this.giftCardName || "",
|
||||
batchRemark: row.batchRemark || "",
|
||||
},
|
||||
});
|
||||
},
|
||||
goIssueBatchCredentials(row) {
|
||||
const batchId = row.issueBatchId != null && row.issueBatchId !== "" ? row.issueBatchId : row.id;
|
||||
this.$router.push({
|
||||
name: "gift-card-cash-batch-credentials",
|
||||
query: {
|
||||
activityId: this.activityId,
|
||||
issueBatchId: batchId,
|
||||
giftCardName: row.giftCardName || this.giftCardName || "",
|
||||
},
|
||||
});
|
||||
},
|
||||
goOrderDetail(orderSn) {
|
||||
this.$router.push({
|
||||
name: "order-detail",
|
||||
query: { sn: orderSn },
|
||||
});
|
||||
},
|
||||
onTabClick(name) {
|
||||
if (name === "createBatch" && this.activityId) {
|
||||
this.loadCreateBatchList();
|
||||
}
|
||||
if (name === "issue" && this.activityId) {
|
||||
this.loadIssueBatchList();
|
||||
}
|
||||
if (name === "usage" && this.activityId) {
|
||||
this.loadUsageRecordList();
|
||||
}
|
||||
},
|
||||
handleCreateSearch() {
|
||||
this.createSearchForm.pageNumber = 1;
|
||||
this.loadCreateBatchList();
|
||||
},
|
||||
/** 日期区间 → yyyy-MM-dd HH:mm:ss,供 Spring 绑定 Date */
|
||||
toApiDateTimeBoundary(val, endOfDay) {
|
||||
const dt = val instanceof Date ? val : new Date(val);
|
||||
if (Number.isNaN(dt.getTime())) {
|
||||
return null;
|
||||
}
|
||||
const y = dt.getFullYear();
|
||||
const m = String(dt.getMonth() + 1).padStart(2, "0");
|
||||
const d = String(dt.getDate()).padStart(2, "0");
|
||||
return endOfDay ? `${y}-${m}-${d} 23:59:59` : `${y}-${m}-${d} 00:00:00`;
|
||||
},
|
||||
appendDateRangeToParams(params, range, startKey, endKey) {
|
||||
if (!Array.isArray(range) || range.length < 2 || !range[0] || !range[1]) {
|
||||
return;
|
||||
}
|
||||
const start = this.toApiDateTimeBoundary(range[0], false);
|
||||
const end = this.toApiDateTimeBoundary(range[1], true);
|
||||
if (start) {
|
||||
params[startKey] = start;
|
||||
}
|
||||
if (end) {
|
||||
params[endKey] = end;
|
||||
}
|
||||
},
|
||||
appendTrimmedParam(params, key, value) {
|
||||
const text = (value || "").trim();
|
||||
if (text) {
|
||||
params[key] = text;
|
||||
}
|
||||
},
|
||||
createChangePage(v) {
|
||||
this.createSearchForm.pageNumber = v;
|
||||
this.loadCreateBatchList();
|
||||
},
|
||||
createChangePageSize(v) {
|
||||
this.createSearchForm.pageNumber = 1;
|
||||
this.createSearchForm.pageSize = v;
|
||||
this.loadCreateBatchList();
|
||||
},
|
||||
loadCreateBatchList() {
|
||||
if (!this.activityId) {
|
||||
return;
|
||||
}
|
||||
this.createLoading = true;
|
||||
const params = {
|
||||
activityId: this.activityId,
|
||||
pageNumber: this.createSearchForm.pageNumber,
|
||||
pageSize: this.createSearchForm.pageSize,
|
||||
sort: this.createSearchForm.sort,
|
||||
order: this.createSearchForm.order,
|
||||
};
|
||||
const cardNo = (this.createSearchForm.cardNo || "").trim();
|
||||
if (cardNo) {
|
||||
params.cardNo = cardNo;
|
||||
}
|
||||
const createBatchId = (this.createSearchForm.createBatchId || "").trim();
|
||||
if (createBatchId) {
|
||||
params.createBatchId = createBatchId;
|
||||
}
|
||||
const giftCardName = (this.createSearchForm.giftCardName || "").trim();
|
||||
if (giftCardName) {
|
||||
params.giftCardName = giftCardName;
|
||||
}
|
||||
const createUserName = (this.createSearchForm.createUserName || "").trim();
|
||||
if (createUserName) {
|
||||
params.createUserName = createUserName;
|
||||
}
|
||||
this.appendDateRangeToParams(
|
||||
params,
|
||||
this.createSearchForm.createTimeRange,
|
||||
"createTimeStart",
|
||||
"createTimeEnd"
|
||||
);
|
||||
this.appendDateRangeToParams(
|
||||
params,
|
||||
this.createSearchForm.expireTimeRange,
|
||||
"expireTimeStart",
|
||||
"expireTimeEnd"
|
||||
);
|
||||
getGiftCardCashCreateBatchPage(params)
|
||||
.then((res) => {
|
||||
this.createLoading = false;
|
||||
if (res.success && res.result) {
|
||||
this.createData = res.result.records || [];
|
||||
this.createTotal = res.result.total || 0;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.createLoading = false;
|
||||
});
|
||||
},
|
||||
issueChangePage(v) {
|
||||
this.issueSearchForm.pageNumber = v;
|
||||
this.loadIssueBatchList();
|
||||
},
|
||||
issueChangePageSize(v) {
|
||||
this.issueSearchForm.pageNumber = 1;
|
||||
this.issueSearchForm.pageSize = v;
|
||||
this.loadIssueBatchList();
|
||||
},
|
||||
handleIssueSearch() {
|
||||
this.issueSearchForm.pageNumber = 1;
|
||||
this.loadIssueBatchList();
|
||||
},
|
||||
loadIssueBatchList() {
|
||||
if (!this.activityId) {
|
||||
return;
|
||||
}
|
||||
this.issueLoading = true;
|
||||
const params = {
|
||||
activityId: this.activityId,
|
||||
pageNumber: this.issueSearchForm.pageNumber,
|
||||
pageSize: this.issueSearchForm.pageSize,
|
||||
sort: this.issueSearchForm.sort,
|
||||
order: this.issueSearchForm.order,
|
||||
};
|
||||
[
|
||||
"cardNo",
|
||||
"issueBatchId",
|
||||
"giftCardName",
|
||||
"issueUserName",
|
||||
].forEach((key) => {
|
||||
this.appendTrimmedParam(params, key, this.issueSearchForm[key]);
|
||||
});
|
||||
this.appendDateRangeToParams(
|
||||
params,
|
||||
this.issueSearchForm.createTimeRange,
|
||||
"createTimeStart",
|
||||
"createTimeEnd"
|
||||
);
|
||||
this.appendDateRangeToParams(
|
||||
params,
|
||||
this.issueSearchForm.expireTimeRange,
|
||||
"expireTimeStart",
|
||||
"expireTimeEnd"
|
||||
);
|
||||
getGiftCardCashIssueBatchPage(params)
|
||||
.then((res) => {
|
||||
this.issueLoading = false;
|
||||
if (res.success && res.result) {
|
||||
const r = res.result;
|
||||
this.issueData = r.records || r.list || r.recordsList || [];
|
||||
this.issueTotal = r.total != null ? r.total : r.totalCount || 0;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.issueLoading = false;
|
||||
});
|
||||
},
|
||||
handleUsageSearch() {
|
||||
this.usageSearchForm.pageNumber = 1;
|
||||
this.loadUsageRecordList();
|
||||
},
|
||||
usageChangePage(v) {
|
||||
this.usageSearchForm.pageNumber = v;
|
||||
this.loadUsageRecordList();
|
||||
},
|
||||
usageChangePageSize(v) {
|
||||
this.usageSearchForm.pageNumber = 1;
|
||||
this.usageSearchForm.pageSize = v;
|
||||
this.loadUsageRecordList();
|
||||
},
|
||||
formatUsageFlowType(type) {
|
||||
const map = {
|
||||
INCREASE: "增加",
|
||||
DECREASE: "减少",
|
||||
};
|
||||
return map[type] || type || "-";
|
||||
},
|
||||
formatUsageBizType(type) {
|
||||
const map = {
|
||||
ORDER_DEDUCT: "订单抵扣",
|
||||
ORDER_REFUND: "订单退款",
|
||||
ORDER_CANCEL: "订单取消",
|
||||
CARD_ACTIVATE: "卡激活",
|
||||
};
|
||||
return map[type] || type || "-";
|
||||
},
|
||||
getUsageAmountDisplay(row) {
|
||||
const raw =
|
||||
row.changeAmount != null && row.changeAmount !== "" ? row.changeAmount : row.deductAmount;
|
||||
if (raw === null || raw === undefined || raw === "") {
|
||||
return null;
|
||||
}
|
||||
const num = Number(raw);
|
||||
if (Number.isNaN(num)) {
|
||||
return null;
|
||||
}
|
||||
const txType = row.transactionType || row.bizType;
|
||||
let color = this.$mainColor;
|
||||
if (txType === "ORDER_DEDUCT") {
|
||||
color = "red";
|
||||
} else if (txType === "ORDER_REFUND") {
|
||||
color = "green";
|
||||
}
|
||||
return { amount: Math.abs(num), color };
|
||||
},
|
||||
loadUsageRecordList() {
|
||||
if (!this.activityId) {
|
||||
return;
|
||||
}
|
||||
this.usageLoading = true;
|
||||
const params = {
|
||||
pageNumber: this.usageSearchForm.pageNumber,
|
||||
pageSize: this.usageSearchForm.pageSize,
|
||||
sort: this.usageSearchForm.sort,
|
||||
order: this.usageSearchForm.order,
|
||||
};
|
||||
[
|
||||
"orderSn",
|
||||
"memberName",
|
||||
"cardNo",
|
||||
"transactionType",
|
||||
].forEach((key) => {
|
||||
this.appendTrimmedParam(params, key, this.usageSearchForm[key]);
|
||||
});
|
||||
this.appendDateRangeToParams(
|
||||
params,
|
||||
this.usageSearchForm.transactionTimeRange,
|
||||
"transactionTimeStart",
|
||||
"transactionTimeEnd"
|
||||
);
|
||||
getGiftCardCashUsageRecordPage(params)
|
||||
.then((res) => {
|
||||
this.usageLoading = false;
|
||||
if (res.success && res.result) {
|
||||
const r = res.result;
|
||||
this.usageData = r.records || r.list || [];
|
||||
this.usageTotal = r.total != null ? r.total : r.totalCount || 0;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.usageLoading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.gcc-records-toolbar {
|
||||
margin-bottom: 22px;
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 1px solid #e8eaec;
|
||||
}
|
||||
.gcc-records-back {
|
||||
font-weight: 500;
|
||||
}
|
||||
.gcc-records-meta {
|
||||
line-height: 1.6;
|
||||
color: #515a6e;
|
||||
}
|
||||
.gcc-create-batch-search.search-form {
|
||||
justify-content: flex-start;
|
||||
align-items: flex-end;
|
||||
flex-wrap: wrap;
|
||||
text-align: left;
|
||||
}
|
||||
/* 与全局 .search-form > .ivu-form-item 的 margin-left:10px 对齐到表格左缘 */
|
||||
.gcc-create-batch-search.search-form > .ivu-form-item:first-of-type {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.gcc-create-batch-search.search-form ::v-deep .ivu-form-item-label {
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
@@ -123,6 +123,17 @@ export default {
|
||||
this.$options.filters.unitPrice(params.row.kanjiaSettlementPrice, "¥")
|
||||
);
|
||||
},
|
||||
}, {
|
||||
title: '礼品卡补贴',
|
||||
key: 'giftCardSubsidy',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"div",
|
||||
this.$options.filters.unitPrice(params.row.giftCardSubsidy, "¥")
|
||||
);
|
||||
},
|
||||
}, {
|
||||
title: '分销佣金',
|
||||
key: 'distributionCommission',
|
||||
@@ -204,6 +215,19 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
}, {
|
||||
title: '礼品卡返还',
|
||||
key: 'giftCardRefundSubsidy',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {
|
||||
props: {
|
||||
value: (0 - params.row.giftCardRefundSubsidy),
|
||||
color: this.$mainColor
|
||||
}
|
||||
});
|
||||
},
|
||||
}, {
|
||||
title: '退单返还分销佣金',
|
||||
key: 'distributionRefundCommission',
|
||||
@@ -237,12 +261,14 @@ export default {
|
||||
siteCouponCommission: 0,
|
||||
pointSettlementPrice: 0,
|
||||
kanjiaSettlementPrice: 0,
|
||||
giftCardSubsidy: 0,
|
||||
distributionCommission: 0,
|
||||
commissionPrice: 0,
|
||||
refundPrice: 0,
|
||||
siteCouponRefundCommission: 0,
|
||||
pointRefundSettlementPrice: 0,
|
||||
kanjiaRefundSettlementPrice: 0,
|
||||
giftCardRefundSubsidy: 0,
|
||||
distributionRefundCommission: 0,
|
||||
refundCommissionPrice: 0
|
||||
},
|
||||
@@ -568,6 +594,8 @@ export default {
|
||||
// 账单详细
|
||||
initTable() {
|
||||
let bill = this.bill;
|
||||
const money = (val) =>
|
||||
val === null || val === undefined || val === "" ? 0 : val;
|
||||
|
||||
this.data[0].name = "结算单状态";
|
||||
this.data[0].value = filters.unixSellerBillStatus(bill.billStatus);
|
||||
@@ -596,19 +624,21 @@ export default {
|
||||
this.data[8].name = "支付时间";
|
||||
this.data[8].value = bill.payTime === null ? "未付款" : bill.payTime;
|
||||
|
||||
this.billData[0].billPrice = this.bill.billPrice;
|
||||
this.billData[0].orderPrice = this.bill.orderPrice;
|
||||
this.billData[0].siteCouponCommission = this.bill.siteCouponCommission;
|
||||
this.billData[0].pointSettlementPrice = this.bill.pointSettlementPrice;
|
||||
this.billData[0].kanjiaSettlementPrice = this.bill.kanjiaSettlementPrice;
|
||||
this.billData[0].distributionCommission = this.bill.distributionCommission;
|
||||
this.billData[0].commissionPrice = this.bill.commissionPrice;
|
||||
this.billData[0].refundPrice = this.bill.refundPrice;
|
||||
this.billData[0].siteCouponRefundCommission = this.bill.siteCouponRefundCommission;
|
||||
this.billData[0].pointRefundSettlementPrice = this.bill.pointRefundSettlementPrice;
|
||||
this.billData[0].kanjiaRefundSettlementPrice = this.bill.kanjiaRefundSettlementPrice;
|
||||
this.billData[0].distributionRefundCommission = this.bill.distributionRefundCommission;
|
||||
this.billData[0].refundCommissionPrice = this.bill.refundCommissionPrice;
|
||||
this.billData[0].billPrice = money(this.bill.billPrice);
|
||||
this.billData[0].orderPrice = money(this.bill.orderPrice);
|
||||
this.billData[0].siteCouponCommission = money(this.bill.siteCouponCommission);
|
||||
this.billData[0].pointSettlementPrice = money(this.bill.pointSettlementPrice);
|
||||
this.billData[0].kanjiaSettlementPrice = money(this.bill.kanjiaSettlementPrice);
|
||||
this.billData[0].giftCardSubsidy = money(this.bill.giftCardSubsidy);
|
||||
this.billData[0].distributionCommission = money(this.bill.distributionCommission);
|
||||
this.billData[0].commissionPrice = money(this.bill.commissionPrice);
|
||||
this.billData[0].refundPrice = money(this.bill.refundPrice);
|
||||
this.billData[0].siteCouponRefundCommission = money(this.bill.siteCouponRefundCommission);
|
||||
this.billData[0].pointRefundSettlementPrice = money(this.bill.pointRefundSettlementPrice);
|
||||
this.billData[0].kanjiaRefundSettlementPrice = money(this.bill.kanjiaRefundSettlementPrice);
|
||||
this.billData[0].giftCardRefundSubsidy = money(this.bill.giftCardRefundSubsidy);
|
||||
this.billData[0].distributionRefundCommission = money(this.bill.distributionRefundCommission);
|
||||
this.billData[0].refundCommissionPrice = money(this.bill.refundCommissionPrice);
|
||||
},
|
||||
getOrder() {
|
||||
API_Shop.getStoreFlow(this.id, this.orderParam).then((res) => {
|
||||
|
||||
@@ -280,7 +280,9 @@ export default {
|
||||
key: "paymentMethod",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.paymentMethod == "WECHAT") {
|
||||
if (params.row.paymentMethod == "NOT_ACTUALLY_PAID") {
|
||||
return h("div", {}, "-");
|
||||
} else if (params.row.paymentMethod == "WECHAT") {
|
||||
return h("div", {}, "微信支付");
|
||||
} else if (params.row.paymentMethod == "ALIPAY") {
|
||||
return h("div", {}, "支付宝");
|
||||
|
||||
Reference in New Issue
Block a user