文件

647 行
26 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>骑手配置管理</title>
<link rel="stylesheet" type="text/css" href="__PUBLIC__/css/menu.css?v=1.0.5"/>
<link rel="stylesheet" type="text/css" href="__PUBLIC__/css/minimal-admin.css?v=1.0.0"/>
<link rel="stylesheet" type="text/css" href="__PUBLIC__/Retail/css/myscroll.css?v=1.0.2"/>
<link rel="stylesheet" type="text/css" href="__PUBLIC__/layui-v2.4.3/layui/css/layui.css"/>
<link rel="stylesheet" type="text/css" href="__PUBLIC__/Retail/css/home.css"/>
<link rel="stylesheet" type="text/css" href="__PUBLIC__/vue/element-ui.css?v=2.13.2">
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script type="text/javascript" charset="utf-8" src="__PUBLIC__/vue/js/vue2.5.16.js"></script>
<script type="text/javascript" charset="utf-8" src="__PUBLIC__/vue/element-ui.js?v=2.13.2"></script>
<script type="text/javascript" charset="utf-8" src="__PUBLIC__/js/common.js?v=1.0.2"></script>
<script type="text/javascript" charset="utf-8" src="__PUBLIC__/jquery/js/jquery-3.2.1.min.js"></script>
<style>
.config-container {
padding: 20px;
background: #f5f7fa;
min-height: calc(100vh - 100px);
}
.config-header {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
}
.config-title {
font-size: 24px;
font-weight: 600;
color: #303133;
display: flex;
align-items: center;
margin-bottom: 10px;
}
.config-description {
color: #909399;
font-size: 14px;
}
.config-card {
background: white;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
overflow: hidden;
}
.config-card-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 15px 20px;
font-size: 16px;
font-weight: 600;
display: flex;
align-items: center;
}
.config-card-body {
padding: 20px;
}
.form-section {
margin-bottom: 30px;
}
.section-title {
font-size: 16px;
font-weight: 600;
color: #303133;
margin-bottom: 15px;
padding-bottom: 8px;
border-bottom: 2px solid #e4e7ed;
display: flex;
align-items: center;
}
.section-title i {
margin-right: 8px;
color: #409EFF;
}
.fee-preview {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 6px;
padding: 15px;
margin-top: 20px;
}
.fee-preview-title {
font-weight: 600;
color: #495057;
margin-bottom: 10px;
}
.fee-result {
font-size: 18px;
font-weight: 700;
color: #28a745;
}
.test-form {
background: #fff3cd;
border: 1px solid #ffeaa7;
border-radius: 6px;
padding: 15px;
margin-top: 20px;
}
.save-actions {
text-align: center;
padding: 20px;
background: #f8f9fa;
border-top: 1px solid #e9ecef;
}
.el-form-item {
margin-bottom: 18px;
}
.switch-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 0;
border-bottom: 1px solid #f0f0f0;
}
.switch-item:last-child {
border-bottom: none;
}
.switch-label {
font-weight: 500;
color: #303133;
}
.switch-description {
font-size: 12px;
color: #909399;
margin-top: 4px;
}
</style>
</head>
<body>
<div id="RiderConfig" v-cloak>
<div class="config-container">
<!-- 页面头部 -->
<div class="config-header">
<div class="config-title">
<i class="fas fa-cogs" style="margin-right: 12px; color: #409EFF;"></i>
骑手配置管理
</div>
<div class="config-description">
配置订单同步规则、配送费用计算方式等骑手端相关设置
</div>
</div>
<!-- 基础配置 -->
<div class="config-card">
<div class="config-card-header">
<i class="fas fa-toggle-on" style="margin-right: 8px;"></i>
基础配置
</div>
<div class="config-card-body">
<el-form :model="config" label-width="140px" size="medium">
<div class="switch-item">
<div>
<div class="switch-label">自动同步订单</div>
<div class="switch-description">开启后,新订单将自动同步到骑手端</div>
</div>
<el-switch
v-model="config.auto_sync_enabled"
:active-value="1"
:inactive-value="0">
</el-switch>
</div>
<div class="switch-item">
<div>
<div class="switch-label">时间加价</div>
<div class="switch-description">在特定时间段内增加配送费用</div>
</div>
<el-switch
v-model="config.time_fee_enabled"
:active-value="1"
:inactive-value="0">
</el-switch>
</div>
<div class="switch-item">
<div>
<div class="switch-label">恶劣天气加价</div>
<div class="switch-description">恶劣天气条件下增加配送费用</div>
</div>
<el-switch
v-model="config.weather_fee_enabled"
:active-value="1"
:inactive-value="0">
</el-switch>
</div>
<div class="switch-item">
<div>
<div class="switch-label">加急配送</div>
<div class="switch-description">允许用户选择加急配送服务</div>
</div>
<el-switch
v-model="config.urgent_fee_enabled"
:active-value="1"
:inactive-value="0">
</el-switch>
</div>
</el-form>
</div>
</div>
<!-- 配送费用配置 -->
<div class="config-card">
<div class="config-card-header">
<i class="fas fa-calculator" style="margin-right: 8px;"></i>
配送费用配置
</div>
<div class="config-card-body">
<el-form :model="config" label-width="140px" size="medium">
<div class="form-section">
<div class="section-title">
<i class="fas fa-coins"></i>
计费方式
</div>
<el-form-item label="计费类型">
<el-radio-group v-model="config.delivery_fee_type">
<el-radio :label="1">按距离计费</el-radio>
<el-radio :label="2">固定费用</el-radio>
<el-radio :label="3">阶梯计费</el-radio>
</el-radio-group>
</el-form-item>
</div>
<div class="form-section">
<div class="section-title">
<i class="fas fa-money-bill-wave"></i>
基础费用设置
</div>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="基础配送费">
<el-input-number
v-model="config.base_fee"
:precision="2"
:step="0.5"
:min="0"
:max="100">
</el-input-number>
<span style="margin-left: 8px; color: #909399;">元</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="每公里费用" v-if="config.delivery_fee_type === 1">
<el-input-number
v-model="config.distance_fee"
:precision="2"
:step="0.1"
:min="0"
:max="10">
</el-input-number>
<span style="margin-left: 8px; color: #909399;">元/公里</span>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="免费配送距离">
<el-input-number
v-model="config.free_distance"
:precision="2"
:step="0.5"
:min="0"
:max="20">
</el-input-number>
<span style="margin-left: 8px; color: #909399;">公里</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="最大配送距离">
<el-input-number
v-model="config.max_distance"
:precision="2"
:step="1"
:min="1"
:max="50">
</el-input-number>
<span style="margin-left: 8px; color: #909399;">公里</span>
</el-form-item>
</el-col>
</el-row>
</div>
<div class="form-section" v-if="config.time_fee_enabled">
<div class="section-title">
<i class="fas fa-clock"></i>
时间加价设置
</div>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="夜间加价比例">
<el-input-number
v-model="config.night_fee_rate"
:precision="2"
:step="0.1"
:min="0"
:max="2">
</el-input-number>
<span style="margin-left: 8px; color: #909399;">倍</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="夜间开始时间">
<el-time-picker
v-model="nightStartTime"
format="HH:mm"
value-format="HH:mm"
placeholder="选择时间">
</el-time-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="夜间结束时间">
<el-time-picker
v-model="nightEndTime"
format="HH:mm"
value-format="HH:mm"
placeholder="选择时间">
</el-time-picker>
</el-form-item>
</el-col>
</el-row>
</div>
<div class="form-section">
<div class="section-title">
<i class="fas fa-plus-circle"></i>
附加费用设置
</div>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="恶劣天气加价" v-if="config.weather_fee_enabled">
<el-input-number
v-model="config.weather_fee_rate"
:precision="2"
:step="0.5"
:min="0"
:max="20">
</el-input-number>
<span style="margin-left: 8px; color: #909399;">元</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="加急费用" v-if="config.urgent_fee_enabled">
<el-input-number
v-model="config.urgent_fee"
:precision="2"
:step="0.5"
:min="0"
:max="20">
</el-input-number>
<span style="margin-left: 8px; color: #909399;">元</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="包装费">
<el-input-number
v-model="config.packaging_fee"
:precision="2"
:step="0.5"
:min="0"
:max="10">
</el-input-number>
<span style="margin-left: 8px; color: #909399;">元</span>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="最小起送金额">
<el-input-number
v-model="config.min_order_amount"
:precision="2"
:step="5"
:min="0"
:max="200">
</el-input-number>
<span style="margin-left: 8px; color: #909399;">元</span>
</el-form-item>
</div>
</el-form>
</div>
</div>
<!-- 费用计算测试 -->
<div class="config-card">
<div class="config-card-header">
<i class="fas fa-flask" style="margin-right: 8px;"></i>
费用计算测试
</div>
<div class="config-card-body">
<div class="test-form">
<el-form :model="testData" label-width="120px" size="medium" inline>
<el-form-item label="配送距离">
<el-input-number
v-model="testData.distance"
:precision="2"
:step="0.5"
:min="0"
:max="50">
</el-input-number>
<span style="margin-left: 8px;">公里</span>
</el-form-item>
<el-form-item label="订单金额">
<el-input-number
v-model="testData.orderAmount"
:precision="2"
:step="10"
:min="0"
:max="1000">
</el-input-number>
<span style="margin-left: 8px;">元</span>
</el-form-item>
<el-form-item label="是否加急">
<el-switch v-model="testData.isUrgent"></el-switch>
</el-form-item>
<el-form-item label="是否夜间">
<el-switch v-model="testData.isNight"></el-switch>
</el-form-item>
<el-form-item label="恶劣天气">
<el-switch v-model="testData.isBadWeather"></el-switch>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="calculateTestFee" :loading="calculating">
<i class="fas fa-calculator" style="margin-right: 5px;"></i>
计算费用
</el-button>
</el-form-item>
</el-form>
</div>
<div class="fee-preview" v-if="testResult.total !== null">
<div class="fee-preview-title">费用计算结果:</div>
<div class="fee-result">
总配送费:¥{{ testResult.total }}
</div>
<div style="margin-top: 10px; font-size: 14px; color: #666;">
<div>基础费用:¥{{ testResult.baseFee }}</div>
<div v-if="testResult.distanceFee > 0">距离费用:¥{{ testResult.distanceFee }}</div>
<div v-if="testResult.urgentFee > 0">加急费用:¥{{ testResult.urgentFee }}</div>
<div v-if="testResult.nightFee > 0">夜间加价:¥{{ testResult.nightFee }}</div>
<div v-if="testResult.weatherFee > 0">恶劣天气加价:¥{{ testResult.weatherFee }}</div>
<div v-if="testResult.packagingFee > 0">包装费:¥{{ testResult.packagingFee }}</div>
</div>
</div>
</div>
</div>
<!-- 保存操作 -->
<div class="save-actions">
<el-button size="large" @click="resetConfig">
<i class="fas fa-undo" style="margin-right: 5px;"></i>
重置配置
</el-button>
<el-button type="primary" size="large" @click="saveConfig" :loading="saving">
<i class="fas fa-save" style="margin-right: 5px;"></i>
保存配置
</el-button>
</div>
</div>
</div>
<script>
new Vue({
el: '#RiderConfig',
data() {
return {
config: {
auto_sync_enabled: 1,
delivery_fee_type: 1,
base_fee: 5.00,
distance_fee: 1.50,
free_distance: 3.00,
max_distance: 20.00,
time_fee_enabled: 0,
night_fee_rate: 0.50,
night_start_time: '22:00',
night_end_time: '06:00',
weather_fee_enabled: 0,
weather_fee_rate: 1.00,
urgent_fee_enabled: 1,
urgent_fee: 3.00,
min_order_amount: 20.00,
packaging_fee: 2.00
},
testData: {
distance: 5.0,
orderAmount: 50.0,
isUrgent: false,
isNight: false,
isBadWeather: false
},
testResult: {
total: null,
baseFee: 0,
distanceFee: 0,
urgentFee: 0,
nightFee: 0,
weatherFee: 0,
packagingFee: 0
},
saving: false,
calculating: false
}
},
computed: {
nightStartTime: {
get() {
return this.config.night_start_time;
},
set(val) {
this.config.night_start_time = val;
}
},
nightEndTime: {
get() {
return this.config.night_end_time;
},
set(val) {
this.config.night_end_time = val;
}
}
},
methods: {
// 加载配置
loadConfig() {
this.sendRequest('Retail/RiderConfig/getConfig', {
success: (response) => {
if (response.status === 1) {
this.config = { ...this.config, ...response.data };
}
}
});
},
// 保存配置
saveConfig() {
this.saving = true;
this.sendRequest('Retail/RiderConfig/saveConfig', {
data: this.config,
success: (response) => {
this.saving = false;
if (response.status === 1) {
this.$message.success('配置保存成功!');
} else {
this.$message.error(response.message || '保存失败');
}
},
error: () => {
this.saving = false;
this.$message.error('保存失败,请重试');
}
});
},
// 重置配置
resetConfig() {
this.$confirm('确定要重置所有配置吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.loadConfig();
this.$message.success('配置已重置');
});
},
// 计算测试费用
calculateTestFee() {
this.calculating = true;
this.sendRequest('Retail/RiderConfig/testFeeCalculation', {
data: {
distance: this.testData.distance,
order_amount: this.testData.orderAmount,
is_urgent: this.testData.isUrgent,
is_night: this.testData.isNight,
is_bad_weather: this.testData.isBadWeather
},
success: (response) => {
this.calculating = false;
if (response.status === 1) {
this.testResult = response.data;
} else {
this.$message.error(response.message || '计算失败');
}
},
error: () => {
this.calculating = false;
this.$message.error('计算失败,请重试');
}
});
},
// 发送请求
sendRequest(url, options) {
const defaultOptions = {
method: 'POST',
data: {},
success: () => {},
error: () => {}
};
const config = { ...defaultOptions, ...options };
$.ajax({
url: `{:U('${url}')}`,
type: config.method,
data: config.data,
success: config.success,
error: config.error
});
}
},
created() {
this.loadConfig();
}
});
</script>
</body>
</html>