electripper-v2-ui/src/views/bst/suit/components/SuitEditDialog.vue

424 lines
14 KiB
Vue
Raw Normal View History

2025-03-18 18:05:19 +08:00
<template>
<el-dialog
:title="title"
:visible.sync="dialogVisible"
width="800px"
append-to-body
:close-on-click-modal="false"
@open="handleOpen"
>
<el-form ref="form" :model="form" :rules="rules" label-width="80px" size="small" v-loading="loading">
<el-row :gutter="10">
2025-03-25 18:04:07 +08:00
<form-col :span="span" label="所属用户" prop="userId">
<user-input v-model="form.userId" :text.sync="form.userName" :disabled="!checkPermi(['system:user:list'])"/>
2025-03-18 18:05:19 +08:00
</form-col>
<form-col :span="span" label="套餐名称" prop="name">
<el-input v-model="form.name" placeholder="请输入套餐名称" />
</form-col>
2025-03-25 18:04:07 +08:00
<form-col :span="span" label="套餐类型" prop="type">
<el-select v-model="form.type" placeholder="请选择套餐类型" style="width: 100%;">
<el-option
v-for="dict in dict.type.suit_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</form-col>
2025-03-18 18:05:19 +08:00
<form-col :span="span" label="预存金额" prop="depositAmount">
2025-03-27 18:04:06 +08:00
<el-input-number
v-model="form.depositAmount"
placeholder="请输入预存金额"
type="number"
:precision="2"
controls-position="right"
style="width: calc(100% - 2em)"
/>
2025-03-18 18:05:19 +08:00
</form-col>
<form-col :span="span" label="免费时长" prop="freeRideTime">
<el-input v-model="form.freeRideTime" placeholder="请输入免费时长(分钟)">
<template slot="append">分钟</template>
</el-input>
</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>
2025-03-25 18:04:07 +08:00
</el-row>
<el-row :gutter="10">
2025-03-18 18:05:19 +08:00
<collapse-panel title="计费规则" :value="true">
<template v-if="form.ridingRule === SuitRidingRule.START && form.startRule">
2025-03-27 18:04:06 +08:00
<div class="rule-row">
<el-input-number
size="small"
v-model="form.startRule.startingTime"
placeholder="起步时间"
:min="0"
:precision="0"
controls-position="right"
style="width: 120px;"
/>
{{unitLabel(form.rentalUnit)}}以内起步价
<el-input-number
size="small"
v-model="form.startRule.startingPrice"
placeholder="起步价"
type="number"
:precision="2"
controls-position="right"
style="width: 120px;"
/>
</div>
<div class="rule-row">
超出起步时间后超出的时间每
<el-input-number
size="small"
v-model="form.startRule.timeoutTime"
placeholder="超时时间"
type="number"
:precision="0"
controls-position="right"
style="width: 120px;"
/>
{{unitLabel(form.rentalUnit)}}
<el-input-number
size="small"
v-model="form.startRule.timeoutPrice"
placeholder="超时价格"
type="number"
:precision="2"
controls-position="right"
style="width: 120px;"
/>
不满{{form.startRule.timeoutTime}}{{unitLabel(form.rentalUnit)}}{{form.startRule.timeoutTime}}{{unitLabel(form.rentalUnit)}}计算
</div>
2025-03-18 18:05:19 +08:00
</template>
<template v-else-if="form.ridingRule === SuitRidingRule.INTERVAL && form.intervalRule">
2025-03-27 18:04:06 +08:00
<div v-for="(item, index) in form.intervalRule" :key="index" class="rule-row">
2025-03-18 18:05:19 +08:00
<el-input-number
2025-03-27 18:04:06 +08:00
size="small"
2025-03-18 18:05:19 +08:00
:value="startTime(index)"
controls-position="right"
style="width: 120px;"
placeholder="开始"
disabled
2025-03-27 18:04:06 +08:00
:precision="0"
2025-03-18 18:05:19 +08:00
/>
<template v-if="index < form.intervalRule.length - 1">
~
<el-input-number
2025-03-27 18:04:06 +08:00
size="small"
2025-03-18 18:05:19 +08:00
v-model="item.end"
2025-03-27 18:04:06 +08:00
controls-position="right"
style="width: 120px;"
placeholder="结束"
:min="minEnd(index)"
:max="maxEnd(index)"
:precision="0"
/>
{{unitLabel(form.rentalUnit)}}之间
2025-03-18 18:05:19 +08:00
</template>
<template v-else>
之后
</template>
<el-input-number
2025-03-27 18:04:06 +08:00
size="small"
2025-03-18 18:05:19 +08:00
v-model="item.eachUnit"
controls-position="right"
style="width: 120px;"
placeholder="间隔"
2025-03-27 18:04:06 +08:00
:min="1"
:precision="0"
2025-03-18 18:05:19 +08:00
:max="maxEachUnit(index)"
/>
{{unitLabel(form.rentalUnit)}}收费
<el-input-number
2025-03-27 18:04:06 +08:00
size="small"
2025-03-18 18:05:19 +08:00
v-model="item.fee"
controls-position="right"
style="width: 120px;"
placeholder="价格"
:precision="2"
/>
<el-button type="primary" size="small" icon="el-icon-plus" plain @click="addRidingRule(index)" circle/>
<el-button type="danger" size="small" icon="el-icon-delete" plain @click="deleteRidingRule(index)" circle/>
</div>
<span>时长不含前面的时间</span>
</template>
</collapse-panel>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</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';
2025-03-25 18:04:07 +08:00
import { SuitRentalUnit, SuitRidingRule, SuitStatus, RoleKeys, SuitType } from '@/utils/enums';
2025-03-18 18:05:19 +08:00
import CollapsePanel from '@/components/CollapsePanel/index.vue';
import { deepClone, dictLabel } from '@/utils';
import { mapGetters } from 'vuex';
export default {
name: 'SuitEditDialog',
components: { FormCol, UserInput, CollapsePanel },
2025-03-25 18:04:07 +08:00
dicts: ['suit_status', 'suit_rental_unit', 'suit_riding_rule', 'suit_type'],
2025-03-18 18:05:19 +08:00
props: {
visible: {
type: Boolean,
default: false
},
id: {
type: [String, Number],
default: null
}
},
data() {
return {
SuitRentalUnit,
SuitRidingRule,
SuitStatus,
RoleKeys,
2025-03-25 18:04:07 +08:00
SuitType,
2025-03-18 18:05:19 +08:00
span: 12,
title: '',
form: {},
loading: false,
rules: {
userId: [
{ required: true, message: "运营商不能为空", trigger: "change" }
],
name: [
{ required: true, message: "套餐名称不能为空", trigger: "blur" }
],
status: [
{ required: true, message: "状态不能为空", trigger: "change" }
],
createTime: [
{ required: true, message: "创建时间不能为空", trigger: "blur" }
],
freeRideTime: [
{ required: true, message: "免费骑行时长(分钟)不能为空", trigger: "blur" }
],
rentalUnit: [
{ required: true, message: "租赁单位不能为空", trigger: "blur" }
],
ridingRule: [
{ required: true, message: "计费规则不能为空", trigger: "blur" }
],
orderNum: [
{ required: true, message: "显示顺序不能为空", trigger: "blur" }
],
depositAmount: [
{ required: true, message: "预存款不能为空", trigger: "blur" }
]
}
}
},
computed: {
...mapGetters(['userId', 'nickName']),
dialogVisible: {
get() {
return this.visible;
},
set(val) {
this.$emit('update:visible', val);
}
},
// 获取最小结束时间
minEnd() {
return (index) => {
if (index == 0) {
return 0;
}
2025-03-27 18:04:06 +08:00
return this.form.intervalRule[index - 1].end + 1;
2025-03-18 18:05:19 +08:00
}
},
// 获取最大结束时间
maxEnd() {
return (index) => {
if (index >= this.form.intervalRule.length - 2 ) {
return 999999999;
} else {
2025-03-27 18:04:06 +08:00
return this.form.intervalRule[index + 1].end - 1;
2025-03-18 18:05:19 +08:00
}
}
},
maxEachUnit() {
return (index) => {
if (index >= this.form.intervalRule.length - 1) {
return 999999999;
}
let item = this.form.intervalRule[index];
return item.end - item.start;
}
},
// 获取开始时间
startTime() {
return (index) => {
if (index == 0) {
return 0;
}
return this.form.intervalRule[index - 1].end;
}
},
unitLabel() {
return (value) => {
return dictLabel(this.dict.type.suit_rental_unit, value);
}
}
},
methods: {
// 添加计费规则
addRidingRule(index) {
let current = this.form.intervalRule[index];
this.form.intervalRule.splice(index + 1, 0, {
2025-03-27 18:04:06 +08:00
start: null,
2025-03-18 18:05:19 +08:00
end: current.end + 1,
eachUnit: 1,
fee: null,
});
},
// 删除计费规则
deleteRidingRule (index) {
if (this.form.intervalRule.length == 1) {
this.$modal.msgError("至少保留一条计费规则");
return;
}
this.form.intervalRule.splice(index, 1);
},
handleOpen() {
if (this.id == null) {
this.reset();
this.title = "添加套餐";
} else {
this.getDetail();
this.title = "修改套餐";
}
},
reset() {
this.form = {
id: null,
userId: this.userId,
name: null,
2025-03-25 18:04:07 +08:00
type: SuitType.SHARE,
2025-03-18 18:05:19 +08:00
status: SuitStatus.NORMAL,
createTime: null,
freeRideTime: null,
rentalUnit: SuitRentalUnit.MINUTE,
ridingRule: SuitRidingRule.START,
startRule: {
startingTime: 60,
startingPrice: 5,
timeoutTime: 60,
timeoutPrice: 5
},
intervalRule: [
{
start: 0,
end: 1,
eachUnit: 1,
fee: null,
}
],
instructions: null,
deleted: null,
orderNum: null,
depositAmount: null,
// vo
userName: this.nickName,
};
this.$nextTick(() => {
this.$refs.form && this.$refs.form.clearValidate();
});
},
getDetail() {
this.loading = true;
getSuit(this.id).then(response => {
let data = response.data;
this.form = data;
}).finally(() => {
this.loading = false;
});
},
submitForm() {
this.$refs.form.validate(valid => {
if (valid) {
// 处理数据将start和end字段特殊处理
let data = deepClone(this.form);
if (data.ridingRule === SuitRidingRule.INTERVAL) {
data.intervalRule.forEach((item,index) => {
if (index == 0) {
item.start = 0;
} else {
item.start = data.intervalRule[index - 1].end;
}
2025-03-27 18:04:06 +08:00
if (index == data.intervalRule.length - 1) {
item.end = null;
}
2025-03-18 18:05:19 +08:00
});
}
const promise = this.form.id != null ? updateSuit(data) : addSuit(data);
promise.then(response => {
this.$modal.msgSuccess(this.form.id != null ? "修改成功" : "新增成功");
this.dialogVisible = false;
this.$emit('success');
});
}
});
},
cancel() {
this.dialogVisible = false;
this.reset();
}
}
}
</script>
<style lang="scss" scoped>
2025-03-27 18:04:06 +08:00
.rule-row {
margin-bottom: 4px;
}
2025-03-18 18:05:19 +08:00
</style>