LabWork05 35
This commit is contained in:
parent
6699eda085
commit
743f35ffef
@ -13,11 +13,14 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// https://mvnrepository.com/artifact/commons-io/commons-io
|
||||
implementation group: 'commons-io', name: 'commons-io', version: '2.6'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'com.h2database:h2:2.1.210'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
|
||||
implementation 'org.webjars:bootstrap:5.1.3'
|
||||
implementation 'org.webjars:jquery:3.6.0'
|
||||
implementation 'org.webjars:font-awesome:6.1.0'
|
||||
|
||||
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.5'
|
||||
|
||||
|
@ -19,9 +19,6 @@
|
||||
<td>
|
||||
<button class="btn btn-danger" @click="deleteCategory(categor.id)">Удалить</button>
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-primary mr-2" @click="OpenModelForProducts();getProductsFromCategory(categor.id)">Просмотр продуктов</button>
|
||||
</td>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -98,9 +95,6 @@ export default {
|
||||
const addModal = document.getElementById('editModal');
|
||||
addModal.addEventListener('shown.bs.modal', function () {
|
||||
})
|
||||
const ModelForProducts = document.getElementById('ModelForProducts');
|
||||
addModal.addEventListener('shown.bs.modal', function () {
|
||||
})
|
||||
},
|
||||
|
||||
data() {
|
||||
@ -169,22 +163,6 @@ export default {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
getProductsFromCategory(category_id){
|
||||
axios.get(this.URL + `group/${category_id}/products`)
|
||||
.then(response => {
|
||||
this.products = response.data;
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
OpenModelForProducts() {
|
||||
document.getElementById("ModelForProducts").style.display = "block";
|
||||
},
|
||||
closeModelForProducts() {
|
||||
document.getElementById("ModelForProducts").style.display = "none";
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -25,6 +25,9 @@
|
||||
<td>
|
||||
<button class="btn btn-danger" @click="deleteProduct(prdct.id)">Удалить</button>
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-primary" @click="product = prdct; openManyToManyModal()">Производители</button>
|
||||
</td>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -69,6 +72,44 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal" tabindex="-1" id="manyToManyModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Add Manufacturers to Product</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Название:</th>
|
||||
<th>Редактировать запись:</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="prod in productManufacturers" :key="prod.id">
|
||||
<td>{{ prod.name }}</td>
|
||||
<td>
|
||||
<button class="btn btn-primary" type="button" @click="removeManufacturer(prod.id)">Удалить</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="input-group mb-3">
|
||||
<select class="form-select" v-model="manufacturerId">
|
||||
<option v-for="mnfctr in manufacturers" :key="mnfctr.id" :value="mnfctr.id">{{ mnfctr.name }}</option>
|
||||
</select>
|
||||
<button class="btn btn-outline-secondary" type="button" @click="addManufacturer()">Добавить</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="editModal" @click="closeManyToManyModal()">Закрыть</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import 'axios';
|
||||
@ -89,6 +130,9 @@ export default {
|
||||
return{
|
||||
products: [],
|
||||
categories: [],
|
||||
manufacturers: [],
|
||||
productManufacturers: [],
|
||||
manufacturerId: 0,
|
||||
URL: "http://localhost:8080/",
|
||||
product: new Product(),
|
||||
editedProduct: new Product(),
|
||||
@ -135,7 +179,8 @@ export default {
|
||||
})
|
||||
},
|
||||
async editProduct(product){
|
||||
await this.toBase64();
|
||||
if(product.photo === undefined) await this.toBase64();
|
||||
console.log(product);
|
||||
axios.put(this.URL + `product/${product.id}`, product)
|
||||
.then(() =>{
|
||||
const index = this.products.findIndex((s) => s.id === product.id);
|
||||
@ -169,7 +214,7 @@ export default {
|
||||
await new Promise((resolve, reject) => {
|
||||
reader.onload = function () {
|
||||
phototemp.photo = reader.result;
|
||||
console.log("phototemp: " + phototemp);
|
||||
console.log(phototemp);
|
||||
resolve();
|
||||
};
|
||||
reader.onerror = function (error) {
|
||||
@ -178,6 +223,49 @@ export default {
|
||||
};
|
||||
});
|
||||
},
|
||||
openManyToManyModal(){
|
||||
this.getAllManufacturers();
|
||||
this.getProductManufacturers();
|
||||
document.getElementById("manyToManyModal").style.display = "block";
|
||||
},
|
||||
closeManyToManyModal() {
|
||||
document.getElementById("manyToManyModal").style.display = "none";
|
||||
},
|
||||
getAllManufacturers(){
|
||||
axios.get(this.URL + "manufacturer")
|
||||
.then(response => {
|
||||
this.manufacturers = response.data;
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
getProductManufacturers(){
|
||||
axios.get(this.URL + `product/${this.product.id}/manufacturers`)
|
||||
.then(response => {
|
||||
this.productManufacturers = response.data;
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
addManufacturer(){
|
||||
axios.post(this.URL + `product/${this.product.id}/Manufacturer/${this.manufacturerId}`)
|
||||
.then(() => {
|
||||
this.getProductManufacturers();
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
removeManufacturer(id){
|
||||
axios.delete(this.URL + `product/${this.product.id}/Manufacturer/${id}`)
|
||||
.then(() =>{
|
||||
this.getProductManufacturers();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -3,6 +3,7 @@ package ru.ulstu.is.sbapp.HardwareShop.controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ru.ulstu.is.sbapp.HardwareShop.models.Category;
|
||||
import ru.ulstu.is.sbapp.HardwareShop.services.CategoryService;
|
||||
import ru.ulstu.is.sbapp.WebConfiguration;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.xml.crypto.dsig.CanonicalizationMethod;
|
||||
@ -11,7 +12,7 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/category")
|
||||
@RequestMapping(WebConfiguration.REST_API + "/category")
|
||||
public class CategoryController {
|
||||
private final CategoryService categoryService;
|
||||
|
||||
|
@ -24,4 +24,8 @@ public class CategoryDTO {
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setId(Long id) { this.id = id; }
|
||||
|
||||
public void setName(String name) { this.name = name; }
|
||||
}
|
||||
|
@ -0,0 +1,65 @@
|
||||
package ru.ulstu.is.sbapp.HardwareShop.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ru.ulstu.is.sbapp.HardwareShop.models.Category;
|
||||
import ru.ulstu.is.sbapp.HardwareShop.services.CategoryService;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/category")
|
||||
public class CategoryMvcController {
|
||||
private final CategoryService categoryService;
|
||||
|
||||
public CategoryMvcController(CategoryService categoryService) {
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getCategories(Model model) {
|
||||
model.addAttribute("categories", categoryService.findAllCategories()
|
||||
.stream()
|
||||
.map(CategoryDTO::new)
|
||||
.toList());
|
||||
return "categories";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/update", "/update/{id}"})
|
||||
public String updateCategory(@PathVariable(required = false) Long id,
|
||||
Model model) {
|
||||
if (id == null || id <= 0) {
|
||||
model.addAttribute("categoryDto", new CategoryDTO());
|
||||
} else {
|
||||
model.addAttribute("categoryDto", id);
|
||||
model.addAttribute("categoryDto", new CategoryDTO(categoryService.findCategory(id)));
|
||||
}
|
||||
return "category-update";
|
||||
}
|
||||
|
||||
@PostMapping(value = {"/", "/{id}"})
|
||||
public String saveCategory(@PathVariable(required = false) Long id,
|
||||
@ModelAttribute("categoryDto") CategoryDTO categoryDTO,
|
||||
BindingResult bindingResult,
|
||||
Model model) throws IOException {
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors",
|
||||
bindingResult.getAllErrors());
|
||||
return "category-update";
|
||||
}
|
||||
if (id == null || id <= 0) {
|
||||
categoryService.addCategory(categoryDTO);
|
||||
} else {
|
||||
categoryService.updateCategory(id, categoryDTO);
|
||||
}
|
||||
return "redirect:/category";
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String deleteCategory(@PathVariable Long id) {
|
||||
categoryService.deleteCategory(id);
|
||||
return "redirect:/category";
|
||||
}
|
||||
}
|
@ -4,13 +4,14 @@ package ru.ulstu.is.sbapp.HardwareShop.controller;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ru.ulstu.is.sbapp.HardwareShop.services.ManufacturerService;
|
||||
import ru.ulstu.is.sbapp.WebConfiguration;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/manufacturer")
|
||||
@RequestMapping(WebConfiguration.REST_API + "/manufacturer")
|
||||
public class ManufacturerController {
|
||||
private final ManufacturerService manufacturerService;
|
||||
|
||||
|
@ -30,4 +30,10 @@ public class ManufacturerDTO {
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setId(Long id) { this.id = id; }
|
||||
|
||||
public void setName(String name) { this.name = name; }
|
||||
|
||||
public void setAddress(String address) { this.address = address; }
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
package ru.ulstu.is.sbapp.HardwareShop.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ru.ulstu.is.sbapp.HardwareShop.services.ManufacturerService;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/manufacturer")
|
||||
public class ManufacturerMvcController {
|
||||
private final ManufacturerService manufacturerService;
|
||||
|
||||
public ManufacturerMvcController(ManufacturerService manufacturerService) {
|
||||
this.manufacturerService = manufacturerService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getManufacturers(Model model) {
|
||||
model.addAttribute("manufacturers",
|
||||
manufacturerService.findAllManufacturers().stream()
|
||||
.map(ManufacturerDTO::new)
|
||||
.toList());
|
||||
return "manufacturers";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/update", "/update/{id}"})
|
||||
public String editManufacturer(@PathVariable(required = false) Long id,
|
||||
Model model) {
|
||||
if (id == null || id <= 0) {
|
||||
model.addAttribute("manufacturerDto", new ManufacturerDTO());
|
||||
} else {
|
||||
model.addAttribute("manufacturerDto", id);
|
||||
model.addAttribute("manufacturerDto", new ManufacturerDTO(manufacturerService.findManufacturer(id)));
|
||||
}
|
||||
return "manufacturer-update";
|
||||
}
|
||||
|
||||
@PostMapping(value = {"/", "/{id}"})
|
||||
public String saveManufacturer(@PathVariable(required = false) Long id,
|
||||
@ModelAttribute("manufacturerDto") ManufacturerDTO manufacturerDTO,
|
||||
BindingResult bindingResult,
|
||||
Model model) throws IOException {
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors",
|
||||
bindingResult.getAllErrors());
|
||||
return "manufacturer-update";
|
||||
}
|
||||
if (id == null || id <= 0) {
|
||||
manufacturerService.addManufacturer(manufacturerDTO);
|
||||
} else {
|
||||
manufacturerService.updateManufacturer(id, manufacturerDTO);
|
||||
}
|
||||
return "redirect:/manufacturer";
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String deleteGenre(@PathVariable Long id) {
|
||||
manufacturerService.deleteManufacturer(id);
|
||||
return "redirect:/manufacturer";
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import ru.ulstu.is.sbapp.HardwareShop.models.Product;
|
||||
import ru.ulstu.is.sbapp.HardwareShop.services.ManufacturerService;
|
||||
import ru.ulstu.is.sbapp.HardwareShop.services.ProductService;
|
||||
import ru.ulstu.is.sbapp.WebConfiguration;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
@ -13,7 +14,7 @@ import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/product")
|
||||
@RequestMapping(WebConfiguration.REST_API + "/product")
|
||||
public class ProductController {
|
||||
|
||||
private final ProductService productService;
|
||||
@ -34,6 +35,11 @@ public class ProductController {
|
||||
.toList();
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/manufacturers")
|
||||
public List<ManufacturerDTO> getProductManufacturers(@PathVariable Long id){
|
||||
return productService.getProductManufacturers(id).stream().map(ManufacturerDTO::new).toList();
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ProductDTO createProduct(@RequestBody @Valid ProductDTO productDTO) throws IOException{
|
||||
return new ProductDTO(productService.addProduct(productDTO));
|
||||
@ -44,9 +50,14 @@ public class ProductController {
|
||||
return new ProductDTO(productService.updateProduct(id, productDTO));
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/{manufacturer}")
|
||||
public void addManufacturer(@PathVariable Long id, @PathVariable Long manufacturer_id) {
|
||||
productService.addManufacturersToProduct(id, manufacturer_id);
|
||||
@PostMapping("/{id}/Manufacturer/{manufacturerId}")
|
||||
public void addManufacturer(@PathVariable Long id, @PathVariable Long manufacturerId) {
|
||||
productService.addManufacturersToProduct(id, manufacturerId);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}/Manufacturer/{manufacturerId}")
|
||||
public void removeManufacturer(@PathVariable Long id, @PathVariable Long manufacturerId) {
|
||||
productService.removeManufacturersToProduct(id, manufacturerId);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
|
@ -15,6 +15,8 @@ public class ProductDTO {
|
||||
@JsonProperty("categoryId")
|
||||
private Long category_id;
|
||||
|
||||
private String categoryName;
|
||||
|
||||
private String name;
|
||||
|
||||
public ProductDTO() {}
|
||||
@ -25,6 +27,7 @@ public class ProductDTO {
|
||||
this.price = product.getPrice();
|
||||
this.photo = new String(product.getPhoto(), StandardCharsets.UTF_8);
|
||||
this.category_id = product.getCategory().getId();
|
||||
this.categoryName = product.getCategory().getName();
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
@ -45,9 +48,15 @@ public class ProductDTO {
|
||||
return category_id;
|
||||
}
|
||||
|
||||
public String getCategoryName() { return categoryName; }
|
||||
|
||||
public void setId(Long id) { this.id = id; }
|
||||
|
||||
public void setPhoto(String photo) { this.photo = photo; }
|
||||
|
||||
public void setName(String name) { this.name = name; }
|
||||
|
||||
public void setPrice(Integer price) { this.price = price; }
|
||||
|
||||
public void setCategoryName(String name) { this.categoryName = name; }
|
||||
}
|
||||
|
@ -0,0 +1,104 @@
|
||||
package ru.ulstu.is.sbapp.HardwareShop.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import ru.ulstu.is.sbapp.HardwareShop.services.CategoryService;
|
||||
import ru.ulstu.is.sbapp.HardwareShop.services.ManufacturerService;
|
||||
import ru.ulstu.is.sbapp.HardwareShop.services.ProductService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/product")
|
||||
public class ProductMvcController {
|
||||
private final ProductService productService;
|
||||
private final ManufacturerService manufacturerService;
|
||||
|
||||
private final CategoryService categoryService;
|
||||
|
||||
public ProductMvcController(ProductService productService, ManufacturerService manufacturerService, CategoryService categoryService) {
|
||||
this.productService = productService;
|
||||
this.manufacturerService = manufacturerService;
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getProducts(Model model) {
|
||||
model.addAttribute("products",
|
||||
productService.findAllProducts().stream()
|
||||
.map(ProductDTO::new)
|
||||
.toList());
|
||||
return "products";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/update", "/update/{id}"})
|
||||
public String updateProduct(@PathVariable(required = false) Long id,
|
||||
Model model) {
|
||||
model.addAttribute("Manufacturers", manufacturerService.findAllManufacturers());
|
||||
if (id == null || id <= 0) {
|
||||
model.addAttribute("productDto", new ProductDTO());
|
||||
} else {
|
||||
model.addAttribute("productDto", id);
|
||||
model.addAttribute("productDto", new ProductDTO(productService.findProduct(id)));
|
||||
}
|
||||
return "product-update";
|
||||
}
|
||||
|
||||
@PostMapping(value = {"/", "/{id}"})
|
||||
public String saveProduct(@PathVariable(required = false) Long id,
|
||||
@RequestParam(value = "multipartFile") MultipartFile multipartFile,
|
||||
@ModelAttribute("productDto") ProductDTO productDTO,
|
||||
BindingResult bindingResult,
|
||||
Model model) throws IOException {
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors",
|
||||
bindingResult.getAllErrors());
|
||||
return "product-update";
|
||||
}
|
||||
productDTO.setPhoto("data:" + multipartFile.getContentType() + ";base64," + Base64.getEncoder().encodeToString(multipartFile.getBytes()));
|
||||
productDTO.setCategoryName(categoryService.findCategory(productDTO.getCategory_id()).getName());
|
||||
if (id == null || id <= 0) {
|
||||
productService.addProduct(productDTO);
|
||||
} else {
|
||||
productService.updateProduct(id, productDTO);
|
||||
}
|
||||
return "redirect:/product";
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String deleteBook(@PathVariable Long id) {
|
||||
productService.deleteProduct(id);
|
||||
return "redirect:/product";
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/manufacturers")
|
||||
public String getProductManufacturers(@PathVariable Long id, Model model){
|
||||
model.addAttribute("product",
|
||||
new ProductDTO(productService.findProduct(id)));
|
||||
model.addAttribute("productmanufacturers",
|
||||
productService.getProductManufacturers(id).stream()
|
||||
.map(ManufacturerDTO::new)
|
||||
.toList());
|
||||
model.addAttribute("manufacturers",
|
||||
manufacturerService.findAllManufacturers().stream()
|
||||
.map(ManufacturerDTO::new)
|
||||
.toList());
|
||||
return "product-mtm";
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/manufacturers")
|
||||
public String addManufacturerToProduct(@PathVariable Long id, @RequestParam(value = "manufacturerid") Long manufacturerid){
|
||||
productService.addManufacturersToProduct(id, manufacturerid);
|
||||
return "redirect:/product/" + id.toString() + "/manufacturers";
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/manufacturers/{manufacturerid}")
|
||||
public String removeManufacturerFromProduct(@PathVariable Long id, @PathVariable Long manufacturerid){
|
||||
productService.removeManufacturersToProduct(id, manufacturerid);
|
||||
return "redirect:/product/" + id.toString() + "/manufacturers";
|
||||
}
|
||||
}
|
@ -58,7 +58,7 @@ public class Product {
|
||||
|
||||
public String getName() { return name; }
|
||||
|
||||
public void setName() { this.name = name; }
|
||||
public void setName(String name) { this.name = name; }
|
||||
|
||||
public void setPrice(Integer price) { this.price = price; }
|
||||
|
||||
|
@ -76,8 +76,10 @@ public class ProductService {
|
||||
@Transactional
|
||||
public Product updateProduct(Long id, ProductDTO productDTO) {
|
||||
final Product currentProduct = findProduct(id);
|
||||
currentProduct.setName(productDTO.getName());
|
||||
currentProduct.setPrice(productDTO.getPrice());
|
||||
/*currentProduct.setPhoto(productDTO.getPhoto().getBytes(StandardCharsets.UTF_8));*/
|
||||
currentProduct.setPhoto(productDTO.getPhoto().getBytes(StandardCharsets.UTF_8));
|
||||
currentProduct.setCategory(categoryService.findCategory(productDTO.getCategory_id()));
|
||||
validatorUtil.validate(currentProduct);
|
||||
return productRepository.save(currentProduct);
|
||||
}
|
||||
@ -121,8 +123,7 @@ public class ProductService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List getProductManufacturers(Long id){
|
||||
List manufacturers = productRepository.getManufacturers(id);
|
||||
return manufacturers;
|
||||
public List<Manufacturer> getProductManufacturers(Long id){
|
||||
return productRepository.findById(id).get().getManufacturerList();
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,11 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import ru.ulstu.is.sbapp.Util.Validation.ValidationException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ControllerAdvice
|
||||
@ControllerAdvice(annotations = RestController.class)
|
||||
public class AdviceController {
|
||||
@ExceptionHandler({
|
||||
ValidationException.class
|
||||
|
@ -2,10 +2,18 @@ package ru.ulstu.is.sbapp;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfiguration implements WebMvcConfigurer {
|
||||
public static final String REST_API = "/api";
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
WebMvcConfigurer.super.addViewControllers(registry);
|
||||
registry.addViewController("product");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**").allowedMethods("*");
|
||||
|
49
src/main/resources/templates/categories.html
Normal file
49
src/main/resources/templates/categories.html
Normal file
@ -0,0 +1,49 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div>
|
||||
<a class="btn btn-success button-fixed"
|
||||
th:href="@{/category/update/}">
|
||||
<i class="fa-solid fa-plus"></i> Добавить
|
||||
</a>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Название</th>
|
||||
<th scope="col">Редактировать запись</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="category, iterator: ${categories}">
|
||||
<td th:text="${category.name}" style="width: 60%"/>
|
||||
<td style="width: 10%">
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<a class="btn btn-warning button-fixed button-sm"
|
||||
th:href="@{/category/update/{id}(id=${category.id})}">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
||||
</a>
|
||||
<button type="button" class="btn btn-danger button-fixed button-sm"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${category.id}').click()|">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
||||
</button>
|
||||
</div>
|
||||
<form th:action="@{/category/delete/{id}(id=${category.id})}" method="post">
|
||||
<button th:id="'remove-' + ${category.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
31
src/main/resources/templates/category-update.html
Normal file
31
src/main/resources/templates/category-update.html
Normal file
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||
<form action="#" th:action="@{/category/{id}(id=${id})}" th:object="${categoryDto}" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Название</label>
|
||||
<input type="text" class="form-control" id="name" th:field="${categoryDto.name}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-success button-fixed">
|
||||
<span th:if="${id == null}">
|
||||
<i class="fa-solid fa-plus"></i> Добавить
|
||||
</span>
|
||||
<span th:if="${id != null}">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i> Сохранить
|
||||
</span>
|
||||
</button>
|
||||
<a class="btn btn-secondary button-fixed" th:href="@{/category}">
|
||||
Назад
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
48
src/main/resources/templates/default.html
Normal file
48
src/main/resources/templates/default.html
Normal file
@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Онлайн магазин</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<link rel="icon" href="/favicon.svg">
|
||||
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
|
||||
<link rel="stylesheet" href="/webjars/bootstrap/5.1.3/css/bootstrap.min.css"/>
|
||||
<link rel="stylesheet" href="/webjars/font-awesome/6.1.0/css/all.min.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<header class="fixed-top">
|
||||
<nav class="navbar navbar-expand-lg bg-success" data-bs-theme="dark">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="#">
|
||||
<strong class="text-white"> Online Shop </strong>
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
|
||||
<div class="navbar-nav" th:with="activeLink=${#request.requestURI}">
|
||||
<a class="nav-link active text-white" aria-current="page" href="/product" th:classappend="${#strings.equals(activeLink, '/product')} ? 'active' : ''">Products</a>
|
||||
<a class="nav-link active text-white" href="/category" th:classappend="${#strings.equals(activeLink, '/category')} ? 'active' : ''">Categories</a>
|
||||
<a class="nav-link active text-white" href="/manufacturer" th:classappend="${#strings.equals(activeLink, '/manufacturer')} ? 'active' : ''">Manufacturers</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<div class="container-fluid" style="margin-top: 50pt;">
|
||||
<div class="container container-padding" layout:fragment="content">
|
||||
</div>
|
||||
</div>
|
||||
<footer class="container pt-4 my-md-5 pt-md-5 text-center border-top">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md">
|
||||
<h5 class=""><strong>End</strong></h5>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
<th:block layout:fragment="scripts">
|
||||
</th:block>
|
||||
</html>
|
10
src/main/resources/templates/error.html
Normal file
10
src/main/resources/templates/error.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
31
src/main/resources/templates/manufacturer-update.html
Normal file
31
src/main/resources/templates/manufacturer-update.html
Normal file
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||
<form action="#" th:action="@{/manufacturer/{id}(id=${id})}" th:object="${manufacturerDto}" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Название</label>
|
||||
<input type="text" class="form-control" id="name" th:field="${manufacturerDto.name}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-success button-fixed">
|
||||
<span th:if="${id == null}">
|
||||
<i class="fa-solid fa-plus"></i> Добавить
|
||||
</span>
|
||||
<span th:if="${id != null}">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i> Сохранить
|
||||
</span>
|
||||
</button>
|
||||
<a class="btn btn-secondary button-fixed" th:href="@{/manufacturer}">
|
||||
Назад
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
51
src/main/resources/templates/manufacturers.html
Normal file
51
src/main/resources/templates/manufacturers.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div>
|
||||
<a class="btn btn-success button-fixed"
|
||||
th:href="@{/manufacturer/update/}">
|
||||
<i class="fa-solid fa-plus"></i> Добавить
|
||||
</a>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Название</th>
|
||||
<th scope="col">Адресс</th>
|
||||
<th scope="col">Редактировать запись</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="manufacturer, iterator: ${manufacturers}">
|
||||
<td th:text="${manufacturer.name}" style="width: 35%"/>
|
||||
<td th:text="${manufacturer.address}" style="width: 35%"/>
|
||||
<td style="width: 10%">
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<a class="btn btn-warning button-fixed button-sm"
|
||||
th:href="@{/manufacturer/update/{id}(id=${manufacturer.id})}">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
||||
</a>
|
||||
<button type="button" class="btn btn-danger button-fixed button-sm"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${manufacturer.id}').click()|">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
||||
</button>
|
||||
</div>
|
||||
<form th:action="@{/manufacturer/delete/{id}(id=${manufacturer.id})}" method="post">
|
||||
<button th:id="'remove-' + ${manufacturer.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
50
src/main/resources/templates/product-mtm.html
Normal file
50
src/main/resources/templates/product-mtm.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Название</th>
|
||||
<th scope="col">Редактировать запись</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="pm, iterator: ${productmanufacturers}">
|
||||
<td th:text="${pm.name}" style="width: 25%"/>
|
||||
<td style="width: 10%">
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<button type="button" class="btn btn-danger button-fixed button-sm"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${pm.id}').click()|">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
||||
</button>
|
||||
</div>
|
||||
<form th:action="@{/product/{id}/manufacturers/{manufacturerid}(id=${product.id}, manufacturerid=${bg.id})}" method="post">
|
||||
<button th:id="'remove-' + ${pm.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<form th:action="@{/product/{id}/manufacturers(id=${product.id})}" enctype="manufacturerid/form-data" method="post">
|
||||
<div class="input-group mb-3">
|
||||
<select class="form-select" th:name="manufacturerid">
|
||||
<option th:each="manufacturer, iterator: ${manufacturers}" th:value="${manufacturer.id}" th:text="${manufacturer.name}"></option>
|
||||
</select>
|
||||
<button class="btn btn-outline-secondary" type="submit">Добавить</button>
|
||||
</div>
|
||||
</form>
|
||||
<div>
|
||||
<a class="btn btn-secondary" th:href="@{/product}">Закрыть</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
44
src/main/resources/templates/product-update.html
Normal file
44
src/main/resources/templates/product-update.html
Normal file
@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||
<form action="#" th:action="@{/product/{id}(id=${id})}" th:object="${productDto}" method="post" enctype="multipart/form-data">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Название</label>
|
||||
<input type="text" class="form-control" id="name" th:field="${productDto.name}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="price" class="form-label">Цена</label>
|
||||
<input type="text" class="form-control" id="price" th:field="${productDto.price}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="photo" class="form-label">Фото</label>
|
||||
<input type="file" class="form-control" id="photo" th:name="multipartFile" required="true">
|
||||
<img th:src="${productDto.photo}" class="img-thumbnail mw-50 mh-50"/>
|
||||
</div>
|
||||
<label for="category" class="form-label">Категория</label>
|
||||
<select id="category" class="form-control" th:field="${productDto.category_id}">
|
||||
<option th:each="category : ${categories}" th:value="${category.id}" th:text="${category.name}"></option>
|
||||
</select>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-success button-fixed">
|
||||
<span th:if="${id == null}">
|
||||
<i class="fa-solid fa-plus"></i> Добавить
|
||||
</span>
|
||||
<span th:if="${id != null}">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i> Сохранить
|
||||
</span>
|
||||
</button>
|
||||
<a class="btn btn-secondary button-fixed" th:href="@{/product}">
|
||||
Назад
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
59
src/main/resources/templates/products.html
Normal file
59
src/main/resources/templates/products.html
Normal file
@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div>
|
||||
<a class="btn btn-success button-fixed"
|
||||
th:href="@{/product/update/}">
|
||||
<i class="fa-solid fa-plus"></i> Добавить
|
||||
</a>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Название</th>
|
||||
<th scope="col">Цена</th>
|
||||
<th scope="col">Фото</th>
|
||||
<th scope="col">Категория</th>
|
||||
<th scope="col">Редактировать запись</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="product, iterator: ${products}">
|
||||
<td th:text="${product.name}" style="width: 25%"/>
|
||||
<td th:text="${product.price}" style="width: 25%"/>
|
||||
<td><img th:src="${product.photo}" class="img-thumbnail mw-50 mh-50"/></td>
|
||||
<td th:text="${product.categoryName}" style="width: 25%"/>
|
||||
<td style="width: 10%">
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<a class="btn btn-warning button-fixed button-sm"
|
||||
th:href="@{/product/update/{id}(id=${product.id})}">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
||||
</a>
|
||||
<button type="button" class="btn btn-danger button-fixed button-sm"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${product.id}').click()|">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
||||
</button>
|
||||
<a class="btn btn-primary button-fixed button-sm"
|
||||
th:href="@{/product/{id}/manufacturers(id=${product.id})}">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i> Производители
|
||||
</a>
|
||||
</div>
|
||||
<form th:action="@{/product/delete/{id}(id=${product.id})}" method="post">
|
||||
<button th:id="'remove-' + ${product.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user