Browse Source

Shop product image upload action

Vova Tkach 5 years ago
parent
commit
af0bc70b44
4 changed files with 156 additions and 0 deletions
  1. 1 0
      .gitignore
  2. 47 0
      modules/module_shop.go
  3. 104 0
      modules/module_shop_act_upload_image.go
  4. 4 0
      modules/modules.go

+ 1 - 0
.gitignore

@@ -26,6 +26,7 @@
 # Test virtual host dir
 /hosts/*
 !/hosts/localhost
+/hosts/*/htdocs/products
 
 # Default host mysql config file
 /hosts/localhost/config/mysql.json

+ 47 - 0
modules/module_shop.go

@@ -848,6 +848,53 @@ func (this *Modules) RegisterModule_Shop() *Module {
 					Value:   data.A_content,
 					Classes: "wysiwyg",
 				},
+				{
+					Kind:    builder.DFKText,
+					Caption: "Product images",
+					Name:    "",
+					Value:   "",
+					CallBack: func(field *builder.DataFormField) string {
+						return `<script>` +
+							`function UploadProductImage(product_id, input_id) {` +
+							`var fd = new FormData();` +
+							`var files = $('#' + input_id)[0].files[0];` +
+							`fd.append('action', 'shop-upload-image');` +
+							`fd.append('id', product_id);` +
+							`fd.append('file', files);` +
+							`$.ajax({` +
+							`url: '/cp/',` +
+							`method: 'POST',` +
+							`type: 'POST',` +
+							`data: fd,` +
+							`contentType: false,` +
+							`processData: false,` +
+							`success: function(response) {` +
+							`console.log('resp', response);` +
+							`}` +
+							`});` +
+							`}` +
+							`</script>` +
+							`<div class="form-group n6">` +
+							`<div class="row">` +
+							`<div class="col-md-3">` +
+							`<label>Product images</label>` +
+							`</div>` +
+							`<div class="col-md-9">` +
+							`<div class="list-wrapper">` +
+							//
+							`<div id="list">` +
+							`` +
+							`</div>` +
+							`<div class="list-button position-relative">` +
+							`<input class="form-control" type="file" id="file" name="file" /><button type="button" class="btn btn-success btn-dynamic-remove" onclick="UploadProductImage(` + utils.IntToStr(data.A_id) + `, 'file');">Upload</button>` +
+							`</div>` +
+							//
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>`
+					},
+				},
 				{
 					Kind:    builder.DFKCheckBox,
 					Caption: "Active",

+ 104 - 0
modules/module_shop_act_upload_image.go

@@ -0,0 +1,104 @@
+package modules
+
+import (
+	"bytes"
+	"image"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"time"
+
+	_ "image/jpeg"
+	_ "image/png"
+
+	"golang-fave/engine/wrapper"
+	"golang-fave/utils"
+)
+
+func (this *Modules) RegisterAction_ShopUploadImage() *Action {
+	return this.newAction(AInfo{
+		WantDB:    true,
+		Mount:     "shop-upload-image",
+		WantAdmin: true,
+	}, func(wrap *wrapper.Wrapper) {
+		pf_id := wrap.R.FormValue("id")
+
+		if !utils.IsNumeric(pf_id) {
+			wrap.MsgError(`Inner system error`)
+			return
+		}
+
+		// Read file from request
+		file, handler, err := wrap.R.FormFile("file")
+		if err != nil {
+			wrap.MsgError(err.Error())
+			return
+		}
+		defer file.Close()
+
+		// Check file name
+		if handler.Filename == "" {
+			wrap.MsgError(`Inner system error`)
+			return
+		}
+
+		// Read file to bytes
+		fileBytes, err := ioutil.ReadAll(file)
+		if err != nil {
+			wrap.MsgError(err.Error())
+			return
+		}
+
+		// Check if file is really an image
+		if _, _, err := image.Decode(bytes.NewReader(fileBytes)); err != nil {
+			wrap.MsgError(err.Error())
+			return
+		}
+
+		// Create dirs
+		if err := os.MkdirAll(wrap.DHtdocs+string(os.PathSeparator)+"products"+string(os.PathSeparator)+"images"+string(os.PathSeparator)+pf_id, os.ModePerm); err != nil {
+			wrap.MsgError(err.Error())
+			return
+		}
+
+		target_file_name := utils.Int64ToStr(time.Now().Unix()) + filepath.Ext(handler.Filename)
+		target_file_full := wrap.DHtdocs + string(os.PathSeparator) + "products" + string(os.PathSeparator) + "images" + string(os.PathSeparator) + pf_id + string(os.PathSeparator) + target_file_name
+
+		if err := wrap.DB.Transaction(func(tx *wrapper.Tx) error {
+			// Block rows
+			if _, err := tx.Exec("SELECT id FROM shop_products WHERE id = ? FOR UPDATE;", utils.StrToInt(pf_id)); err != nil {
+				return err
+			}
+
+			// Insert row
+			if _, err := tx.Exec(
+				`INSERT INTO shop_product_images SET
+					product_id = ?,
+					filename = ?
+				;`,
+				utils.StrToInt(pf_id),
+				target_file_name,
+			); err != nil {
+				return err
+			}
+
+			// Write file to disk
+			if err := ioutil.WriteFile(target_file_full, fileBytes, 0664); err != nil {
+				return err
+			}
+			return nil
+		}); err != nil {
+			wrap.MsgError(err.Error())
+			return
+		}
+
+		wrap.Write(`Some!`)
+
+		// wrap.Write(`if($('#prod_attr_` + pf_id + `').length > 0) {`)
+		// wrap.Write(`$('#prod_attr_` + pf_id + ` select').prop('disabled', false).prop('multiple', true);`)
+		// wrap.Write(`$('#prod_attr_` + pf_id + ` select').html('` + options + `');`)
+		// wrap.Write(`$('#prod_attr_` + pf_id + ` select').selectpicker({});`)
+		// wrap.Write(`$('#prod_attr_` + pf_id + ` button').prop('disabled', false);`)
+		// wrap.Write(`}`)
+	})
+}

+ 4 - 0
modules/modules.go

@@ -265,6 +265,10 @@ func (this *Modules) XXXActionFire(wrap *wrapper.Wrapper) bool {
 	if wrap.R.Method == "POST" {
 		if err := wrap.R.ParseForm(); err == nil {
 			name := wrap.R.FormValue("action")
+			if name == "" {
+				wrap.R.ParseMultipartForm(32 << 20)
+				name = wrap.R.FormValue("action")
+			}
 			if name != "" {
 				if act, ok := this.acts[name]; ok {
 					if act.Info.WantDB {