You need to enable JavaScript to run this app. Laravel裁切公司下单选包装公司后联动地址获取与配送选择
优惠活动
大模型
产品
解决方案
定价
更多

Laravel裁切公司下单选包装公司后联动地址获取与配送选择

功能实现落地步骤

1. 调整后端数据查询逻辑

原来的控制器加载包装公司数据时,不需要把全表字段都取出来,只保留前端需要的基础字段+地址关联字段,减少资源冗余:

public function createCutting()
{
    // 仅查询需要的字段,关联取出包装公司对接人的名称
    $packaging_company = PackagingCompany::select('id', 'address', 'lat', 'lng')
        ->with('staffs:id,name')
        ->get();
    return view('web.cutting.working_orders.create', compact('packaging_company'));
}

2. 调整前端下拉框的附属数据传递

(1)改造包装公司选择下拉框

给每个<option>标签加自定义属性,把对应公司的地址、经纬度存在标签上,减少后续冗余Ajax请求:

<div class="form-group col-lg-6" id="packaging_company">
    <label style="color: #44484d;">Select Packaging Company <span class="text-danger">*</span></label>
    <select class="form-control kt-selectpicker" required data-live-search="true" name="packaging_company">
        @foreach ($packaging_company as $company)
            <option 
                value="{{ $company->id }}"
                data-address="{{ $company->address }}"
                data-lat="{{ $company->lat }}"
                data-lng="{{ $company->lng }}"
            >
                {{ $company->staffs->name }}
            </option>
        @endforeach
    </select>
    <span class="text-danger p-1">{{ $errors->first('packaging_company') }}</span>
</div>

(2)改造配送目的地选择下拉框,新增联动区块

给下拉框加id方便事件监听,同时补充两个不同场景的地址展示/输入区块,默认隐藏,匹配对应条件再展示:

<div class="form-group col-lg-6">
    <label style="color: #44484d;">Fruit delivery destination <span class="text-danger">*</span></label>
    <select class="form-control kt-selectpicker" data-live-search="true" name="fruit_delivery_location" id="delivery_type">
        <option value="company"> Packaging Company Location </option>
        <option value="custom"> Other </option>
    </select>
    <span class="text-danger p-1">{{ $errors->first('fruit_delivery_location') }}</span>
</div>

<!-- 区块1:选中“包装公司地址”时展示,只读展示公司获取到的地址 -->
<div class="form-group col-lg-12 d-none" id="company_address_block">
    <label style="color: #44484d;">Packaging Company Address</label>
    <input type="text" class="form-control" name="company_delivery_address" id="company_address_input" readonly>
</div>

<!-- 区块2:选中“其他地址”时展示,支持手动输入+谷歌地图选点 -->
<div class="form-group col-lg-12 d-none" id="custom_address_block">
    <label style="color: #44484d;">Custom Delivery Address</label>
    <input type="text" class="form-control" name="custom_delivery_address" id="custom_address_input" placeholder="Search or select on map below">
    <div id="google_map_container" style="height: 300px; width: 100%; margin-top: 10px;"></div>
    <!-- 隐藏域存储地图选点的经纬度,提交后端使用 -->
    <input type="hidden" name="custom_delivery_lat" id="custom_lat">
    <input type="hidden" name="custom_delivery_lng" id="custom_lng">
</div>

3. 编写前端联动交互逻辑

// 全局缓存当前选中的包装公司地址数据
let selectedCompanyData = {
    address: '',
    lat: '',
    lng: ''
}

// 监听包装公司下拉选择事件
$('select[name="packaging_company"]').on('change', function() {
    const selectedOption = $(this).find('option:selected');
    // 从option的自定义属性中取出公司地址、经纬度
    selectedCompanyData = {
        address: selectedOption.data('address'),
        lat: selectedOption.data('lat'),
        lng: selectedOption.data('lng')
    }
    // 触发一次配送目的地的选择事件,自动匹配显示对应地址区块
    $('#delivery_type').trigger('change')
})

// 监听配送目的地下拉选择事件
$('#delivery_type').on('change', function() {
    const selectedType = $(this).val()
    // 先隐藏所有地址区块
    $('#company_address_block').addClass('d-none')
    $('#custom_address_block').addClass('d-none')

    if (selectedType === 'company') {
        // 选择使用包装公司地址的场景校验
        if (!selectedCompanyData.address) {
            alert('Please select a packaging company first')
            $(this).val('')
            return
        }
        // 展示公司地址区块,填充缓存的地址信息
        $('#company_address_block').removeClass('d-none')
        $('#company_address_input').val(selectedCompanyData.address)
    } else if (selectedType === 'custom') {
        // 选择自定义地址的场景:展示自定义区块,初始化谷歌地图
        $('#custom_address_block').removeClass('d-none')
        initGoogleMap()
    }
})

// 谷歌地图选点核心逻辑
let map, marker;
function initGoogleMap() {
    // 地图初始中心点:优先用已选包装公司的坐标,无则用默认城市坐标
    const centerPoint = selectedCompanyData.lat ? 
        {lat: parseFloat(selectedCompanyData.lat), lng: parseFloat(selectedCompanyData.lng)} :
        {lat: 0, lng: 0} // 替换为业务覆盖的默认城市坐标
    
    map = new google.maps.Map(document.getElementById('google_map_container'), {
        zoom: 15,
        center: centerPoint
    })
    marker = new google.maps.Marker({
        position: centerPoint,
        map: map,
        draggable: true // 支持拖拽Marker选点
    })

    // Marker拖拽结束后自动反查对应地址,填充表单字段
    google.maps.event.addListener(marker, 'dragend', function(event) {
        updateAddressByLatLng(event.latLng.lat(), event.latLng.lng())
    })

    // 给自定义地址输入框绑定谷歌地址搜索自动补全
    const searchBox = new google.maps.places.SearchBox(document.getElementById('custom_address_input'))
    map.addListener('bounds_changed', function() {
        searchBox.setBounds(map.getBounds())
    })
    searchBox.addListener('places_changed', function() {
        const places = searchBox.getPlaces()
        if (places.length == 0) return
        const place = places[0]
        // 搜索选中地址后,自动更新地图位置和Marker
        map.setCenter(place.geometry.location)
        marker.setPosition(place.geometry.location)
        // 填充地址和经纬度到表单字段
        $('#custom_address_input').val(place.formatted_address)
        $('#custom_lat').val(place.geometry.location.lat())
        $('#custom_lng').val(place.geometry.location.lng())
    })
}

// 通过经纬度反查格式化地址
function updateAddressByLatLng(lat, lng) {
    const geocoder = new google.maps.Geocoder()
    geocoder.geocode({location: {lat: lat, lng: lng}}, function(results) {
        if (results[0]) {
            $('#custom_address_input').val(results[0].formatted_address)
        }
        $('#custom_lat').val(lat)
        $('#custom_lng').val(lng)
    })
}

4. 落地注意事项

  • 针对kt-selectpicker组件:事件绑定要等组件初始化完成后再执行,避免因组件重绘DOM导致事件监听失效。
  • 针对表单提交:提交前需要根据选中的配送目的地类型,校验对应区块的字段完整性——选公司地址时不用校验自定义字段,选自定义地址时需确认经纬度是否获取成功。
  • 针对大数据量场景:如果包装公司总数超过100家,不建议将地址存在option的自定义属性中,可改为选中公司后发送Ajax请求获取对应地址,避免页面加载性能下降。

内容的提问来源于stack exchange,提问作者Saad Ramay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.04 14:54:04