681 lines
19 KiB
Vue
Raw Normal View History

2025-04-14 10:57:27 +08:00
<template>
<a-spin
:spinning="spinning"
:tip="tipContent"
>
<a-form
:model="form"
:label-col="{sm: { span: 8 } }"
:wrapper-col="{ span:24}"
ref="formRef"
>
<a-row :gutter="8">
<a-col :xs="12">
<a-form-item
label="计费方式"
required
name="chargingMode"
:rules="[{ required: true, message: '请选择计费方式' }]"
>
<a-select
v-model:value="form.chargingMode"
placeholder="请选择计费方式"
allow-clear
>
<a-select-option value="1">时间计费</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="8">
<a-col :xs="12">
<a-form-item
label="免费时长模式"
required
name="freeDurationMode"
:rules="[{ required: true, message: '请选择免费时长模式' }]"
>
<a-radio-group
v-model:value="form.freeDurationMode"
name="radioGroup"
@change="changeFreeDurationMode"
>
<a-radio value="1">分钟</a-radio>
<a-radio value="2"></a-radio>
</a-radio-group>
</a-form-item>
</a-col>
<a-col :xs="12">
<a-form-item
:label="freeDuration"
required
name="freeDuration"
:rules="[{ required: true, message: '请输入免费时长' }]"
>
<a-input
v-model:value="form.freeDuration"
placeholder="请输入免费时长"
type="number"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="8">
<a-col :xs="12">
<a-form-item
label="分时段计费"
required
name="timeDivisionCharging"
:rules="[{ required: true, message: '请选择分时段计费' }]"
>
<a-radio-group
v-model:value="form.timeDivisionCharging"
name="radioGroup"
@change="changeTimeDivisionCharging"
>
<a-radio value="1">关闭</a-radio>
<a-radio value="2">时间段</a-radio>
<a-radio value="3"></a-radio>
</a-radio-group>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="8">
<a-col :xs="12">
<a-form-item
label="起步费用(元)"
required
name="startupCost"
:rules="[{ required: true, message: '请输入起步费用' }]"
>
<a-input
v-model:value="form.startupCost"
placeholder="请输入起步费用"
type="number"
/>
</a-form-item>
</a-col>
<a-col :xs="12">
<a-form-item
label="起步时长(分钟)"
required
name="startupDuration"
:rules="[{ required: true, message: '起步时长' }]"
>
<a-input
v-model:value="form.startupDuration"
placeholder="起步时长"
type="number"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="8">
<a-col :xs="12">
<a-form-item
label="时长费用(元)"
required
name="durationCost"
:rules="[{ required: true, message: '请输入时长费用' }]"
>
<a-input
v-model:value="form.durationCost"
placeholder="请输入时长费用"
type="number"
/>
</a-form-item>
</a-col>
<a-col :xs="12">
<a-form-item
label="时长(分钟)"
required
name="duration"
:rules="[{ required: true, message: '请输入时长' }]"
>
<a-input
v-model:value="form.duration"
placeholder="请输入时长"
type="number"
/>
</a-form-item>
</a-col>
</a-row>
<a-row
:gutter="8"
v-if="deteilShow"
>
<a-col :xs="24">
<a-form-item
label="分时段明细"
:name="field"
:label-col="{ sm: { span: 4 }}"
:wrapper-Col="{span: 24 }"
>
<a-table
bordered
:columns="columns"
:dataSource="form[field]"
:scroll="{ x: 'max-content' }"
:pagination="false"
>
<template #headerCell="{ column }">
<template v-if="column.key === 'action'">
<SettingOutlined style="margin-right: 5px" />{{ column.title }}
</template>
</template>
<template #bodyCell="{ column,record,index }">
<template v-if="column.key === 'phase'">
<a-space>
{{index + 1}}
</a-space>
</template>
<template v-if="column.key === 'action'">
<a-popconfirm
title="删除此行?"
ok-text="确定"
cancel-text="取消"
@confirm="deleteRecord(record)"
>
<a-space>
<a href="#">删除</a>
</a-space>
</a-popconfirm>
</template>
<template v-if=" column.type == 'input'">
<a-input
v-model:value="record[column.dataIndex]"
:placeholder="`请输入`"
:style="{ width: '100%' }"
/>
</template>
<template v-if=" column.type == 'time'">
<TimePicker
placeholder="请选择"
v-model:value="record[column.dataIndex]"
/>
</template>
<template v-if=" column.type == 'select'">
<a-select
v-model:value="record[column.dataIndex]"
mode="multiple"
style="width: 100%"
placeholder="请选择"
:max-tag-count="1"
>
<a-select-option value="1">周一</a-select-option>
<a-select-option value="2">周二</a-select-option>
<a-select-option value="3">周三</a-select-option>
<a-select-option value="4">周四</a-select-option>
<a-select-option value="5">周五</a-select-option>
<a-select-option value="6">周六</a-select-option>
<a-select-option value="7">周日</a-select-option>
</a-select>
</template>
</template>
</a-table>
<a-button
type="default"
@click="addRecord"
:style="{
width: '100%',
marginTop: '5px',
border: '1px dashed #1890ff',
backgroundColor: 'transparent',
color: '#1890ff'
}"
>
<PlusOutlined />
向下添加一行
</a-button>
<div style="width: 100%;margin-top: 15px;color: rgb(140,140,140);">{{warmReminder}}</div>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="8">
<a-col :xs="12">
<a-form-item
label="运营区域外调度费(元)"
required
name="dispatchFeeOutOperateArea"
:rules="[{ required: true, message: '请输入运营区域外调度费' }]"
>
<a-input
v-model:value="form.dispatchFeeOutOperateArea"
placeholder="请输入运营区域外调度费"
type="number"
/>
</a-form-item>
</a-col>
<a-col :xs="12">
<a-form-item
label="禁停区调度费(元)"
required
name="dispatchFeeBanArea"
:rules="[{ required: true, message: '请输入禁停区调度费' }]"
>
<a-input
v-model:value="form.dispatchFeeBanArea"
placeholder="请输入禁停区调度费"
type="number"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="8">
<a-col :xs="12">
<a-form-item
label="停车区外调度费(元)"
required
name="parkingAreaOutDispatchFee"
:rules="[{ required: true, message: '请输入停车区外调度费' }]"
>
<a-input
v-model:value="form.parkingAreaOutDispatchFee"
placeholder="请输入停车区外调度费"
type="number"
/>
</a-form-item>
</a-col>
<a-col :xs="12">
<a-form-item
label="头盔管理费(元)"
required
name="helmetManagementFee"
:rules="[{ required: true, message: '请输入头盔管理费' }]"
>
<a-input
v-model:value="form.helmetManagementFee"
placeholder="请输入头盔管理费"
type="number"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="8">
<a-col :xs="12">
<a-form-item
label="封顶金额(元)"
required
name="cappedAmount"
:rules="[{ required: true, message: '请输入封顶金额' }]"
>
<a-input
v-model:value="form.cappedAmount"
placeholder="请输入封顶金额"
type="number"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="8">
<a-col :xs="12">
<a-form-item
label="短租预付款"
required
name="shortRentAdvance"
:rules="[{ required: true, message: '请选择短租预付款' }]"
>
<a-radio-group
v-model:value="form.shortRentAdvance"
name="radioGroup"
>
<a-radio value="1"></a-radio>
<a-radio value="2"></a-radio>
</a-radio-group>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="8">
<a-col :xs="12">
<a-form-item
label="是否开启长租"
required
name="whetherOpenLongRent"
:rules="[{ required: true, message: '请选择计费方式' }]"
>
<a-radio-group
v-model:value="form.whetherOpenLongRent"
name="radioGroup"
>
<a-radio value="1"></a-radio>
<a-radio value="2"></a-radio>
</a-radio-group>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-spin>
</template>
<style scoped>
.a-tabs-card {
position: relative;
}
</style>
<script setup>
2025-04-14 12:31:03 +08:00
import { ref } from 'vue'
2025-04-14 10:57:27 +08:00
import { callOperate } from '@/apis/call.js'
import { message } from 'ant-design-vue'
import { getGUID } from '@/utils/tools';
import _ from 'lodash'
import { TimePicker } from 'ant-design-vue'
import dayjs from 'dayjs';
const formRef = ref();
const spinning = ref(false);
const tipContent = ref("加载中...");
const freeDuration = ref("免费时长(分钟)");
const deteilShow = ref(false);
const isAdd = ref(true);
const warmReminder = ref("");
const field = ref("");
2025-04-16 11:42:37 +08:00
const formData = () => ({
2025-04-14 10:57:27 +08:00
costConfigId: "",
regionId: "",
chargingMode: "",
freeDurationMode: "1",
freeDuration: "",
timeDivisionCharging: "1",
ebikeSysRcostsetTimePeriodDtos: [],
ebikeSysRcostsetWeekDtos: [],
startupCost: "",
startupDuration: "",
durationCost: "",
duration: "",
dispatchFeeOutOperateArea: "",
dispatchFeeBanArea: "",
parkingAreaOutDispatchFee: "",
helmetManagementFee: "",
cappedAmount: "",
shortRentAdvance: "",
whetherOpenLongRent: ""
});
2025-04-16 11:42:37 +08:00
const form = ref(formData());
2025-04-14 10:57:27 +08:00
// 表格列配置
const columns = ref([])
const changeFreeDurationMode = (data) => {
const value = data.target.value;
if (value == "1") {
freeDuration.value = "免费时长(分钟)";
} else if (value == "2") {
freeDuration.value = "免费时长(秒)";
}
}
2025-04-16 11:42:37 +08:00
const timePeriodColumns = [
{
title: '阶段',
key: 'phase',
width: 70,
align: 'center',
dataIndex: 'phase'
},
{
title: '起始时间',
key: 'startupTime',
width: 130,
align: 'center',
dataIndex: 'startupTime',
type: 'time'
},
{
title: '结束时间',
key: 'endTime',
width: 130,
align: 'center',
dataIndex: 'endTime',
type: 'time'
},
{
title: '起步费用(元)',
key: 'startupCost',
width: 120,
align: 'center',
dataIndex: 'startupCost',
type: 'input'
},
{
title: '起步时长(分)',
key: 'startupDuration',
width: 120,
align: 'center',
dataIndex: 'startupDuration',
type: 'input'
},
{
title: '时长费用(元)',
key: 'durationCost',
width: 120,
align: 'center',
dataIndex: 'durationCost',
type: 'input'
},
{
title: '时长(分)',
key: 'duration',
width: 100,
align: 'center',
dataIndex: 'duration',
type: 'input'
},
{
title: '操作',
key: 'action',
width: 80,
align: 'center',
fixed: 'right',
}
]
const weekColumns = [
{
title: '名称',
key: 'configName',
width: 100,
align: 'center',
dataIndex: 'configName',
type: 'input'
},
{
title: '周',
key: 'week',
width: 170,
align: 'center',
dataIndex: 'week',
type: 'select'
},
{
title: '起步费用(元)',
key: 'startupCost',
width: 50,
align: 'center',
dataIndex: 'startupCost',
type: 'input'
},
{
title: '起步时长(分)',
key: 'startupDuration',
width: 120,
align: 'center',
dataIndex: 'startupDuration',
type: 'input'
},
{
title: '时长费用(元)',
key: 'durationCost',
width: 120,
align: 'center',
dataIndex: 'durationCost',
type: 'input'
},
{
title: '时长(分)',
key: 'duration',
width: 100,
align: 'center',
dataIndex: 'duration',
type: 'input'
},
{
title: '操作',
key: 'action',
width: 80,
align: 'center',
fixed: 'right',
}
]
2025-04-14 10:57:27 +08:00
const changeTimeDivisionCharging = (data) => {
const value = data.target.value;
if (value == "2") {
field.value = "ebikeSysRcostsetTimePeriodDtos";
if (form.value['ebikeSysRcostsetTimePeriodDtos'] == null) {
form.value['ebikeSysRcostsetTimePeriodDtos'] = [];
}
form.value.ebikeSysRcostsetWeekDtos = [];
deteilShow.value = true;
warmReminder.value = "温馨提示当天结束的阶段为23:59:59没有设置的话默认配置为上面的字段。";
2025-04-16 11:42:37 +08:00
columns.value = timePeriodColumns;
2025-04-14 10:57:27 +08:00
} else if (value == "3") {
field.value = "ebikeSysRcostsetWeekDtos";
if (form.value['ebikeSysRcostsetWeekDtos'] == null) {
form.value['ebikeSysRcostsetWeekDtos'] = [];
}
form.value.ebikeSysRcostsetTimePeriodDtos = [];
deteilShow.value = true;
warmReminder.value = "温馨提示周的日期支持多选比如可以选择周一、周二、周三为1种计费方式没有选择的按默认选择方式来。";
2025-04-16 11:42:37 +08:00
columns.value = weekColumns;
2025-04-14 10:57:27 +08:00
} else {
field.value = "";
deteilShow.value = false;
warmReminder.value = "";
columns.value = []
form.value.ebikeSysRcostsetTimePeriodDtos = [];
form.value.ebikeSysRcostsetWeekDtos = [];
}
}
const openForm = (params = {}) => {
deteilShow.value = false;
2025-04-16 11:42:37 +08:00
Object.assign(form.value, formData());
formRef.value.resetFields();
isAdd.value = true;
2025-04-14 10:57:27 +08:00
if (params['regionId']) {
form.value.regionId = params['regionId']
spinning.value = true;
callOperate("/ebikesysrcostset/getRegionFeeConfigById?regionId="
+ params['regionId'], {}, "get").then(res => {
spinning.value = false;
if (res.code == 200) {
if (res.data) {
isAdd.value = false;
form.value = res.data;
if (res.data.timeDivisionCharging == '2') {
const item = res.data.ebikeSysRcostsetTimePeriodDtos;
if (item.length > 0) {
item.forEach(t => {
t['startupTime'] = dayjs(t['startupTime'], 'HH:mm:ss');
t['endTime'] = dayjs(t['endTime'], 'HH:mm:ss');
})
}
form.value.ebikeSysRcostsetTimePeriodDtos = item;
field.value = "ebikeSysRcostsetTimePeriodDtos";
deteilShow.value = true;
warmReminder.value = "温馨提示当天结束的阶段为23:59:59没有设置的话默认配置为上面的字段。";
2025-04-16 11:42:37 +08:00
columns.value = timePeriodColumns;
2025-04-14 10:57:27 +08:00
} else if (res.data.timeDivisionCharging == '3') {
field.value = "ebikeSysRcostsetWeekDtos";
deteilShow.value = true;
warmReminder.value = "温馨提示周的日期支持多选比如可以选择周一、周二、周三为1种计费方式没有选择的按默认选择方式来。";
2025-04-16 11:42:37 +08:00
columns.value = weekColumns;
2025-04-14 10:57:27 +08:00
} else {
field.value = "";
}
}
} else {
message.error(res.message);
}
})
}
};
const addRecord = () => {
const timeDivisionCharging = form.value.timeDivisionCharging;
let item = {};
let timeSegmentDetail = field.value
if (timeDivisionCharging == '2') {
item = {
key: getGUID(),
phase: "",
startupTime: dayjs("00:00:00", 'HH:mm:ss'),
endTime: dayjs("23:59:59", 'HH:mm:ss'),
startupCost: "",
startupDuration: "",
durationCost: "",
duration: ""
};
} else if (timeDivisionCharging == '3') {
item = {
key: getGUID(),
configName: "",
week: [],
startupCost: "",
startupDuration: "",
durationCost: "",
duration: "",
};
}
form.value[timeSegmentDetail].push(item)
}
const deleteRecord = (record) => {
const key = record['key'];
let timeSegmentDetail = field.value
let item = _.clone(form.value[timeSegmentDetail]);
remove(key, "key", item)
form.value[timeSegmentDetail] = item;
}
const remove = (val, filed, array) => {
const index = array.findIndex(obj => obj[filed] === val);
if (index > -1) {
array.splice(index, 1);
}
}
2025-04-14 12:31:03 +08:00
const formSave = (callBack) => {
2025-04-14 10:57:27 +08:00
formRef.value.validate().then(() => {
2025-04-16 11:42:37 +08:00
debugger;
2025-04-14 10:57:27 +08:00
tipContent.value = "保存中..."
spinning.value = true;
let url = "regionFeeConfigAdds";
if (!isAdd.value) {
url = "updateRegionFeeConfig"
}
const param = _.cloneDeep(form.value)
if (param['ebikeSysRcostsetTimePeriodDtos'] && param['ebikeSysRcostsetTimePeriodDtos'].length > 0) {
param['ebikeSysRcostsetTimePeriodDtos'].forEach(item => {
item['startupTime'] = item['startupTime'].format('HH:mm:ss');
item['endTime'] = item['endTime'].format('HH:mm:ss');
})
}
callOperate("/ebikesysrcostset/" + url, param).then(res => {
spinning.value = false;
2025-04-14 12:31:03 +08:00
if (callBack) {
2025-04-14 10:57:27 +08:00
res.data = param;
2025-04-14 12:31:03 +08:00
callBack(res);
2025-04-14 10:57:27 +08:00
}
})
}).catch(error => {
console.log('error', error);
});
};
defineExpose({ openForm, formSave });
</script>