12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131 |
- package service
- import (
- "database/sql"
- "encoding/json"
- "errors"
- "fmt"
- mercator "git.xiaoniaokuaiyan.com/qiaozhi/xn-mercator"
- "github.com/smartwalle/alipay/v3"
- "gopkg.in/guregu/null.v3"
- "log"
- "math/rand"
- "strconv"
- "strings"
- "sync"
- "time"
- "xiaoniaokuaiyan.com/xiaoniao/pay/ali"
- "xiaoniaokuaiyan.com/xiaoniao/config"
- "xiaoniaokuaiyan.com/xiaoniao/constants"
- "xiaoniaokuaiyan.com/xiaoniao/dal"
- "xiaoniaokuaiyan.com/xiaoniao/entity"
- "xiaoniaokuaiyan.com/xiaoniao/pay/wx"
- "xiaoniaokuaiyan.com/xiaoniao/util"
- )
- type OrderService struct {
- dal.IOrder
- *WeixinService
- }
- /*
- type tubeInfo struct {
- Yellow uint `json:"yellow"`
- Green uint `json:"green"`
- Purple uint `json:"purple"`
- }
- */
- type OrderHookSymbol int
- const (
- BEFORE_ORDER_CREATE OrderHookSymbol = iota + 1
- AFTER_ORDER_CANCEL
- )
- const BUYER_OPENID_KEY string = "buyer_openid_key"
- const BUYER_TPL string = "支付成功,我们会尽快为被邀请人发送酒精基因检测包"
- const OPENID_TPL string = "您的朋友已经为您支付成功,我们会尽快为您邮寄酒精基因检测包"
- type OrderHookHandle func(oitem *entity.Order) error
- var orderHooks = map[OrderHookSymbol][]OrderHookHandle{}
- func RegistOrderHook(typ OrderHookSymbol, handle OrderHookHandle) {
- if _, ok := orderHooks[typ]; !ok {
- orderHooks[typ] = []OrderHookHandle{}
- }
- orderHooks[typ] = append(orderHooks[typ], handle)
- }
- func (srv *OrderService) AddOrder(orderItem *entity.Order, city_id int, city string) (interface{}, error) {
- if orderItem == nil || len(orderItem.ProductIds) == 0 {
- return nil, errors.New("1::wrong request")
- }
- var btime time.Time
- btime, err := time.Parse("2006-01", orderItem.Birthday)
- if err != nil {
- btime, err = time.Parse("2006-01-02", orderItem.Birthday)
- if err != nil {
- return nil, errors.New("9::wrong birthday")
- }
- }
- if orderItem.Age <= 0 {
- orderItem.Age = time.Now().Year() - btime.Year()
- }
- db := util.GetWriteSqlDB()
- var (
- productIds = []int{}
- productQuantityMap = map[int]int{}
- )
- for _, v := range orderItem.ProductIds {
- productIds = append(productIds, v.ProductId)
- //20210119 添加 产品1149 两人核酸,下单后拆单
- //splitProductId, err := config.IniConf.Section("server").Key("split_product").Int()
- //if err == nil && v.ProductId == splitProductId {
- // v.Quantity *= 2
- //}
- productQuantityMap[v.ProductId] = v.Quantity
- }
- /*
- var plist = []*entity.ProductDB{}
- //db.Select(&plist, "select * from t_product where id in ("+util.IntJoin(productIds, ",")+") order by is_no_booktime desc")
- s_source_zfb := ""
- if orderItem.IsZFB {
- s_source_zfb = " and t2.source='sp_zfb' "
- }
- sqlTemp := "select t1.*, sum(t4.quantity) as bought_num from (select * from t_product where id in(" + util.IntJoin(productIds, ",") + ")) t1 left join (select t3.quantity, t3.product_id from t_order t2 left join t_order_product t3 on t2.id = t3.order_id where custom_mobile = ? and t2.status not in (7,9,14) and t2.retype in ('100','110') " + s_source_zfb + " ) t4 on t1.id = t4.product_id GROUP BY t1.id order by t1.is_no_booktime desc"
- db.Select(&plist, sqlTemp, orderItem.CustomMobile)
- if len(plist) != len(productIds) {
- return nil, errors.New("6::wrong param productids")
- }
- // 20230629 增加支付宝特殊处理
- if orderItem.IsZFB {
- entity.ZFBWash(plist)
- }
- //检查库存以及个人限量
- for _, pitem := range plist {
- if pitem.StockSwitch == "ON" && pitem.Stock < productQuantityMap[pitem.Id] {
- return nil, errors.New("10::out of stock")
- }
- if pitem.PstockSwitch == "ON" && int(pitem.BoughtNum.Int64)+productQuantityMap[pitem.Id] > pitem.Pstock {
- return nil, errors.New(fmt.Sprintf("11::upper limit of product %d", pitem.Id))
- }
- //20210922 处理坐标
- if pitem.SaleMode == 100 && strings.Contains(orderItem.Coordinates, ",") {
- str := "select maps from v_product_city where city_id = ? and product_id = ?"
- var maps string
- err = db.Get(&maps, str, city_id, pitem.Id)
- is := mercator.IsPointInRingByStr(orderItem.Coordinates, maps)
- if !is {
- return nil, fmt.Errorf("12::订单坐标超过范围 %s", orderItem.Coordinates)
- }
- }
- }*/
- plist, err := Stocklimit(orderItem.CustomMobile, productIds, productQuantityMap, orderItem.IsZFB)
- if err != nil {
- return nil, err
- }
- for _, pitem := range plist {
- //20210922 处理坐标
- if pitem.SaleMode == 100 && strings.Contains(orderItem.Coordinates, ",") {
- str := "select maps from v_product_city where city_id = ? and product_id = ?"
- var maps string
- err = db.Get(&maps, str, city_id, pitem.Id)
- is := mercator.IsPointInRingByStr(orderItem.Coordinates, maps)
- if !is {
- return nil, fmt.Errorf("12::订单坐标超过范围 %s", orderItem.Coordinates)
- }
- }
- }
- //如果产品中含有不需要预约时间的,则省略产能检查
- //检查产能是否足够
- strSql := "select t1.gnum, t2.remain_num, t2.pdate, t1.id as gid, t2.id as infoid, t1.shortname from (select tpc.id, num as gnum, shortname from t_producer_config tpc,t_city where city_id = t_city.id and city_id = ? and tpc.id = ?) t1 left join t_producer_info t2 on t1.id = t2.global_id and t2.pdate = ? and t2.time_range = ?"
- var producerInfo = struct {
- GNum int `db:"gnum"`
- RemainNum sql.NullInt64 `db:"remain_num"`
- PDate sql.NullString `db:"pdate"`
- GId int `db:"gid"`
- InfoId sql.NullInt64 `db:"infoid"`
- Shortname string `db:"shortname"`
- }{}
- var pinfoSqlResult sql.Result
- err = db.Get(&producerInfo, strSql, city_id, orderItem.PTId, orderItem.VisitDate, orderItem.VisitTimeRange)
- if err != nil {
- return nil, errors.New("4::该城市暂未开通服务")
- }
- tx := db.MustBegin()
- if len(plist) > 0 && plist[0].IsNoBooktime != 1 {
- visitDate, err := time.Parse("2006-01-02", orderItem.VisitDate)
- if err != nil {
- return nil, errors.New("2::wrong visit date")
- }
- //当天下单最早只能约第二天上门,240220 houyf改为20点
- if visitDate.Before(time.Now()) || (time.Now().Hour() >= 20 && time.Now().Truncate(time.Hour*24).Add(time.Hour*48).After(visitDate)) {
- return nil, errors.New("3::invalid visit date")
- }
- if producerInfo.PDate.String == orderItem.VisitDate && producerInfo.RemainNum.Int64 <= 0 {
- return nil, errors.New("5::producer not enough")
- }
- if !producerInfo.PDate.Valid {
- pinfoSqlResult = tx.MustExec("insert into t_producer_info(global_id, pdate, time_range, num, remain_num) values(?, ?, ?, ?, ?)", producerInfo.GId, visitDate, orderItem.VisitTimeRange, producerInfo.GNum, producerInfo.GNum-1)
- lid, err := pinfoSqlResult.LastInsertId()
- if err != nil {
- tx.Tx.Rollback()
- return nil, err
- }
- orderItem.MaterialId = int(lid)
- } else {
- pinfoSqlResult = tx.MustExec("update t_producer_info set remain_num = ? where id = ? and remain_num = ?", producerInfo.RemainNum.Int64-1, producerInfo.InfoId, producerInfo.RemainNum.Int64)
- orderItem.MaterialId = int(producerInfo.InfoId.Int64)
- }
- if ra, _ := pinfoSqlResult.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return nil, errors.New("7::failed to update producer info")
- }
- }
- //orderItem.VisitDate = visitDate
- if city == "" {
- if producerInfo.Shortname != "" {
- city = producerInfo.Shortname
- } else {
- city = "QG"
- }
- }
- orderId := GenerateOrderNo(city)
- orderItem.Id = orderId
- //region 20221012 护士加项 使用折扣金额
- result := map[string]interface{}{}
- isNurse := false
- json.Unmarshal([]byte(orderItem.ShareSource), &result)
- if nurse, ok := result["source"].(string); ok && nurse == "nurse" {
- if deliver_user_id, ok := result["id"].(float64); ok {
- orderItem.Payment, orderItem.RepeatItemFee, err = ComputeProductPriceByDeliverID(productIds, productQuantityMap, deliver_user_id)
- isNurse = true
- }
- }
- if !isNurse { //20221012如果没经过护士折扣,就正常计算价格
- orderItem.Payment, orderItem.RepeatItemFee, err = ComputeProductPrice(productIds, productQuantityMap, false)
- }
- // 20230629 增加支付宝特殊处理
- if orderItem.IsZFB {
- orderItem.Payment, orderItem.RepeatItemFee, err = ComputeProductPrice_ZFB(productIds, productQuantityMap)
- }
- //endregion
- //orderItem.Payment, orderItem.RepeatItemFee, err = ComputeProductPrice(productIds, productQuantityMap, false)
- //20211127 联仁根据门店id 修改定价
- if shopId, ok := util.StringToInt(orderItem.JdOrderId); ok && orderItem.Source == "lianren" {
- lianRenPrice(plist, shopId)
- orderItem.Payment = plist[0].Price
- }
- //取消减免重复项目费用
- orderItem.RepeatItemFee = 0
- if err != nil {
- tx.Tx.Rollback()
- return nil, err
- }
- if len(orderItem.ItemIds) > 0 {
- iprice, _, err := ComputeProductPrice(orderItem.ItemIds, productQuantityMap, true)
- if err != nil {
- tx.Tx.Rollback()
- return nil, err
- }
- orderItem.Payment += iprice
- tempResult := tx.MustExec("insert into t_product_detect_item(detect_item_ids) values(?)", util.IntJoin(orderItem.ItemIds, ","))
- if tpid, err := tempResult.LastInsertId(); err != nil {
- tx.Tx.Rollback()
- return nil, err
- } else {
- tx.MustExec("insert into t_order_product(order_id, product_id, is_personal) values(?,?,?)", orderId, tpid, 1)
- }
- }
- WORK_FEE_REQUIRED, _ := config.IniConf.Section("server").Key("work_fee_required_bound").Int()
- WORK_FEE, _ := config.IniConf.Section("server").Key("work_fee").Int()
- //判断是否需要上门费
- orderItem.OnlinePayment = orderItem.Payment
- for _, pitem := range plist {
- if pitem.SaleMode == 200 || pitem.IsWorkFee == 2 {
- orderItem.OnlinePayment -= pitem.Price
- }
- }
- if orderItem.Source != "web-jiaxiang" && (orderItem.OnlinePayment > 0 && orderItem.Payment < WORK_FEE_REQUIRED) {
- orderItem.WorkFee = WORK_FEE
- }
- //todo 20210331 判断是否活动来的订单,如果是某些特殊的产品id,按照数量扣减99块钱(2,132,568,645,958)
- //存到RepeatItemFee 里面,这样,在支付的时候,和前端都可以扣减相应的钱
- if len(orderItem.CustomManagerId) > 0 {
- cmId := &struct {
- Source string `json:"s"`
- IsCheck string `json:"t"`
- }{}
- err := json.Unmarshal([]byte(orderItem.CustomManagerId), &cmId)
- quantity := 0
- if err == nil && cmId.IsCheck == "200" {
- if count, ok := productQuantityMap[2]; ok {
- quantity += count
- }
- if count, ok := productQuantityMap[132]; ok {
- quantity += count
- }
- if count, ok := productQuantityMap[568]; ok {
- quantity += count
- }
- if count, ok := productQuantityMap[645]; ok {
- quantity += count
- }
- if count, ok := productQuantityMap[958]; ok {
- quantity += count
- }
- orderItem.RepeatItemFee += 99 * quantity * 100
- }
- }
- if orderItem.OnlinePayment <= 0 {
- orderItem.OnlinePayment = -1
- }
- orderItem.CreatedAt = time.Now().Format("2006-01-02 15:04:05")
- //判断并标记是否来自销售系统订单
- if srv.IsAgentOrder(orderItem.OpenId) {
- orderItem.IsAgent = 1
- }
- relationship := orderItem.Relationship
- orderItem.Relationship = ""
- strSql, mkv := util.GenerateInsertSqlFromStruct("t_order", orderItem)
- osqlResult, err := tx.NamedExec(strSql, mkv)
- if err != nil {
- tx.Tx.Rollback()
- return nil, err
- }
- if ra, _ := osqlResult.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return nil, errors.New("8::failed to upadte order info")
- }
- var (
- tube = map[string]interface{}{}
- maxTube = map[string]interface{}{}
- )
- sqlStock := "update t_product set stock = stock -? where id = ?;"
- if orderItem.IsZFB {
- sqlStock = "update t_product set zfb_stock = zfb_stock -? where id = ?;"
- }
- for _, pitem := range plist {
- if pitem.Tube.Valid && pitem.Tube.String != "" {
- json.Unmarshal([]byte(pitem.Tube.String), &tube)
- for k, v := range tube {
- if iv, iok := v.(float64); iok {
- if v1, ok := maxTube[k]; ok {
- if uint(iv) > v1.(uint) {
- maxTube[k] = uint(iv)
- }
- } else {
- maxTube[k] = uint(iv)
- }
- } else {
- if _, ok := maxTube[k]; ok {
- maxTube[k] = fmt.Sprintf("%v[%v]", maxTube[k], v)
- } else {
- maxTube[k] = v
- }
- }
- }
- }
- tx.MustExec("insert into t_order_product(order_id, product_id, product_name, price, picture, quantity) values(?,?,?,?, ?, ?)", orderId, pitem.Id, pitem.Name, pitem.Price, pitem.Picture, productQuantityMap[pitem.Id])
- if pitem.StockSwitch == "ON" && pitem.Stock >= 0 {
- tx.MustExec(sqlStock, productQuantityMap[pitem.Id], pitem.Id)
- }
- }
- tx.Commit()
- go func() {
- strTube, _ := json.Marshal(maxTube)
- _, err = db.Exec("insert into t_order_extra(order_id, pressure_pipe, relationship, is_yunxue, is_dfguomin) values (?,?,?,?,?)", orderItem.Id, strTube, relationship, orderItem.IsYunxue, orderItem.IsDfguomin)
- if err != nil {
- fmt.Println(err)
- }
- if orderItem.IsNeedPay != "N" {
- client := util.GetRedis()
- client.Select(12)
- client.HSet("order_unpay", orderItem.Id, fmt.Sprintf("%s;%d", orderItem.CreatedAt, orderItem.MaterialId))
- }
- //update sale num of product
- db.Exec("update t_product set sale_num = sale_num + 1 where id in (" + util.IntJoin(productIds, ",") + ");")
- }()
- go func() {
- if util.SourceCheck(orderItem.Source) && orderItem.Source != "lianren" {
- client := util.GetRedis()
- client.Select(12)
- msg := map[string]interface{}{
- "user": "system",
- "orderid": orderItem.Id,
- "source": orderItem.Source,
- "status": constants.ORDERSTATUS_UNPAY,
- }
- buf, _ := json.Marshal(msg)
- client.Publish("order-status-change", string(buf))
- }
- }()
- return orderItem, nil
- }
- func (srv *OrderService) AddOrderInner(orderItem *entity.Order, city_id int, city string) (interface{}, error) {
- if orderItem == nil || len(orderItem.ProductIds) == 0 {
- return nil, errors.New("1::wrong request")
- }
- var btime time.Time
- btime, err := time.Parse("2006-01", orderItem.Birthday)
- if err != nil {
- btime, err = time.Parse("2006-01-02", orderItem.Birthday)
- if err != nil {
- return nil, errors.New("9::wrong birthday")
- }
- }
- if orderItem.Age <= 0 {
- orderItem.Age = time.Now().Year() - btime.Year()
- }
- db := util.GetWriteSqlDB()
- var (
- productIds = []int{}
- productQuantityMap = map[int]int{}
- )
- for _, v := range orderItem.ProductIds {
- productIds = append(productIds, v.ProductId)
- productQuantityMap[v.ProductId] = v.Quantity
- }
- var plist []entity.ProductDB = []entity.ProductDB{}
- db.Select(&plist, "select * from t_product where id in ("+util.IntJoin(productIds, ",")+") order by is_no_booktime desc")
- if len(plist) != len(productIds) {
- return nil, errors.New("6::wrong param productids")
- }
- tx := db.MustBegin()
- //orderItem.VisitDate = visitDate
- orderItem.Payment, orderItem.RepeatItemFee, err = ComputeProductPrice(productIds, productQuantityMap, false)
- //取消减免重复项目费用
- orderItem.RepeatItemFee = 0
- if err != nil {
- tx.Tx.Rollback()
- return nil, err
- }
- /*WORK_FEE_REQUIRED, _ := config.IniConf.Section("server").Key("work_fee_required_bound").Int()
- WORK_FEE, _ := config.IniConf.Section("server").Key("work_fee").Int()
- //判断是否需要上门费 */
- orderItem.OnlinePayment = orderItem.Payment
- for _, pitem := range plist {
- if pitem.SaleMode == 200 || pitem.IsWorkFee == 2 {
- orderItem.OnlinePayment -= pitem.Price
- }
- }
- discount, _ := config.IniConf.Section("server").Key("inner_add_discount").Int()
- orderItem.Payment = int(float64(orderItem.Payment) * float64(discount) / 100)
- /*if orderItem.OnlinePayment > 0 && orderItem.Payment < WORK_FEE_REQUIRED {
- orderItem.WorkFee = WORK_FEE
- }
- */
- if orderItem.OnlinePayment <= 0 {
- orderItem.OnlinePayment = -1
- }
- orderItem.CreatedAt = time.Now().Format("2006-01-02 15:04:05")
- relationship := orderItem.Relationship
- orderItem.Relationship = ""
- if city == "" {
- db.Get(&city, "select shortname from t_city where id = ?", city_id)
- }
- orderId := GenerateOrderNo(city)
- orderItem.Id = orderId
- if hooks, ok := orderHooks[BEFORE_ORDER_CREATE]; ok {
- for _, handle := range hooks {
- if err = handle(orderItem); err != nil {
- tx.Tx.Rollback()
- return nil, err
- }
- }
- }
- strSql, mkv := util.GenerateInsertSqlFromStruct("t_order", orderItem)
- osqlResult, err := tx.NamedExec(strSql, mkv)
- if err != nil {
- tx.Tx.Rollback()
- return nil, err
- }
- if ra, _ := osqlResult.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return nil, errors.New("8::failed to upadte order info")
- }
- var (
- tube = map[string]uint{}
- maxTube = map[string]uint{}
- )
- for _, pitem := range plist {
- if pitem.Tube.Valid && pitem.Tube.String != "" {
- json.Unmarshal([]byte(pitem.Tube.String), &tube)
- for k, v := range tube {
- if v1, ok := maxTube[k]; ok {
- if v > v1 {
- maxTube[k] = v
- }
- } else {
- maxTube[k] = v
- }
- }
- }
- tx.MustExec("insert into t_order_product(order_id, product_id, product_name, price, picture, quantity) values(?,?,?,?, ?, ?)", orderId, pitem.Id, pitem.Name, pitem.Price, pitem.Picture, productQuantityMap[pitem.Id])
- }
- tx.Commit()
- go func() {
- strTube, _ := json.Marshal(maxTube)
- _, err = db.Exec("insert into t_order_extra(order_id, pressure_pipe, relationship, is_yunxue, is_dfguomin, bloodtest_id) values (?,?,?,?,?,?)", orderItem.Id, strTube, relationship, orderItem.IsYunxue, orderItem.IsDfguomin, orderItem.BloodTestId)
- if err != nil {
- fmt.Println(err)
- }
- client := util.GetRedis()
- client.Select(12)
- client.HSet("order_unpay", orderItem.Id, fmt.Sprintf("%s;%d", orderItem.CreatedAt, orderItem.MaterialId))
- //update sale num of product
- db.Exec("update t_product set sale_num = sale_num + 1 where id in (" + util.IntJoin(productIds, ",") + ");")
- }()
- //20210129 护士下单绑定护士信息
- if len(orderItem.NurseId) > 0 {
- nurseId, _ := strconv.Atoi(orderItem.NurseId)
- strSql = "insert into t_order_deliver_user(order_id,deliver_user_id,career,visit_date,visit_time_range,create_at,get_type) values(?,?,?,?,?,?,?);"
- sqlResult, _ := db.Exec(strSql, orderId, nurseId, "2", orderItem.VisitDate, orderItem.VisitTimeRange, time.Now().Format("2006-01-02 15:04:05"), "assign")
- if la, _ := sqlResult.RowsAffected(); la <= 0 {
- tx.Tx.Rollback()
- return false, nil
- }
- }
- return orderItem, nil
- }
- // 20210527 vip 健康好礼活动 兑换码下单
- func (srv *OrderService) AddOrderFCode(orderItem *entity.Order, city_id int, city, fcode string) (interface{}, error) {
- //直接待接单状态,不用支付
- //校验兑换码是否使用?
- //t_fcode 改成已使用
- //jd_order_id 保存 DHM:兑换码
- if len(fcode) == 0 {
- return nil, fmt.Errorf("12:fcode %s error ", fcode)
- }
- if orderItem == nil || len(orderItem.ProductIds) == 0 {
- return nil, errors.New("1::wrong request")
- }
- var btime time.Time
- btime, err := time.Parse("2006-01", orderItem.Birthday)
- if err != nil {
- btime, err = time.Parse("2006-01-02", orderItem.Birthday)
- if err != nil {
- return nil, errors.New("9::wrong birthday")
- }
- }
- if orderItem.Age <= 0 {
- orderItem.Age = time.Now().Year() - btime.Year()
- }
- db := util.GetWriteSqlDB()
- var (
- productIds = []int{}
- productQuantityMap = map[int]int{}
- )
- for _, v := range orderItem.ProductIds {
- productIds = append(productIds, v.ProductId)
- productQuantityMap[v.ProductId] = v.Quantity
- }
- /*var plist []entity.ProductDB = []entity.ProductDB{}
- //db.Select(&plist, "select * from t_product where id in ("+util.IntJoin(productIds, ",")+") order by is_no_booktime desc")
- sqlTemp := "select t1.*, sum(t4.quantity) as bought_num from (select * from t_product where id in(" + util.IntJoin(productIds, ",") + ")) t1 left join (select t3.quantity, t3.product_id from t_order t2 left join t_order_product t3 on t2.id = t3.order_id where custom_mobile = ? and t2.status not in (7,9,14) and t2.retype in ('100','110')) t4 on t1.id = t4.product_id GROUP BY t1.id order by t1.is_no_booktime desc"
- db.Select(&plist, sqlTemp, orderItem.CustomMobile)
- if len(plist) != len(productIds) {
- return nil, errors.New("6::wrong param productids")
- }
- //检查库存以及个人限量
- for _, pitem := range plist {
- if pitem.StockSwitch == "ON" && pitem.Stock < productQuantityMap[pitem.Id] {
- return nil, errors.New("10::out of stock")
- }
- if pitem.PstockSwitch == "ON" && int(pitem.BoughtNum.Int64)+productQuantityMap[pitem.Id] > pitem.Pstock {
- return nil, errors.New(fmt.Sprintf("11::upper limit of product %d", pitem.Id))
- }
- }*/
- plist, err := Stocklimit(orderItem.CustomMobile, productIds, productQuantityMap, false)
- if err != nil {
- return nil, err
- }
- //如果产品中含有不需要预约时间的,则省略产能检查
- //检查产能是否足够
- strSql := "select t1.gnum, t2.remain_num, t2.pdate, t1.id as gid, t2.id as infoid, t1.shortname from (select tpc.id, num as gnum, shortname from t_producer_config tpc,t_city where city_id = t_city.id and city_id = ? and tpc.id = ?) t1 left join t_producer_info t2 on t1.id = t2.global_id and t2.pdate = ? and t2.time_range = ?"
- var producerInfo = struct {
- GNum int `db:"gnum"`
- RemainNum sql.NullInt64 `db:"remain_num"`
- PDate sql.NullString `db:"pdate"`
- GId int `db:"gid"`
- InfoId sql.NullInt64 `db:"infoid"`
- Shortname string `db:"shortname"`
- }{}
- var pinfoSqlResult sql.Result
- err = db.Get(&producerInfo, strSql, city_id, orderItem.PTId, orderItem.VisitDate, orderItem.VisitTimeRange)
- if err != nil {
- return nil, errors.New("4::该城市暂未开通服务")
- }
- tx := db.MustBegin()
- if len(plist) > 0 && plist[0].IsNoBooktime != 1 {
- visitDate, err := time.Parse("2006-01-02", orderItem.VisitDate)
- if err != nil {
- return nil, errors.New("2::wrong visit date")
- }
- //当天下单最早只能约第二天上门,240220 houyf改为20点
- if visitDate.Before(time.Now()) || (time.Now().Hour() >= 20 && time.Now().Truncate(time.Hour*24).Add(time.Hour*48).After(visitDate)) {
- return nil, errors.New("3::invalid visit date")
- }
- if producerInfo.PDate.String == orderItem.VisitDate && producerInfo.RemainNum.Int64 <= 0 {
- return nil, errors.New("5::producer not enough")
- }
- if !producerInfo.PDate.Valid {
- pinfoSqlResult = tx.MustExec("insert into t_producer_info(global_id, pdate, time_range, num, remain_num) values(?, ?, ?, ?, ?)", producerInfo.GId, visitDate, orderItem.VisitTimeRange, producerInfo.GNum, producerInfo.GNum-1)
- lid, err := pinfoSqlResult.LastInsertId()
- if err != nil {
- tx.Tx.Rollback()
- return nil, err
- }
- orderItem.MaterialId = int(lid)
- } else {
- pinfoSqlResult = tx.MustExec("update t_producer_info set remain_num = ? where id = ? and remain_num = ?", producerInfo.RemainNum.Int64-1, producerInfo.InfoId, producerInfo.RemainNum.Int64)
- orderItem.MaterialId = int(producerInfo.InfoId.Int64)
- }
- if ra, _ := pinfoSqlResult.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return nil, errors.New("7::failed to update producer info")
- }
- }
- //fcode 验证
- pinfoSqlResult = tx.MustExec("update t_fcode set already_use_num = already_use_num +1 where code_str = ? and use_num>= already_use_num+1 ", fcode)
- if ra, _ := pinfoSqlResult.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return nil, errors.New("13::failed to update t_fcode ")
- }
- //orderItem.VisitDate = visitDate
- if city == "" {
- if producerInfo.Shortname != "" {
- city = producerInfo.Shortname
- } else {
- city = "QG"
- }
- }
- orderId := GenerateOrderNo(city)
- orderItem.Id = orderId
- orderItem.Payment, orderItem.RepeatItemFee, err = ComputeProductPrice(productIds, productQuantityMap, false)
- //取消减免重复项目费用
- orderItem.RepeatItemFee = 0
- if err != nil {
- tx.Tx.Rollback()
- return nil, err
- }
- if len(orderItem.ItemIds) > 0 {
- iprice, _, err := ComputeProductPrice(orderItem.ItemIds, productQuantityMap, true)
- if err != nil {
- tx.Tx.Rollback()
- return nil, err
- }
- orderItem.Payment += iprice
- tempResult := tx.MustExec("insert into t_product_detect_item(detect_item_ids) values(?)", util.IntJoin(orderItem.ItemIds, ","))
- if tpid, err := tempResult.LastInsertId(); err != nil {
- tx.Tx.Rollback()
- return nil, err
- } else {
- tx.MustExec("insert into t_order_product(order_id, product_id, is_personal) values(?,?,?)", orderId, tpid, 1)
- }
- }
- WORK_FEE_REQUIRED, _ := config.IniConf.Section("server").Key("work_fee_required_bound").Int()
- WORK_FEE, _ := config.IniConf.Section("server").Key("work_fee").Int()
- //判断是否需要上门费
- orderItem.OnlinePayment = orderItem.Payment
- for _, pitem := range plist {
- if pitem.SaleMode == 200 || pitem.IsWorkFee == 2 {
- orderItem.OnlinePayment -= pitem.Price
- }
- }
- if orderItem.Source != "web-jiaxiang" && (orderItem.OnlinePayment > 0 && orderItem.Payment < WORK_FEE_REQUIRED) {
- orderItem.WorkFee = WORK_FEE
- }
- if orderItem.OnlinePayment <= 0 {
- orderItem.OnlinePayment = -1
- }
- orderItem.CreatedAt = time.Now().Format("2006-01-02 15:04:05")
- //判断并标记是否来自销售系统订单
- if srv.IsAgentOrder(orderItem.OpenId) {
- orderItem.IsAgent = 1
- }
- relationship := orderItem.Relationship
- orderItem.Relationship = ""
- orderItem.JdOrderId = fmt.Sprintf("兑换码:%s", fcode)
- orderItem.Status = 10
- strSql, mkv := util.GenerateInsertSqlFromStruct("t_order", orderItem)
- osqlResult, err := tx.NamedExec(strSql, mkv)
- if err != nil {
- tx.Tx.Rollback()
- return nil, err
- }
- if ra, _ := osqlResult.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return nil, errors.New("8::failed to upadte order info")
- }
- var (
- tube = map[string]interface{}{}
- maxTube = map[string]interface{}{}
- )
- var pnames string
- for _, pitem := range plist {
- if pitem.Tube.Valid && pitem.Tube.String != "" {
- json.Unmarshal([]byte(pitem.Tube.String), &tube)
- for k, v := range tube {
- if iv, iok := v.(float64); iok {
- if v1, ok := maxTube[k]; ok {
- if uint(iv) > v1.(uint) {
- maxTube[k] = uint(iv)
- }
- } else {
- maxTube[k] = uint(iv)
- }
- } else {
- if _, ok := maxTube[k]; ok {
- maxTube[k] = fmt.Sprintf("%v[%v]", maxTube[k], v)
- } else {
- maxTube[k] = v
- }
- }
- }
- }
- tx.MustExec("insert into t_order_product(order_id, product_id, product_name, price, picture, quantity) values(?,?,?,?, ?, ?)", orderId, pitem.Id, pitem.Name, pitem.Price, pitem.Picture, productQuantityMap[pitem.Id])
- if pitem.StockSwitch == "ON" && pitem.Stock >= 0 {
- tx.MustExec("update t_product set stock = stock -? where id = ?;", productQuantityMap[pitem.Id], pitem.Id)
- }
- pnames += pitem.Name + ","
- }
- tx.Commit()
- go func() {
- strTube, _ := json.Marshal(maxTube)
- _, err = db.Exec("insert into t_order_extra(order_id, pressure_pipe, relationship, is_yunxue, is_dfguomin) values (?,?,?,?,?)", orderItem.Id, strTube, relationship, orderItem.IsYunxue, orderItem.IsDfguomin)
- if err != nil {
- fmt.Println(err)
- }
- //update sale num of product
- db.Exec("update t_product set sale_num = sale_num + 1 where id in (" + util.IntJoin(productIds, ",") + ");")
- }()
- go func() {
- sms := &SMSService{dal.DefaultSMSCodeDal}
- smsType := int(constants.SMS_ORDER_PAID_INFORM)
- var params = map[string]string{}
- params["products"] = pnames[0 : len(pnames)-1]
- sms.SendSMS(orderItem.Mobile, smsType, params)
- }()
- return orderItem, nil
- }
- // 20240122 创建普通订单以后创建普通非支付订单可以调用次方法
- func AddOrderNormal(orderItem *entity.Order) (string, error) {
- db := util.GetWriteSqlDB()
- shortName := orderItem.Id
- us := UserService{}
- //注册用户
- user, err := us._registUser(orderItem.Mobile, false)
- if err != nil || user == nil {
- return "", errors.New(fmt.Sprintf("2::RegistUser user error :%s ,[%s]", orderItem.Mobile, err))
- }
- toUpFields := map[string]interface{}{
- "custom_mobile": orderItem.Mobile,
- "name": orderItem.Name,
- "custom_id": user.Id,
- "status": 10,
- "gender": orderItem.Gender,
- "birthday": orderItem.Birthday,
- "mobile": orderItem.Mobile,
- "source": orderItem.Source,
- "created_at": time.Now().Format("2006-01-02 15:04:05"),
- }
- tx := db.MustBegin()
- var strSql string
- //todo 插入 t_order_product
- var pinfo = struct {
- Name string `db:"name"`
- ProductId int `db:"product_id"`
- Price int `db:"price"`
- Picture string `db:"picture"`
- Tube null.String `db:"tube"`
- }{}
- strSql = "select id, name, price, picture, tube from t_product where id = ?"
- err = db.Get(&pinfo, strSql, orderItem.ProductIds[0].ProductId)
- if err != nil {
- tx.Tx.Rollback()
- return "", errors.New(fmt.Sprintf("6:: no record t_product :%d[%s]", orderItem.ProductIds[0].ProductId, err))
- }
- id := GenerateOrderNo(shortName)
- toUpFields["id"] = id
- toUpFields["payment"] = pinfo.Price
- //todo 插入 t_order
- strSql = util.GenerateInsertSql("t_order", toUpFields)
- _, err = tx.NamedExec(strSql, toUpFields)
- if err != nil {
- tx.Tx.Rollback()
- return "", errors.New(fmt.Sprintf("5:: Insert t_order error :[%s]", err))
- }
- strSql = "insert into t_order_product(order_id, product_id, product_name,price, picture, quantity) values(?,?,?,?,?,1);"
- _, err = tx.Exec(strSql, id, pinfo.ProductId, pinfo.Name, pinfo.Price, pinfo.Picture)
- if err != nil {
- tx.Tx.Rollback()
- return "", errors.New(fmt.Sprintf("7:: insert t_order_product error :[%s]", err))
- }
- //todo 插入t_order_extra 表
- strSql = "insert into t_order_extra(order_id, pressure_pipe) values(?,?);"
- _, err = tx.Exec(strSql, id, pinfo.Tube)
- if err != nil {
- tx.Tx.Rollback()
- return "", errors.New(fmt.Sprintf("8:: insert t_order_extra error :[%s]", err))
- }
- tx.Commit()
- return id, nil
- }
- // 20211220 酒精基因,推送公众号消息
- func (srv *OrderService) sendWXtpl(openid, tpl, url string) {
- msg := map[string]interface{}{
- "touser": openid,
- "template_id": "4E6pVJlubXT-uItbymrn-ghkvTCBQxBu2-Z0ljL0V3c",
- "url": url,
- "data": map[string]interface{}{
- "first": map[string]interface{}{
- "value": "",
- "color": "#173177",
- },
- "keyword1": map[string]interface{}{
- "value": "PK赢茅台 大奖等你来",
- "color": "#173177",
- },
- "keyword2": map[string]interface{}{
- "value": time.Now().Format("2006-01-02"),
- "color": "#173177",
- },
- "remark": map[string]interface{}{
- "value": tpl,
- "color": "#173177",
- },
- },
- }
- buf, _ := json.Marshal(msg)
- _, err := srv.WeixinService.SendTpl(string(buf), "")
- if err != nil {
- log.Println(err.Error())
- }
- }
- // 家政分享下单 相关操作 20200814 qz
- // openId:下单人,
- // toopenId:分享人,
- // custommobild 下单人电话
- func (srv *OrderService) InsertAgent(orderId, openId, toopenId, customMobile string) (interface{}, error) {
- //检索 分享人id 查不到就终止操作
- parentagent, err := getAgentByOpenId(toopenId)
- if err != nil {
- return nil, errors.New("no toopenid found")
- }
- fmt.Println(parentagent)
- db := util.GetWriteSqlDB()
- agent, _ := getAgentByOpenId(openId)
- if agent != nil {
- userparentid := ""
- agentType := 2
- if agent.UserParentId.String == "0" {
- //如果
- userparentid = agent.UserParentId.String
- if agent.AgentType.Int64 == 0 {
- agentType = 2
- } else if agent.AgentType.Int64 == 1 {
- agentType = 3
- } else {
- agentType = int(agent.AgentType.Int64)
- }
- //更新
- _, err = db.Exec("update t_agent set userparentid = ? ,type = ?where id = ?", userparentid, agentType, agent.Id)
- }
- } else {
- _, err = db.Exec("insert into t_agent(openid,userparentid,mobile,type) values(?,?,?,2)", openId, parentagent.Id, customMobile)
- }
- //日志存mongodb
- //defer func() {
- // // go func() {
- // // db := getMgoDB()
- // // defer db.Session.Close()
- // // message := "success"
- // // if err != nil {
- // // message = err.Error()
- // // }
- // // db.C("Order_add_InsertAgent_log").Insert(bson.M{
- // // "orderId": orderId,
- // // "toOpenId": toopenId,
- // // "mobile": customMobile,
- // // "message": message,
- // // "created_at": time.Now().Format("2006-01-02 15:04:05"),
- // // })
- // // }()
- // //}()
- return nil, err
- }
- func getAgentByOpenId(openid string) (*entity.AgentEntity, error) {
- strSql := "select id,type,openid,userparentid from t_agent a where openid = ? "
- db := util.GetSqlDB()
- var items entity.AgentEntity
- err := db.Get(&items, strSql, openid)
- if err != nil {
- return nil, errors.New("no record found")
- }
- return &items, nil
- }
- func (srv *OrderService) Pay(orderItem *entity.Order, extra map[string]string) (interface{}, error) {
- if orderItem == nil || orderItem.Id == "" {
- return nil, errors.New("wrong request")
- }
- ti, err := srv.IOrder.Detail(orderItem.Id)
- if err != nil {
- return nil, err
- }
- orderDb := ti.(*dal.OrderResult)
- //todo 检查用户是否已经生成支付请求
- if orderDb == nil {
- return nil, errors.New("1::can not find order " + orderItem.Id)
- }
- if orderDb.Status != int(constants.ORDERSTATUS_UNPAY) {
- return nil, errors.New("2::order already paid or canceled")
- }
- //判断是否使用优惠券并检查券的有效性
- if len(orderItem.Coupons) > 0 {
- coupon, err := dal.DefaultCouponDal.Get(orderItem.Coupons[0], "")
- if err != nil {
- return nil, errors.New("query coupon error")
- }
- if coupon == nil {
- return nil, errors.New("3::coupon not found")
- }
- if coupon.Mobile != orderDb.CustomMobile && coupon.Mobile != orderDb.Mobile {
- return nil, errors.New("4::wrong coupon")
- }
- if coupon.OrderId.Valid && coupon.OrderId.String == orderItem.Id {
- goto SkipCheck
- }
- if !coupon.IsValid(orderDb.Payment) {
- return nil, errors.New("5::invalid coupon")
- }
- SkipCheck:
- /*if coupon.TypeId == int(constants.COUPONTYPE_LIMIT) && coupon.UseMaxValue.Int64 > int64(orderDb.Payment) {
- return nil, errors.New("can not use this coupon")
- }*/
- var plist = []struct {
- ProductId string `json:"pid"`
- Name string `json:"name"`
- }{}
- if coupon.BindProducts.Valid && strings.Trim(coupon.BindProducts.String, " ") != "" {
- err = json.Unmarshal([]byte(coupon.BindProducts.String), &plist)
- if err != nil {
- return nil, errors.New("6::invalid product limit coupon")
- }
- }
- var computeValidProductPrice = func() (bool, int) {
- var (
- validTotalPrice int
- isValid bool
- )
- for _, opitem := range orderDb.Products {
- if len(plist) > 0 {
- for _, pitem := range plist {
- if opitem.DiscountSwitch == "OFF" {
- continue
- }
- if strconv.Itoa(opitem.ProductId) == pitem.ProductId {
- validTotalPrice += opitem.ProductPrice * opitem.Quantity
- isValid = true
- break
- //break OUTER_PRODUCT_LOOP
- }
- }
- } else {
- isValid = true
- if opitem.DiscountSwitch == "ON" {
- validTotalPrice += opitem.ProductPrice * opitem.Quantity
- }
- }
- }
- return isValid, validTotalPrice
- }
- //计算可以优惠的产品总价
- var maxProductPrice int
- var valid bool = false
- valid, maxProductPrice = computeValidProductPrice()
- //OUTER_PRODUCT_LOOP:
- if len(plist) > 0 {
- if !valid {
- return nil, errors.New("7::coupon and product dismatch")
- }
- //绑定产品的券去掉上门费
- orderDb.WorkFee.SetValid(0)
- }
- if coupon.Value > maxProductPrice {
- coupon.Value = maxProductPrice
- }
- //满减券
- if coupon.TypeId == int(constants.COUPONTYPE_LIMIT) {
- if coupon.UseMaxValue.Int64 > int64(maxProductPrice) {
- return nil, errors.New("5::invalid limit coupon")
- }
- }
- //免服务费券
- if coupon.TypeId == int(constants.COUPONTYPE_SERVICE) && orderDb.WorkFee.Int64 > 0 {
- coupon.Value = int(orderDb.WorkFee.Int64)
- }
- //折扣券
- if coupon.TypeId == int(constants.COUPONTYPE_DISCOUNT) {
- coupon.Value = maxProductPrice * (100 - coupon.Value) / 100
- }
- orderItem.FreeFee = coupon.Value
- orderItem.ActualPayment -= coupon.Value
- }
- //判断是否需要上门费
- //if orderDb.Payment < WORK_FEE_REQUIRED {
- orderItem.WorkFee = int(orderDb.WorkFee.Int64)
- orderItem.ActualPayment += orderItem.WorkFee
- //}
- orderItem.ActualPayment += orderDb.Payment - orderDb.RepeatItemFee
- //update order status
- //in order to update workfee to zero, let workfee euqals -1
- if orderItem.WorkFee == 0 {
- orderItem.WorkFee = -1
- }
- var payResult interface{}
- payType := constants.PaymentType(orderItem.PayType)
- if orderItem.ActualPayment <= 0 {
- //不需要使用第三方支付接口了
- payResult = map[string]interface{}{
- "needThirdPay": false,
- "payResult": "SUCCESS",
- }
- ouitem := entity.Order{
- Status: int(constants.ORDERSTATUS_UNRECEIVE),
- FreeFee: orderItem.FreeFee,
- PaymentTime: time.Now().Format("2006-01-02 15:04:05"),
- PayType: int(constants.PAYMENTTYPE_COUPON),
- PayNo: GenerateOrderPayNO("P"),
- Id: orderDb.Id,
- WorkFee: orderItem.WorkFee,
- }
- _, err := srv.IOrder.Update(&ouitem)
- if err != nil {
- return nil, err
- }
- go func() {
- sms := &SMSService{dal.DefaultSMSCodeDal}
- smsType := int(constants.SMS_ORDER_PAID_INFORM)
- var pnames string
- for _, opitem := range orderDb.Products {
- pnames += opitem.ProductName + ","
- }
- if orderDb.Source == "jd-jicai" {
- smsType = int(constants.SMS_JDBOOK)
- }
- sms.SendSMS(orderDb.Mobile, smsType, map[string]string{
- "OrderId": orderDb.Id,
- "products": pnames[0 : len(pnames)-1],
- "time": orderDb.VisitDate.String + " " + orderDb.VisitTimeRange.String,
- "address": orderDb.Address + "(" + orderDb.DetailAddress + ")",
- })
- _, err = srv.SendWxPaySuccessMsg(map[string]string{
- "pay_no": ouitem.PayNo,
- "openid": extra["openid"],
- "money": "0元",
- "wx_type": extra["wx_type"],
- "sms_ctype": "",
- })
- if err != nil {
- log.Println(err)
- }
- srv.firstGiveTicket(orderDb.CustomMobile)
- //inform admin
- client := util.GetRedis()
- client.Select(12)
- msg := map[string]interface{}{
- "user": "system",
- "orderid": orderItem.Id,
- "source": orderDb.Source,
- "status": constants.ORDERSTATUS_UNRECEIVE,
- }
- buf, _ := json.Marshal(msg)
- client.Publish("order-status-change", string(buf))
- delUnpayFromRedis(orderItem.Id)
- }()
- goto AFTERPAY
- //return nil, nil
- }
- //根据支付类型调用相应支付方法
- switch payType {
- case constants.PAYMENTTYPE_WEIXIN:
- payResult, err = srv.wxPay(orderItem, extra)
- case constants.PAYMENTTYPE_ALIPAY:
- payResult, err = srv.aliPay(orderItem, extra)
- default:
- return nil, errors.New("8::UnSupport pay type")
- }
- if err != nil {
- return nil, err
- }
- //update coupon status if used
- AFTERPAY:
- if len(orderItem.Coupons) > 0 {
- citem := entity.DiscountTicket{
- Id: orderItem.Coupons[0],
- Status: 1,
- OrderId: orderItem.Id,
- }
- dal.DefaultCouponDal.Update(&citem)
- }
- //todo when pay success set coupon status to used
- go func() {
- if util.SourceCheck(orderDb.Source) {
- client := util.GetRedis()
- client.Select(12)
- msg := map[string]interface{}{
- "user": "system",
- "orderid": orderDb.Id,
- "source": orderDb.Source,
- "status": constants.ORDERSTATUS_UNPAY,
- }
- buf, _ := json.Marshal(msg)
- client.Publish("order-status-change", string(buf))
- }
- }()
- return payResult, nil
- }
- // 从redis删除该订单未支付状态并发布消息通知订单状态变更
- func delUnpayFromRedis(orderId string) {
- client := util.GetRedis()
- client.Select(12)
- client.HDel("order_unpay", orderId)
- }
- func (srv *OrderService) IsAgentOrder(openid string) bool {
- strSql := "select openid from t_agent a where openid = ? and a.type in(2,3) and a.userparentid>0 and a.isdelete='N'"
- db := util.GetSqlDB()
- var items = []string{}
- db.Select(&items, strSql, openid)
- if len(items) <= 0 {
- return false
- }
- return true
- }
- //const NOORDERID string = "NOORDERID"
- // 微信支付统一下单
- func (srv *OrderService) wxPay(orderItem *entity.Order, extra map[string]string) (interface{}, error) {
- //todo check whether have already done a wx union pay request
- if extra == nil {
- return nil, errors.New("miss param extra")
- }
- if _, ok := extra["ip"]; !ok {
- return nil, errors.New("need request ip")
- }
- if _, ok := extra["trade_type"]; !ok {
- return nil, errors.New("need param trade_type of weixin pay")
- }
- if _, ok := extra["device_info"]; !ok && extra["trade_type"] == "JSAPI" {
- extra["device_info"] = "WEB"
- }
- if _, ok := extra["openid"]; !ok && extra["trade_type"] == "JSAPI" {
- return nil, errors.New("miss param openid")
- }
- payNo := GenerateOrderPayNO("P")
- wxJsSdk := wx.NewJsSdk()
- var (
- appid string = wx.DefaultConfig["appid"]
- secret = wx.DefaultConfig["secret"]
- )
- if extra["wx_type"] == "mp" {
- appid = config.IniConf.Section("weixin").Key("wx.mp.appid").Value()
- secret = config.IniConf.Section("weixin").Key("wx.mp.secret").Value()
- }
- weixin := wx.NewWeixin(appid, secret)
- nonceStr := wxJsSdk.GenerateNoncestr(16)
- reqItem := map[string]string{
- "appid": appid,
- "mch_id": wx.DefaultConfig["mch_id"],
- "nonce_str": nonceStr,
- "body": "小鸟快验订单-" + payNo,
- "notify_url": wx.DefaultConfig["paycb_notify_url"],
- "out_trade_no": payNo,
- "spbill_create_ip": extra["ip"],
- "total_fee": fmt.Sprintf("%d", orderItem.ActualPayment),
- "trade_type": extra["trade_type"],
- "attach": orderItem.Id,
- }
- if extra["trade_type"] == "JSAPI" {
- reqItem["openid"] = extra["openid"]
- }
- if extra["device_info"] != "" {
- reqItem["device_info"] = extra["device_info"]
- }
- sign := wxJsSdk.ComputePaySignature(reqItem, wx.DefaultConfig["apikey"])
- reqItem["sign"] = sign
- fmt.Println(reqItem)
- rel, err := weixin.PrepareOrder(reqItem)
- if err != nil {
- return nil, err
- }
- if rel.ReturnCode == "FAIL" {
- return nil, errors.New(rel.ReturnMsg)
- }
- //update order payno
- upOrder := &entity.Order{
- PayNo: payNo,
- Id: orderItem.Id,
- WorkFee: orderItem.WorkFee,
- FreeFee: orderItem.FreeFee,
- }
- _, err = srv.IOrder.Update(upOrder)
- if err != nil {
- return nil, err
- }
- resultItem := map[string]string{
- "appId": appid,
- "timeStamp": fmt.Sprintf("%d", time.Now().Unix()),
- "nonceStr": wxJsSdk.GenerateNoncestr(16),
- "package": "prepay_id=" + rel.PrepayId,
- "signType": "MD5",
- "mweb_url": rel.MWebUrl,
- "code_url": rel.CodeUrl,
- }
- //小程序支付时保存prepare_id 到redis,用于后续支付成功发送模板消息
- if extra["wx_type"] == "mp" {
- rclient := util.GetRedis()
- rclient.Select(12)
- rclient.HSet("mp_prepare_id", orderItem.Id, rel.PrepayId)
- }
- resultItem["sign"] = wxJsSdk.ComputePaySignature(resultItem, config.IniConf.Section("weixin").Key("wx.apikey").Value())
- return resultItem, nil
- }
- // 支付宝支付
- func (srv *OrderService) aliPay(orderItem *entity.Order, extra map[string]string) (interface{}, error) {
- aliClient := ali.GetAliClient()
- if aliClient == nil {
- return nil, fmt.Errorf("支付宝初始化错误")
- }
- pay := alipay.TradeCreate{}
- payNo := GenerateOrderPayNO("P")
- pay.NotifyURL = config.IniConf.Section("ali").Key("ali.paycb_notify_url").Value()
- //支付标题
- pay.Subject = "小鸟快验订单-" + payNo
- //订单号,一个订单号只能支付一次
- pay.OutTradeNo = payNo
- //商品code
- //pay.ProductCode = time.Now().String()
- //金额
- pay.TotalAmount = strconv.FormatFloat(float64(orderItem.ActualPayment)/100, 'f', -1, 64)
- pay.BuyerId = extra["user_zfb_id"]
- res, err := aliClient.TradeCreate(pay)
- //失败
- if err != nil {
- return nil, err
- }
- if !res.Content.Code.IsSuccess() {
- return nil, fmt.Errorf(res.Content.Msg)
- }
- upOrder := &entity.Order{
- PayNo: payNo,
- Id: orderItem.Id,
- WorkFee: orderItem.WorkFee,
- FreeFee: orderItem.FreeFee,
- }
- _, err = srv.IOrder.Update(upOrder)
- resultItem := map[string]string{
- "trade_no": res.Content.TradeNo,
- }
- return resultItem, nil
- }
- func (srv *OrderService) PayQuery(oid string, extra map[string]string) (interface{}, error) {
- orderDb, err := srv.IOrder.Get(oid)
- if err != nil {
- return nil, err
- }
- //todo 检查用户是否已经生成支付请求
- if orderDb == nil {
- return nil, errors.New("1::can not find order " + oid)
- }
- if orderDb.ActualPayment.Int64 > 0 && orderDb.Status != int(constants.ORDERSTATUS_UNPAY) {
- return map[string]string{
- "status": "SUCCESS",
- "order_id": oid,
- "actual_payment": fmt.Sprintf("%d", orderDb.ActualPayment.Int64),
- }, nil
- }
- switch extra["pay_type"] {
- case fmt.Sprintf("%d", constants.PAYMENTTYPE_WEIXIN):
- extra["out_trade_no"] = orderDb.PayNo.String
- return srv.WxPayQuery(extra)
- case fmt.Sprintf("%d", constants.PAYMENTTYPE_ALIPAY):
- extra["out_trade_no"] = orderDb.PayNo.String
- return srv.AliPayQuery(extra)
- default:
- return nil, errors.New("UNKNOWN PAY TYPE")
- }
- }
- func (srv *OrderService) WxPayQuery(extra map[string]string) (map[string]string, error) {
- wxJsSdk := wx.NewJsSdk()
- var (
- appid string = wx.DefaultConfig["appid"]
- secret = wx.DefaultConfig["secret"]
- )
- if extra["wx_type"] == "mp" {
- appid = config.IniConf.Section("weixin").Key("wx.mp.appid").Value()
- secret = config.IniConf.Section("weixin").Key("wx.mp.secret").Value()
- }
- weixin := wx.NewWeixin(appid, secret)
- nonceStr := wxJsSdk.GenerateNoncestr(16)
- reqItem := map[string]string{
- "appid": appid,
- "mch_id": wx.DefaultConfig["mch_id"],
- "nonce_str": nonceStr,
- "out_trade_no": extra["out_trade_no"],
- "sign_type": "MD5",
- }
- sign := wxJsSdk.ComputePaySignature(reqItem, wx.DefaultConfig["apikey"])
- reqItem["sign"] = sign
- rel, err := weixin.OrderQuery(reqItem)
- if err != nil {
- return nil, err
- }
- if rel["return_code"] == "FAIL" {
- return nil, errors.New(rel["return_msg"])
- }
- if rel["return_code"] == "FAIL" {
- return nil, errors.New(rel["err_code"] + ":" + rel["err_code_des"])
- }
- //kv, _ := util.StructToMap(rel)
- kv := rel
- osign := rel["sign"]
- delete(kv, "sign")
- csign := wxJsSdk.ComputePaySignature(kv, wx.DefaultConfig["apikey"])
- if csign != osign {
- log.Println("pay_query_err: wrong sign", csign, osign, kv)
- return nil, errors.New("wrong sign")
- }
- log.Println("weixin pay query of order ", extra["out_trade_no"], ":", rel["trade_state"])
- if rel["trade_state"] == "SUCCESS" {
- //TODO update order status and pay infomation
- srv.WxPayCB(rel)
- }
- return map[string]string{
- "status": rel["trade_state"],
- "actual_payment": rel["total_fee"],
- }, nil
- }
- // 支付宝支付查询
- func (srv *OrderService) AliPayQuery(extra map[string]string) (map[string]string, error) {
- client := ali.GetAliClient()
- req := alipay.TradeQuery{}
- req.OutTradeNo = extra["out_trade_no"]
- res, err := client.TradeQuery(req)
- if err != nil {
- return nil, errors.New("1::aliquery err" + err.Error())
- }
- if !res.IsSuccess() {
- return nil, errors.New("2::aliquery err" + res.Content.SubMsg)
- }
- kv := map[string]string{
- "gmt_payment": res.Content.SendPayDate,
- "total_amount": res.Content.TotalAmount,
- "out_trade_no": res.Content.OutTradeNo,
- "trade_no": res.Content.TradeNo,
- }
- srv.AliPayCB(kv)
- moneyFloat, _ := strconv.ParseFloat(res.Content.TotalAmount, 64)
- moneyInt := int64(moneyFloat * 100)
- actualPay := strconv.FormatInt(moneyInt, 10)
- return map[string]string{
- "status": "SUCCESS",
- "actual_payment": actualPay,
- }, nil
- }
- // 统一支付成功后推送微信消息
- type pName struct {
- PName string `db:"product_name"`
- PId string `db:"product_id"`
- OrderId string `db:"oid"`
- PreOrderId string `db:"pre_order_id"`
- }
- // 推荐有奖活动-支付成功回调处理逻辑
- func (srv *OrderService) recommentActCallback(params map[string]string) {
- db := util.GetWriteSqlDB()
- var actInfo = struct {
- Mobile null.String `db:"mobile"`
- Status null.Int `db:"age"`
- Id int `db:"id"`
- }{}
- const source string = "SHARE_PRIZE"
- strSql := "select id, mobile, age from t_activity_info where custom_name = ? and source = ? order by created_at desc limit 1;"
- err := db.Get(&actInfo, strSql, params["openid"], source)
- if err != nil {
- if err == sql.ErrNoRows {
- return
- }
- log.Println("recommentActCallback: ", err)
- return
- }
- if actInfo.Id == 0 || actInfo.Status.Int64 == 1 {
- return
- }
- //自己扫自己
- if params["mobile"] == actInfo.Mobile.String {
- return
- }
- strSql = "select id from t_activity_info where mobile = ? and custom_name = ? and source = ? and age = 1;"
- var hasGetId int
- err = db.Get(&hasGetId, strSql, actInfo.Mobile.String, source)
- if hasGetId > 0 {
- return
- }
- strSql = "select count(*) from t_activity_info where mobile = ? and source = ? and age = 1;"
- var ac int
- err = db.Get(&ac, strSql, actInfo.Mobile.String, source)
- if err != nil {
- log.Println("recommentActCallback1: ", err)
- return
- }
- strSql = "update t_activity_info set age = 1 where id =?;"
- db.Exec(strSql, actInfo.Id)
- //发酒精代谢酶基因检测券
- now := time.Now()
- _, err = dal.DefaultCouponDal.Save(&entity.DiscountTicket{
- Mobile: params["mobile"],
- TypeId: int(constants.COUPONTYPE_NORMAL),
- BindProducts: `[{"pid":"26", "name":"酒精代谢酶基因检测"}]`,
- Value: 19900,
- CreatedAt: now.Format("2006-01-02 15:04:05"),
- Deadline: now.Add(time.Hour * 24 * 30 * 6).Format("2006-01-02 15:04:05"),
- })
- if err != nil {
- fmt.Println("recommentActCallback: ", err)
- return
- }
- var (
- firstVal string = "感谢您参加分享有奖活动,现赠送您酒精基因检测一份"
- remarkVal string = "我们已往您的账户内发放好相应的优惠券,点击下单"
- linkUrl string = config.IniConf.Section("weixin").Key("wx.front_host").Value() + "/index/index/detail/id/26"
- toUser string = params["openid"]
- )
- msg := map[string]interface{}{
- "touser": &toUser,
- "template_id": "gglvp7ygDMpqMgxW7scWCAW7xochSKD1LZtojEkNxcg",
- "url": &linkUrl,
- "data": map[string]interface{}{
- "first": map[string]interface{}{
- "value": &firstVal,
- "color": "#173177",
- },
- "keyword1": map[string]interface{}{
- "value": "推荐有奖活动",
- "color": "#173177",
- },
- "keyword2": map[string]interface{}{
- "value": "",
- "color": "#173177",
- },
- "remark": map[string]interface{}{
- "value": &remarkVal,
- "color": "#173177",
- },
- },
- }
- buf, _ := json.Marshal(msg)
- _, err = srv.WeixinService.SendTpl(string(buf), "")
- if err != nil {
- log.Println("recommentActCallback: ", err)
- }
- if ac > 4 {
- return
- }
- //发100元优惠券
- _, err = dal.DefaultCouponDal.Save(&entity.DiscountTicket{
- Mobile: actInfo.Mobile.String,
- TypeId: int(constants.COUPONTYPE_NORMAL),
- CreatedAt: now.Format("2006-01-02 15:04:05"),
- Deadline: now.Add(time.Hour * 24 * 30 * 6).Format("2006-01-02 15:04:05"),
- Value: 10000,
- })
- if err != nil {
- log.Println("recommentActCallback: ", err)
- return
- }
- //发送微信通知
- var uextra null.String
- db.Get(&uextra, "select extra from t_custom where mobile = ? limit 1", actInfo.Mobile.String)
- if !uextra.Valid || uextra.String == "" {
- log.Println("fetch openid failed with mobile: ", actInfo.Mobile.String)
- return
- }
- var extraMap = map[string]string{}
- err = json.Unmarshal([]byte(uextra.String), &extraMap)
- if err != nil {
- log.Println("wrong extra json format from custom")
- return
- }
- var wxNickname null.String
- db.Get(&wxNickname, "select nickname from t_wechat_userinfo where openid = ?", params["openid"])
- toUser = extraMap["openid"]
- firstVal = fmt.Sprintf("您的好友%s通过您分享的海报下单啦!恭喜您获得100元优惠券,赶快到账户中查看吧!", wxNickname.String)
- remarkVal = fmt.Sprintf("您还有%d次获得优惠券的机会哦,快快邀请其他好友吧~", 4-ac)
- linkUrl = config.IniConf.Section("weixin").Key("wx.front_host").Value() + "/index/user/my"
- buf, _ = json.Marshal(msg)
- _, err = srv.WeixinService.SendTpl(string(buf), "")
- if err != nil {
- log.Println("recommentActCallback: ", err)
- }
- }
- func (srv *OrderService) firstGiveTicket(mobile string) {
- //如果是用户首次下单,发优惠券50,有效期两个星期
- if isFirst, err := srv.IOrder.IsFirst(mobile); err != nil && isFirst {
- //add coupon user account related to the order
- couponItem := &entity.DiscountTicket{
- TypeId: int(constants.COUPONTYPE_DISCOUNT),
- Mobile: mobile,
- Value: 88,
- Deadline: time.Now().Add(time.Hour * 24 * 60).Format("2006-01-02 15:04:05"),
- CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
- }
- _, err = dal.DefaultCouponDal.Save(couponItem)
- if err != nil {
- log.Println("firstGiveTicket: ", err)
- }
- } else {
- if err != nil {
- log.Println(err)
- }
- }
- }
- func (srv *OrderService) WxPayCB(payResult map[string]string) {
- db := util.GetWriteSqlDB()
- payTime, _ := time.Parse("20060102150405", payResult["time_end"])
- actualPay := payResult["total_fee"]
- strSql := `select t1.id, mobile, address, detail_address, custom_mobile, visit_date, visit_time_range, t2.product_id,t2.product_name, t3.is_jiyin, source from t_order t1 left join
- t_order_product t2 on t1.id = t2.order_id left join t_product t3 on t2.product_id = t3.id where t1.pay_no = ?`
- var orderItem = []struct {
- Id string `db:"id"`
- Mobile string `db:"mobile"`
- CustomMobile string `db:"custom_mobile"`
- VisitDate null.String `db:"visit_date"`
- VisitTimeRange null.String `db:"visit_time_range"`
- ProductName string `db:"product_name"`
- ProductId int `db:"product_id"`
- Source string `db:"source"`
- Address string `db:"address"`
- DetailAddress string `db:"detail_address"`
- IsJiyin int `db:"is_jiyin"`
- }{}
- err := db.Select(&orderItem, strSql, payResult["out_trade_no"])
- if len(orderItem) <= 0 {
- log.Println("WX callback error: can not found order of out trade no ", payResult["out_trade_no"])
- if err != nil {
- log.Println(err)
- }
- return
- }
- srv.firstGiveTicket(orderItem[0].CustomMobile)
- var status = 2
- if orderItem[0].Source == "web-jiaxiang" {
- status = 3
- }
- //if util.ProductStatusJumpTo10(orderItem[0].ProductId) {
- // status = 10
- //}
- sqlResult, err := db.Exec("update t_order set status = ?, third_pay_no = ?, actual_payment = ?, payment_time = ?, pay_type = ? where pay_no = ? and status = 1", status, payResult["transaction_id"], actualPay, payTime.Format("2006-01-02 15:04:05"), constants.PAYMENTTYPE_WEIXIN, payResult["out_trade_no"])
- if err != nil {
- log.Println("UPDATE_PAY_STATUS:", err)
- return
- } else {
- if ra, _ := sqlResult.RowsAffected(); ra <= 0 {
- log.Println("UPDATE_PAY_STATUS:", "update failed")
- return
- }
- go func() {
- var (
- pnames string
- )
- if err == nil {
- for _, oitem := range orderItem {
- pnames += oitem.ProductName + ","
- }
- //20230413 问诊不发送短信
- if util.ProductWenZhen(orderItem[0].ProductId) {
- goto JUMPSMS
- }
- //fmt.Println(orderItem, isJiyin, hasMBH)
- sms := &SMSService{dal.DefaultSMSCodeDal}
- smsType := int(constants.SMS_ORDER_PAID_INFORM)
- var params = map[string]string{}
- params["OrderId"] = orderItem[0].Id
- params["products"] = pnames[0 : len(pnames)-1]
- params["time"] = orderItem[0].VisitDate.String + " " + orderItem[0].VisitTimeRange.String
- params["address"] = orderItem[0].Address + "(" + orderItem[0].DetailAddress + ")"
- if orderItem[0].Source == "jd-jicai" {
- smsType = int(constants.SMS_JDBOOK)
- }
- sms.SendSMS(orderItem[0].Mobile, smsType, params)
- }
- JUMPSMS:
- //inform admin
- client := util.GetRedis()
- client.Select(12)
- msg := map[string]interface{}{
- "user": "system",
- "orderid": orderItem[0].Id,
- "source": orderItem[0].Source,
- "status": constants.ORDERSTATUS_UNRECEIVE,
- }
- buf, _ := json.Marshal(msg)
- client.Publish("order-status-change", string(buf))
- client.HDel("order_unpay", orderItem[0].Id)
- //call recommentActCallback
- srv.recommentActCallback(map[string]string{
- "mobile": orderItem[0].Mobile,
- "openid": payResult["openid"],
- })
- }()
- var wxType = ""
- if payResult["appid"] == config.IniConf.Section("weixin").Key("wx.mp.appid").Value() {
- wxType = "mp"
- }
- smsCtype := ""
- tfee, _ := strconv.ParseInt(payResult["total_fee"], 10, 64)
- _, err = srv.SendWxPaySuccessMsg(map[string]string{
- "pay_no": payResult["out_trade_no"],
- "openid": payResult["openid"],
- "money": fmt.Sprintf("%.2f元", float32(tfee)/100),
- "wx_type": wxType,
- "sms_ctype": smsCtype,
- })
- if err != nil {
- log.Println(err)
- }
- //qz add 拆单的操作
- //go srv.SplitOrder(orderItem[0].Id, orderItem[0].ProductId)
- //20210816 加急核酸1274 发送钉钉
- if orderItem[0].ProductId == 1274 {
- srv.SendDingMsg(orderItem[0].Id)
- }
- //20211019 修改web-jiaxiang 护士佣金 前置条件/order/inner/pay ->20210129 护士下单绑定护士信息
- go func() {
- var count int
- db.Get(&count, "select count(1) from t_order_deliver_user where order_id = ?", orderItem[0].Id)
- if count > 0 && orderItem[0].Source == "web-jiaxiang" {
- pay, err := strconv.Atoi(actualPay)
- pay = pay / 10
- sqlResult, err = db.Exec("update t_order_extra set paynurse = ? where order_id = ?", pay, orderItem[0].Id)
- if err != nil {
- log.Printf("error update t_order_extra paynurse id:%s payment:%s err:%v", orderItem[0].Id, actualPay, err)
- return
- }
- log.Printf("success update t_order_extra paynurse id:%s payment:%s ", orderItem[0].Id, actualPay)
- }
- }()
- }
- }
- // 支付宝callback
- func (srv *OrderService) AliPayCB(payResult map[string]string) {
- db := util.GetWriteSqlDB()
- _, err := time.Parse("2006-01-02 15:04:05", payResult["gmt_payment"]) // noti.GmtPayment
- if err != nil {
- payResult["gmt_payment"] = time.Now().Format("2006-01-02 15:04:05")
- }
- moneyFloat, _ := strconv.ParseFloat(payResult["total_amount"], 64) //noti.TotalAmount
- moneyInt := int64(moneyFloat * 100)
- actualPay := strconv.FormatInt(moneyInt, 10)
- strSql := `select t1.id, mobile, address, detail_address, custom_mobile, visit_date, visit_time_range, t2.product_id,t2.product_name, t3.is_jiyin, source from t_order t1 left join
- t_order_product t2 on t1.id = t2.order_id left join t_product t3 on t2.product_id = t3.id where t1.pay_no = ?`
- var orderItem = []struct {
- Id string `db:"id"`
- Mobile string `db:"mobile"`
- CustomMobile string `db:"custom_mobile"`
- VisitDate null.String `db:"visit_date"`
- VisitTimeRange null.String `db:"visit_time_range"`
- ProductName string `db:"product_name"`
- ProductId int `db:"product_id"`
- Source string `db:"source"`
- Address string `db:"address"`
- DetailAddress string `db:"detail_address"`
- IsJiyin int `db:"is_jiyin"`
- }{}
- err = db.Select(&orderItem, strSql, payResult["out_trade_no"]) //noti.OutTradeNo
- if len(orderItem) <= 0 {
- log.Println("ZFB callback error: can not found order of out trade no ", payResult["out_trade_no"])
- if err != nil {
- log.Println(err)
- }
- return
- }
- srv.firstGiveTicket(orderItem[0].CustomMobile)
- var status = 2
- if orderItem[0].Source == "web-jiaxiang" {
- status = 3
- }
- sqlResult, err := db.Exec("update t_order set status = ?, third_pay_no = ?, actual_payment = ?, payment_time = ?, pay_type = ? where pay_no = ? and status = 1", status, payResult["trade_no"], actualPay, payResult["gmt_payment"], constants.PAYMENTTYPE_ALIPAY, payResult["out_trade_no"])
- if err != nil {
- log.Println("UPDATE_PAY_STATUS:", err)
- return
- } else {
- if ra, _ := sqlResult.RowsAffected(); ra <= 0 {
- log.Println("UPDATE_PAY_STATUS:", "update failed")
- return
- }
- go func() {
- var (
- pnames string
- )
- if err == nil {
- for _, oitem := range orderItem {
- pnames += oitem.ProductName + ","
- }
- //fmt.Println(orderItem, isJiyin, hasMBH)
- sms := &SMSService{dal.DefaultSMSCodeDal}
- smsType := int(constants.SMS_ORDER_PAID_INFORM)
- var params = map[string]string{}
- params["OrderId"] = orderItem[0].Id
- params["products"] = pnames[0 : len(pnames)-1]
- params["time"] = orderItem[0].VisitDate.String + " " + orderItem[0].VisitTimeRange.String
- params["address"] = orderItem[0].Address + "(" + orderItem[0].DetailAddress + ")"
- if orderItem[0].Source == "jd-jicai" {
- smsType = int(constants.SMS_JDBOOK)
- }
- sms.SendSMS(orderItem[0].Mobile, smsType, params)
- }
- //inform admin
- client := util.GetRedis()
- client.Select(12)
- msg := map[string]interface{}{
- "user": "system",
- "orderid": orderItem[0].Id,
- "source": orderItem[0].Source,
- "status": constants.ORDERSTATUS_UNRECEIVE,
- }
- buf, _ := json.Marshal(msg)
- client.Publish("order-status-change", string(buf))
- client.HDel("order_unpay", orderItem[0].Id)
- //call recommentActCallback
- //srv.recommentActCallback(map[string]string{
- // "mobile": orderItem[0].Mobile,
- // "openid": payResult["openid"],
- //})
- }()
- //qz add 拆单的操作
- //go srv.SplitOrder(orderItem[0].Id, orderItem[0].ProductId)
- _, err = srv.SendWxPaySuccessMsg(map[string]string{
- "pay_no": payResult["out_trade_no"],
- })
- //20210816 加急核酸1274 发送钉钉
- if orderItem[0].ProductId == 1274 {
- srv.SendDingMsg(orderItem[0].Id)
- }
- }
- }
- func (srv *OrderService) SendWxPaySuccessMsg(params map[string]string) (interface{}, error) {
- strSql := "select t1.id as oid, product_name,product_id from t_order t1 left join t_order_product t2 on t1.id = t2.order_id where t1.pay_no = ?"
- var nameList = []pName{}
- db := util.GetSqlDB()
- err := db.Select(&nameList, strSql, params["pay_no"])
- if err != nil {
- return nil, err
- }
- if len(nameList) == 0 {
- return nil, errors.New("order have no product")
- }
- go srv.IOrder.CheckAndSplitOrder(nameList[0].OrderId)
- //20230413 问诊不发送微信通知
- pid, _ := strconv.Atoi(nameList[0].PId)
- if util.ProductWenZhen(pid) {
- return nil, nil
- }
- strPName := ""
- strPid := ""
- yuanyiMap := map[string]struct{}{}
- for i, item := range nameList {
- if i+1 == len(nameList) {
- strPName += item.PName
- strPid += item.PId
- } else {
- strPName += item.PName + " "
- strPid += item.PId + ","
- }
- yuanyiMap[item.PId] = struct{}{}
- }
- isExistShangMen := 1
- //20220524 如果只有邮寄的,那么更换消息通知,存在上门的,就保持原来的推送
- db.Get(&isExistShangMen, "select count(1) from t_product where id in ("+strPid+") and is_no_booktime =0")
- var wxBodyContent = config.IniConf.Section("weixin").Key("msg.pay_success").Value()
- if params["sms_ctype"] == "MBH" {
- wxBodyContent = config.IniConf.Section("weixin").Key("msg.pay_success_mbh").Value()
- }
- if isExistShangMen == 0 {
- wxBodyContent = config.IniConf.Section("weixin").Key("msg.pay_success_youji").Value()
- }
- //20220525 远毅 1338 ,推送新的报文
- if len(yuanyiMap) == 1 {
- for k := range yuanyiMap {
- if util.ProductYuanYi(k) {
- wxBodyContent = config.IniConf.Section("weixin").Key("msg.pay_success_yuanyi").Value()
- }
- }
- }
- msg := map[string]interface{}{
- "touser": params["openid"],
- "template_id": "og_C32ekCtZDIG86FodplOJ-Agj0pYYjTlQLJxt3j_0",
- "url": config.IniConf.Section("weixin").Key("wx.front_host").Value() + "/activity/question", // + nameList[0].OrderId,
- "data": map[string]interface{}{
- "first": map[string]interface{}{
- "value": wxBodyContent,
- "color": "#173177",
- },
- "orderMoneySum": map[string]interface{}{
- "value": params["money"],
- "color": "#173177",
- },
- "orderProductName": map[string]interface{}{
- "value": strPName,
- "color": "#173177",
- },
- "Remark": map[string]interface{}{
- "value": "为了能更加精准解读您的检测报告,请您点击详情填写“身体健康评估表”,我们将对您的个人信息进行严格保密。首次填写身体健康评估表并完成提交,小鸟将为您奉上金额不等优惠卷,随时供您使用。",
- "color": "#173177",
- },
- },
- }
- if params["wx_type"] == "mp" {
- rclient := util.GetRedis()
- rclient.Select(12)
- strCmd := rclient.HGet("mp_prepare_id", nameList[0].OrderId)
- if terr := strCmd.Err(); terr != nil {
- log.Println(terr)
- return false, terr
- }
- msg = map[string]interface{}{
- "touser": params["openid"],
- "template_id": "_4Ps93u932mI8tnFhnde02aCKekEgVOLNPYc5L67Nuw",
- "page": "",
- "form_id": strCmd.Val(),
- "data": map[string]interface{}{
- "keyword1": map[string]interface{}{
- "value": params["money"],
- "color": "#173177",
- },
- "keyword2": map[string]interface{}{
- "value": strPName,
- "color": "#173177",
- },
- "keyword3": map[string]interface{}{
- "value": "为了能更加精准解读您的检测报告,请您点击详情填写“身体健康评估表”,我们将对您的个人信息进行严格保密。首次填写身体健康评估表并完成提交,小鸟将为您奉上金额不等优惠卷,随时供您使用。",
- "color": "#173177",
- },
- },
- }
- }
- buf, _ := json.Marshal(msg)
- return srv.WeixinService.SendTpl(string(buf), params["wx_type"])
- /*_, err = srv.WeixinService.SendTpl(string(buf))
- if err != nil {
- log.Println(err)
- }
- msg = map[string]interface{}{
- "touser": params["openid"],
- "msgtype": "news",
- "news": map[string]interface{}{
- "articles": []map[string]interface{}{
- map[string]interface{}{
- "title": "身体健康调查表",
- "description": "详细填写后,医生会为您撰写更加精准的报告",
- "url": config.IniConf.Section("weixin").Key("wx.front_host").Value() + "/activity/question",
- "picurl": config.IniConf.Section("weixin").Key("wx.front_host").Value() + "/images/wx_survey.jpg",
- },
- },
- },
- }
- msg = map[string]interface{}{
- "touser": params["openid"],
- "msgtype": "text",
- "text": map[string]interface{}{
- "content": config.IniConf.Section("weixin").Key("msg.survey").Value(),
- },
- }
- return srv.WeixinService.Send(msg)*/
- }
- // 退款
- func (srv *OrderService) Refund(params map[string]string) (interface{}, error) {
- if _, ok := params["orderId"]; !ok {
- return nil, errors.New("miss param orderId")
- }
- orderItem, err := srv.IOrder.Get(params["orderId"])
- if err != nil {
- return nil, err
- }
- if orderItem.Status < int(constants.ORDERSTATUS_UNRECEIVE) || orderItem.Status == int(constants.ORDERSTATUS_COMPLETE) {
- return nil, errors.New("the order can not refund")
- }
- payType := constants.PaymentType(orderItem.PayType.Int64)
- var (
- rid string
- payNo string
- thirdRefundId string
- refundFee interface{}
- cashRefundFee interface{}
- rtype string
- )
- switch payType {
- case constants.PAYMENTTYPE_WEIXIN:
- rel, err := srv.wxRefund(orderItem, params)
- if err != nil {
- return nil, err
- }
- rid = rel["out_refund_no"]
- payNo = rel["out_trade_no"]
- thirdRefundId = rel["refund_id"]
- refundFee = rel["refund_fee"]
- cashRefundFee = rel["cash_refund_fee"]
- rtype = "WX"
- case constants.PAYMENTTYPE_ALIPAY:
- rel, err := srv.aliRefund(orderItem, params)
- if err != nil {
- return nil, err
- }
- rid = rel["out_refund_no"]
- payNo = rel["out_trade_no"]
- thirdRefundId = rel["refund_id"]
- refundFee = rel["refund_fee"]
- cashRefundFee = rel["cash_refund_fee"]
- rtype = "ZFB"
- default:
- return nil, errors.New("UnSupport pay type(非微信支付无法退款)")
- }
- strsql := "insert into t_refund(id, pay_no, third_refund_id, refund_fee, cash_refund_fee, type) values(?,?,?,?,?,?);"
- db := util.GetWriteSqlDB()
- tx := db.MustBegin()
- sqlResult := tx.MustExec(strsql, rid, payNo, thirdRefundId, refundFee, cashRefundFee, rtype)
- if ra, _ := sqlResult.RowsAffected(); ra <= 0 {
- log.Println("failed to update refund fee")
- return nil, errors.New("failed to update refund fee")
- }
- strsql = "update t_order set refund = refund + ? where id = ?"
- sqlResult = tx.MustExec(strsql, refundFee, orderItem.Id)
- if ra, _ := sqlResult.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- log.Println("failed to update refund fee2")
- return nil, errors.New("failed to update refund fee2")
- }
- tx.Tx.Commit()
- return map[string]interface{}{
- "refund_id": rid,
- "pay_no": payNo,
- "third_refund_id": thirdRefundId,
- "type": rtype,
- "refund_fee": refundFee,
- "cash_refund_fee": cashRefundFee,
- }, nil
- }
- // 微信退款
- func (srv *OrderService) wxRefund(orderItem *entity.OrderDB, extra map[string]string) (map[string]string, error) {
- wxJsSdk := wx.NewJsSdk()
- weixin := wx.NewWeixin(wx.DefaultConfig["appid"], wx.DefaultConfig["secret"])
- nonceStr := wxJsSdk.GenerateNoncestr(16)
- var refundFee interface{} = orderItem.ActualPayment.Int64
- if _, ok := extra["refund_fee"]; ok {
- refundFee = extra["refund_fee"]
- }
- reqItem := map[string]string{
- "appid": wx.DefaultConfig["appid"],
- "mch_id": wx.DefaultConfig["mch_id"],
- "nonce_str": nonceStr,
- "out_trade_no": orderItem.PayNo.String,
- "out_refund_no": GenerateOrderPayNO("R"),
- "total_fee": fmt.Sprintf("%d", orderItem.ActualPayment.Int64),
- "refund_fee": fmt.Sprintf("%v", refundFee),
- "op_user_id": wx.DefaultConfig["mch_id"],
- }
- if _, ok := extra["device_info"]; ok {
- reqItem["device_info"] = extra["device_info"]
- }
- sign := wxJsSdk.ComputePaySignature(reqItem, wx.DefaultConfig["apikey"])
- reqItem["sign"] = sign
- rel, err := weixin.Refund(reqItem, wx.DefaultConfig["cert_file"], wx.DefaultConfig["key_file"])
- if err != nil {
- return nil, err
- }
- if rel != nil && rel["return_code"] == "FAIL" {
- return nil, errors.New(rel["return_msg"])
- } else {
- if rel["result_code"] == "FAIL" {
- return nil, errors.New(rel["err_code_des"])
- }
- }
- //todo save refund record
- return rel, nil
- }
- // 支付宝退款
- func (srv *OrderService) aliRefund(orderItem *entity.OrderDB, extra map[string]string) (map[string]string, error) {
- //var refundFee interface{} = orderItem.ActualPayment.Int64
- refundFee := strconv.FormatFloat(float64(orderItem.ActualPayment.Int64)/100, 'f', -1, 64)
- if _, ok := extra["refund_fee"]; ok {
- payment, err := strconv.ParseFloat(extra["refund_fee"], 64)
- if err == nil {
- refundFee = strconv.FormatFloat(payment/100, 'f', -1, 64)
- }
- }
- client := ali.GetAliClient()
- req := alipay.TradeRefund{}
- req.OutTradeNo = orderItem.PayNo.String
- req.RefundAmount = refundFee
- req.OutRequestNo = GenerateOrderNo("R")
- res, err := client.TradeRefund(req)
- if err != nil {
- return nil, errors.New("1::alirefund err" + err.Error())
- }
- if !res.IsSuccess() {
- return nil, errors.New("2::alirefund err" + res.Content.SubMsg)
- }
- refund_fee, _ := strconv.ParseFloat(res.Content.SendBackFee, 64)
- reqItem := map[string]string{
- "out_trade_no": res.Content.OutTradeNo,
- "refund_id": res.Content.TradeNo,
- "out_refund_no": req.OutRequestNo,
- "cash_refund_fee": fmt.Sprintf("%d", orderItem.ActualPayment.Int64),
- "refund_fee": fmt.Sprintf("%v", refund_fee*100),
- }
- return reqItem, nil
- }
- // 微信支付回调
- func (srv *OrderService) WxPayCallBack(payResult *wx.UnionPayResult) (interface{}, error) {
- return nil, nil
- }
- // 支付失败
- func (srv *OrderService) FailedOrder(oid string) (bool, error) {
- //释放优惠券
- db := util.GetWriteSqlDB()
- oitem, err := srv.IOrder.Get(oid)
- if err != nil {
- return false, err
- }
- if oitem.Status != 1 {
- return false, errors.New("该订单不能取消")
- }
- //20220124 联仁订单不解绑优惠券
- if oitem.Source == "lianren" {
- return true, nil
- }
- citem, _ := dal.DefaultCouponDal.Get(0, oitem.Id)
- if citem == nil {
- return true, nil
- }
- WORK_FEE_REQUIRED, _ := config.IniConf.Section("server").Key("work_fee_required_bound").Int()
- WORK_FEE, _ := config.IniConf.Section("server").Key("work_fee").Int()
- if citem.TypeId == int(constants.COUPONTYPE_SERVICE) || (citem.BindProducts.Valid && strings.Trim(citem.BindProducts.String, " ") != "" && oitem.OnlinePayment > 0 && oitem.Payment < WORK_FEE_REQUIRED) {
- db.Exec("update t_order set work_fee = ? where id = ?", WORK_FEE, oid)
- }
- strSql := "update t_discount_ticket set order_id = null, status = 0 where order_id = ?;"
- _, err = db.Exec(strSql, oid)
- if err != nil {
- return false, err
- }
- return true, nil
- }
- func (srv *OrderService) CancelOrder(oid string) (bool, error) {
- orderDb, err := srv.IOrder.Get(oid)
- if err != nil {
- return false, err
- }
- //根据订单状态判断是否可以取消
- status := constants.OrderStatus(orderDb.Status)
- if (status == constants.ORDERSTATUS_UNPAY || status == constants.ORDERSTATUS_UNRECEIVE) && (orderDb.Source == "web" || orderDb.Source == "h5") {
- //20210203如果来源是web 和h5 状态时 1:待支付,2:待接单 走取消流程(还有退款)
- } else if status != constants.ORDERSTATUS_UNPAY && orderDb.Source != "jd-jicai" {
- //其他来源,状态1 才可以取消 20210203 给前端开放取消功能,所以修改此条件
- return false, errors.New("该订单不能取消")
- }
- if orderDb.Source == "jd-jicai" && orderDb.Status > 3 {
- return false, errors.New("该订单不能取消")
- }
- //todo 释放订单占用的产能并更改订单状态
- db := util.GetWriteSqlDB()
- tx := db.MustBegin()
- if orderDb.Source == "jd-jicai" {
- result := tx.MustExec("update t_jd_productivity set remain_pnum = remain_pnum + 1 where addr_id = ? and pdate = ?;", orderDb.MaterialId, orderDb.VisitDate.String)
- if ra, _ := result.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return false, errors.New("更新产能失败")
- }
- } else {
- if orderDb.MaterialId > 0 {
- result := tx.MustExec("update t_producer_info set remain_num = remain_num + 1 where id = ? ", orderDb.MaterialId)
- if ra, _ := result.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return false, errors.New("更新产能失败")
- }
- }
- }
- result := tx.MustExec("update t_order set status = ?, m_id = 0 where id = ?", constants.ORDERSTATUS_CANCELED, orderDb.Id)
- if ra, _ := result.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return false, errors.New("更新订单状态失败")
- }
- //回滚库存
- var ops = []entity.OrderProduct{}
- db.Select(&ops, "select t1.*, t2.stock_switch from t_order_product t1 left join t_product t2 on t1.product_id = t2.id where order_id = ?", oid)
- sql := "update t_product set stock = stock + ? where id = ?"
- if orderDb.Source == "sp_zfb" {
- sql = "update t_product set zfb_stock = zfb_stock + ? where id = ?"
- }
- for _, op := range ops {
- if op.StockSwitch == "ON" {
- result = tx.MustExec(sql, op.Quantity, op.ProductId)
- if ra, _ := result.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return false, errors.New("更新库存失败")
- }
- }
- }
- tx.Commit()
- go delUnpayFromRedis(oid)
- if orderDb.Source == "jd-jicai" && (orderDb.Status == 2 || orderDb.Status == 3) {
- rps := map[string]string{
- "orderId": orderDb.Id,
- "refund_fee": fmt.Sprintf("%d", orderDb.ActualPayment.Int64),
- }
- log.Println("refund: ", orderDb.Id)
- _, err = srv.Refund(rps)
- if err != nil {
- log.Println(err)
- }
- } else if (orderDb.Source == "web" || orderDb.Source == "h5" || orderDb.Source == "sp" || orderDb.Source == "sp_zfb") && orderDb.Status == 2 {
- //20210203 如果来源是web h5 而且状态是2的,走退款流程
- rps := map[string]string{
- "orderId": orderDb.Id,
- "refund_fee": fmt.Sprintf("%d", orderDb.ActualPayment.Int64),
- }
- log.Println("refund: ", orderDb.Id)
- _, err = srv.Refund(rps)
- if err != nil {
- log.Println(err)
- }
- //优惠券复原
- strSql := "update t_discount_ticket set order_id = null, status = 0 where order_id = ?;"
- _, err = db.Exec(strSql, oid)
- } else if orderDb.Source == "lianren" {
- //20220124 联仁单独解绑优惠券
- strSql := "update t_discount_ticket set order_id = null, status = 0 where order_id = ?;"
- _, err = db.Exec(strSql, oid)
- }
- if util.SourceCheck(orderDb.Source) {
- go pushOrderStatus(oid, orderDb.Source, orderDb.Status)
- }
- return true, nil
- }
- func (srv *OrderService) DelOrder(oid string) (bool, error) {
- orderDb, err := srv.IOrder.Get(oid)
- if err != nil {
- return false, err
- }
- //根据订单状态判断是否可以删除
- status := constants.OrderStatus(orderDb.Status)
- if status > constants.ORDERSTATUS_UNPAY && status < constants.ORDERSTATUS_COMPLETE {
- return false, errors.New("该订单不能删除")
- }
- //todo 释放订单占用的产能并更改订单状态
- db := util.GetWriteSqlDB()
- tx := db.MustBegin()
- if status == constants.ORDERSTATUS_UNPAY && orderDb.MaterialId > 0 {
- result := tx.MustExec("update t_producer_info set remain_num = remain_num + 1 where id = ? ", orderDb.MaterialId)
- if ra, _ := result.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return false, errors.New("更新产能失败")
- }
- }
- //result := tx.MustExec("update t_order set status = ? where id = ?", constants.ORDERSTATUS_DELETED, orderDb.Id)
- result := tx.MustExec("update t_order set is_delete = ? where id = ?", "Y", orderDb.Id)
- if ra, _ := result.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return false, errors.New("删除订单失败")
- }
- tx.Commit()
- if status == constants.ORDERSTATUS_UNPAY {
- go delUnpayFromRedis(oid)
- }
- if util.SourceCheck(orderDb.Source) {
- go pushOrderStatus(oid, orderDb.Source, orderDb.Status)
- }
- return true, nil
- }
- func pushOrderStatus(orderId, source string, status int) {
- if util.SourceCheck(source) {
- client := util.GetRedis()
- client.Select(12)
- msg := map[string]interface{}{
- "user": "system",
- "orderid": orderId,
- "source": source,
- "status": status,
- }
- buf, _ := json.Marshal(msg)
- client.Publish("order-status-change", string(buf))
- }
- }
- // 获取订单列表
- func (srv *OrderService) ListOrder(customId, pageIndex, pageSize, status int, mobile string, isZFB bool, isHis bool) (interface{}, error) {
- return srv.IOrder.List(customId, pageIndex, pageSize, status, mobile, isZFB, isHis)
- }
- // 根据custom_file_id获取订单列表 20211210
- func (srv *OrderService) ListFileOrder(customId, pageIndex, pageSize, status int, mobile string, isZFB, isHis bool) (interface{}, error) {
- return srv.IOrder.ListCustomFile(customId, pageIndex, pageSize, status, mobile, isZFB, isHis)
- }
- // 获取订单详细信息
- func (srv *OrderService) OrderDetail(oid string) (interface{}, error) {
- if oid == "" {
- return nil, errors.New("miss param order id")
- }
- return srv.IOrder.Detail(oid)
- }
- func (srv *OrderService) OrderReport(oid string, otype string) (interface{}, error) {
- if oid == "" {
- return nil, errors.New("miss param order id")
- }
- oid = strings.ToUpper(oid)
- var orderTableName = "t_order"
- if otype == "SPECIAL" {
- orderTableName = "t_special_order"
- }
- strSql := "select t1.id,original_report, report_picture,complete_time, mobile,custom_mobile, t1.name,gender,birthday,age,t1.type, is_view_report, share_code, blood_codes, source, group_concat(t2.product_id) as product_ids,group_concat(t3.name) as product_names,group_concat(t3.is_jiyin) as is_jiyins from " + orderTableName + " t1 left join t_order_product t2 on t1.id = t2.order_id left join t_product t3 on t2.product_id = t3.id where t1.id = ?"
- db := util.GetSqlDB()
- var data = &struct {
- Id string `db:"id"`
- Mobile string `db:"mobile"`
- CustomMobile string `db:"custom_mobile"`
- ReportPicture string `db:"report_picture"`
- IsViewReport string `db:"is_view_report"`
- CustomName string `db:"name"`
- Gender int `db:"gender"`
- Age int `db:"age"`
- Birthday string `db:"birthday"`
- ProductIds string `db:"product_ids"`
- ProductNames string `db:"product_names"`
- BloodCodes null.String `db:"blood_codes"`
- ShareCode null.String `db:"share_code"`
- ReportData interface{} `db:"-"`
- CompleteTime null.String `db:"complete_time"`
- Type string `db:"type"`
- IsJinyins string `db:"is_jiyins"`
- OriginalReport null.String `db:"original_report"`
- Source string `db:"source"`
- }{}
- err := db.Get(data, strSql, oid)
- if err != nil {
- return nil, err
- }
- if !data.ShareCode.Valid || strings.Trim(data.ShareCode.String, " ") == "" {
- code := util.GenerateCodeStr(8)
- strSql := fmt.Sprintf("update %s set share_code = ? where id = ?;", orderTableName)
- _, err = db.Exec(strSql, code, oid)
- if err != nil {
- return nil, err
- }
- data.ShareCode.SetValid(code)
- }
- if strings.Trim(data.ReportPicture, " ") != "" {
- return data, err
- }
- reportData, err := GetReportData(oid, otype)
- if err != nil {
- return nil, err
- }
- data.ReportData = reportData
- return data, nil
- }
- type (
- reportDetectItem struct {
- DetectProductId string `json:"detect_product_id"`
- Id string `json:"id"`
- Name string `json:"name"`
- UpRefValue string `json:"up_refvalue"`
- RefValue string `json:"refvalue"`
- Final string `json:"final"`
- FinalStatus int8 `json:"final_status"`
- Unit string `json:"unit"`
- CheckTime string `json:"check_time"`
- IsShowRefvalue int8 `json:"is_show_refvalue"`
- Description string `json:"description"`
- FinalTip string `json:"final_tip"`
- Extra string `json:"extra"`
- }
- reportDetectProduct struct {
- Id string `json:"id"`
- ProductId string `json:"product_id"`
- Name string `json:"name"`
- SortNo string `json:"sort_no"`
- Items []*reportDetectItem `json:"items"`
- Comment string `json:"comment"`
- AnomalyCount uint `json:"anomaly_count"`
- Icon string `json:"icon"`
- IconSmall string `json:"icon_small"`
- }
- reportProduct struct {
- ProductId string `json:"product_id"`
- ProductName string `json:"product_name"`
- IsJiyin int `json:"is_jiyin"`
- Items []*reportDetectProduct `json:"items"`
- }
- detectItemResult struct {
- DetectItemId string `db:"detect_item_id"`
- Final string `db:"final"`
- FinalStatus int8 `db:"final_status"`
- RefValue string `db:"refValue"`
- Age string `db:"age"`
- Gender string `db:"gender"`
- Unit string `db:"unit"`
- CheckTime null.String `db:"checkTime"`
- Description null.String `db:"description"`
- FinalTip null.String `db:"final_tip"`
- Extra null.String `db:"extra"`
- }
- analysisItemResult struct {
- Title null.String `db:"title"`
- Analysis null.String `db:"analysis"`
- OrderNum int `db:"order_num"`
- }
- tempCItem struct {
- Comment null.String
- Icon null.String
- IconSmall null.String
- }
- )
- func GetReportData(oid string, otype string) (interface{}, error) {
- oid = strings.ToUpper(oid)
- var (
- strSql = "select product_schema from t_order_product_snapshot where order_id = ? limit 1"
- productSchema string
- db = util.GetSqlDB()
- productList = []reportProduct{}
- )
- err := db.Get(&productSchema, strSql, oid)
- if err != nil {
- return nil, err
- }
- err = json.Unmarshal([]byte(productSchema), &productList)
- if err != nil {
- return nil, err
- }
- strSql = "select t1.*, t2.description from t_custom_detect_result t1 left join t_detect_item t2 on t1.detect_item_id = t2.id where order_no = ?"
- ditemResultList := []detectItemResult{}
- ditemIdxMap := map[string]int{}
- err = db.Select(&ditemResultList, strSql, oid)
- if err != nil {
- return nil, err
- }
- for idx, ditem := range ditemResultList {
- ditemIdxMap[ditem.DetectItemId] = idx
- }
- strSql = "select detect_product_id, result_comment, t2.icon, t2.icon_small from t_detect_product_comment t1 left join t_detect_product t2 on t1.detect_product_id = t2.id where order_no = ?"
- rows, err := db.Queryx(strSql, oid)
- if err != nil {
- return nil, err
- }
- var (
- dpid string
- comment null.String
- comments = map[string]tempCItem{}
- icon null.String
- iconSmall null.String
- )
- for rows.Next() {
- rows.Scan(&dpid, &comment, &icon, &iconSmall)
- comments[dpid] = tempCItem{
- Comment: comment,
- Icon: icon,
- IconSmall: iconSmall,
- }
- }
- rows.Close()
- analysisInfo := struct {
- Analysis null.String `db:"analysis" json:"analysis"`
- CustomName string `db:"name" json:"custom_name"`
- Mobile string `db:"mobile" json:"mobile"`
- Age string `db:"-" json:"age"`
- Gender string `db:"-" json:"gender"`
- Summarize null.String `db:"summarize" json:"summarize"`
- ReportItems string `db:"-" json:"report_items"`
- AnalysisList interface{} `db:"-" json:"analysis_desc"`
- }{}
- var orderTableName = "t_order"
- if otype == "SPECIAL" {
- orderTableName = "t_special_order"
- }
- strSql = "select analysis, mobile, name, summarize from " + orderTableName + " t1 left join t_report_analysis t2 on t1.id = t2.order_id left join t_report_summarize t3 on t1.id = t3.order_id where t1.id = ?"
- err = db.Get(&analysisInfo, strSql, oid)
- if err != nil {
- return nil, err
- }
- strSql = "select * from t_report_analysis_desc where order_id = ? order by order_num asc;"
- var alist = []analysisItemResult{}
- err = db.Select(&alist, strSql, oid)
- if err != nil {
- return nil, err
- }
- analysisInfo.AnalysisList = alist
- var ritems string
- db.Get(&ritems, "select item from t_report_item where order_id = ?", oid)
- analysisInfo.ReportItems = ritems
- for _, pitem := range productList {
- for _, dpItem := range pitem.Items {
- if _, ok := comments[dpItem.Id]; ok {
- dpItem.Comment = comments[dpItem.Id].Comment.String
- dpItem.Icon = comments[dpItem.Id].Icon.String
- dpItem.IconSmall = comments[dpItem.Id].IconSmall.String
- }
- for _, ditem := range dpItem.Items {
- if idx, ok := ditemIdxMap[ditem.Id]; ok {
- ditem.RefValue = ditemResultList[idx].RefValue
- ditem.FinalStatus = ditemResultList[idx].FinalStatus
- ditem.Final = ditemResultList[idx].Final
- ditem.Unit = ditemResultList[idx].Unit
- ditem.CheckTime = ditemResultList[idx].CheckTime.String
- ditem.Description = ditemResultList[idx].Description.String
- ditem.FinalTip = ditemResultList[idx].FinalTip.String
- if analysisInfo.Age == "" {
- analysisInfo.Age = ditemResultList[idx].Age
- }
- if analysisInfo.Gender == "" {
- analysisInfo.Gender = ditemResultList[idx].Gender
- }
- ditem.Extra = ditemResultList[idx].Extra.String
- }
- if ditem.FinalStatus == 1 || ditem.FinalStatus == 2 || ditem.FinalStatus == -1 || ditem.FinalStatus == 3 {
- dpItem.AnomalyCount++
- }
- }
- }
- }
- return map[string]interface{}{
- "base_info": analysisInfo,
- "product_list": productList,
- }, nil
- }
- func (srv *OrderService) OrderUpdate(oitem *entity.Order, upType string) (interface{}, error) {
- if oitem.Id == "" {
- return nil, errors.New("miss param order id")
- }
- var upItem *entity.Order
- switch upType {
- case "1":
- upItem = &entity.Order{
- Id: oitem.Id,
- IsViewReport: oitem.IsViewReport,
- }
- case "2":
- strSql := "select blood_codes from t_order where blood_codes = ? and mobile <> ? limit 1;"
- db := util.GetSqlDB()
- var bcodes string
- err := db.Get(&bcodes, strSql, oitem.BloodCodes, oitem.Mobile)
- if err != nil && err != sql.ErrNoRows {
- return nil, err
- }
- if err == nil {
- return nil, errors.New("1:: blood code was already used")
- }
- var oids = strings.Split(oitem.Id, ",")
- var strOids string
- for _, oid := range oids {
- strOids += "'" + oid + "',"
- }
- strOids = strOids[0 : len(strOids)-1]
- db.Exec("update t_order set blood_codes = ? where id in("+strOids+");", oitem.BloodCodes)
- return true, nil
- case "4": //qz 20210105 修改
- db := util.GetSqlDB()
- if len(oitem.Remark) > 0 {
- _, err := db.Exec("update t_order set remark = ? where id =? and custom_id = ? ", oitem.Remark, oitem.Id, oitem.CustomId)
- if err != nil {
- fmt.Println(err.Error())
- return false, errors.New("4::update t_order remark error")
- }
- return true, nil
- } else {
- flag, err := UpdateOrderCase4(oitem)
- if err != nil || !flag {
- fmt.Println(err.Error())
- return false, err
- }
- return true, nil
- }
- default:
- }
- if upItem == nil {
- return nil, nil
- }
- return srv.IOrder.Update(upItem)
- }
- // 20210204 修改 orderUpdate case 4 的逻辑 只有remark 单独处理,其他的提取出来
- func UpdateOrderCase4(oitem *entity.Order) (bool, error) {
- db := util.GetSqlDB()
- tx := db.MustBegin()
- //获取原始订单,主要需要visit_date visit_time_range m_id
- old, err := dal.DefaultOrderDal.Get(oitem.Id)
- if err != nil {
- return false, fmt.Errorf("7::查询订单失败%s", oitem.Id)
- }
- //todo 判断新旧日期,判断不同就需要查询产能,并且归还产能
- if oitem.VisitTimeRange == old.VisitTimeRange.String && oitem.VisitDate == old.VisitDate.String {
- //如果新旧日期相同, 就不修改产能
- } else { //todo 更新产能
- //todo 1 查询新产能
- strSql := `SELECT
- t1.num,
- t2.remain_num,
- t2.pdate,
- t1.id AS gid,
- t2.id AS infoid
- FROM t_producer_config t1
- LEFT JOIN t_producer_info t2 ON t1.id = t2.global_id
- AND t1.id = ?
- AND t2.pdate = ?
- AND t2.time_range = ?`
- var producerInfo = struct {
- GNum int `db:"num"`
- RemainNum sql.NullInt64 `db:"remain_num"`
- PDate sql.NullString `db:"pdate"`
- GId int `db:"gid"`
- InfoId sql.NullInt64 `db:"infoid"`
- }{}
- var pinfoSqlResult sql.Result
- err := db.Get(&producerInfo, strSql, oitem.PTId, oitem.VisitDate, oitem.VisitTimeRange)
- if err != nil {
- return false, errors.New("1::该城市暂未开通服务")
- }
- visitDate, err := time.Parse("2006-01-02", oitem.VisitDate)
- if err != nil {
- return false, errors.New("2::错误的上门日期")
- }
- //当天下单最早只能约第二天上门,240220 houyf改为20点
- if visitDate.Before(time.Now()) || (time.Now().Hour() >= 20 && time.Now().Truncate(time.Hour*24).Add(time.Hour*48).After(visitDate)) {
- return false, errors.New("3::失效的上门日期")
- }
- if producerInfo.PDate.String == oitem.VisitDate && producerInfo.RemainNum.Int64 <= 0 {
- return false, errors.New("4::产能不足")
- }
- if !producerInfo.PDate.Valid {
- pinfoSqlResult = tx.MustExec("insert into t_producer_info(global_id, pdate, time_range, num, remain_num) values(?, ?, ?, ?, ?)", producerInfo.GId, visitDate, oitem.VisitTimeRange, producerInfo.GNum, producerInfo.GNum-1)
- lid, err := pinfoSqlResult.LastInsertId()
- if err != nil {
- tx.Tx.Rollback()
- return false, err
- }
- oitem.MaterialId = int(lid)
- } else {
- pinfoSqlResult = tx.MustExec("update t_producer_info set remain_num = ? where id = ? and remain_num = ?", producerInfo.RemainNum.Int64-1, producerInfo.InfoId, producerInfo.RemainNum.Int64)
- oitem.MaterialId = int(producerInfo.InfoId.Int64)
- }
- if ra, _ := pinfoSqlResult.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return false, errors.New("5::更新产能失败")
- }
- //归还产能
- if old.MaterialId > 0 && (old.Source == "web" || old.Source == "h5") {
- result := tx.MustExec("update t_producer_info set remain_num = remain_num + 1 where id = ? ", old.MaterialId)
- if ra, _ := result.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- return false, errors.New("6::更新产能失败")
- }
- }
- }
- sqlStr, kvm := util.GenerateUpdateSqlFromStruct("t_order", oitem, " where id='"+oitem.Id+"'")
- _, err = tx.NamedExec(sqlStr, kvm)
- if err != nil {
- tx.Tx.Rollback()
- return false, err
- }
- tx.Commit()
- if util.SourceCheck(old.Source) {
- client := util.GetRedis()
- client.Select(12)
- msg := map[string]interface{}{
- "user": "system",
- "orderid": old.Id,
- "source": old.Source,
- "status": old.Status,
- }
- buf, _ := json.Marshal(msg)
- client.Publish("order-status-change", string(buf))
- }
- return true, nil
- }
- func (srv *OrderService) CommitSurvey(osItem *entity.OrderSurvey, userId int) (interface{}, error) {
- oitem, err := srv.IOrder.Get(osItem.OrderId)
- if oitem == nil {
- return nil, errors.New("invalid order id")
- }
- if err != nil {
- return nil, err
- }
- /*if oitem.CustomId != userId {
- log.Println(oitem.CustomId, ":", userId)
- return nil, errors.New("forbidden")
- }*/
- success, err := srv.IOrder.CommitSurvey(osItem)
- if err != nil {
- return false, err
- }
- if osItem.ServiceScore == "200" {
- return success, nil
- }
- if success {
- //add coupon user account related to the order
- couponItem := &entity.DiscountTicket{
- TypeId: int(constants.COUPONTYPE_NORMAL),
- Mobile: oitem.Mobile,
- Value: 1000,
- Deadline: time.Now().Add(time.Hour * 24 * 365).Format("2006-01-02 15:04:05"),
- OrderId: oitem.Id,
- CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
- }
- _, err = dal.DefaultCouponDal.Save(couponItem)
- if err != nil {
- return false, err
- }
- return true, nil
- }
- return success, err
- }
- func (srv *OrderService) SaveCallbackInfo(info entity.OrderCallbackInfo) (interface{}, error) {
- db := util.GetWriteSqlDB()
- var c int
- db.Get(&c, "select count(*) from t_order where id = ?", info.OrderId)
- if c <= 0 {
- return nil, errors.New("1::order not found")
- }
- c = 0
- db.Get(&c, "select count(*) from t_order_abnormal where order_id = ?", info.OrderId)
- if c > 0 {
- return nil, errors.New("2::record already exists")
- }
- reviewDate, err := time.Parse("2006-01-02", info.VisitEndtime)
- if err != nil {
- return nil, errors.New("4::wrong visit end time")
- }
- info.ReviewDate = reviewDate.AddDate(0, 0, 60).Format("2006-01-02")
- strSql, mkv := util.GenerateInsertSqlFromStruct("t_order_abnormal", &info)
- _, err = db.NamedExec(strSql, mkv)
- if err != nil {
- return nil, errors.New("3::" + err.Error())
- }
- return true, nil
- }
- func (srv *OrderService) GetCallbackInfo(orderId string) (interface{}, error) {
- var info = struct {
- Mobile string `json:"mobile" db:"mobile"`
- CustomMobile string `json:"custom_mobile" db:"custom_mobile"`
- OrderId string `json:"order_id" db:"id"`
- }{}
- db := util.GetSqlDB()
- err := db.Get(&info, "select mobile, custom_mobile, t2.id from t_order_abnormal t1 left join t_order t2 on t1.order_id = t2.id where t1.order_id = ? and is_own_date = 1 limit 1", orderId)
- if err != nil {
- if err == sql.ErrNoRows {
- return nil, nil
- }
- return nil, err
- }
- return info, nil
- }
- // 根据血检条码获取订单信息
- func (srv *OrderService) GetOrderInfoByCode(code string) (interface{}, error) {
- return srv.IOrder.GetByCode(code)
- }
- func (srv *OrderService) GetOrderInfoByNurse(orderId string, deliverUserId int) (interface{}, error) {
- db := util.GetSqlDB()
- var oid string
- db.Get(&oid, "select order_id from t_order_deliver_user where order_id = ? and deliver_user_id =?;", orderId, deliverUserId)
- if oid == "" {
- return nil, errors.New("forbidden")
- }
- return srv.OrderDetail(orderId)
- }
- func ComputeProductPrice(ids []int, quantityMap map[int]int, isPersonal bool) (int, int, error) {
- if len(ids) == 0 {
- return 0, 0, nil
- }
- inStr := ""
- for _, pid := range ids {
- inStr += fmt.Sprintf("%d,", pid)
- }
- inStr = inStr[0 : len(inStr)-1]
- db := util.GetSqlDB()
- var price int
- var strSql string
- var repeatFee int
- if isPersonal {
- strSql = "select sum(market_price) as price from t_detect_item where id in(" + inStr + ")"
- } else {
- strSql = `select t3.price, count(t3.id) as count from t_product_detect_product t1 left join t_detect_product_item t2 on
- t1.detect_product_id = t2.detect_product_id left join t_detect_item t3 on t2.detect_item_id = t3.id where t1.product_id in (` + inStr + `) group by t3.id having (count > 1);`
- rows, err := db.Queryx(strSql)
- if err != nil {
- return price, repeatFee, err
- }
- defer rows.Close()
- var (
- mp int
- count int
- )
- for rows.Next() {
- rows.Scan(&mp, &count)
- repeatFee += mp * (count - 1)
- }
- rows.Close()
- strSql = `select id, price from t_product where id in(` + inStr + ")"
- var (
- productId int
- pprice int
- )
- rows, _ = db.Queryx(strSql)
- for rows.Next() {
- rows.Scan(&productId, &pprice)
- price += pprice * quantityMap[productId]
- }
- }
- return price, repeatFee, nil
- }
- // 20221009 通过护士id 获取 产品 折扣价格
- func ComputeProductPriceByDeliverID(ids []int, quantityMap map[int]int, deliverid float64) (int, int, error) {
- if len(ids) == 0 {
- return 0, 0, nil
- }
- inStr := ""
- for _, pid := range ids {
- inStr += fmt.Sprintf("%d,", pid)
- }
- inStr = inStr[0 : len(inStr)-1]
- db := util.GetSqlDB()
- var price int
- var strSql string
- var repeatFee int
- strSql = `select t3.price, count(t3.id) as count from t_product_detect_product t1 left join t_detect_product_item t2 on
- t1.detect_product_id = t2.detect_product_id left join t_detect_item t3 on t2.detect_item_id = t3.id where t1.product_id in (` + inStr + `) group by t3.id having (count > 1);`
- rows, err := db.Queryx(strSql)
- if err != nil {
- return price, repeatFee, err
- }
- defer rows.Close()
- var (
- mp int
- count int
- )
- for rows.Next() {
- rows.Scan(&mp, &count)
- repeatFee += mp * (count - 1)
- }
- rows.Close()
- strSql = `select p.id, p.price,case when d.discount_price is null then 0 else d.discount_price end as discount_price from t_product p LEFT JOIN t_product_question_deliver d on p.id = d.product_id and d.deliver_user_id = ? and d.is_delete = 0 where p.id in (` + inStr + ")"
- var (
- productId int
- pprice int
- discount int
- )
- rows, _ = db.Queryx(strSql, deliverid)
- for rows.Next() {
- rows.Scan(&productId, &pprice, &discount)
- if discount > 0 {
- price += discount * quantityMap[productId]
- } else {
- price += pprice * quantityMap[productId]
- }
- }
- return price, repeatFee, nil
- }
- func ComputeProductPrice_ZFB(ids []int, quantityMap map[int]int) (int, int, error) {
- if len(ids) == 0 {
- return 0, 0, nil
- }
- inStr := ""
- for _, pid := range ids {
- inStr += fmt.Sprintf("%d,", pid)
- }
- inStr = inStr[0 : len(inStr)-1]
- db := util.GetSqlDB()
- var price int
- var strSql string
- var repeatFee int
- strSql = `select t3.price, count(t3.id) as count from t_product_detect_product t1 left join t_detect_product_item t2 on
- t1.detect_product_id = t2.detect_product_id left join t_detect_item t3 on t2.detect_item_id = t3.id where t1.product_id in (` + inStr + `) group by t3.id having (count > 1);`
- rows, err := db.Queryx(strSql)
- if err != nil {
- return price, repeatFee, err
- }
- defer rows.Close()
- var (
- mp int
- count int
- )
- for rows.Next() {
- rows.Scan(&mp, &count)
- repeatFee += mp * (count - 1)
- }
- rows.Close()
- strSql = `select id, zfb_price from t_product where id in(` + inStr + ")"
- var (
- productId int
- pprice int
- )
- rows, _ = db.Queryx(strSql)
- for rows.Next() {
- rows.Scan(&productId, &pprice)
- price += pprice * quantityMap[productId]
- }
- return price, repeatFee, nil
- }
- var orderNoMutex = &sync.Mutex{}
- func GenerateOrderNo(prefix string) string {
- prefix = strings.ToUpper(prefix)
- timeStr := time.Now().Format("060102150405")
- orderNoMutex.Lock()
- defer orderNoMutex.Unlock()
- timestamp := time.Now().Unix()
- rand.Seed(timestamp + int64(time.Now().Nanosecond()))
- var rnum = rand.Intn(100000)
- strNum := fmt.Sprintf("0000%d", rnum)
- strNum = strNum[len(strNum)-5:]
- return fmt.Sprintf("%s%s%s", prefix, timeStr, strNum)
- }
- func GenerateOrderPayNO(prefix string) string {
- timeStr := time.Now().Format("20060102150405")
- timestamp := time.Now().Unix() + int64(time.Now().Nanosecond())
- rand.Seed(timestamp)
- var rnum = rand.Intn(100000)
- strNum := fmt.Sprintf("00000%d", rnum)
- strNum = strNum[len(strNum)-5:]
- return prefix + timeStr + strNum
- }
- // qz 20200828 特定产品在交钱完成之后,拆分
- func (srv *OrderService) SplitOrder(orderId string, productId int) {
- //20220620 取消
- return
- /*
- db := util.GetWriteSqlDB()
- //查询拆单关系
- tpsInfoList := []struct {
- ProductId int `db:"product_id" `
- ChildId int `db:"child_id"`
- IsMain int `db:"is_main"`
- CreateAt string `db:"create_at"`
- Remark null.String `db:"remark"`
- Name null.String `db:"name"`
- Price null.String `db:"price"`
- }{}
- sqlSearch := "select t1.*,t2.name as name,t2.price as price from t_product_split t1 left join t_product t2 on t1.child_id = t2.id where t1.product_id =? order by t1.is_main desc"
- err := db.Select(&tpsInfoList, sqlSearch, productId)
- if err != nil || len(tpsInfoList) <= 0 {
- log.Println(fmt.Sprintf("订单%s,产品编号为%d 不需要拆单", orderId, productId))
- return
- }
- //查询订单,
- orderDb, err := srv.IOrder.Get(orderId)
- fmt.Println(orderDb)
- //查询订单 产品关联
- plist := struct {
- OrderId string `db:"order_id"`
- ProductId string `db:"product_id"`
- ProductName string `db:"product_name"`
- Price int `db:"price"`
- Picture string `db:"picture"`
- Quantity int `db:"quantity"`
- IsPersonal int `db:"is_personal"`
- }{}
- strSql := "select * from t_order_product where order_id = ? and product_id = ?"
- err = db.Get(&plist, strSql, orderId, productId)
- //查询订单 扩展
- //elist :=struct {
- // OrderID string `db:"order_id"`
- // NeedEmtiness int `db:"need_emptiness"`
- // ReportPeriod string `db:"report_period"`
- // PressurePipe string `db:"pressure_pipe"`
- // BloodAddress string `db:"blood_address"`
- // Notice string `db:"notice"`
- // UpdatedAt time.Time `db:"updated_at"`
- // Remark1 string `db:"remark1"`
- // CancelReason int `db:"cancel_reason"`
- // IsNotice string `db:"is_notice"`
- // RelationShip string `db:"relationship"`
- // IsYunXue int `db:"is_yunxue"`
- // IsDfgoumin int `db:"is_dfguomin"`
- // BloodTestId string `db:"bloodtest_id"`
- // ReportResult string `db:"reportresult"`
- // PayNurse int `db:"paynurse"`
- // IsAddpor string `db:"isaddpro"`
- // Sample string `db:"sample"`
- // JiCaiName string `db:"jicai_name"`
- // Express string `db:"express"`
- // ExpressNumber string `db:"expressnumber"`
- // ExpressStatus string `db:"expressstatus"`
- // ExpressInfo string `db:"expressinfo"`
- // ExpressUser string `db:"express_user"`
- // ExpressnumberUser string `db:"expressnumber_user"`
- //}{}
- //strSql = "select * from t_order_extra where order_id = ?"
- //err = db.Select(&elist, strSql, orderId)
- //拆分 order
- tx := db.MustBegin()
- for i := 0; i < len(tpsInfoList); i++ {
- if tpsInfoList[i].IsMain == 1 {
- //order 不用更新
- //更新order_product
- result := tx.MustExec("update t_order_product set product_id = ?,product_name = ?,price=? where order_id = ? and product_id = ?", tpsInfoList[i].ChildId, tpsInfoList[i].Name, tpsInfoList[i].Price, orderId, productId)
- if ra, _ := result.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- log.Println(fmt.Sprintf("订单%s,产品编号为%d 拆单失败 更新 t_order_product ", orderId, productId))
- return
- }
- //order_extra 不用更新
- } else {
- //生成订单号
- orderNewId := GenerateOrderNoByOld(orderId, i)
- fmt.Println(orderNewId)
- //插入 t_order
- orderDb.Id = orderNewId
- orderDb.Payment = 0
- orderDb.ServiceRemark = null.StringFrom(fmt.Sprintf("由%s拆单", orderId))
- strSql, mkv := util.GenerateInsertSqlFromStruct("t_order", orderDb)
- osqlResult, err := tx.NamedExec(strSql, mkv)
- if err != nil {
- tx.Tx.Rollback()
- log.Println(fmt.Sprintf("订单%s,产品编号为%d 拆单失败 插入 t_order %s", orderId, productId, orderNewId))
- return
- }
- if ra, _ := osqlResult.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- log.Println(fmt.Sprintf("订单%s,产品编号为%d 拆单失败 插入 t_order %s", orderId, productId, orderNewId))
- return
- }
- //todo 查询product
- //插入 t_order_product 注意 金额
- var fields = map[string]interface{}{
- "order_id": orderNewId,
- "product_id": tpsInfoList[i].ChildId,
- "product_name": tpsInfoList[i].Name,
- "price": tpsInfoList[i].Price,
- "picture": plist.Picture,
- "quantity": plist.Quantity,
- "is_personal": plist.IsPersonal,
- }
- strSql = util.GenerateInsertSql("t_order_product", fields)
- _, err = tx.NamedExec(strSql, fields)
- if err != nil {
- tx.Tx.Rollback()
- log.Println(fmt.Sprintf("订单%s,产品编号为%d 拆单失败,新建 t_order_product %s", orderId, productId, orderNewId))
- return
- }
- //复制 t_order_extra
- result := tx.MustExec(fmt.Sprintf("insert into t_order_extra(`order_id`, `need_emptiness`, `report_period`, `pressure_pipe`, `blood_address`, `notice`, `updated_at`, `remark1`, `cancel_reason`, `is_notice`, `relationship`, `is_yunxue`, `is_dfguomin`, `bloodtest_id`, `reportresult`, `paynurse`, `isaddpro`, `sample`, `jicai_name`, `express`, `expressnumber`, `expressstatus`, `expressinfo`, `express_user`, `expressnumber_user`) select '%s',`need_emptiness`, `report_period`, `pressure_pipe`, `blood_address`, `notice`, `updated_at`, `remark1`, `cancel_reason`, `is_notice`, `relationship`, `is_yunxue`, `is_dfguomin`, `bloodtest_id`, `reportresult`, `paynurse`, `isaddpro`, `sample`, `jicai_name`, `express`, `expressnumber`, `expressstatus`, `expressinfo`, `express_user`, `expressnumber_user` from t_order_extra where order_id =?", orderNewId), orderId)
- if ra, _ := result.RowsAffected(); ra <= 0 {
- tx.Tx.Rollback()
- log.Println(fmt.Sprintf("订单%s,产品编号为%d 拆单失败,新建 t_order_extra %s", orderId, productId, orderNewId))
- return
- }
- }
- }
- tx.Commit()
- */
- }
- func (srv *OrderService) SendDingMsg(orderId string) {
- util.SendOrderMsg(fmt.Sprintf("加急核酸来订单了,订单来源xn ,订单编号%s", orderId))
- }
- //20210119 添加 产品1149 两人核酸,下单后拆单 20220620 删除
- // 20210607 金睡莲活动,支付成功后更新状态码
- func (srv *OrderService) JinShuiLianServer(id string) {
- //t_custom_wxscan_pay remark 保存了 t_activity_info 的 id ;t_activity_info address 保存 fcode 还需要mobile 发送短信
- db := util.GetWriteSqlDB()
- aInfo := struct {
- Mobile null.String `db:"mobile"`
- FCode string `db:"address"`
- }{}
- db.Get(&aInfo, "select mobile,address from t_activity_info where id = ?", id)
- pinfoSqlResult := db.MustExec("update t_fcode set already_use_num = already_use_num +1 where code_str = ? and use_num>= already_use_num+1 ", aInfo.FCode)
- if ra, _ := pinfoSqlResult.RowsAffected(); ra <= 0 {
- fmt.Println("fcode update error")
- }
- sms := &SMSService{dal.DefaultSMSCodeDal}
- if aInfo.Mobile.Valid {
- sms.SendSMS(aInfo.Mobile.ValueOrZero(), 24, nil)
- }
- }
- // 20211127 联仁根据门店id 修改定价
- func lianRenPrice(list []*entity.ProductDB, shopId int) {
- db := util.GetSqlDB()
- var price int
- db.Get(&price, "select price from t_shop_lianren where id = ? ", shopId)
- if price > 0 {
- for i := 0; i < len(list); i++ {
- list[i].Price = price
- }
- }
- }
- // 20230830 拆分历史表
- // 提取 addorder addorderFcode addorderFcodeYuanyi addGenorder 的库存检查
- func Stocklimit(mobile string, productIds []int, productQuantityMap map[int]int, isZFB bool) ([]*entity.ProductDB, error) {
- plist := []*entity.ProductDB{}
- s_source_zfb := ""
- if isZFB {
- s_source_zfb = " and t2.source='sp_zfb' "
- }
- db := util.GetSqlDB()
- sqlTemp := "select t1.*, sum(t4.quantity) as bought_num from (select * from t_product where id in(" + util.IntJoin(productIds, ",") + ")) t1 left join (select t3.quantity, t3.product_id from t_order t2 left join t_order_product t3 on t2.id = t3.order_id where custom_mobile = ? and t2.status not in (7,9,14) and t2.retype in ('100','110') " + s_source_zfb + " ) t4 on t1.id = t4.product_id GROUP BY t1.id order by t1.is_no_booktime desc"
- db.Select(&plist, sqlTemp, mobile)
- if len(plist) != len(productIds) {
- return nil, errors.New("6::wrong param productids")
- }
- if isZFB {
- entity.ZFBWash(plist)
- }
- for _, pitem := range plist {
- if pitem.StockSwitch == "ON" && pitem.Stock < productQuantityMap[pitem.Id] {
- return nil, errors.New("10::out of stock")
- }
- if pitem.PstockSwitch == "ON" && int(pitem.BoughtNum.Int64)+productQuantityMap[pitem.Id] > pitem.Pstock {
- return nil, errors.New(fmt.Sprintf("11::upper limit of product %d", pitem.Id))
- }
- }
- return plist, nil
- }
- // 20240221 查询有效订单表
- func (*OrderService) OrderVaildCount(customId, status int, mobile string) (interface{}, error) {
- strSql := "select count(distinct t2.id) from (select id, mobile from t_custom where id = ?) t1, t_order t2 "
- strSql += " where (t1.id = t2.custom_id or t1.mobile = t2.mobile) and status not in (7,9,14) "
- whereValue := []interface{}{
- customId,
- }
- //if status > 0 {
- // whereStr += " "
- // whereValue = append(whereValue, status)
- //} else if status == -1 {
- // whereStr += " and status in(6,11) "
- //} else {
- // //whereStr += " and status <> 8 "
- // whereStr += " and is_delete='N'"
- //}
- if mobile != "" {
- strSql += " and t2.mobile = ? "
- whereValue = append(whereValue, mobile)
- }
- strSql += " and t2.retype in ('100','110')"
- db := util.GetSqlDB()
- var count1, count2 int
- err := db.Get(&count1, strSql, whereValue...)
- if err != nil {
- return 0, err
- }
- err = db.Get(&count2, util.ChangeOrderTableName(strSql), whereValue...)
- if err != nil {
- return 0, err
- }
- return count1 + count2, nil
- }
|