Browse Source

Front-end product filter values

Vova Tkach 5 years ago
parent
commit
ee5d5d370b

+ 65 - 105
assets/template/shop_product_html_file.go

@@ -8,22 +8,24 @@ var VarShopProductHtmlFile = []byte(`{{template "header.html" .}}
 			<li class="nav-item">
 				<a class="nav-link active" id="all-tab" data-toggle="tab" href="#all" role="tab" aria-controls="all" aria-selected="true">All about product</a>
 			</li>
-			<li class="nav-item">
-				<a class="nav-link" id="specifications-tab" data-toggle="tab" href="#specifications" role="tab" aria-controls="specifications" aria-selected="false">Specifications</a>
-			</li>
+			{{if $.Data.Shop.Product.HaveSpecs}}
+				<li class="nav-item">
+					<a class="nav-link" id="specifications-tab" data-toggle="tab" href="#specifications" role="tab" aria-controls="specifications" aria-selected="false">Specifications</a>
+				</li>
+			{{end}}
 		</ul>
 		<div class="tab-content" id="myTabContent">
 			<div class="tab-pane no-fade pt-3 show active" id="all" role="tabpanel" aria-labelledby="all-tab">
 				<div class="row">
 					<div class="col-md-6">
 						<div class="card" id="product_image">
-							{{if $.Data.Shop.Product.HaveImages }}
+							{{if $.Data.Shop.Product.HaveImages}}
 								<img class="card-img-top" src="{{$.Data.Shop.Product.Image.Thumbnail3}}" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
 							{{else}}
 								<img class="card-img-top" src="data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22286%22%20height%3D%22180%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20286%20180%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_16c7e5ac360%20text%20%7B%20fill%3Argba(255%2C255%2C255%2C.75)%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_16c7e5ac360%22%3E%3Crect%20width%3D%22286%22%20height%3D%22180%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22107.0078125%22%20y%3D%2296.234375%22%3E286x180%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
 							{{end}}
 						</div>
-						{{if gt $.Data.Shop.Product.ImagesCount 0 }}
+						{{if $.Data.Shop.Product.HaveImages}}
 							<div class="card mt-1">
 								<div id="product_thumbnails" class="thumbnails d-flex flex-wrap">
 									{{range $index, $img := $.Data.Shop.Product.Images}}
@@ -49,113 +51,71 @@ var VarShopProductHtmlFile = []byte(`{{template "header.html" .}}
 						</div>
 					</div>
 				</div>
-				
-				{{if ne $.Data.Shop.Product.Content ""}}
-					<hr>
-					<h3>Description</h3>
-					<hr>
-					<div class="product-description">
-						{{$.Data.Shop.Product.Content}}
-					</div>
-				{{end}}
-				<hr>
-				<h3>Specifications</h3>
-				<hr>
-				<!-- <table class="table table-striped table-bordered mb-0 table-specifications">
-					<tbody>
-						<tr>
-							<td class="tcol-1">Диагональ экрана</td>
-							<td class="tcol-2">15.6" (1920x1080) Full HD</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Процессор</td>
-							<td class="tcol-2">Шестиядерный Intel Core i7-8750H (2.2 - 4.1 ГГц)</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Частота обновления экрана</td>
-							<td class="tcol-2">60 Гц</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Объем оперативной памяти</td>
-							<td class="tcol-2">8 ГБ</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Операционная система</td>
-							<td class="tcol-2">Windows 10 Home 64bit</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Цвет</td>
-							<td class="tcol-2">Черный</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Поколение процессора Intel</td>
-							<td class="tcol-2">8-ое Coffee Lake</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Объём накопителя</td>
-							<td class="tcol-2">1 ТБ + SSD 128 ГБ</td>
-						</tr>
-					</tbody>
-				</table> -->
-			</div>
-			<div class="tab-pane no-fade pt-3" id="specifications" role="tabpanel" aria-labelledby="specifications-tab">
 				<div class="row">
-					<div class="col-md-8">
-						<!-- <table class="table table-striped table-bordered mb-0 table-specifications">
-							<tbody>
-								<tr>
-									<td class="tcol-1">Диагональ экрана</td>
-									<td class="tcol-2">15.6" (1920x1080) Full HD</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Процессор</td>
-									<td class="tcol-2">Шестиядерный Intel Core i7-8750H (2.2 - 4.1 ГГц)</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Частота обновления экрана</td>
-									<td class="tcol-2">60 Гц</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Объем оперативной памяти</td>
-									<td class="tcol-2">8 ГБ</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Операционная система</td>
-									<td class="tcol-2">Windows 10 Home 64bit</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Цвет</td>
-									<td class="tcol-2">Черный</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Поколение процессора Intel</td>
-									<td class="tcol-2">8-ое Coffee Lake</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Объём накопителя</td>
-									<td class="tcol-2">1 ТБ + SSD 128 ГБ</td>
-								</tr>
-							</tbody>
-						</table> -->
-					</div>
-					<div class="col-md-4">
-						<div class="card mt-3 mt-sm-3 mt-md-0 mt-lg-0">
-							<div class="card-body">
-								{{if $.Data.Shop.Product.HaveImages }}
-									<img class="card-img-top" src="{{$.Data.Shop.Product.Image.Thumbnail2}}" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
-								{{else}}
-									<img class="card-img-top" src="data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22286%22%20height%3D%22180%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20286%20180%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_16c7e5ac360%20text%20%7B%20fill%3Argba(255%2C255%2C255%2C.75)%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_16c7e5ac360%22%3E%3Crect%20width%3D%22286%22%20height%3D%22180%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22107.0078125%22%20y%3D%2296.234375%22%3E286x180%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
-								{{end}}
+					<div class="col-md-6">
+						{{if ne $.Data.Shop.Product.Content ""}}
+							<hr>
+							<h3>Description</h3>
+							<hr>
+							<div class="product-description">
+								{{$.Data.Shop.Product.Content}}
 							</div>
+						{{end}}
+						{{if $.Data.Shop.Product.HaveSpecs}}
+							<hr>
+							<h3>Specifications</h3>
+							<hr>
+							<table class="table table-striped table-bordered mb-0 table-specifications">
+								<tbody>
+									{{range $.Data.Shop.Product.Specs}}
+										<tr>
+											<td class="tcol-1">{{.FilterName}}</td>
+											<td class="tcol-2">{{.FilterValue}}</td>
+										</tr>
+									{{end}}
+								</tbody>
+							</table>
+						{{end}}
+					</div>
+					<div class="col-md-6"></div>
+				</div>
+			</div>
+			{{if $.Data.Shop.Product.HaveSpecs}}
+				<div class="tab-pane no-fade pt-3" id="specifications" role="tabpanel" aria-labelledby="specifications-tab">
+					<div class="row">
+						<div class="col-md-8">
+							{{if $.Data.Shop.Product.HaveSpecs}}
+								<table class="table table-striped table-bordered mb-0 table-specifications">
+									<tbody>
+										{{range $.Data.Shop.Product.Specs}}
+											<tr>
+												<td class="tcol-1">{{.FilterName}}</td>
+												<td class="tcol-2">{{.FilterValue}}</td>
+											</tr>
+										{{end}}
+									</tbody>
+								</table>
+							{{end}}
 						</div>
-						<div class="card mt-3">
-							<div class="card-body">
-								<h3 class="price mb-0 mr-4">{{$.Data.Shop.Product.PriceFormat "%.2f"}} {{$.Data.Shop.Product.Currency.Code}}</h3><a href="" class="btn btn-success btn-buy">Buy</a>
+						<div class="col-md-4">
+							<div class="card mt-3 mt-sm-3 mt-md-0 mt-lg-0">
+								<div class="card-body">
+									{{if $.Data.Shop.Product.HaveImages}}
+										<img class="card-img-top" src="{{$.Data.Shop.Product.Image.Thumbnail2}}" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
+									{{else}}
+										<img class="card-img-top" src="data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22286%22%20height%3D%22180%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20286%20180%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_16c7e5ac360%20text%20%7B%20fill%3Argba(255%2C255%2C255%2C.75)%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_16c7e5ac360%22%3E%3Crect%20width%3D%22286%22%20height%3D%22180%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22107.0078125%22%20y%3D%2296.234375%22%3E286x180%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
+									{{end}}
+								</div>
+							</div>
+							<div class="card mt-3">
+								<div class="card-body">
+									<h3 class="price mb-0 mr-4">{{$.Data.Shop.Product.PriceFormat "%.2f"}} {{$.Data.Shop.Product.Currency.Code}}</h3><a href="" class="btn btn-success btn-buy">Buy</a>
+								</div>
 							</div>
 						</div>
 					</div>
 				</div>
-			</div>
+			{{end}}
 		</div>
 	</div>
 </div>

+ 81 - 8
engine/fetdata/shop_product.go

@@ -2,6 +2,7 @@ package fetdata
 
 import (
 	"html/template"
+	"strings"
 	"time"
 
 	"golang-fave/engine/wrapper"
@@ -17,6 +18,7 @@ type ShopProduct struct {
 	category *ShopCategory
 
 	images []*ShopProductImage
+	specs  []*ShopProductSpec
 }
 
 func (this *ShopProduct) load() *ShopProduct {
@@ -47,6 +49,53 @@ func (this *ShopProduct) load() *ShopProduct {
 			}
 		}
 	}
+
+	filter_ids := []int{}
+	filter_names := map[int]string{}
+	filter_values := map[int][]string{}
+	if rows, err := this.wrap.DB.Query(
+		`SELECT
+			shop_filters.id,
+			shop_filters.filter,
+			shop_filters_values.name
+		FROM
+			shop_filter_product_values
+			LEFT JOIN shop_filters_values ON shop_filters_values.id = shop_filter_product_values.filter_value_id
+			LEFT JOIN shop_filters ON shop_filters.id = shop_filters_values.filter_id
+		WHERE
+			shop_filter_product_values.product_id = ?
+		ORDER BY
+			shop_filters.filter ASC,
+			shop_filters_values.name ASC
+		;`,
+		this.object.A_id,
+	); err == nil {
+		defer rows.Close()
+		values := make([]string, 3)
+		scan := make([]interface{}, len(values))
+		for i := range values {
+			scan[i] = &values[i]
+		}
+		for rows.Next() {
+			err = rows.Scan(scan...)
+			if err == nil {
+				if !utils.InArrayInt(filter_ids, utils.StrToInt(string(values[0]))) {
+					filter_ids = append(filter_ids, utils.StrToInt(string(values[0])))
+				}
+				filter_names[utils.StrToInt(string(values[0]))] = string(values[1])
+				filter_values[utils.StrToInt(string(values[0]))] = append(filter_values[utils.StrToInt(string(values[0]))], string(values[2]))
+			}
+		}
+	}
+	for _, filter_id := range filter_ids {
+		this.specs = append(this.specs, &ShopProductSpec{wrap: this.wrap, object: &utils.MySql_shop_product_spec{
+			A_product_id:   this.object.A_id,
+			A_filter_id:    filter_id,
+			A_filter_name:  filter_names[filter_id],
+			A_filter_value: strings.Join(filter_values[filter_id], ", "),
+		}})
+	}
+
 	return this
 }
 
@@ -177,24 +226,24 @@ func (this *ShopProduct) Permalink() string {
 	return "/shop/" + this.object.A_alias + "/"
 }
 
-func (this *ShopProduct) HaveImages() bool {
+func (this *ShopProduct) Image() *ShopProductImage {
 	if this == nil {
-		return false
+		return nil
 	}
 	if len(this.images) <= 0 {
-		return false
+		return nil
 	}
-	return true
+	return this.images[0]
 }
 
-func (this *ShopProduct) Image() *ShopProductImage {
+func (this *ShopProduct) HaveImages() bool {
 	if this == nil {
-		return nil
+		return false
 	}
 	if len(this.images) <= 0 {
-		return nil
+		return false
 	}
-	return this.images[0]
+	return true
 }
 
 func (this *ShopProduct) Images() []*ShopProductImage {
@@ -210,3 +259,27 @@ func (this *ShopProduct) ImagesCount() int {
 	}
 	return len(this.images)
 }
+
+func (this *ShopProduct) HaveSpecs() bool {
+	if this == nil {
+		return false
+	}
+	if len(this.specs) <= 0 {
+		return false
+	}
+	return true
+}
+
+func (this *ShopProduct) Specs() []*ShopProductSpec {
+	if this == nil {
+		return []*ShopProductSpec{}
+	}
+	return this.specs
+}
+
+func (this *ShopProduct) SpecsCount() int {
+	if this == nil {
+		return 0
+	}
+	return len(this.specs)
+}

+ 36 - 0
engine/fetdata/shop_product_spec.go

@@ -0,0 +1,36 @@
+package fetdata
+
+import (
+	"golang-fave/engine/wrapper"
+	"golang-fave/utils"
+)
+
+type ShopProductSpec struct {
+	wrap   *wrapper.Wrapper
+	object *utils.MySql_shop_product_spec
+}
+
+func (this *ShopProductSpec) load() *ShopProductSpec {
+	return this
+}
+
+func (this *ShopProductSpec) FilterId() int {
+	if this == nil {
+		return 0
+	}
+	return this.object.A_filter_id
+}
+
+func (this *ShopProductSpec) FilterName() string {
+	if this == nil {
+		return ""
+	}
+	return this.object.A_filter_name
+}
+
+func (this *ShopProductSpec) FilterValue() string {
+	if this == nil {
+		return ""
+	}
+	return this.object.A_filter_value
+}

+ 65 - 105
hosts/localhost/template/shop-product.html

@@ -6,22 +6,24 @@
 			<li class="nav-item">
 				<a class="nav-link active" id="all-tab" data-toggle="tab" href="#all" role="tab" aria-controls="all" aria-selected="true">All about product</a>
 			</li>
-			<li class="nav-item">
-				<a class="nav-link" id="specifications-tab" data-toggle="tab" href="#specifications" role="tab" aria-controls="specifications" aria-selected="false">Specifications</a>
-			</li>
+			{{if $.Data.Shop.Product.HaveSpecs}}
+				<li class="nav-item">
+					<a class="nav-link" id="specifications-tab" data-toggle="tab" href="#specifications" role="tab" aria-controls="specifications" aria-selected="false">Specifications</a>
+				</li>
+			{{end}}
 		</ul>
 		<div class="tab-content" id="myTabContent">
 			<div class="tab-pane no-fade pt-3 show active" id="all" role="tabpanel" aria-labelledby="all-tab">
 				<div class="row">
 					<div class="col-md-6">
 						<div class="card" id="product_image">
-							{{if $.Data.Shop.Product.HaveImages }}
+							{{if $.Data.Shop.Product.HaveImages}}
 								<img class="card-img-top" src="{{$.Data.Shop.Product.Image.Thumbnail3}}" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
 							{{else}}
 								<img class="card-img-top" src="data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22286%22%20height%3D%22180%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20286%20180%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_16c7e5ac360%20text%20%7B%20fill%3Argba(255%2C255%2C255%2C.75)%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_16c7e5ac360%22%3E%3Crect%20width%3D%22286%22%20height%3D%22180%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22107.0078125%22%20y%3D%2296.234375%22%3E286x180%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
 							{{end}}
 						</div>
-						{{if gt $.Data.Shop.Product.ImagesCount 0 }}
+						{{if $.Data.Shop.Product.HaveImages}}
 							<div class="card mt-1">
 								<div id="product_thumbnails" class="thumbnails d-flex flex-wrap">
 									{{range $index, $img := $.Data.Shop.Product.Images}}
@@ -47,113 +49,71 @@
 						</div>
 					</div>
 				</div>
-				
-				{{if ne $.Data.Shop.Product.Content ""}}
-					<hr>
-					<h3>Description</h3>
-					<hr>
-					<div class="product-description">
-						{{$.Data.Shop.Product.Content}}
-					</div>
-				{{end}}
-				<hr>
-				<h3>Specifications</h3>
-				<hr>
-				<!-- <table class="table table-striped table-bordered mb-0 table-specifications">
-					<tbody>
-						<tr>
-							<td class="tcol-1">Диагональ экрана</td>
-							<td class="tcol-2">15.6" (1920x1080) Full HD</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Процессор</td>
-							<td class="tcol-2">Шестиядерный Intel Core i7-8750H (2.2 - 4.1 ГГц)</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Частота обновления экрана</td>
-							<td class="tcol-2">60 Гц</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Объем оперативной памяти</td>
-							<td class="tcol-2">8 ГБ</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Операционная система</td>
-							<td class="tcol-2">Windows 10 Home 64bit</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Цвет</td>
-							<td class="tcol-2">Черный</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Поколение процессора Intel</td>
-							<td class="tcol-2">8-ое Coffee Lake</td>
-						</tr>
-						<tr>
-							<td class="tcol-1">Объём накопителя</td>
-							<td class="tcol-2">1 ТБ + SSD 128 ГБ</td>
-						</tr>
-					</tbody>
-				</table> -->
-			</div>
-			<div class="tab-pane no-fade pt-3" id="specifications" role="tabpanel" aria-labelledby="specifications-tab">
 				<div class="row">
-					<div class="col-md-8">
-						<!-- <table class="table table-striped table-bordered mb-0 table-specifications">
-							<tbody>
-								<tr>
-									<td class="tcol-1">Диагональ экрана</td>
-									<td class="tcol-2">15.6" (1920x1080) Full HD</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Процессор</td>
-									<td class="tcol-2">Шестиядерный Intel Core i7-8750H (2.2 - 4.1 ГГц)</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Частота обновления экрана</td>
-									<td class="tcol-2">60 Гц</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Объем оперативной памяти</td>
-									<td class="tcol-2">8 ГБ</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Операционная система</td>
-									<td class="tcol-2">Windows 10 Home 64bit</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Цвет</td>
-									<td class="tcol-2">Черный</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Поколение процессора Intel</td>
-									<td class="tcol-2">8-ое Coffee Lake</td>
-								</tr>
-								<tr>
-									<td class="tcol-1">Объём накопителя</td>
-									<td class="tcol-2">1 ТБ + SSD 128 ГБ</td>
-								</tr>
-							</tbody>
-						</table> -->
-					</div>
-					<div class="col-md-4">
-						<div class="card mt-3 mt-sm-3 mt-md-0 mt-lg-0">
-							<div class="card-body">
-								{{if $.Data.Shop.Product.HaveImages }}
-									<img class="card-img-top" src="{{$.Data.Shop.Product.Image.Thumbnail2}}" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
-								{{else}}
-									<img class="card-img-top" src="data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22286%22%20height%3D%22180%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20286%20180%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_16c7e5ac360%20text%20%7B%20fill%3Argba(255%2C255%2C255%2C.75)%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_16c7e5ac360%22%3E%3Crect%20width%3D%22286%22%20height%3D%22180%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22107.0078125%22%20y%3D%2296.234375%22%3E286x180%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
-								{{end}}
+					<div class="col-md-6">
+						{{if ne $.Data.Shop.Product.Content ""}}
+							<hr>
+							<h3>Description</h3>
+							<hr>
+							<div class="product-description">
+								{{$.Data.Shop.Product.Content}}
 							</div>
+						{{end}}
+						{{if $.Data.Shop.Product.HaveSpecs}}
+							<hr>
+							<h3>Specifications</h3>
+							<hr>
+							<table class="table table-striped table-bordered mb-0 table-specifications">
+								<tbody>
+									{{range $.Data.Shop.Product.Specs}}
+										<tr>
+											<td class="tcol-1">{{.FilterName}}</td>
+											<td class="tcol-2">{{.FilterValue}}</td>
+										</tr>
+									{{end}}
+								</tbody>
+							</table>
+						{{end}}
+					</div>
+					<div class="col-md-6"></div>
+				</div>
+			</div>
+			{{if $.Data.Shop.Product.HaveSpecs}}
+				<div class="tab-pane no-fade pt-3" id="specifications" role="tabpanel" aria-labelledby="specifications-tab">
+					<div class="row">
+						<div class="col-md-8">
+							{{if $.Data.Shop.Product.HaveSpecs}}
+								<table class="table table-striped table-bordered mb-0 table-specifications">
+									<tbody>
+										{{range $.Data.Shop.Product.Specs}}
+											<tr>
+												<td class="tcol-1">{{.FilterName}}</td>
+												<td class="tcol-2">{{.FilterValue}}</td>
+											</tr>
+										{{end}}
+									</tbody>
+								</table>
+							{{end}}
 						</div>
-						<div class="card mt-3">
-							<div class="card-body">
-								<h3 class="price mb-0 mr-4">{{$.Data.Shop.Product.PriceFormat "%.2f"}} {{$.Data.Shop.Product.Currency.Code}}</h3><a href="" class="btn btn-success btn-buy">Buy</a>
+						<div class="col-md-4">
+							<div class="card mt-3 mt-sm-3 mt-md-0 mt-lg-0">
+								<div class="card-body">
+									{{if $.Data.Shop.Product.HaveImages}}
+										<img class="card-img-top" src="{{$.Data.Shop.Product.Image.Thumbnail2}}" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
+									{{else}}
+										<img class="card-img-top" src="data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22286%22%20height%3D%22180%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20286%20180%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_16c7e5ac360%20text%20%7B%20fill%3Argba(255%2C255%2C255%2C.75)%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_16c7e5ac360%22%3E%3Crect%20width%3D%22286%22%20height%3D%22180%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22107.0078125%22%20y%3D%2296.234375%22%3E286x180%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
+									{{end}}
+								</div>
+							</div>
+							<div class="card mt-3">
+								<div class="card-body">
+									<h3 class="price mb-0 mr-4">{{$.Data.Shop.Product.PriceFormat "%.2f"}} {{$.Data.Shop.Product.Currency.Code}}</h3><a href="" class="btn btn-success btn-buy">Buy</a>
+								</div>
 							</div>
 						</div>
 					</div>
 				</div>
-			</div>
+			{{end}}
 		</div>
 	</div>
 </div>

+ 8 - 0
utils/mysql_struct_shop_product_spec.go

@@ -0,0 +1,8 @@
+package utils
+
+type MySql_shop_product_spec struct {
+	A_product_id   int
+	A_filter_id    int
+	A_filter_name  string
+	A_filter_value string
+}