Как правильно перенести калькулятор в MysQL
Имеется калькулятор, возможно ли перенести и заполнять данные в нем из БД MYSQL, в данный момент все данные хранятся в файле vue_calc.js, использовался ранее на HTML сайте. Сейчас сайт переезжает на Laravel, и хотелось бы сделать так, чтобы данные брались из БД, и изменялись в админке сайта.
У каждого дня недели свои данные, то есть в понедельник с 3 до 7 утра на своем автомобиле работа будет стоить 1250 рублей, во вторник данные уже иные 1430 рублей. Но так же всё зависит и от колонки тип автомобиля, так как на арендном в понедельник 1250 рублей, на своём же сумма эта меньше 1150 рублей.
Vue.component('time-picker', {
template: `
<div class="form-group row">
<label for="fromTime" class="col-sm-1 col-form-label">С</label>
<select v-model = "activeFrom" @change="changeHandler()" class="form-control col-sm-3" id="fromTime" >
<option v-for="time in fromIntervals">{{time}}</option>
</select>
<label for="toTime" class="col-sm-2 col-form-label">до</label>
<select v-model= "activeTo" @change="changeHandler()" class="form-control col-sm-3" id="toTime">
<option v-for="time in toIntervals">{{time}}</option>
</select>
<div class="col-sm-3 text-center">
<div class="btn-group" role="group" aria-label="Basic example">
<button
v-if="addPickerButtonVisable"
@click="addPicker()"
type="button"
class="btn btn-outline-success btn-sm"
data-toggle="tooltip"
data-placement="top"
title="Добавить время"
>
<svg width="22px" height="22px" viewBox="0 0 16 16" class="bi bi-plus-circle" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8 3.5a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5H4a.5.5 0 0 1 0-1h3.5V4a.5.5 0 0 1 .5-.5z"/>
<path fill-rule="evenodd" d="M7.5 8a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1H8.5V12a.5.5 0 0 1-1 0V8z"/>
<path fill-rule="evenodd" d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
</svg>
</button>
<button
v-if= "removePickerButtonVisable"
@click="removePicker()"
type="button"
class="btn btn-outline-danger btn-sm"
data-toggle="tooltip" data-placement="top"
title="Убрать время"
>
<svg width="22px" height="22px" viewBox="0 0 16 16" class="bi bi-x-circle" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
<path fill-rule="evenodd" d="M11.854 4.146a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708-.708l7-7a.5.5 0 0 1 .708 0z"/>
<path fill-rule="evenodd" d="M4.146 4.146a.5.5 0 0 0 0 .708l7 7a.5.5 0 0 0 .708-.708l-7-7a.5.5 0 0 0-.708 0z"/>
</svg>
</button>
</div>
</div>
</div>`,
props: ['uid', 'removePickerButtonVisable', 'addPickerButtonVisable', 'day'],
data () {
return {
activeFrom: 0,
activeTo: 0,
}
},
methods: {
addPicker() {
this.$emit('add-picker')
},
removePicker() {
this.$emit('remove-picker', this.uid)
},
changeHandler() {
if (this.activeFrom != 0 && this.activeTo != 0)
this.$emit('date-picked', { activeFrom:this.activeFrom, activeTo:this.activeTo, id:this.uid, day:this.day})
}
},
computed: {
toIntervals() {
if (this.activeFrom == 0) return [];
if (this.activeFrom == '00:00') return ['00:00'];
let avList = [];
let start = +this.activeFrom.slice(0,2); // get hours val
if ((start+1) < 10) {
for (let i = (start+1); i < 10; i++) avList.push(`0${i}:00`);
for (let i = 10; i < 24; i++) avList.push(`${i}:00`);
} else {
for (let i = (start+1); i < 24; i++) avList.push(`${i}:00`);
}
return avList;
},
fromIntervals () {
let ar = [];
for (let i = 00; i < 10; i++) ar.push(`0${i}:00`);
for (let i = 10; i < 24; i++) ar.push(`${i}:00`);
return ar;
}
}
});
Vue.component('time-picker-group', {
template: `
<div class="border-bottom">
<p>{{name}}</p>
<time-picker
:day="day"
v-for="picker in datePickerInfo"
:uid="picker.id"
:key="picker.id"
:add-picker-button-visable="addPickerButtonVisable"
:remove-picker-button-visable="removePickerButtonVisable"
@date-picked="changePicker"
@add-picker="addPicker"
@remove-picker="removePicker"
></time-picker>
</div>
`,
props: ['day', 'name'],
data () {
return {
pickerIdCounter: 0, // необходим для обеспечения уникальности пикеров времени
datePickerInfo: [
{id:0, from: -1, to: -1}
],
}
},
computed: {
removePickerButtonVisable() {
// если два и больше разрешаем удалять
return this.datePickerInfo.length > 1;
},
addPickerButtonVisable() {
// один и невыбранный
if ( (this.datePickerInfo.length == 1) && (this.datePickerInfo[0].to == -1)) return false;
// достигли максимального количества
if (this.datePickerInfo.length == 4) return false;
// иначе
return true;
}
},
methods: {
changePicker (event) {
let obj = this.datePickerInfo.find(item => item.id == event.id);
obj.from = +event.activeFrom.slice(0,2); // перевод часов в индексы
obj.to = (event.activeTo == '00:00')? 23 : ((+event.activeTo.slice(0,2)) - 1);
this.$emit('date-picked', event)
},
addPicker() {
this.datePickerInfo.push({
id: ++this.pickerIdCounter,
from: -1,
to: -1
});
},
removePicker(event) {
let index;
for (let i = 0; i < this.datePickerInfo.length; i++) {
if (this.datePickerInfo[i].id == event) index = i;
}
this.datePickerInfo.splice(index, 1);
this.$emit('date-picker-remove', {day:this.day,id:event});
},
},
});
var app = new Vue({
el: '#calc',
data () {
return {
days : [
{id:0, text:'Понедельник', active: false, },
{id:1, text:'Вторник', active: false, },
{id:2, text:'Среда', active: false, },
{id:3, text:'Четверг', active: false, },
{id:4, text:'Пятница', active: false, },
{id:5, text:'Суббота', active: false, },
{id:6, text:'Воскресенье', active: false, }
],
globalDatePickerInfo: [],
globalIntervals: [
[ // Понедельник
{from: '00', to: '01', busy: false},{from: '01', to: '02', busy: false},{from: '02', to: '03', busy: false},
{from: '03', to: '04', busy: false},{from: '04', to: '05', busy: false},{from: '05', to: '06', busy: false},
{from: '06', to: '07', busy: false},{from: '07', to: '08', busy: false},{from: '08', to: '09', busy: false},
{from: '09', to: '10', busy: false},{from: '10', to: '11', busy: false},{from: '11', to: '12', busy: false},
{from: '12', to: '13', busy: false},{from: '13', to: '14', busy: false},{from: '14', to: '15', busy: false},
{from: '15', to: '16', busy: false},{from: '16', to: '17', busy: false},{from: '17', to: '18', busy: false},
{from: '18', to: '19', busy: false},{from: '19', to: '20', busy: false},{from: '20', to: '21', busy: false},
{from: '21', to: '22', busy: false},{from: '22', to: '23', busy: false},{from: '23', to: '00', busy: false},
], [ // Вторник
{from: '00', to: '01', busy: false},{from: '01', to: '02', busy: false},{from: '02', to: '03', busy: false},
{from: '03', to: '04', busy: false},{from: '04', to: '05', busy: false},{from: '05', to: '06', busy: false},
{from: '06', to: '07', busy: false},{from: '07', to: '08', busy: false},{from: '08', to: '09', busy: false},
{from: '09', to: '10', busy: false},{from: '10', to: '11', busy: false},{from: '11', to: '12', busy: false},
{from: '12', to: '13', busy: false},{from: '13', to: '14', busy: false},{from: '14', to: '15', busy: false},
{from: '15', to: '16', busy: false},{from: '16', to: '17', busy: false},{from: '17', to: '18', busy: false},
{from: '18', to: '19', busy: false},{from: '19', to: '20', busy: false},{from: '20', to: '21', busy: false},
{from: '21', to: '22', busy: false},{from: '22', to: '23', busy: false},{from: '23', to: '00', busy: false},
], [ // Среда
{from: '00', to: '01', busy: false},{from: '01', to: '02', busy: false},{from: '02', to: '03', busy: false},
{from: '03', to: '04', busy: false},{from: '04', to: '05', busy: false},{from: '05', to: '06', busy: false},
{from: '06', to: '07', busy: false},{from: '07', to: '08', busy: false},{from: '08', to: '09', busy: false},
{from: '09', to: '10', busy: false},{from: '10', to: '11', busy: false},{from: '11', to: '12', busy: false},
{from: '12', to: '13', busy: false},{from: '13', to: '14', busy: false},{from: '14', to: '15', busy: false},
{from: '15', to: '16', busy: false},{from: '16', to: '17', busy: false},{from: '17', to: '18', busy: false},
{from: '18', to: '19', busy: false},{from: '19', to: '20', busy: false},{from: '20', to: '21', busy: false},
{from: '21', to: '22', busy: false},{from: '22', to: '23', busy: false},{from: '23', to: '00', busy: false},
], [ // Четверг
{from: '00', to: '01', busy: false},{from: '01', to: '02', busy: false},{from: '02', to: '03', busy: false},
{from: '03', to: '04', busy: false},{from: '04', to: '05', busy: false},{from: '05', to: '06', busy: false},
{from: '06', to: '07', busy: false},{from: '07', to: '08', busy: false},{from: '08', to: '09', busy: false},
{from: '09', to: '10', busy: false},{from: '10', to: '11', busy: false},{from: '11', to: '12', busy: false},
{from: '12', to: '13', busy: false},{from: '13', to: '14', busy: false},{from: '14', to: '15', busy: false},
{from: '15', to: '16', busy: false},{from: '16', to: '17', busy: false},{from: '17', to: '18', busy: false},
{from: '18', to: '19', busy: false},{from: '19', to: '20', busy: false},{from: '20', to: '21', busy: false},
{from: '21', to: '22', busy: false},{from: '22', to: '23', busy: false},{from: '23', to: '00', busy: false},
], [ // Пятница
{from: '00', to: '01', busy: false},{from: '01', to: '02', busy: false},{from: '02', to: '03', busy: false},
{from: '03', to: '04', busy: false},{from: '04', to: '05', busy: false},{from: '05', to: '06', busy: false},
{from: '06', to: '07', busy: false},{from: '07', to: '08', busy: false},{from: '08', to: '09', busy: false},
{from: '09', to: '10', busy: false},{from: '10', to: '11', busy: false},{from: '11', to: '12', busy: false},
{from: '12', to: '13', busy: false},{from: '13', to: '14', busy: false},{from: '14', to: '15', busy: false},
{from: '15', to: '16', busy: false},{from: '16', to: '17', busy: false},{from: '17', to: '18', busy: false},
{from: '18', to: '19', busy: false},{from: '19', to: '20', busy: false},{from: '20', to: '21', busy: false},
{from: '21', to: '22', busy: false},{from: '22', to: '23', busy: false},{from: '23', to: '00', busy: false},
], [ // Суббота
{from: '00', to: '01', busy: false},{from: '01', to: '02', busy: false},{from: '02', to: '03', busy: false},
{from: '03', to: '04', busy: false},{from: '04', to: '05', busy: false},{from: '05', to: '06', busy: false},
{from: '06', to: '07', busy: false},{from: '07', to: '08', busy: false},{from: '08', to: '09', busy: false},
{from: '09', to: '10', busy: false},{from: '10', to: '11', busy: false},{from: '11', to: '12', busy: false},
{from: '12', to: '13', busy: false},{from: '13', to: '14', busy: false},{from: '14', to: '15', busy: false},
{from: '15', to: '16', busy: false},{from: '16', to: '17', busy: false},{from: '17', to: '18', busy: false},
{from: '18', to: '19', busy: false},{from: '19', to: '20', busy: false},{from: '20', to: '21', busy: false},
{from: '21', to: '22', busy: false},{from: '22', to: '23', busy: false},{from: '23', to: '00', busy: false},
], [ // Воскресенье
{from: '00', to: '01', busy: false},{from: '01', to: '02', busy: false},{from: '02', to: '03', busy: false},
{from: '03', to: '04', busy: false},{from: '04', to: '05', busy: false},{from: '05', to: '06', busy: false},
{from: '06', to: '07', busy: false},{from: '07', to: '08', busy: false},{from: '08', to: '09', busy: false},
{from: '09', to: '10', busy: false},{from: '10', to: '11', busy: false},{from: '11', to: '12', busy: false},
{from: '12', to: '13', busy: false},{from: '13', to: '14', busy: false},{from: '14', to: '15', busy: false},
{from: '15', to: '16', busy: false},{from: '16', to: '17', busy: false},{from: '17', to: '18', busy: false},
{from: '18', to: '19', busy: false},{from: '19', to: '20', busy: false},{from: '20', to: '21', busy: false},
{from: '21', to: '22', busy: false},{from: '22', to: '23', busy: false},{from: '23', to: '00', busy: false},
]
],
autoVariations: [
{name: 'Свой автомобиль', active: false},
{name: 'Арендованный автомобиль', active: false},
],
currentAutoVariation: -1,
}
},
computed: {
activeDayList () {
return this.days.filter (day => day.active)
},
profitComment () {
if (this.currentAutoVariation == -1) return '';
else {
if (this.currentAutoVariation.name == 'Свой автомобиль' ) return `Ваш ориентировочный доход за неделю составит: ${this.sumOwnCar} рублей.`
else return `Ваш ориентировочный доход за неделю составит: ${this.sumRentedCar} рублей.`
}
},
sumOwnCar() {
let sum = 0;
for (let day = 0; day < this.days.length; day++) {
if (!this.days[day].active) continue;
for (let val = 0; val < this.globalIntervals[day].length; val++) {
if (!this.globalIntervals[day][val].busy) continue;
sum += this.getProfitPerIntervalByOwnCar(day,val);
}
}
return sum;
},
sumRentedCar(){
let sum = 0;
for (let day = 0; day < this.days.length; day++) {
if (!this.days[day].active) continue;
for (let val = 0; val < this.globalIntervals[day].length; val++) {
if (!this.globalIntervals[day][val].busy) continue;
sum += this.getProfitPerIntervalByRentedCar(day,val);
}
}
return sum;
},
},
methods: {
getCarVarationClass (variation) {
return variation.active? "active list-group-item list-group-item-action" : "list-group-item list-group-item-action";
},
carVariationSelectHandler(variation) {
if (this.currentAutoVariation == -1) {
variation.active = true;
} else {
this.autoVariations[0].active = !this.autoVariations[0].active;
this.autoVariations[1].active = !this.autoVariations[1].active;
}
this.currentAutoVariation = variation;
},
getProfitPerIntervalByOwnCar(day, val){
const costs = [
// ПН
[500,500,300,300,300,300,300,460,460,380,380,340,340,340,340,340,360,400,400,360,350,350,380,380],
//ВТ
[320,320,270,270,270,270,270,380,380,330,330,300,300,300,300,300,320,370,340,330,350,350,370,370],
//Ср
[350,350,300,270,270,270,270,380,380,330,330,300,300,300,300,300,320,370,340,330,350,350,370,370],
//ЧТ
[330,330,270,270,270,270,270,400,400,330,330,300,300,300,300,300,320,370,340,340,350,350,370,370],
//ПТ
[330,330,300,300,300,300,300,380,380,360,360,320,320,320,320,360,360,360,400,400,400,400,400,400],
//СБ
[400,400,400,400,400,400,400,400,400,350,350,320,320,320,320,350,350,390,390,430,430,430,430,430],
//ВС
[500,500,500,500,500,320,320,400,400,300,300,350,350,350,350,350,350,400,400,430,430,430,430,430]
];
switch (day) {
case 0: return costs[0][val];// ПН
case 1: return costs[1][val];// ВТ
case 2: return costs[2][val];// СР
case 3: return costs[3][val];// ЧТ
case 4: return costs[4][val];// ПТ
case 5: return costs[5][val];// СБ
case 6: return costs[6][val];// ВС
}
},
getProfitPerIntervalByRentedCar(day, val){
const costs = [
// ПН
[500,500,330,330,330,330,330,460,460,380,380,370,370,370,370,370,390,400,400,390,380,380,400,400],
// ВТ
[350,350,300,300,300,300,300,380,380,370,370,340,340,340,340,340,340,380,380,350,380,380,400,400],
// СР
[400,400,300,300,300,300,300,380,380,350,350,330,330,330,330,330,340,370,370,350,380,380,400,400],
// ЧТ
[380,380,300,300,300,300,300,400,400,350,350,330,330,330,330,330,340,370,370,370,380,380,400,400],
// ПТ
[380,380,320,320,320,320,320,380,380,360,360,350,350,350,350,360,360,360,400,400,400,400,400,400],
// СБ
[400,400,400,400,400,400,400,400,400,380,380,350,350,350,350,380,380,390,390,430,430,430,430,430],
// ВС
[500,500,500,500,500,340,340,420,420,350,350,380,380,380,380,380,380,400,400,430,430,430,430,430]
];
switch (day) {
case 0: return costs[0][val];// ПН
case 1: return costs[1][val];// ВТ
case 2: return costs[2][val];// СР
case 3: return costs[3][val];// ЧТ
case 4: return costs[4][val];// ПТ
case 5: return costs[5][val];// СБ
case 6: return costs[6][val];// ВС
}
},
removePicker(event) {
let removeIndex = -1;
for (let i =0; i < this.globalDatePickerInfo; i++) {
let obj = this.globalDatePickerInfo[i]
if (obj.id == event.id && obj.day == event.day) removeIndex = i;
}
this.globalDatePickerInfo.splice(removeIndex, 1);
this.updateGlobalIntervals();
},
updateGlobalIntervals () { // todo
for (let i = 0; i < this.globalIntervals.length; i++)
for (let j = 0; j < this.globalIntervals[i].length; j++)
this.globalIntervals[i][j].busy = false; // сбрасываем выбор
for (let i = 0; i < this.globalDatePickerInfo.length; i++) { // обновляем данные по всем пикерам
//if (this.datePickerInfo[i].from == -1 || this.datePickerInfo[i].to == -1) continue;
let from = this.globalDatePickerInfo[i].from;
let to = this.globalDatePickerInfo[i].to;
let day = this.globalDatePickerInfo[i].day;
for (let j = from; j <= to; j++) {
this.globalIntervals[day][j].busy = true;
}
}
},
reserveTime(event) { // todo
let activeFrom = event.activeFrom; // данные по новову выбору
let activeTo = event.activeTo;
let day = event.day;
let id = event.id;
let fromIndex = +activeFrom.slice(0,2); // перевод часов в индексы
let toIndex = (activeTo == '00:00')? 23 : ((+activeTo.slice(0,2)) - 1);
let obj = this.globalDatePickerInfo.find(item => ((item.id == id) && (item.day == day))); // получаем объект по данному пикеру
if (!obj) {
this.globalDatePickerInfo.push({from:fromIndex, to:toIndex, id:id, day:day});
} else {
obj.from = fromIndex; // сохраняем данные в глобальном хранилище
obj.to = toIndex;
}
this.updateGlobalIntervals();
},
getDayClass (day) {
return day.active? "active list-group-item list-group-item-action" : "list-group-item list-group-item-action";
},
daySelectHandler (day) {
if (day.active) {
day.active = false;
this.globalDatePickerInfo = this.globalDatePickerInfo.filter( item => item.day != day.id);
} else {
day.active = true;
}
}
}
})
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="container">
<div class="row">
<div id="calc" class="col-12 text-center">
<!-- Content here -->
<div class="row">
<div class="col-sm alert alert-prymary" role="alert">
День недели
<p>(выберите дни в которые планируете работать)</p>
</div>
<div class="col-sm alert alert-light" role="alert">
Время работы
<p>(укажите один или несколько интервалы)</p>
</div>
<div class="col-sm alert alert-light" role="alert">
Тип автомобиля
<p>(выберите тип автомобиля)</p>
</div>
</div>
<div class="row">
<div class="col-sm">
<div class="list-group">
<button v-for="day in days" type="button" :class="getDayClass(day)" @click="daySelectHandler(day)">@{{day.text}}</button>
</div>
</div>
<div class="col-sm border-right border-left">
<time-picker-group v-for="day in activeDayList" :key="day.id" :name="day.text" :day="day.id" @date-picked="reserveTime" @date-picker-remove="removePicker"></time-picker-group>
</div>
<div class="col-sm">
<div class="list-group">
<button v-for="variation in autoVariations" type="button" :class="getCarVarationClass(variation)" @click="carVariationSelectHandler(variation)">@{{variation.name}}</button>
</div>
</div>
</div>
<div class="row">
<div class="col-sm border-top mt-2 alert" role="alert">
<div class="bordered-calc"><strong>@{{profitComment}}</strong><br> Реальный доход может быть и выше, если в течении значительной части времени, которое вы посвятили работе, были неблагоприятные погодные условия, что соответственно повлекло повышенный спрос на такси и
соответствующие высокие надбавки к тарифам.</div>
</div>
</div>
</div>
</div>
Как перенести все данные из калькулятора VueJS в MYSQL ?
