This commit is contained in:
2025-10-31 15:30:59 +08:00
parent 40d66ae230
commit 7026d1fe1d
3 changed files with 214 additions and 28 deletions

View File

@@ -9,7 +9,7 @@ export function listGiftCoupons(query) {
}) })
} }
// 礼金详情 // 礼金详情(包含关联订单)
export function getGiftCoupon(giftCouponKey) { export function getGiftCoupon(giftCouponKey) {
return request({ return request({
url: `/system/giftcoupon/${giftCouponKey}`, url: `/system/giftcoupon/${giftCouponKey}`,

View File

@@ -243,6 +243,23 @@ export const dynamicRoutes = [
} }
] ]
}, },
// 礼金管理
{
path: '/giftcoupon',
component: Layout,
redirect: 'noredirect',
name: 'GiftCoupon',
meta: { title: '礼金管理', icon: 'money' },
permissions: ['system:giftcoupon:list'],
children: [
{
path: 'index',
component: () => import('@/views/system/giftcoupon/index'),
name: 'GiftCouponIndex',
meta: { title: '礼金列表', icon: 'gift' }
}
]
},
// 系统管理 // 系统管理
{ {
path: '/system', path: '/system',

View File

@@ -40,6 +40,7 @@
<el-form-item> <el-form-item>
<el-button type="primary" size="small" icon="el-icon-search" @click="handleQuery">搜索</el-button> <el-button type="primary" size="small" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button size="small" icon="el-icon-refresh" @click="resetQuery">重置</el-button> <el-button size="small" icon="el-icon-refresh" @click="resetQuery">重置</el-button>
<el-button type="success" size="small" icon="el-icon-plus" @click="handleCreate">创建礼金</el-button>
<el-button type="warning" size="small" icon="el-icon-download" @click="handleExport" v-hasPermi="['system:giftcoupon:export']">导出</el-button> <el-button type="warning" size="small" icon="el-icon-download" @click="handleExport" v-hasPermi="['system:giftcoupon:export']">导出</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@@ -147,30 +148,97 @@
</template> </template>
</list-layout> </list-layout>
<!-- 创建礼金对话框 -->
<el-dialog title="创建礼金" :visible.sync="createDialogVisible" width="500px" append-to-body>
<el-form :model="createForm" :rules="createRules" ref="createForm" label-width="120px">
<el-form-item label="商品链接/SKU" prop="materialUrl">
<el-input v-model="createForm.materialUrl" placeholder="请输入商品链接或SKU ID" />
</el-form-item>
<el-form-item label="商品名称" prop="skuName">
<el-input v-model="createForm.skuName" placeholder="商品名称(可选)" />
</el-form-item>
<el-form-item label="商品类型" prop="owner">
<el-radio-group v-model="createForm.owner">
<el-radio label="g">自营</el-radio>
<el-radio label="pop">POP</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="礼金金额(元)" prop="amount">
<el-input-number v-model="createForm.amount" :min="0.01" :max="50" :precision="2" :step="0.01" style="width: 100%" />
<div style="color: #909399; font-size: 12px; margin-top: 5px;">范围1-50</div>
</el-form-item>
<el-form-item label="礼金数量" prop="quantity">
<el-input-number v-model="createForm.quantity" :min="1" :max="100" style="width: 100%" />
<div style="color: #909399; font-size: 12px; margin-top: 5px;">范围1-100</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="createDialogVisible = false"> </el-button>
<el-button type="primary" :loading="createLoading" @click="submitCreate"> </el-button>
</div>
</el-dialog>
<!-- 详情对话框 --> <!-- 详情对话框 -->
<el-dialog title="礼金详情" :visible.sync="detailVisible" width="600px" append-to-body> <el-dialog title="礼金详情" :visible.sync="detailVisible" width="1000px" append-to-body>
<el-descriptions :column="2" border v-if="currentRow"> <div v-if="detailData && detailData.giftCoupon">
<el-descriptions-item label="礼金Key" :span="2">{{ currentRow.giftCouponKey }}</el-descriptions-item> <el-tabs v-model="activeDetailTab">
<el-descriptions-item label="商品SKU">{{ currentRow.skuId }}</el-descriptions-item> <el-tab-pane label="基本信息" name="info">
<el-descriptions-item label="商品名称" :span="2">{{ currentRow.skuName }}</el-descriptions-item> <el-descriptions :column="2" border style="margin-top: 20px;">
<el-descriptions-item label="类型"> <el-descriptions-item label="礼金Key" :span="2">
<el-tag :type="currentRow.owner === 'g' ? 'success' : 'warning'"> <span style="margin-right: 10px;">{{ detailData.giftCoupon.giftCouponKey }}</span>
{{ currentRow.owner === 'g' ? '自营' : 'POP' }} <el-button type="text" size="mini" icon="el-icon-copy-document" @click="copyToClipboard(detailData.giftCoupon.giftCouponKey)">复制</el-button>
</el-tag> </el-descriptions-item>
</el-descriptions-item> <el-descriptions-item label="商品SKU">{{ detailData.giftCoupon.skuId }}</el-descriptions-item>
<el-descriptions-item label="使用次数">{{ currentRow.useCount }}</el-descriptions-item> <el-descriptions-item label="商品名称" :span="2">{{ detailData.giftCoupon.skuName }}</el-descriptions-item>
<el-descriptions-item label="总分摊金额">¥{{ formatMoney(currentRow.totalOcsAmount || 0) }}</el-descriptions-item> <el-descriptions-item label="类型">
<el-descriptions-item label="创建时间">{{ parseTime(currentRow.createTime) }}</el-descriptions-item> <el-tag :type="detailData.giftCoupon.owner === 'g' ? 'success' : 'warning'">
<el-descriptions-item label="过期时间"> {{ detailData.giftCoupon.owner === 'g' ? '自营' : 'POP' }}
<span v-if="currentRow.expireTime">{{ parseTime(currentRow.expireTime) }}</span> </el-tag>
<span v-else>-</span> </el-descriptions-item>
</el-descriptions-item> <el-descriptions-item label="使用次数">{{ detailData.giftCoupon.useCount }}</el-descriptions-item>
<el-descriptions-item label="过期状态" :span="2"> <el-descriptions-item label="总分摊金额">¥{{ formatMoney(detailData.giftCoupon.totalOcsAmount || 0) }}</el-descriptions-item>
<el-tag :type="currentRow.isExpired === 1 ? 'danger' : 'success'"> <el-descriptions-item label="创建时间">{{ parseTime(detailData.giftCoupon.createTime) }}</el-descriptions-item>
{{ currentRow.isExpired === 1 ? '已过期' : '未过期' }} <el-descriptions-item label="过期时间">
</el-tag> <span v-if="detailData.giftCoupon.expireTime">{{ parseTime(detailData.giftCoupon.expireTime) }}</span>
</el-descriptions-item> <span v-else>-</span>
</el-descriptions> </el-descriptions-item>
<el-descriptions-item label="过期状态" :span="2">
<el-tag :type="detailData.giftCoupon.isExpired === 1 ? 'danger' : 'success'">
{{ detailData.giftCoupon.isExpired === 1 ? '已过期' : '未过期' }}
</el-tag>
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="关联订单" name="orders">
<el-table :data="detailData.orders || []" border style="margin-top: 20px;" max-height="400">
<el-table-column label="订单号" prop="orderId" width="200" />
<el-table-column label="商品名称" prop="skuName" min-width="200" show-overflow-tooltip />
<el-table-column label="商品SKU" prop="skuId" width="120" />
<el-table-column label="订单金额" prop="price" width="100">
<template slot-scope="scope">¥{{ formatMoney(scope.row.price || 0) }}</template>
</el-table-column>
<el-table-column label="礼金分摊" prop="giftCouponOcsAmount" width="100">
<template slot-scope="scope">¥{{ formatMoney(scope.row.giftCouponOcsAmount || 0) }}</template>
</el-table-column>
<el-table-column label="下单时间" prop="orderTime" width="160">
<template slot-scope="scope">{{ parseTime(scope.row.orderTime) }}</template>
</el-table-column>
<el-table-column label="短链" width="200">
<template slot-scope="scope">
<div v-if="scope.row.positionId">
<a :href="getShortUrl(scope.row.positionId)" target="_blank" style="margin-right: 8px;">查看短链</a>
<el-button type="text" size="mini" icon="el-icon-copy-document" @click="copyToClipboard(getShortUrl(scope.row.positionId))">复制</el-button>
</div>
<span v-else>-</span>
</template>
</el-table-column>
</el-table>
<div v-if="!detailData.orders || detailData.orders.length === 0" style="text-align: center; padding: 40px; color: #909399;">
暂无关联订单
</div>
</el-tab-pane>
</el-tabs>
</div>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button @click="detailVisible = false"> </el-button> <el-button @click="detailVisible = false"> </el-button>
</div> </div>
@@ -179,7 +247,8 @@
</template> </template>
<script> <script>
import { listGiftCoupons, getGiftCouponStatistics, exportGiftCoupons } from '@/api/system/giftcoupon' import { listGiftCoupons, getGiftCoupon, getGiftCouponStatistics, exportGiftCoupons } from '@/api/system/giftcoupon'
import { createGiftCoupon, transferWithGift } from '@/api/system/jdorder'
import ListLayout from '@/components/ListLayout' import ListLayout from '@/components/ListLayout'
import { parseTime } from '@/utils/ruoyi' import { parseTime } from '@/utils/ruoyi'
@@ -211,7 +280,22 @@ export default {
totalOcsAmount: 0 totalOcsAmount: 0
}, },
detailVisible: false, detailVisible: false,
currentRow: null detailData: null,
activeDetailTab: 'info',
createDialogVisible: false,
createLoading: false,
createForm: {
materialUrl: '',
skuName: '',
owner: 'g',
amount: null,
quantity: 10
},
createRules: {
materialUrl: [{ required: true, message: '请输入商品链接或SKU', trigger: 'blur' }],
amount: [{ required: true, message: '请输入礼金金额', trigger: 'blur' }],
quantity: [{ required: true, message: '请输入礼金数量', trigger: 'blur' }]
}
} }
}, },
created() { created() {
@@ -291,10 +375,95 @@ export default {
this.exportLoading = false this.exportLoading = false
}) })
}, },
/** 创建礼金 */
handleCreate() {
this.createForm = {
materialUrl: '',
skuName: '',
owner: 'g',
amount: null,
quantity: 10
}
this.createDialogVisible = true
},
/** 提交创建礼金 */
async submitCreate() {
this.$refs.createForm.validate(async (valid) => {
if (!valid) return
if (!this.createForm.amount || this.createForm.amount < 0.01 || this.createForm.amount > 50) {
this.$modal.msgError('礼金金额必须在0.01-50元之间')
return
}
if (!this.createForm.quantity || this.createForm.quantity < 1 || this.createForm.quantity > 100) {
this.$modal.msgError('礼金数量必须在1-100之间')
return
}
this.createLoading = true
try {
const params = {
materialUrl: this.createForm.materialUrl,
amount: this.createForm.amount,
quantity: this.createForm.quantity,
owner: this.createForm.owner,
skuName: this.createForm.skuName
}
const res = await createGiftCoupon(params)
if (res && res.code === 200) {
const giftKey = (res.data && (res.data.giftCouponKey || res.data.giftKey)) || (typeof res.data === 'string' ? res.data : null)
if (giftKey) {
// 可选:自动生成短链
try {
await transferWithGift({ materialUrl: this.createForm.materialUrl, giftCouponKey: giftKey })
this.$modal.msgSuccess('礼金创建成功,短链已生成')
} catch (e) {
this.$modal.msgSuccess('礼金创建成功')
}
} else {
this.$modal.msgSuccess('礼金创建成功')
}
this.createDialogVisible = false
this.getList()
this.loadStatistics()
} else {
this.$modal.msgError(res.msg || '创建失败')
}
} catch (e) {
this.$modal.msgError('创建失败:' + (e.message || '未知错误'))
} finally {
this.createLoading = false
}
})
},
/** 查看详情 */ /** 查看详情 */
handleDetail(row) { async handleDetail(row) {
this.currentRow = row this.activeDetailTab = 'info'
this.detailVisible = true this.detailVisible = true
try {
const res = await getGiftCoupon(row.giftCouponKey)
if (res && res.code === 200) {
if (res.data.giftCoupon) {
this.detailData = res.data
} else {
// 兼容直接返回GiftCoupon对象的情况
this.detailData = {
giftCoupon: res.data,
orders: []
}
}
} else {
this.$modal.msgError('获取详情失败')
this.detailVisible = false
}
} catch (e) {
this.$modal.msgError('获取详情失败')
this.detailVisible = false
}
},
/** 生成短链URL */
getShortUrl(positionId) {
// 根据positionId生成短链这里需要根据实际情况调整
if (!positionId) return ''
return `https://u.jd.com/${positionId}`
}, },
/** 复制到剪贴板 */ /** 复制到剪贴板 */
copyToClipboard(text) { copyToClipboard(text) {