Tutorial POS Restaurante – Laravel + Vue.js Parte 3 : Crear producto y almacenar imagen

SQL Mysql

Crear una tabla llamado productos y ejecutar en sql

--
-- Estructura de tabla para la tabla `productos`
--

CREATE TABLE `productos` (
  `prod_id` int(11) NOT NULL,
  `prod_name` varchar(100) NOT NULL,
  `prod_price` int(11) NOT NULL,
  `prod_description` varchar(300) DEFAULT NULL,
  `prod_categoria` int(11) NOT NULL,
  `prod_visible` tinyint(1) NOT NULL,
  `prod_delete` tinyint(1) NOT NULL,
  `prod_image` text
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Índices para tablas volcadas
--

--
-- Indices de la tabla `productos`
--
ALTER TABLE `productos`
  ADD PRIMARY KEY (`prod_id`);

--
-- AUTO_INCREMENT de las tablas volcadas
--

--
-- AUTO_INCREMENT de la tabla `productos`
--
ALTER TABLE `productos`
  MODIFY `prod_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=10;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

Vue.js (Frontend)

Componente de component-producto.vue

Crear un componente de vue resources/js/components/component-producto.vue

<template>
  <div class="container">

        <br>
        <div class="row">

          <div class="col-md-8 order-md-1">

            <h4 class="mb-3">Modulo Producto</h4>

          </div>
        </div>

  </div>  
</template>

<script>
    export default {
        data(){
        },
        mounted() {
        },
        methods:{

        }
    }
</script>

Importar el componente en el app.js

Vue.component('component-producto', require('./components/component-producto.vue').default);

Variables

data(){
          return{
            listCat:[],
            campoName:'Hamburguesa',
            campoDescription:'Descripcion de Hamburguesa',
            campoPrice:'4500',
            campoCategoria:0, 
            picFile:null
          }
        }

Formulario de Producto

<div class="form-group">
                   <label for="exampleFormControlInput1">Nombre del Producto</label>
                   <input type="text" class="form-control" id="exampleFormControlInput1" >
                 </div>
                 <div class="form-group">
                   <label for="exampleFormControlTextarea1">Descripcion</label>
                   <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
                 </div>
                 <div class="form-group">
                   <label for="exampleFormControlTextarea1">Precio</label>
                   <div class="input-group mb-3">
                      <div class="input-group-prepend">
                        <span class="input-group-text">$</span>
                      </div>
                      <input type="text" class="form-control" aria-label="Amount (to the nearest dollar)">
                      <div class="input-group-append">
                        <span class="input-group-text">.00</span>
                      </div>
                   </div>
                 </div>

                 <div class="form-group">
                   <label for="exampleFormControlSelect1">Categoria</label>
                   <select class="form-control" id="exampleFormControlSelect1">
                     <option>1</option>
                     <option>2</option>
                     <option>3</option>
                     <option>4</option>
                     <option>5</option>
                   </select>
                 </div>

                 <div class="form-group">
                    <label for="exampleFormControlInput1">Imagen</label>
                    <input type="file" class="form-control" id="exampleFormControlInput1"  >
                  </div>

Botón y Modal de Formulario del Producto

<!-- Button trigger modal -->
        <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
          Crear un producto
        </button>

        <!-- Modal -->
        <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
          <div class="modal-dialog" role="document">
            <div class="modal-content">
              <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">Formulario de producto</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                  <span aria-hidden="true">×</span>
                </button>
              </div>
              <div class="modal-body">

                <div class="form-group">
                   <label for="exampleFormControlInput1">Nombre del Producto</label>
                   <input type="text" class="form-control" v-model="campoName" >
                 </div>
                 <div class="form-group">
                   <label for="exampleFormControlTextarea1">Descripcion</label>
                   <textarea class="form-control" v-model="campoDescription" rows="2"></textarea>
                 </div>
                 <div class="form-group">
                   <label for="exampleFormControlTextarea1">Precio</label>
                   <div class="input-group mb-3">
                      <div class="input-group-prepend">
                        <span class="input-group-text">$</span>
                      </div>
                      <input type="text" class="form-control"  v-model="campoPrice">
                      <div class="input-group-append">
                        <span class="input-group-text">.00</span>
                      </div>
                   </div>
                 </div>

                 <div class="form-group">
                   <label for="exampleFormControlSelect1">Categoria</label>
                   <select class="form-control" id="exampleFormControlSelect1" @change="onSelectCategories($event)" >
                     <option v-for="cat in listCat" :value="cat.cat_id" >{{cat.cat_nombre}}</option>
                   </select>
                 </div>

                 <div class="form-group">
                    <label for="exampleFormControlInput1">Imagen</label>
                    <input type="file" class="form-control" ref="file" v-on:change="onUploadImage()"  >
                  </div>

              </div>
              <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Cerrar</button>
                <button type="button" class="btn btn-primary" v-on:click="sendNetwordCreateProduct()">Guardar</button>
              </div>
            </div>
          </div>
        </div>

Funciones de Methods

Llamar los datos de categorías para listar los opciones en el select de categoría

listCatService(){

            axios.get("api/Categoria/list")
            .then(response=>{
              // cargar datos
              this.listCat = response.data
            })
            .catch(error=>{
              alert(error)
            })

          }

Nota: Después de esto también debería agregar una linea de código para cargar datos de categoría en el mounted Mounted

this.listCatService()

@change de Select para guardar variable de seleccion de la categoria.

onSelectCategories(event){
            this.campoCategoria = event.target.value
          },

Capturar variable definido al cargar desde el campo de imagen

onUploadImage(){
            this.picFile = this.$refs.file.files[0];
          },

Enviar datos desde API

sendNetwordCreateProduct(){

            if (this.campoName=="") {
              alert("Completa los campo de nombre ")
            }
            else if (this.campoPrice=="") {
              alert("Completa los campo de precio")
            }
            else if (this.campoCategoria==0) {
              alert("Selecciona la categoria")
            }
            else {

              const formData = new FormData()
              formData.append('name',this.campoName)
              formData.append('description',this.campoDescription)
              formData.append('categorie',this.campoCategoria)
              formData.append('price',this.campoPrice)

              // por si no esta nulo
              if (this.picFile) {
                formData.append('prod_image',this.picFile)
              }

              //console.log(JSON.stringify(this))

              axios.post("api/Producto/create",formData)
              .then(response => {
                // limpiar campo_
                alert(response.data.message)
                // cargar lista de nuevo
                //this.listCatService()
              })
              .catch(error => {
                alert(error)
              })

            } 

          },

Laravel (Backend)

Modelo

Comando para crear modelo

php artisan make:model Productos

Modelo de Productos app/Productos.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Productos extends Model
{
    //
    protected $table = "productos";

    protected $fillable = [
      'prod_id',
      'prod_name',
      'prod_price',
      'prod_categoria',
      'prod_description',
      'prod_visible',
      'prod_delete',
      'prod_image'
    ];

    public $timestamps = false;

}

Controlador

Comando para crear un controlador

php artisan make:controller API/ProductoController

Controlador de Producto app/Http/Controllers/API/ProductoController.php

<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
//importar modelo
use App\Productos;
use Log;

class ProductoController extends Controller
{

    public function create(Request $request){

      $input['prod_name'] = $request->input('name'); 
      $input['prod_description'] = $request->input('description'); 
      $input['prod_categoria'] = $request->input('categorie'); 
      $input['prod_price'] = $request->input('price'); 
      
      $input['prod_visible'] = 1;
      $input['prod_delete'] = 0;
      $input['prod_image'] = null;

      if ($request->file('prod_image')==null)
      {
        $input['prod_image'] = null;
      }
      else
      {
        $image = $request->file('prod_image');
        // almacena y captura el nombre del archivo
        $input['prod_image'] =  $image->store('producto','public');
      }

      $data = Productos::insert($input);

      $response['message'] = "Guardo exitosamente ";
      $response['success'] = true;
      return $response;

    }
}

Blade

resources/views/producto.blade.php

html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Jumbotron Template for Bootstrap</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  </head>

  <body >

    <div id="app">
      <component-header-pos></component-header-pos>
      <component-categoria></component-categoria> 
    </div>

    <!-- importar component vue -->
    <script src="{{ asset('js/app.js') }}" ></script>

    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  </body>
</html>

Ruta

routes/web.php

Route::get('/producto', function () {
    return view('producto');
});


// API
Route::group(['prefix'=>'api'],function(){

  // ...... //

  // producto
  Route::post('Producto/create','API\ProductoController@create');


});

y Ahora a compilar npm run watch-poll

Pronto en GITHUB

Añadir un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *