临时提交

This commit is contained in:
磷叶 2025-05-19 18:10:55 +08:00
parent d8b9e4ef04
commit d0e47d8a35
6 changed files with 229 additions and 67 deletions

View File

@ -72,3 +72,12 @@ export function verifyOrder(data) {
data: data
})
}
// 订单押金抵扣
export function deductOrder(data) {
return request({
url: '/bst/order/deduct',
method: 'put',
data: data
})
}

View File

@ -153,13 +153,14 @@ export const AreaJoinType = {
// 订单状态
export const OrderStatus = {
WAIT_PAY: "WAIT_PAY", // 待支付
WAIT_PAY: "WAIT_PAY", // 押金待支付
PROCESSING: "PROCESSING", // 进行中
FINISHED: "FINISHED", // 已结束
CANCELED: "CANCELED", // 已取消
WAIT_VERIFY: "WAIT_VERIFY", // 待审核
REJECTED: "REJECTED", // 已驳回
REFUNDED: "REFUNDED", // 已退款
RIDE_WAIT_PAY: "RIDE_WAIT_PAY", // 骑行费待支付
// 允许支付的订单状态
canPay() {
@ -200,7 +201,15 @@ export const OrderStatus = {
// 已完成的订单状态
finishedList() {
return [this.FINISHED, this.WAIT_VERIFY, this.REJECTED, this.REFUNDED];
}
},
// 允许押金抵扣的订单状态
canDeduct() {
return [this.RIDE_WAIT_PAY];
},
// 允许骑行支付成功的订单状态
canRidePaySuccess() {
return [this.RIDE_WAIT_PAY];
},
}
// 支付业务类型

View File

@ -0,0 +1,104 @@
<template>
<el-dialog
title="还车审核"
:visible.sync="dialogVisible"
width="500px"
append-to-body
@open="handleOpen"
>
<el-form :model="form" :rules="rules" ref="form" label-width="5em" v-loading="loading" size="small">
<el-form-item label="抵扣金额" prop="amount">
<el-input-number
v-model="form.amount"
type="number"
placeholder="请输入抵扣金额"
:min="0"
controls-position="right"
style="width: 100%;"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="success" plain @click="handleSubmit()" icon="el-icon-check" :loading="submitLoading">确定</el-button>
<el-button plain @click="handleCancel()" icon="el-icon-close" :loading="submitLoading">取消</el-button>
</div>
</el-dialog>
</template>
<script>
import { deductOrder, getOrder } from '@/api/bst/order';
export default {
props: {
id: {
type: String,
default: null
},
visible: {
type: Boolean,
default: false
}
},
data() {
return {
detail: {},
form: {},
loading: false,
submitLoading: false,
rules: {
}
}
},
computed: {
dialogVisible: {
get() {
return this.visible;
},
set(val) {
this.$emit('update:visible', val);
}
},
},
methods: {
getDetail() {
this.loading = true;
getOrder(this.id).then(response => {
this.detail = response.data;
}).finally(() => {
this.loading = false;
});
},
handleOpen() {
this.getDetail();
this.reset();
},
reset() {
this.form = {
id: this.id,
amount: null,
};
this.resetForm('form');
},
handleSubmit() {
this.$refs.form.validate().then(() => {
this.submitLoading = true;
deductOrder(this.form).then((response) => {
if (response.code == 200) {
this.$message.success('操作成功');
this.dialogVisible = false;
this.$emit('success');
}
}).finally(() => {
this.submitLoading = false;
});
});
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -150,10 +150,12 @@
<br/>
<dict-tag :options="dict.type.suit_type" :value="d.row.suitType" size="mini"/>
<dict-tag :options="dict.type.suit_riding_rule" :value="d.row.suitRidingRule" size="mini" style="margin-left: 4px;"/>
<el-tag v-if="d.row.suitDepositDeduction" type="success" size="mini">自动抵扣</el-tag>
</template>
<template v-else-if="column.key === 'returnType'">
<dict-tag :options="dict.type.order_return_type" :value="d.row.returnType" size="mini"/>
<dict-tag :options="dict.type.order_return_mode" :value="d.row.returnMode" size="mini"/>
<dict-tag :options="dict.type.order_pay_type" :value="d.row.payType" size="mini"/>
</template>
<template v-else-if="column.key === 'suitRentalUnit'">
<dict-tag :options="dict.type.suit_rental_unit" :value="d.row[column.key]" size="mini"/>
@ -270,6 +272,14 @@
v-has-permi="['bst:order:verify']"
v-show="OrderStatus.canVerify().includes(scope.row.status)"
>审核</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-wallet"
@click="handleDeduct(scope.row)"
v-has-permi="['bst:order:deduct']"
v-show="OrderStatus.canDeduct().includes(scope.row.status)"
>押金抵扣</el-button>
</template>
</el-table-column>
</el-table>
@ -285,6 +295,8 @@
<order-refund-dialog :id="row.id" :visible.sync="showRefundDialog" @success="getList" />
<order-verify-dialog :id="row.id" :visible.sync="showVerifyDialog" @success="getList" />
<order-deduct-dialog :id="row.id" :visible.sync="showDeductDialog" @success="getList" />
</div>
</template>
@ -300,6 +312,7 @@ import FormCol from "@/components/FormCol/index.vue";
import { toDescriptionFromSecond } from '@/utils/date';
import { OrderStatus } from "@/utils/enums";
import { $showColumns } from '@/utils/mixins';
import OrderDeductDialog from "@/views/bst/order/components/OrderDeductDialog.vue";
import OrderRefundDialog from "@/views/bst/order/components/OrderRefundDialog.vue";
import OrderVerifyDialog from "@/views/bst/order/components/OrderVerifyDialog.vue";
import { getOrderDuration } from '@/views/bst/order/util.js';
@ -313,8 +326,8 @@ const defaultSort = {
export default {
name: "Order",
mixins: [$showColumns],
dicts: ['order_status', 'suit_type', 'order_return_type', 'order_return_mode', 'suit_rental_unit', 'suit_riding_rule', 'device_status'],
components: {FormCol, OrderRefundDialog, OrderVerifyDialog, UserLink, DeviceLink, OrderLink, AreaLink, AreaRemoteSelect},
dicts: ['order_status', 'suit_type', 'order_return_type', 'order_return_mode', 'suit_rental_unit', 'suit_riding_rule', 'device_status', 'order_pay_type'],
components: {FormCol, OrderRefundDialog, OrderVerifyDialog, OrderDeductDialog, UserLink, DeviceLink, OrderLink, AreaLink, AreaRemoteSelect},
props: {
query: {
type: Object,
@ -387,6 +400,7 @@ export default {
row: {},
showRefundDialog: false,
showVerifyDialog: false,
showDeductDialog: false,
};
},
created() {
@ -396,6 +410,10 @@ export default {
methods: {
getOrderDuration,
toDescriptionFromSecond,
handleDeduct(row) {
this.row = row;
this.showDeductDialog = true;
},
handleVerify(row) {
this.row = row;
this.showVerifyDialog = true;

View File

@ -7,7 +7,7 @@
:close-on-click-modal="false"
@open="handleOpen"
>
<el-form ref="form" :model="form" :rules="rules" label-width="80px" size="small" v-loading="loading">
<el-form ref="form" :model="form" :rules="rules" label-width="6em" size="small" v-loading="loading">
<el-row :gutter="10">
<form-col :span="span" label="所属用户" prop="userId">
<user-input v-model="form.userId" :text.sync="form.userName" :disabled="!checkPermi(['system:user:list'])"/>
@ -15,15 +15,6 @@
<form-col :span="span" label="套餐名称" prop="name">
<el-input v-model="form.name" placeholder="请输入套餐名称" />
</form-col>
<form-col :span="24" label="适用车型" prop="modelIds">
<model-remote-select
:before-get-options="beforeGetModelOptions"
v-model="form.modelIds"
multiple
:query="modelQuery"
style="width: 100%;"
/>
</form-col>
<form-col :span="span" label="套餐类型" prop="type">
<el-select v-model="form.type" placeholder="请选择套餐类型" style="width: 100%;">
<el-option
@ -34,10 +25,49 @@
></el-option>
</el-select>
</form-col>
<form-col :span="span" label="预存金额" prop="depositAmount">
<form-col :span="span" label="显示顺序" prop="orderNum">
<el-input-number v-model="form.orderNum" placeholder="请输入显示顺序" controls-position="right" :min="0" style="width: 100%;" />
</form-col>
<form-col :span="span" label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.suit_status"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</form-col>
<form-col :span="24" label="说明" prop="instructions">
<el-input v-model="form.instructions" type="textarea" placeholder="请输入内容" maxlength="1000" show-word-limit :autosize="{ minRows: 3, maxRows: 10 }"/>
</form-col>
</el-row>
<el-row :gutter="10">
<collapse-panel title="计费规则" :value="true">
<form-col :span="span" label="计费方式" prop="ridingRule">
<el-select v-model="form.ridingRule" placeholder="请选择计费方式" style="width: 100%;" >
<el-option
v-for="dict in dict.type.suit_riding_rule"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</form-col>
<form-col :span="span" label="租赁单位" prop="rentalUnit">
<el-select v-model="form.rentalUnit" placeholder="请选择租赁单位" style="width: 100%;">
<el-option
v-for="dict in dict.type.suit_rental_unit"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</form-col>
<form-col :span="span" label="押金金额" prop="depositAmount">
<el-input-number
v-model="form.depositAmount"
placeholder="请输入预存金额"
placeholder="请输入押金金额"
type="number"
:precision="2"
controls-position="right"
@ -55,44 +85,6 @@
style="width: calc(100% - 3em)"
/>
</form-col>
<form-col :span="span" label="显示顺序" prop="orderNum">
<el-input-number v-model="form.orderNum" placeholder="请输入显示顺序" controls-position="right" :min="0" style="width: 100%;" />
</form-col>
<form-col :span="span" label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.suit_status"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</form-col>
<form-col :span="24" label="说明" prop="instructions">
<el-input v-model="form.instructions" type="textarea" placeholder="请输入内容" maxlength="1000" show-word-limit :autosize="{ minRows: 3, maxRows: 10 }"/>
</form-col>
<form-col :span="span" label="租赁单位" prop="rentalUnit">
<el-select v-model="form.rentalUnit" placeholder="请选择租赁单位" style="width: 100%;">
<el-option
v-for="dict in dict.type.suit_rental_unit"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</form-col>
<form-col :span="span" label="计费方式" prop="ridingRule">
<el-select v-model="form.ridingRule" placeholder="请选择计费方式" style="width: 100%;" >
<el-option
v-for="dict in dict.type.suit_riding_rule"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</form-col>
</el-row>
<el-row :gutter="10">
<collapse-panel title="计费规则" :value="true">
<template v-if="form.ridingRule === SuitRidingRule.START && form.startRule">
<div class="rule-row">
@ -198,6 +190,23 @@
</template>
</collapse-panel>
</el-row>
<el-row>
<collapse-panel title="更多设置" :value="true">
<form-col :span="24" label="押金自动抵扣" label-width="8em" prop="depositDeduction" tip="开启后,订单结束后将自动进行押金抵扣,并将剩余金额退还给用户">
<el-switch v-model="form.depositDeduction" active-text="开启" inactive-text="关闭"/>
</form-col>
<form-col :span="24" label="适用车型" prop="modelIds">
<model-remote-select
:before-get-options="beforeGetModelOptions"
v-model="form.modelIds"
multiple
:query="modelQuery"
style="width: 100%;"
/>
</form-col>
</collapse-panel>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
@ -207,14 +216,14 @@
</template>
<script>
import { getSuit, addSuit, updateSuit } from "@/api/bst/suit";
import FormCol from "@/components/FormCol/index.vue";
import UserInput from '@/components/Business/User/UserInput.vue';
import { SuitRentalUnit, SuitRidingRule, SuitStatus, RoleKeys, SuitType } from '@/utils/enums';
import CollapsePanel from '@/components/CollapsePanel/index.vue';
import { deepClone, dictLabel } from '@/utils';
import { mapGetters } from 'vuex';
import { addSuit, getSuit, updateSuit } from "@/api/bst/suit";
import ModelRemoteSelect from '@/components/Business/Model/ModelRemoteSelect.vue';
import UserInput from '@/components/Business/User/UserInput.vue';
import CollapsePanel from '@/components/CollapsePanel/index.vue';
import FormCol from "@/components/FormCol/index.vue";
import { deepClone, dictLabel } from '@/utils';
import { RoleKeys, SuitRentalUnit, SuitRidingRule, SuitStatus, SuitType } from '@/utils/enums';
import { mapGetters } from 'vuex';
export default {
name: 'SuitEditDialog',
@ -268,6 +277,12 @@ export default {
],
depositAmount: [
{ required: true, message: "预存款不能为空", trigger: "blur" }
],
depositDeduction: [
{ required: true, message: "押金自动抵扣不能为空", trigger: "blur" }
],
type: [
{ required: true, message: "套餐类型不能为空", trigger: "blur" }
]
}
}
@ -376,6 +391,7 @@ export default {
freeRideTime: null,
rentalUnit: SuitRentalUnit.MINUTE,
ridingRule: SuitRidingRule.START,
depositDeduction: false,
modelIds: [],
startRule: {
startingTime: 60,

View File

@ -138,6 +138,9 @@
<template v-else-if="column.key === 'modelNames'">
<el-tag type="primary" v-for="modelName of d.row.modelNames" :key="modelName" size="mini" style="margin-right: 4px;">{{modelName | dv}}</el-tag>
</template>
<template v-else-if="column.key === 'depositDeduction'">
<boolean-tag :value="d.row.depositDeduction" size="mini"/>
</template>
<template v-else>
{{d.row[column.key]}}
</template>
@ -181,11 +184,13 @@
</template>
<script>
import { listSuit, delSuit } from "@/api/bst/suit";
import { delSuit, listSuit } from "@/api/bst/suit";
import BooleanTag from '@/components/BooleanTag/index.vue';
import UserLink from '@/components/Business/User/UserLink.vue';
import { toDescriptionFromSecond } from '@/utils/date';
import { $showColumns } from '@/utils/mixins';
import SuitEditDialog from '@/views/bst/suit/components/SuitEditDialog.vue';
import { toDescriptionFromSecond } from '@/utils/date';
import UserLink from '@/components/Business/User/UserLink.vue';
//
const defaultSort = {
prop: "orderNum",
@ -196,7 +201,7 @@ export default {
name: "Suit",
mixins: [$showColumns],
dicts: ['suit_status', 'suit_rental_unit', 'suit_riding_rule', 'suit_type'],
components: { SuitEditDialog, UserLink },
components: { SuitEditDialog, UserLink, BooleanTag },
props: {
query: {
type: Object,
@ -210,12 +215,13 @@ export default {
{key: 'id', visible: false, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: "80"},
{key: 'name', visible: true, label: '名称', minWidth: "200", sortable: true, overflow: false, align: 'left', width: null},
{key: 'userName', visible: true, label: '所属人', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'depositAmount', visible: true, label: '预存', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'depositAmount', visible: true, label: '押金', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'rentalUnit', visible: true, label: '租赁单位', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'instructions', visible: true, label: '说明', minWidth: null, sortable: true, overflow: true, align: 'center', width: null},
{key: 'freeRideTime', visible: true, label: '免费时长', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'orderNum', visible: true, label: '排序', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'seconds', visible: true, label: '可用时长', minWidth: null, sortable: true, overflow: false, align: 'center', width: "180"},
{key: 'depositDeduction', visible: true, label: '自动抵扣', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'modelNames', visible: true, label: '适用车型', minWidth: "200", sortable: false, overflow: false, align: 'center', width: null},
{key: 'createTime', visible: true, label: '创建时间', minWidth: null, sortable: true, overflow: false, align: 'center', width: "180"},
],