398 lines
13 KiB
Vue
398 lines
13 KiB
Vue
<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> |