You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue+Laravel+Axios实现销售报价单批量增改功能求助

Hey there! Let's work through this batch update/insert problem for your sales quotation form—you're already halfway there by looking into axios.all, so let's break this down step by step for both your Detail.vue frontend and SalesQuotationsController.php backend.

Core Idea First

The key here is to split your quotation items into two groups: new items (no existing ID) that need to be inserted, and existing items (with an ID) that need to be updated. You can either use axios.all to run multiple requests in parallel, or simplify things by sending all data to a single backend endpoint (I'll cover both approaches).


Frontend Implementation (Detail.vue)

First, make sure you're maintaining an array of quotation items in your component's data, where each item tracks whether it's new or existing:

1. Set Up Data & Basic UI

<template>
  <div class="quotation-form">
    <!-- Quotation Header Fields (like customer name, date, etc.) -->
    <input v-model="quotation.customer_name" placeholder="Customer Name">
    
    <!-- Item List -->
    <div v-for="(item, index) in quotationItems" :key="index" class="item-row">
      <input v-model="item.product_name" placeholder="Product Name" />
      <input v-model.number="item.price" placeholder="Unit Price" type="number" />
      <input v-model.number="item.quantity" placeholder="Quantity" type="number" />
      <button @click="removeItem(index)">Delete</button>
    </div>

    <!-- Action Buttons -->
    <button @click="addNewItem">Add New Product</button>
    <button @click="batchSave">Save All Changes</button>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      quotation: {
        id: 123, // Replace with your actual quotation ID
        customer_name: ''
      },
      quotationItems: [
        // Initialize with existing items (if editing an existing quotation)
        // { id: 1, product_name: 'Laptop', price: 999, quantity: 1 },
        // Or start empty for new quotations
      ]
    };
  },
  methods: {
    addNewItem() {
      // Add a blank new item (no ID = needs insertion)
      this.quotationItems.push({
        id: null,
        product_name: '',
        price: 0,
        quantity: 1
      });
    },
    removeItem(index) {
      this.quotationItems.splice(index, 1);
    },
    // ... Batch save method below
  }
};
</script>

2. Batch Save with axios.all

Add this method to your methods section to handle parallel requests for inserts and updates:

batchSave() {
  // Split items into new (insert) and existing (update)
  const newItems = this.quotationItems.filter(item => !item.id);
  const updateItems = this.quotationItems.filter(item => item.id);

  // Build an array of axios requests
  const requests = [];

  // Add bulk insert request for new items
  if (newItems.length > 0) {
    requests.push(axios.post('/api/quotations/items', {
      quotation_id: this.quotation.id,
      items: newItems
    }));
  }

  // Add individual update requests for existing items
  updateItems.forEach(item => {
    requests.push(axios.put(`/api/quotations/items/${item.id}`, item));
  });

  // Execute all requests in parallel
  axios.all(requests)
    .then(axios.spread((...responses) => {
      // Handle success: show feedback, refresh data
      alert('All items saved successfully!');
      // Optional: Fetch the latest quotation data from backend
      this.fetchQuotationData();
    }))
    .catch(error => {
      // Handle errors: log and notify user
      console.error('Save failed:', error);
      alert('Oops! Something went wrong. Please check your input and try again.');
    });
}

Alternative: Single Request for All Changes

If you prefer fewer network calls, send both new and updated items to one backend endpoint:

batchSave() {
  const payload = {
    quotation_id: this.quotation.id,
    new_items: this.quotationItems.filter(item => !item.id),
    updated_items: this.quotationItems.filter(item => item.id)
  };

  axios.post('/api/quotations/save-all', payload)
    .then(() => {
      alert('All changes saved!');
      this.fetchQuotationData();
    })
    .catch(error => {
      console.error('Save failed:', error);
      alert('Error saving changes.');
    });
}

Backend Implementation (SalesQuotationsController.php)

Now set up the backend endpoints to handle the frontend requests.

1. Bulk Insert for New Items

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\QuotationItem; // Replace with your actual model name

class SalesQuotationsController extends Controller
{
    // Handle bulk insertion of new quotation items
    public function storeItems(Request $request)
    {
        // Validate incoming data
        $validated = $request->validate([
            'quotation_id' => 'required|exists:quotations,id', // Ensure quotation exists
            'items.*.product_name' => 'required|string|max:255',
            'items.*.price' => 'required|numeric|min:0',
            'items.*.quantity' => 'required|integer|min:1'
        ]);

        // Bulk insert items
        foreach ($validated['items'] as $item) {
            QuotationItem::create([
                'quotation_id' => $validated['quotation_id'],
                'product_name' => $item['product_name'],
                'price' => $item['price'],
                'quantity' => $item['quantity']
                // Add any other required fields here
            ]);
        }

        return response()->json(['message' => 'Items added successfully'], 201);
    }

    // Handle update of a single existing item
    public function updateItem(Request $request, $id)
    {
        $item = QuotationItem::findOrFail($id);

        // Validate data
        $validated = $request->validate([
            'product_name' => 'required|string|max:255',
            'price' => 'required|numeric|min:0',
            'quantity' => 'required|integer|min:1'
        ]);

        // Update the item
        $item->update($validated);

        return response()->json(['message' => 'Item updated successfully'], 200);
    }

    // Alternative: Handle both insert and update in one endpoint
    public function saveAll(Request $request)
    {
        $validated = $request->validate([
            'quotation_id' => 'required|exists:quotations,id',
            'new_items.*.product_name' => 'required|string|max:255',
            'new_items.*.price' => 'required|numeric|min:0',
            'new_items.*.quantity' => 'required|integer|min:1',
            'updated_items.*.id' => 'required|exists:quotation_items,id',
            'updated_items.*.product_name' => 'required|string|max:255',
            'updated_items.*.price' => 'required|numeric|min:0',
            'updated_items.*.quantity' => 'required|integer|min:1'
        ]);

        // Insert new items
        if (!empty($validated['new_items'])) {
            foreach ($validated['new_items'] as $item) {
                QuotationItem::create([
                    'quotation_id' => $validated['quotation_id'],
                    ...$item
                ]);
            }
        }

        // Update existing items
        if (!empty($validated['updated_items'])) {
            foreach ($validated['updated_items'] as $item) {
                QuotationItem::find($item['id'])->update($item);
            }
        }

        return response()->json(['message' => 'All changes saved successfully'], 200);
    }
}

2. Set Up Routes

Add these to your routes/api.php file:

// For axios.all approach
Route::post('/quotations/items', [SalesQuotationsController::class, 'storeItems']);
Route::put('/quotations/items/{id}', [SalesQuotationsController::class, 'updateItem']);

// For single request approach
Route::post('/quotations/save-all', [SalesQuotationsController::class, 'saveAll']);

Final Tips

  • Always validate data on both frontend and backend to avoid invalid entries.
  • If you're dealing with a large number of items, the single-request approach is more efficient (fewer network roundtrips).
  • Add loading states to your save button to prevent duplicate clicks.

This should resolve your batch update/insert issue! If you hit specific errors (like validation failures or database issues), share the error messages and we can tweak the code further.

内容的提问来源于stack exchange,提问作者Rasta KP

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:02:37