Jianghan 3 gadi atpakaļ
vecāks
revīzija
73f7018d86

+ 156 - 5
src/service/repair_service.go

@@ -1,21 +1,25 @@
 package service
 
 import (
+	"bytes"
 	"encoding/json"
 	"fmt"
 	"github.com/go-xweb/xweb"
 	"github.com/tealeg/xlsx"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/primitive"
+	"io"
 	"io/ioutil"
 	"log"
 	mu "mfw/util"
 	"mongodb"
 	"net"
+	"net/http"
 	qu "qfw/util"
 	"qfw/util/elastic"
 	"qfw/util/redis"
 	"regexp"
+	"strconv"
 	"strings"
 	"time"
 	"udptask"
@@ -54,11 +58,13 @@ type RepairRule struct {
 	repairNewAdd xweb.Mapper `xweb:"/service/jy/repair/newAdd"`
 	repairPub    xweb.Mapper `xweb:"/service/jy/repair/pubSave"`
 
-	redisRepair xweb.Mapper `xweb:"/service/jy/repair/redis"`
-	esDel       xweb.Mapper `xweb:"/service/jy/repair/es/del"`
-	esDelRecord xweb.Mapper `xweb:"/service/jy/repair/es/del/record"`
-	esCount     xweb.Mapper `xweb:"/service/jy/repair/es/count/byField"`
-	esDelBy     xweb.Mapper `xweb:"/service/jy/repair/es/del/byField"`
+	redisRepair  xweb.Mapper `xweb:"/service/jy/repair/redis"`
+	upFile       xweb.Mapper `xweb:"/service/jy/repair/upfile"`
+	upFileRecord xweb.Mapper `xweb:"/service/jy/repair/upfile/record"`
+	esDel        xweb.Mapper `xweb:"/service/jy/repair/es/del"`
+	esDelRecord  xweb.Mapper `xweb:"/service/jy/repair/es/del/record"`
+	esCount      xweb.Mapper `xweb:"/service/jy/repair/es/count/byField"`
+	esDelBy      xweb.Mapper `xweb:"/service/jy/repair/es/del/byField"`
 }
 
 func (jy *RepairRule) RepairList() {
@@ -1108,3 +1114,148 @@ func (jy *RepairRule) EsDelRecord() {
 		})
 	}
 }
+
+func (jy *RepairRule) UpFileRecord() {
+	defer qu.Catch()
+	if jy.Method() == "POST" {
+		start, _ := jy.GetInteger("start")
+		limit, _ := jy.GetInteger("length")
+		draw, _ := jy.GetInteger("draw")
+		searchStr := jy.GetString("search[value]")
+		search := strings.TrimSpace(searchStr)
+		query := bson.M{}
+		if search != "" {
+			query["$or"] = []interface{}{
+				//bson.M{"s_customer": bson.M{"$regex": search}},
+				//bson.M{"s_tagname": bson.M{"$regex": search}},
+			}
+		}
+		data, _ := Mgo.Find("jy_upfile_log", query, `{"createtime": -1}`, nil, false, start, limit)
+		count := Mgo.Count("jy_upfile_log", query)
+		jy.ServeJson(map[string]interface{}{
+			"draw":            draw,
+			"data":            data,
+			"recordsFiltered": count,
+			"recordsTotal":    count,
+		})
+	}
+}
+
+func (jy *RepairRule) UpFile() {
+	defer qu.Catch()
+	if jy.Method() == "POST" {
+		identity := jy.GetString("identity")
+		var id string
+		if len(identity) == 24 {
+			id = identity
+		} else {
+			identity = rpre.ReplaceAllString(identity, "")
+			identity = rsuf.ReplaceAllString(identity, "")
+			id = qu.CommonDecodeArticle("content", identity)[0]
+		}
+		qu.Debug("download --- url/id ---", id)
+		files := jy.GetString("files")
+		var fileArr []map[string]interface{}
+		if err := json.Unmarshal([]byte(files), &fileArr); err != nil {
+			qu.Debug("UserInfo Unmarshal Failed:", err)
+			jy.ServeJson(map[string]interface{}{
+				"rep": false,
+				"msg": "用户信息解析失败",
+			})
+			return
+		}
+		InitOss()
+		var atts []map[string]interface{}
+		for _, m := range fileArr {
+			download := qu.ObjToString(m["org_url"])
+			filename := qu.ObjToString(m["filename"])
+			res, err := http.Get(download)
+			if err != nil {
+				qu.Debug("Download url error ---", download)
+				jy.ServeJson(map[string]interface{}{
+					"rep": false,
+					"msg": "文件下载失败",
+				})
+				return
+			}
+			bt, _ := ioutil.ReadAll(res.Body)
+			key := GetHashKey(bt) + TypeByExt(filename)
+			b, err := OssPutObject(key, io.Reader(res.Body))
+			if b {
+				tmp := make(map[string]interface{})
+				tmp["org_url"] = download
+				tmp["filename"] = filename
+				tmp["ftype"] = TypeByExt(filename)
+				tmp["fid"] = key
+				tmp["url"] = "oss"
+				br := bytes.NewReader(bt)
+				tmp["size"] = qu.ConvertFileSize(br.Len())
+				atts = append(atts, tmp)
+			} else {
+				qu.Debug("File upload error ---", err)
+				jy.ServeJson(map[string]interface{}{
+					"rep": false,
+					"msg": "文件上传失败",
+				})
+				return
+			}
+		}
+
+		coll := ""
+		if id > "5a862e7040d2d9bbe88e3b1f" {
+			coll = "bidding"
+		} else {
+			coll = "bidding_back"
+		}
+		info, _ := JYMgo.FindById(coll, id, map[string]interface{}{"projectinfo": 1})
+		if len(*info) > 0 {
+			if (*info)["projectinfo"] != nil {
+				if attsMap := (*info)["projectinfo"].(map[string]interface{}); attsMap["attachments"] != nil {
+					maps := attsMap["attachments"].(map[string]interface{})
+					max := 0
+					for k, _ := range maps {
+						if qu.IntAll(k) > max {
+							max = qu.IntAll(k)
+						}
+					}
+					for i, att := range atts {
+						maps[strconv.Itoa(i+max+1)] = att
+					}
+					attsMap["attachments"] = maps
+				} else {
+					tmp := make(map[string]interface{})
+					for i, att := range atts {
+						tmp[strconv.Itoa(i)] = att
+					}
+					attsMap["attachments"] = tmp
+				}
+				delete(*info, "_id")
+				JYMgo.UpdateById(coll, id, map[string]interface{}{"$set": *info})
+			} else {
+				tmp := make(map[string]interface{})
+				for i, att := range atts {
+					tmp[strconv.Itoa(i+1)] = att
+				}
+				attsmap := make(map[string]interface{})
+				attsmap["attachments"] = tmp
+				updateMap := make(map[string]interface{})
+				updateMap["projectinfo"] = attsmap
+				JYMgo.UpdateById(coll, id, map[string]interface{}{"$set": updateMap})
+			}
+		} else {
+			jy.ServeJson(map[string]interface{}{
+				"rep": false,
+				"msg": "id查询失败, " + id,
+			})
+			return
+		}
+
+		jy.ServeJson(map[string]interface{}{
+			"rep": true,
+		})
+		Mgo.Save("jy_upfile_log", bson.M{"infoid": id, "value": "上传附件", "createtime": time.Now().Unix()})
+
+	} else {
+		_ = jy.Render("repair/jy_file_upload.html")
+	}
+}

+ 91 - 0
src/util/ossclient.go

@@ -0,0 +1,91 @@
+// ossclient
+package util
+
+import (
+	"crypto/sha256"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"qfw/util"
+
+	"github.com/aliyun/aliyun-oss-go-sdk/oss"
+)
+
+var (
+	ossEndpoint        = "oss-cn-beijing.aliyuncs.com" //正式环境用:oss-cn-beijing-internal.aliyuncs.com 测试:oss-cn-beijing.aliyuncs.com
+	ossAccessKeyId     = "LTAI4G5x9aoZx8dDamQ7vfZi"
+	ossAccessKeySecret = "Bk98FsbPYXcJe72n1bG3Ssf73acuNh"
+	ossBucketName      = "jy-editor" //topjy
+	ossclient          *oss.Client
+)
+
+func InitOss() {
+	client, err := oss.New(ossEndpoint, ossAccessKeyId, ossAccessKeySecret)
+	if err != nil {
+		fmt.Println("Error:", err)
+		os.Exit(-1)
+	}
+	ossclient = client
+}
+
+// OssPutObject oss附件上传
+func OssPutObject(objectName string, fd io.Reader) (bool, error) {
+	util.Catch()
+	// 获取存储空间。
+	bucket, err := ossclient.Bucket(ossBucketName)
+	if err != nil {
+		fmt.Println("Error:", err)
+		return false, err
+	}
+	// 上传文件流。
+	err = bucket.PutObject(objectName, fd)
+	if err != nil {
+		fmt.Println("Error:", err)
+		return false, err
+	}
+
+	return true, nil
+}
+
+func OssGetObject(objectName string) string {
+	util.Catch()
+	// 获取存储空间。
+	bucket, err := ossclient.Bucket(ossBucketName)
+	if err != nil {
+		fmt.Println("Error:", err)
+		return ""
+	}
+
+	// 下载文件到流。
+	body, err := bucket.GetObject(objectName)
+	if err != nil {
+		fmt.Println("Error:", err)
+		return ""
+	}
+	defer body.Close()
+	data, err := ioutil.ReadAll(body)
+	if err != nil {
+		fmt.Println("Error:", err)
+		return ""
+	}
+	return string(data)
+}
+
+func GetHashKey(bs []byte) string {
+	util.Catch()
+	ha := sha256.New()
+	ha.Write(bs)
+	hbs := ha.Sum(nil)
+	key := fmt.Sprintf("%x", hbs)
+	return key
+}
+
+func TypeByExt(path string) string {
+	for i := len(path) - 1; i >= 0 && path[i] != '/'; i-- {
+		if path[i] == '.' {
+			return path[i+1:]
+		}
+	}
+	return ""
+}

+ 165 - 0
src/web/templates/repair/jy_file_upload.html

@@ -0,0 +1,165 @@
+{{include "com/inc.html"}}
+<!-- Main Header -->
+{{include "com/header.html"}}
+<!-- Left side column. 权限菜单 -->
+{{include "com/menu.html"}}
+
+<div class="content-wrapper">
+    <section class="content-header">
+        <h1>es数据删除</h1>
+        <ol class="breadcrumb">
+            <li><a href="#"><i class="fa fa-dashboard"></i> 首页</a></li>
+            <li><a href="/service/jy/repair/es/del"> es数据删除</a></li>
+        </ol>
+    </section>
+    <!-- Main content -->
+    <section class="content">
+        <div class="nav-tabs-custom">
+            <form class="form-horizontal">
+                <br>
+                <div class="box-body">
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label">剑鱼链接/数据ID</label>
+                        <div class="col-sm-3">
+                            <input type="text" class="form-control" id="identity" placeholder="剑鱼链接/数据ID" value="">
+                        </div>
+                    </div>
+                    <div id="TaskDiv">
+                        <div id="itemDiv" style="display: none">
+                            <div class="form-group">
+                                <label class="col-sm-2 control-label">附件地址</label>
+                                <div class="col-sm-5">
+                                    <input type="text" class="furl form-control" placeholder="附件下载地址" value="">
+                                </div>
+                            </div>
+                            <div class="form-group">
+                                <label class="col-sm-2 control-label">附件名称</label>
+                                <div class="col-sm-5">
+                                    <input type="text" class="fname form-control" placeholder="附件名称.类型" value="">
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="group-item">
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">附件地址</label>
+                            <div class="col-sm-5">
+                                <input type="text" class="furl form-control" id="downloadurl" placeholder="附件下载地址" value="">
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">附件名称</label>
+                            <div class="col-sm-5">
+                                <input type="text" class="fname form-control" id="filename" placeholder="附件名称.类型" value="">
+                            </div>
+                            <input type="button" class="btn btn-info" value="新增" onclick="addFile()">
+                            <input type="button" class="btn btn-info" value="上传" onclick="upload()">
+                        </div>
+                    </div>
+                    <br>
+                    <table id="dataTable" class="table table-bordered table-hover">
+                        <thead>
+                        <tr>
+                            <th>编号</th>
+                            <th>数据id</th>
+                            <th>修改类型</th>
+                            <th>操作时间</th>
+                        </tr>
+                        </thead>
+                    </table>
+                </div>
+            </form>
+        </div>
+    </section>
+</div>
+
+{{include "com/footer.html"}}
+<script>
+    menuActive("/service/jy/repair/upfile");
+
+    $(document).ready(function () {
+        ttable = $('#dataTable').dataTable({
+            "paging": true,
+            "lengthChange": false,
+            "searching": false,
+            "ordering": false,
+            "info": true,
+            "autoWidth": false,
+            "serverSide": false,
+            "ajax": {
+                "url": "/service/jy/repair/upfile/record",
+                "type": "post",
+                "data": {}
+            },
+            "language": {
+                "url": "/dist/js/dataTables.chinese.lang"
+            },
+            "fnDrawCallback": function () {
+                $("ul.pagination").prepend("&nbsp;&nbsp;&nbsp;转到第 <input type='text' id='changePage'   style='width:20px;'> 页    <a type='text' href='javascript:void(0);' id='dataTable-btn' style='text-align:center'>GO</a>");
+                $('#dataTable-btn').click(function (e) {
+                    var redirectpage = 0
+                    if ($("#changePage").val() && $("#changePage").val() > 0) {
+                        var redirectpage = $("#changePage").val() - 1;
+                    }
+                    ttable.page(redirectpage).draw(false);
+                });
+                this.api().column(0).nodes().each(function(cell, i) {
+                    cell.innerHTML = i + 1;
+                });
+            },
+            "columns": [
+                {"data": null},
+                {"data": "infoid"},
+                {"data": "value"},
+                {"data": "createtime", render: function (val) {
+                        var dt = new Date()
+                        dt.setTime(parseInt(val) * 1000);
+                        return dt.format("yyyy-MM-dd hh:mm")
+                    }}
+            ]
+        });
+    });
+
+    function addFile() {
+        let tNode = $('#itemDiv').clone().addClass('group-item').addClass('clone-template').show()
+        $('#TaskDiv').append($(tNode))
+    }
+
+    function upload() {
+        let identity = $('#identity').val()
+        if (identity === "") {
+            showMsg("请填写剑鱼url或者数据id")
+            return
+        }
+        let arr = []
+        $('.group-item').each(function () {
+            let furl = $(this).find("input.furl").val()
+            if (furl === undefined) {
+                showTip("请填写附件下载地址")
+                return
+            }
+            let fname = $(this).find("input.fname").val()
+            if (fname === "") {
+                showTip("请填写附件名称和文件类型")
+                return
+            }
+            let tmp = {}
+            tmp["org_url"] = furl
+            tmp["filename"] = fname
+            arr.push(tmp)
+        })
+        $.ajax({
+            url: "/service/jy/repair/upfile",
+            type: 'POST',
+            data: {"identity": identity, "files": JSON.stringify(arr)},
+            success: function (r) {
+                if (r.rep) {
+                    ttable.api().ajax.reload();
+                } else {
+                    showTip(r.msg);
+                }
+            }
+        })
+    }
+
+</script>