zhou.xiaoning пре 3 година
родитељ
комит
f831ab720c

+ 1 - 1
.gitignore

@@ -1,3 +1,3 @@
 log/
-files/
+.tmp/
 __debug_bin.exe

+ 1 - 1
config.yaml

@@ -29,4 +29,4 @@ rabbitmq:
 # system configuration
 system:
   env: 'develop'  # "develop" & "public", Change to "develop" to skip authentication for development mode
-  store-path: 'files' # 文件存储根目录
+  store-path: 'd:\tmp' # JAVA文件上传目录

+ 2 - 2
core/rabbitmq.go

@@ -63,7 +63,7 @@ func Publish(topic string, msg *global.MQPacket) (err error) {
 // Receive 接收消息
 func Receive(topic string, processer global.MsgProcesser) (err error) {
 	// 队列名称
-	queuename := fmt.Sprintf("mtp20_access_%s", topic)
+	queuename := fmt.Sprintf("mtp20_assisted_%s", topic)
 
 	if global.M2A_RABBITMQ == nil || global.M2A_RABBITMQ.Connection.IsClosed() {
 		err = errors.New("rabbitmq is not connected")
@@ -80,7 +80,7 @@ func Receive(topic string, processer global.MsgProcesser) (err error) {
 	go func() {
 		for msg := range msgList {
 			processer.Process(&msg.Body)
-			msg.Ack(false)
+			// msg.Ack(false)
 		}
 	}()
 

+ 2 - 1
go.mod

@@ -4,9 +4,11 @@ go 1.18
 
 require (
 	github.com/fsnotify/fsnotify v1.6.0
+	github.com/gofrs/uuid v4.0.0+incompatible
 	github.com/golang/protobuf v1.5.2
 	github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
 	github.com/mattn/go-oci8 v0.1.1
+	github.com/nguyenthenguyen/docx v0.0.0-20220721043308-1903da0ef37d
 	github.com/spf13/viper v1.13.0
 	github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271
 	go.uber.org/zap v1.23.0
@@ -25,7 +27,6 @@ require (
 	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
-	github.com/nguyenthenguyen/docx v0.0.0-20220721043308-1903da0ef37d // indirect
 	github.com/pelletier/go-toml v1.9.5 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.5 // indirect
 	github.com/pkg/errors v0.9.1 // indirect

+ 1 - 0
go.sum

@@ -129,6 +129,7 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
 github.com/goccy/go-json v0.8.1 h1:4/Wjm0JIJaTDm8K1KcGrLHJoa8EsJ13YWeX+6Kfq6uI=
 github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
 github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=

+ 33 - 0
model/database.go

@@ -334,3 +334,36 @@ type Wrstandard struct {
 func (r *Wrstandard) TableName() string {
 	return "WRSTANDARD"
 }
+
+// Thjpurchasetransfer 铁合金采购协议表
+type Thjpurchasetransfer struct {
+	TRANSFERID               int64   `json:"transferid" xorm:"TRANSFERID"`                             // 协议转让ID(332+Unix秒时间戳(10位)+xxxxxx)
+	WRTRADEDETAILID          int64   `json:"wrtradedetailid" xorm:"WRTRADEDETAILID"`                   // 采购成交单ID(321+Unix秒时间戳(10位)+xxxxxx)
+	PRESALEAPPLYID           int64   `json:"presaleapplyid" xorm:"PRESALEAPPLYID"`                     // 预售申请ID(184+Unix秒时间戳(10位)+xxxxxx)
+	TRADEDATE                string  `json:"tradedate" xorm:"TRADEDATE"`                               // 交易日(yyyyMMdd)
+	WRFACTORTYPEID           int64   `json:"wrfactortypeid" xorm:"WRFACTORTYPEID"`                     // 仓单要素类型ID
+	DELIVERYGOODSID          int32   `json:"deliverygoodsid" xorm:"DELIVERYGOODSID"`                   // 现货品种ID
+	WRSTANDARDID             int32   `json:"wrstandardid" xorm:"WRSTANDARDID"`                         // 现货商品ID
+	WAREHOUSEID              int64   `json:"warehouseid" xorm:"WAREHOUSEID"`                           // 仓库ID
+	MARKETID                 int32   `json:"marketid" xorm:"MARKETID"`                                 // 市场ID(固定为(64202)
+	SELLUSERID               int64   `json:"selluserid" xorm:"SELLUSERID"`                             // 卖方用户ID
+	SELLACCOUNTID            int64   `json:"sellaccountid" xorm:"SELLACCOUNTID"`                       // 卖方账号ID
+	TRANSFERQTY              int64   `json:"transferqty" xorm:"TRANSFERQTY"`                           // 数量
+	TRANSFERPRICE            float64 `json:"transferprice" xorm:"TRANSFERPRICE"`                       // 转让价格
+	TRANSFERAMOUNT           float64 `json:"transferamount" xorm:"TRANSFERAMOUNT"`                     // 转让金额
+	REMARK                   string  `json:"remark" xorm:"REMARK"`                                     // 备注
+	BUYUSERID                int64   `json:"buyuserid" xorm:"BUYUSERID"`                               // 买方用户ID
+	BUYACCOUNTID             int64   `json:"buyaccountid" xorm:"BUYACCOUNTID"`                         // 买方账号ID
+	CONTRACTADDR             string  `json:"contractaddr" xorm:"CONTRACTADDR"`                         // 协议转让合同地址
+	SELLCHARGEALGORITHM      int32   `json:"sellchargealgorithm" xorm:"SELLCHARGEALGORITHM"`           // 卖方手续费收取方式 1:比率  2:固定
+	SELLCHARGEALGORITHMVALUE float64 `json:"sellchargealgorithmvalue" xorm:"SELLCHARGEALGORITHMVALUE"` // 手续费设置值(交易所部分)
+	SELLCHARGE               float64 `json:"sellcharge" xorm:"SELLCHARGE"`                             // 卖方手续费值
+	TRANSFERTRADEDATE        string  `json:"transfertradedate" xorm:"TRANSFERTRADEDATE"`               // 转让交易日
+	TRANSFERSTATUS           int32   `json:"transferstatus" xorm:"TRANSFERSTATUS"`                     // 转让状态 - 1:挂牌中 2:已撤销 3:处理中 4:已转让
+	HANDLESTATUS             int32   `json:"handlestatus" xorm:"HANDLESTATUS"`                         // 处理状态
+}
+
+// TableName is THJ_PURCHASETRANSFER
+func (r *Thjpurchasetransfer) TableName() string {
+	return "THJ_PURCHASETRANSFER"
+}

+ 6 - 0
model/thj.go

@@ -11,3 +11,9 @@ func (t *Thjpurchasetradedetail) Get() (has bool, err error) {
 func (t *Wrpresaleinfo) Get() (has bool, err error) {
 	return global.M2A_DB.Where("PRESALEAPPLYID = ?", t.PRESALEAPPLYID).Get(t)
 }
+
+// UpdateContractAddrBuy 更新预售模板合同
+func (t *Thjpurchasetradedetail) UpdateContractAddrBuy() (err error) {
+	_, err = global.M2A_DB.Where("WRTRADEDETAILID = ?", t.WRTRADEDETAILID).Cols("CONTRACTADDRBUY").Update(t)
+	return
+}

+ 73 - 0
res/sh/mtp20_assisted_linux.sh

@@ -0,0 +1,73 @@
+#!/bin/bash
+
+export base=$HOME/build/git/MTP20_ASSISTED
+
+export GOROOT=/home/pub/go
+export GOPATH=/home/pub/gowebapi
+export GOBIN=$GOPATH/bin
+export GO111MODULE=on
+export GOPROXY=https://goproxy.cn
+export PATH=$PATH:$GOROOT/bin:$GOBIN
+
+export PKG_CONFIG_PATH=/home/pub/pkconfig
+export LD_LIBRARY_PATH=/home/pub/instantclient_11_2/
+
+function build()
+{
+  local src=$1
+  local oldpwd=`pwd`
+  cd $src
+
+  echo "Before switching: "
+  git branch
+  git reset --hard
+  git clean -fdx
+  git pull --rebase
+  git checkout $branch_name
+  echo "After switching: "
+  git branch 
+
+  if [ $? -ne 0  ]; then
+    echo "git update err:1"
+    exit 1
+  fi
+  
+  githash=`git log -n 1 --format=format:"%H"` 
+ 
+  cd $src
+  echo `go version`
+  echo "go build begin:"`date "+%Y-%m-%d %H:%M:%S"`
+  
+  echo "path:"$src
+  local datestr=`date +%Y%m%d%H%M%S`
+  local zipfile=mtp20_assisted_${datestr}.zip
+
+  go build -ldflags "-X 'main._VERSION_=$zipfile' -X 'main._GITHASH_=$githash'" -a -o bin/mtp20_assisted
+  if [ $? -ne 0  ]; then
+    echo "go build err: 2"
+    exit 2
+  fi
+  echo "go build finish:"`date "+%Y-%m-%d %H:%M:%S"`
+  cp -r $src/config.yaml bin/
+  cp -r $src/static bin/static
+  
+  cd $src/bin/
+
+  local rsync_ip=192.168.30.153
+  local rsync_project=mtp2.0_release
+  
+  zip -r $zipfile ./
+    
+  rsync -avh $src/bin/${zipfile} $rsync_ip::build/$rsync_project/${zipfile}
+  echo "Storage path: \\\\$rsync_ip\\share\\build\\$rsync_project\\$zipfile"
+  echo "quick download: wget -c http://$rsync_ip/share/build/$rsync_project/$zipfile"
+  rm -rf $src/bin
+}
+
+#######################main function#########################
+build $base
+if [ $? -ne 0  ]; then
+    exit -1
+fi
+
+

+ 57 - 6
service/thjNtf.go

@@ -2,13 +2,17 @@ package service
 
 import (
 	"encoding/hex"
+	"fmt"
 	"mtp20_assisted/global"
 	"mtp20_assisted/model"
 	"mtp20_assisted/res/pb"
 	"mtp20_assisted/utils"
+	"os"
 	"strconv"
+	"strings"
 	"time"
 
+	"github.com/gofrs/uuid"
 	"github.com/nguyenthenguyen/docx"
 	"go.uber.org/zap"
 	"google.golang.org/protobuf/proto"
@@ -35,7 +39,7 @@ func (t *THJNtf) Process(msg *[]byte) {
 // onTHJPurchaseTradeNtf 铁合金成交通知
 func onTHJPurchaseTradeNtf(bytes *[]byte) {
 	// Read from docx file
-	r, err := docx.ReadDocxFile("./static/现货预售合同.doc")
+	r, err := docx.ReadDocxFile("./static/产能预售合同.docx")
 	if err != nil {
 		global.M2A_LOG.Error("读取合同文件失败", zap.Error(err))
 		return
@@ -109,6 +113,15 @@ func onTHJPurchaseTradeNtf(bytes *[]byte) {
 		global.M2A_LOG.Error("[onTHJPurchaseTradeNtf] 获取甲方签约信息失败", zap.Error(err))
 		return
 	}
+	// 账号解密
+	if len(bankaccountsign.BANKACCOUNTNO) > 0 {
+		if tt, err := hex.DecodeString(bankaccountsign.BANKACCOUNTNO); err == nil { // hex -> []byte
+			if dd, err := utils.AESDecrypt(tt, key); err == nil {
+				bankaccountsign.BANKACCOUNTNO = string(dd)
+			}
+		}
+	}
+
 	// 银行信息
 	bankinfo := model.Bankbankinfo{BANKID: bankaccountsign.BANKID}
 	if has, err := bankinfo.Get(); err != nil || !has {
@@ -124,25 +137,63 @@ func onTHJPurchaseTradeNtf(bytes *[]byte) {
 	}
 
 	docx1 := r.Editable()
+	// global.M2A_LOG.Info(docx1.GetContent())
 	docx1.Replace("${WRTRADEDETAILID}", strconv.Itoa(int(thjpurchasetradedetail.WRTRADEDETAILID)), -1)
 	docx1.Replace("${TRADETIME}", thjpurchasetradedetail.TRADETIME.Format("2006年01月02日"), -1)
 	docx1.Replace("${DESADDRESS}", totalAddress, -1)
-	docx1.Replace("${CUSTOMERNAME}", userinfo.CUSTOMERNAME, -1)
-	docx1.Replace("${CARDNUM}", userinfo.CARDNUM, -1)
+	// 判断是公司还是个人
+	if userinfo.USERINFOTYPE == 1 {
+		// 个人
+		docx1.Replace("COMPANY", "", -1)
+		docx1.Replace("${LEGALPERSONNAME}", userinfo.CUSTOMERNAME, -1)
+	} else {
+		// 公司
+		docx1.Replace("COMPANY", userinfo.CUSTOMERNAME, -1)
+		docx1.Replace("${LEGALPERSONNAME}", userinfo.LEGALPERSONNAME, -1)
+	}
+	docx1.Replace("CARDNUM", userinfo.CARDNUM, -1)
 	docx1.Replace("${MOBILE}", userinfo.MOBILE, -1)
 	docx1.Replace("${BANK}", bankinfo.BANKNAME, -1)
 	docx1.Replace("${BANKACCOUNTNO}", bankaccountsign.BANKACCOUNTNO, -1)
 	docx1.Replace("${WRSTANDARDNAME}", wrstandard.WRSTANDARDNAME, -1)
 	docx1.Replace("${SELLUSER}", selluserinfo.CUSTOMERNAME, -1)
 	docx1.Replace("${LASTAMOUNT}", strconv.FormatFloat(thjpurchasetradedetail.LASTAMOUNT, 'f', -1, 64), -1)
-	docx1.Replace("${DEPOSITRATE}", strconv.FormatFloat(thjpurchasetradedetail.DEPOSITRATE, 'f', -1, 64), -1)
+	docx1.Replace("${DEPOSITRATE}", strconv.FormatFloat(thjpurchasetradedetail.DEPOSITRATE*100, 'f', -1, 64)+"%", -1)
 	docx1.Replace("${TRADEQTY}", strconv.Itoa(int(thjpurchasetradedetail.TRADEQTY)), -1)
 	docx1.Replace("${TRADEPRICE}", strconv.FormatFloat(thjpurchasetradedetail.TRADEPRICE, 'f', -1, 64), -1)
 	docx1.Replace("${ENDDATEMONTH}", strconv.Itoa(int(wrpresaleinfo.ENDDATE.Local().Month())), -1)
 	docx1.Replace("${THJDELIVERYMODE}", thjdeliverymode, -1)
-	docx1.Replace("${ENDDATE}", wrpresaleinfo.ENDDATE.Format("200601"), -1)
+	docx1.Replace("${ENDDATE}", wrpresaleinfo.ENDDATE.Format("200601"), -1)
 	docx1.Replace("${STORAGEFEE}", strconv.FormatFloat(wrstandard.STORAGEFEE, 'f', -1, 64), -1)
 
-	docx1.WriteToFile("./new_result_1.doc")
+	// 暂存docx文件
+	if exist, _ := utils.PathExists("./.tmp"); !exist {
+		os.Mkdir("./.tmp", os.ModePerm)
+	}
+	uid, _ := uuid.NewV4()
+	docFilename := fmt.Sprintf("%v_%v.docx", strconv.Itoa(int(thjpurchasetradedetail.WRTRADEDETAILID)), uid.String())
+	pdfFilename := strings.Replace(docFilename, "docx", "pdf", -1)
+	docx1.WriteToFile("./.tmp/" + docFilename)
 	r.Close()
+
+	// 导出pdf到目标目录
+	folderPath := "/Purchase_Contract/" + time.Now().Format("20060102")
+	savePath := global.M2A_CONFIG.System.StorePath + folderPath
+	if exist, _ := utils.PathExists(savePath); !exist {
+		os.MkdirAll(savePath, os.ModePerm)
+	}
+	success := utils.ConvertToPDF("./.tmp/"+docFilename, savePath)
+	if !success {
+		// 转换失败
+		global.M2A_LOG.Error("[onTHJPurchaseTradeNtf] docx转换pdf失败", zap.Error(err))
+		return
+	}
+
+	// 更新数据库
+	thjpurchasetradedetail.CONTRACTADDRBUY = fmt.Sprintf("./uploadFile/%v/%v", folderPath, pdfFilename)
+	if err = thjpurchasetradedetail.UpdateContractAddrBuy(); err != nil {
+		global.M2A_LOG.Error("[onTHJPurchaseTradeNtf] 更新数据库失败", zap.Error(err))
+		return
+	}
+	global.M2A_LOG.Info("[onTHJPurchaseTradeNtf] 合同生成成功", zap.Any("file", savePath+pdfFilename))
 }

+ 36 - 0
static/main.go

@@ -0,0 +1,36 @@
+package main
+
+import (
+	"github.com/nguyenthenguyen/docx"
+)
+
+func main() {
+	// Read from docx file
+	r, err := docx.ReadDocxFile("./现货预售合同.docx")
+	if err != nil {
+		return
+	}
+
+	docx1 := r.Editable()
+	docx1.Replace("${WRTRADEDETAILID}", "WRTRADEDETAILID", -1)
+	docx1.Replace("${TRADETIME}", "TRADETIME", -1)
+	docx1.Replace("${DESADDRESS}", "DESADDRESS", -1)
+	docx1.Replace("${CUSTOMERNAME}", "CUSTOMERNAME", -1)
+	docx1.Replace("${CARDNUM}", "CARDNUM", -1)
+	docx1.Replace("${MOBILE}", "MOBILE", -1)
+	docx1.Replace("${BANK}", "BANK", -1)
+	docx1.Replace("${BANKACCOUNTNO}", "BANKACCOUNTNO", -1)
+	docx1.Replace("${WRSTANDARDNAME}", "WRSTANDARDNAME", -1)
+	docx1.Replace("${SELLUSER}", "SELLUSER", -1)
+	docx1.Replace("${LASTAMOUNT}", "LASTAMOUNT", -1)
+	docx1.Replace("${DEPOSITRATE}", "DEPOSITRATE", -1)
+	docx1.Replace("${TRADEQTY}", "TRADEQTY", -1)
+	docx1.Replace("${TRADEPRICE}", "TRADEPRICE", -1)
+	docx1.Replace("${ENDDATEMONTH}", "ENDDATEMONTH", -1)
+	docx1.Replace("${THJDELIVERYMODE}", "THJDELIVERYMODE", -1)
+	docx1.Replace("${ENDDATE}", "ENDDATE", -1)
+	docx1.Replace("${STORAGEFEE}", "STORAGEFEE", -1)
+
+	docx1.WriteToFile("./new_result_1.doc")
+	r.Close()
+}

BIN
static/产能预售合同.docx


BIN
static/现货预售合同.doc


BIN
static/现货预售合同.docx


+ 60 - 0
utils/pdf.go

@@ -0,0 +1,60 @@
+package utils
+
+import (
+	"bytes"
+	"mtp20_assisted/global"
+	"os/exec"
+	"runtime"
+
+	"go.uber.org/zap"
+)
+
+// 说明:使用本功能需要下载libreoffice SDK
+// https://zh-cn.libreoffice.org/download/libreoffice/
+
+//
+//  ConvertToPDF
+//  @Description: 转换文件为pdf
+//  @param filePath 需要转换的文件
+//  @param outPath 转换后的PDF文件存放目录
+//  @return string
+//
+func ConvertToPDF(filePath string, outPath string) bool {
+	// 1、拼接执行转换的命令
+	commandName := ""
+	var params []string
+	if runtime.GOOS == "windows" {
+		commandName = "cmd"
+		params = []string{"/c", "soffice", "--headless", "--invisible", "--convert-to", "pdf", filePath, "--outdir", outPath}
+	} else if runtime.GOOS == "linux" {
+		commandName = "libreoffice"
+		params = []string{"--invisible", "--headless", "--convert-to", "pdf", filePath, "--outdir", outPath}
+	}
+	// 开始执行转换
+	if _, ok := interactiveToexec(commandName, params); ok {
+		return true
+	} else {
+		return false
+	}
+}
+
+//
+//  interactiveToexec
+//  @Description: 执行指定命令
+//  @param commandName 命令名称
+//  @param params 命令参数
+//  @return string 执行结果返回信息
+//  @return bool 是否执行成功
+//
+func interactiveToexec(commandName string, params []string) (string, bool) {
+	cmd := exec.Command(commandName, params...)
+	buf, err := cmd.Output()
+	w := bytes.NewBuffer(nil)
+	cmd.Stderr = w
+	if err != nil {
+		global.M2A_LOG.Error("执行命令错误", zap.Any("err", err))
+		return "", false
+	} else {
+		return string(buf), true
+	}
+}