This commit is contained in:
磷叶 2025-01-19 16:39:06 +08:00
parent 0aa3cdd763
commit 184ead5b2d
9 changed files with 163 additions and 47 deletions

View File

@ -0,0 +1,30 @@
<template>
<el-link :type="type" @click="handleClick" :disabled="id == null">{{text | defaultValue}}</el-link>
</template>
<script>
export default {
name: "VipOrderLink",
props: {
id: {
type: String,
default: null,
},
text: {
type: String,
default: null
},
type: {
type: String,
default: 'primary'
}
},
methods: {
handleClick() {
let url = `/view/vipOrder/${this.id}`;
this.$router.push(url)
}
}
}
</script>

View File

@ -1,7 +1,17 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="订单编号" prop="billNo" v-if="notHasView(views.recharge)">
<el-form-item label="业务类型" prop="bstType" v-if="notHasView([views.recharge, views.vipOrder])">
<el-select v-model="queryParams.bstType" placeholder="请选择业务类型" clearable @change="handleQuery" >
<el-option
v-for="dict in dict.type.bonus_bst_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="订单编号" prop="billNo" v-if="notHasView([views.recharge, views.vipOrder])">
<el-input
v-model="queryParams.billNo"
placeholder="请输入订单编号"
@ -37,7 +47,7 @@
/>
</el-select>
</el-form-item>
<el-form-item label="是否退款" prop="hasRefund">
<el-form-item label="是否退款" prop="hasRefund">
<el-select v-model="queryParams.hasRefund" placeholder="请选择是否有退款" clearable @change="handleQuery">
<el-option label="是" :value="true" />
<el-option label="否" :value="false" />
@ -87,6 +97,9 @@
<template v-else-if="column.key === 'arrivalType'">
<dict-tag :options="dict.type.bonus_arrival_type" :value="d.row[column.key]"/>
</template>
<template v-else-if="column.key === 'bstType'">
<dict-tag :options="dict.type.bonus_bst_type" :value="d.row[column.key]"/>
</template>
<template v-else-if="column.key === 'point'">
{{d.row.point | money | defaultValue}} %
</template>
@ -224,7 +237,7 @@ export default {
name: "Bonus",
components: { UserLink, BooleanTag },
mixins: [$showColumns, $view],
dicts: ['bonus_status', 'bonus_arrival_type'],
dicts: ['bonus_status', 'bonus_arrival_type', 'bonus_bst_type'],
props: {
query: {
type: Object,
@ -238,6 +251,7 @@ export default {
//
columns: [
{key: 'id', visible: false, label: '分成编号', minWidth: null, sortable: true, overflow: false, align: 'center', width: "100"},
{key: 'bstType', visible: true, label: '业务类型', minWidth: null, sortable: true, overflow: false, align: 'center', width: "100"},
{key: 'billNo', visible: true, label: '订单编号', minWidth: null, sortable: true, overflow: false, align: 'center', width: "180"},
{key: 'status', visible: true, label: '状态', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'arrivalName', visible: true, label: '收款方', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},

View File

@ -19,6 +19,22 @@
:default-time="['00:00:00', '23:59:59']"
/>
</el-form-item>
<el-form-item label="使用限制" prop="limitType">
<el-select v-model="form.limitType" placeholder="请选择使用限制" style="width: 100%;">
<el-option
v-for="dict in dict.type.vip_level_sku_limit_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="限制次数" prop="limitCount" v-if="form.limitType !== VipLevelSkuLimitType.NONE">
<el-input-number v-model="form.limitCount" placeholder="请输入限制次数" clearable controls-position="right" style="width: 100%;"/>
</el-form-item>
<el-form-item label="剩余次数" prop="surplusCount">
<el-input-number v-model="form.surplusCount" placeholder="请输入剩余次数" clearable controls-position="right" style="width: 100%;"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
@ -33,10 +49,12 @@ import StoreInput from '@/components/Business/Store/StoreInput.vue'
import VipLevelInput from '@/components/Business/VipLevel/VipLevelInput.vue'
import { addVip, getVip, updateVip } from '@/api/ss/vip'
import { $editDialog } from '@/utils/mixins'
import { VipLevelSkuLimitType } from '@/utils/constants'
export default {
name: "VipEditDialog",
mixins: [$editDialog],
dicts: ['vip_level_sku_limit_type'],
components: { VipLevelInput, StoreInput, UserInput },
props: {
rules: {
@ -48,11 +66,21 @@ export default {
levelId: [
{ required: true, message: "会员等级不能为空", trigger: "change" }
],
skuLimitType: [
{ required: true, message: "使用限制不能为空", trigger: "change" }
],
limitCount: [
{ required: true, message: "限制次数不能为空", trigger: "change" }
],
surplusCount: [
{ required: true, message: "剩余次数不能为空", trigger: "change" }
],
})
}
},
data() {
return {
VipLevelSkuLimitType,
}
},
computed: {
@ -88,6 +116,9 @@ export default {
levelId: null,
startTime: null,
endTime: null,
limitType: VipLevelSkuLimitType.NONE,
limitCount: null,
surplusCount: null,
};
this.resetForm("form");
},

View File

@ -47,19 +47,27 @@
{{d.row[column.key]}}
</template>
<template v-else-if="column.key === 'limitType'">
{{d.row[column.key] | defaultValue}} / <dict-tag :options="dict.type.vip_level_sku_limit_type" :value="d.row[column.key]"/>
</template>
<template v-else-if="column.key === 'roundCount'">
<dict-tag :options="dict.type.vip_level_sku_limit_type" :value="d.row[column.key]"/>
{{d.row[column.key] | defaultValue}}
</template>
<template v-else-if="column.key === 'totalCount'">
<template v-else-if="['roundCount', 'totalCount', 'surplusCount'].includes(column.key)">
{{d.row[column.key] | defaultValue}}
</template>
<template v-else-if="column.key === 'startTime'">
{{d.row.startTime | defaultValue}} {{d.row.endTime | defaultValue}}
开始{{d.row.startTime | defaultValue}}<br/>
结束{{d.row.endTime | defaultValue}}
</template>
<template v-else-if="column.key === 'storeList'">
<el-tag v-for="store in d.row[column.key]" :key="store.storeId" size="small" type="success">{{store.name | defaultValue}}</el-tag>
<template v-else-if="column.key === 'storeName'">
<store-link :id="d.row.storeId" :name="d.row.storeName"/>
</template>
<template v-else-if="column.key === 'inValid'">
<boolean-tag :value="d.row[column.key]"/>
</template>
<template v-else-if="column.key === 'userName'">
<user-link :id="d.row.userId" :name="d.row.userName"/>
</template>
<template v-else-if="column.key === 'mchName'">
<user-link :id="d.row.vipMchId" :name="d.row.mchName"/>
</template>
<template v-else>
{{d.row[column.key]}}
@ -86,7 +94,9 @@
<script>
import { listVip } from '@/api/ss/vip'
import { $showColumns } from '@/utils/mixins'
import StoreLink from '@/components/Business/Store/StoreLink.vue'
import BooleanTag from '@/components/BooleanTag/index.vue'
import UserLink from '@/components/Business/SmUser/UserLink.vue'
//
const defaultSort = {
prop: "createTime",
@ -96,20 +106,30 @@ export default {
name: 'VipTable',
mixins: [$showColumns],
dicts: ['vip_level_sku_limit_type'],
components: { StoreLink, BooleanTag, UserLink },
props: {
listApi: {
type: Function,
default: listVip
}
},
data() {
return {
//
columns: [
{key: 'id', visible: true, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: "80"},
{key: 'userName', visible: true, label: '用户', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'mchName', visible: true, label: '商户', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'vipLevelName', visible: true, label: '会员等级', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'storeList', visible: true, label: '可用店铺', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'startTime', visible: true, label: '有效期', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'nextResetTime', visible: true, label: '下次重置', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'totalCount', visible: true, label: '总计使用', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'storeName', visible: true, label: '可用店铺', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'inValid', visible: true, label: '有效状态', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'roundCount', visible: true, label: '当前周期使用', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'totalCount', visible: true, label: '总计使用', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'surplusCount', visible: true, label: '剩余次数', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'limitType', visible: true, label: '使用限制', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'createTime', visible: true, label: '创建时间', minWidth: null, sortable: false, overflow: false, align: 'center', width: null},
{key: 'startTime', visible: true, label: '有效期', minWidth: null, sortable: false, overflow: false, align: 'center', width: "200"},
{key: 'nextResetTime', visible: true, label: '下次重置', minWidth: null, sortable: false, overflow: false, align: 'center', width: "100"},
{key: 'createTime', visible: true, label: '创建时间', minWidth: null, sortable: false, overflow: false, align: 'center', width: "100"},
],
//
orderSorts: ['ascending', 'descending', null],
@ -154,7 +174,7 @@ export default {
/** 查询会员列表 */
getList() {
this.loading = true;
listVip(this.queryParams).then(response => {
this.listApi(this.queryParams).then(response => {
this.vipList = response.rows;
this.total = response.total;
this.loading = false;

View File

@ -35,13 +35,13 @@
</el-col>
</template>
<template v-slot:row-operator="scope">
<el-button
<!-- <el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['ss:vip:edit']"
>修改</el-button>
>修改</el-button> -->
<el-button
size="mini"
type="text"

View File

@ -52,9 +52,6 @@
<template v-else-if="column.key === 'discount'">
{{d.row.discount | dv}}
</template>
<template v-else-if="column.key === 'storeIds'">
<el-tag v-for="store in d.row.storeList" :key="store.storeId" type="primary">{{store.name}}</el-tag>
</template>
<template v-else>
{{d.row[column.key]}}
</template>
@ -107,7 +104,7 @@ export default {
{key: 'name', visible: true, label: '等级名称', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'discount', visible: true, label: '折扣', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'description', visible: true, label: '描述文本', minWidth: null, sortable: true, overflow: true, align: 'center', width: null},
{key: 'storeIds', visible: true, label: '可用店铺', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'storeName', visible: true, label: '可用店铺', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'createTime', visible: true, label: '创建时间', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
],
//

View File

@ -1,5 +1,5 @@
<template>
<el-dialog :title="title" :visible.sync="open" width="1400px" append-to-body @open="onOpen">
<el-dialog :title="title" :visible.sync="open" width="1480px" append-to-body @open="onOpen">
<el-form ref="form" :model="form" :rules="rules" label-width="80px" v-loading="loading">
<el-row :gutter="8">
<form-col :span="span" label="商户" prop="mchId" v-if="visibleColumn('mchId')">
@ -11,12 +11,12 @@
<form-col :span="span" label="折扣" prop="discount">
<el-input-number v-model="form.discount" placeholder="请输入折扣" :min="0" :max="10" style="width: calc(100% - 2em)" controls-position="right"/>
</form-col>
<form-col :span="span" label="可用店铺" prop="storeId">
<store-input v-model="form.storeId" placeholder="请选择店铺" :query="storeQuery" :before-open="beforeOpenStore"/>
</form-col>
<form-col :span="24" label="描述" prop="description">
<el-input v-model="form.description" type="textarea" placeholder="请输入内容" maxlength="1000" show-word-limit/>
</form-col>
<form-col :span="24" label="可用店铺" prop="storeIds">
<store-input v-model="form.storeIds" placeholder="请选择店铺" multiple :query="storeQuery" :before-open="beforeOpenStore"/>
</form-col>
</el-row>
<el-tabs>
@ -87,6 +87,11 @@
<el-input-number v-model="row.limitCount" placeholder="请输入限制次数" style="width: 100%" :step="1" :min="0" step-sticky controls-position="right"/>
</template>
</table-form-col>
<table-form-col label="总次数限制" prop="limitTotal" prop-prefix="skuList" tips="总次数限制,多次购买相同权益会员则叠加">
<template #default="{row}">
<el-input-number v-model="row.limitTotal" placeholder="请输入限制次数" style="width: 100%" :step="1" :min="0" step-sticky controls-position="right"/>
</template>
</table-form-col>
<table-form-col label="描述" prop="description" prop-prefix="skuList">
<template #default="{row}">
<el-input
@ -129,8 +134,9 @@ import VipLevelInput from '@/components/Business/VipLevel/VipLevelInput.vue'
import TableFormCol from '@/components/TableFormCol/index.vue'
import { $editDialog, $showColumns } from '@/utils/mixins'
import { addVipLevel, getVipLevel, updateVipLevel } from '@/api/ss/vipLevel'
import { SmUserType, VipLevelSkuStatus, VipLevelSkuLimitType } from '@/utils/constants'
import { SmUserType, VipLevelSkuStatus, VipLevelSkuLimitType, UserType } from '@/utils/constants'
import FormCol from '@/components/FormCol/index.vue'
import { mapGetters } from 'vuex'
export default {
name: "VipLevelEditDialog",
@ -145,19 +151,19 @@ export default {
{ required: true, message: "商户不能为空", trigger: "change" }
],
name: [
{ required: true, message: "等级名称不能为空", trigger: "blur" }
{ required: true, message: "等级名称不能为空", trigger: "change" }
],
status: [
{ required: true, message: "状态不能为空", trigger: "change" }
],
discount: [
{ required: true, message: "折扣不能为空", trigger: "blur" }
{ required: true, message: "折扣不能为空", trigger: "change" }
],
storeIds: [
{ required: true, type: 'array', message: "可用店铺不能为空", trigger: "blur" }
storeId: [
{ required: true, message: "可用店铺不能为空", trigger: "change" }
],
skuList: [
{ required: true, type: 'array', message: "定价不能为空", trigger: "blur" },
{ required: true, type: 'array', message: "定价不能为空", trigger: "change" },
]
})
},
@ -179,11 +185,12 @@ export default {
form: {},
title: null,
loading: false,
span: 8,
span: 6,
submitLoading: false
}
},
computed: {
...mapGetters(['userType', 'userId']),
storeQuery() {
return {
userId: this.form.mchId
@ -218,14 +225,12 @@ export default {
this.title = "新增会员等级";
this.form = {
id: null,
mchId: null,
mchId: this.userType == UserType.APP ? this.userId : null,
name: null,
discount: null,
createTime: null,
description: null,
price: null,
time: null,
storeIds: [],
storeId: null,
skuList: []
};
this.resetForm("form");

View File

@ -115,6 +115,9 @@
<template v-if="column.key === 'id'">
{{d.row[column.key]}}
</template>
<template v-else-if="column.key === 'orderNo'">
<vip-order-link :id="d.row.id" :text="d.row.orderNo"/>
</template>
<template v-else-if="column.key === 'skuLimitType'">
<dict-tag :options="dict.type.vip_level_sku_limit_type" :value="d.row[column.key]"/>
</template>
@ -130,6 +133,9 @@
<template v-else-if="column.key === 'mchName'">
<user-link :id="d.row.mchId" :name="d.row.mchName"/>
</template>
<template v-else-if="column.key === 'storeName'">
<store-link :id="d.row.levelStoreId" :name="d.row.storeName"/>
</template>
<template v-else-if="column.key === 'levelDiscount'">
{{d.row[column.key] | dv}}
</template>
@ -174,6 +180,8 @@
<script>
import { listVipOrder, getVipOrder, delVipOrder, addVipOrder, updateVipOrder } from "@/api/ss/vipOrder";
import UserLink from "@/components/Business/SmUser/UserLink.vue";
import StoreLink from "@/components/Business/Store/StoreLink.vue";
import VipOrderLink from "@/components/Business/VipOrder/VipOrderLink.vue";
import { $showColumns } from '@/utils/mixins';
//
@ -185,7 +193,7 @@ const defaultSort = {
export default {
name: "VipOrder",
mixins: [$showColumns],
components: { UserLink },
components: { UserLink, StoreLink, VipOrderLink },
dicts: ['vip_level_sku_limit_type', 'vip_order_status','vip_level_solution'],
data() {
return {
@ -193,17 +201,18 @@ export default {
columns: [
{key: 'id', visible: false, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'orderNo', visible: true, label: '订单编号', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'status', visible: true, label: '状态', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'userName', visible: true, label: '用户', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'mchName', visible: true, label: '商户', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'storeName', visible: true, label: '店铺', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'levelName', visible: true, label: '等级', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'status', visible: true, label: '状态', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'amount', visible: true, label: '金额', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'levelDiscount', visible: true, label: '折扣', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'levelSolution', visible: true, label: '续费方案', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'skuName', visible: true, label: 'SKU', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'skuTime', visible: true, label: '购买时长', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'skuLimitType', visible: true, label: '使用限制', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'skuLimitCount', visible: true, label: '限制次数', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'amount', visible: true, label: '金额', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'createTime', visible: true, label: '下单时间', minWidth: null, sortable: true, overflow: false, align: 'center', width: "100"},
{key: 'expireTime', visible: false, label: '过期时间', minWidth: null, sortable: false, overflow: false, align: 'center', width: "100"},
{key: 'payNo', visible: true, label: '支付订单', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},

View File

@ -54,10 +54,13 @@
<user-link :id="detail.mchId" :name="detail.mchName"/>
</el-descriptions-item>
<el-descriptions-item label="下单时间">
{{ detail.createTime }}
{{ detail.createTime | dv }}
</el-descriptions-item>
<el-descriptions-item label="过期时间">
{{ detail.expireTime }}
<!-- <el-descriptions-item label="过期时间">
{{ detail.expireTime | dv }}
</el-descriptions-item> -->
<el-descriptions-item label="VIP等级">
{{ detail.levelName | dv }}
</el-descriptions-item>
<el-descriptions-item label="SKU名称">
{{ detail.skuName }}
@ -70,11 +73,17 @@
</template>
</div>
</el-descriptions-item>
<el-descriptions-item label="续费次数">
{{ detail.skuLimitTotal | dv }}
</el-descriptions-item>
<el-descriptions-item label="续费方案">
<dict-tag :options="dict.type.vip_level_solution" :value="detail.levelSolution" size="small"/>
</el-descriptions-item>
<el-descriptions-item label="可用店铺" :span="2">
<el-tag v-for="store in detail.storeNameList" :key="store.storeId" size="small">{{store.name | dv}}</el-tag>
<el-descriptions-item label="可用店铺">
<store-link :id="detail.levelStoreId" :name="detail.storeName"/>
</el-descriptions-item>
<el-descriptions-item label="支付渠道">
{{ detail.channelName | dv }}
</el-descriptions-item>
</el-descriptions>
@ -103,13 +112,14 @@
<script>
import { getVipOrder } from "@/api/ss/vipOrder";
import UserLink from "@/components/Business/SmUser/UserLink.vue";
import StoreLink from "@/components/Business/Store/StoreLink.vue";
import { VipOrderStatus, PayBillBstType, views} from "@/utils/constants";
import Bonus from "@/views/ss/bonus/index.vue";
import PayBill from "@/views/ss/payBill/index.vue";
export default {
name: "VipOrderView",
components: { UserLink, Bonus, PayBill },
components: { UserLink, Bonus, PayBill, StoreLink },
dicts: ['vip_level_sku_limit_type', 'vip_order_status', 'vip_level_solution'],
data() {
return {