electripper-v2-ui/src/views/bst/suit/components/SuitEditDialog.vue
2025-03-25 18:04:07 +08:00

398 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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">
<form-col :span="span" label="所属用户" prop="userId">
<user-input v-model="form.userId" :text.sync="form.userName" :disabled="!checkPermi(['system:user:list'])"/>
</form-col>
<form-col :span="span" label="套餐名称" prop="name">
<el-input v-model="form.name" placeholder="请输入套餐名称" />
</form-col>
<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>
<form-col :span="span" label="预存金额" prop="depositAmount">
<el-input v-model="form.depositAmount" placeholder="请输入预存金额" type="number">
<template slot="append">元</template>
</el-input>
</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>
</el-row>
<el-row :gutter="10">
<collapse-panel title="计费规则" :value="true">
<template v-if="form.ridingRule === SuitRidingRule.START && form.startRule">
<el-input-number
v-model="form.startRule.startingTime"
placeholder="起步时间"
:min="0"
:precision="1"
controls-position="right"
style="width: 120px;"
/>
{{unitLabel(form.rentalUnit)}}以内,起步价
<el-input-number
v-model="form.startRule.startingPrice"
placeholder="起步价"
type="number"
controls-position="right"
style="width: 120px;"
/>
元;<br/>超出起步时间后,超出的时间每
<el-input-number
v-model="form.startRule.timeoutTime"
placeholder="超时时间"
type="number"
controls-position="right"
style="width: 120px;"
/>
{{unitLabel(form.rentalUnit)}}
<el-input-number
v-model="form.startRule.timeoutPrice"
placeholder="超时价格"
type="number"
controls-position="right"
style="width: 120px;"
/>
元,不满{{form.startRule.timeoutTime}}{{unitLabel(form.rentalUnit)}},按{{form.startRule.timeoutTime}}{{unitLabel(form.rentalUnit)}}计算。
</template>
<template v-else-if="form.ridingRule === SuitRidingRule.INTERVAL && form.intervalRule">
<div v-for="(item, index) in form.intervalRule" :key="index">
<el-input-number
:value="startTime(index)"
controls-position="right"
style="width: 120px;"
placeholder="开始"
disabled
:precision="1"
/>
<template v-if="index < form.intervalRule.length - 1">
~
<el-input-number
v-model="item.end"
controls-position="right"
style="width: 120px;"
placeholder="结束"
:min="minEnd(index)"
:max="maxEnd(index)"
:precision="1"
/>
{{unitLabel(form.rentalUnit)}}之间,
</template>
<template v-else>
之后,
</template>
<el-input-number
v-model="item.eachUnit"
controls-position="right"
style="width: 120px;"
placeholder="间隔"
:min="0.1"
:precision="1"
:max="maxEachUnit(index)"
/>
{{unitLabel(form.rentalUnit)}}收费
<el-input-number
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';
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';
export default {
name: 'SuitEditDialog',
components: { FormCol, UserInput, CollapsePanel },
dicts: ['suit_status', 'suit_rental_unit', 'suit_riding_rule', 'suit_type'],
props: {
visible: {
type: Boolean,
default: false
},
id: {
type: [String, Number],
default: null
}
},
data() {
return {
SuitRentalUnit,
SuitRidingRule,
SuitStatus,
RoleKeys,
SuitType,
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;
}
return this.form.intervalRule[index - 1].end;
}
},
// 获取最大结束时间
maxEnd() {
return (index) => {
if (index >= this.form.intervalRule.length - 2 ) {
return 999999999;
} else {
return this.form.intervalRule[index + 1].end;
}
}
},
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, {
start: current.end,
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,
type: SuitType.SHARE,
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 if (index == data.intervalRule.length - 1) {
item.end = null;
} else {
item.start = data.intervalRule[index - 1].end;
}
});
}
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>
</style>