<template>
|
<GlobalWindow
|
:title="title"
|
:visible.sync="visible"
|
width="60%"
|
>
|
<el-tabs v-model="activeTab">
|
<el-tab-pane label="就地寄存" name="local">
|
<div class="price-tip">根据行李尺寸以及存放天数收费(不足一天按一天计价)</div>
|
<div class="price-items">
|
<div class="price-item">
|
<span class="price-label">其中大件行李每天收费</span>
|
<el-input style="width: 200px;" v-model="form.bigPriceDay" type="number" placeholder="请输入"></el-input>
|
<span class="price-unit">元</span>
|
</div>
|
<div class="price-item">
|
<span class="price-label">其中中件行李每天收费</span>
|
<el-input style="width: 200px;" v-model="form.mediumPriceDay" type="number" placeholder="请输入"></el-input>
|
<span class="price-unit">元</span>
|
</div>
|
<div class="price-item">
|
<span class="price-label">其中小件行李每天收费</span>
|
<el-input style="width: 200px;" v-model="form.smallPriceDay" type="number" placeholder="请输入"></el-input>
|
<span class="price-unit">元</span>
|
</div>
|
</div>
|
</el-tab-pane>
|
<el-tab-pane label="异地寄存" name="remote">
|
<div class="remote-config-title">异地寄送配置</div>
|
<div class="remote-header">
|
<span class="remote-tip">根据行李尺寸、配送里程及配送价格收取费用(不足1公里按1公里计价)</span>
|
</div>
|
<el-table :data="remoteTableData" border stripe>
|
<el-table-column prop="baggageSize" label="行李尺寸" min-width="100px"></el-table-column>
|
<el-table-column prop="deliveryDistance" label="起送里程(公里)" min-width="120px">
|
<template slot-scope="{row}">
|
<el-input v-model="row.deliveryDistance" type="number" placeholder="请输入"></el-input>
|
</template>
|
</el-table-column>
|
<el-table-column prop="deliveryPrice" label="起送价格(元)" min-width="140px">
|
<template slot-scope="{row}">
|
<el-input v-model="row.deliveryPrice" type="number" placeholder="请输入"></el-input>
|
</template>
|
</el-table-column>
|
<el-table-column prop="sortnum" label="续送里程(公里)" min-width="80px">
|
<template slot-scope="{row}">
|
<el-input v-model="row.sortnum" type="number" placeholder="请输入"></el-input>
|
</template>
|
</el-table-column>
|
<el-table-column prop="sortnum" label="续送价格(元)" min-width="80px">
|
<template slot-scope="{row}">
|
<el-input v-model="row.sortnum" type="number" placeholder="请输入"></el-input>
|
</template>
|
</el-table-column>
|
</el-table>
|
</el-tab-pane>
|
<el-tab-pane label="预计时效" name="time">
|
<div class="remote-config-title">预计时效规则</div>
|
<div class="remote-header">
|
<span class="remote-tip">根据配送里程预计配送时长并展示在小程序下单页面</span>
|
</div>
|
<el-table :data="timeTableData" border stripe>
|
<el-table-column prop="deliveryDistance" label="起送里程(公里)" min-width="120px">
|
<template slot-scope="{row}">
|
<el-input v-model="row.deliveryDistance" type="number" placeholder="请输入"></el-input>
|
</template>
|
</el-table-column>
|
<el-table-column prop="deliveryHours" label="起送时长(小时)" min-width="120px">
|
<template slot-scope="{row}">
|
<el-input v-model="row.deliveryHours" type="number" placeholder="请输入"></el-input>
|
</template>
|
</el-table-column>
|
<el-table-column prop="sortnum" label="续送里程(公里)" min-width="80px">
|
<template slot-scope="{row}">
|
<el-input v-model="row.sortnum" type="number" placeholder="请输入"></el-input>
|
</template>
|
</el-table-column>
|
<el-table-column prop="sortnum" label="续送时长(小时)" min-width="80px">
|
<template slot-scope="{row}">
|
<el-input v-model="row.sortnum" type="number" placeholder="请输入"></el-input>
|
</template>
|
</el-table-column>
|
</el-table>
|
</el-tab-pane>
|
<el-tab-pane label="门店注册押金" name="deposit">
|
<div class="price-tip">根据所在城市以及注册类型不同,平台收取不同数额押金。押金会在门店退网后线下原额退还(门店线上微信支付的押金因微信官方要求具有时效性)</div>
|
<div class="price-items">
|
<div class="price-item">
|
<span class="price-label">其中企业收取押金</span>
|
<el-input style="width: 200px;" v-model="form.corporateDepositAmount" type="number" placeholder="请输入"></el-input>
|
<span class="price-unit">元</span>
|
</div>
|
<div class="price-item">
|
<span class="price-label">其中个人收取押金</span>
|
<el-input style="width: 200px;" v-model="form.personalDepositAmount" type="number" placeholder="请输入"></el-input>
|
<span class="price-unit">元</span>
|
</div>
|
</div>
|
</el-tab-pane>
|
<el-tab-pane label="分成比例" name="share">
|
<div class="price-tip">根据订单中不同运营角色而独立配置不同分成比例</div>
|
<div class="price-items">
|
<div class="price-item">
|
<span class="price-label">其中门店类型为企业并在订单中作为寄件点时,分成比例为</span>
|
<el-input style="width: 100px;" v-model="form.corporateSenderRatio" type="number" placeholder="请输入"></el-input>
|
<span class="price-unit">%</span>
|
</div>
|
<div class="price-item">
|
<span class="price-label">其中门店类型为个人并在订单中作为寄件点时,分成比例为</span>
|
<el-input style="width: 100px;" v-model="form.personalSenderRatio" type="number" placeholder="请输入"></el-input>
|
<span class="price-unit">%</span>
|
</div>
|
<div class="price-item">
|
<span class="price-label">其中门店类型为企业并在订单中作为收件点时,分成比例为</span>
|
<el-input style="width: 100px;" v-model="form.corporateReceiverRatio" type="number" placeholder="请输入"></el-input>
|
<span class="price-unit">%</span>
|
</div>
|
<div class="price-item">
|
<span class="price-label">其中门店类型为个人并在订单中作为收件点时,分成比例为</span>
|
<el-input style="width: 100px;" v-model="form.personalReceiverRatio" type="number" placeholder="请输入"></el-input>
|
<span class="price-unit">%</span>
|
</div>
|
<div class="price-item">
|
<span class="price-label">在订单中作为配送员时,分成比例为</span>
|
<el-input style="width: 100px;" v-model="form.deliverRatio" type="number" placeholder="请输入"></el-input>
|
<span class="price-unit">%</span>
|
</div>
|
</div>
|
</el-tab-pane>
|
</el-tabs>
|
<div slot="footer" class="dialog-footer">
|
<el-button @click="visible = false">取消</el-button>
|
<el-button type="primary" @click="confirm" :loading="isWorking">确定</el-button>
|
</div>
|
</GlobalWindow>
|
</template>
|
|
<script>
|
import BaseOpera from '@/components/base/BaseOpera'
|
import GlobalWindow from '@/components/common/GlobalWindow'
|
import { fetchPriceRule } from '@/api/business/areas'
|
export default {
|
name: 'OperaCityPriceRuleWindow',
|
extends: BaseOpera,
|
components: { GlobalWindow },
|
data () {
|
return {
|
activeTab: 'local',
|
remoteTableData: [
|
{ size: 1, a: '', b: '', c: '', d: '' }
|
],
|
remotePageIndex: 1,
|
remotePageSize: 5,
|
remoteTotal: 0,
|
timeTableData: [],
|
timePageIndex: 1,
|
timePageSize: 5,
|
timeTotal: 0,
|
form: {
|
id: null,
|
cityName: '',
|
bigPrice: '大件',
|
bigPriceDay: null,
|
mediumPrice: '中件',
|
mediumPriceDay: null,
|
smallPrice: '小件',
|
smallPriceDay: null,
|
remoteBigPrice: '大件',
|
remoteBigPriceDay: null,
|
remoteMediumPrice: '中件',
|
remoteMediumPriceDay: null,
|
remoteSmallPrice: '小件',
|
remoteSmallPriceDay: null,
|
timeLimit: '',
|
corporateDeposit: '企业',
|
corporateDepositAmount: null,
|
personalDeposit: '个人',
|
personalDepositAmount: null,
|
corporateType: '企业',
|
corporateSenderRatio: null,
|
corporateReceiverRatio: null,
|
personalType: '个人',
|
personalSenderRatio: null,
|
personalReceiverRatio: null,
|
deliverType: '配送员',
|
deliverRatio: null
|
}
|
}
|
},
|
created () {
|
this.config({
|
api: '/business/area',
|
'field.id': 'id'
|
})
|
},
|
methods: {
|
open (title, target) {
|
this.title = title
|
this.visible = true
|
this.activeTab = 'local'
|
this.remoteTableData = []
|
this.remotePageIndex = 1
|
this.remoteTotal = 0
|
this.timeTableData = [{
|
deliveryDistance: null,
|
deliveryHours: null,
|
sortnum: null
|
}]
|
this.timePageIndex = 1
|
this.timeTotal = 0
|
this.form = {
|
id: target.id,
|
cityName: target.name,
|
bigPrice: '大件',
|
bigPriceDay: null,
|
mediumPrice: '中件',
|
mediumPriceDay: null,
|
smallPrice: '小件',
|
smallPriceDay: null,
|
remoteBigPrice: '大件',
|
remoteBigPriceDay: null,
|
remoteMediumPrice: '中件',
|
remoteMediumPriceDay: null,
|
remoteSmallPrice: '小件',
|
remoteSmallPriceDay: null,
|
timeLimit: '',
|
corporateDeposit: '企业',
|
corporateDepositAmount: null,
|
personalDeposit: '个人',
|
personalDepositAmount: null,
|
corporateType: '企业',
|
corporateSenderRatio: null,
|
corporateReceiverRatio: null,
|
personalType: '个人',
|
personalSenderRatio: null,
|
personalReceiverRatio: null,
|
deliverType: '配送员',
|
deliverRatio: null
|
}
|
this.loadPriceRule(target.id)
|
},
|
loadPriceRule (cityId) {
|
fetchPriceRule({ cityId }).then(res => {
|
if (res) {
|
try {
|
const data = typeof res === 'string' ? JSON.parse(res) : res
|
if (data.remoteList && Array.isArray(data.remoteList)) {
|
this.remoteTableData = data.remoteList
|
this.remoteTotal = data.remoteList.length
|
}
|
if (data.timeList && Array.isArray(data.timeList)) {
|
this.timeTableData = data.timeList
|
this.timeTotal = data.timeList.length
|
}
|
Object.assign(this.form, data)
|
} catch (e) {
|
console.error('Parse price rule failed', e)
|
}
|
}
|
}).catch(e => {
|
this.$tip.apiFailed(e)
|
})
|
},
|
confirm () {
|
const submitData = {
|
...this.form,
|
remoteList: this.remoteTableData,
|
timeList: this.timeTableData
|
}
|
this.isWorking = true
|
this.api.updateById(submitData)
|
.then(() => {
|
this.$tip.apiSuccess('保存成功')
|
this.visible = false
|
this.$emit('success')
|
})
|
.catch(e => {
|
this.$tip.apiFailed(e)
|
})
|
.finally(() => {
|
this.isWorking = false
|
})
|
},
|
handleAddRemote () {
|
this.$prompt('请输入行李尺寸', '新增异地寄存配置', {
|
inputValue: '',
|
confirmButtonText: '确定',
|
cancelButtonText: '取消'
|
}).then(({ value }) => {
|
if (!value) {
|
this.$message.warning('行李尺寸不能为空')
|
return
|
}
|
this.remoteTableData.push({
|
id: null,
|
baggageSize: value,
|
deliveryDistance: null,
|
deliveryPrice: null,
|
sortnum: this.remoteTableData.length + 1
|
})
|
this.remoteTotal = this.remoteTableData.length
|
}).catch(() => {})
|
},
|
handleEditRemote (row, index) {
|
this.$prompt('请输入行李尺寸', '编辑异地寄存配置', {
|
inputValue: row.baggageSize,
|
confirmButtonText: '确定',
|
cancelButtonText: '取消'
|
}).then(({ value }) => {
|
if (!value) {
|
this.$message.warning('行李尺寸不能为空')
|
return
|
}
|
this.$prompt('请输入配送里程(公里)', '编辑配送里程', {
|
inputValue: row.deliveryDistance,
|
confirmButtonText: '确定',
|
cancelButtonText: '取消'
|
}).then(({ value: distance }) => {
|
this.$prompt('请输入配送价格(每公里/元)', '编辑配送价格', {
|
inputValue: row.deliveryPrice,
|
confirmButtonText: '确定',
|
cancelButtonText: '取消'
|
}).then(({ value: price }) => {
|
this.$prompt('请输入排序', '编辑排序', {
|
inputValue: row.sortnum,
|
confirmButtonText: '确定',
|
cancelButtonText: '取消'
|
}).then(({ value: sortnum }) => {
|
this.$prompt('请输入行李尺寸', '编辑异地寄存配置', {
|
inputValue: row.baggageSize
|
})
|
this.remoteTableData.splice(index, 1, {
|
...row,
|
baggageSize: value,
|
deliveryDistance: distance ? Number(distance) : null,
|
deliveryPrice: price ? Number(price) : null,
|
sortnum: sortnum ? Number(sortnum) : this.remoteTableData.length + 1
|
})
|
}).catch(() => {})
|
}).catch(() => {})
|
}).catch(() => {})
|
}).catch(() => {})
|
},
|
handleDeleteRemote (row, index) {
|
this.$confirm('确认删除该异地寄存配置吗?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(() => {
|
this.remoteTableData.splice(index, 1)
|
this.remoteTotal = this.remoteTableData.length
|
}).catch(() => {})
|
},
|
handleAddTime () {
|
this.$refs.operaTimeRuleWindow.open('新建预计时效规则', null)
|
},
|
handleTimeRuleSuccess (data) {
|
if (data) {
|
this.timeTableData.push(data)
|
this.timeTotal = this.timeTableData.length
|
}
|
},
|
handleEditTime (row, index) {
|
this.$prompt('请输入配送里程(公里)', '编辑预计时效配置', {
|
inputValue: row.deliveryDistance,
|
confirmButtonText: '确定',
|
cancelButtonText: '取消'
|
}).then(({ value }) => {
|
this.$prompt('请输入配送时长(小时)', '编辑预计时效配置', {
|
inputValue: row.deliveryHours,
|
confirmButtonText: '确定',
|
cancelButtonText: '取消'
|
}).then(({ value: hours }) => {
|
this.$prompt('请输入排序', '编辑预计时效配置', {
|
inputValue: row.sortnum,
|
confirmButtonText: '确定',
|
cancelButtonText: '取消'
|
}).then(({ value: sortnum }) => {
|
this.timeTableData.splice(index, 1, {
|
...row,
|
deliveryDistance: value ? Number(value) : null,
|
deliveryHours: hours ? Number(hours) : null,
|
sortnum: sortnum ? Number(sortnum) : this.timeTableData.length + 1
|
})
|
}).catch(() => {})
|
}).catch(() => {})
|
}).catch(() => {})
|
},
|
handleDeleteTime (row, index) {
|
this.$confirm('确认删除该预计时效配置吗?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(() => {
|
this.timeTableData.splice(index, 1)
|
this.timeTotal = this.timeTableData.length
|
}).catch(() => {})
|
},
|
handleTimePageChange (page) {
|
this.timePageIndex = page
|
},
|
handleRemotePageChange (page) {
|
this.remotePageIndex = page
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.price-tip {
|
margin-bottom: 20px;
|
color: #666;
|
font-size: 14px;
|
}
|
.price-items {
|
display: flex;
|
flex-direction: column;
|
gap: 16px;
|
}
|
.price-item {
|
display: flex;
|
align-items: center;
|
gap: 10px;
|
}
|
.price-label {
|
flex-shrink: 0;
|
font-weight: 500;
|
}
|
.price-unit {
|
color: #666;
|
white-space: nowrap;
|
}
|
.dialog-footer {
|
text-align: right;
|
padding: 10px 20px;
|
border-top: 1px solid #eee;
|
}
|
.remote-config-title {
|
font-weight: bold;
|
margin-bottom: 15px;
|
}
|
.remote-header {
|
display: flex;
|
align-items: center;
|
gap: 15px;
|
margin-bottom: 15px;
|
}
|
.remote-tip {
|
color: #666;
|
font-size: 14px;
|
}
|
.remote-pagination {
|
margin-top: 15px;
|
text-align: right;
|
}
|
</style>
|