Нема описа
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211
  1. <?php
  2. /**
  3. * 易优CMS
  4. * ============================================================================
  5. * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
  6. * 网站地址: http://www.eyoucms.com
  7. * ----------------------------------------------------------------------------
  8. * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
  9. * ============================================================================
  10. * Author: 陈风任 <491085389@qq.com>
  11. * Date: 2020-05-07
  12. */
  13. namespace app\api\model\v1;
  14. use think\Db;
  15. use think\Cache;
  16. use think\Config;
  17. /**
  18. * 微信小程序商城订单模型
  19. */
  20. load_trait('controller/Jump');
  21. class Shop extends UserBase
  22. {
  23. use \traits\controller\Jump;
  24. private $miniproInfo = [];
  25. //初始化
  26. protected function initialize()
  27. {
  28. // 需要调用`Model`的`initialize`方法
  29. parent::initialize();
  30. $this->times = getTime();
  31. $dataConf = tpSetting("OpenMinicode.conf_".self::$provider, [], self::$lang);
  32. $this->miniproInfo = json_decode($dataConf, true);
  33. }
  34. public function getCartTotalNum()
  35. {
  36. $cart_total_num = 0;
  37. if (!empty($this->users_id)){
  38. $cart_total_num = Db::name('shop_cart')->where(['users_id' => $this->users_id])->sum('product_num');
  39. }
  40. return $cart_total_num;
  41. }
  42. /*购物车操作--Start*/
  43. // 页面点击直接添加购物车
  44. public function ShopPageAddCart($post = [])
  45. {
  46. $post['product_id'] = intval($post['product_id']);
  47. $post['users_id'] = intval($post['users_id']);
  48. $post['product_num'] = intval($post['product_num']);
  49. // 查询条件
  50. $ArchivesWhere = [
  51. 'aid' => $post['product_id'],
  52. 'lang' => get_home_lang(),
  53. 'arcrank' => ['>=', 0]
  54. ];
  55. $count = Db::name('archives')->where($ArchivesWhere)->count();
  56. // 加入购物车处理
  57. if (!empty($count)) {
  58. // 查询条件
  59. $CartWhere = [
  60. 'users_id' => $post['users_id'],
  61. 'product_id' => $post['product_id'],
  62. 'lang' => get_home_lang()
  63. ];
  64. /*若开启多规格则执行*/
  65. $usersConfig = getUsersConfigData('shop');
  66. if (!empty($usersConfig['shop_open_spec'])) {
  67. $combiWhere = [
  68. 'aid' => $post['product_id'],
  69. 'spec_stock' => ['>', 0],
  70. ];
  71. //获取第一个有库存的规格
  72. $Field = 'spec_value_id, spec_stock';
  73. $SpecValue = Db::name('product_spec_value')->field($Field)->where($combiWhere)->order('value_id asc')->find();
  74. if (!empty($SpecValue)) {
  75. if ($SpecValue['spec_stock'] > 0) {
  76. $post['spec_value_id'] = $CartWhere['spec_value_id'] = $SpecValue['spec_value_id'];
  77. } else {
  78. $this->error('商品已售罄');
  79. }
  80. }
  81. }
  82. /* END */
  83. $ProductNum = Db::name('shop_cart')->field('product_num')->where($CartWhere)->getField('product_num');
  84. if (!empty($ProductNum)) {
  85. // 购物车内已有相同商品,进行数量更新。
  86. $ResultID = Db::name('shop_cart')->where($CartWhere)->setInc('product_num', $post['product_num']);
  87. } else {
  88. // 购物车内还未有相同商品,进行添加。
  89. $data = [
  90. 'users_id' => $post['users_id'],
  91. 'product_id' => $post['product_id'],
  92. 'product_num' => $post['product_num'],
  93. 'spec_value_id' => empty($post['spec_value_id']) || 'undefined' == $post['spec_value_id'] ? '' : $post['spec_value_id'],
  94. 'selected' => 1,
  95. 'lang' => get_home_lang(),
  96. 'add_time' => getTime(),
  97. 'update_time' => getTime()
  98. ];
  99. $ResultID = Db::name('shop_cart')->add($data);
  100. }
  101. if (!empty($ResultID)) {
  102. $cart_total_num = Db::name('shop_cart')->where(['users_id' => $post['users_id']])->sum('product_num');
  103. $this->success('加入成功','',['cart_total_num'=>$cart_total_num]);
  104. } else {
  105. $this->error('加入失败');
  106. }
  107. } else {
  108. $this->error('商品已下架');
  109. }
  110. }
  111. /*购物车操作--Start*/
  112. // 添加购物车
  113. public function ShopAddCart($post = [])
  114. {
  115. $post['product_id'] = intval($post['product_id']);
  116. $post['users_id'] = intval($post['users_id']);
  117. $post['product_num'] = intval($post['product_num']);
  118. // 查询条件
  119. $ArchivesWhere = [
  120. 'aid' => $post['product_id'],
  121. 'lang' => get_home_lang(),
  122. 'arcrank' => ['>=', 0]
  123. ];
  124. $count = Db::name('archives')->where($ArchivesWhere)->count();
  125. // 加入购物车处理
  126. if (!empty($count)) {
  127. // 查询条件
  128. $CartWhere = [
  129. 'users_id' => $post['users_id'],
  130. 'product_id' => $post['product_id'],
  131. 'lang' => get_home_lang()
  132. ];
  133. if (!empty($post['discount_active_id'])){
  134. $CartWhere['discount_active_id'] = $post['discount_active_id'];
  135. }else{
  136. $CartWhere['discount_active_id'] = 0;
  137. }
  138. /*若开启多规格则执行*/
  139. $usersConfig = getUsersConfigData('shop');
  140. if (!empty($post['spec_value_id']) && 'undefined' != $post['spec_value_id'] && !empty($usersConfig['shop_open_spec'])) {
  141. $CartWhere['spec_value_id'] = $post['spec_value_id'];
  142. }
  143. /* END */
  144. $ProductNum = Db::name('shop_cart')->field('product_num')->where($CartWhere)->getField('product_num');
  145. if (!empty($ProductNum)) {
  146. // 购物车内已有相同商品,进行数量更新。
  147. $ResultID = Db::name('shop_cart')->where($CartWhere)->setInc('product_num', $post['product_num']);
  148. } else {
  149. // 购物车内还未有相同商品,进行添加。
  150. $data = [
  151. 'users_id' => $post['users_id'],
  152. 'product_id' => $post['product_id'],
  153. 'product_num' => $post['product_num'],
  154. 'spec_value_id' => empty($post['spec_value_id']) || 'undefined' == $post['spec_value_id'] ? '' : $post['spec_value_id'],
  155. 'selected' => 1,
  156. 'lang' => get_home_lang(),
  157. 'add_time' => getTime(),
  158. 'update_time' => getTime(),
  159. 'discount_active_id' => !empty($CartWhere['discount_active_id']) ? $CartWhere['discount_active_id'] : 0
  160. ];
  161. $ResultID = Db::name('shop_cart')->add($data);
  162. }
  163. if (!empty($ResultID)) {
  164. $totalCart = Db::name('shop_cart')->where(['users_id' => $post['users_id']])->sum('product_num');
  165. $this->success('加入成功','',['cart_total_num'=>$totalCart]);
  166. } else {
  167. $this->error('加入失败');
  168. }
  169. } else {
  170. $this->error('商品已下架');
  171. }
  172. }
  173. // 删除购物车商品
  174. public function ShopCartDelete($param = [])
  175. {
  176. if (empty($param['users_id'])) $this->error('请先登录');
  177. if (empty($param['action'])) $this->error('数据错误,请重试');
  178. if ('[]' == $param['cart_id']) $this->error('选择要删除的商品');
  179. $where = [
  180. 'users_id' => intval($param['users_id']),
  181. 'cart_id' => ['IN', $param['cart_id']],
  182. ];
  183. $ResultID = Db::name('shop_cart')->where($where)->delete();
  184. if (!empty($ResultID)) {
  185. $totalCart = Db::name('shop_cart')->where(['users_id' => $param['users_id']])->sum('product_num');
  186. $this->success('操作成功','',['cart_total_num'=>$totalCart]);
  187. } else {
  188. $this->error('操作失败');
  189. }
  190. }
  191. // 购物车数据列表
  192. public function ShopCartList($users_id = null, $level_discount = 100, $level_id = 0)
  193. {
  194. $result = [];
  195. $result['cart_list'] = [];
  196. if (!empty($users_id)) {
  197. // 查询购物车数据
  198. $condition = [
  199. 'a.users_id' => $users_id,
  200. 'a.lang' => get_home_lang(),
  201. 'b.arcrank' => array('egt', 0)
  202. ];
  203. $field = 'a.*, b.aid, b.title, b.litpic, b.users_price, b.users_discount_type, b.stock_count, b.attrlist_id, c.spec_price, c.spec_stock';
  204. if ('v1.5.1' < getVersion()) {
  205. $field .= ',c.seckill_price, c.seckill_stock';
  206. }
  207. if ('v1.5.7' < getVersion()) {
  208. $field .= ',c.discount_price, c.discount_stock';
  209. }
  210. $ShopCart = Db::name("shop_cart")
  211. ->field($field)
  212. ->alias('a')
  213. ->join('__ARCHIVES__ b', 'a.product_id = b.aid', 'LEFT')
  214. ->join('__PRODUCT_SPEC_VALUE__ c', 'a.spec_value_id = c.spec_value_id and a.product_id = c.aid', 'LEFT')
  215. ->where($condition)
  216. ->order('a.selected desc, a.add_time desc')
  217. ->select();
  218. if (!empty($ShopCart)) {
  219. // 获取商城配置信息
  220. $ConfigData = getUsersConfigData('shop');
  221. // 会员折扣
  222. $users_discount = strval($level_discount) / strval(100);
  223. // 处理购物车数据
  224. $ShopCart = $this->OrderProductProcess($ShopCart, $ConfigData, $users_discount, $level_id);
  225. }
  226. $result['cart_list'] = $ShopCart;
  227. }
  228. $result['product'] = model('v1.Api')->getRecomProduct();
  229. return $result;
  230. }
  231. // 购物车数量增加
  232. public function ShopCartNumAdd($param = [])
  233. {
  234. if (empty($param['users_id'])) $this->error('请先登录');
  235. if (empty($param['action']) || empty($param['product_id'])) $this->error('数据错误,请重试');
  236. $where = [
  237. 'users_id' => intval($param['users_id']),
  238. 'product_id' => intval($param['product_id']),
  239. ];
  240. if (!empty($param['spec_value_id']) && 'undefined' != $param['spec_value_id']) {
  241. $where['spec_value_id'] = $param['spec_value_id'];
  242. }
  243. $ResultID = Db::name('shop_cart')->where($where)->setInc('product_num');
  244. if (!empty($ResultID)) {
  245. $cart_total_num = Db::name('shop_cart')->where('users_id',$param['users_id'])->sum('product_num');
  246. $this->success('操作成功','',['cart_total_num'=>$cart_total_num]);
  247. } else {
  248. $this->error('操作失败');
  249. }
  250. }
  251. // 购物车数量减少
  252. public function ShopCartNumLess($param = [])
  253. {
  254. if (empty($param['users_id'])) $this->error('请先登录');
  255. if (empty($param['action']) || empty($param['product_id'])) $this->error('数据错误,请重试');
  256. $where = [
  257. 'users_id' => intval($param['users_id']),
  258. 'product_id' => intval($param['product_id']),
  259. ];
  260. if (!empty($param['spec_value_id']) && 'undefined' != $param['spec_value_id']) {
  261. $where['spec_value_id'] = $param['spec_value_id'];
  262. }
  263. $product_num_tmp = Db::name('shop_cart')->where($where)->getField('product_num');
  264. if (!empty($product_num_tmp)) {
  265. if ($product_num_tmp > 1) {
  266. $ResultID = Db::name('shop_cart')->where($where)->setDec('product_num');
  267. if (!empty($ResultID)) {
  268. $cart_total_num = Db::name('shop_cart')->where('users_id',$param['users_id'])->sum('product_num');
  269. $this->success('操作成功','',['cart_total_num'=>$cart_total_num]);
  270. }
  271. } else {
  272. $this->error('数量至少一件!');
  273. }
  274. }
  275. $this->error('操作失败');
  276. }
  277. // 购物车商品更新是否选中
  278. public function ShopCartSelected($param = [])
  279. {
  280. if (empty($param['users_id'])) $this->error('请先登录');
  281. if (empty($param['action']) || empty($param['product_id'])) $this->error('数据错误,请重试');
  282. $where = [
  283. 'users_id' => intval($param['users_id']),
  284. 'product_id' => intval($param['product_id']),
  285. ];
  286. if (!empty($param['spec_value_id']) && 'undefined' != $param['spec_value_id']) {
  287. $where['spec_value_id'] = $param['spec_value_id'];
  288. }
  289. $update = [
  290. 'selected' => $param['selected'] == 1 ? 0 : 1,
  291. 'update_time' => getTime()
  292. ];
  293. $ResultID = Db::name('shop_cart')->where($where)->update($update);
  294. if (!empty($ResultID)) {
  295. $this->success('操作成功');
  296. } else {
  297. $this->error('操作失败');
  298. }
  299. }
  300. // 全选/反选
  301. public function ShopCartAllSelected($param = [])
  302. {
  303. if (empty($param['users_id'])) $this->error('请先登录');
  304. if (empty($param['action'])) $this->error('数据错误,请重试');
  305. $where = [
  306. 'users_id' => intval($param['users_id']),
  307. ];
  308. $update = [
  309. 'selected' => $param['all_selected'],
  310. 'update_time' => getTime()
  311. ];
  312. $ResultID = Db::name('shop_cart')->where($where)->update($update);
  313. if (!empty($ResultID)) {
  314. $this->success('操作成功');
  315. } else {
  316. $this->error('操作失败');
  317. }
  318. }
  319. /*购物车操作--END*/
  320. /*商城购物流程--Start*/
  321. // 立即购买
  322. public function ShopBuyNow($post = [])
  323. {
  324. // 查询条件
  325. $ArchivesWhere = [
  326. 'aid' => $post['product_id'],
  327. 'lang' => get_home_lang(),
  328. 'arcrank' => ['>=', 0]
  329. ];
  330. $count = Db::name('archives')->where($ArchivesWhere)->count();
  331. // 加入购物车处理
  332. if (!empty($count)) {
  333. // 对ID和订单号加密,拼装url路径
  334. $querydata = [
  335. 'product_id' => $post['product_id'],
  336. 'product_num' => $post['product_num'],
  337. 'active_time_id' => isset($post['active_time_id']) ? $post['active_time_id'] : 0,
  338. 'discount_active_id' => isset($post['discount_active_id']) ? $post['discount_active_id'] : 0,
  339. ];
  340. /*存在规格则执行*/
  341. if (!empty($post['spec_value_id']) && 'undefined' != $post['spec_value_id']) {
  342. $querydata['spec_value_id'] = $post['spec_value_id'];
  343. }
  344. /* END */
  345. // 先 json_encode 后 md5 加密信息
  346. $querystr = md5(json_encode($querydata));
  347. // 存入缓存,一天有效期
  348. Cache::set($querystr, $querydata, 86400);
  349. // 跳转链接
  350. if (1 == input('param.fenbao/d')) {
  351. $url = '?querystr=' . $querystr;
  352. } else {
  353. $url = '/pages/product_buy/index?querystr=' . $querystr;
  354. }
  355. $this->success('数据正确', $url, ['url'=>$url]);
  356. } else {
  357. $this->error('该商品不存在或已下架!');
  358. }
  359. }
  360. // 获取商品信息进行展示
  361. public function GetProductData($querystr = null, $users_id = null, $level_discount = 100, $users = [], $post = [])
  362. {
  363. if (empty($users_id)) $this->error('请先登录');
  364. /* 商品信息 */
  365. $CacheData = Cache::get($querystr);
  366. // 是否存在购买商品
  367. $list = $this->GetBuyOrderList($CacheData, $users_id, $post);
  368. if (empty($list)) $this->error('链接失效,请重新下单');
  369. //购物车下单
  370. if (empty($CacheData)) {
  371. $logistics_type_arr = get_arr_column($list, 'logistics_type');
  372. if (empty($post['deliveryShow']) && empty($post['verifyShow']) && in_array(1, $logistics_type_arr)) {
  373. $post['deliveryShow'] = 1;
  374. }
  375. }
  376. // 获取商城配置信息
  377. $ConfigData = getUsersConfigData('shop');
  378. // 会员折扣
  379. $users_discount = strval($level_discount) / strval(100);
  380. if (!empty($CacheData['active_time_id'])){
  381. //秒杀商品没有会员折扣
  382. $users_discount = 0;
  383. }
  384. /* 商品规格/折扣数据处理 */
  385. $list = $this->OrderProductProcess($list, $ConfigData, $users_discount, $users['level_id']);
  386. if (empty($list)) $this->error('商品库存不足或已过期!');
  387. /* END */
  388. /* 全局信息组装 */
  389. $GlobalInfo = $this->GetGlobalInfo($ConfigData, $CacheData);
  390. /* END */
  391. /* 商品数据整合处理 */
  392. foreach ($list as $key => $value) {
  393. // 合计金额、合计数量计算
  394. if ($value['users_price'] >= 0 && !empty($value['product_num'])) {
  395. // 计算单品小计
  396. $list[$key]['subtotal'] = unifyPriceHandle($value['users_price'] * $value['product_num']);
  397. // 计算合计金额
  398. $GlobalInfo['TotalAmount'] += $list[$key]['subtotal'];
  399. $GlobalInfo['TotalAmount'] = unifyPriceHandle($GlobalInfo['TotalAmount']);
  400. // 计算合计数量
  401. $GlobalInfo['TotalNumber'] += $value['product_num'];
  402. // 判断订单类型,目前逻辑:一个订单中,只要存在一个普通商品(实物商品,需要发货物流),则为普通订单
  403. // 0表示为普通订单,1表示为虚拟订单,虚拟订单无需发货物流,无需选择收货地址,无需计算运费
  404. if (empty($value['prom_type'])) $GlobalInfo['PromType'] = 0;
  405. }
  406. // 仅到店核销
  407. if ('2' === $value['logistics_type']) $GlobalInfo['onlyVerify'] = true;
  408. // 仅物流配送
  409. if ('1' === $value['logistics_type']) $GlobalInfo['onlyDelivery'] = true;
  410. // 物流配送 和 到店核销 都支持
  411. if ('1,2' === $value['logistics_type']) $GlobalInfo['allLogisticsType'] = true;
  412. }
  413. /* END */
  414. /* 默认地址 */
  415. $address = Db::name('shop_address')->where('users_id', $users_id)->order('is_default desc')->find();
  416. if (!empty($address)) {
  417. $address['region']['province'] = $this->GetRegionName($address['province']);
  418. $address['region']['city'] = $this->GetRegionName($address['city']);
  419. $address['region']['district'] = $this->GetRegionName($address['district']);
  420. $address['region']['detail'] = $address['address'];
  421. $address['address_all'] = $address['region']['province'] . $address['region']['city'] . $address['region']['district'] . $address['region']['detail'];
  422. if (!empty($GlobalInfo['shop_open_shipping'])) {
  423. /* 查询运费 */
  424. $where['province_id'] = $address['province'];
  425. $template_money = Db::name('shop_shipping_template')->where($where)->getField('template_money');
  426. if (0 == $template_money) {
  427. $where['province_id'] = 100000;
  428. $template_money = Db::name('shop_shipping_template')->where($where)->getField('template_money');
  429. }
  430. $address['template_money'] = $template_money;
  431. /* END */
  432. } else {
  433. $address['template_money'] = 0;
  434. }
  435. } else {
  436. $address['template_money'] = 0;
  437. }
  438. /* END */
  439. // 最终支付总金额
  440. if (!empty($post['deliveryShow']) && 1 === intval($post['deliveryShow'])) {
  441. // 订单总金额 + 运费金额
  442. $GlobalInfo['PayTotalAmount'] = unifyPriceHandle($GlobalInfo['TotalAmount'] + $address['template_money']);
  443. } else {
  444. $GlobalInfo['PayTotalAmount'] = unifyPriceHandle($GlobalInfo['TotalAmount']);
  445. }
  446. // 数据返回
  447. $ResultData = [
  448. 'users' => $users,
  449. 'address' => $address,
  450. 'global_info' => $GlobalInfo,
  451. 'product_data' => $list
  452. ];
  453. $ResultData['coupon_data'] = $this->getOrderCoupon($list,$users_id);
  454. $coupon_ids = get_arr_column($ResultData['coupon_data'],'coupon_id');
  455. $ResultData['unuse_coupon_data'] = $this->getUnuseOrderCoupon($coupon_ids,$users_id);
  456. $this->success('数据正确', null, $ResultData);
  457. }
  458. /**
  459. * 获取该订单可用优惠券
  460. */
  461. public function getOrderCoupon($product_data,$user_id)
  462. {
  463. $aids = [];
  464. $aid_price = 0;
  465. $totol_price = 0;
  466. foreach ($product_data as $k => $v){
  467. if (!empty($v['stop_buy']) && 1 == $v['stop_buy']){
  468. continue;
  469. }
  470. if (!in_array($v['aid'],$aids)){
  471. $aids[] = $v['aid'];
  472. $aid_price += $v['subtotal'];
  473. }
  474. $totol_price += $v['subtotal'];
  475. }
  476. $where['a.users_id'] = $user_id;
  477. $where['a.start_time'] = ['<=',getTime()];
  478. $where['a.end_time'] = ['>=',getTime()];
  479. $where['a.use_status'] = 0;
  480. $where['b.coupon_id'] = ['>',1];
  481. $use_data = [];
  482. //查出全部的没过期优惠券
  483. $data = Db::name('shop_coupon_use')
  484. ->alias('a')
  485. ->join('shop_coupon b','a.coupon_id = b.coupon_id','left')
  486. ->where($where)
  487. ->getAllWithIndex('use_id');
  488. $type_coupon_arr = [];
  489. if (!empty($data)){
  490. foreach ($data as $k => $v){
  491. if (1 == $v['coupon_form']){
  492. $v['coupon_form_name'] = '满减券';
  493. }
  494. $v['start_time'] = date('Y/m/d', $v['start_time']);
  495. $v['end_time'] = date('Y/m/d', $v['end_time']);
  496. switch ($v['coupon_type'])
  497. {
  498. case 2:
  499. $v['coupon_type_name'] = '指定商品';
  500. //指定商品
  501. if (!empty($v['product_id'])){
  502. $product_arr = explode(",",$v['product_id']);
  503. $in = 0;
  504. foreach ($aids as $m){
  505. if (in_array($m,$product_arr) && $aid_price >= $v['conditions_use']){
  506. //此优惠券可用
  507. $in = 1;
  508. break;
  509. }
  510. }
  511. if (!empty($in)){
  512. $use_data[] = $v;
  513. }
  514. }
  515. break;
  516. case 3:
  517. $v['coupon_type_name'] = '指定分类';
  518. //指定分类
  519. if (!empty($v['arctype_id'])){
  520. $arctype_arr = explode(",",$v['arctype_id']);
  521. $is_have = 0;
  522. foreach ($product_data as $key => $val){
  523. if (in_array($val['typeid'],$arctype_arr)){
  524. $is_have = 1;
  525. if (empty($v['goods_total_price'])){
  526. $v['goods_total_price'] = $val['subtotal'];
  527. }else{
  528. $v['goods_total_price'] += $val['subtotal'];
  529. }
  530. }
  531. }
  532. if (!empty($is_have)) $type_coupon_arr[] = $v;
  533. }
  534. break;
  535. default:
  536. $v['coupon_type_name'] = '全部商品';
  537. if ($totol_price >= $v['conditions_use']) {
  538. $use_data[] = $v;
  539. }
  540. break;
  541. }
  542. }
  543. if (!empty($type_coupon_arr)){
  544. foreach ($type_coupon_arr as $k => $v) {
  545. if ($v['goods_total_price'] >= $v['conditions_use']){
  546. unset($type_coupon_arr[$k]['goods_total_price']);
  547. $use_data[] = $v;
  548. }
  549. }
  550. }
  551. }
  552. return $use_data;
  553. }
  554. /**
  555. * 获取该订单不可用优惠券
  556. */
  557. public function getUnuseOrderCoupon($coupon_ids = [],$users_id)
  558. {
  559. $where['a.users_id'] = $users_id;
  560. $where['a.use_status'] = 0;
  561. $where['a.end_time'] = ['>=',getTime()];
  562. $where['b.coupon_id'] = ['not in',$coupon_ids];
  563. $unuse_data = [];
  564. //查出全部的优惠券
  565. $data = Db::name('shop_coupon_use')
  566. ->alias('a')
  567. ->join('shop_coupon b','a.coupon_id = b.coupon_id','left')
  568. ->where($where)
  569. ->getAllWithIndex('use_id');
  570. if (!empty($data)){
  571. foreach ($data as $k => $v){
  572. if (1 == $v['coupon_form']){
  573. $v['coupon_form_name'] = '满减券';
  574. }
  575. $v['start_time'] = date('Y/m/d', $v['start_time']);
  576. $v['end_time'] = date('Y/m/d', $v['end_time']);
  577. switch ($v['coupon_type']) {
  578. case '1':
  579. $v['coupon_type_name'] = '全部商品';
  580. break;
  581. case '2';
  582. $v['coupon_type_name'] = '指定商品';
  583. break;
  584. case '3';
  585. $v['coupon_type_name'] = '指定分类';
  586. break;
  587. }
  588. $unuse_data[] = $v;
  589. }
  590. }
  591. return $unuse_data;
  592. }
  593. // 订单结算
  594. public function ShopOrderPay($post = [], $level_discount = 100, $level_id = 0, $usersData = [])
  595. {
  596. // 基础判断
  597. if (empty($post['users_id'])) $this->error('请先登录');
  598. if (1 != $post['prom_type']){
  599. if (empty($post['addr_id']) || $post['addr_id'] == 'undefined') $this->error('请添加收货地址');
  600. }
  601. if (empty($post['pay_type'])) $this->error('请选择支付方式');
  602. // 获取商城配置信息
  603. $ConfigData = getUsersConfigData('shop');
  604. // 会员折扣
  605. $users_discount = strval($level_discount) / strval(100);
  606. if (isset($post['order_source']) && 20 == $post['order_source']) $users_discount = 0;
  607. // 获取下单的商品数据
  608. $CacheData = Cache::get($post['querystr']);
  609. $list = $this->GetBuyOrderList($CacheData, $post['users_id'], $post);
  610. if (empty($list)) $this->error('链接失效,请重新下单');
  611. // 订单商品数据处理
  612. $list = $this->OrderProductProcess($list, $ConfigData, $users_discount, $level_id);
  613. if (empty($list)) $this->error('商品库存不足或已过期');
  614. // 组装订单流程所需全局信息
  615. $GlobalInfo = $this->GetGlobalInfo($ConfigData, $CacheData);
  616. /* 商品数据整合处理 */
  617. foreach ($list as $key => $value) {
  618. /* 合计金额、合计数量计算 */
  619. if ($value['users_price'] >= 0 && !empty($value['product_num'])) {
  620. // 计算合计金额
  621. $GlobalInfo['TotalAmount'] += unifyPriceHandle($value['users_price'] * $value['product_num']);
  622. $GlobalInfo['TotalAmount'] = unifyPriceHandle($GlobalInfo['TotalAmount']);
  623. // 计算合计数量
  624. $GlobalInfo['TotalNumber'] += $value['product_num'];
  625. // 判断订单类型,目前逻辑:一个订单中,只要存在一个普通商品(实物商品,需要发货物流),则为普通订单
  626. // 0表示为普通订单,1表示为虚拟订单,虚拟订单无需发货物流,无需选择收货地址,无需计算运费
  627. if (empty($value['prom_type'])) $GlobalInfo['PromType'] = 0;
  628. }
  629. /* END */
  630. }
  631. /* END */
  632. $AddrData = [];
  633. if (!empty($post['deliveryShow']) && 1 === intval($post['deliveryShow'])) {
  634. // 获取用户下单时提交的收货地址及运费
  635. $AddrData = $this->GetUsersAddrData($post, $GlobalInfo['PromType']);
  636. // 订单总金额 + 运费金额
  637. $GlobalInfo['PayTotalAmount'] = unifyPriceHandle($GlobalInfo['TotalAmount'] + $AddrData['shipping_fee']);
  638. } else {
  639. $GlobalInfo['PayTotalAmount'] = unifyPriceHandle($GlobalInfo['TotalAmount']);
  640. }
  641. // 应付总金额
  642. $PayAmount = $GlobalInfo['PayTotalAmount'];
  643. // 使用优惠券
  644. if (!empty($post['coupon_id'])){
  645. $coupon_where = [
  646. 'a.coupon_id'=>$post['coupon_id'],
  647. 'a.use_status'=>0,
  648. 'a.users_id' => $post['users_id'],
  649. ];
  650. $coupon_where['a.start_time'] = ['<=',getTime()];
  651. $coupon_where['a.end_time'] = ['>=',getTime()];
  652. $coupon_info = Db::name('shop_coupon_use')
  653. ->alias('a')
  654. ->join('shop_coupon b','a.coupon_id = b.coupon_id','left')
  655. ->where($coupon_where)
  656. ->find();
  657. if (!empty($coupon_info)){
  658. $PayAmount = $PayAmount-$coupon_info['coupon_price'] < 0 ? 0 : $PayAmount-$coupon_info['coupon_price'];
  659. }
  660. }
  661. if (2 == $post['pay_type']) {
  662. $UsersMoney = Db::name('users')->where('users_id', $post['users_id'])->getField('users_money');
  663. if ($GlobalInfo['PayTotalAmount'] > $UsersMoney) $this->error('您的余额不足,支付失败');
  664. }
  665. // 添加到订单主表
  666. $time = getTime();
  667. $OrderData = [
  668. 'order_code' => date('Ymd') . $time . rand(10, 100),
  669. 'users_id' => $post['users_id'],
  670. 'order_status' => 0, // 订单未付款
  671. 'add_time' => $time,
  672. 'payment_method' => 0,
  673. 'pay_time' => 0,
  674. 'pay_name' => 'wechat',
  675. 'wechat_pay_type' => 'WeChatInternal',
  676. 'order_terminal' => 3,
  677. 'pay_details' => '',
  678. 'order_total_amount' => $GlobalInfo['PayTotalAmount'],
  679. 'order_amount' => $PayAmount,
  680. 'order_total_num' => $GlobalInfo['TotalNumber'],
  681. 'prom_type' => $GlobalInfo['PromType'],
  682. 'order_source' => isset($post['order_source']) ? $post['order_source'] : 10,
  683. 'order_source_id' => isset($post['order_source_id']) ? $post['order_source_id'] : 0,
  684. 'virtual_delivery' => '',
  685. 'admin_note' => '',
  686. 'user_note' => $post['remark'],
  687. 'lang' => get_home_lang()
  688. ];
  689. if (!empty($coupon_info)) {
  690. $OrderData['coupon_id'] = $coupon_info['coupon_id'];
  691. $OrderData['use_id'] = $coupon_info['use_id'];
  692. $OrderData['coupon_price'] = $coupon_info['coupon_price'];
  693. }
  694. // 存在收货地址则追加合并到主表数组
  695. if (!empty($AddrData)) $OrderData = array_merge($OrderData, $AddrData);
  696. // 订单提交处理 -- 其他逻辑公共调用方法,部分逻辑改动不适合直接修改原文件时请在此方法做处理和兼容
  697. $OrderData = model('ShopPublicHandle')->orderSubmitPublicHandle($OrderData, $this->usersConfig, $this->users_id, $post, $list);
  698. // 抖音支付时更新订单支付类型
  699. if (9 === intval($post['pay_type'])) {
  700. $OrderData['pay_name'] = 'tikTokPay';
  701. $OrderData['wechat_pay_type'] = '';
  702. }
  703. // 添加订单及后续处理
  704. $OrderId = Db::name('shop_order')->add($OrderData);
  705. if (!empty($OrderId)) {
  706. $OrderData['order_id'] = $OrderId;
  707. // 订单创建后续处理 -- 其他逻辑公共调用方法,部分逻辑改动不适合直接修改原文件时请在此方法做处理和兼容
  708. $OrderData = model('ShopPublicHandle')->orderCreatePublicHandle($OrderData, $this->usersConfig, $this->users_id, $post, $list);
  709. //锁定优惠券
  710. if (!empty($coupon_info)){
  711. $coupon_update = [
  712. 'coupon_id'=>$post['coupon_id'],
  713. 'use_status'=> 0,
  714. 'users_id' => $post['users_id'],
  715. ];
  716. Db::name('shop_coupon_use')->where($coupon_update)->update(['use_status'=> 1,'use_time'=>getTime(),'update_time'=>getTime()]);
  717. }
  718. $cart_ids = $UpSpecValue = [];
  719. $contains_virtual = 1;//是否包含虚拟产品
  720. foreach ($list as $key => $value) {
  721. $attr_value = $attr_value_new = $spec_value = '';
  722. // 旧商品属性处理
  723. $attr_value = $this->ProductAttrProcessing($value);
  724. // 新商品属性处理
  725. $attr_value_new = $this->ProductNewAttrProcessing($value);
  726. // 商品规格处理
  727. $spec_value = $this->ProductSpecProcessing($value);
  728. // 规格及属性
  729. $ParamData = [
  730. // 商品属性
  731. 'attr_value' => htmlspecialchars($attr_value),
  732. // 商品属性
  733. 'attr_value_new' => htmlspecialchars($attr_value_new),
  734. // 商品规格
  735. 'spec_value' => htmlspecialchars($spec_value),
  736. // 商品规格值ID
  737. 'spec_value_id' => $value['spec_value_id'],
  738. // 对应规格值ID的唯一标识ID,数据表主键ID
  739. 'value_id' => $value['value_id'],
  740. // 后续添加
  741. ];
  742. // 订单副表添加数组
  743. $OrderDetailsData[] = [
  744. 'order_id' => $OrderId,
  745. 'users_id' => $post['users_id'],
  746. 'product_id' => $value['aid'],
  747. 'product_name' => $value['title'],
  748. 'num' => $value['product_num'],
  749. 'data' => serialize($ParamData),
  750. 'product_price' => $value['users_price'],
  751. 'prom_type' => $value['prom_type'],
  752. 'litpic' => $value['litpic'],
  753. 'add_time' => $time,
  754. 'lang' => get_home_lang()
  755. ];
  756. // 处理购物车ID
  757. if (empty($GlobalInfo['submit_order_type'])) {
  758. array_push($cart_ids, $value['cart_id']);
  759. }
  760. // 商品库存处理
  761. $UpSpecValue[] = [
  762. 'aid' => $value['aid'],
  763. 'value_id' => $value['value_id'],
  764. 'quantity' => $value['product_num'],
  765. 'spec_value_id' => $value['spec_value_id'],
  766. 'order_source' => isset($post['order_source']) ? $post['order_source'] : 10,
  767. 'order_source_id' => isset($post['order_source_id']) ? $post['order_source_id'] : 0,
  768. ];
  769. if (in_array($value['prom_type'],[1,2,3])){
  770. $contains_virtual = 2;
  771. }
  772. }
  773. if (2 == $contains_virtual) {
  774. Db::name('shop_order')->where('order_id',$OrderId)->update(['contains_virtual'=>$contains_virtual]);
  775. }
  776. $DetailsId = Db::name('shop_order_details')->insertAll($OrderDetailsData);
  777. if (!empty($OrderId) && !empty($DetailsId)) {
  778. // 清理购物车中已下单的ID
  779. if (!empty($cart_ids)) Db::name('shop_cart')->where('cart_id', 'IN', $cart_ids)->delete();
  780. // 商品库存、销量处理
  781. $this->ProductStockProcessing($UpSpecValue);
  782. // 添加订单操作记录
  783. AddOrderAction($OrderId, $post['users_id']);
  784. // 微信支付
  785. if (1 === intval($post['pay_type'])) {
  786. $weChatPay = $this->GetWechatAppletsPay($post['openid'], $OrderData['order_code'], $OrderData['order_amount']);
  787. $result = [
  788. 'WeChatPay' => $weChatPay,
  789. 'OrderData' => [
  790. 'order_id' => $OrderId,
  791. 'order_code' => $OrderData['order_code']
  792. ]
  793. ];
  794. $result['tmplData'] = [];
  795. // 返回提示
  796. $this->success('正在支付', null, $result);
  797. }
  798. // 余额支付
  799. else if (2 === intval($post['pay_type'])) {
  800. $pay_details = [
  801. 'unified_id' => $OrderId,
  802. 'unified_number' => $OrderData['order_code'],
  803. 'payment_amount' => $OrderData['order_amount'],
  804. 'payment_type' => '余额支付'
  805. ];
  806. $UpOrderData = [
  807. 'order_status' => 1,
  808. 'pay_name' => 'balance',
  809. 'wechat_pay_type' => '',
  810. 'pay_details' => serialize($pay_details),
  811. 'pay_time' => getTime(),
  812. 'update_time' => getTime()
  813. ];
  814. $ReturnID = Db::name('shop_order')->where('order_id', $OrderId)->update($UpOrderData);
  815. if (!empty($ReturnID)) {
  816. $UsersData = [
  817. 'users_money' => $UsersMoney - $OrderData['order_amount'],
  818. 'update_time' => getTime()
  819. ];
  820. $users_id = Db::name('users')->where('users_id', $post['users_id'])->update($UsersData);
  821. if (!empty($users_id)) {
  822. // 添加会员余额记录
  823. $getParam = [
  824. 'users_money' => $UsersMoney,
  825. 'users_id' => $post['users_id']
  826. ];
  827. UsersMoneyAction($OrderData['order_code'], $getParam, $OrderData['order_amount'], '订单支付');
  828. // 添加订单操作记录
  829. AddOrderAction($OrderId, $post['users_id'], 0, 1, 0, 1, '支付成功!', '会员使用余额完成支付!');
  830. // 虚拟自动发货
  831. $ShopModel = new \app\user\model\Pay();
  832. $Where = [
  833. 'lang' => get_home_lang(),
  834. 'users_id' => $post['users_id'],
  835. 'order_id' => $OrderId
  836. ];
  837. $ShopModel->afterVirtualProductPay($Where);
  838. // 统计销售额
  839. eyou_statistics_data(2);
  840. eyou_statistics_data(3, $OrderData['order_amount']);
  841. $result['tmplData'] = [];
  842. // 邮箱发送
  843. $result['email'] = GetEamilSendData(tpCache('smtp'), $usersData, $OrderData, 1, 'balance');
  844. // 短信发送
  845. $result['mobile'] = GetMobileSendData(tpCache('sms'), $usersData, $OrderData, 1, 'balance');
  846. // 发送站内信给后台
  847. $OrderData['pay_method'] = '余额支付';
  848. SendNotifyMessage($OrderData, 5, 1, 0);
  849. // 返回数据
  850. $result['OrderData'] = $OrderData;
  851. $this->success('支付完成', '/pages/order/index', $result);
  852. }
  853. }
  854. }
  855. // 抖音支付
  856. else if (9 === intval($post['pay_type'])) {
  857. $tikTokPay = model('TikTok')->getTikTokAppletsPay($OrderId, $OrderData['order_code'], $OrderData['order_amount'], $this->usersConfig['order_unpay_close_time']);
  858. $result = [
  859. 'tikTokPay' => $tikTokPay,
  860. 'OrderData' => [
  861. 'order_id' => $OrderId,
  862. 'order_code' => $OrderData['order_code']
  863. ]
  864. ];
  865. // 已开启的微信订阅消息模板
  866. // $where = [
  867. // 'is_open' => 1,
  868. // 'send_scene' => ['IN', [7]],
  869. // 'template_code' => ['GT', 0],
  870. // ];
  871. // $tmplData = Db::name('applets_template')->where($where)->order('send_scene asc')->getAllWithIndex('template_id');
  872. // $result['tmplData'] = $tmplData;
  873. $result['tmplData'] = [];
  874. // 返回提示
  875. $this->success('正在支付', null, $result);
  876. }
  877. } else if (!empty($OrderId) && empty($DetailsId)) {
  878. // 订单详情添加失败则删除已添加的订单主表数据
  879. Db::name('shop_order')->delete($OrderId);
  880. $this->error('订单生成失败,商品数据有误!');
  881. }
  882. }
  883. $this->error('订单生成失败,商品数据有误!');
  884. }
  885. //生成核销码
  886. public function create_verify_code($length = 12)
  887. {
  888. $chars = "0123456789";
  889. $char_len = strlen($chars);
  890. $verify_code = '';
  891. for ($i = 0; $i < $length; $i++) {
  892. $loop = mt_rand(0, ($char_len - 1));
  893. $verify_code .= $chars[$loop];
  894. }
  895. $is_have = Db::name('shop_order_verify')->where('verify_code',$verify_code)->count();
  896. if (!empty($is_have)){
  897. $verify_code = $this->create_verify_code(12);
  898. }
  899. return $verify_code;
  900. }
  901. // 微信小程序支付后续处理
  902. public function WechatAppletsPayDealWith($PostData = [], $notify = false)
  903. {
  904. $OpenID = !empty($PostData['openid']) ? $PostData['openid'] : '';
  905. $UsersID = !empty($PostData['users_id']) ? $PostData['users_id'] : '';
  906. $OrderID = $PostData['order_id'];
  907. $OrderCode = $PostData['order_code'];
  908. if (!empty($OrderID) && !empty($OrderCode)) {
  909. /* 查询本站订单状态 */
  910. $where = [
  911. 'users_id' => $UsersID,
  912. 'order_id' => $OrderID,
  913. 'order_code' => $OrderCode,
  914. ];
  915. $order = Db::name('shop_order')->where($where)->find();
  916. if (empty($order)) {
  917. $this->error('无效订单!');
  918. } else if (0 < $order['order_status']) {
  919. // 订单已支付
  920. if ($notify === true) { // 异步
  921. return [
  922. 'code' => 1,
  923. 'msg' => 'ok',
  924. ];
  925. }
  926. else { // 同步
  927. $usersData = Db::name('users')->where('users_id', $UsersID)->find();
  928. // 邮箱发送
  929. $resultData['email'] = GetEamilSendData(tpCache('smtp'), $usersData, $order, 1, 'wechat');
  930. // 短信发送
  931. $resultData['mobile'] = GetMobileSendData(tpCache('sms'), $usersData, $order, 1, 'wechat');
  932. $this->success('支付完成', '/pages/order/index', $resultData);
  933. }
  934. }
  935. // 当前时间戳
  936. $time = getTime();
  937. // 当前时间戳 + OpenID 经 MD5加密
  938. $nonceStr = md5($time . $OpenID);
  939. // 调用支付接口参数
  940. $params = [
  941. 'appid' => $this->miniproInfo['appid'],
  942. 'mch_id' => $this->miniproInfo['mchid'],
  943. 'nonce_str' => $nonceStr,
  944. 'out_trade_no' => $OrderCode
  945. ];
  946. // 生成参数签名
  947. $params['sign'] = $this->ParamsSign($params, $this->miniproInfo['apikey']);
  948. // 生成参数XML格式
  949. $ParamsXml = $this->ParamsXml($params);
  950. // 调用接口返回数据
  951. $url = 'https://api.mch.weixin.qq.com/pay/orderquery';
  952. $result = $this->HttpsPost($url, $ParamsXml);
  953. // 解析XML格式
  954. $ResultData = $this->ResultXml($result);
  955. // 订单是否存在
  956. if (!empty($ResultData) && 'SUCCESS' == $ResultData['return_code'] && 'OK' == $ResultData['return_msg']) {
  957. // if ('NOTPAY' == $ResultData['trade_state'] && !empty($ResultData['trade_state_desc'])) {
  958. // // 订单未支付
  959. // $this->error($ResultData['trade_state_desc']);
  960. // }
  961. if ('SUCCESS' == $ResultData['trade_state']) {
  962. // 订单已支付,处理订单流程
  963. $OrderWhere = [
  964. 'order_id' => $OrderID,
  965. 'users_id' => $order['users_id']
  966. ];
  967. $OrderData = [
  968. 'order_status' => 1,
  969. 'pay_details' => serialize($ResultData),
  970. 'pay_time' => getTime(),
  971. 'update_time' => getTime()
  972. ];
  973. $ResultID = Db::name('shop_order')->where($OrderWhere)->update($OrderData);
  974. if (!empty($ResultID)) {
  975. // 添加订单操作记录
  976. AddOrderAction($OrderID, $order['users_id'], 0, 1, 0, 1, '支付成功', '会员使用微信小程序完成支付');
  977. // 虚拟自动发货
  978. $ShopModel = new \app\user\model\Pay();
  979. $Where = [
  980. 'lang' => get_home_lang(),
  981. 'users_id' => $UsersID,
  982. 'order_id' => $OrderID
  983. ];
  984. $ShopModel->afterVirtualProductPay($Where);
  985. // 站内信通知
  986. $order['pay_method'] = '微信支付';
  987. SendNotifyMessage($order, 5, 1, 0);
  988. // 添加会员积分记录
  989. $where = [
  990. 'users_id' => $UsersID,
  991. 'order_id' => $OrderID
  992. ];
  993. $data = Db::name('shop_order_details')->where($where)->getField('data');
  994. $data = !empty($data) ? unserialize($data) : [];
  995. $pointsGoodsBuyField = !empty($data['pointsGoodsBuyField']) ? json_decode($data['pointsGoodsBuyField'], true) : [];
  996. if (!empty($pointsGoodsBuyField['goodsTotalPoints'])) {
  997. $insert = [
  998. 'type' => 11, // 积分商城订单支付
  999. 'users_id' => $UsersID,
  1000. 'score' => $pointsGoodsBuyField['goodsTotalPoints'],
  1001. 'info' => '积分商城订单支付',
  1002. 'remark' => '积分商城订单支付',
  1003. ];
  1004. addConsumObtainScores($insert, 1, false);
  1005. }
  1006. // 订单支付完成
  1007. if ($notify === true) { // 异步
  1008. return [
  1009. 'code' => 1,
  1010. 'msg' => 'ok',
  1011. ];
  1012. }
  1013. else {// 同步
  1014. // 统计销售额
  1015. eyou_statistics_data(2);
  1016. eyou_statistics_data(3, $order['order_amount']);
  1017. $usersData = Db::name('users')->where('users_id', $UsersID)->find();
  1018. // 邮箱发送
  1019. $resultData['email'] = GetEamilSendData(tpCache('smtp'), $usersData, $order, 1, 'wechat');
  1020. // 短信发送
  1021. $resultData['mobile'] = GetMobileSendData(tpCache('sms'), $usersData, $order, 1, 'wechat');
  1022. $this->success('支付完成', '/pages/order/index', $resultData);
  1023. }
  1024. }
  1025. }
  1026. }
  1027. }
  1028. }
  1029. // 用于订单列表和订单详情页直接支付
  1030. public function OrderDirectPay($post = [])
  1031. {
  1032. $where = [
  1033. 'users_id' => $post['users_id'],
  1034. 'order_id' => $post['order_id'],
  1035. 'order_code' => $post['order_code']
  1036. ];
  1037. $field = 'order_status, order_amount';
  1038. $Result = Db::name('shop_order')->where($where)->field($field)->find();
  1039. if (!empty($Result)) {
  1040. if (0 == $Result['order_status']) {
  1041. $Data = $this->GetWechatAppletsPay($post['openid'], $post['order_code'], $Result['order_amount']);
  1042. $ResultData = [
  1043. 'WeChatPay' => $Data,
  1044. 'OrderData' => [
  1045. 'order_id' => $post['order_id'],
  1046. 'order_code' => $post['order_code']
  1047. ]
  1048. ];
  1049. $url = '/pages/order/index';
  1050. $this->success('正在支付', $url, $ResultData);
  1051. } else if (in_array($Result['order_status'], [1, 2, 3])) {
  1052. $this->success('订单已支付');
  1053. } else if ($Result['order_status'] == 4) {
  1054. $this->success('订单已过期');
  1055. } else if ($Result['order_status'] == -1) {
  1056. $this->success('订单已关闭');
  1057. }
  1058. }
  1059. $this->error('订单不存在');
  1060. }
  1061. // 微信小程序支付
  1062. public function GetWechatAppletsPay($OpenID = null, $out_trade_no = null, $total_fee = null, $notify_url = '')
  1063. {
  1064. $notify_url = !empty($notify_url) ? $notify_url : url('api/v1.Api/wxpay_notify', [], true, true, 1, 1);
  1065. // 当前时间戳
  1066. $time = time();
  1067. // 当前时间戳 + OpenID 经 MD5加密
  1068. $nonceStr = md5($time . $OpenID);
  1069. // 调用支付接口参数
  1070. $params = [
  1071. 'appid' => $this->miniproInfo['appid'],
  1072. 'attach' => "微信小程序支付",
  1073. 'body' => "商品支付",
  1074. 'mch_id' => $this->miniproInfo['mchid'],
  1075. 'nonce_str' => $nonceStr,
  1076. 'notify_url' => $notify_url,
  1077. 'openid' => $OpenID,
  1078. 'out_trade_no' => $out_trade_no,
  1079. 'spbill_create_ip' => $this->GetClientIP(),
  1080. 'total_fee' => strval($total_fee * 100),
  1081. 'trade_type' => 'JSAPI'
  1082. ];
  1083. // 生成参数签名
  1084. $params['sign'] = $this->ParamsSign($params, $this->miniproInfo['apikey']);
  1085. // 生成参数XML格式
  1086. $ParamsXml = $this->ParamsXml($params);
  1087. // 调用接口返回数据
  1088. $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
  1089. $result = $this->HttpsPost($url, $ParamsXml);
  1090. // 解析XML格式
  1091. $ResultData = $this->ResultXml($result);
  1092. // 数据返回
  1093. if ($ResultData['return_code'] == 'SUCCESS' && $ResultData['return_msg'] == 'OK') {
  1094. // 返回支付所需参数
  1095. $ReturnData = [
  1096. 'prepay_id' => $ResultData['prepay_id'],
  1097. 'nonceStr' => $nonceStr,
  1098. 'timeStamp' => strval($time),
  1099. 'return_code' => $ResultData['return_code']
  1100. ];
  1101. // 生成支付所需的签名
  1102. $ReturnData['paySign'] = $this->PaySign($this->miniproInfo['appid'], $params['nonce_str'], $ResultData['prepay_id'], $time);
  1103. return $ReturnData;
  1104. } else if ($ResultData['return_code'] == 'FAIL') {
  1105. if ($ResultData['return_msg'] == '签名错误') {
  1106. $ResultData['return_msg'] = '小程序支付配置不正确!';
  1107. }
  1108. return $ResultData;
  1109. } else {
  1110. return $ResultData;
  1111. }
  1112. }
  1113. private function ParamsSign($values, $apikey)
  1114. {
  1115. //签名步骤一:按字典序排序参数
  1116. ksort($values);
  1117. $string = $this->ParamsUrl($values);
  1118. //签名步骤二:在string后加入KEY
  1119. $string = $string . '&key=' . $apikey;
  1120. //签名步骤三:MD5加密
  1121. $string = md5($string);
  1122. //签名步骤四:所有字符转为大写
  1123. $result = strtoupper($string);
  1124. return $result;
  1125. }
  1126. private function ParamsUrl($values)
  1127. {
  1128. $Url = '';
  1129. foreach ($values as $k => $v) {
  1130. if ($k != 'sign' && $v != '' && !is_array($v)) {
  1131. $Url .= $k . '=' . $v . '&';
  1132. }
  1133. }
  1134. return trim($Url, '&');
  1135. }
  1136. private function ParamsXml($values)
  1137. {
  1138. if (!is_array($values)
  1139. || count($values) <= 0
  1140. ) {
  1141. return false;
  1142. }
  1143. $xml = "<xml>";
  1144. foreach ($values as $key => $val) {
  1145. if (is_numeric($val)) {
  1146. $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
  1147. } else {
  1148. $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
  1149. }
  1150. }
  1151. $xml .= "</xml>";
  1152. return $xml;
  1153. }
  1154. private function ResultXml($xml)
  1155. {
  1156. // 禁止引用外部xml实体
  1157. @libxml_disable_entity_loader(true);
  1158. return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  1159. }
  1160. private function GetClientIP()
  1161. {
  1162. if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
  1163. $ip = getenv('HTTP_CLIENT_IP');
  1164. } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
  1165. $ip = getenv('HTTP_X_FORWARDED_FOR');
  1166. } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
  1167. $ip = getenv('REMOTE_ADDR');
  1168. } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
  1169. $ip = $_SERVER['REMOTE_ADDR'];
  1170. }
  1171. return preg_match('/[\d\.]{7,15}/', $ip, $matches) ? $matches [0] : '';
  1172. }
  1173. private function HttpsPost($url, $data)
  1174. {
  1175. $result = httpRequest($url, 'POST', $data);
  1176. return $result;
  1177. $ch = curl_init();
  1178. curl_setopt($ch, CURLOPT_URL, $url);
  1179. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
  1180. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  1181. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  1182. // curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 );
  1183. curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
  1184. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  1185. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  1186. $result = curl_exec($ch);
  1187. if (curl_errno($ch)) {
  1188. return 'Errno: ' . curl_error($ch);
  1189. }
  1190. curl_close($ch);
  1191. return $result;
  1192. }
  1193. private function PaySign($appid, $nonceStr, $prepay_id, $timeStamp)
  1194. {
  1195. $data = [
  1196. 'appId' => $appid,
  1197. 'nonceStr' => $nonceStr,
  1198. 'package' => 'prepay_id=' . $prepay_id,
  1199. 'signType' => 'MD5',
  1200. 'timeStamp' => $timeStamp,
  1201. ];
  1202. // 签名步骤一:按字典序排序参数
  1203. ksort($data);
  1204. $string = $this->ParamsUrl($data);
  1205. // 签名步骤二:在string后加入KEY
  1206. $string = $string . '&key=' . $this->miniproInfo['apikey'];
  1207. // 签名步骤三:MD5加密
  1208. $string = md5($string);
  1209. // 签名步骤四:所有字符转为大写
  1210. $result = strtoupper($string);
  1211. return $result;
  1212. }
  1213. // 扣除商品库存
  1214. private function ProductStockProcessing($SpecValue = [])
  1215. {
  1216. if (!empty($SpecValue)) {
  1217. $SpecUpData = []; // 有规格
  1218. $ArcUpData = []; // 无规格
  1219. foreach ($SpecValue as $key => $value) {
  1220. if (!empty($value['value_id'])) {
  1221. if (!empty($value['order_source']) && $value['order_source'] == 20){
  1222. //秒杀订单
  1223. $SpecUpData[] = [
  1224. 'value_id' => $value['value_id'],
  1225. 'seckill_stock' => Db::raw('seckill_stock-' . ($value['quantity'])),
  1226. 'seckill_sales_num' => Db::raw('seckill_sales_num+' . ($value['quantity'])),
  1227. ];
  1228. }else{
  1229. //普通订单
  1230. $SpecUpData[] = [
  1231. 'value_id' => $value['value_id'],
  1232. 'spec_stock' => Db::raw('spec_stock-' . ($value['quantity'])),
  1233. 'spec_sales_num' => Db::raw('spec_sales_num+' . ($value['quantity'])),
  1234. ];
  1235. $ArcUpData[] = [
  1236. 'aid' => $value['aid'],
  1237. 'stock_count' => Db::raw('stock_count-' . ($value['quantity'])),
  1238. 'sales_num' => Db::raw('sales_num+' . ($value['quantity'])),
  1239. 'sales_all' => Db::raw('sales_all+' . ($value['quantity'])),
  1240. ];
  1241. }
  1242. } else {
  1243. if ($value['order_source'] != 20){
  1244. //普通订单
  1245. $ArcUpData[] = [
  1246. 'aid' => $value['aid'],
  1247. 'stock_count' => Db::raw('stock_count-' . ($value['quantity'])),
  1248. 'sales_num' => Db::raw('sales_num+' . ($value['quantity'])),
  1249. 'sales_all' => Db::raw('sales_all+' . ($value['quantity'])),
  1250. ];
  1251. }
  1252. }
  1253. //秒杀订单无论单规格还是多规格都要更改sharp_goods的库存和销量
  1254. if (!empty($value['order_source']) && $value['order_source'] == 20){
  1255. $SharpUpData = [
  1256. 'aid' => $value['aid'],
  1257. 'seckill_stock' => Db::raw('seckill_stock-' . ($value['quantity'])),
  1258. 'sales' => Db::raw('sales+' . ($value['quantity']))
  1259. ];
  1260. Db::name('sharp_goods')->where('aid',$value['aid'])->update($SharpUpData);
  1261. Db::name('sharp_active_goods')
  1262. ->where(['active_time_id'=>$value['order_source_id'],'aid'=> $value['aid']])
  1263. ->update(['sales_actual'=>Db::raw('sales_actual+' . ($value['quantity']))]);
  1264. }
  1265. }
  1266. // 更新规格库存销量
  1267. if (!empty($SpecUpData)) {
  1268. $ProductSpecValueModel = new \app\user\model\ProductSpecValue();
  1269. $ProductSpecValueModel->saveAll($SpecUpData);
  1270. }
  1271. // 更新商品库存销量
  1272. if (!empty($ArcUpData)) {
  1273. $ArchivesModel = new \app\user\model\Archives();
  1274. $ArchivesModel->saveAll($ArcUpData);
  1275. }
  1276. }
  1277. }
  1278. // 获取下单的商品数据
  1279. private function GetBuyOrderList($CacheData = [], $users_id = null, $post = [])
  1280. {
  1281. $list = [];
  1282. if (!empty($CacheData)) {
  1283. // 立即购买下单
  1284. $where['a.aid'] = $CacheData['product_id'];
  1285. if (!empty($CacheData['spec_value_id'])) $where['b.spec_value_id'] = $CacheData['spec_value_id'];
  1286. $field = 'a.aid, a.typeid, a.title, a.litpic, a.users_price, a.users_discount_type, a.stock_count, a.prom_type, a.attrlist_id, a.logistics_type, b.value_id, b.aid as product_id, b.spec_value_id, b.spec_price, b.spec_stock';
  1287. if ('v1.5.1' < getVersion()) {
  1288. $field .= ',b.seckill_price, b.seckill_stock';
  1289. }
  1290. if ('v1.5.7' < getVersion()) {
  1291. $field .= ',b.discount_price, b.discount_stock';
  1292. }
  1293. $list = Db::name('archives')->alias('a')->field($field)
  1294. ->join('__PRODUCT_SPEC_VALUE__ b', 'a.aid = b.aid', 'LEFT')
  1295. ->where($where)
  1296. ->limit('0, 1')
  1297. ->select();
  1298. $list[0]['product_num'] = $CacheData['product_num'];
  1299. if (isset($CacheData['active_time_id']) && !empty($CacheData['active_time_id'])){
  1300. $list[0]['active_time_id'] = $CacheData['active_time_id'];
  1301. //判断是否还在秒杀时间内
  1302. $hour = date('H');
  1303. $date = strtotime(date('Y-m-d'));
  1304. $active_time = Db::name('sharp_active_time')
  1305. ->alias('a')
  1306. ->join('sharp_active b','a.active_id = b.active_id')
  1307. ->where('b.active_date',$date)
  1308. ->where('a.active_time',$hour)
  1309. ->getField('active_time_id');
  1310. if (empty($active_time) || $CacheData['active_time_id'] != $active_time){
  1311. if (empty($list)) $this->error('秒杀活动已结束!');
  1312. }
  1313. //判断该秒杀商品是多规格还是单规格
  1314. $is_sku = Db::name('sharp_active_goods')
  1315. ->alias('a')
  1316. ->join('sharp_goods b','a.aid = b.aid')
  1317. ->where('a.aid',$CacheData['product_id'])
  1318. ->where('a.active_time_id',$CacheData['active_time_id'])
  1319. ->getField('b.is_sku');
  1320. $list[0]['is_sku'] = $is_sku;
  1321. if (empty($is_sku)){
  1322. //单规格
  1323. $active_goods = Db::name('sharp_goods')->where('aid',$CacheData['product_id'])->field('seckill_price,seckill_stock')->find();
  1324. if (!empty($active_goods)){
  1325. $list[0]['users_price'] = $list[0]['seckill_price'] = $active_goods['seckill_price'];
  1326. $list[0]['stock_count'] = $list[0]['seckill_stock'] = $active_goods['seckill_stock'];
  1327. }
  1328. }
  1329. }elseif (isset($CacheData['discount_active_id']) && !empty($CacheData['discount_active_id'])){
  1330. $list[0]['discount_active_id'] = $CacheData['discount_active_id'];
  1331. $end_date = Db::name('discount_active')->where('active_id',$CacheData['discount_active_id'])->value('end_date');
  1332. if ($end_date < getTime()){
  1333. if (empty($list)) $this->error('活动已结束!');
  1334. }
  1335. //判断该秒杀商品是多规格还是单规格
  1336. $discount_goods = Db::name('discount_active_goods')
  1337. ->alias('a')
  1338. ->field('b.is_sku,b.discount_price,b.discount_stock')
  1339. ->join('discount_goods b','a.aid = b.aid')
  1340. ->where('a.aid',$CacheData['product_id'])
  1341. ->where('a.active_id',$CacheData['discount_active_id'])
  1342. ->find();
  1343. $list[0]['is_sku'] = $discount_goods['is_sku'];
  1344. if (empty($discount_goods['is_sku'])){
  1345. //单规格
  1346. $list[0]['users_price'] = $list[0]['discount_price'] = $discount_goods['discount_price'];
  1347. $list[0]['stock_count'] = $list[0]['discount_stock'] = $discount_goods['discount_stock'];
  1348. }
  1349. }
  1350. } else {
  1351. // 购物车下单
  1352. $where = [
  1353. 'a.users_id' => $users_id,
  1354. 'a.lang' => get_home_lang(),
  1355. 'a.selected' => 1,
  1356. ];
  1357. $list = Db::name('shop_cart')->field('a.*,b.typeid, b.aid, b.title, b.litpic, b.users_price, b.users_discount_type, b.stock_count, b.prom_type, b.attrlist_id, b.logistics_type, c.spec_price, c.spec_stock, c.value_id')
  1358. ->alias('a')
  1359. ->join('__ARCHIVES__ b', 'a.product_id = b.aid', 'LEFT')
  1360. ->join('__PRODUCT_SPEC_VALUE__ c', 'a.spec_value_id = c.spec_value_id and a.product_id = c.aid', 'LEFT')
  1361. ->where($where)
  1362. ->select();
  1363. $logistics_type_arr = get_arr_column($list,'logistics_type');
  1364. if (empty($post['deliveryShow']) && empty($post['verifyShow']) && in_array(1,$logistics_type_arr)){
  1365. $post['deliveryShow'] = 1;
  1366. }
  1367. foreach ($list as $key => $value) {
  1368. // 仅购买支持到店核销商品
  1369. if (!empty($post['verifyShow']) && 1 === intval($post['verifyShow'])) {
  1370. if ('1' === $value['logistics_type']) unset($list[$key]);
  1371. }
  1372. // 仅购买支持快递配送商品
  1373. else if (!empty($post['deliveryShow']) && 1 === intval($post['deliveryShow'])) {
  1374. if ('2' === $value['logistics_type']) unset($list[$key]);
  1375. }
  1376. }
  1377. }
  1378. return $list;
  1379. }
  1380. // 商品规格/折扣数据处理
  1381. private function OrderProductProcess($list = [], $ConfigData = [], $users_discount = 1, $level_id = 0)
  1382. {
  1383. foreach ($list as $key => $value) {
  1384. // 规格处理
  1385. $list[$key]['product_spec_list'] = !empty($value['spec_value_id']) ? model('ShopPublicHandle')->getGoodsSpecList($value) : [];
  1386. /* 未开启多规格则执行 */
  1387. if (!isset($ConfigData['shop_open_spec']) || empty($ConfigData['shop_open_spec'])) {
  1388. $value['spec_value_id'] = $value['spec_price'] = $value['spec_stock'] = 0;
  1389. $list[$key]['spec_value_id'] = $list[$key]['spec_price'] = $list[$key]['spec_stock'] = 0;
  1390. }
  1391. /* END */
  1392. /* 商品存在规格且价格不为空,则覆盖商品原来的价格 */
  1393. if (!empty($value['spec_value_id']) && 'undefined' != $value['spec_value_id'] && $value['spec_price'] >= 0) {
  1394. // 规格价格覆盖商品原价
  1395. $list[$key]['users_price'] = $value['users_price'] = $value['spec_price'];
  1396. }
  1397. /* END */
  1398. /* 商品原价 */
  1399. $list[$key]['old_price'] = unifyPriceHandle($list[$key]['users_price']);
  1400. /* END */
  1401. /* 计算折扣后的价格 */
  1402. if (!empty($users_discount) && 0 === intval($value['users_discount_type'])) {
  1403. // 会员折扣价
  1404. $list[$key]['users_price'] = unifyPriceHandle($value['users_price'] * $users_discount);
  1405. }
  1406. /* END */
  1407. $list[$key]['discount_end_date'] = 0;
  1408. /* 限时折扣商品多规格商品,则覆盖商品原来的价格 */
  1409. if (!empty($value['discount_active_id'])) {
  1410. if (empty($value['discount_price'])){
  1411. $value['discount_price'] = Db::name('discount_goods')->where('aid',$value['aid'])->value('discount_price');
  1412. }
  1413. $list[$key]['users_price'] = $value['spec_price'] = $value['discount_price'];
  1414. $list[$key]['discount_end_date'] = Db::name('discount_active')->where('active_id',$value['discount_active_id'])->value('end_date');
  1415. }
  1416. /* END */
  1417. /* 商品存在规格且库存不为空,则覆盖商品原来的库存 */
  1418. if (!empty($value['spec_stock'])) {
  1419. // 规格库存覆盖商品库存
  1420. $list[$key]['stock_count'] = $value['stock_count'] = $value['spec_stock'];
  1421. }
  1422. if ($value['product_num'] > $value['stock_count']) {
  1423. // 购买数量超过最大库存量则默认购买最大库存量
  1424. $list[$key]['stock_count'] = $list[$key]['product_num'] = $value['stock_count'];
  1425. }
  1426. /* END */
  1427. // 图片处理
  1428. $list[$key]['litpic'] = $this->get_default_pic($value['litpic'], true);
  1429. // 商品是 单规格 且 设置会员折扣价 则处理
  1430. if (empty($list[$key]['product_spec']) && 1 === intval($value['users_discount_type']) && !empty($level_id)) {
  1431. $list[$key]['users_price'] = model('ShopPublicHandle')->handleUsersDiscountPrice($value['aid'], $level_id);
  1432. }
  1433. /* 若库存为空则清除这条数据 */
  1434. if (empty($value['stock_count'])) {
  1435. unset($list[$key]);
  1436. continue;
  1437. }
  1438. /* END */
  1439. }
  1440. return $list;
  1441. }
  1442. // 组装订单流程所需全局信息
  1443. private function GetGlobalInfo($ConfigData = [], $CacheData = [])
  1444. {
  1445. $GlobalInfo = [
  1446. // 温馨提示内容,为空则不展示
  1447. 'shop_prompt' => !empty($ConfigData['shop_prompt']) ? $ConfigData['shop_prompt'] : '',
  1448. // 是否开启线下支付(货到付款)
  1449. 'shop_open_offline' => !empty($ConfigData['shop_open_offline']) ? $ConfigData['shop_open_offline'] : 0,
  1450. // 是否开启运费设置
  1451. 'shop_open_shipping' => !empty($ConfigData['shop_open_shipping']) ? $ConfigData['shop_open_shipping'] : 0,
  1452. // 初始化支付总额
  1453. 'TotalAmount' => 0,
  1454. // 初始化支付总额,包含运费
  1455. 'PayTotalAmount' => 0,
  1456. // 初始化总数
  1457. 'TotalNumber' => 0,
  1458. // 提交来源:0购物车;1直接下单
  1459. 'submit_order_type' => !empty($CacheData) ? 1 : 0,
  1460. // 1表示为虚拟订单
  1461. 'PromType' => 1,
  1462. // 虚拟订单文案
  1463. 'virtual_text1' => '1、该产品为虚拟产品,仅支持在线支付且无需选择收货地址及运费计算。',
  1464. 'virtual_text2' => '2、若产品是充值类产品,请将您的手机号或需充值的卡号填入留言中。',
  1465. // 仅到店核销
  1466. 'onlyVerify' => false,
  1467. // 仅物流配送
  1468. 'onlyDelivery' => false,
  1469. // 物流支持
  1470. 'allLogisticsType' => false,
  1471. ];
  1472. return $GlobalInfo;
  1473. }
  1474. // 获取用户下单时提交的收货地址及运费
  1475. private function GetUsersAddrData($post = [], $PromType = 0)
  1476. {
  1477. $AddrData = [];
  1478. if (0 == $PromType) {
  1479. // 查询收货地址
  1480. $AddrWhere = [
  1481. 'addr_id' => $post['addr_id'],
  1482. 'users_id' => $post['users_id'],
  1483. 'lang' => get_home_lang()
  1484. ];
  1485. $AddressData = Db::name('shop_address')->where($AddrWhere)->find();
  1486. if (empty($AddressData)) $this->error('收货地址不存在!');
  1487. $shop_open_shipping = getUsersConfigData('shop.shop_open_shipping');
  1488. $template_money = '0.00';
  1489. if (!empty($shop_open_shipping)) {
  1490. // 通过省份获取运费模板中的运费价格
  1491. $where['province_id'] = $AddressData['province'];
  1492. $template_money = Db::name('shop_shipping_template')->where($where)->getField('template_money');
  1493. if (0 == $template_money) {
  1494. // 省份运费价格为0时,使用统一的运费价格,固定ID为100000
  1495. $where['province_id'] = 100000;
  1496. $template_money = Db::name('shop_shipping_template')->where($where)->getField('template_money');
  1497. }
  1498. }
  1499. }
  1500. // 拼装数组
  1501. $AddrData = [
  1502. 'consignee' => !empty($AddressData['consignee']) ? $AddressData['consignee'] : '',
  1503. 'country' => !empty($AddressData['country']) ? $AddressData['country'] : '',
  1504. 'province' => !empty($AddressData['province']) ? $AddressData['province'] : '',
  1505. 'city' => !empty($AddressData['city']) ? $AddressData['city'] : '',
  1506. 'district' => !empty($AddressData['district']) ? $AddressData['district'] : '',
  1507. 'address' => !empty($AddressData['address']) ? $AddressData['address'] : '',
  1508. 'mobile' => !empty($AddressData['mobile']) ? $AddressData['mobile'] : '',
  1509. 'shipping_fee' => !empty($template_money) ? $template_money : 0,
  1510. ];
  1511. return $AddrData;
  1512. }
  1513. // 旧产品属性处理
  1514. private function ProductAttrProcessing($value = array())
  1515. {
  1516. $attr_value = '';
  1517. $AttrWhere = [
  1518. 'a.aid' => $value['aid'],
  1519. 'b.lang' => get_home_lang()
  1520. ];
  1521. $attrData = Db::name('product_attr')
  1522. ->alias('a')
  1523. ->field('a.attr_value as value, b.attr_name as name')
  1524. ->join('__PRODUCT_ATTRIBUTE__ b', 'a.attr_id = b.attr_id', 'LEFT')
  1525. ->where($AttrWhere)
  1526. ->order('b.sort_order asc, a.attr_id asc')
  1527. ->select();
  1528. foreach ($attrData as $val) {
  1529. $attr_value .= $val['name'] . ':' . $val['value'] . '<br/>';
  1530. }
  1531. return $attr_value;
  1532. }
  1533. // 新商品属性处理
  1534. private function ProductNewAttrProcessing($value = array())
  1535. {
  1536. $attr_value = '';
  1537. $where = [
  1538. 'a.list_id' => $value['attrlist_id'],
  1539. 'a.status' => 1,
  1540. 'b.aid' => $value['aid']
  1541. ];
  1542. $attrData = Db::name('shop_product_attribute')
  1543. ->alias('a')
  1544. ->field('a.attr_name as name, b.attr_value as value')
  1545. ->join('__SHOP_PRODUCT_ATTR__ b', 'a.attr_id = b.attr_id', 'LEFT')
  1546. ->where($where)
  1547. ->order('a.sort_order asc, a.attr_id asc')
  1548. ->select();
  1549. foreach ($attrData as $val) {
  1550. $attr_value .= $val['name'] . ':' . $val['value'] . '<br/>';
  1551. }
  1552. return $attr_value;
  1553. }
  1554. // 商品规格处理
  1555. private function ProductSpecProcessing($value = array())
  1556. {
  1557. $spec_value_s = '';
  1558. if (!empty($value['spec_value_id'])) {
  1559. $spec_value_id = explode('_', $value['spec_value_id']);
  1560. if (!empty($spec_value_id)) {
  1561. $SpecWhere = [
  1562. 'aid' => $value['aid'],
  1563. 'lang' => get_home_lang(),
  1564. 'spec_value_id' => ['IN', $spec_value_id],
  1565. ];
  1566. $ProductSpecData = Db::name("product_spec_data")->where($SpecWhere)->field('spec_name,spec_value')->select();
  1567. foreach ($ProductSpecData as $spec_value) {
  1568. $spec_value_s .= $spec_value['spec_name'] . ':' . $spec_value['spec_value'] . '<br/>';
  1569. }
  1570. }
  1571. }
  1572. return $spec_value_s;
  1573. }
  1574. /*商城购物流程--END*/
  1575. /* 判断商品库存 */
  1576. public function IsSoldOut($post = [])
  1577. {
  1578. if (!empty($post['product_id'])) {
  1579. if (!empty($post['spec_value_id'])) {
  1580. $SpecWhere = [
  1581. 'aid' => $post['product_id'],
  1582. 'lang' => get_home_lang(),
  1583. 'spec_stock' => ['>', 0],
  1584. 'spec_value_id' => $post['spec_value_id']
  1585. ];
  1586. $find_field = 'spec_stock';
  1587. if (!empty($post['active_time_id'])){
  1588. $find_field = 'seckill_stock';
  1589. }
  1590. if (!empty($post['discount_active_id'])){
  1591. $find_field = 'discount_stock';
  1592. }
  1593. $spec_stock = Db::name('product_spec_value')->where($SpecWhere)->getField($find_field);
  1594. if (empty($spec_stock)) {
  1595. $this->error('商品已售罄!');
  1596. }
  1597. if ($spec_stock < $post['product_num']) {
  1598. $this->error('商品最大库存:' . $spec_stock);
  1599. }
  1600. } else {
  1601. $ArchivesWhere = [
  1602. 'aid' => $post['product_id'],
  1603. 'lang' => get_home_lang(),
  1604. 'arcrank' => ['>=', 0]
  1605. ];
  1606. if (!empty($post['active_time_id'])){
  1607. $stock_count = Db::name('sharp_goods')->where('aid',$post['product_id'])->getField('seckill_stock');
  1608. }elseif (!empty($post['discount_active_id'])){
  1609. $stock_count = Db::name('discount_goods')->where('aid',$post['product_id'])->getField('discount_stock');
  1610. }else{
  1611. $stock_count = Db::name('archives')->where($ArchivesWhere)->getField('stock_count');
  1612. }
  1613. if (empty($stock_count)) {
  1614. $this->error('商品已售罄!');
  1615. }
  1616. if ($stock_count < $post['product_num']) {
  1617. $this->error('商品最大库存:' . $stock_count);
  1618. }
  1619. }
  1620. }
  1621. }
  1622. /* END */
  1623. /*收货地址--Start*/
  1624. // 收货地址列表
  1625. public function GetAllAddressList($users = [])
  1626. {
  1627. $ReturnData = [];
  1628. $list = !empty($users['address_1588820149']) ? $users['address_1588820149'] : [];
  1629. $default_id = !empty($users['address_default_1588820149']) ? $users['address_default_1588820149']['addr_id'] : 0;
  1630. if (!empty($list)) {
  1631. // 将地址ID转成地址名称
  1632. foreach ($list as $key => $value) {
  1633. $list[$key]['provinceName'] = $this->GetRegionName($value['province']);
  1634. $list[$key]['cityName'] = $this->GetRegionName($value['city']);
  1635. $list[$key]['districtName'] = $this->GetRegionName($value['district']);
  1636. }
  1637. // 若没有默认收货地址则默认第一个地址为默认地址
  1638. if (empty($default_id)) {
  1639. $default_id = $list[0]['addr_id'];
  1640. $where = [
  1641. 'addr_id' => $default_id,
  1642. 'users_id' => $this->users_id
  1643. ];
  1644. $update = [
  1645. 'is_default' => 1,
  1646. 'update_time' => getTime()
  1647. ];
  1648. Db::name('shop_address')->where($where)->update($update);
  1649. }
  1650. }
  1651. // 返回数据
  1652. $ReturnData = [
  1653. 'list' => $list,
  1654. 'default_id' => $default_id
  1655. ];
  1656. $this->success('查询成功', null, $ReturnData);
  1657. }
  1658. // 获取单条收货地址
  1659. public function GetFindAddrDetail($post = [], $users = [])
  1660. {
  1661. if (!empty($users['address_1588820149'])) {
  1662. $ResultData['detail'] = [];
  1663. foreach ($users['address_1588820149'] as $key => $value) {
  1664. if ($post['addr_id'] == $value['addr_id']) {
  1665. $ResultData['detail'] = $value;
  1666. break;
  1667. }
  1668. }
  1669. if (!empty($ResultData)) {
  1670. // 查询地址名称
  1671. $ProvinceName = $this->ProcessingProvince($this->GetRegionName($ResultData['detail']['province']));
  1672. $CityName = $this->GetRegionName($ResultData['detail']['city']);
  1673. $DistrictName = $this->GetRegionName($ResultData['detail']['district']);
  1674. // 拼装地址
  1675. $region = $ProvinceName . ',' . $CityName . ',' . $DistrictName;
  1676. $ResultData['detail']['region'] = [
  1677. 'province' => $ProvinceName,
  1678. 'city' => $CityName,
  1679. 'region' => $DistrictName
  1680. ];
  1681. $ResultData['region'] = explode(',', $region);
  1682. // 查询地址名称
  1683. $ProvinceName = $this->GetRegionName($ResultData['detail']['province']);
  1684. // 拼装地址
  1685. $regionNew = $ProvinceName . ',' . $CityName . ',' . $DistrictName;
  1686. $ResultData['detail']['regionNew'] = [
  1687. 'province' => $ProvinceName,
  1688. 'city' => $CityName,
  1689. 'region' => $DistrictName
  1690. ];
  1691. $ResultData['regionNew'] = explode(',', $regionNew);
  1692. $this->success('查询成功', null, $ResultData);
  1693. }
  1694. }
  1695. $this->error('数据错误');
  1696. }
  1697. // 添加单条收货地址
  1698. public function FindAddAddr($post = [], $users_id = null)
  1699. {
  1700. if (!empty($post['name']) && !empty($post['phone']) && !empty($post['region']) && !empty($users_id)) {
  1701. /* 微信地址名称换取本站地址ID */
  1702. $AddrData = $this->GetAddrData($post['region']);
  1703. /* END */
  1704. $AddData = [
  1705. 'users_id' => $users_id,
  1706. 'consignee' => $post['name'],
  1707. 'country' => 1,
  1708. 'province' => $AddrData['province'],
  1709. 'city' => $AddrData['city'],
  1710. 'district' => $AddrData['district'],
  1711. 'address' => $post['detail'],
  1712. 'mobile' => $post['phone'],
  1713. 'lang' => get_home_lang(),
  1714. 'add_time' => getTime(),
  1715. 'update_time' => getTime()
  1716. ];
  1717. $ResultID = Db::name('shop_address')->add($AddData);
  1718. if (!empty($ResultID)) $this->success('添加成功');
  1719. }
  1720. $this->error('数据错误');
  1721. }
  1722. // 编辑单条收货地址
  1723. public function FindEditAddr($post = [], $users_id = null)
  1724. {
  1725. if (!empty($post['name']) && !empty($post['phone']) && !empty($post['region']) && !empty($users_id)) {
  1726. /* 微信地址名称换取本站地址ID */
  1727. $AddrData = $this->GetAddrData($post['region']);
  1728. /* END */
  1729. $UpData = [
  1730. 'users_id' => $users_id,
  1731. 'consignee' => $post['name'],
  1732. 'country' => 1,
  1733. 'province' => $AddrData['province'],
  1734. 'city' => $AddrData['city'],
  1735. 'district' => $AddrData['district'],
  1736. 'address' => $post['detail'],
  1737. 'mobile' => $post['phone'],
  1738. 'update_time' => getTime()
  1739. ];
  1740. $ResultID = Db::name('shop_address')->where('addr_id', $post['addr_id'])->update($UpData);
  1741. if (!empty($ResultID)) $this->success('编辑成功');
  1742. }
  1743. $this->error('数据错误');
  1744. }
  1745. // 设置默认地址
  1746. public function SetDefaultAddr($post = [], $users_id = null)
  1747. {
  1748. if (empty($post['addr_id']) || empty($users_id)) $this->error('请刷新重试');
  1749. /*设置默认地址*/
  1750. $where = [
  1751. 'addr_id' => $post['addr_id'],
  1752. 'users_id' => $users_id
  1753. ];
  1754. $update = [
  1755. 'is_default' => 1,
  1756. 'update_time' => getTime()
  1757. ];
  1758. $ResultID = Db::name('shop_address')->where($where)->update($update);
  1759. /* END */
  1760. if (!empty($ResultID)) {
  1761. /*将其他地址设置为非默认地址*/
  1762. $where = [
  1763. 'addr_id' => ['NEQ', $post['addr_id']],
  1764. 'users_id' => $users_id
  1765. ];
  1766. $update = [
  1767. 'is_default' => 0,
  1768. 'update_time' => getTime()
  1769. ];
  1770. Db::name('shop_address')->where($where)->update($update);
  1771. /* END */
  1772. $this->success('更新成功');
  1773. }
  1774. $this->error('更新失败,请刷新重试');
  1775. }
  1776. // 删除单条收货地址
  1777. public function FindDelAddr($post = [], $users_id = null)
  1778. {
  1779. if (!empty($post['addr_id']) && !empty($users_id)) {
  1780. $where = [
  1781. 'users_id' => $users_id,
  1782. 'addr_id' => $post['addr_id']
  1783. ];
  1784. $ResultID = Db::name('shop_address')->where($where)->delete();
  1785. if (!empty($ResultID)) $this->success('操作成功');
  1786. }
  1787. $this->error('数据错误');
  1788. }
  1789. // 微信地址名称换取本站地址ID
  1790. private function GetAddrData($region = null)
  1791. {
  1792. $region = explode(',', $region);
  1793. $province = substr($region[0], 0, 6); // 截取前两个汉字
  1794. $ResultData['province'] = $this->GetRegionID(1, $province);
  1795. $ResultData['city'] = $this->GetRegionID(2, $region[1], $ResultData['province']);
  1796. $ResultData['district'] = $this->GetRegionID(3, $region[2], $ResultData['city']);
  1797. return $ResultData;
  1798. }
  1799. // 微信地址名称换取本站地址ID
  1800. private function GetRegionID($level = 1, $name = 1, $parent_id = 0)
  1801. {
  1802. $old_name = $name;
  1803. // 当区域名称大于2两个字是,就去除末尾指定的字
  1804. if ($level > 1 && strlen($name) >= 9) {
  1805. $name = preg_replace('/(省|市|县|区|乡|镇)$/i', '', $name);
  1806. }
  1807. $where = [
  1808. 'level' => $level,
  1809. 'parent_id' => $parent_id,
  1810. 'name' => ['LIKE', "{$name}%"],
  1811. ];
  1812. $id = Db::name('region')->where($where)->getField('id');
  1813. if (empty($id) && 2 <= $level) {
  1814. $addData = [
  1815. 'name' => $old_name,
  1816. 'level' => $level,
  1817. 'parent_id' => $parent_id,
  1818. 'initial' => getFirstCharter($old_name),
  1819. ];
  1820. $id = Db::name('region')->insertGetId($addData);
  1821. }
  1822. return $id;
  1823. }
  1824. // 地址ID换取地址名称
  1825. private function GetRegionName($id = 1)
  1826. {
  1827. $name = Db::name('region')->where('id', $id)->getField('name');
  1828. return $name;
  1829. }
  1830. // 特殊地区处理
  1831. private function ProcessingProvince($province = null)
  1832. {
  1833. if (empty($province)) return $province;
  1834. if ('山西' == $province) {
  1835. $province = '山西省';
  1836. } else if ('内蒙古' == $province) {
  1837. $province = '内蒙古自治区';
  1838. } else if ('广西' == $province) {
  1839. $province = '广西壮族自治区';
  1840. } else if ('西藏' == $province) {
  1841. $province = '西藏自治区';
  1842. } else if ('宁夏' == $province) {
  1843. $province = '宁夏回族自治区';
  1844. } else if ('新疆' == $province) {
  1845. $province = '新疆维吾尔族自治区';
  1846. } else if ('香港' == $province) {
  1847. $province = '香港特别行政区';
  1848. } else if ('澳门' == $province) {
  1849. $province = '澳门特别行政区';
  1850. } else if ('台湾' == $province) {
  1851. $province = '台湾省';
  1852. }
  1853. return $province;
  1854. }
  1855. /* 收货地址--END */
  1856. /**
  1857. * 获取订单总数
  1858. * @param $user
  1859. * @param string $type
  1860. * @return int|string
  1861. * @throws \think\Exception
  1862. */
  1863. public function getOrderCount($users, $type = 'all')
  1864. {
  1865. if ($users === false) {
  1866. return false;
  1867. }
  1868. // 筛选条件
  1869. $filter = [];
  1870. // 订单数据类型
  1871. switch ($type) {
  1872. case 'all': // 全部订单
  1873. break;
  1874. case 'payment'; // 待付款订单
  1875. $filter['order_status'] = 0;
  1876. break;
  1877. case 'delivery'; // 待发货
  1878. $filter['order_status'] = 1;
  1879. break;
  1880. case 'received'; // 待收货订单
  1881. $filter['order_status'] = 2;
  1882. break;
  1883. case 'complete'; // 已完成
  1884. $filter['order_status'] = 3;
  1885. break;
  1886. }
  1887. $filter['users_id'] = $users['users_id'];
  1888. $filter['lang'] = get_home_lang();
  1889. $count = Db::name('shop_order')
  1890. ->where($filter)
  1891. ->count();
  1892. return $count;
  1893. }
  1894. /**
  1895. * 用户中心订单列表
  1896. * @param $users_id
  1897. * @param string $type
  1898. * @return \think\Paginator
  1899. * @throws \think\exception\DbException
  1900. */
  1901. public function getOrderList($users_id = 0, $type = 'all')
  1902. {
  1903. // 筛选条件
  1904. $where = [
  1905. 'lang' => get_home_lang(),
  1906. 'users_id' => intval($users_id),
  1907. ];
  1908. // 订单数据类型
  1909. switch ($type) {
  1910. case 'all': // 全部
  1911. break;
  1912. case 'payment'; // 待付款
  1913. $where['order_status'] = 0;
  1914. break;
  1915. case 'delivery'; // 待发货
  1916. $where['order_status'] = 1;
  1917. break;
  1918. case 'received'; // 待收货
  1919. $where['order_status'] = 2;
  1920. break;
  1921. case 'complete'; // 待评价
  1922. $where['order_status'] = 3;
  1923. // $where['is_comment'] = 0;
  1924. break;
  1925. case 'close'; // 订单关闭
  1926. $where['order_status'] = -1;
  1927. break;
  1928. }
  1929. $result = Db::name('shop_order')->where($where)->order('order_id desc')->paginate(15, false, ['query' => request()->param()]);
  1930. !empty($result) && $result = $result->toArray();
  1931. $order_ids = get_arr_column($result['data'], 'order_id');
  1932. // 订单商品详情
  1933. $orderGoods = [];
  1934. $where = [
  1935. 'users_id' => intval($users_id),
  1936. 'order_id' => ['IN', $order_ids],
  1937. ];
  1938. $goodsList = Db::name('shop_order_details')->where($where)->order('order_id desc')->select();
  1939. // 安装积分商城插件则执行
  1940. if (!empty($goodsList)) {
  1941. $weappInfo = model('ShopPublicHandle')->getWeappPointsShop();
  1942. if (!empty($weappInfo)) {
  1943. // 积分商城插件积分订单商品详情处理
  1944. $pointsOrderModel = new \app\plugins\model\PointsOrder();
  1945. $pointsGoodsBuyField = $pointsOrderModel->pointsGoodsOrderDetails($goodsList);
  1946. }
  1947. }
  1948. foreach ($goodsList as $key => $_goods) {
  1949. $_goods['product_price'] = unifyPriceHandle($_goods['product_price']);
  1950. // 获取订单商品规格列表(购买时的商品规格)
  1951. $_goods['product_spec_list'] = model('ShopPublicHandle')->getOrderGoodsSpecList($_goods);
  1952. $_goods['litpic'] = $this->get_default_pic($_goods['litpic'], true);
  1953. $orderGoods[$_goods['order_id']][] = $_goods;
  1954. }
  1955. // 模型名称
  1956. $channeltype_row = \think\Cache::get('extra_global_channeltype');
  1957. $channeltypeInfo = !empty($channeltype_row[2]) ? $channeltype_row[2] : [];
  1958. $channel_ntitle = !empty($channeltypeInfo['ntitle']) ? $channeltypeInfo['ntitle'] : '商品';
  1959. $pay_method_arr = config('global.pay_method_arr');
  1960. $order_status_arr = config('global.order_status_arr');
  1961. foreach ($result['data'] as $key => &$_order) {
  1962. $_order['shipping_fee'] = unifyPriceHandle($_order['shipping_fee']);
  1963. $_order['order_amount'] = unifyPriceHandle($_order['order_amount']);
  1964. $_order['order_total_amount'] = unifyPriceHandle($_order['order_total_amount']);
  1965. $_order['pay_name_text'] = !empty($pay_method_arr[$_order['pay_name']]) ? $pay_method_arr[$_order['pay_name']] : '未支付';
  1966. $_order['order_status_text'] = $order_status_arr[$_order['order_status']];
  1967. $_order['add_time'] = MyDate('Y-m-d H:i:s', $_order['add_time']);
  1968. $_order['goods'] = !empty($orderGoods[$_order['order_id']]) ? $orderGoods[$_order['order_id']] : [];
  1969. $_order['channel_ntitle'] = '商品'; // $channel_ntitle;
  1970. $_order['pointsGoodsBuyField'] = !empty($pointsGoodsBuyField[$_order['order_id']]) ? $pointsGoodsBuyField[$_order['order_id']] : [];
  1971. }
  1972. return $result;
  1973. }
  1974. // 取消订单
  1975. public function orderCancel($order_id, $users_id)
  1976. {
  1977. // 更新条件
  1978. $Where = [
  1979. 'order_id' => $order_id,
  1980. 'users_id' => $users_id,
  1981. ];
  1982. // 更新数据
  1983. $Data = [
  1984. 'order_status' => -1,
  1985. 'update_time' => getTime(),
  1986. ];
  1987. // 更新订单主表
  1988. $return = Db::name('shop_order')->where($Where)->update($Data);
  1989. if (!empty($return)) {
  1990. //还原优惠券
  1991. $use_id = Db::name('shop_order')->where($Where)->value('use_id');
  1992. if (!empty($use_id)){
  1993. $coupon_use = Db::name('shop_coupon_use')->where(['use_id'=>$use_id])->find();
  1994. if (!empty($coupon_use)){
  1995. if ($coupon_use['start_time'] <= getTime() && $coupon_use['end_time'] >= getTime()){
  1996. $use_update = ['use_status'=>0];
  1997. }else{
  1998. $use_update = ['use_status'=>2];
  1999. }
  2000. $use_update['use_time'] = 0;
  2001. $use_update['update_time'] = getTime();
  2002. Db::name('shop_coupon_use')->where(['use_id'=>$use_id,'users_id' => $users_id])->update($use_update);
  2003. }
  2004. }
  2005. //查询是否是秒杀订单
  2006. $order_info = Db::name('shop_order')->where($Where)->find();
  2007. $productSpecValue = new \app\user\model\ProductSpecValue;
  2008. if (20 == $order_info['order_source']){
  2009. $productSpecValue->SaveSharpStock($order_id, $users_id,$order_info);
  2010. }else{
  2011. // 订单取消,还原单内产品数量
  2012. $productSpecValue->SaveProducSpecValueStock($order_id, $users_id);
  2013. }
  2014. // 如果安装了秒杀插件则执行
  2015. if (is_dir('./weapp/Seckill/')) {
  2016. $SeckillRow = model('Weapp')->getWeappList('Seckill');
  2017. //is_seckill_order 只有安装了秒杀插件 shop_order表才会有这个字段
  2018. if (!empty($SeckillRow) && 1 == intval($SeckillRow['status']) && !empty($order['is_seckill_order'])) {
  2019. // 调用秒杀逻辑层方法
  2020. $weappSeckillLogic = new \weapp\Seckill\logic\SeckillLogic;
  2021. $weappSeckillLogic->cancelOrderHandle($order_id, $users_id);
  2022. }
  2023. }
  2024. // 添加订单操作记录
  2025. AddOrderAction($order_id, $users_id, 0, 0, 0, 0, '订单取消!', '会员关闭订单!');
  2026. $this->success('订单取消成功!');
  2027. }
  2028. }
  2029. // 订单提醒发货
  2030. public function orderRemind($order_id = 0, $users_id = 0)
  2031. {
  2032. $post = input('post.');
  2033. // 添加订单操作记录
  2034. AddOrderAction($order_id, $users_id, 0, 1, 0, 1, '提醒成功!', '会员提醒管理员及时发货!');
  2035. $this->success('提醒成功');
  2036. }
  2037. // 确认收货
  2038. public function orderReceipt($order_id, $users_id)
  2039. {
  2040. // 更新条件
  2041. $where = [
  2042. 'order_id' => $order_id,
  2043. 'users_id' => $users_id,
  2044. ];
  2045. $order = Db::name('shop_order')->where($where)->find();
  2046. $orderStatus = empty($order['order_status']) ? 0 : intval($order['order_status']);
  2047. if (2 === intval($orderStatus)) {
  2048. // 更新数据
  2049. $update = [
  2050. 'order_status' => 3,
  2051. 'confirm_time' => getTime(),
  2052. 'update_time' => getTime(),
  2053. ];
  2054. // 更新订单主表
  2055. $return = Db::name('shop_order')->where($where)->update($update);
  2056. if (!empty($return)) {
  2057. // 更新数据
  2058. $update = [
  2059. 'update_time' => getTime(),
  2060. ];
  2061. // 更新订单明细表
  2062. Db::name('shop_order_details')->where($where)->update($update);
  2063. // 添加订单操作记录
  2064. AddOrderAction($order_id, $users_id, 0, 3, 1, 1, '确认收货!', '会员已确认收到货物,订单完成!');
  2065. // 如果安装了分销插件则执行
  2066. if (is_dir('./weapp/DealerPlugin/')) {
  2067. // 开启分销插件则执行
  2068. $data = model('Weapp')->getWeappList('DealerPlugin');
  2069. if (!empty($data['status']) && 1 == $data['status']) {
  2070. // 调用分销逻辑层方法
  2071. $dealerCommonLogic = new \weapp\DealerPlugin\logic\DealerCommonLogic;
  2072. $dealerCommonLogic->dealerOrderSettlementExecute($order_id, $users_id);
  2073. }
  2074. }
  2075. // 如果安装了秒杀插件则执行
  2076. if (is_dir('./weapp/Seckill/')) {
  2077. $SeckillRow = model('Weapp')->getWeappList('Seckill');
  2078. //is_seckill_order 只有安装了秒杀插件 shop_order表才会有这个字段
  2079. if (!empty($SeckillRow) && 1 == intval($SeckillRow['status']) && !empty($order['is_seckill_order'])) {
  2080. // 调用秒杀逻辑层方法
  2081. $weappSeckillLogic = new \weapp\Seckill\logic\SeckillLogic;
  2082. $weappSeckillLogic->confirmOrderHandle($order_id, $users_id);
  2083. }
  2084. }
  2085. $this->success('确认收货成功');
  2086. } else {
  2087. $this->error('101:订单异常,请刷新重试');
  2088. }
  2089. } else {
  2090. $this->error('102:订单异常,请刷新重试');
  2091. }
  2092. }
  2093. /**
  2094. * 订单详情
  2095. * @param $order_id
  2096. * @param null $user_id
  2097. * @return null|static
  2098. * @throws BaseException
  2099. * @throws \think\exception\DbException
  2100. */
  2101. public function getOrderDetail($order_id, $users_id)
  2102. {
  2103. // 公共条件
  2104. $Where = [
  2105. 'order_id' => $order_id,
  2106. 'users_id' => $users_id,
  2107. ];
  2108. // 订单主表
  2109. $result = Db::name("shop_order")->where($Where)->find();
  2110. if (empty($result)) {
  2111. $this->error('订单不存在!');
  2112. }
  2113. // 优化显示金额
  2114. $result['coupon_price'] = unifyPriceHandle($result['coupon_price']);
  2115. $result['shipping_fee'] = unifyPriceHandle($result['shipping_fee']);
  2116. $result['order_amount'] = unifyPriceHandle($result['order_amount']);
  2117. $result['order_total_amount'] = unifyPriceHandle($result['order_total_amount']);
  2118. // 模型名称
  2119. $channeltype_row = \think\Cache::get('extra_global_channeltype');
  2120. $channeltypeInfo = !empty($channeltype_row[2]) ? $channeltype_row[2] : [];
  2121. $result['channel_ntitle'] = '商品'; // !empty($channeltypeInfo['ntitle']) ? $channeltypeInfo['ntitle'] : '商品';
  2122. // 获取订单状态
  2123. $order_status_arr = config('global.order_status_arr');
  2124. $result['order_status_text'] = $order_status_arr[$result['order_status']];
  2125. // 获取订单支付方式
  2126. $pay_method_arr = config('global.pay_method_arr');
  2127. $result['pay_name_text'] = !empty($pay_method_arr[$result['pay_name']]) ? $pay_method_arr[$result['pay_name']] : '未支付';
  2128. // 收货地址
  2129. $result['province_text'] = $this->GetRegionName($result['province'], 1);
  2130. $result['city_text'] = $this->GetRegionName($result['city'], 2);
  2131. $result['district_text'] = $this->GetRegionName($result['district'], 3);
  2132. // 下单时间
  2133. $result['add_time'] = MyDate('Y-m-d H:i:s', $result['add_time']);
  2134. // 订单总金额
  2135. $result['TotalAmount'] = 0.00;
  2136. // 订单明细表
  2137. $result['goods'] = Db::name("shop_order_details")->order('product_price desc, product_name desc')->where($Where)->select();
  2138. // 订单操作记录
  2139. $result['orderLog'] = Db::name('shop_order_log')->where('order_id', $order_id)->order('action_id desc')->select();
  2140. foreach ($result['orderLog'] as $key => $value) {
  2141. $result['orderLog'][$key]['add_time'] = MyDate('Y-m-d H:i:s', $value['add_time']);
  2142. }
  2143. // 安装积分商城插件则执行
  2144. $result['pointsGoodsBuyField'] = [];
  2145. if (!empty($result['goods'])) {
  2146. $weappInfo = model('ShopPublicHandle')->getWeappPointsShop();
  2147. if (!empty($weappInfo)) {
  2148. // 积分商城插件积分订单商品详情处理
  2149. $pointsOrderModel = new \app\plugins\model\PointsOrder();
  2150. $pointsGoodsBuyField = $pointsOrderModel->pointsGoodsOrderDetails($result['goods']);
  2151. $result['pointsGoodsBuyField'] = !empty($pointsGoodsBuyField[$result['order_id']]) ? $pointsGoodsBuyField[$result['order_id']] : [];
  2152. }
  2153. }
  2154. // 安装订单核销插件则执行
  2155. $result['verify'] = [];
  2156. if (!empty($result['verify_id'])) {
  2157. $weappInfo = model('ShopPublicHandle')->getWeappVerifyInfo();
  2158. if (!empty($weappInfo)) {
  2159. // 订单核销插件核销订单商品详情处理
  2160. $verifyModel = new \app\plugins\model\Verify();
  2161. $result['verify'] = $verifyModel->verifyOrderDetails($result);
  2162. }
  2163. }
  2164. //虚拟商品拼接回复
  2165. $virtual_delivery = '';
  2166. // 虚拟发货
  2167. $virtual_delivery_status = false;
  2168. // 商品处理
  2169. foreach ($result['goods'] as $key => $value) {
  2170. $result['prom_type'] = $value['prom_type'];
  2171. $result['goods'][$key]['product_price'] = unifyPriceHandle($value['product_price']);
  2172. $result['goods'][$key]['product_spec_list'] = model('ShopPublicHandle')->getOrderGoodsSpecList($value);
  2173. //虚拟需要自动发货的商品卖家回复拼接
  2174. if ($value['prom_type'] == 2 && 2 <= intval($result['order_status'])) {
  2175. $virtual_delivery_status = true;
  2176. //查询商品名称
  2177. // $product_title = Db::name('archives')->where('aid', $value['product_id'])->getField('title');
  2178. //查网盘信息
  2179. $netdisk = Db::name("product_netdisk")->where('aid', $value['product_id'])->find();
  2180. if ($netdisk) {
  2181. // $virtual_delivery .= "商品标题:" . $product_title . "";
  2182. $virtual_delivery .= "网盘地址:" . $netdisk['netdisk_url'] . "";
  2183. if (!empty($netdisk['netdisk_pwd'])) {
  2184. $virtual_delivery .= "提取码:" . $netdisk['netdisk_pwd'] . "";
  2185. }
  2186. if (!empty($netdisk['unzip_pwd'])) {
  2187. $virtual_delivery .= "解压密码:" . $netdisk['unzip_pwd'] . "";
  2188. }
  2189. $virtual_delivery .= "--------------------";
  2190. }
  2191. $result['netdisk'] = $netdisk;
  2192. } else if ($value['prom_type'] == 3 && 2 <= intval($result['order_status'])) {
  2193. $virtual_delivery_status = true;
  2194. //查询商品名称
  2195. // $product_title = Db::name('archives')->where('aid', $value['product_id'])->getField('title');
  2196. //查网盘信息
  2197. $netdisk = Db::name("product_netdisk")->where('aid', $value['product_id'])->find();
  2198. if ($netdisk) {
  2199. // $virtual_delivery .= "商品标题:" . $product_title . "";
  2200. $virtual_delivery .= "文本内容:" . $netdisk['text_content'] . "";
  2201. $virtual_delivery .= "--------------------";
  2202. }
  2203. $result['netdisk'] = $netdisk;
  2204. } else if ($value['prom_type'] == 1) {
  2205. $virtual_delivery_status = true;
  2206. //查询商品名称
  2207. if (!empty($result['virtual_delivery'])) {
  2208. // $product_title = Db::name('archives')->where('aid', $value['product_id'])->getField('title');
  2209. // $virtual_delivery .= "商品标题:" . $product_title . "";
  2210. $virtual_delivery .= filter_line_return($result['virtual_delivery'], '') . "";
  2211. $virtual_delivery .= "--------------------";
  2212. }
  2213. }
  2214. $result['virtual_delivery_status'] = $virtual_delivery_status;
  2215. if ($virtual_delivery_status && !empty($virtual_delivery)) $result['virtual_delivery'] = $virtual_delivery;
  2216. // 商品属性处理
  2217. $ValueData = unserialize($value['data']);
  2218. $spec_value = !empty($ValueData['spec_value']) ? htmlspecialchars_decode($ValueData['spec_value']) : '';
  2219. $spec_value = !empty($spec_value) ? htmlspecialchars_decode($spec_value) : '';
  2220. // 旧参数+规格值
  2221. // $attr_value = !empty($ValueData['attr_value']) ? htmlspecialchars_decode($ValueData['attr_value']) : '';
  2222. // $attr_value = htmlspecialchars_decode($attr_value);
  2223. // $spec_data = $spec_value . $attr_value;
  2224. // $spec_data = str_replace('<br/>', ';', $spec_data);
  2225. // $result['goods'][$key]['data'] = trim($spec_data, ';');
  2226. $result['goods'][$key]['data'] = trim(str_replace('<br/>', ';', $spec_value), ';');
  2227. // 新参数+规格值
  2228. // $attr_value_new = !empty($ValueData['attr_value_new']) ? htmlspecialchars_decode($ValueData['attr_value_new']) : '';
  2229. // $attr_value_new = htmlspecialchars_decode($attr_value_new);
  2230. // $new_spec_data = $spec_value . $attr_value_new;
  2231. // $new_spec_data = str_replace('<br/>', ';', $new_spec_data);
  2232. // $result['goods'][$key]['new_data'] = trim($new_spec_data, ';');
  2233. $result['goods'][$key]['new_data'] = trim(str_replace('<br/>', ';', $spec_value), ';');
  2234. // 图片处理
  2235. $result['goods'][$key]['litpic'] = $this->get_default_pic($value['litpic'], true);
  2236. // 小计
  2237. $result['goods'][$key]['subtotal'] = $value['product_price'] * $value['num'];
  2238. $result['goods'][$key]['subtotal'] = unifyPriceHandle($result['goods'][$key]['subtotal']);
  2239. // 合计金额
  2240. $result['TotalAmount'] += $result['goods'][$key]['subtotal'];
  2241. $result['TotalAmount'] = unifyPriceHandle($result['TotalAmount']);
  2242. }
  2243. // 自动关闭未付款订单时间
  2244. $orderUnpayCloseTime = getUsersConfigData('order.order_unpay_close_time');
  2245. $result['orderUnpayCloseTime'] = !empty($orderUnpayCloseTime) ? intval($orderUnpayCloseTime) / 60 : 0;
  2246. return $result;
  2247. }
  2248. /**
  2249. * 获取评价订单商品列表
  2250. * @param $order_id
  2251. * @param $users_id
  2252. */
  2253. public function getOrderComment($order_id, $users_id)
  2254. {
  2255. //判断该订单是否已经评价
  2256. $comment_count = Db::name('shop_order_comment')->where(['order_id' => $order_id, 'users_id' => $users_id, 'lang' => get_home_lang()])->count();
  2257. if (!empty($comment_count)) {
  2258. $this->error('该订单已经评价!');
  2259. }
  2260. $order_data = $this->getOrderDetail($order_id, $users_id);
  2261. return $order_data['goods'];
  2262. }
  2263. public function getSaveComment($post, $users_id)
  2264. {
  2265. $order_id = intval($post['order_id']);
  2266. //判断该订单是否已经评价
  2267. $comment_count = Db::name('shop_order_comment')->where(['order_id' => $order_id, 'users_id' => $users_id])->count();
  2268. if (!empty($comment_count)) {
  2269. $this->error('该订单已经评价!');
  2270. }
  2271. if (!empty($post['formData'])) {
  2272. $post['formData'] = json_decode(htmlspecialchars_decode($post['formData']), true);
  2273. $insert = [];
  2274. $detail_ids = [];
  2275. $order_code = Db::name('shop_order')->where(['order_id'=>$order_id])->value('order_code');
  2276. foreach ($post['formData'] as $k => $v) {
  2277. $detail_ids[] = $v['order_details_id'];
  2278. $uploadImg = '';
  2279. if (!empty($v['uploaded'])) {
  2280. $uploadImg = implode(',', $v['uploaded']);
  2281. } else if (!empty($v['image_list'])) {
  2282. $uploadImg = implode(',', $v['image_list']);
  2283. }
  2284. $insert[] = [
  2285. 'upload_img' => serialize($uploadImg),
  2286. 'total_score' => $v['score'],
  2287. 'content' => serialize($v['content']),
  2288. 'users_id' => $users_id,
  2289. 'order_id' => $order_id,
  2290. 'order_code' => $order_code,
  2291. 'product_id' => $v['goods_id'],
  2292. 'details_id' => $v['order_details_id'],
  2293. 'add_time' => getTime(),
  2294. 'update_time' => getTime(),
  2295. ];
  2296. }
  2297. $insert_data = Db::name('shop_order_comment')->insertAll($insert);
  2298. if ($insert_data) {
  2299. Db::name('shop_order')
  2300. ->where([
  2301. 'order_id' => $order_id,
  2302. 'users_id' => $users_id,
  2303. 'order_status' => 3,
  2304. ])
  2305. ->update(['is_comment' => 1, 'update_time' => getTime()]);
  2306. if (!empty($detail_ids)) {
  2307. Db::name('shop_order_details')
  2308. ->where('details_id', 'in', $detail_ids)
  2309. ->where('users_id', $users_id)
  2310. ->update(['is_comment' => 1, 'update_time' => getTime()]);
  2311. }
  2312. \think\Cache::clear('archives');
  2313. $this->success('评价成功!');
  2314. }
  2315. }
  2316. $this->error('评价失败!');
  2317. }
  2318. /**
  2319. * 获取评论列表
  2320. */
  2321. public function getGoodsCommentList($goods_id = 0 ,$score = 0 ,$page = 1 )
  2322. {
  2323. $field='a.*,u.nickname,u.head_pic';
  2324. // 筛选条件
  2325. $condition = [
  2326. 'a.product_id' => $goods_id,
  2327. 'a.is_show' => 1,
  2328. 'a.lang' => get_home_lang(),
  2329. ];
  2330. $score > 0 && $condition['total_score'] = $score;
  2331. $pagesize = empty($pagesize) ? config('paginate.list_rows') : $pagesize;
  2332. $cacheKey = 'api-'.md5(__CLASS__.__FUNCTION__.json_encode(func_get_args()));
  2333. $result = cache($cacheKey);
  2334. if (true || empty($result)) {
  2335. $paginate = array(
  2336. 'page' => $page,
  2337. );
  2338. $pages = Db::name('shop_order_comment')
  2339. ->field($field)
  2340. ->alias('a')
  2341. ->join('users u','a.users_id = u.users_id')
  2342. ->where($condition)
  2343. ->order('a.add_time desc')
  2344. ->paginate($pagesize, false, $paginate);
  2345. $result = $pages->toArray();
  2346. foreach ($result['data'] as $key => $val) {
  2347. if ($val['is_anonymous'] == 1){
  2348. //匿名用户
  2349. $val['head_pic'] = get_head_pic();
  2350. $val['nickname'] = '匿名用户';
  2351. }else{
  2352. if (empty($val['head_pic'])){
  2353. $val['head_pic'] = get_head_pic();
  2354. }
  2355. }
  2356. $val['head_pic'] = get_default_pic($val['head_pic'],true);
  2357. if (isset($val['add_time'])) {
  2358. $val['add_time'] = date('Y-m-d H:i:s', $val['add_time']);
  2359. }
  2360. if (!empty($val['upload_img'])){
  2361. $val['upload_img'] = unserialize($val['upload_img']);
  2362. $val['upload_img'] = explode(',',$val['upload_img']);
  2363. foreach ($val['upload_img'] as $k => $v){
  2364. $val['upload_img'][$k] = get_default_pic($v,true);
  2365. }
  2366. }
  2367. if (!empty($val['content'])){
  2368. $val['content'] = unserialize($val['content']);
  2369. }
  2370. $result['data'][$key] = $val;
  2371. }
  2372. $score_type = Db::name('shop_order_comment')
  2373. ->where([
  2374. 'product_id' => $goods_id,
  2375. 'is_show' => 1,
  2376. 'lang' => get_home_lang(),
  2377. ])->field('count(*) as count,total_score')
  2378. ->group('total_score')
  2379. ->getAllWithIndex('total_score');
  2380. $result['count']['goods'] = isset($score_type[1]) ? $score_type[1]['count'] : 0;
  2381. $result['count']['middle'] = isset($score_type[2]) ? $score_type[2]['count'] : 0;
  2382. $result['count']['bad'] = isset($score_type[3]) ? $score_type[3]['count'] : 0;
  2383. $result['count']['all'] = $result['count']['goods']+$result['count']['middle']+$result['count']['bad'] ;
  2384. cache($cacheKey, $result, null, 'getGoodsCommentList');
  2385. }
  2386. return $result;
  2387. }
  2388. /**
  2389. * 获取秒杀tabbar
  2390. */
  2391. public function GetSharpTabbar()
  2392. {
  2393. $time = strtotime(date('Y-m-d'));
  2394. $hour = date('H');
  2395. $where['b.status'] = 1;
  2396. $where['a.status'] = 1;
  2397. $where['b.is_del'] = 0;
  2398. //非当日预告
  2399. $active = Db::name('sharp_active_time')
  2400. ->alias('a')
  2401. ->field('a.*,b.active_date')
  2402. ->join('sharp_active b','a.active_id = b.active_id')
  2403. ->where($where)
  2404. ->where('b.active_date', '>',$time)
  2405. ->order('b.active_date asc,a.active_time asc')
  2406. ->select();
  2407. //当天
  2408. $data = Db::name('sharp_active_time')
  2409. ->alias('a')
  2410. ->field('a.*,b.active_date')
  2411. ->join('sharp_active b','a.active_id = b.active_id')
  2412. ->where($where)
  2413. ->where('b.active_date', $time)
  2414. ->where('a.active_time', '>=',$hour)
  2415. ->order('active_time asc')
  2416. ->select();
  2417. if (!empty($data) && !empty($active)){
  2418. $data[] = $active[0];
  2419. }else if (empty($data) && !empty($active)){
  2420. $data[] = $active;
  2421. }
  2422. $date = date('Y-m-d');
  2423. foreach ($data as $k => $v){
  2424. if ($v['active_time'] < 10){
  2425. $v['active_time'] = '0'.$v['active_time'];
  2426. }
  2427. $active_time = $v['active_time'];
  2428. $v['active_time'] = $v['active_time'].':00';
  2429. $date_time = $date.' '.$v['active_time']; //2020-15-2-15 15:00
  2430. $time_plus = strtotime($date_time . "+1 hours"); //2020-15-2-15 15:00
  2431. $time_plus = date('Y-m-d H:i',$time_plus); //2020-15-2-15 16:00
  2432. if ($time == $v['active_date']){
  2433. if ($active_time == $hour){
  2434. $v['status'] = 10;
  2435. $arr = ['正在疯抢','已开抢','正在疯抢',$time_plus,$time_plus,$date_time];
  2436. }else if ($active_time > $hour){
  2437. $v['status'] = 20;
  2438. $arr = [$v['active_time'].' 场预告','即将开抢','即将开抢',$date_time,$time_plus,$date_time];
  2439. }
  2440. }else{
  2441. $v['status'] = 30;
  2442. $arr = [$date_time.' 开始','预告',$date_time.' 开始',$date_time,$time_plus,$date_time];
  2443. }
  2444. $v['sharp_modular_text'] = $arr[0];
  2445. $v['status_text'] = $arr[1];
  2446. $v['status_text2'] = $arr[2];
  2447. $v['count_down_time'] = $arr[3];
  2448. $v['end_time'] = $arr[4];
  2449. $v['start_time'] = $arr[5];
  2450. $data[$k] = $v;
  2451. }
  2452. return $data;
  2453. }
  2454. /**
  2455. * 获取秒杀列表
  2456. */
  2457. public function GetSharpIndex( $tid = 0 , $page = 1 )
  2458. {
  2459. $pagesize = 10;
  2460. $pagesize = empty($pagesize) ? config('paginate.list_rows') : $pagesize;
  2461. $cacheKey = 'api-'.md5(__CLASS__.__FUNCTION__.json_encode(func_get_args()));
  2462. $result = cache($cacheKey);
  2463. if (true || empty($result)) {
  2464. $paginate = array(
  2465. 'page' => $page,
  2466. );
  2467. $pages = Db::name('sharp_active_goods')
  2468. ->alias('a')
  2469. ->field('c.*,b.litpic,b.title,a.*,b.users_price')
  2470. ->join('archives b','a.aid = b.aid')
  2471. ->join('sharp_goods c','a.sharp_goods_id = c.sharp_goods_id')
  2472. ->where('a.active_time_id',$tid)
  2473. ->paginate($pagesize, false, $paginate);
  2474. $result = $pages->toArray();
  2475. $aids = [];
  2476. foreach ($result['data'] as $k => $v){
  2477. $result['data'][$k]['litpic'] = get_default_pic($v['litpic'],true);
  2478. if (1 == $v['is_sku']){
  2479. $aids[] = $v['aid'];
  2480. }
  2481. }
  2482. //多规格
  2483. if (!empty($aids)) {
  2484. $sku = Db::name('product_spec_value')
  2485. ->field('*,min(seckill_price) as seckill_price')
  2486. ->where('aid', 'in', $aids)
  2487. ->group('aid')
  2488. ->getAllWithIndex('aid');
  2489. }
  2490. //sales_actual //
  2491. foreach ($result['data'] as $k => $v){
  2492. if (1 == $v['is_sku'] && !empty($sku[$v['aid']])){
  2493. $v['seckill_price'] = $sku[$v['aid']]['seckill_price'];
  2494. }
  2495. $v['progress'] = 0;
  2496. if (0 < $v['sales_actual']){
  2497. $count_stock = $v['sales_actual']+$v['seckill_stock']+$v['virtual_sales'];
  2498. $v['progress'] = intval(($v['sales_actual']+$v['virtual_sales'])/$count_stock*100);
  2499. }else{
  2500. if (0 < $v['virtual_sales']){
  2501. $v['progress'] = intval($v['virtual_sales']/($v['virtual_sales']+$v['seckill_stock'])*100);;
  2502. }
  2503. }
  2504. if (0 < $v['virtual_sales']){
  2505. $v['sales_actual'] = $v['sales_actual'] +$v['virtual_sales'];
  2506. }
  2507. $result['data'][$k] = $v;
  2508. }
  2509. cache($cacheKey, $result, null, 'GetSharpIndex');
  2510. }
  2511. return $result;
  2512. }
  2513. /**
  2514. * 获取物流动态信息
  2515. * @param $express_name
  2516. * @param $express_code
  2517. * @param $express_order
  2518. * @return array|bool
  2519. */
  2520. public function orderExpress($express_name, $express_code, $express_order, $timestamp = '')
  2521. {
  2522. $data = [
  2523. 'express_name' => $express_name,
  2524. 'express_order' => $express_order
  2525. ];
  2526. // 快递100 请求查询接口
  2527. $data['list'] = $this->orderExpressQuery($express_code, $express_order);
  2528. if ($data['list'] === false) {
  2529. $this->error('没有找到物流信息!');
  2530. return false;
  2531. }
  2532. return $data;
  2533. }
  2534. /**
  2535. * 执行查询
  2536. * @param $express_code
  2537. * @param $express_order
  2538. * @return bool
  2539. */
  2540. private function orderExpressQuery($express_code, $express_order)
  2541. {
  2542. // 缓存索引
  2543. $cacheKey = 'api-'.md5(__CLASS__.__FUNCTION__.json_encode(func_get_args()));
  2544. if ($data = Cache::get($cacheKey)) {
  2545. return $data;
  2546. }
  2547. // 查询物流链接
  2548. empty($timestamp) && $timestamp = getTime();
  2549. $postData = [
  2550. 'postid' => $express_order,
  2551. 'id' => 1,
  2552. 'valicode' => '',
  2553. 'temp' => $timestamp,
  2554. 'type' => $express_code,
  2555. 'phone' => '',
  2556. 'token' => '',
  2557. 'platform' => 'MWWW',
  2558. 'coname' => 'indexall',
  2559. ];
  2560. $expressUrl = "https://m.kuaidi100.com/query";
  2561. $response = httpRequest($expressUrl, 'POST', $postData);
  2562. $express = json_decode($response, true);
  2563. // 记录错误信息
  2564. if (!isset($express['message']) || $express['message'] != 'ok') {
  2565. $msg = '查询失败';
  2566. $this->error($msg);
  2567. return false;
  2568. }
  2569. // $expressUrl = "https://m.kuaidi100.com/app/query/?com=".$express_code."&nu=".$express_order."&callbackurl=";
  2570. // $mobileExpressUrl = "https://m.kuaidi100.com/index_all.html?type=".$result['express_code']."&postid=".$result['express_order']."&callbackurl=".$ReturnUrl;
  2571. // 记录缓存, 时效5分钟
  2572. Cache::set($cacheKey, $express['data'], 300);
  2573. return $express['data'];
  2574. }
  2575. /**
  2576. * 执行查询
  2577. * @param $express_code
  2578. * @param $express_order
  2579. * @return bool
  2580. */
  2581. private function orderExpressQuery2($express_code, $express_order)
  2582. {
  2583. // 缓存索引
  2584. $cacheKey = 'api-'.md5(__CLASS__.__FUNCTION__.json_encode(func_get_args()));
  2585. if ($data = Cache::get($cacheKey)) {
  2586. return $data;
  2587. }
  2588. $key = 'anFrVFyu8015'; // '快递100 授权KEY';
  2589. $customer = 'B972EB01B5B32404957BE09C8FE85A51'; // '快递100 Customer';
  2590. // 参数设置
  2591. $postData = [
  2592. 'customer' => $customer,
  2593. 'param' => json_encode([
  2594. 'resultv2' => '1',
  2595. 'com' => $express_code,
  2596. 'num' => $express_order
  2597. ])
  2598. ];
  2599. $postData['sign'] = strtoupper(md5($postData['param'] . $key . $postData['customer']));
  2600. // 请求快递100 api
  2601. $url = 'http://poll.kuaidi100.com/poll/query.do';
  2602. $result = httpRequest($url, 'POST', $postData);
  2603. $express = json_decode($result, true);
  2604. // 记录错误信息
  2605. if (isset($express['returnCode']) || !isset($express['data'])) {
  2606. $msg = isset($express['message']) ? $express['message'] : '查询失败';
  2607. $this->error($msg);
  2608. return false;
  2609. }
  2610. // 记录缓存, 时效5分钟
  2611. Cache::set($cacheKey, $express['data'], 300);
  2612. return $express['data'];
  2613. }
  2614. /**
  2615. * 构建支付请求的参数
  2616. * @param $users
  2617. * @param $order
  2618. * @param $payType
  2619. * @return array
  2620. * @throws BaseException
  2621. * @throws \think\exception\DbException
  2622. */
  2623. public function onOrderPayment($users, $order, $payType = 20)
  2624. {
  2625. if ($payType == 20) { // 微信支付
  2626. return $this->onPaymentByWechat($users, $order);
  2627. }
  2628. return [];
  2629. }
  2630. /**
  2631. * 构建微信支付请求
  2632. * @param $users
  2633. * @param $order
  2634. * @return array
  2635. * @throws BaseException
  2636. * @throws \think\exception\DbException
  2637. */
  2638. protected function onPaymentByWechat($users, $order)
  2639. {
  2640. // 统一下单API
  2641. if (empty($this->miniproInfo['mchid']) || empty($this->miniproInfo['apikey'])) {
  2642. return [
  2643. 'code' => 0,
  2644. 'msg' => '很抱歉,请在网站小程序后台,完善微信支付配置!',
  2645. ];
  2646. }
  2647. $openid = Db::name('weapp_diyminipro_mall_users')->where(['users_id' => $users['users_id']])->getField('openid');
  2648. $payment = $this->unifiedorder($order['order_code'], $openid, $order['order_amount']);
  2649. return $payment;
  2650. }
  2651. /**
  2652. * 统一下单API
  2653. * @param $order_code
  2654. * @param $openid
  2655. * @param $totalFee
  2656. * @return array
  2657. * @throws BaseException
  2658. */
  2659. public function unifiedorder($order_code, $openid, $totalFee)
  2660. {
  2661. // 当前时间
  2662. $time = getTime();
  2663. // 生成随机字符串
  2664. $nonceStr = md5($time . $openid);
  2665. // API参数
  2666. $params = [
  2667. 'appid' => $this->miniproInfo['appid'],
  2668. 'attach' => '微信小程序支付',
  2669. 'body' => $order_code,
  2670. 'mch_id' => $this->miniproInfo['mchid'],
  2671. 'nonce_str' => $nonceStr,
  2672. 'notify_url' => url('api/v1/Api/wxpay_notify', [], true, true, 1, 1), // 异步通知地址
  2673. 'openid' => $openid,
  2674. 'out_trade_no' => $order_code,
  2675. 'spbill_create_ip' => clientIP(),
  2676. 'total_fee' => $totalFee * 100, // 价格:单位分
  2677. 'trade_type' => 'JSAPI',
  2678. ];
  2679. // 生成签名
  2680. $params['sign'] = model('v1.User')->makeSign($params, $this->miniproInfo['apikey']);
  2681. // 请求API
  2682. $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
  2683. $result = httpRequest($url, 'POST', model('v1.User')->toXml($params));
  2684. $prepay = model('v1.User')->fromXml($result);
  2685. // 请求失败
  2686. if ($prepay['return_code'] === 'FAIL') {
  2687. return [
  2688. 'code' => 0,
  2689. 'msg' => "微信支付api:{$prepay['return_msg']}",
  2690. ];
  2691. }
  2692. if ($prepay['result_code'] === 'FAIL') {
  2693. return [
  2694. 'code' => 0,
  2695. 'msg' => "微信支付api:{$prepay['err_code_des']}",
  2696. ];
  2697. }
  2698. // 生成 nonce_str 供前端使用
  2699. $paySign = $this->makePaySign($this->miniproInfo['appid'], $params['nonce_str'], $prepay['prepay_id'], $time);
  2700. return [
  2701. 'prepay_id' => $prepay['prepay_id'],
  2702. 'nonceStr' => $nonceStr,
  2703. 'timeStamp' => (string)$time,
  2704. 'paySign' => $paySign
  2705. ];
  2706. }
  2707. /**
  2708. * 生成paySign
  2709. * @param $nonceStr
  2710. * @param $prepay_id
  2711. * @param $timeStamp
  2712. * @return string
  2713. */
  2714. private function makePaySign($appid, $nonceStr, $prepay_id, $timeStamp)
  2715. {
  2716. $data = [
  2717. 'appId' => $appid,
  2718. 'nonceStr' => $nonceStr,
  2719. 'package' => 'prepay_id=' . $prepay_id,
  2720. 'signType' => 'MD5',
  2721. 'timeStamp' => $timeStamp,
  2722. ];
  2723. // 签名步骤一:按字典序排序参数
  2724. ksort($data);
  2725. $string = model('v1.User')->toUrlParams($data);
  2726. // 签名步骤二:在string后加入KEY
  2727. $string = $string . '&key=' . $this->miniproInfo['apikey'];
  2728. // 签名步骤三:MD5加密
  2729. $string = md5($string);
  2730. // 签名步骤四:所有字符转为大写
  2731. $result = strtoupper($string);
  2732. return $result;
  2733. }
  2734. /**
  2735. * 获取我的优惠券
  2736. */
  2737. public function GetMyCouponList($users_id, $type = 0)
  2738. {
  2739. // 筛选条件
  2740. $filter = [];
  2741. //0-未使用 1-已使用 2-已过期
  2742. $filter['a.use_status'] = $type;
  2743. // 订单数据类型
  2744. switch ($type) {
  2745. case '0': // 未使用
  2746. $filter['a.end_time'] = ['>=',getTime()];
  2747. break;
  2748. case '1'; // 已使用
  2749. break;
  2750. case '2'; // 已过期
  2751. unset($filter['a.use_status']);
  2752. $filter['a.end_time'] = ['<',getTime()];
  2753. break;
  2754. }
  2755. $filter['a.users_id'] = $users_id;
  2756. $filter['b.coupon_id'] = ['>',0];
  2757. $result = Db::name('shop_coupon_use')
  2758. ->alias('a')
  2759. ->join('shop_coupon b','a.coupon_id = b.coupon_id','left')
  2760. ->where($filter)
  2761. ->order('a.add_time desc')
  2762. ->paginate(10, false, [
  2763. 'query' => request()->param()
  2764. ]);
  2765. !empty($result) && $result = $result->toArray();
  2766. foreach ($result['data'] as $k => $v ) {
  2767. $v['coupon_form_name'] = '满减券';
  2768. $v['start_time'] = date('Y/m/d',$v['start_time']);
  2769. $v['end_time'] = date('Y/m/d',$v['end_time']);
  2770. switch ($v['coupon_type']) {
  2771. case '1': // 未使用
  2772. $v['coupon_type_name'] = '全部商品';
  2773. break;
  2774. case '2'; // 已使用
  2775. $v['coupon_type_name'] = '指定商品';
  2776. break;
  2777. case '3'; // 已过期
  2778. $v['coupon_type_name'] = '指定分类';
  2779. break;
  2780. }
  2781. $result['data'][$k] = $v;
  2782. }
  2783. return $result;
  2784. }
  2785. /**
  2786. * 领券中心
  2787. */
  2788. public function GetCouponCenter($users_id)
  2789. {
  2790. // 筛选条件
  2791. $filter = [
  2792. 'status' => 1
  2793. ];
  2794. $filter['start_date'] = ['<=',getTime()];
  2795. $filter['end_date'] = ['>=',getTime()];
  2796. $coupon_type = input('param.coupon_type/d');
  2797. if (!empty($coupon_type)) $filter['coupon_type'] = $coupon_type;
  2798. $result = Db::name('shop_coupon')
  2799. ->where($filter)
  2800. ->order('sort_order asc,coupon_id desc')
  2801. ->paginate(6, false, [
  2802. 'query' => request()->param()
  2803. ]);
  2804. if (!empty($result)) {
  2805. $coupon_ids = [];
  2806. $result = $result->toArray();
  2807. foreach ($result['data'] as $k => $v ) {
  2808. $coupon_ids[] = $v['coupon_id'];
  2809. $v['coupon_form_name'] = '满减券';
  2810. $v['start_date'] = date('Y/m/d',$v['start_date']);
  2811. $v['end_date'] = date('Y/m/d',$v['end_date']);
  2812. switch ($v['use_type']) {
  2813. case '1': // 固定期限有效
  2814. $v['use_start_time'] = date('Y/m/d',$v['use_start_time']);
  2815. $v['use_end_time'] = date('Y/m/d',$v['use_end_time']);
  2816. $v['use_type_name'] = $v['use_start_time'].'-'.$v['use_end_time'];
  2817. break;
  2818. case '2'; // 领取当天开始有效
  2819. $v['use_type_name'] = '领取'.$v['valid_days'].'天内有效';
  2820. break;
  2821. case '3'; // 领取次日开始有效
  2822. $v['use_type_name'] = '领取次日开始'.$v['valid_days'].'天内有效';
  2823. break;
  2824. }
  2825. $result['data'][$k] = $v;
  2826. }
  2827. $have_where['users_id'] = $users_id;
  2828. $have_where['coupon_id'] = ['in',$coupon_ids];
  2829. $have_where['use_status'] = 0;
  2830. $have = Db::name('shop_coupon_use')->where($have_where)->column('coupon_id');
  2831. if (!empty($have)){
  2832. foreach ($result['data'] as $k => $v ) {
  2833. if (in_array($v['coupon_id'],$have)){
  2834. $result['data'][$k]['geted'] = 1;//当前还有已领取未使用的
  2835. }
  2836. }
  2837. }
  2838. }
  2839. return $result;
  2840. }
  2841. // 会员余额记录
  2842. public function getUsersMoneyDetails($users = [], $param = [])
  2843. {
  2844. $where = [
  2845. 'status' => ['IN', [2, 3]],
  2846. 'users_id' => $param['users_id'],
  2847. ];
  2848. $UsersMoney = Db::name('users_money')->where($where)->order('moneyid desc')->select();
  2849. // 获取金额明细类型
  2850. $pay_cause_type_arr = Config::get('global.pay_cause_type_arr');
  2851. // 获取金额明细状态
  2852. $pay_status_arr = Config::get('global.pay_status_arr');
  2853. foreach ($UsersMoney as $key => $value) {
  2854. $value['status_name'] = $pay_status_arr[$value['status']];
  2855. $value['add_time'] = MyDate('Y-m-d H:i:s', $value['add_time']);
  2856. $value['cause_type_name'] = $pay_cause_type_arr[$value['cause_type']];
  2857. $UsersMoney[$key] = $value;
  2858. }
  2859. $users['MoneyList'] = $UsersMoney;
  2860. // 会员余额首页
  2861. $this->success('查询成功', null, $users);
  2862. }
  2863. // 会员余额充值
  2864. public function getUsersMoneyRecharge($param = [])
  2865. {
  2866. if (empty($param['usersMoney'])) $this->error('请输入充值金额');
  2867. // 记录类型,充值
  2868. $cause_type = 1;
  2869. // 清理当前会员的未支付的充值记录
  2870. $where = [
  2871. 'status' => 1,
  2872. 'cause_type' => $cause_type,
  2873. 'users_id' => $param['users_id'],
  2874. ];
  2875. Db::name('users_money')->where($where)->delete();
  2876. // 查询当前会员的余额
  2877. $where = [
  2878. 'users_id' => $param['users_id']
  2879. ];
  2880. $UsersMoney = Db::name('users')->where($where)->getField('users_money');
  2881. // 充值记录数据处理
  2882. $time = getTime();
  2883. // 订单号规则
  2884. $OrderNumber = date('Ymd') . $time . rand(10, 100);
  2885. // 支付类型中文名称
  2886. $pay_cause_type_arr = Config::get('global.pay_cause_type_arr');
  2887. // 记录数据
  2888. $insert = [
  2889. 'users_id' => $param['users_id'],
  2890. 'cause_type' => $cause_type,
  2891. 'cause' => $pay_cause_type_arr[$cause_type],
  2892. 'money' => $param['usersMoney'],
  2893. 'users_money' => $UsersMoney + $param['usersMoney'],
  2894. 'pay_method' => 'wechat',
  2895. 'pay_details' => '',
  2896. 'order_number' => $OrderNumber,
  2897. 'status' => 1,
  2898. 'add_time' => $time
  2899. ];
  2900. $insertID = Db::name('users_money')->insertGetId($insert);
  2901. if (!empty($insertID)) {
  2902. $openid = Db::name('wx_users')->where('users_id', $param['users_id'])->getField('openid');
  2903. $Data = $this->GetWechatAppletsPay($openid, $OrderNumber, $param['usersMoney']);
  2904. $ResultData = [
  2905. 'WeChatPay' => $Data,
  2906. 'OrderData' => [
  2907. 'moneyid' => $insertID,
  2908. 'order_number' => $OrderNumber
  2909. ]
  2910. ];
  2911. $this->success('正在支付', null, $ResultData);
  2912. } else {
  2913. $this->error('充值失败');
  2914. }
  2915. }
  2916. // 会员余额充值后续处理
  2917. public function getUsersMoneyRechargePay($param = [])
  2918. {
  2919. // 查询订单信息
  2920. $where = [
  2921. 'cause_type' => 1,
  2922. 'users_id' => $param['users_id'],
  2923. 'moneyid' => $param['moneyid'],
  2924. 'order_number' => $param['order_number'],
  2925. ];
  2926. $usersMoney = Db::name('users_money')->where($where)->find();
  2927. if (empty($usersMoney)) $this->error('订单错误,刷新重试');
  2928. if (1 !== intval($usersMoney['status'])) $this->error('订单已被处理,刷新重试');
  2929. // 查询会员openid
  2930. $openid = Db::name('wx_users')->where('users_id', $param['users_id'])->getField('openid');
  2931. // 下单确认页数据处理
  2932. $WeChatPay = $this->GetWeChatPayDetails($openid, $param['order_number']);
  2933. // 判断处理订单是否真实支付并处理订单
  2934. if (!empty($WeChatPay) && 'SUCCESS' == $WeChatPay['return_code'] && 'OK' == $WeChatPay['return_msg'] && 'SUCCESS' == $WeChatPay['trade_state']) {
  2935. // 充值订单已支付,将订单更新为已支付
  2936. $update = [
  2937. 'status' => 2,
  2938. 'pay_details' => serialize($WeChatPay),
  2939. 'update_time' => getTime(),
  2940. ];
  2941. $ResultID = Db::name('users_money')->where($where)->update($update);
  2942. if (!empty($ResultID)) {
  2943. // 增加会员余额
  2944. $update = [
  2945. 'users_money' => Db::raw('users_money+'.($usersMoney['money'])),
  2946. ];
  2947. $ResultID = Db::name('users')->where('users_id', $param['users_id'])->update($update);
  2948. if (!empty($ResultID)) {
  2949. // 将充值订单更新为已完成
  2950. $update = [
  2951. 'status' => 3,
  2952. 'update_time' => getTime(),
  2953. ];
  2954. Db::name('users_money')->where($where)->update($update);
  2955. //统计余额充值
  2956. eyou_statistics_data(5, floatval($usersMoney['money']));
  2957. // 返回结束
  2958. $this->success('支付完成');
  2959. }
  2960. }
  2961. $this->success('订单处理失败,请联系管理员');
  2962. }
  2963. }
  2964. // 查询会员支付信息详情
  2965. public function GetWeChatPayDetails($openid = 0, $orderCode = 0)
  2966. {
  2967. // 当前时间戳
  2968. $time = getTime();
  2969. // 当前时间戳 + openid 经 MD5加密
  2970. $nonceStr = md5($time . $openid);
  2971. // 调用支付接口参数
  2972. $params = [
  2973. 'appid' => $this->miniproInfo['appid'],
  2974. 'mch_id' => $this->miniproInfo['mchid'],
  2975. 'nonce_str' => $nonceStr,
  2976. 'out_trade_no' => $orderCode
  2977. ];
  2978. // 生成参数签名
  2979. $params['sign'] = $this->ParamsSign($params, $this->miniproInfo['apikey']);
  2980. // 生成参数XML格式
  2981. $ParamsXml = $this->ParamsXml($params);
  2982. // 调用接口返回数据
  2983. $url = 'https://api.mch.weixin.qq.com/pay/orderquery';
  2984. $result = httpRequest($url, 'POST', $ParamsXml);
  2985. // 解析XML格式
  2986. $ResultData = $this->ResultXml($result);
  2987. return $ResultData;
  2988. }
  2989. // 查询订单内的指定的某个商品,判断是否已申请售后或已评价商品
  2990. public function getOrderGoodsDetect($param = [])
  2991. {
  2992. // 查询商品
  2993. $where = [
  2994. 'users_id' => $param['users_id'],
  2995. 'order_id' => $param['order_id'],
  2996. 'details_id' => $param['details_id'],
  2997. 'product_id' => $param['product_id']
  2998. ];
  2999. $field = 'details_id, order_id, users_id, product_id, apply_service, is_comment';
  3000. $orderGoods = Db::name("shop_order_details")->where($where)->field($field)->find();
  3001. if (empty($orderGoods)) $this->error('订单商品不存在');
  3002. $orderGoods['service_id'] = 0;
  3003. // 检测商品是否可以进行下一步操作
  3004. if ('service' == $param['use']) {
  3005. if (!empty($orderGoods['apply_service'])) {
  3006. $where['status'] = ['NEQ', 8];
  3007. $orderGoods['service_id'] = Db::name('shop_order_service')->where($where)->getField('service_id');
  3008. }
  3009. } else if ('comment' == $param['use']) {
  3010. if (!empty($orderGoods['is_comment'])) {
  3011. $url = strval('/pages/article/view?aid=' . $param['product_id']);
  3012. $this->success('订单商品已完成评价', $url, false);
  3013. }
  3014. }
  3015. // 返回信息
  3016. $this->success('检测完成', null, $orderGoods);
  3017. }
  3018. // 查询售后服务单列表
  3019. public function getOrderGoodsServiceList($param = [])
  3020. {
  3021. $where = [
  3022. 'users_id' => $param['users_id'],
  3023. ];
  3024. if (!empty($param['serviceStatus']) && 1 == $param['serviceStatus']) {
  3025. $where['status'] = ['IN', [1, 2, 4, 5]];
  3026. } else if (!empty($param['serviceStatus']) && 2 == $param['serviceStatus']) {
  3027. $where['status'] = ['IN', [6, 7]];
  3028. }
  3029. $field = 'service_id, service_type, users_id, product_name, product_img, status, add_time';
  3030. // 分页参数
  3031. $Query = request()->param();
  3032. // 查询订单数据
  3033. $result = Db::name('shop_order_service')->field($field)->where($where)->paginate(15, false, ['query' => $Query]);
  3034. !empty($result) && $serviceData = $result->toArray();
  3035. if (!empty($serviceData['data'])) {
  3036. $orderServiceType = Config::get('global.order_service_type');
  3037. $orderServiceStatus = Config::get('global.order_service_status');
  3038. foreach ($serviceData['data'] as $key => $value) {
  3039. // 处理数据
  3040. $value['add_time'] = MyDate('Y-m-d H:i:s', $value['add_time']);
  3041. $value['product_img'] = $this->get_default_pic($value['product_img'], true);
  3042. $value['status_name'] = $orderServiceStatus[$value['status']];
  3043. $value['service_type_name'] = $orderServiceType[$value['service_type']];
  3044. // 重载数据
  3045. $serviceData['data'][$key] = $value;
  3046. }
  3047. }
  3048. $this->success('查询成功', null, $serviceData);
  3049. }
  3050. // 查询申请售后的订单商品
  3051. public function getOrderGoodsService($param = [])
  3052. {
  3053. $serviceData = $serviceDataLog = $expressData = [];
  3054. if (!empty($param['service_id'])) {
  3055. // 如果存在则查询售后服务订单
  3056. $where = [
  3057. 'users_id' => $param['users_id'],
  3058. 'service_id' => $param['service_id'],
  3059. ];
  3060. $serviceData = Db::name('shop_order_service')->where($where)->find();
  3061. if (empty($serviceData)) $this->error('售后订单不存在');
  3062. $uploadImg = explode(',', $serviceData['upload_img']);
  3063. foreach ($uploadImg as $key => $value) {
  3064. if (!empty($value)) {
  3065. $uploadImg[$key] = $this->get_default_pic($value, true);
  3066. } else {
  3067. unset($serviceImg[$key]);
  3068. }
  3069. }
  3070. $serviceData['upload_img'] = $uploadImg;
  3071. $serviceData['add_time'] = MyDate('Y-m-d H:i:s', $serviceData['add_time']);
  3072. $serviceData['product_img'] = $this->get_default_pic($serviceData['product_img'], true);
  3073. $serviceData['status_name'] = Config::get('global.order_service_status')[$serviceData['status']];
  3074. $serviceData['service_type_name'] = Config::get('global.order_service_type')[$serviceData['service_type']];
  3075. $serviceData['admin_delivery'] = !empty($serviceData['admin_delivery']) ? unserialize($serviceData['admin_delivery']) : '';
  3076. $serviceData['users_delivery'] = !empty($serviceData['users_delivery']) ? unserialize($serviceData['users_delivery']) : '';
  3077. // 查询售后订单流程记录
  3078. $where = [
  3079. 'service_id' => $param['service_id'],
  3080. ];
  3081. $serviceDataLog = Db::name('shop_order_service_log')->order('log_id desc')->where($where)->select();
  3082. foreach ($serviceDataLog as $key => $value) {
  3083. if (!empty($value['users_id'])) {
  3084. $serviceDataLog[$key]['name'] = '会员';
  3085. } else if (!empty($value['admin_id'])) {
  3086. $serviceDataLog[$key]['name'] = '商家';
  3087. }
  3088. $serviceDataLog[$key]['add_time'] = MyDate('Y-m-d H:i:s', $value['add_time']);
  3089. }
  3090. // 物流数据表
  3091. $expressData = Db::name('shop_express')->select();
  3092. // 追加参数用于查询
  3093. $param['order_id'] = $serviceData['order_id'];
  3094. $param['product_id'] = $serviceData['product_id'];
  3095. $param['details_id'] = $serviceData['details_id'];
  3096. }
  3097. // 查询商品
  3098. $where = [
  3099. 'a.users_id' => $param['users_id'],
  3100. 'a.order_id' => $param['order_id'],
  3101. 'a.details_id' => $param['details_id'],
  3102. 'a.product_id' => $param['product_id']
  3103. ];
  3104. $field = 'a.users_id, a.order_id, b.order_code, a.details_id, a.product_id, a.product_name, a.product_price, a.num as product_num, a.litpic, a.apply_service, b.pay_time, b.consignee, b.mobile, b.province, b.city, b.district, b.address';
  3105. $orderGoods = Db::name("shop_order_details")->alias('a')->join('__SHOP_ORDER__ b', 'a.order_id = b.order_id', 'LEFT')->where($where)->field($field)->find();
  3106. if (empty($orderGoods)) $this->error('订单商品不存在');
  3107. // 处理商品信息
  3108. $orderGoods['litpic'] = $this->get_default_pic($orderGoods['litpic'], true);
  3109. $orderGoods['pay_time'] = MyDate('Y-m-d H:i:s', $orderGoods['pay_time']);
  3110. $Province = $this->GetRegionName($orderGoods['province']);
  3111. $City = $this->GetRegionName($orderGoods['city']);
  3112. $District = $this->GetRegionName($orderGoods['district']);
  3113. $orderGoods['address'] = $Province . ' ' . $City . ' ' . $District . ' ' . $orderGoods['address'];
  3114. // 后台设置的商家收货地址
  3115. $orderGoods['admin_addr'] = getUsersConfigData('addr');
  3116. // 物流数据
  3117. $orderGoods['express'] = $expressData;
  3118. // 售后服务订单
  3119. $orderGoods['service'] = $serviceData;
  3120. $orderGoods['service_log'] = $serviceDataLog;
  3121. $this->success('查询成功', null, $orderGoods);
  3122. }
  3123. // 添加申请售后的订单商品入库
  3124. public function addOrderGoodsService($param = [])
  3125. {
  3126. // 解析参数
  3127. $formData = htmlspecialchars_decode($param['formData']);
  3128. $formData = json_decode(htmlspecialchars_decode($formData), true);
  3129. // 查询是否已申请售后
  3130. $where = [
  3131. 'status' => ['NEQ', 8],
  3132. 'users_id' => $param['users_id'],
  3133. 'order_id' => $formData['order_id'],
  3134. 'product_id' => $formData['product_id'],
  3135. 'details_id' => $formData['details_id']
  3136. ];
  3137. $IsCount = Db::name('shop_order_service')->where($where)->count();
  3138. if (!empty($IsCount)) $this->error('订单商品已申请售后');
  3139. $time = getTime();
  3140. $addService = [
  3141. 'service_type' => !empty($formData['service_type']) ? intval($formData['service_type']) : 0,
  3142. 'users_id' => intval($param['users_id']),
  3143. 'order_id' => !empty($formData['order_id']) ? intval($formData['order_id']) : 0,
  3144. 'order_code' => !empty($formData['order_code']) ? strval($formData['order_code']) : 0,
  3145. 'details_id' => !empty($formData['details_id']) ? intval($formData['details_id']) : 0,
  3146. 'product_id' => !empty($formData['product_id']) ? intval($formData['product_id']) : 0,
  3147. 'product_name' => !empty($formData['product_name']) ? strval($formData['product_name']) : '',
  3148. 'product_num' => !empty($formData['product_num']) ? intval($formData['product_num']) : 0,
  3149. 'product_img' => !empty($formData['litpic']) ? strval($formData['litpic']) : '',
  3150. 'content' => !empty($formData['content']) ? htmlspecialchars($formData['content']) : '',
  3151. 'upload_img' => !empty($formData['uploaded'][0]) ? implode(',', $formData['uploaded']) : '',
  3152. 'address' => strval($formData['address']),
  3153. 'consignee' => !empty($formData['consignee']) ? $formData['consignee'] : '',
  3154. 'mobile' => !empty($formData['mobile']) ? $formData['mobile'] : 0,
  3155. 'refund_price' => !empty($formData['product_price']) ? $formData['product_price'] : 0,
  3156. 'refund_code' => 'HH' . $time . rand(10,100),
  3157. 'add_time' => $time,
  3158. 'update_time' => $time,
  3159. ];
  3160. if (2 == $addService['service_type'] && !empty($addService['refund_price'])) $addService['refund_code'] = 'TK' . $time . rand(10,100);
  3161. $ResultID = Db::name('shop_order_service')->insertGetId($addService);
  3162. // 申请售后后续操作
  3163. if (!empty($ResultID)) {
  3164. // 更新订单明细表中对应商品为申请服务
  3165. $update = [
  3166. 'details_id' => $addService['details_id'],
  3167. 'apply_service' => 1,
  3168. 'update_time' => getTime()
  3169. ];
  3170. Db::name('shop_order_details')->update($update);
  3171. // 添加订单服务记录
  3172. $LogNote = 1 == $addService['service_type'] ? '会员提交换货申请,待管理员审核!' : '会员提交退货申请,待管理员审核!';
  3173. OrderServiceLog($ResultID, $addService['order_id'], $addService['users_id'], 0, $LogNote);
  3174. // 申请成功返回
  3175. $this->success('已申请,待审核');
  3176. } else {
  3177. $this->error('申请售后失败');
  3178. }
  3179. }
  3180. // 取消售后订单会员邮寄物流信息
  3181. public function cancelOrderGoodsService($param = [])
  3182. {
  3183. // 取消服务单
  3184. $where = [
  3185. 'users_id' => $param['users_id'],
  3186. 'service_id' => $param['service_id']
  3187. ];
  3188. $update = [
  3189. 'status' => 8,
  3190. 'update_time' => getTime(),
  3191. ];
  3192. $ResultID = Db::name('shop_order_service')->where($where)->update($update);
  3193. if (!empty($ResultID)) {
  3194. // 更新订单明细表中对应商品为未申请服务
  3195. $where = [
  3196. 'users_id' => $param['users_id'],
  3197. 'details_id' => $param['details_id']
  3198. ];
  3199. $update = [
  3200. 'apply_service' => 0,
  3201. 'update_time' => getTime()
  3202. ];
  3203. Db::name('shop_order_details')->where($where)->update($update);
  3204. // 添加记录单
  3205. $param['status'] = 8;
  3206. $this->addOrderServiceLog($param);
  3207. $this->success('取消成功');
  3208. } else {
  3209. $this->error('取消失败');
  3210. }
  3211. }
  3212. // 添加售后订单会员邮寄物流信息
  3213. public function addServiceUsersDelivery($param = [])
  3214. {
  3215. // 解析物流参数
  3216. $usersDelivery = htmlspecialchars_decode($param['usersDelivery']);
  3217. $usersDelivery = json_decode(htmlspecialchars_decode($usersDelivery), true);
  3218. // 更新处理
  3219. $where = [
  3220. 'users_id' => $param['users_id'],
  3221. 'service_id' => $param['service_id'],
  3222. ];
  3223. $update = [
  3224. 'status' => 4,
  3225. 'users_delivery' => !empty($usersDelivery) ? serialize($usersDelivery) : '',
  3226. 'update_time' => getTime(),
  3227. ];
  3228. $ResultID = Db::name('shop_order_service')->where($where)->update($update);
  3229. if (!empty($ResultID)) {
  3230. // 添加记录单
  3231. $param['status'] = 4;
  3232. $this->addOrderServiceLog($param);
  3233. $this->success('提交物流成功');
  3234. } else {
  3235. $this->error('提交物流失败');
  3236. }
  3237. }
  3238. // 记录商品退换货服务单信息
  3239. private function addOrderServiceLog($param = [])
  3240. {
  3241. if (empty($param)) return false;
  3242. if (2 == $param['status']) {
  3243. $LogNote = '商家通过申请,等待会员将货物寄回商家!';
  3244. } else if (3 == $param['status']) {
  3245. $LogNote = '商家拒绝申请,请联系商家处理!';
  3246. } else if (4 == $param['status']) {
  3247. $LogNote = '会员已将货物发出,等待商家收货!';
  3248. } else if (5 == $param['status']) {
  3249. $LogNote = '商家已收到货物,待管理员进行退换货处理!';
  3250. } else if (6 == $param['status']) {
  3251. $LogNote = '商家已将新货物重新发出,换货完成,服务结束!';
  3252. } else if (7 == $param['status']) {
  3253. $LogNote = '商家已将金额、余额、积分退回,退款完成,服务结束!';
  3254. } else if (8 == $param['status']) {
  3255. $LogNote = '服务单被取消,服务结束!';
  3256. }
  3257. OrderServiceLog($param['service_id'], $param['order_id'], $param['users_id'], 0, $LogNote);
  3258. }
  3259. /************************** 限时折扣 开始 ****************************/
  3260. //获取单次显示折扣
  3261. public function getOneDiscount($param = [])
  3262. {
  3263. $avtive_id = !empty($param['activeid']) ? intval($param['activeid']) : 0;
  3264. $where['status'] = 1;
  3265. $where['is_del'] = 0;
  3266. //如果没传活动id就取当前正在进行的
  3267. if (!empty($avtive_id)){
  3268. $where['active_id'] = $avtive_id;
  3269. $active = Db::name('discount_active')->where($where)->find();
  3270. }else{
  3271. $where['start_date'] = ['<=',getTime()];
  3272. $where['end_date'] = ['>=',getTime()];
  3273. //获取已开始未结束的限时折扣
  3274. $active = Db::name('discount_active')->where($where)->find();
  3275. //如果没有就取即将开始的
  3276. if (empty($active)){
  3277. $active = Db::name('discount_active')
  3278. ->where('status',1)
  3279. ->where('is_del',0)
  3280. ->where('start_date','>',getTime())
  3281. ->order('start_date asc')
  3282. ->find();
  3283. }
  3284. }
  3285. $return = [];
  3286. if (!empty($active)){
  3287. $return['active'] = $active;
  3288. if ($active['start_date'] <= getTime()){
  3289. $return['active']['active_status'] = 10;//进行中
  3290. }else{
  3291. $return['active']['active_status'] = 20;//即将开始
  3292. }
  3293. $param['active_id'] = $return['active']['active_id'];
  3294. $return['goodsList'] = $this->getDiscountGoodsList($param);
  3295. }
  3296. return $return;
  3297. }
  3298. /**
  3299. * 限时折扣:获取限时折扣商品列表
  3300. */
  3301. public function getDiscountGoodsList($param = [])
  3302. {
  3303. $limit = !empty($param['limit']) ? intval($param['limit']) : 6;
  3304. $active_id = $param['active_id'];
  3305. $data = Db::name('discount_active_goods')
  3306. ->alias('a')
  3307. ->field('c.*,b.litpic,b.title,a.*,b.users_price')
  3308. ->join('archives b','a.aid = b.aid')
  3309. ->join('discount_goods c','a.discount_goods_id = c.discount_gid')
  3310. ->where('a.active_id',$active_id)
  3311. ->limit($limit)
  3312. ->getAllWithIndex('aid');
  3313. if (!empty($data)){
  3314. $aids = [];
  3315. foreach ($data as $k => $v){
  3316. $data[$k]['litpic'] = get_default_pic($v['litpic'],true);
  3317. if (1 == $v['is_sku']){
  3318. $aids[] = $v['aid'];
  3319. }
  3320. }
  3321. //多规格
  3322. if (!empty($aids)){
  3323. $sku = Db::name('product_spec_value')
  3324. ->field('*,min(discount_price) as discount_price')
  3325. ->where('aid','in',$aids)
  3326. ->group('aid')
  3327. ->getAllWithIndex('aid');
  3328. }
  3329. foreach ($data as $k => $v){
  3330. if (1 == $v['is_sku'] && !empty($sku[$v['aid']])){
  3331. $v['discount_price'] = $sku[$v['aid']]['discount_price'];
  3332. }
  3333. $v['progress'] = 0;
  3334. if (0 < $v['sales_actual']){
  3335. $count_stock = $v['sales_actual']+$v['discount_stock']+$v['virtual_sales'];
  3336. $v['progress'] = intval(($v['sales_actual']+$v['virtual_sales'])/$count_stock*100);
  3337. }else{
  3338. if (0 < $v['virtual_sales']){
  3339. $v['progress'] = intval($v['virtual_sales']/($v['virtual_sales']+$v['discount_stock'])*100);;
  3340. }
  3341. }
  3342. if (0 < $v['virtual_sales']){
  3343. $v['sales_actual'] = $v['sales_actual'] +$v['virtual_sales'];
  3344. }
  3345. $data[$k] = $v;
  3346. }
  3347. }
  3348. return $data;
  3349. }
  3350. /**
  3351. * 获取限时折扣列表
  3352. */
  3353. public function GetDiscountIndex($param = [])
  3354. {
  3355. $active_id = $param['active_id'];
  3356. $page = !empty($param['page']) ? $param['page'] : 1;
  3357. $pagesize = !empty($param['limit']) ? $param['limit'] : 20;
  3358. $cacheKey = 'api-'.md5(__CLASS__.__FUNCTION__.json_encode(func_get_args()));
  3359. $result = cache($cacheKey);
  3360. if (true || empty($result)) {
  3361. $paginate = array(
  3362. 'page' => $page,
  3363. );
  3364. $pages = Db::name('discount_active_goods')
  3365. ->alias('a')
  3366. ->field('c.*,b.litpic,b.title,a.*,b.users_price')
  3367. ->join('archives b','a.aid = b.aid')
  3368. ->join('discount_goods c','a.discount_goods_id = c.discount_gid')
  3369. ->where('a.active_id',$active_id)
  3370. ->paginate($pagesize, false, $paginate);
  3371. $result = $pages->toArray();
  3372. $aids = [];
  3373. foreach ($result['data'] as $k => $v){
  3374. $result['data'][$k]['litpic'] = get_default_pic($v['litpic'],true);
  3375. if (1 == $v['is_sku']){
  3376. $aids[] = $v['aid'];
  3377. }
  3378. }
  3379. //多规格
  3380. if (!empty($aids)) {
  3381. $sku = Db::name('product_spec_value')
  3382. ->field('*,min(discount_price) as discount_price')
  3383. ->where('aid', 'in', $aids)
  3384. ->group('aid')
  3385. ->getAllWithIndex('aid');
  3386. }
  3387. //sales_actual //
  3388. foreach ($result['data'] as $k => $v){
  3389. if (1 == $v['is_sku'] && !empty($sku[$v['aid']])){
  3390. $v['discount_price'] = $sku[$v['aid']]['discount_price'];
  3391. }
  3392. $v['progress'] = 0;
  3393. if (0 < $v['sales_actual']){
  3394. $count_stock = $v['sales_actual']+$v['discount_stock']+$v['virtual_sales'];
  3395. $v['progress'] = intval(($v['sales_actual']+$v['virtual_sales'])/$count_stock*100);
  3396. }else{
  3397. if (0 < $v['virtual_sales']){
  3398. $v['progress'] = intval($v['virtual_sales']/($v['virtual_sales']+$v['discount_stock'])*100);;
  3399. }
  3400. }
  3401. if (0 < $v['virtual_sales']){
  3402. $v['sales_actual'] = $v['sales_actual'] + $v['virtual_sales'];
  3403. }
  3404. $result['data'][$k] = $v;
  3405. }
  3406. if(1 == $page){
  3407. $result['active'] = $this->GetDiscount($active_id);
  3408. }
  3409. cache($cacheKey, $result, null, 'GetDiscountIndex');
  3410. }
  3411. return $result;
  3412. }
  3413. //获取限时折扣活动信息(不包括折扣商品信息)
  3414. public function GetDiscount($active_id = 0){
  3415. $data = Db::name('discount_active')->where('active_id',$active_id)->find();
  3416. if ($data['start_date'] <= getTime()){
  3417. $data['active_status'] = 10;//进行中
  3418. }else{
  3419. $data['active_status'] = 20;//即将开始
  3420. }
  3421. return $data;
  3422. }
  3423. /************************** 限时折扣 结束 ****************************/
  3424. /************************** 会员升级 开始 ****************************/
  3425. // 会员升级
  3426. public function upgradeUserLevel($param = [])
  3427. {
  3428. if (empty($param['type_id'])) $this->error('缺少升级类型');
  3429. $users_type_manage = Db::name('users_type_manage')->where('type_id',$param['type_id'])->find();
  3430. // 记录类型,消费
  3431. $cause_type = 0;
  3432. // 清理当前会员的未支付的充值记录
  3433. $where = [
  3434. 'status' => 1,
  3435. 'cause_type' => $cause_type,
  3436. 'users_id' => $this->users_id,
  3437. ];
  3438. Db::name('users_money')->where($where)->delete();
  3439. $times = getTime();
  3440. // 查询当前会员的余额
  3441. $where = [
  3442. 'users_id' => $this->users_id
  3443. ];
  3444. $users = Db::name('users')->where($where)->find();
  3445. $UsersMoney = $users['users_money'];
  3446. $level_name = Db::name('users_level')->where('level_id',$users['level'])->value('level_name');
  3447. // 充值记录数据处理
  3448. $time = getTime();
  3449. // 订单号规则
  3450. $OrderNumber = date('Ymd') . $time . rand(10, 100);
  3451. $pay_detail = "会员当前级别为【{$level_name}】,使用微信支付【{$users_type_manage['type_name']}】,支付金额为{$users_type_manage['price']}";
  3452. // 记录数据
  3453. $insert = [
  3454. 'users_id' => $this->users_id,
  3455. 'cause_type' => $cause_type,
  3456. 'cause' => serialize($users_type_manage),
  3457. 'money' => $users_type_manage['price'],
  3458. 'users_money' => $UsersMoney - $users_type_manage['price'],
  3459. 'pay_method' => 'wechat',
  3460. 'pay_details' => serialize($pay_detail),
  3461. 'order_number' => $OrderNumber,
  3462. 'level_id' => $users_type_manage['level_id'],
  3463. 'status' => 1,
  3464. 'add_time' => $time
  3465. ];
  3466. $insertID = Db::name('users_money')->insertGetId($insert);
  3467. if (!empty($insertID)) {
  3468. if ('wechat' == $param['pay_type']) {
  3469. // 微信支付
  3470. $openid = Db::name('wx_users')->where('users_id', $param['users_id'])->getField('openid');
  3471. $notify_url = url('api/v1/Api/wxpay_notify_users', [], true, true, 1, 2);
  3472. $Data = $this->GetWechatAppletsPay($openid, $OrderNumber, $users_type_manage['price'],$notify_url);
  3473. $ResultData = [
  3474. 'WeChatPay' => $Data,
  3475. 'OrderData' => [
  3476. 'moneyid' => $insertID,
  3477. 'order_number' => $OrderNumber
  3478. ]
  3479. ];
  3480. $this->success('正在支付', null, $ResultData);
  3481. } else if ('balance' == $param['pay_type']) {
  3482. //先判断余额够不够
  3483. if ($users['users_money'] < $users_type_manage['price']){
  3484. $this->error('余额不足!');
  3485. }
  3486. // 余额支付
  3487. $UpOrderData = [
  3488. 'status' => 2,
  3489. 'pay_name' => 'balance',
  3490. 'update_time' => getTime()
  3491. ];
  3492. $ReturnID = Db::name('users_money')->where('order_number', $OrderNumber)->update($UpOrderData);
  3493. if (!empty($ReturnID)) {
  3494. $limit_arr = Config::get('global.admin_member_limit_arr');
  3495. $day = $limit_arr[$users_type_manage['limit_id']]['maturity_days'];
  3496. $users_update['level_maturity_days'] = Db::Raw('level_maturity_days +'.$day);
  3497. if (empty($users['level_maturity_days'])){
  3498. $users_update['open_level_time'] = getTime();
  3499. }
  3500. $users_update['level'] = $users_type_manage['level_id'];
  3501. $users_update['update_time'] = getTime();
  3502. $users_update['users_money'] = Db::Raw('users_money-'.$users_type_manage['price']);
  3503. Db::name('users')->where('users_id', $param['users_id'])->update($users_update);
  3504. $url = '/pages/user/index';
  3505. $this->success('支付完成', $url);
  3506. }
  3507. }
  3508. } else {
  3509. $this->error('会员升级失败');
  3510. }
  3511. }
  3512. // 会员升级
  3513. public function handleUpgradeUserLevel($param = [])
  3514. {
  3515. // 查询订单信息
  3516. $where = [
  3517. 'cause_type' => 0,
  3518. 'users_id' => $this->users_id,
  3519. 'order_number' => $param['order_number'],
  3520. ];
  3521. $usersMoney = Db::name('users_money')->where($where)->find();
  3522. if (empty($usersMoney)) $this->error('订单错误,刷新重试');
  3523. if (1 !== intval($usersMoney['status'])) $this->error('订单已被处理,刷新重试');
  3524. // 查询会员openid
  3525. $openid = Db::name('wx_users')->where('users_id', $param['users_id'])->getField('openid');
  3526. // 下单确认页数据处理
  3527. $WeChatPay = $this->GetWeChatPayDetails($openid, $param['order_number']);
  3528. // 判断处理订单是否真实支付并处理订单
  3529. if (!empty($WeChatPay) && 'SUCCESS' == $WeChatPay['return_code'] && 'OK' == $WeChatPay['return_msg'] && 'SUCCESS' == $WeChatPay['trade_state']) {
  3530. // 充值订单已支付,将订单更新为已支付
  3531. $update = [
  3532. 'status' => 2,
  3533. 'update_time' => getTime(),
  3534. ];
  3535. $ResultID = Db::name('users_money')->where($where)->update($update);
  3536. if (!empty($ResultID)) {
  3537. $usersMoney['cause'] = unserialize($usersMoney['cause']);
  3538. $level_maturity_days = Db::name('users')->where('users_id', $param['users_id'])->value('level_maturity_days');
  3539. $limit_arr = Config::get('global.admin_member_limit_arr');
  3540. $day = $limit_arr[$usersMoney['cause']['limit_id']]['maturity_days'];
  3541. $users_update['level_maturity_days'] = Db::Raw('level_maturity_days +'.$day);
  3542. if (empty($level_maturity_days)){
  3543. $users_update['open_level_time'] = getTime();
  3544. }
  3545. $users_update['level'] = $usersMoney['cause']['level_id'];
  3546. $users_update['update_time'] = getTime();
  3547. Db::name('users')->where('users_id', $param['users_id'])->update($users_update);
  3548. // 返回结束
  3549. $this->success('支付完成');
  3550. }
  3551. $this->success('订单处理失败,请联系管理员');
  3552. }
  3553. }
  3554. // 微信小程序支付后续处理
  3555. public function WechatAppletsPayDealWithUsersMoney($PostData = [], $notify = false)
  3556. {
  3557. $OpenID = !empty($PostData['openid']) ? $PostData['openid'] : '';
  3558. $UsersID = !empty($PostData['users_id']) ? $PostData['users_id'] : '';
  3559. $order_number = $PostData['order_number'];
  3560. if (!empty($moneyid) && !empty($order_number)) {
  3561. $where = [
  3562. 'users_id' => $UsersID,
  3563. 'order_number' => $order_number,
  3564. ];
  3565. //查询订单状态
  3566. $order = Db::name('users_money')->where($where)->find();
  3567. if (empty($order)) {
  3568. $this->error('无效订单!');
  3569. } else if (1 < $order['status']) {
  3570. // 订单已支付
  3571. if ($notify === true) { // 异步
  3572. return [
  3573. 'code' => 1,
  3574. 'msg' => 'ok',
  3575. ];
  3576. } else { // 同步
  3577. $this->success('支付完成', '/pages/user/index');
  3578. }
  3579. }
  3580. // 当前时间戳
  3581. $time = getTime();
  3582. // 当前时间戳 + OpenID 经 MD5加密
  3583. $nonceStr = md5($time . $OpenID);
  3584. // 调用支付接口参数
  3585. $params = [
  3586. 'appid' => $this->miniproInfo['appid'],
  3587. 'mch_id' => $this->miniproInfo['mchid'],
  3588. 'nonce_str' => $nonceStr,
  3589. 'out_trade_no' => $order_number
  3590. ];
  3591. // 生成参数签名
  3592. $params['sign'] = $this->ParamsSign($params, $this->miniproInfo['apikey']);
  3593. // 生成参数XML格式
  3594. $ParamsXml = $this->ParamsXml($params);
  3595. // 调用接口返回数据
  3596. $url = 'https://api.mch.weixin.qq.com/pay/orderquery';
  3597. $result = $this->HttpsPost($url, $ParamsXml);
  3598. // 解析XML格式
  3599. $ResultData = $this->ResultXml($result);
  3600. // 订单是否存在
  3601. if (!empty($ResultData) && 'SUCCESS' == $ResultData['return_code'] && 'OK' == $ResultData['return_msg']) {
  3602. // if ('NOTPAY' == $ResultData['trade_state'] && !empty($ResultData['trade_state_desc'])) {
  3603. // // 订单未支付
  3604. // $this->error($ResultData['trade_state_desc']);
  3605. // }
  3606. if ('SUCCESS' == $ResultData['trade_state']) {
  3607. // 订单已支付,处理订单流程
  3608. $OrderWhere = [
  3609. 'order_number' => $order_number,
  3610. 'users_id' => $UsersID
  3611. ];
  3612. $OrderData = [
  3613. 'status' => 2,
  3614. 'update_time' => getTime()
  3615. ];
  3616. $ResultID = Db::name('users_money')->where($OrderWhere)->update($OrderData);
  3617. if (!empty($ResultID)) {
  3618. $order['cause'] = unserialize($order['cause']);
  3619. $level_maturity_days = Db::name('users')->where('users_id', $UsersID)->value('level_maturity_days');
  3620. $limit_arr = Config::get('global.admin_member_limit_arr');
  3621. $day = $limit_arr[$order['cause']['limit_id']]['maturity_days'];
  3622. $users_update['level_maturity_days'] = Db::Raw('level_maturity_days +'.$day);
  3623. if (empty($level_maturity_days)){
  3624. $users_update['open_level_time'] = getTime();
  3625. }
  3626. $users_update['level'] = $order['cause']['level_id'];
  3627. $users_update['update_time'] = getTime();
  3628. Db::name('users')->where('users_id', $UsersID)->update($users_update);
  3629. // 订单支付完成
  3630. if ($notify === true) { // 异步
  3631. return [
  3632. 'code' => 1,
  3633. 'msg' => 'ok',
  3634. ];
  3635. } else { // 同步
  3636. $url = '/pages/user/index';
  3637. $this->success('支付完成', $url);
  3638. }
  3639. }
  3640. }
  3641. }
  3642. }
  3643. }
  3644. /************************** 会员升级 结束 ****************************/
  3645. /************************** 视频购买 开始 ****************************/
  3646. // 视频购买
  3647. public function buyMedia($param = [])
  3648. {
  3649. if (empty($param['aid'])) $this->error('缺少必要参数');
  3650. // 清理当前会员的未支付的充值记录
  3651. $where = [
  3652. 'order_status' => 0,
  3653. 'users_id' => $this->users_id,
  3654. ];
  3655. Db::name('media_order')->where($where)->delete();
  3656. $users = Db::name('users')
  3657. ->field('a.*,b.discount')
  3658. ->alias('a')
  3659. ->join('users_level b','a.level = b.level_id','left')
  3660. ->where('a.users_id',$this->users_id)
  3661. ->find();
  3662. $list = Db::name('archives')->where('aid',$param['aid'])->find();
  3663. $price = unifyPriceHandle($list['users_price'] * ($users['discount'] / 100));
  3664. // 生成订单并保存到数据库
  3665. $time = getTime();
  3666. $OrderData = [
  3667. 'order_code' => date('Y') . $time . rand(10,100),
  3668. 'users_id' => $this->users_id,
  3669. 'mobile' => !empty($users['mobile']) ?$users['mobile'] : '',
  3670. 'order_status' => 0,
  3671. 'order_amount' => $price,
  3672. 'pay_time' => '',
  3673. 'pay_name' => '',
  3674. 'wechat_pay_type' => '',
  3675. 'pay_details' => '',
  3676. 'product_id' => $list['aid'],
  3677. 'product_name' => $list['title'],
  3678. 'product_litpic' => get_default_pic($list['litpic']),
  3679. 'lang' => get_home_lang(),
  3680. 'add_time' => $time,
  3681. 'update_time' => $time
  3682. ];
  3683. $insertID = Db::name('media_order')->insertGetId($OrderData);
  3684. if (!empty($insertID)) {
  3685. if ('wechat' == $param['pay_type']) {
  3686. // 微信支付
  3687. $openid = Db::name('wx_users')->where('users_id', $param['users_id'])->getField('openid');
  3688. $notify_url = url('api/v1/Api/wxpay_notify_media', [], true, true, 1, 2);
  3689. $Data = $this->GetWechatAppletsPay($openid, $OrderData['order_code'], $price,$notify_url);
  3690. $ResultData = [
  3691. 'WeChatPay' => $Data,
  3692. 'OrderData' => [
  3693. 'order_id' => $insertID,
  3694. 'order_code' => $OrderData['order_code']
  3695. ]
  3696. ];
  3697. $this->success('正在支付', null, $ResultData);
  3698. } else if ('balance' == $param['pay_type']) {
  3699. //先判断余额够不够
  3700. if ($users['users_money'] < $price){
  3701. $this->error('余额不足!');
  3702. }
  3703. // 订单更新数据,更新为已付款
  3704. $pay_details['unified_id'] = $insertID;
  3705. $pay_details['unified_number'] = $OrderData['order_code'];
  3706. $pay_details['payment_type'] = '余额支付';
  3707. $pay_details['payment_amount'] = $price;
  3708. $pay_details['transaction_type'] = 8;
  3709. // 余额支付
  3710. $UpOrderData = [
  3711. 'order_status' => 1,
  3712. 'pay_time' => getTime(),
  3713. 'pay_name' => 'balance',
  3714. 'pay_details' => serialize($pay_details),
  3715. 'update_time' => getTime()
  3716. ];
  3717. $ReturnID = Db::name('media_order')->where('order_code', $OrderData['order_code'])->update($UpOrderData);
  3718. if (!empty($ReturnID)) {
  3719. $Where = [
  3720. 'users_id' => $this->users_id
  3721. ];
  3722. $UsersData = [
  3723. 'users_money' => Db::raw('users_money-'.$OrderData['order_amount']),
  3724. 'update_time' => getTime()
  3725. ];
  3726. Db::name('users')->where($Where)->update($UsersData);
  3727. UsersMoneyRecording($OrderData['order_code'], $users, $OrderData['order_amount'], '视频购买', 3);
  3728. $url = '/pages/user/index';
  3729. $this->success('支付完成', $url);
  3730. }
  3731. }
  3732. } else {
  3733. $this->error('会员升级失败');
  3734. }
  3735. }
  3736. // 会员升级
  3737. public function handleBuyMedia($param = [])
  3738. {
  3739. // 查询订单信息
  3740. $where = [
  3741. 'users_id' => $this->users_id,
  3742. 'order_code' => $param['order_code'],
  3743. ];
  3744. $order = Db::name('media_order')->where($where)->find();
  3745. if (empty($order)) $this->error('订单错误,刷新重试');
  3746. if (0 !== intval($order['status'])) $this->error('订单已被处理,刷新重试');
  3747. // 查询会员openid
  3748. $openid = Db::name('wx_users')->where('users_id', $param['users_id'])->getField('openid');
  3749. // 下单确认页数据处理
  3750. $WeChatPay = $this->GetWeChatPayDetails($openid, $param['order_code']);
  3751. // 判断处理订单是否真实支付并处理订单
  3752. if (!empty($WeChatPay) && 'SUCCESS' == $WeChatPay['return_code'] && 'OK' == $WeChatPay['return_msg'] && 'SUCCESS' == $WeChatPay['trade_state']) {
  3753. // 视频订单已支付,将订单更新为已支付
  3754. // 订单更新数据,更新为已付款
  3755. $pay_details['unified_id'] = $order['order_id'];
  3756. $pay_details['unified_number'] = $order['order_code'];
  3757. $pay_details['payment_type'] = '微信支付';
  3758. $pay_details['payment_amount'] = $order['order_amount'];
  3759. $pay_details['transaction_type'] = 8;
  3760. // 余额支付
  3761. $UpOrderData = [
  3762. 'order_status' => 1,
  3763. 'pay_time' => getTime(),
  3764. 'pay_name' => 'wechat',
  3765. 'wechat_pay_type' => 'WeChatScanCode',
  3766. 'pay_details' => serialize($pay_details),
  3767. 'update_time' => getTime()
  3768. ];
  3769. $return = Db::name('media_order')->where('order_code', $param['order_code'])->update($UpOrderData);
  3770. if (!empty($return)) {
  3771. // 返回结束
  3772. $this->success('支付完成');
  3773. }
  3774. $this->success('订单处理失败,请联系管理员');
  3775. }
  3776. }
  3777. // 微信小程序支付后续处理
  3778. public function WechatAppletsPayDealWithMedia($PostData = [], $notify = false)
  3779. {
  3780. $OpenID = !empty($PostData['openid']) ? $PostData['openid'] : '';
  3781. $UsersID = !empty($PostData['users_id']) ? $PostData['users_id'] : '';
  3782. $order_code = $PostData['order_code'];
  3783. if (!empty($order_code)) {
  3784. $where = [
  3785. 'users_id' => $UsersID,
  3786. 'order_code' => $order_code,
  3787. ];
  3788. //查询订单状态
  3789. $order = Db::name('media_order')->where($where)->find();
  3790. if (empty($order)) {
  3791. $this->error('无效订单!');
  3792. } else if (0 < $order['status']) {
  3793. // 订单已支付
  3794. if ($notify === true) { // 异步
  3795. return [
  3796. 'code' => 1,
  3797. 'msg' => 'ok',
  3798. ];
  3799. } else { // 同步
  3800. $this->success('支付完成', '/pages/user/index');
  3801. }
  3802. }
  3803. // 当前时间戳
  3804. $time = getTime();
  3805. // 当前时间戳 + OpenID 经 MD5加密
  3806. $nonceStr = md5($time . $OpenID);
  3807. // 调用支付接口参数
  3808. $params = [
  3809. 'appid' => $this->miniproInfo['appid'],
  3810. 'mch_id' => $this->miniproInfo['mchid'],
  3811. 'nonce_str' => $nonceStr,
  3812. 'out_trade_no' => $order_code
  3813. ];
  3814. // 生成参数签名
  3815. $params['sign'] = $this->ParamsSign($params, $this->miniproInfo['apikey']);
  3816. // 生成参数XML格式
  3817. $ParamsXml = $this->ParamsXml($params);
  3818. // 调用接口返回数据
  3819. $url = 'https://api.mch.weixin.qq.com/pay/orderquery';
  3820. $result = $this->HttpsPost($url, $ParamsXml);
  3821. // 解析XML格式
  3822. $ResultData = $this->ResultXml($result);
  3823. // 订单是否存在
  3824. if (!empty($ResultData) && 'SUCCESS' == $ResultData['return_code'] && 'OK' == $ResultData['return_msg']) {
  3825. // if ('NOTPAY' == $ResultData['trade_state'] && !empty($ResultData['trade_state_desc'])) {
  3826. // // 订单未支付
  3827. // $this->error($ResultData['trade_state_desc']);
  3828. // }
  3829. if ('SUCCESS' == $ResultData['trade_state']) {
  3830. // 订单已支付,处理订单流程
  3831. $OrderWhere = [
  3832. 'order_code' => $order_code,
  3833. 'users_id' => $UsersID
  3834. ];
  3835. // 订单更新数据,更新为已付款
  3836. $pay_details['unified_id'] = $order['order_id'];
  3837. $pay_details['unified_number'] = $order['order_code'];
  3838. $pay_details['payment_type'] = '微信支付';
  3839. $pay_details['payment_amount'] = $order['order_amount'];
  3840. $pay_details['transaction_type'] = 8;
  3841. // 余额支付
  3842. $UpOrderData = [
  3843. 'order_status' => 1,
  3844. 'pay_time' => getTime(),
  3845. 'pay_name' => 'wechat',
  3846. 'wechat_pay_type' => 'WeChatScanCode',
  3847. 'pay_details' => serialize($pay_details),
  3848. 'update_time' => getTime()
  3849. ];
  3850. $ResultID = Db::name('media_order')->where($OrderWhere)->update($UpOrderData);
  3851. if (!empty($ResultID)) {
  3852. // 订单支付完成
  3853. if ($notify === true) { // 异步
  3854. return [
  3855. 'code' => 1,
  3856. 'msg' => 'ok',
  3857. ];
  3858. } else { // 同步
  3859. $url = '/pages/user/index';
  3860. $this->success('支付完成', $url);
  3861. }
  3862. }
  3863. }
  3864. }
  3865. }
  3866. }
  3867. /************************** 视频购买 结束 ****************************/
  3868. }