UserStringCodePlus.php 157 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034
  1. <?php
  2. /**
  3. * 厦门云联储网络科技有限公司
  4. * https://www.baokuaiyun.com
  5. * Copyright (c) 2023 爆块云 All rights reserved.
  6. */
  7. namespace app\models;
  8. use app\constants\OptionSetting;
  9. use Yii;
  10. use \app\plugins\scanCodePay\models\Order as ScanOrder;
  11. use yii\behaviors\TimestampBehavior;
  12. use yii\db\ActiveRecord;
  13. use yii\db\Expression;
  14. use yii\helpers\ArrayHelper;
  15. use yii\helpers\Json;
  16. /**
  17. * This is the model class for table "{{%user_string_code_plus}}".
  18. *
  19. * @property integer $id
  20. * @property integer $store_id
  21. * @property integer $user_id
  22. * @property integer $parent_id
  23. * @property integer $parent_node
  24. * @property string $recommend_relation
  25. * @property integer $layer
  26. * @property string $recommend_relation_node
  27. * @property integer $layer_node
  28. * @property integer $team_num
  29. * @property integer $area_key
  30. * @property integer $layer_rank
  31. * @property integer $created_at
  32. * @property integer $updated_at
  33. * @property integer $saas_id
  34. */
  35. class UserStringCodePlus extends \yii\db\ActiveRecord
  36. {
  37. const MODEL_SHOP = 0;
  38. const MODEL_ALLIANCE = 1;
  39. const ALLIANCE_STORE_ID = -1;
  40. const Serial_Code_Collaboration = -99;
  41. const MODEL_NAME_LIST = array(
  42. self::MODEL_SHOP => '小模型',
  43. self::MODEL_ALLIANCE => '大模型',
  44. );
  45. /**
  46. * @inheritdoc
  47. */
  48. public static function tableName()
  49. {
  50. return '{{%user_string_code_plus}}';
  51. }
  52. public function behaviors()
  53. {
  54. return [
  55. [
  56. 'class' => TimestampBehavior::class,
  57. 'attributes' => [
  58. ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
  59. ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at']
  60. ]
  61. ]
  62. ];
  63. }
  64. /**
  65. * @inheritdoc
  66. */
  67. public function rules()
  68. {
  69. return [
  70. [['recommend_relation', 'recommend_relation_node'], 'string'],
  71. [
  72. [
  73. 'store_id',
  74. 'user_id',
  75. 'parent_id',
  76. 'layer',
  77. 'layer_node',
  78. 'created_at',
  79. 'updated_at',
  80. 'parent_node',
  81. 'team_num',
  82. 'area_key',
  83. 'layer_rank',
  84. 'saas_id'
  85. ],
  86. 'integer'
  87. ],
  88. ];
  89. }
  90. /**
  91. * @inheritdoc
  92. */
  93. public function attributeLabels()
  94. {
  95. return [
  96. 'id' => 'ID',
  97. 'store_id' => '店铺id',
  98. 'user_id' => '用户id',
  99. 'parent_id' => '分销上级id',
  100. 'parent_node' => '父节点',
  101. 'recommend_relation_node' => '节点推荐关系',
  102. 'layer_node' => '节点层级',
  103. 'recommend_relation' => '分销推荐关系',
  104. 'layer' => '分销层级',
  105. 'area_key' => '区域Key',
  106. 'layer_rank' => '层级排位',
  107. 'team_num' => '团队人数',
  108. 'created_at' => '创建时间',
  109. 'updated_at' => '更新时间',
  110. 'saas_id' => 'saas用户id',
  111. ];
  112. }
  113. /**
  114. * @param $store_id
  115. * @return bool
  116. */
  117. public static function checkSettingByStoreId($store_id, $setting)
  118. {
  119. if (!$setting) {
  120. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】未配置串码设置"], "app_debug.log");
  121. return false;
  122. }
  123. if (!isset($setting['string_code_store_switch']) || $setting['string_code_store_switch'] != 1) {
  124. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】未开启串码功能"], "app_debug.log");
  125. return false;
  126. }
  127. if (!isset($setting['string_code_model'])) {
  128. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】未设置串码模式"], "app_debug.log");
  129. return false;
  130. }
  131. if (!is_array($setting['string_code_model'])) {
  132. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】串码模式配置不是数组"], "app_debug.log");
  133. return false;
  134. }
  135. // if (!isset($setting['string_code_max_layer']) || $setting['string_code_max_layer'] <= 0) {
  136. // //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】未设置串码最大层级"], "app_debug.log");
  137. // return false;
  138. // }
  139. // if (!isset($setting['string_code_condition_value']) || $setting['string_code_condition_value'] <= 0) {
  140. // //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】未设置结点加入金额条件"], "app_debug.log");
  141. // return false;
  142. // }
  143. // if (!isset($setting['string_code_root_user_id']) || $setting['string_code_root_user_id'] <= 0) {
  144. // //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】未设置根结点用户"], "app_debug.log");
  145. // return false;
  146. // }
  147. // if (!isset($setting['string_code_scan_scale_1']) || $setting['string_code_scan_scale_1'] <= 0) {
  148. // //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】未设置当面付比例"], "app_debug.log");
  149. // return false;
  150. // }
  151. // if (!isset($setting['string_code_order_scale_1']) || $setting['string_code_order_scale_1'] <= 0) {
  152. // //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】未设置订单比例"], "app_debug.log");
  153. // return false;
  154. // }
  155. // if (!isset($setting['string_code_pv_scale_1']) || $setting['string_code_pv_scale_1'] <= 0) {
  156. // //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】未设置PV比例"], "app_debug.log");
  157. // return false;
  158. // }
  159. // if ($store_id != self::ALLIANCE_STORE_ID) {
  160. // if (!isset($setting['string_code_scan_scale_0']) || $setting['string_code_scan_scale_0'] <= 0) {
  161. // //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】未设置当面付比例"], "app_debug.log");
  162. // return false;
  163. // }
  164. // if (!isset($setting['string_code_order_scale_0']) || $setting['string_code_order_scale_0'] <= 0) {
  165. // //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】未设置订单比例"], "app_debug.log");
  166. // return false;
  167. // }
  168. // if (!isset($setting['string_code_pv_scale_0']) || $setting['string_code_pv_scale_0'] <= 0) {
  169. // //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】未设置PV比例"], "app_debug.log");
  170. // return false;
  171. // }
  172. // }
  173. return true;
  174. }
  175. /**
  176. * 加入节点
  177. * @param $order
  178. * @return bool
  179. */
  180. public static function joinNode($order, $is_scan = 0)
  181. {
  182. $store_id = $order->store_id;
  183. $user_id = $order->user_id;
  184. $order_id = $order->id;
  185. $order_no = $order->order_no;
  186. $temporder = json_encode($order);
  187. //debug_log([__METHOD__, __LINE__, "订单信息:【{$temporder}】- $store_id - $user_id - $order_id - $order_no - $is_scan "], "app_debug.log");
  188. $saas_user_id = SaasUser::findSaasIdByUserId($user_id);
  189. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  190. $setting = $setting ? Json::decode($setting['value']) : [];
  191. $check_res = self::checkSettingByStoreId($store_id, $setting);
  192. if (!$check_res) {
  193. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】设置条件不满足"], "app_debug.log");
  194. return false;
  195. }
  196. //门店模式
  197. $string_code_shop_value = 0;
  198. if ($store_id != -1) {
  199. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  200. $setting = $setting ? Json::decode($setting['value']) : [];
  201. $string_code_shop_value = $setting['string_code_shop_value'] ? $setting['string_code_shop_value'] : 0;
  202. }
  203. //debug_log([__METHOD__, __LINE__, "加入节点 门店模式:{$string_code_shop_value},0品牌模式 1门店模式"], "app_debug.log");
  204. list($model_switch_shop, $model_switch_alliance) = self::getModelSwitchBySettingArray($setting['string_code_model']);
  205. if ($model_switch_shop) {
  206. $res = self::joinNodeByShopModel($store_id, $user_id, $setting, self::MODEL_SHOP);
  207. if ($res) {
  208. UserStringCodeOrderHistory::sendRedPacket($store_id, $user_id, self::MODEL_SHOP, $order_id, $order_no, $is_scan, $string_code_shop_value);
  209. }
  210. }
  211. if ($model_switch_alliance) {
  212. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, self::ALLIANCE_STORE_ID, OptionSetting::SHARE_GROUP_NAME, '{}');
  213. $setting = $setting ? Json::decode($setting['value']) : [];
  214. $res = self::joinNodeByAllianceModel(self::ALLIANCE_STORE_ID, $saas_user_id, $setting, self::MODEL_ALLIANCE);
  215. if ($res) {
  216. UserStringCodeOrderHistory::sendRedPacket($store_id, $user_id, self::MODEL_ALLIANCE, $order_id, $order_no, $is_scan, $string_code_shop_value);
  217. }
  218. }
  219. return true;
  220. }
  221. public static function joinNodeByShopModel($store_id, $user_id, $setting, $model_val, $string_code_shop_value = 0)
  222. {
  223. $user = User::findOne($user_id);
  224. $saas_user_id = SaasUser::findSaasIdByUserId($user_id);
  225. $model_name = self::MODEL_NAME_LIST[self::MODEL_SHOP];
  226. $string_code_root_user_id = self::getRootUserId($store_id, self::MODEL_SHOP);
  227. $user_string_code = self::findOne(['store_id' => $store_id, 'user_id' => $user_id]);
  228. if ($user_string_code) {
  229. //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$model_name},店铺:【{$store_id}】,用户:{$user_id}已加入串码节点"], "app_debug.log");
  230. return false;
  231. }
  232. $root_string_code = self::findOne(['store_id' => $store_id, 'user_id' => $string_code_root_user_id]);
  233. if (!$root_string_code) {
  234. //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$model_name},店铺:【{$store_id}】,用户:{$user_id},根节点用户:{$string_code_root_user_id}不存在"], "app_debug.log");
  235. return false;
  236. }
  237. $consume_amount = self::getStoreConsumeAmount($store_id, $user_id);
  238. // //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$model_name},消费金额:{$consume_amount}"], "app_debug.log");
  239. if (bccomp($consume_amount, $setting['string_code_condition_value'], 4) == -1) {
  240. $msg = "加入节点 串码模式:{$model_name},店铺:【{$store_id}】,用户:{$user_id},消费:{$consume_amount} 未达到 {$setting['string_code_condition_value']} 元,加入串码节点失败";
  241. //debug_log([__METHOD__, __LINE__, $msg], "app_debug.log");
  242. return false;
  243. }
  244. $parent_id = !$user['parent_id'] ? $root_string_code['user_id'] : $user['parent_id'];
  245. // 深度优先,从左至右
  246. list($real_parent_node, $layer_rank, $area_key) = self::getRealParentNodePlus($store_id, $user_id, $parent_id, $setting['string_code_max_layer'], $model_val, $string_code_shop_value);
  247. if (empty($real_parent_node->recommend_relation_node)) {
  248. $recommend_relation_node = ',' . $real_parent_node->user_id . ',';
  249. } else {
  250. $recommend_relation_node = $real_parent_node->recommend_relation_node . $real_parent_node->user_id . ',';
  251. }
  252. $parent_string_code = self::findOne(['store_id' => $store_id, 'user_id' => $parent_id]);
  253. if (empty($parent_string_code->recommend_relation)) {
  254. $recommend_relation = ',' . $parent_string_code->user_id . ',';
  255. } else {
  256. $recommend_relation = $real_parent_node->recommend_relation . $parent_string_code->user_id . ',';
  257. }
  258. // 保存节点数据
  259. $user_string_code = new self();
  260. $user_string_code->store_id = $store_id;
  261. $user_string_code->user_id = $user_id;
  262. $user_string_code->parent_id = $parent_id;
  263. $user_string_code->parent_node = $real_parent_node->user_id;
  264. $user_string_code->recommend_relation_node = $recommend_relation_node;
  265. $user_string_code->layer_node = $real_parent_node->layer_node + 1;
  266. $user_string_code->recommend_relation = $recommend_relation;
  267. $user_string_code->layer = $parent_string_code->layer + 1;
  268. $user_string_code->area_key = $area_key;
  269. $user_string_code->layer_rank = $layer_rank;
  270. $user_string_code->saas_id = $saas_user_id;
  271. if (!$user_string_code->save()) {
  272. $errors = json_encode($user_string_code->getErrors());
  273. $msg = "加入节点 店铺:【{$store_id}】,用户:{$user_id},保存串码节点失败 {$errors}";
  274. //debug_log([__METHOD__, __LINE__, $msg], "app_debug.log");
  275. return false;
  276. }
  277. // 所有上级节点 团队人数 + 1
  278. self::setTeamCountInc($store_id, $user_id);
  279. return true;
  280. }
  281. public static function joinNodeByAllianceModel($store_id, $saas_user_id, $setting, $model_val, $string_code_shop_value = 0)
  282. {
  283. $user_id = $saas_user_id;
  284. $user = SaasUser::findOne($saas_user_id);
  285. $model_name = self::MODEL_NAME_LIST[self::MODEL_ALLIANCE];
  286. $string_code_root_user_id = self::getRootUserId($store_id, self::MODEL_ALLIANCE);
  287. $user_string_code = self::findOne(['store_id' => $store_id, 'user_id' => $user_id]);
  288. if ($user_string_code) {
  289. //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$model_name},用户:{$user_id}已加入串码节点"], "app_debug.log");
  290. return false;
  291. }
  292. $root_string_code = self::findOne(['store_id' => $store_id, 'user_id' => $string_code_root_user_id]);
  293. if (!$root_string_code) {
  294. //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$model_name},用户:{$user_id}根节点不存在"], "app_debug.log");
  295. return false;
  296. }
  297. $consume_amount = self::getStoreConsumeAmount($store_id, $user_id);
  298. // //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$model_name}, 消费金额:{$consume_amount}"], "app_debug.log");
  299. if (bccomp($consume_amount, $setting['string_code_condition_value'], 4) == -1) {
  300. $msg = "加入节点 串码模式:{$model_name},店铺:【{$store_id}】,用户:{$user_id},消费:{$consume_amount}未达到{$setting['string_code_condition_value']}元,加入串码节点失败";
  301. //debug_log([__METHOD__, __LINE__, $msg], "app_debug.log");
  302. return false;
  303. }
  304. $parent_id = !$user['parent_id'] ? $root_string_code['user_id'] : $user['parent_id'];
  305. // 深度优先,从左至右
  306. list($real_parent_node, $layer_rank, $area_key) = self::getRealParentNodePlus($store_id, $user_id, $parent_id, $setting['string_code_max_layer'], $model_val, $string_code_shop_value);
  307. if (empty($real_parent_node['recommend_relation_node'])) {
  308. $recommend_relation_node = ',' . $real_parent_node->user_id . ',';
  309. } else {
  310. $recommend_relation_node = $real_parent_node['recommend_relation_node'] . $real_parent_node->user_id . ',';
  311. }
  312. $parent_string_code = self::findOne(['store_id' => $store_id, 'user_id' => $parent_id]);
  313. if (empty($parent_string_code['recommend_relation'])) {
  314. $recommend_relation = ',' . $parent_string_code->user_id . ',';
  315. } else {
  316. $recommend_relation = $real_parent_node['recommend_relation'] . $parent_string_code->user_id . ',';
  317. }
  318. // 保存节点数据
  319. $user_string_code = new self();
  320. $user_string_code->store_id = $store_id;
  321. $user_string_code->user_id = $user_id;
  322. $user_string_code->parent_id = $parent_id;
  323. $user_string_code->parent_node = $real_parent_node['user_id'];
  324. $user_string_code->recommend_relation_node = $recommend_relation_node;
  325. $user_string_code->layer_node = $real_parent_node['layer_node'] + 1;
  326. $user_string_code->recommend_relation = $recommend_relation;
  327. $user_string_code->layer = $parent_string_code['layer'] + 1;
  328. $user_string_code->area_key = $area_key;
  329. $user_string_code->layer_rank = $layer_rank;
  330. $user_string_code->saas_id = $saas_user_id;
  331. if (!$user_string_code->save()) {
  332. $errors = json_encode($user_string_code->getErrors());
  333. $msg = "加入节点 店铺:【{$store_id}】,用户:{$user_id},保存串码节点失败 {$errors}";
  334. //debug_log([__METHOD__, __LINE__, $msg], "app_debug.log");
  335. return false;
  336. }
  337. // 所有上级节点 团队人数 + 1
  338. self::setTeamCountInc($store_id, $user_id);
  339. return true;
  340. }
  341. /**
  342. * 消费金额
  343. */
  344. public static function getStoreConsumeAmount($store_id, $user_id)
  345. {
  346. // 订单金额
  347. // $order_money = Order::find()->where(
  348. // [
  349. // 'is_delete' => 0,
  350. // 'trade_status' => Order::ORDER_FLOW_CONFIRM,
  351. // ])
  352. // ->andWhere(['in', 'user_id', $user_ids])
  353. // ->andWhere(['or', ['is_pay' => 1], ['pay_type' => 2]])
  354. // ->sum('pay_price');
  355. // $scan_order_money = ScanOrder::find()->where(
  356. // [
  357. // 'is_delete' => 0,
  358. // 'trade_status' => Order::ORDER_FLOW_CONFIRM,
  359. // 'is_pay' => 1
  360. // ])
  361. // ->andWhere(['in', 'user_id', $user_ids])
  362. // ->sum('pay_price');
  363. // $user = SaasUser::findOne(['id' => $saas_user_id]);
  364. // $order_total = bcadd($order_money, $scan_order_money, 4);
  365. // //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$string_code_model}, 消费金额:{$order_total}"], "app_debug.log");
  366. // 联盟分
  367. $user_wallet = UserWallet::getCurrencyWallet($store_id, $user_id, Currency::CURRENCY_COIN);
  368. return $user_wallet['money_total'] ?: 0;
  369. }
  370. /**
  371. * 赠送贡献积分
  372. * @param $order
  373. * @param $is_scan
  374. * @return false|void
  375. */
  376. public static function giveCoin($order, $is_scan)
  377. {
  378. $store_id = $order->store_id;
  379. $order_id = $order->id;
  380. $user_id = $order->user_id;
  381. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  382. $setting = $setting ? Json::decode($setting['value']) : [];
  383. $check_res = self::checkSettingByStoreId($store_id, $setting);
  384. if (!$check_res) {
  385. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】设置条件不满足"], "app_debug.log");
  386. return false;
  387. }
  388. list($model_switch_shop, $model_switch_alliance) = self::getModelSwitchBySettingArray($setting['string_code_model']);
  389. if ($model_switch_shop) {
  390. if ($is_scan) {
  391. $order_pv = $order->pay_price;
  392. $money = bcmul($order_pv, $setting['string_code_scan_scale_0'] / 100, 4);
  393. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[self::MODEL_SHOP] . " " . "赠送店铺分 当面付 联盟PV:【{$order_pv}】比例:【{$setting['string_code_scan_scale_0']}】"], "app_debug.log");
  394. } else {
  395. $order_pv_0 = OrderDetail::find()
  396. ->andWhere(['order_id' => $order['id'], 'is_delete' => 0])
  397. ->select([
  398. 'sum(pv_0)',
  399. ])->scalar();
  400. $money = bcmul($order_pv_0, $setting['string_code_order_scale_0'] / 100, 4);
  401. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[self::MODEL_SHOP] . " " . "赠送店铺分 商城单 联盟PV:【{$order_pv_0}】比例:【{$setting['string_code_order_scale_0']}】"], "app_debug.log");
  402. }
  403. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[self::MODEL_SHOP] . " " . "赠送店铺分 店铺:【{$store_id}】分值:【{$money}】"], "app_debug.log");
  404. $log_type = $is_scan ? UserWallet::TYPE_SCAN : UserWallet::TYPE_ORDER;
  405. $log_desc = self::MODEL_NAME_LIST[self::MODEL_SHOP] . " " . UserWallet::TYPE_NAME_LIST[$log_type] . "【{$order->order_no}】 赠送店铺分";
  406. $source_table = $is_scan ? "\app\plugins\scanCodePay\models\Order" : "app\models\Order";
  407. $currency = Currency::findOne(['code' => Currency::CURRENCY_COIN]);
  408. UserWallet::addLog($currency, $store_id, $user_id, $money, $log_desc, $log_type, $source_table, $order_id);
  409. }
  410. if ($model_switch_alliance) {
  411. $store_id = self::ALLIANCE_STORE_ID;
  412. if ($is_scan) {
  413. $order_pv = $order->pay_price;
  414. $money = bcmul($order_pv, $setting['string_code_scan_scale_1'] / 100, 4);
  415. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[self::MODEL_ALLIANCE] . " " . "赠送联盟分 当面付 联盟PV:【{$order_pv}】比例:【{$setting['string_code_scan_scale_1']}】"], "app_debug.log");
  416. } else {
  417. $order_pv_1 = OrderDetail::find()
  418. ->andWhere(['order_id' => $order['id'], 'is_delete' => 0])
  419. ->select([
  420. 'sum(pv_1)',
  421. ])->scalar();
  422. $money = bcmul($order_pv_1, $setting['string_code_order_scale_1'] / 100, 4);
  423. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[self::MODEL_ALLIANCE] . " " . "赠送联盟分 商城单 联盟PV:【{$order_pv_1}】比例:【{$setting['string_code_order_scale_1']}】"], "app_debug.log");
  424. }
  425. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[self::MODEL_ALLIANCE] . " " . "赠送联盟分 店铺:【{$store_id}】分值:【{$money}】"], "app_debug.log");
  426. $log_type = $is_scan ? UserWallet::TYPE_SCAN : UserWallet::TYPE_ORDER;
  427. $log_desc = self::MODEL_NAME_LIST[self::MODEL_ALLIANCE] . " " . UserWallet::TYPE_NAME_LIST[$log_type] . "【{$order->order_no}】 赠送联盟分";
  428. $source_table = $is_scan ? "\app\plugins\scanCodePay\models\Order" : "app\models\Order";
  429. $currency = Currency::findOne(['code' => Currency::CURRENCY_COIN]);
  430. $saas_user_id = SaasUser::findSaasIdByUserId($order->user_id);
  431. UserWallet::addLog($currency, $store_id, $saas_user_id, $money, $log_desc, $log_type, $source_table, $order_id);
  432. }
  433. }
  434. /**
  435. * 门店让利额的用途,门店推荐人4%,合伙人分红6%,会员所属门店10%,用户推荐人20%,串码红包60%(20个点位各3%) 5%区县代理商,3%街道代理商
  436. * @param $is_scan
  437. * @return false
  438. */
  439. public static function transfer($order, $is_scan = 0)
  440. {
  441. //debug_log([__METHOD__, __LINE__, '串码让利 start'], "app_debug.log");
  442. if (!$order->is_pay) {
  443. return false;
  444. }
  445. $store_id = $order->store_id;
  446. $store = Store::findOne($store_id);
  447. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  448. $setting = $setting ? Json::decode($setting['value']) : [];
  449. $check_res = self::checkSettingByStoreId($store_id, $setting);
  450. if (!$check_res) {
  451. return false;
  452. }
  453. $t = \Yii::$app->db->beginTransaction();
  454. try {
  455. $is_scan = 0;
  456. if ($order instanceof ScanOrder) {
  457. $is_scan = 1;
  458. }
  459. self::transferByModel($order, $setting, $is_scan);
  460. $UserStringCodeOrderlist = UserStringCodeOrder::findAll([
  461. 'order_id' => $order->id,
  462. 'is_scan' => $is_scan,
  463. 'type' => [
  464. UserStringCodeOrder::TYPE_STORE_USER_REFERRER,
  465. UserStringCodeOrder::TYPE_STORE_USER_AFFILIATED,
  466. UserStringCodeOrder::TYPE_STORE_REFERRER,
  467. UserStringCodeOrder::TYPE_BRAND_USER_REFERRER,
  468. UserStringCodeOrder::TYPE_BRAND_USER_AFFILIATED,
  469. UserStringCodeOrder::TYPE_BRAND_REFERRER,
  470. UserStringCodeOrder::TYPE_BRAND_PROVINCE_AGENT
  471. ] // 用数组指定多个类型
  472. ]);
  473. if (count($UserStringCodeOrderlist) > 0) {
  474. $order->team_reward_status = 1;
  475. $order->save();
  476. }
  477. self::sendDistrictStreetAgentDivvy($order);
  478. $t->commit();
  479. } catch (\Exception $e) {
  480. $t->rollBack();
  481. //debug_log([__METHOD__, __LINE__, "串码让利 异常" . $e->getMessage()], "app_debug.log");
  482. }
  483. //debug_log([__METHOD__, __LINE__, '串码让利 end'], "app_debug.log");
  484. }
  485. public static function storeTransferByShopModel($order, $string_code_setting, $model_val)
  486. {
  487. $store_id = $order->store_id;
  488. if ($order instanceof ScanOrder) {
  489. $order_pv = $order->pay_price;
  490. } else {
  491. $order_pv = OrderDetail::find()
  492. ->andWhere(['order_id' => $order['id'], 'is_delete' => 0])
  493. ->select([
  494. 'sum(pv_0)',
  495. ])->scalar();
  496. }
  497. $transfer_money = bcmul($order_pv, $string_code_setting['string_code_pv_scale_0'] / 100, 4);
  498. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】门店总待分账金额:{$transfer_money} 订单金额:{$order_pv} pv:{$string_code_setting['string_code_pv_scale_0']}"], "app_debug.log");
  499. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_SALE_SETTING, self::ALLIANCE_STORE_ID, OptionSetting::SHARE_GROUP_NAME, '{}');
  500. $setting = $setting ? Json::decode($setting['value']) : [];
  501. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】店铺推荐人:{$setting['string_code_store_referrer']} 合伙人分红:{$setting['string_code_store_partner']} 会员所属门店:{$setting['string_code_store_user_affiliated']} 用户推荐人:{$setting['string_code_store_user_referrer']}"], "app_debug.log");
  502. if (isset($setting['string_code_store_referrer']) && $setting['string_code_store_referrer'] > 0) {
  503. $store_referral = SaasStoreReferral::findOne(['store_id' => $store_id]);
  504. $saas_id = $store_referral['referral_id'];
  505. $money = bcmul($transfer_money, $setting['string_code_store_referrer'] / 100, 4);
  506. $type = UserStringCodeOrder::TYPE_STORE_REFERRER;
  507. UserStringCodeOrder::transferAddUserWallet($order, $saas_id, $money, $type, $model_val);
  508. }
  509. //debug_log([__METHOD__, __LINE__, "---------------- 开始插入分红池 -------------------" . $setting['string_code_store_partner']], "app_debug.log");
  510. if (isset($setting['string_code_store_partner']) && $setting['string_code_store_partner'] > 0) {
  511. $money = bcmul($transfer_money, $setting['string_code_store_partner'] / 100, 4);
  512. if (bccomp($money, 0, 4) > 0) {
  513. //debug_log([__METHOD__, __LINE__, "---------------- 开始插入分红池 -------------------"], "app_debug.log");
  514. $desc = self::MODEL_NAME_LIST[$model_val] . " " . "订单号:【{$order->order_no}】合伙人分红增加";
  515. PartnerPool::poolPush($order, $money, $desc, $order_pv, $string_code_setting['string_code_pv_scale_0'], $setting['string_code_store_partner'], $model_val);
  516. } else {
  517. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】门店总待分账金额:{$transfer_money},合伙人分账金额:{$money} 有误"], "app_debug.log");
  518. }
  519. }
  520. if (isset($setting['string_code_store_user_affiliated']) && $setting['string_code_store_user_affiliated'] > 0) {
  521. $first_store_id = SaasUser::findFirstStoreIdByUserId($order->user_id);
  522. $store_admin = Admin::findOne(['type' => 'store', 'type_id' => $first_store_id, 'is_delete' => 0]);
  523. $saas_id = $store_admin['saas_user_id'];
  524. $money = bcmul($transfer_money, $setting['string_code_store_user_affiliated'] / 100, 4);
  525. $type = UserStringCodeOrder::TYPE_STORE_USER_AFFILIATED;
  526. UserStringCodeOrder::transferAddUserWallet($order, $saas_id, $money, $type, $model_val);
  527. }
  528. if (isset($setting['string_code_store_user_referrer']) && $setting['string_code_store_user_referrer'] > 0) {
  529. $user = User::findOne($order->user_id);
  530. $saas_id = SaasUser::findSaasParentIdByUserId($user['id']);
  531. $money = bcmul($transfer_money, $setting['string_code_store_user_referrer'] / 100, 4);
  532. $type = UserStringCodeOrder::TYPE_STORE_USER_REFERRER;
  533. UserStringCodeOrder::transferAddUserWallet($order, $saas_id, $money, $type, $model_val);
  534. }
  535. }
  536. public static function transferByModel($order, $string_code_setting, $is_scan)
  537. {
  538. $store_id = $order->store_id;
  539. //$setting = Option::getShareSaleSetting(self::ALLIANCE_STORE_ID);
  540. $setting = Option::getShareSaleSetting($store_id);
  541. if ($order instanceof ScanOrder) {
  542. $order_pv = $order->pay_price+$order->take_price;
  543. if (isset($setting['string_code_store_partner']) && $setting['string_code_store_partner'] > 0) {
  544. //debug_log([__METHOD__, __LINE__, "门店合伙人分红比例 : " . ($string_code_setting['scan_qr_code_percent'])], "app_debug.log");
  545. self::stringCodeStorPartner($order, $order_pv, $string_code_setting['scan_qr_code_percent'], $setting['string_code_store_partner'], $setting, $is_scan, $string_code_setting['string_code_model'], $store_id, 0);
  546. }
  547. self::unionUintFounder($order, $order_pv, $string_code_setting['scan_qr_code_percent'], $setting, $string_code_setting['string_code_model'],$store_id,$is_scan, 0);
  548. if (isset($setting['string_code_brand_partner']) && $setting['string_code_brand_partner'] > 0) {
  549. //debug_log([__METHOD__, __LINE__, "品牌合伙人分红比例 : " . ($string_code_setting['alliance_scan_qr_code_percent'])], "app_debug.log");
  550. self::stringCodeStorPartner($order, $order_pv, $string_code_setting['alliance_scan_qr_code_percent'], $setting['string_code_brand_partner'], $setting, $is_scan, $string_code_setting['string_code_model'], $store_id, 1);
  551. }
  552. self::unionUintFounder($order, $order_pv, $string_code_setting['alliance_scan_qr_code_percent'], $setting, $string_code_setting['string_code_model'],$store_id,$is_scan, 1);
  553. } else {
  554. $order_pv = OrderDetail::find()->andWhere(['order_id' => $order['id'], 'is_delete' => 0])->select(['sum(pv_0)'])->scalar();
  555. self::stringCodeStorPartner($order, $order_pv, $string_code_setting['string_code_pv_scale_0'], $setting['string_code_brand_partner'], $setting, $is_scan, $string_code_setting['string_code_model'], $store_id, 0);
  556. self::unionUintFounder($order, $order_pv, $string_code_setting['string_code_pv_scale_0'], $setting, $string_code_setting['string_code_model'],$store_id,$is_scan, 0);
  557. $order_pv = OrderDetail::find()->andWhere(['order_id' => $order['id'], 'is_delete' => 0])->select(['sum(pv_1)'])->scalar();
  558. self::stringCodeStorPartner($order, $order_pv, $string_code_setting['string_code_pv_scale_1'], $setting['string_code_brand_partner'], $setting, $is_scan, $string_code_setting['string_code_model'], $store_id, 1);
  559. self::unionUintFounder($order, $order_pv, $string_code_setting['string_code_pv_scale_1'], $setting, $string_code_setting['string_code_model'],$store_id,$is_scan, 1);
  560. }
  561. //debug_log([__METHOD__, __LINE__, "串码让利 订单金额:{$order_pv} pv:{$string_code_setting['string_code_make_concessions_scan']}"], "app_debug.log");
  562. //debug_log([__METHOD__, __LINE__, "串码让利 店铺推荐人:{$setting['string_code_store_referrer']} 合伙人分红:{$setting['string_code_make_concessions_scan']} 会员所属门店:{$setting['string_code_store_user_affiliated']} 用户推荐人:{$setting['string_code_store_user_referrer']}"], "app_debug.log");
  563. }
  564. public static function stringCodeStorPartner($order, $order_pv, $scan_qr_code_percent, $rate, $setting, $is_scan, $string_code_model, $store_id, $model_val)
  565. {
  566. if (in_array($model_val, $string_code_model)) {
  567. ////debug_log([__METHOD__, __LINE__, "大模型比例 : " . ($scan_qr_code_percent / 100)], "app_debug.log");
  568. $add_money = bcmul($order_pv, $scan_qr_code_percent / 100, 4);
  569. $money = bcmul($add_money, $rate / 100, 4);
  570. ////debug_log([__METHOD__, __LINE__, "大模型:order_pv : " . $order_pv . ',$add_money:' . $add_money . ',$money:' . $money], "app_debug.log");
  571. if (bccomp($money, 0, 4) > 0) {
  572. $desc = self::MODEL_NAME_LIST[$model_val] . " " . "订单号:【{$order->order_no}】合伙人分红增加";
  573. PartnerPool::poolPush($order, $money, $desc, $order_pv, $rate, $scan_qr_code_percent, $model_val, $add_money);
  574. }
  575. }
  576. }
  577. public static function unionUintFounder($order, $order_pv, $scan_qr_code_percent, $setting, $string_code_model,$store_id,$is_scan, $model_val)
  578. {
  579. if (in_array($model_val, $string_code_model)) {
  580. //debug_log([__METHOD__, __LINE__, "大模型比例 : " . ($scan_qr_code_percent / 100) . ',Store_id:' . $order->store_id, ',order_id:' . $order->id], "app_debug.log");
  581. $add_money = bcmul($order_pv, $scan_qr_code_percent / 100, 4);
  582. $money = bcmul($add_money, $setting['string_code_alliance_merchant'] / 100, 4);
  583. //debug_log([__METHOD__, __LINE__, "大模型:order_pv : " . $order_pv . ',$add_money:' . $add_money . ',$money:' . $money], "app_debug.log");
  584. $desc = self::MODEL_NAME_LIST[$model_val] . " " . "订单号:【{$order->order_no}】分红增加";
  585. if (bccomp($money, 0, 4) > 0) {
  586. StoreUnionPool::poolPush($order, $money, $desc, $order_pv, $setting['string_code_alliance_merchant'], $scan_qr_code_percent, $model_val, $add_money);
  587. }
  588. $money = bcmul($add_money, $setting['string_code_brand_cofounder'] / 100, 4);
  589. //debug_log([__METHOD__, __LINE__, "大模型:order_pv : " . $order_pv . ',$add_money:' . $add_money . ',$money:' . $money], "app_debug.log");
  590. if (bccomp($money, 0, 4) > 0) {
  591. UnitFounderPool::poolPush($order, $money, $desc, $order_pv, $setting['string_code_brand_cofounder'], $scan_qr_code_percent, $model_val, $add_money);
  592. }
  593. if (bccomp($add_money, 0, 4) > 0) {
  594. self::hotAwardSend($setting['string_code_hot_district_agent'], $setting['string_code_ad_hot'], $setting['string_code_store_district_agent_divvy'], $add_money, $model_val, $order);
  595. self::adAwardSend($order->store_id, $add_money, $setting['string_code_ad_brand'], $setting['string_code_expansion_manager'], $model_val, $order,$setting['string_code_store_push_id']);
  596. self::areaAwardSend($order->store_id, $order, $add_money, $model_val, 1);//品牌区县代理
  597. self::areaAwardSend($order->store_id, $order, $add_money, $model_val, 2);//品牌市代理
  598. self::areaAwardSend($order->store_id, $order, $add_money, $model_val, 3);//品牌省代理
  599. self::stringCodeStoreReferrer($order, $setting, $store_id, $add_money, $model_val);
  600. self::stringCodeStoreUserAffiliated($order, $setting, $add_money, $model_val);
  601. self::stringCodeStoreUserReferrer($order, $setting, $add_money, $model_val);
  602. $store = Store::findOne($store_id);
  603. self::sendMakeConcessionsScan($order, $setting, $is_scan, $store, $model_val);
  604. }
  605. }
  606. }
  607. private static function areaAwardSend($store_id, $order, $order_pv, $model, $area_level)
  608. {
  609. if ($order_pv <= 0) return false;
  610. $setting = Option::getShareSaleSetting(OptionSetting::ALLIANCE_STORE_ID);
  611. $store = Store::find()->where(['id' => $store_id])->select(['salesman_id', 'district_id','city_id','province_id'])->asArray()->one();
  612. $salesman_id = $store['salesman_id'];
  613. //debug_log([__METHOD__, __LINE__, "============拓展经理:($salesman_id),,广告推流店铺id:" . $store_id], "app_debug.log");
  614. $salesman = Salesman::findOne(['id' => $salesman_id, 'is_delete' => 0, 'status' => 1]);
  615. $admin = Admin::findOne(['id' => $salesman->admin_id, 'is_delete' => 0]);
  616. $query = Admin::find()->select('saas_user_id')->where(['agent_id' => $salesman->admin_id,'is_enable'=>1,'is_delete'=>0]);
  617. switch ($area_level) {
  618. case 1:
  619. $area = $setting['string_code_brand_district_agent'];
  620. $type = UserStringCodeOrder::TYPE_BRAND_DISTRICT_AGENT;
  621. $d_query = clone $query;
  622. $agent_id = $d_query->andWhere(['district_id' => $store['district_id'], 'area_level' => 1])->scalar() ?: null;
  623. if ($agent_id) break;
  624. //debug_log([__METHOD__, __LINE__, "============没找到区县代理" ], "app_debug.log");
  625. case 2:
  626. if ($area_level == 2) {
  627. $type = UserStringCodeOrder::TYPE_BRAND_CITY_AGENT;
  628. $area = $setting['string_code_brand_city_agent'];
  629. }
  630. $c_query = clone $query;
  631. $agent_id = $c_query->andWhere(['city_id' => $store['city_id'], 'area_level' => 2])->scalar() ?: null;
  632. if ($agent_id) break;
  633. //debug_log([__METHOD__, __LINE__, "============没找到市代理" ], "app_debug.log");
  634. case 3:
  635. if ($area_level == 3) {
  636. $type = UserStringCodeOrder::TYPE_BRAND_PROVINCE_AGENT;
  637. $area = $setting['string_code_brand_province_agent'];
  638. }
  639. $p_query = clone $query;
  640. $agent_id = $p_query->andWhere(['province_id' => $store['province_id'], 'area_level' => 3])->scalar() ?: null;
  641. break;
  642. default:
  643. $area = 0;
  644. break;
  645. }
  646. if ($area && $salesman->admin_id) {
  647. $area_money = $order_pv * $area / 100;
  648. $agent_id = $agent_id ?:($admin->advert_push_user_id?:$setting['string_code_store_push_id']);
  649. //debug_log([__METHOD__, __LINE__, "============区县代理商:".$agent_id."金额 : " . ($area_money)], "app_debug.log");
  650. if ($agent_id){
  651. UserStringCodeOrder::transferAddUserWallet($order, $agent_id, $area_money, $type, $model);
  652. }
  653. }
  654. return true;
  655. }
  656. public static function stringCodeStoreReferrer($order, $setting, $store_id, $transfer_money, $model_val)
  657. {
  658. $referrer = 0;
  659. if ($order instanceof ScanOrder) {
  660. if (isset($setting['string_code_store_referrer']) && $setting['string_code_store_referrer'] > 0) {
  661. $referrer = $setting['string_code_store_referrer'];
  662. }
  663. } else {
  664. if (isset($setting['string_code_brand_referrer']) && $setting['string_code_brand_referrer'] > 0) {
  665. $referrer = $setting['string_code_brand_referrer'];
  666. }
  667. }
  668. if ($referrer > 0) {
  669. $store_referral = SaasStoreReferral::findOne(['store_id' => $store_id]);
  670. $saas_id = $store_referral['referral_id'];
  671. $money = bcmul($transfer_money, $referrer / 100, 4);
  672. $type = UserStringCodeOrder::TYPE_STORE_REFERRER;
  673. UserStringCodeOrder::transferAddUserWallet($order, $saas_id, $money, $type, $model_val);
  674. }
  675. }
  676. public static function stringCodeStoreUserAffiliated($order, $setting, $transfer_money, $model_val)
  677. {
  678. $affiliated = 0;
  679. if ($order instanceof ScanOrder) {
  680. if (isset($setting['string_code_store_user_affiliated']) && $setting['string_code_store_user_affiliated'] > 0) {
  681. $affiliated = $setting['string_code_store_user_affiliated'];
  682. }
  683. } else {
  684. if (isset($setting['string_code_brand_user_affiliated']) && $setting['string_code_brand_user_affiliated'] > 0) {
  685. $affiliated = $setting['string_code_brand_user_affiliated'];
  686. }
  687. }
  688. if ($affiliated > 0) {
  689. $first_store_id = SaasUser::findFirstStoreIdByUserId($order->user_id);
  690. $store_admin = Admin::findOne(['type' => 'store', 'type_id' => $first_store_id, 'is_delete' => 0]);
  691. $saas_id = $store_admin['saas_user_id'];
  692. $money = bcmul($transfer_money, $affiliated / 100, 4);
  693. $type = UserStringCodeOrder::TYPE_STORE_USER_AFFILIATED;
  694. UserStringCodeOrder::transferAddUserWallet($order, $saas_id, $money, $type, $model_val);
  695. }
  696. }
  697. public static function stringCodeStoreUserReferrer($order, $setting, $transfer_money, $model_val)
  698. {
  699. $referrer = 0;
  700. if ($order instanceof ScanOrder) {
  701. if (isset($setting['string_code_store_user_referrer']) && $setting['string_code_store_user_referrer'] > 0) {
  702. $referrer = $setting['string_code_store_user_referrer'];
  703. }
  704. } else {
  705. if (isset($setting['string_code_brand_user_referrer']) && $setting['string_code_brand_user_referrer'] > 0) {
  706. $referrer = $setting['string_code_brand_user_referrer'];
  707. }
  708. }
  709. if ($referrer > 0) {
  710. $user = User::findOne($order->user_id);
  711. if ($user->id > 0) {
  712. $saas_id = SaasUser::findSaasParentIdByUserId($order->user_id);
  713. $money = bcmul($transfer_money, $referrer / 100, 4);
  714. $type = UserStringCodeOrder::TYPE_STORE_USER_REFERRER;
  715. UserStringCodeOrder::transferAddUserWallet($order, $saas_id, $money, $type, $model_val);
  716. }
  717. }
  718. }
  719. public static function sendDistrictStreetAgentDivvy($order, $model_val = 1, $modelType = '街道代理商')
  720. {
  721. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_SALE_SETTING, self::ALLIANCE_STORE_ID, OptionSetting::SHARE_GROUP_NAME, '{}');
  722. $setting = $setting ? Json::decode($setting['value']) : [];
  723. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】店铺推荐人:{$setting['string_code_store_referrer']} 合伙人分红:{$setting['string_code_store_partner']} 会员所属门店:{$setting['string_code_store_user_affiliated']} 用户推荐人:{$setting['string_code_store_user_referrer']}"], "app_debug.log");
  724. $transfer_money = 0;
  725. if ($order instanceof ScanOrder) {
  726. $transfer_money = UserStringCodePlus::countOrderPvBonus($order);
  727. }
  728. if ($transfer_money <= 0.01) {
  729. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】{$modelType}总待分账金额:{$transfer_money} 小于0.01不分账"], "app_debug.log");
  730. return;
  731. }
  732. /*if (isset($setting['string_code_store_district_agent_divvy']) && $setting['string_code_store_district_agent_divvy'] > 0) {
  733. $money = bcmul($transfer_money, $setting['string_code_store_district_agent_divvy'] / 100, 4);
  734. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】{$modelType}总待分账金额:{$transfer_money} 门店区县代理商待分账金额:{$money}"], "app_debug.log");
  735. if ($money > 0) {
  736. self::getAgentSaasIdByOrder($order, UserStringCodeOrder::TYPE_STRING_CODE_STORE_DISTRICT_AGENT_DIVVY, $money, $model_val, $modelType);
  737. }
  738. }*/
  739. if (isset($setting['string_code_store_street_agent_divvy']) && $setting['string_code_store_street_agent_divvy'] > 0) {
  740. $money = bcmul($transfer_money, $setting['string_code_store_street_agent_divvy'] / 100, 4);
  741. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】{$modelType}总待分账金额:{$transfer_money} 门店街道代理商待分账金额:{$money}"], "app_debug.log");
  742. if ($money > 0) {
  743. self::getAgentSaasIdByOrder($order, UserStringCodeOrder::TYPE_STRING_CODE_STORE_STREET_AGENT_DIVVY, $money, $model_val, $modelType);
  744. }
  745. }
  746. }
  747. public static function getModelSwitchBySettingArray($string_code_model_arr)
  748. {
  749. // 如果是字符串,自动转成数组
  750. if (!isset($string_code_model_arr) || !is_array($string_code_model_arr)) {
  751. $string_code_model_arr = is_string($string_code_model_arr)
  752. ? explode(',', $string_code_model_arr)
  753. : [];
  754. }
  755. $model_switch_shop = in_array(0, $string_code_model_arr) ? 1 : 0;
  756. $model_switch_alliance = in_array(1, $string_code_model_arr) ? 1 : 0;
  757. return [$model_switch_shop, $model_switch_alliance];
  758. }
  759. /**
  760. * 获取根结点用户ID
  761. * @param $store_id
  762. * @param $string_code_model
  763. * @return int
  764. */
  765. public static function getRootUserId($store_id, $string_code_model)
  766. {
  767. if ($string_code_model == self::MODEL_ALLIANCE) {
  768. $store_id = self::ALLIANCE_STORE_ID;
  769. }
  770. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  771. $setting = $setting ? Json::decode($setting['value']) : [];
  772. return isset($setting['string_code_root_user_id']) && $setting['string_code_root_user_id'] ? (int)$setting['string_code_root_user_id'] : 0;
  773. }
  774. /**
  775. * 设置根结点用户ID
  776. * todo 根结点改为后台手选,废弃
  777. * @param $store_id
  778. * @param $string_code_model
  779. * @return int
  780. */
  781. public static function setRootUserId($store_id, $user_id)
  782. {
  783. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  784. $setting = $setting ? Json::decode($setting['value']) : [];
  785. $check_res = self::checkSettingByStoreId($store_id, $setting);
  786. if (!$check_res) {
  787. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】设置条件不满足"], "app_debug.log");
  788. return false;
  789. }
  790. $first_order_user = Order::find()->where(
  791. [
  792. 'is_delete' => 0,
  793. 'trade_status' => Order::ORDER_FLOW_CONFIRM,
  794. 'store_id' => $store_id
  795. ]
  796. )->andWhere(['or', ['is_pay' => 1], ['pay_type' => 2]])->orderBy('pay_time DESC')->select('user_id')->column();
  797. if ($first_order_user) {
  798. $setting['string_code_root_user_id'] = $first_order_user;
  799. $json = json_encode($setting);
  800. Option::set(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $json, $store_id, OptionSetting::SHARE_GROUP_NAME);
  801. return true;
  802. }
  803. $first_scan_order_user = ScanOrder::find()->where(
  804. [
  805. 'is_delete' => 0,
  806. 'trade_status' => Order::ORDER_FLOW_CONFIRM,
  807. 'store_id' => $store_id,
  808. 'is_pay' => 1
  809. ]
  810. )->select('user_id')->orderBy('pay_time DESC')->column();
  811. if ($first_scan_order_user) {
  812. $setting['string_code_root_user_id'] = $first_scan_order_user;
  813. $json = json_encode($setting);
  814. Option::set(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $json, $store_id, OptionSetting::SHARE_GROUP_NAME);
  815. return true;
  816. }
  817. return true;
  818. }
  819. /**
  820. * 发放串码红包
  821. * @param $order
  822. * @return bool
  823. */
  824. public static function sendRedPacket($order, $is_scan)
  825. {
  826. $order_id = $order->id;
  827. $store_id = $order->store_id;
  828. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  829. $setting = $setting ? Json::decode($setting['value']) : [];
  830. $check_res = self::checkSettingByStoreId($store_id, $setting);
  831. if (!$check_res) {
  832. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】设置条件不满足"], "app_debug.log");
  833. return false;
  834. }
  835. $ids = UserStringCodeOrder::find()
  836. ->where(['order_id' => $order_id, 'status' => 0])
  837. ->andWhere(['in', 'type', [UserStringCodeOrder::TYPE_BRAND_RED_PACKET, UserStringCodeOrder::TYPE_STORE_RED_PACKET,
  838. UserStringCodeOrder::TYPE_BRAND_TEAM_PARTNER, UserStringCodeOrder::TYPE_STORE_TEAM_PARTNER]])
  839. ->select('id')
  840. ->column();
  841. if (!$ids) {
  842. //debug_log([__METHOD__, __LINE__, "串码红包发放 订单id:【{$order_id}】店铺:【{$store_id}】待发放订单为空"], "app_debug.log");
  843. return false;
  844. }
  845. foreach ($ids as $item_id) {
  846. $string_code_order = UserStringCodeOrder::findOne($item_id);
  847. $money = $string_code_order->money;
  848. $model_val = $string_code_order->model_val;
  849. if ($string_code_order->store_id == self::ALLIANCE_STORE_ID) {
  850. $to_user_id = $string_code_order->saas_id;
  851. } else {
  852. $to_user_id = $string_code_order->user_id;
  853. }
  854. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[$model_val] . " " . "串码红包发放 记录:【{$item_id}】,店铺:【{$store_id}】用户:【{$to_user_id}】,红包金额:【{$money}】"], "app_debug.log");
  855. $log_type = $is_scan ? UserWallet::TYPE_SCAN : UserWallet::TYPE_ORDER;
  856. $log_desc = self::MODEL_NAME_LIST[$model_val] . " " . UserWallet::TYPE_NAME_LIST[$log_type] . "【{$order->order_no}】 发放串码红包";
  857. $source_table = $is_scan ? "\app\plugins\scanCodePay\models\Order" : "app\models\Order";
  858. $currency = Currency::findOne(['code' => Currency::CURRENCY_STRING_CODE]);
  859. UserWallet::addLog($currency, $string_code_order->store_id, $to_user_id, $money, $log_desc, $log_type, $source_table, $order_id,$string_code_order->store_id,$string_code_order->type);
  860. }
  861. UserStringCodeOrder::updateAll(
  862. ['status' => UserStringCodeOrder::STATUS_SUCCESS],
  863. [
  864. 'and',
  865. ['order_id' => $order_id, 'status' => 0],
  866. ['in', 'type', [UserStringCodeOrder::TYPE_BRAND_RED_PACKET, UserStringCodeOrder::TYPE_STORE_RED_PACKET,
  867. UserStringCodeOrder::TYPE_BRAND_TEAM_PARTNER, UserStringCodeOrder::TYPE_STORE_TEAM_PARTNER]]
  868. ]
  869. );
  870. return true;
  871. }
  872. /**
  873. * 指定用户上级所有节点团队人数 + 1
  874. * @param $store_id
  875. * @param $user_id
  876. * @return int
  877. */
  878. public static function setTeamCountInc($store_id, $user_id)
  879. {
  880. $parent_node_ids = self::getAllParentNodeIds($store_id, $user_id);
  881. if ($parent_node_ids) {
  882. return self::updateAll(
  883. ['team_num' => new Expression('team_num + 1')],
  884. ['in', 'user_id', $parent_node_ids]
  885. );
  886. } else {
  887. return 0;
  888. }
  889. }
  890. /**
  891. * 获取用户最后一个节点
  892. * 从上至下,从左至右
  893. * @param $store_id 店铺ID
  894. * @param $user_id 下单用户ID
  895. * @param $parent_id 下单用户上级ID
  896. * @param $max_layer 限制最大层数
  897. * @return array
  898. */
  899. public static function getRealParentNode($store_id, $order_user_id, $parent_id, $max_layer)
  900. {
  901. // 针对父节点对应的区
  902. $real_area_key = 0;
  903. // 针对根节点对应的排序
  904. $real_layer_rank = 0;
  905. $parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $parent_id]);
  906. $children_list = self::findOne(['store_id' => $store_id, 'parent_node' => $parent_id]);
  907. // 未有子节点
  908. if (!$children_list) {
  909. //debug_log([__METHOD__, __LINE__, "未有子节点"], "app_debug.log");
  910. $real_parent_node = $parent_node;
  911. return [$real_parent_node, $real_area_key, $real_layer_rank];
  912. }
  913. // 先判断 最大层级下 第一列能否能占位
  914. $temp_parent_id = $parent_id;
  915. //debug_log([__METHOD__, __LINE__, "最大层数:{$max_layer}"], "app_debug.log");
  916. for ($i = 0; $i < $max_layer; $i++) {
  917. //debug_log([__METHOD__, __LINE__, "第1区循环:{$i},用户ID:{$temp_parent_id}"], "app_debug.log");
  918. $temp_node = self::findOne(['store_id' => $store_id, 'parent_node' => $temp_parent_id, 'area_key' => $real_area_key]);
  919. if (!$temp_node) {
  920. $real_parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $temp_parent_id]);
  921. return [$real_parent_node, $real_layer_rank, $real_area_key];
  922. } else {
  923. $temp_parent_id = $temp_node['user_id'];
  924. }
  925. }
  926. $queue = [];
  927. $queue[] = $parent_node;
  928. while (!empty($queue)) {
  929. // 当前节点
  930. $current_node = array_shift($queue);
  931. // 当前层数
  932. $current_layer = $current_node['layer_node'] - $parent_node['layer_node'];
  933. //debug_log([__METHOD__, __LINE__, "当前节点ID:{$current_node['user_id']},当前层数:{$current_layer}"], "app_debug.log");
  934. // 判断用户第1区有无落点
  935. $parent_first_col_auth = self::findOne(['store_id' => $store_id, 'parent_node' => $current_node['user_id'], 'area_key' => 0]);
  936. if (!$parent_first_col_auth) {
  937. $real_area_key = 0;
  938. //debug_log([__METHOD__, __LINE__, "当前节点ID:{$current_node['user_id']},1区没人,落第1区"], "app_debug.log");
  939. $real_parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $current_node['user_id']]);
  940. $current_layer_rank = self::find()
  941. ->where(['store_id' => $store_id, 'layer_node' => $real_parent_node['layer_node'] + 1])
  942. ->max('layer_rank');
  943. $real_layer_rank = $current_layer_rank + 1;
  944. return [$real_parent_node, $real_layer_rank, $real_area_key];
  945. }
  946. // 判断用户能否开第2区
  947. $parent_second_col_auth = self::checkSecondColumnAuthPlus($store_id, $order_user_id, $current_node['user_id'], $max_layer);
  948. if ($parent_second_col_auth) {
  949. // 判断第2区第一个有无占位
  950. $real_area_key = 1;
  951. $temp_node = self::findOne(['store_id' => $store_id, 'parent_node' => $current_node['user_id'], 'area_key' => $real_area_key]);
  952. if (!$temp_node) {
  953. //debug_log([__METHOD__, __LINE__, "当前节点ID:{$current_node['user_id']},可开第2区,落第2区"], "app_debug.log");
  954. $real_parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $current_node['user_id']]);
  955. $current_layer_rank = self::find()
  956. ->where(['store_id' => $store_id, 'layer_node' => $real_parent_node['layer_node'] + 1])
  957. ->max('layer_rank');
  958. $real_layer_rank = $current_layer_rank + 1;
  959. return [$real_parent_node, $real_layer_rank, $real_area_key];
  960. }
  961. }
  962. // 判断用户能否开第3区
  963. $parent_multi_col_auth = self::checkMultiColumnAuth($store_id, $current_node['user_id']);
  964. if ($parent_multi_col_auth) {
  965. // 判断第3区第一个有无占位
  966. $real_area_key = 2;
  967. $temp_node = self::findOne(['store_id' => $store_id, 'parent_node' => $current_node['user_id'], 'area_key' => $real_area_key]);
  968. if (!$temp_node) {
  969. //debug_log([__METHOD__, __LINE__, "当前节点ID:{$current_node['user_id']},可开第3区,落第3区"], "app_debug.log");
  970. $real_parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $current_node['user_id']]);
  971. $current_layer_rank = self::find()
  972. ->where(['store_id' => $store_id, 'layer_node' => $real_parent_node['layer_node'] + 1])
  973. ->max('layer_rank');
  974. $real_layer_rank = $current_layer_rank + 1;
  975. return [$real_parent_node, $real_layer_rank, $real_area_key];
  976. }
  977. }
  978. // 查询当前节点的子节点(假设最多有3个子节点情况,根据实际parent_id关联查询)
  979. $children_nodes = self::find()->where(['store_id' => $store_id, 'parent_node' => $current_node['user_id']])->orderBy("area_key ASC")->all();
  980. if ($children_nodes) {
  981. foreach ($children_nodes as $node) {
  982. $queue[] = $node;
  983. }
  984. }
  985. }
  986. }
  987. /**
  988. * 获取用户最后一个节点
  989. * 深度优先,从左至右 左子树满20层,右子树第一个节点满20层,再层次落点
  990. * @param $store_id 店铺ID
  991. * @param $user_id 下单用户ID
  992. * @param $parent_id 下单用户上级ID
  993. * @param $max_layer 限制最大层数
  994. * @param $model_val 0=单店,1=联盟
  995. * @return array
  996. */
  997. public static function getRealParentNodePlus($store_id, $order_user_id, $parent_id, $max_layer, $model_val, $string_code_shop_value = 0)
  998. {
  999. // 针对父节点对应的区
  1000. $real_area_key = 0;
  1001. // 针对根节点对应的排序
  1002. $real_layer_rank = 0;
  1003. // $parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $parent_id]);
  1004. // $children_list = self::findOne(['store_id' => $store_id, 'parent_node' => $parent_id]);
  1005. $parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $parent_id]);
  1006. if (!$parent_node) { ///推荐人不在点位表中
  1007. $tmepparent_node = $parent_node; //赋初始值
  1008. $whereuser = SaasUser::findOne($parent_id); //找推荐人看一下
  1009. $tempparent_id = $whereuser['parent_id'];
  1010. $parent_id = $tempparent_id;
  1011. while ($tempparent_id != 0 && !$tmepparent_node) {
  1012. $tmepparent_node = self::findOne(['store_id' => $store_id, 'user_id' => $tempparent_id]);
  1013. if (!$tmepparent_node) {
  1014. $whereuser = SaasUser::findOne($tempparent_id);
  1015. $tempparent_id = $whereuser['parent_id'];
  1016. } else {
  1017. $parent_node = $tmepparent_node;
  1018. break;
  1019. }
  1020. //循环加入查找推荐人信息
  1021. $parent_id = $tempparent_id;
  1022. }
  1023. }
  1024. // 小杨新增
  1025. if (!$parent_node) { ///推荐人不在点位表中
  1026. if ($store_id < 0) { // $parent_id ==》 saas_id
  1027. $tmepparent_node = $parent_node; //赋初始值
  1028. $whereuser = SaasUser::findOne($parent_id); //找推荐人看一下
  1029. $tempparent_id = $whereuser['parent_id'];
  1030. $parent_id = $tempparent_id;
  1031. while ($tempparent_id != 0 && !$tmepparent_node) {
  1032. $tmepparent_node = self::findOne(['store_id' => $store_id, 'user_id' => $tempparent_id]);
  1033. if (!$tmepparent_node) {
  1034. $whereuser = SaasUser::findOne($tempparent_id);
  1035. $tempparent_id = $whereuser['parent_id'];
  1036. } else {
  1037. $parent_node = $tmepparent_node;
  1038. break;
  1039. }
  1040. //循环加入查找推荐人信息
  1041. $parent_id = $tempparent_id;
  1042. }
  1043. } else {
  1044. // $parent_id ==》 user_id
  1045. $parentUser = User::findOne($parent_id);
  1046. $parent_id = 0; //查不到节点 $parent_id 置为 0,重新查
  1047. //userid的binding查询SaaSID,通过saasId查询下一级推荐关系
  1048. if (!empty($parentUser) && !empty($parentUser['binding'])) {
  1049. $saasUser = SaasUser::findOne(['mobile' => $parentUser['binding']]);
  1050. if (!empty($saasUser) && !empty($saasUser['parent_id'])) {
  1051. $parentSaasId = $saasUser['parent_id'];
  1052. $parentSaasIdArr = []; //循环的saasId避免推荐人是自己导致死循环
  1053. while (!empty($parentSaasId)) {
  1054. //debug_log([__METHOD__, __LINE__, "加入节点店铺:【{$store_id}】,推荐人SaaSID:{$parentSaasId},已查过的推荐人SaaSID:" . json_encode($parentSaasIdArr, JSON_UNESCAPED_UNICODE)], "app_debug.log");
  1055. if (in_array($parentSaasId, $parentSaasIdArr)) break;
  1056. $parentSaasIdArr[] = $parentSaasId;
  1057. $parentSaasUser = SaasUser::findOne($parentSaasId);
  1058. if (!empty($parentSaasUser)) {
  1059. $parentUser = User::findOne(['binding' => $parentSaasUser['mobile'], 'store_id' => $store_id]);
  1060. if (!empty($parentUser)) {
  1061. $childrenList = self::findOne(['store_id' => $store_id, 'parent_node' => $parentUser['id']]);
  1062. if (!empty($childrenList)) {
  1063. $parent_id = $parentUser['id'];
  1064. //debug_log([__METHOD__, __LINE__, "加入节点店铺:【{$store_id}】,已查到节点用户推荐人SaaSID:【{$parentSaasId}】,UserID:【{$parentUser['id']}】"], "app_debug.log");
  1065. break;
  1066. } else {
  1067. $parentSaasId = $parentSaasUser['parent_id'];
  1068. }
  1069. } else {
  1070. $parentSaasId = $parentSaasUser['parent_id'];
  1071. }
  1072. }
  1073. }
  1074. }
  1075. }
  1076. //debug_log([__METHOD__, __LINE__, "加入节点店铺:【{$store_id}】,父节点:{$parent_id}"], "app_debug.log");
  1077. //都查不到用string_code_root_user_id
  1078. if (empty($parent_id)) {
  1079. $string_code_root_user_id = self::getRootUserId($store_id, self::MODEL_SHOP);
  1080. $parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $string_code_root_user_id]);
  1081. if (!$parent_node) {
  1082. //debug_log([__METHOD__, __LINE__, "加入节点店铺:【{$store_id}】,根节点用户:{$string_code_root_user_id}不存在"], "app_debug.log");
  1083. return [null, $real_area_key, $real_layer_rank];
  1084. }
  1085. $parent_id = $parent_node['user_id'];
  1086. //debug_log([__METHOD__, __LINE__, "加入节点店铺:【{$store_id}】,根节点用户:{$parent_id}"], "app_debug.log");
  1087. }
  1088. }
  1089. }
  1090. //debug_log([__METHOD__, __LINE__, "加入节点店铺:【{$store_id}】,父节点:{$parent_id}"], "app_debug.log");
  1091. $children_list = self::findOne(['store_id' => $store_id, 'parent_node' => $parent_id]);
  1092. // 未有子节点
  1093. if (!$children_list) {
  1094. //debug_log([__METHOD__, __LINE__, "{$parent_id} 未有子节点"], "app_debug.log");
  1095. $real_parent_node = $parent_node;
  1096. return [$real_parent_node, $real_area_key, $real_layer_rank];
  1097. }
  1098. //debug_log([__METHOD__, __LINE__, "门店模型{$string_code_shop_value}"], "app_debug.log");
  1099. // 默认品牌模型
  1100. if ($string_code_shop_value == 0) {
  1101. // 先判断 最大层级下 左区是否能占位
  1102. $temp_parent_id = $parent_id;
  1103. //debug_log([__METHOD__, __LINE__, "推荐人:{$parent_id},1-区:{$max_layer} 查找"], "app_debug.log");
  1104. for ($i = 0; $i < $max_layer; $i++) {
  1105. //debug_log([__METHOD__, __LINE__, "1-区 循环:{$i},用户ID:{$temp_parent_id}"], "app_debug.log");
  1106. $temp_node = self::findOne(['store_id' => $store_id, 'parent_node' => $temp_parent_id, 'area_key' => 0]);
  1107. if (!$temp_node) {
  1108. $real_parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $temp_parent_id]);
  1109. return [$real_parent_node, $real_layer_rank, $real_area_key];
  1110. } else {
  1111. $temp_parent_id = $temp_node['user_id'];
  1112. }
  1113. }
  1114. // 再判断 最大层级下 右区是否能占位
  1115. // 判断推荐人能否开第2区
  1116. $parent_second_col_auth = self::checkSecondColumnAuth($store_id, $order_user_id, $parent_id);
  1117. if ($parent_second_col_auth) {
  1118. // 判断第2-区第一个有无占位
  1119. //debug_log([__METHOD__, __LINE__, "推荐人:{$parent_id},2-区可开"], "app_debug.log");
  1120. $temp_node = self::findOne(['store_id' => $store_id, 'parent_node' => $parent_id, 'area_key' => 1]);
  1121. if (!$temp_node) {
  1122. $real_parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $parent_id]);
  1123. $current_layer_rank = self::find()
  1124. ->where(['store_id' => $store_id, 'layer_node' => $real_parent_node['layer_node'] + 1])
  1125. ->max('layer_rank');
  1126. $real_layer_rank = $current_layer_rank + 1;
  1127. return [$real_parent_node, $real_layer_rank, 1];
  1128. } else {
  1129. // 先判断 最大层级下 右区是否能占位
  1130. $temp_parent_id = $temp_node['user_id'];
  1131. //debug_log([__METHOD__, __LINE__, "推荐人:{$parent_id},2-区:{$max_layer} 查找"], "app_debug.log");
  1132. for ($i = 0; $i < $max_layer - 1; $i++) {
  1133. //debug_log([__METHOD__, __LINE__, "2-区 循环:{$i},用户ID:{$temp_parent_id}"], "app_debug.log");
  1134. $temp_node = self::findOne(['store_id' => $store_id, 'parent_node' => $temp_parent_id, 'area_key' => 0]);
  1135. if (!$temp_node) {
  1136. $real_parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $temp_parent_id]);
  1137. return [$real_parent_node, $real_layer_rank, 0];
  1138. } else {
  1139. $temp_parent_id = $temp_node['user_id'];
  1140. }
  1141. }
  1142. }
  1143. } else {
  1144. //debug_log([__METHOD__, __LINE__, "推荐人:{$parent_id},2-区不可开"], "app_debug.log");
  1145. }
  1146. $queue = [];
  1147. $queue[] = $parent_node;
  1148. $search_layer = 0; // 搜索层数
  1149. while (!empty($queue)) {
  1150. $n = count($queue);
  1151. // 层序遍历
  1152. for ($i = 0; $i < $n; $i++) {
  1153. // 变量 i 无实际意义,只是为了循环 n 次
  1154. // 当前节点
  1155. $current_node = array_shift($queue);
  1156. //debug_log([__METHOD__, __LINE__, "当前节点ID:{$current_node['user_id']},搜索层数:{$search_layer}"], "app_debug.log");
  1157. // 判断用户第1-区有无落点
  1158. $parent_first_col_auth = self::findOne(['store_id' => $store_id, 'parent_node' => $current_node['user_id'], 'area_key' => 0]);
  1159. if (!$parent_first_col_auth) {
  1160. $real_area_key = 0;
  1161. //debug_log([__METHOD__, __LINE__, "当前节点ID:{$current_node['user_id']},1-区没人,落第1-区"], "app_debug.log");
  1162. $real_parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $current_node['user_id']]);
  1163. $current_layer_rank = self::find()
  1164. ->where(['store_id' => $store_id, 'layer_node' => $real_parent_node['layer_node'] + 1])
  1165. ->max('layer_rank');
  1166. $real_layer_rank = $current_layer_rank + 1;
  1167. return [$real_parent_node, $real_layer_rank, $real_area_key];
  1168. }
  1169. // 大于最大限制层数
  1170. // 查询当前节点的子节点
  1171. $children_nodes = self::find()->where(['store_id' => $store_id, 'parent_node' => $current_node['user_id']])->orderBy("area_key ASC")->all();
  1172. if ($children_nodes) {
  1173. foreach ($children_nodes as $node) {
  1174. $queue[] = $node;
  1175. }
  1176. }
  1177. $search_layer++;
  1178. }
  1179. }
  1180. }
  1181. // 门店模型
  1182. if ($string_code_shop_value == 1) {
  1183. // 直线推荐关系,逐级查找父节点直到满足条件
  1184. $current_node = self::findOne(['store_id' => $store_id, 'user_id' => $parent_id]);
  1185. // 从父节点开始,逐级向上查找父节点直到满足条件
  1186. while ($current_node) {
  1187. //debug_log([__METHOD__, __LINE__, "当前节点ID:{$current_node['user_id']}"], "app_debug.log");
  1188. // 判断左区是否可以占位
  1189. $parent_first_col_auth = self::findOne(['store_id' => $store_id, 'parent_node' => $current_node['user_id'], 'area_key' => 0]);
  1190. if (!$parent_first_col_auth) {
  1191. $real_area_key = 0; // 1-区没人,落第1-区
  1192. //debug_log([__METHOD__, __LINE__, "当前节点ID:{$current_node['user_id']},1-区没人,落第1-区"], "app_debug.log");
  1193. // 查找父节点并返回
  1194. $real_parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $current_node['user_id']]);
  1195. $current_layer_rank = self::find()
  1196. ->where(['store_id' => $store_id, 'layer_node' => $real_parent_node['layer_node'] + 1])
  1197. ->max('layer_rank');
  1198. $real_layer_rank = $current_layer_rank + 1;
  1199. return [$real_parent_node, $real_layer_rank, $real_area_key]; // 返回左区的位置
  1200. }
  1201. // 如果左区占位,继续向上查找
  1202. $current_node = self::findOne(['store_id' => $store_id, 'user_id' => $current_node['parent_node']]);
  1203. }
  1204. }
  1205. }
  1206. /**
  1207. * 获取用户最后一个节点
  1208. * 深度优先,从左至右 落满左区成完全树
  1209. * @param $store_id 店铺ID
  1210. * @param $user_id 下单用户ID
  1211. * @param $parent_id 下单用户上级ID
  1212. * @param $max_layer 限制最大层数
  1213. * @return array
  1214. */
  1215. public static function getRealParentNodeBack($store_id, $order_user_id, $parent_id, $max_layer)
  1216. {
  1217. // 针对父节点对应的区
  1218. $real_area_key = 0;
  1219. // 针对根节点对应的排序
  1220. $real_layer_rank = 0;
  1221. $parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $parent_id]);
  1222. $children_list = self::findOne(['store_id' => $store_id, 'parent_node' => $parent_id]);
  1223. // 未有子节点
  1224. if (!$children_list) {
  1225. //debug_log([__METHOD__, __LINE__, "未有子节点"], "app_debug.log");
  1226. $real_parent_node = $parent_node;
  1227. return [$real_parent_node, $real_area_key, $real_layer_rank];
  1228. }
  1229. $queue = [];
  1230. $queue[] = $parent_node;
  1231. $search_layer = 0; // 搜索层数
  1232. while (!empty($queue)) {
  1233. $n = count($queue);
  1234. // 层序遍历
  1235. for ($i = 0; $i < $n; $i++) {
  1236. // 变量 i 无实际意义,只是为了循环 n 次
  1237. // 当前节点
  1238. $current_node = array_shift($queue);
  1239. //debug_log([__METHOD__, __LINE__, "当前节点ID:{$current_node['user_id']},搜索层数:{$search_layer}"], "app_debug.log");
  1240. if ($search_layer < $max_layer) {
  1241. // 小于最大限制层级
  1242. // 深度优先 $max_layer - $search_layer 控制遍历层次深度
  1243. $res = self::findLastNode($store_id, $order_user_id, $current_node, $max_layer - $search_layer);
  1244. if ($res) {
  1245. return $res;
  1246. }
  1247. }
  1248. // 大于最大限制层数
  1249. // 查询当前节点的子节点
  1250. $children_nodes = self::find()->where(['store_id' => $store_id, 'parent_node' => $current_node['user_id']])->orderBy("area_key ASC")->all();
  1251. if ($children_nodes) {
  1252. foreach ($children_nodes as $node) {
  1253. $queue[] = $node;
  1254. }
  1255. }
  1256. $search_layer++;
  1257. }
  1258. }
  1259. }
  1260. /**
  1261. * 算法查找最后落点
  1262. * @param $store_id 店铺id
  1263. * @param UserStringCodePlus $node 节点
  1264. * @param $depth 查找深度
  1265. * @param $remain_node
  1266. * @return array
  1267. */
  1268. public static function findLastNode($store_id, $order_user_id, $node, $depth, $remain_node = [])
  1269. {
  1270. //debug_log([__METHOD__, __LINE__, "算法查找最后落点:{$node['user_id']},深度层数:{$depth}"], "app_debug.log");
  1271. if ($depth < 0 && !$remain_node) {
  1272. // 还有剩余节点,继续找
  1273. $temp_node = array_shift($remain_node);
  1274. $depth = $temp_node['layer_node'];
  1275. return self::findLastNode($store_id, $order_user_id, $temp_node, $depth, $remain_node);
  1276. }
  1277. if ($depth < 0 && empty($remain_node)) {
  1278. return null;
  1279. }
  1280. // 针对父节点对应的区
  1281. $real_area_key = 0;
  1282. // 针对根节点对应的排序
  1283. $real_layer_rank = 0;
  1284. // 左子树队列 不包括 根节点
  1285. $left_queue = [];
  1286. // 先左子数查满层
  1287. $temp_parent_id = $node['user_id'];
  1288. for ($i = 0; $i < $depth; $i++) {
  1289. $temp_node = UserStringCodePlus::findOne(['store_id' => $store_id, 'parent_node' => $temp_parent_id, 'area_key' => $real_area_key]);
  1290. if (!$temp_node) {
  1291. $real_parent_node = UserStringCodePlus::findOne(['store_id' => $store_id, 'user_id' => $temp_parent_id]);
  1292. //debug_log([__METHOD__, __LINE__, "A区深度查找:节点未占,落点:{$temp_parent_id},深度层数:{$depth},A区循环:{$i}"], "app_debug.log");
  1293. return [$real_parent_node, $real_layer_rank, $real_area_key];
  1294. } else {
  1295. //debug_log([__METHOD__, __LINE__, "A区深度查找:节点被{$temp_node['user_id']}占点,深度层数:{$depth},A区循环:{$i}"], "app_debug.log");
  1296. $temp_parent_id = $temp_node['user_id'];
  1297. $left_queue[] = $temp_node;
  1298. $remain_node[] = $temp_node;
  1299. }
  1300. }
  1301. //debug_log([__METHOD__, __LINE__, "算法查找最后落点:{$node['user_id']},A区深度:{$depth} 找不到落点"], "app_debug.log");
  1302. // 除了根结点,深度减 1
  1303. $depth = $depth - 1;
  1304. //debug_log([__METHOD__, __LINE__, "算法查找最后落点:{$node['user_id']},深度层数:{$depth}"], "app_debug.log");
  1305. foreach ($left_queue as $index => $item_node) {
  1306. // 判断用户能否开第2区
  1307. $parent_second_col_auth = self::checkSecondColumnAuth($store_id, $order_user_id, $item_node['user_id']);
  1308. if ($parent_second_col_auth) {
  1309. // 判断第2区第一个有无占位
  1310. //debug_log([__METHOD__, __LINE__, "算法查找最后落点:{$item_node['user_id']},B区可开"], "app_debug.log");
  1311. $real_area_key = 1;
  1312. $temp_node = UserStringCodePlus::findOne(['store_id' => $store_id, 'parent_node' => $item_node['user_id'], 'area_key' => $real_area_key]);
  1313. if (!$temp_node) {
  1314. $real_parent_node = UserStringCodePlus::findOne(['store_id' => $store_id, 'user_id' => $item_node['user_id']]);
  1315. $current_layer_rank = UserStringCodePlus::find()
  1316. ->where(['store_id' => $store_id, 'layer_node' => $real_parent_node['layer_node'] + 1])
  1317. ->max('layer_rank');
  1318. $real_layer_rank = $current_layer_rank + 1;
  1319. return [$real_parent_node, $real_layer_rank, $real_area_key];
  1320. } else {
  1321. return self::findLastNode($store_id, $order_user_id, $temp_node, $depth - $index - 1, $remain_node);
  1322. }
  1323. } else {
  1324. //debug_log([__METHOD__, __LINE__, "算法查找最后落点:{$item_node['user_id']},B区不可开"], "app_debug.log");
  1325. }
  1326. }
  1327. // A 区满,又不可开B区
  1328. return null;
  1329. }
  1330. /**
  1331. * 判断用户是否能开第 2 区
  1332. * 条件 直推一个且已排位置 就可开通 2 区
  1333. * @param $store_id
  1334. * @param $user_id
  1335. * @param $max_layer
  1336. * @return bool
  1337. */
  1338. public static function checkSecondColumnAuth($store_id, $order_user_id, $user_id)
  1339. {
  1340. if ($store_id == self::ALLIANCE_STORE_ID) {
  1341. $invite_user_ids = SaasUser::find()
  1342. ->where(['parent_id' => $user_id])
  1343. ->select('id')
  1344. ->column();
  1345. } else {
  1346. $invite_user_ids = User::find()
  1347. ->where(['store_id' => $store_id, 'parent_id' => $user_id])
  1348. ->column();
  1349. }
  1350. $node = self::find()
  1351. ->where(['store_id' => $store_id])
  1352. ->andWhere(['in', 'user_id', $invite_user_ids])
  1353. ->select('id')
  1354. ->one();
  1355. if ($node) {
  1356. return true;
  1357. } else {
  1358. return false;
  1359. }
  1360. }
  1361. /**
  1362. * 深度优先搜索
  1363. * @param $node
  1364. * @return mixed
  1365. */
  1366. public static function findLastNodeDFS($node, $depth, $current_depth = 0)
  1367. {
  1368. // 达到指定深度,退出
  1369. if ($current_depth + 1 >= $depth) {
  1370. return null;
  1371. }
  1372. $last_node = $node;
  1373. $children_nodes = self::find()->where(['store_id' => $last_node['store_id'], 'parent_node' => $last_node['user_id']])->orderBy("area_key ASC")->all();
  1374. // 判断右子树是否有
  1375. // 递归处理所有子树
  1376. foreach ($children_nodes as $children_node) {
  1377. $temp = self::findLastNodeDFS($children_node, $depth, $current_depth + 1);
  1378. if ($temp) {
  1379. $last_node = $temp;
  1380. }
  1381. }
  1382. return $last_node;
  1383. }
  1384. /**
  1385. * 获取用户最后一个节点
  1386. * 从上至下,从左至右
  1387. * @param $store_id 店铺ID
  1388. * @param $parent_id 上级ID
  1389. * @return array
  1390. */
  1391. public static function findLastNodeBFS($store_id, $parent_id)
  1392. {
  1393. $parent_node = self::findOne(['store_id' => $store_id, 'user_id' => $parent_id]);
  1394. $queue = [];
  1395. $queue[] = $parent_node;
  1396. $search_layer = 0; // 搜索层数
  1397. while (!empty($queue)) {
  1398. $n = count($queue);
  1399. // 层序遍历
  1400. for ($i = 0; $i < $n; $i++) {
  1401. // 变量 i 无实际意义,只是为了循环 n 次
  1402. // 当前节点
  1403. $current_node = array_shift($queue);
  1404. // //debug_log([__METHOD__, __LINE__, "当前节点ID:{$current_node['user_id']},搜索层数:{$search_layer}"], "app_debug.log");
  1405. echo "搜索层数:{$search_layer}:{$current_node['user_id']} \n";
  1406. // 大于最大限制层数
  1407. // 查询当前节点的子节点
  1408. $children_nodes = self::find()->where(['store_id' => $store_id, 'parent_node' => $current_node['user_id']])->orderBy("area_key ASC")->all();
  1409. if ($children_nodes) {
  1410. foreach ($children_nodes as $node) {
  1411. $queue[] = $node;
  1412. }
  1413. }
  1414. $search_layer++;
  1415. }
  1416. }
  1417. }
  1418. public static function getAllParentIds($user_id)
  1419. {
  1420. $relation = self::findOne(['user_id' => $user_id]);
  1421. $recommon_relation = trim($relation['recommend_relation'], ',');
  1422. if (!$recommon_relation) return [];
  1423. return explode(',', $recommon_relation);
  1424. }
  1425. /**
  1426. * 获取所有上级节点 user_ids
  1427. * @param $store_id
  1428. * @param $user_id
  1429. * @return array|false|string[]
  1430. */
  1431. public static function getAllParentNodeIds($store_id, $user_id)
  1432. {
  1433. $relation = self::findOne(['store_id' => $store_id, 'user_id' => $user_id]);
  1434. $recommon_relation_node = trim($relation['recommend_relation_node'], ',');
  1435. if (!$recommon_relation_node) return [];
  1436. return explode(',', $recommon_relation_node);
  1437. }
  1438. public static function getAllParentNodeIdsAll($store_id, $user_id,$is_scan=0)
  1439. {
  1440. if($is_scan == 0){
  1441. $users = \Yii::$app->db->createCommand("
  1442. SELECT *
  1443. FROM cyy_user
  1444. WHERE id = :id
  1445. ", [
  1446. ':id' => $user_id
  1447. ])->queryOne();
  1448. $saas_user = \Yii::$app->db->createCommand("
  1449. SELECT *
  1450. FROM cyy_saas_user
  1451. WHERE mobile = :mobile
  1452. ", [
  1453. ':mobile' => $users['binding']
  1454. ])->queryOne();
  1455. if($store_id == -1){
  1456. $saas_user = \Yii::$app->db->createCommand("
  1457. SELECT *
  1458. FROM cyy_saas_user
  1459. WHERE id = :id
  1460. ", [
  1461. ':id' => $user_id
  1462. ])->queryOne();
  1463. }
  1464. $ranking_user = \Yii::$app->db->createCommand("
  1465. SELECT *
  1466. FROM ysdl_ranking_user
  1467. WHERE store_id = :storeId
  1468. AND saas_user_id = :saasUserId
  1469. ", [
  1470. ':storeId' => $store_id,
  1471. ':saasUserId' => $saas_user['id']
  1472. ])->queryOne();
  1473. if ($ranking_user) {
  1474. $ranking_user_list = str_replace(['[', ']'], '', $ranking_user['tree_saas_path']);
  1475. if (!empty($ranking_user_list)) {
  1476. $ranking_user_list_array = explode(',', $ranking_user_list);
  1477. } else {
  1478. $ranking_user_list_array = [];
  1479. }
  1480. $ranking_user_list_array [] = SaasUser::findSaasIdByUserId($user_id);;
  1481. $new_ranking_user_list = [];
  1482. if (!empty($ranking_user_list_array)) {
  1483. foreach ($ranking_user_list_array as $key => &$val) {
  1484. $rank_info = \Yii::$app->db->createCommand("
  1485. SELECT node_valid
  1486. FROM ysdl_ranking_user
  1487. WHERE store_id = :storeId
  1488. AND saas_user_id = :saasUserId
  1489. ", [
  1490. ':storeId' => $store_id,
  1491. ':saasUserId' => $val
  1492. ])->queryOne();
  1493. if ($rank_info['node_valid'] == 1) {
  1494. $mobile = \Yii::$app->db->createCommand("
  1495. SELECT mobile
  1496. FROM cyy_saas_user
  1497. WHERE id = :userId
  1498. ", [
  1499. ':userId' => $val
  1500. ])->queryScalar();
  1501. $new_ranking_user_list[] = \Yii::$app->db->createCommand("
  1502. SELECT id
  1503. FROM cyy_user
  1504. WHERE binding = :binding
  1505. AND store_id = :storeId
  1506. LIMIT 1
  1507. ", [
  1508. ':binding' => $mobile,
  1509. ':storeId' => $store_id
  1510. ])->queryScalar();
  1511. } else {
  1512. unset($ranking_user_list_array[$key]);
  1513. }
  1514. }
  1515. }
  1516. if ($store_id == -1) {
  1517. return $ranking_user_list_array;
  1518. } else {
  1519. return $new_ranking_user_list;
  1520. }
  1521. } else {
  1522. if ($store_id == -1) {
  1523. return [SaasUser::findSaasIdByUserId($user_id)];
  1524. } else {
  1525. return [$user_id];
  1526. }
  1527. }
  1528. } else {
  1529. sleep(1);
  1530. $relation = self::findOne(['store_id' => $store_id, 'user_id' => $user_id]);
  1531. if ($relation) {
  1532. $recommon_relation_node = trim($relation['recommend_relation_node'], ',');
  1533. $recommon_relation_node =$recommon_relation_node.",".$user_id;
  1534. if (!$recommon_relation_node) return [-1];
  1535. return explode(',', $recommon_relation_node);
  1536. } else {
  1537. return [$user_id];
  1538. }
  1539. $recommon_relation_node = trim($relation['recommend_relation_node'], ',');
  1540. $recommon_relation_node =$recommon_relation_node.",".$user_id;
  1541. if (!$recommon_relation_node) return [$user_id];
  1542. return explode(',', $recommon_relation_node);
  1543. }
  1544. /*$relation = self::findOne(['store_id' => $store_id, 'user_id' => $user_id]);
  1545. if ($relation) {
  1546. $recommon_relation_node = trim($relation['recommend_relation_node'], ',');
  1547. if (!$recommon_relation_node) return [-1];
  1548. return explode(',', $recommon_relation_node);
  1549. } else {
  1550. return [];
  1551. }*/
  1552. }
  1553. public static function getChildNodeIdsByUserId($user_id, $area_key = '', $level = 0, $scope = 'all')
  1554. {
  1555. $user_node = self::find()->select(['layer_node'])->where(['user_id' => $user_id])->asArray()->one();
  1556. $layer_node = (int)$user_node['layer_node'];
  1557. $query = self::find()->select(['user_id'])->where(['like', 'recommend_relation_node', (',' . $user_id . ',')]);
  1558. if ($area_key) $query->andWhere(['area_key' => $area_key]);
  1559. //查询多N代全部子用户
  1560. if ($level > 0 && $scope == 'all') $query->andWhere(['>=', 'layer_node', $level + $layer_node]);
  1561. //查询指定代子用户
  1562. if ($level > 0 && $scope == 'equal') $query->andWhere(['=', 'layer_node', $level + $layer_node]);
  1563. return $query->asArray()->column();
  1564. }
  1565. /**
  1566. * 查询用户指定部门的所有用户
  1567. * @param $user_id
  1568. * @param $node_key
  1569. * @return array
  1570. */
  1571. public static function getChildNodeIdsByNodeKey($user_id, $department_key)
  1572. {
  1573. // if ($department_key) {
  1574. // // 其他 部门
  1575. // $first_node = self::find()->select(['user_id'])
  1576. // ->where(['parent_id' => $user_id, 'node_key' => $department_key])
  1577. // ->asArray()
  1578. // ->one();
  1579. // if (!$first_node) return [];
  1580. // $res = self::find()->select(['user_id'])
  1581. // ->where(['or', ['user_id' => $first_node['user_id']], ['like', 'recommend_relation_node', (',' . $first_node['user_id'] . ',')]])
  1582. // ->asArray()->column();
  1583. // } else {
  1584. // // A 部门
  1585. // $res = self::find()->select(['user_id'])
  1586. // ->where(['like', 'recommend_relation_node', (',' . $user_id . ',')])
  1587. // ->asArray()->column();
  1588. // }
  1589. $res = UserNodeDepartment::find()->select(['child_id'])
  1590. ->where(['user_id' => $user_id, 'department_key' => $department_key])
  1591. ->asArray()->column();
  1592. return $res;
  1593. }
  1594. public static function getAllParentList($user_id)
  1595. {
  1596. $relation = self::findOne(['user_id' => $user_id]);
  1597. $recommon_relation = trim($relation['recommend_relation'], ',');
  1598. $relation_arr = explode(',', $recommon_relation);
  1599. if (empty($relation_arr)) {
  1600. return [];
  1601. }
  1602. $list = Share::find()->alias('s')->where(array('in', 's.user_id', $relation_arr))
  1603. ->andWhere(['sl.is_delete' => 0])
  1604. ->leftJoin(['sl' => ShareLevel::tableName()], 'sl.level=s.level')
  1605. ->select('s.user_id, sl.order_layer, sl.point_reward')
  1606. ->asArray()
  1607. ->all();
  1608. if (empty($list)) {
  1609. return [];
  1610. }
  1611. $level_list = ArrayHelper::index($list, "user_id");
  1612. $res = [];
  1613. foreach ($relation_arr as $v) {
  1614. $temp = [];
  1615. $temp['user_id'] = $v;
  1616. $temp['order_layer'] = $level_list[$v]['order_layer'] ?? 0;
  1617. $temp['point_reward'] = $level_list[$v]['point_reward'] ?? 0;
  1618. $temp['is_bonus'] = isset($level_list[$v]);
  1619. $res[] = $temp;
  1620. }
  1621. return $res;
  1622. }
  1623. public static function getAllParentNodeList($user_id)
  1624. {
  1625. $relation = self::findOne(['user_id' => $user_id]);
  1626. $recommon_relation_node = trim($relation['recommend_relation_node'], ',');
  1627. $relation_arr = explode(',', $recommon_relation_node);
  1628. if (empty($relation_arr)) {
  1629. return [];
  1630. }
  1631. $list = Share::find()->alias('s')->where(array('in', 's.user_id', $relation_arr))
  1632. ->andWhere(['sl.is_delete' => 0])
  1633. ->leftJoin(['sl' => ShareLevel::tableName()], 'sl.level=s.level')
  1634. ->select('s.user_id, sl.order_layer, sl.point_reward')
  1635. ->asArray()
  1636. ->all();
  1637. if (empty($list)) {
  1638. return [];
  1639. }
  1640. $level_list = ArrayHelper::index($list, "user_id");
  1641. $res = [];
  1642. foreach ($relation_arr as $v) {
  1643. $temp = [];
  1644. $temp['user_id'] = $v;
  1645. $temp['order_layer'] = $level_list[$v]['order_layer'] ?? 0;
  1646. $temp['point_reward'] = $level_list[$v]['point_reward'] ?? 0;
  1647. $temp['is_bonus'] = isset($level_list[$v]);
  1648. $res[] = $temp;
  1649. }
  1650. return $res;
  1651. }
  1652. public static function getRecommendRelationByUserId($user_id)
  1653. {
  1654. $res = "";
  1655. $parentList = [];
  1656. self::getParentList($user_id, $parentList);
  1657. if ($parentList) {
  1658. $res = "," . implode(',', array_reverse($parentList)) . ",";
  1659. }
  1660. return $res;
  1661. }
  1662. public static function getParentList($user_id, &$parentList)
  1663. {
  1664. $user = User::findOne(['id' => $user_id]);
  1665. if ($user['parent_id']) {
  1666. $parentList[] = $user['parent_id'];
  1667. $parent = User::findOne(['id' => $user['parent_id']]);
  1668. if ($parent) {
  1669. return self::getParentList($parent['id'], $parentList);
  1670. }
  1671. }
  1672. return $parentList;
  1673. }
  1674. public static function getLayerByUserId($user_id)
  1675. {
  1676. $res = 1;
  1677. $parentList = [];
  1678. self::getParentList($user_id, $parentList);
  1679. if ($parentList) {
  1680. $res += count($parentList);
  1681. }
  1682. return $res;
  1683. }
  1684. public static function createRootNode($store_id, $user_id)
  1685. {
  1686. $root_node = self::findOne(['store_id' => $store_id, 'user_id' => $user_id]);
  1687. if (!$root_node) {
  1688. $saas_user_id = SaasUser::findSaasIdByUserId($user_id);
  1689. $root_node = new UserStringCodePlus();
  1690. $root_node->store_id = $store_id;
  1691. $root_node->user_id = $user_id;
  1692. $root_node->area_key = 0;
  1693. $root_node->recommend_relation = "";
  1694. $root_node->recommend_relation_node = "";
  1695. $root_node->saas_id = $saas_user_id;
  1696. if (!$root_node->save()) {
  1697. //debug_log([__METHOD__, __LINE__, "用户:{$user_id},节点信息保存失败"], "app_debug.log");
  1698. }
  1699. }
  1700. return $root_node;
  1701. }
  1702. public static function createUserNode($store_id, $user_id)
  1703. {
  1704. $user_node = UserStringCodePlus::findOne(['store_id' => $store_id, 'user_id' => $user_id]);
  1705. if (!$user_node) {
  1706. $user = User::findOne(['id' => $user_id]);
  1707. $saas_user_id = SaasUser::findSaasIdByUserId($user_id);
  1708. $user_node = new UserStringCodePlus();
  1709. $user_node->store_id = $store_id;
  1710. $user_node->user_id = $user_id;
  1711. $user_node->parent_id = $user['parent_id'];
  1712. $user_node->recommend_relation = self::getRecommendRelationByUserId($user_id);
  1713. $user_node->layer = self::getLayerByUserId($user_id);
  1714. $user_node->recommend_relation_node = "";
  1715. $user_node->layer_node = 0;
  1716. $user_node->created_at = time();
  1717. $user_node->saas_id = $saas_user_id;
  1718. if (!$user_node->save()) {
  1719. //debug_log([__METHOD__, __LINE__, "用户:{$user_id},节点信息保存失败"], "app_debug.log");
  1720. }
  1721. }
  1722. return $user_node;
  1723. }
  1724. public static function getChildNodeCount($store_id, $user_id)
  1725. {
  1726. $node_count = self::find()->select('COUNT(id) as node_count')
  1727. ->where(['store_id' => $store_id])
  1728. ->andWhere(['like', 'recommend_relation_node', (',' . $user_id . ',')])->scalar();
  1729. return (int)$node_count;
  1730. }
  1731. public static function getChildNodeCountNew($store_id, $user_id)
  1732. {
  1733. $storeStringCodeSet = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  1734. $storeStringCodeSet = json_decode($storeStringCodeSet['value'], true);
  1735. $string_code_max_layer = $storeStringCodeSet['string_code_max_layer'];
  1736. $max_level = $string_code_max_layer; // 限制最大层级为 20
  1737. $node_count = 0;
  1738. $queue = [];
  1739. // 获取根节点
  1740. $root_node = self::findOne(['store_id' => $store_id, 'parent_node' => $user_id]);
  1741. if (!$root_node) {
  1742. return 0; // 如果没有找到根节点,则返回 0
  1743. }
  1744. // 初始化队列,存储每个节点及其层级
  1745. $queue[] = ['node' => $root_node, 'level' => 0]; // 初始层级为 0
  1746. while (!empty($queue)) {
  1747. $current_item = array_shift($queue); // 获取队列中的第一个节点
  1748. $current_node = $current_item['node'];
  1749. $current_level = $current_item['level'];
  1750. // 如果当前层级大于最大层级,则停止继续查找子节点
  1751. if ($current_level >= $max_level) {
  1752. continue;
  1753. }
  1754. // 查找当前节点的子节点
  1755. $children_nodes = self::find()->where(['store_id' => $store_id, 'parent_node' => $current_node['user_id']])->all();
  1756. if ($children_nodes) {
  1757. foreach ($children_nodes as $node) {
  1758. // 将子节点及其层级加入队列
  1759. $queue[] = ['node' => $node, 'level' => $current_level + 1];
  1760. }
  1761. }
  1762. // 计数当前节点
  1763. $node_count++;
  1764. }
  1765. return $node_count;
  1766. }
  1767. public static function getTeamNodeOrderPrice($store_id, $user_id)
  1768. {
  1769. $child_ids = self::getChildNodeIdsByUserId($store_id, $user_id);
  1770. $team_ids = array_merge($child_ids, [$user_id]);
  1771. $res = UserWallet::find()
  1772. ->where(['store_id' => $store_id, 'currency_code' => Currency::CURRENCY_COIN])
  1773. ->andWhere(['in', 'user_id', $team_ids])
  1774. ->select('SUM(`money_total`) as node_order_price')
  1775. ->scalar();
  1776. return round($res, 4);
  1777. }
  1778. /**
  1779. * 获取用户部门列表
  1780. * @param $user_id
  1781. * @return array
  1782. */
  1783. public static function getUserDepartmentList($store_id, $user_id)
  1784. {
  1785. $user = User::findOne(['id' => $user_id]);
  1786. $user_share_holder_level = ShareHolder::findOne(['user_id' => $user_id]);
  1787. if ($user['total_coin'] < 50) {
  1788. // 未消费大礼包只有A部门
  1789. $department_key_highest = 0;
  1790. } else {
  1791. // 有消费则有A,B等多部门
  1792. if ($user_share_holder_level['level_id'] < 9) {
  1793. // 股东等级小于V7只有A,B两条线
  1794. $department_key_highest = 1;
  1795. } else {
  1796. // 大于等于V7可开多线
  1797. $department_key_highest = self::getLastNodeKeyByUserId($user_id) + 1;
  1798. }
  1799. }
  1800. $res = [];
  1801. for ($department_key = 0; $department_key <= $department_key_highest; $department_key++) {
  1802. $last_user_id = self::getLastUserByDepartmentKey($user_id, $department_key);
  1803. $last_user = User::findOne(['id' => $last_user_id]);
  1804. $department_name = $department_key + 1;
  1805. $temp = [];
  1806. $temp['id'] = $department_key;
  1807. $temp['department_key'] = $department_key;
  1808. $temp['user_id'] = $last_user_id;
  1809. $temp['department_name'] = "{$department_name}-部门";
  1810. $temp['nickname'] = $last_user['nickname'];
  1811. $temp['mobile'] = $last_user['binding'];
  1812. $res[] = $temp;
  1813. }
  1814. return $res;
  1815. }
  1816. /**
  1817. * 获取指定用户最高部门 node_key
  1818. * @param $user_id
  1819. * @return int|mixed
  1820. */
  1821. public static function getLastNodeKeyByUserId($user_id)
  1822. {
  1823. $last_node_key = 0;
  1824. $node_list = UserStringCodePlus::find()
  1825. ->where(['parent_id' => $user_id])
  1826. ->orderBy('node_key DESC')
  1827. ->asArray()
  1828. ->one();
  1829. if ($node_list) {
  1830. $last_node_key = $node_list['node_key'];
  1831. }
  1832. return $last_node_key;
  1833. }
  1834. /**
  1835. * 获取指定用户的部门最后一个用户
  1836. * @param $user_id
  1837. * @param $department_name
  1838. * @return int
  1839. */
  1840. public static function getLastUserByDepartmentKey($user_id, $department_key)
  1841. {
  1842. // $first_node = self::find()->select(['user_id'])
  1843. // ->where(['parent_id' => $user_id, 'node_key' => $department_key])
  1844. // ->asArray()
  1845. // ->one();
  1846. // if (!$first_node) return (int)$user_id;
  1847. //
  1848. // $last_user_node = UserNode::find()
  1849. // ->where(['or', ['user_id' => $first_node['user_id']], ['like', 'recommend_relation_node', (',' . $first_node['user_id'] . ',')]])
  1850. // ->orderBy('layer_node DESC')
  1851. // ->asArray()
  1852. // ->one();
  1853. //
  1854. // if ($last_user_node) {
  1855. // return (int)$last_user_node['user_id'];
  1856. // } else {
  1857. // return (int)$user_id;
  1858. // }
  1859. $last = UserNodeDepartment::find()
  1860. ->where(['user_id' => $user_id, 'department_key' => $department_key])
  1861. ->orderBy('id DESC')
  1862. ->asArray()
  1863. ->one();
  1864. return $last['user_id'];
  1865. }
  1866. public static function getLastParentNodeLeader($user_id)
  1867. {
  1868. $user_node = self::findOne(['user_id' => $user_id]);
  1869. if ($user_node->parent_id == $user_node->parent_node) {
  1870. return self::findOne(['user_id' => $user_node->parent_id]);
  1871. } else {
  1872. return self::getLastParentNodeLeader($user_node->parent_node);
  1873. }
  1874. }
  1875. /**
  1876. * 查询用户指定部门的所有用户 ids
  1877. * @param $user_id
  1878. * @param $node_key
  1879. * @return array
  1880. */
  1881. public static function getChildNodeIdsByAreaKey($store_id, $user_id, $area_key)
  1882. {
  1883. $child_ids = [];
  1884. $queue = [];
  1885. $root_node = self::findOne(['store_id' => $store_id, 'parent_node' => $user_id, 'area_key' => $area_key]);
  1886. $queue[] = $root_node;
  1887. while (!empty($queue)) {
  1888. $current_node = array_shift($queue);
  1889. $children_nodes = self::find()->where(['store_id' => $store_id, 'parent_node' => $current_node['user_id']])->all();
  1890. if ($children_nodes) {
  1891. foreach ($children_nodes as $node) {
  1892. $queue[] = $node;
  1893. }
  1894. }
  1895. $child_ids[] = $current_node['user_id'];
  1896. }
  1897. return $child_ids;
  1898. }
  1899. public static function getChildNodeIdsByAreaKeyToMaxLayer($store_id, $user_id, $area_key)
  1900. {
  1901. $child_ids = [];
  1902. $queue = [];
  1903. $root_node = self::findOne(['store_id' => $store_id, 'parent_node' => $user_id, 'area_key' => $area_key]);
  1904. // 初始化队列并设置层级
  1905. $queue[] = ['node' => $root_node, 'level' => 0]; // 添加节点和层级(初始为0)
  1906. $storeStringCodeSet = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  1907. $storeStringCodeSet = json_decode($storeStringCodeSet['value'], true);
  1908. $string_code_max_layer = $storeStringCodeSet['string_code_max_layer'];
  1909. $temparr = [];
  1910. while (!empty($queue)) {
  1911. // 从队列中取出当前节点和层级
  1912. $current_item = array_shift($queue);
  1913. $current_node = $current_item['node'];
  1914. $current_level = $current_item['level'];
  1915. // 限制层级最大为 20 层
  1916. // if ($current_level >= 20) {
  1917. if ($current_level >= $string_code_max_layer) {
  1918. continue; // 超过 20 层,不继续查询子节点
  1919. }
  1920. $tempupuser = $current_node['user_id'];
  1921. // 查询当前节点的子节点
  1922. $children_nodes = self::find()->where(['store_id' => $store_id, 'parent_node' => $current_node['user_id']])->all();
  1923. // 将子节点添加到队列,并增加层级
  1924. if ($children_nodes) {
  1925. foreach ($children_nodes as $node) {
  1926. $queue[] = ['node' => $node, 'level' => $current_level + 1];
  1927. }
  1928. $tempuser = $children_nodes;
  1929. }
  1930. $temparr[] = ['level' => $current_level, 'user_id' => $tempupuser, 'parent_node' => $tempuser];
  1931. // 记录当前节点的 user_id
  1932. $child_ids[] = $current_node['user_id'];
  1933. }
  1934. return [
  1935. 'nodelist' => $temparr,
  1936. 'child_ids' => $child_ids
  1937. ];
  1938. }
  1939. public static function addOrderPvIntegralBonus($order)
  1940. {
  1941. //debug_log([__METHOD__, __LINE__, $order->order_no . '串码订单店铺让利-------- start --------'], "model_pv_integral_bonus_debug.log");
  1942. //debug_log([__METHOD__, __LINE__, json_encode($order, JSON_UNESCAPED_UNICODE)], "model_pv_integral_bonus_debug.log");
  1943. $store_id = $order->store_id;
  1944. $store = Store::findOne($store_id);
  1945. try {
  1946. //获取结算商户信息
  1947. $merchants = ScanCodePayOrderPercent::find()->where(['order_no' => $order->order_no, 'is_type' => 1])->asArray()->all();
  1948. if (!empty($merchants)) {
  1949. foreach ($merchants as $merchant) {
  1950. //店铺汇付配置支付则记录结算信息
  1951. if ($merchant['pay_price'] <= 0) {
  1952. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . "串码订单商户支付金额:" . $merchant['pay_price'] . " 0元"], "model_pv_integral_bonus_debug.log");
  1953. continue;
  1954. }
  1955. $subMoney = Store::subStoreMoney($store, $merchant['pay_price'], "扣{$merchant['desc']}奖励", $order->id, $order->user_id);
  1956. if (!$subMoney) {
  1957. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . "扣{$merchant['desc']}奖励:" . $merchant['pay_price'] . " 失败"], "model_pv_integral_bonus_debug.log");
  1958. return false;
  1959. }
  1960. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . "扣{$merchant['desc']}奖励:" . $merchant['pay_price'] . " 成功"], "model_pv_integral_bonus_debug.log");
  1961. }
  1962. return true;
  1963. }
  1964. //debug_log([__METHOD__, __LINE__, $order->order_no . '串码订单店铺让利:未获取结算商户信息----失败---- end --------'], "model_pv_integral_bonus_debug.log");
  1965. return false;
  1966. } catch (\Exception $e) {
  1967. //debug_log([__METHOD__, __LINE__, $order->order_no . "串码订单店铺让利失败:" . $e->getMessage() . ':' . $e->getLine() . ':' . $e->getFile() . '---- end --------'], "model_pv_integral_bonus_debug.log");
  1968. return false;
  1969. }
  1970. }
  1971. public static function addOrderPvIntegralBonus_back($order)
  1972. {
  1973. //debug_log([__METHOD__, __LINE__, $order->order_no . '串码订单店铺让利-------- start --------'], "model_pv_integral_bonus_debug.log");
  1974. //debug_log([__METHOD__, __LINE__, json_encode($order, JSON_UNESCAPED_UNICODE)], "model_pv_integral_bonus_debug.log");
  1975. $store_id = $order->store_id;
  1976. $store = Store::findOne($store_id);
  1977. if (!in_array($store->store_type, [Store::TYPE_STORE, Store::TYPE_BRAND])) {
  1978. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】类型即不是门店也不是品牌,不进行让利"], "model_pv_integral_bonus_debug.log");
  1979. return false;
  1980. }
  1981. //串码红包设置
  1982. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  1983. $setting = $setting ? Json::decode($setting['value']) : [];
  1984. $check_res = self::checkSettingByStoreId($store_id, $setting);
  1985. if (!$check_res) {
  1986. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】设置条件不满足"], "model_pv_integral_bonus_debug.log");
  1987. return false;
  1988. }
  1989. $t = \Yii::$app->db->beginTransaction();
  1990. try {
  1991. list($model_switch_shop, $model_switch_alliance) = self::getModelSwitchBySettingArray($setting['string_code_model']);
  1992. //大模型
  1993. $bigModelMoney = 0;
  1994. $oldBigModelMoney = $order->big_model_pv_bonus;
  1995. if ($model_switch_alliance) {
  1996. if ($order instanceof ScanOrder) {
  1997. $order_pv = $order->pay_price;
  1998. $order->big_model_pv_integral = bcmul($order_pv, $setting['string_code_scan_scale_1'] / 100, 8);
  1999. //debug_log([__METHOD__, __LINE__, $order->order_no . "大模型扫描订单PV:" . $order_pv . " 大模型pv积分:" . $order->big_model_pv_integral], "model_pv_integral_bonus_debug.log");
  2000. } else {
  2001. $order_pv = OrderDetail::find()
  2002. ->andWhere(['order_id' => $order['id'], 'is_delete' => 0])
  2003. ->select([
  2004. 'sum(pv_1)',
  2005. ])->scalar();
  2006. $order->big_model_pv_integral = bcmul($order_pv, $setting['string_code_order_scale_1'] / 100, 8);
  2007. //debug_log([__METHOD__, __LINE__, $order->order_no . "大模型商城订单PV:" . $order_pv . " 大模型pv积分:" . $order->big_model_pv_integral], "model_pv_integral_bonus_debug.log");
  2008. }
  2009. $bigModelMoney = bcmul($order_pv, $setting['string_code_pv_scale_1'] / 100, 8);
  2010. $order->big_model_pv_bonus = $bigModelMoney;
  2011. //debug_log([__METHOD__, __LINE__, $order->order_no . "大模型商城订单PV:" . $order_pv . " 大模型pv奖励:" . $bigModelMoney], "model_pv_integral_bonus_debug.log");
  2012. }
  2013. //小模型
  2014. $smallModelMoney = 0;
  2015. $oldSmallModelMoney = $order->small_model_pv_bonus;
  2016. if ($model_switch_shop) {
  2017. if ($order instanceof ScanOrder) {
  2018. $order_pv = $order->pay_price;
  2019. $order->small_model_pv_integral = bcmul($order_pv, $setting['string_code_scan_scale_0'] / 100, 8);
  2020. //debug_log([__METHOD__, __LINE__, $order->order_no . "小模型扫描订单PV:" . $order_pv . " 小模型pv积分:" . $order->small_model_pv_integral], "model_pv_integral_bonus_debug.log");
  2021. } else {
  2022. $order_pv = OrderDetail::find()
  2023. ->andWhere(['order_id' => $order['id'], 'is_delete' => 0])
  2024. ->select([
  2025. 'sum(pv_0)',
  2026. ])->scalar();
  2027. $order->small_model_pv_integral = bcmul($order_pv, $setting['string_code_order_scale_0'] / 100, 8);
  2028. //debug_log([__METHOD__, __LINE__, $order->order_no . "小模型商城订单PV:" . $order_pv . " 小模型pv积分:" . $order->small_model_pv_integral], "model_pv_integral_bonus_debug.log");
  2029. }
  2030. $smallModelMoney = bcmul($order_pv, $setting['string_code_pv_scale_0'] / 100, 8);
  2031. $order->small_model_pv_bonus = $smallModelMoney;
  2032. //debug_log([__METHOD__, __LINE__, $order->order_no . "小模型商城订单PV:" . $order_pv . " 小模型pv奖励:" . $smallModelMoney], "model_pv_integral_bonus_debug.log");
  2033. }
  2034. if ($order->save()) {
  2035. // //汇付支付账号是否平台账号
  2036. // if (is_use_platform_mch_huifu_id($order->huifu_id)) {
  2037. // //debug_log([__METHOD__, __LINE__, $order->order_no . '串码订单店铺让利---使用平台账号支付,汇付ID:' . $order->huifu_id], "model_pv_integral_bonus_debug.log");
  2038. // //小模型
  2039. // if ($oldSmallModelMoney == 0 && $smallModelMoney != 0) {
  2040. // $subMoney = Store::subStoreMoney($store, $smallModelMoney, '扣小模型PV奖励', $order->id, $order->user_id);
  2041. // if (!$subMoney) {
  2042. // $t->rollBack();
  2043. // //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣小模型PV奖励:" . $bigModelMoney . " 失败"], "model_pv_integral_bonus_debug.log");
  2044. // return false;
  2045. // }
  2046. // //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣小模型PV奖励:" . $bigModelMoney . " 成功"], "model_pv_integral_bonus_debug.log");
  2047. // }
  2048. // //大模型
  2049. // if ($oldBigModelMoney == 0 && $bigModelMoney != 0) {
  2050. // $subMoney = Store::subStoreMoney($store, $bigModelMoney, '扣大模型PV奖励', $order->id, $order->user_id);
  2051. // if (!$subMoney) {
  2052. // $t->rollBack();
  2053. // //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣大模型PV奖励:" . $bigModelMoney . " 失败"], "model_pv_integral_bonus_debug.log");
  2054. // return false;
  2055. // }
  2056. // //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣大模型PV奖励:" . $bigModelMoney . " 成功"], "model_pv_integral_bonus_debug.log");
  2057. // }
  2058. // }
  2059. //汇付支付账号是否平台账号
  2060. //debug_log([__METHOD__, __LINE__, "$order->order_no 串码订单店铺让利---使用平台账号支付,汇付ID:$order->huifu_id 小模型:$smallModelMoney 大模型:$bigModelMoney"], "model_pv_integral_bonus_debug.log");
  2061. if ($order->pay_type > 2000 && $order->pay_type < 3000) {
  2062. if (!empty($order->is_use_platform_mch)) {
  2063. //debug_log([__METHOD__, __LINE__, $order->order_no . '串码订单店铺让利---使用平台账号支付,汇付ID:' . $order->huifu_id], "model_pv_integral_bonus_debug.log");
  2064. //小模型
  2065. if ($oldSmallModelMoney == 0 && $smallModelMoney > 0) {
  2066. $subMoney = Store::subStoreMoney($store, $smallModelMoney, '扣小模型PV奖励', $order->id, $order->user_id);
  2067. if (!$subMoney) {
  2068. $t->rollBack();
  2069. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣小模型PV奖励:" . $bigModelMoney . " 失败"], "model_pv_integral_bonus_debug.log");
  2070. return false;
  2071. }
  2072. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣小模型PV奖励:" . $bigModelMoney . " 成功"], "model_pv_integral_bonus_debug.log");
  2073. }
  2074. //大模型
  2075. if ($oldBigModelMoney == 0 && $bigModelMoney > 0) {
  2076. $subMoney = Store::subStoreMoney($store, $bigModelMoney, '扣大模型PV奖励', $order->id, $order->user_id);
  2077. if (!$subMoney) {
  2078. $t->rollBack();
  2079. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣大模型PV奖励:" . $bigModelMoney . " 失败"], "model_pv_integral_bonus_debug.log");
  2080. return false;
  2081. }
  2082. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣大模型PV奖励:" . $bigModelMoney . " 成功"], "model_pv_integral_bonus_debug.log");
  2083. }
  2084. }
  2085. } else {
  2086. //debug_log([__METHOD__, __LINE__, $order->order_no . '串码订单店铺让利---使用平台账号支付,支付类型:' . $order->pay_type], "model_pv_integral_bonus_debug.log");
  2087. //小模型
  2088. if ($smallModelMoney > 0) {
  2089. $subMoney = Store::subStoreMoney($store, $smallModelMoney, '扣小模型PV奖励', $order->id, $order->user_id);
  2090. if (!$subMoney) {
  2091. $t->rollBack();
  2092. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣小模型PV奖励:" . $smallModelMoney . " 失败"], "model_pv_integral_bonus_debug.log");
  2093. return false;
  2094. }
  2095. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣小模型PV奖励:" . $smallModelMoney . " 成功"], "model_pv_integral_bonus_debug.log");
  2096. }
  2097. //大模型
  2098. if ($bigModelMoney > 0) {
  2099. $subMoney = Store::subStoreMoney($store, $bigModelMoney, '扣大模型PV奖励', $order->id, $order->user_id);
  2100. if (!$subMoney) {
  2101. $t->rollBack();
  2102. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣大模型PV奖励:" . $bigModelMoney . " 失败"], "model_pv_integral_bonus_debug.log");
  2103. return false;
  2104. }
  2105. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣大模型PV奖励:" . $bigModelMoney . " 成功"], "model_pv_integral_bonus_debug.log");
  2106. }
  2107. }
  2108. $t->commit();
  2109. //debug_log([__METHOD__, __LINE__, $order->order_no . '串码订单店铺让利----成功---- end --------'], "model_pv_integral_bonus_debug.log");
  2110. return true;
  2111. }
  2112. $t->rollBack();
  2113. //debug_log([__METHOD__, __LINE__, $order->order_no . '串码订单店铺让利:订单保存让利失败----失败---- end --------'], "model_pv_integral_bonus_debug.log");
  2114. return false;
  2115. } catch (\Exception $e) {
  2116. $t->rollBack();
  2117. //debug_log([__METHOD__, __LINE__, $order->order_no . '串码订单店铺让利失败:' . $e->getMessage()], "model_pv_integral_bonus_debug.log");
  2118. return false;
  2119. }
  2120. }
  2121. public static function getAgentSaasIdByOrder($order, $agentType, $money, $model_val, $modelType)
  2122. {
  2123. $commission = 0.00;
  2124. $agent = UserStringCodeOrder::TYPE_LIST[UserStringCodeOrder::TYPE_STRING_CODE_STORE_DISTRICT_AGENT_DIVVY];
  2125. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】{$modelType} {$agent}待分账金额:{$money} 门店:{$order->store_id} ------start-----"], "app_debug.log");
  2126. //获取店铺
  2127. $store = Store::findOne($order->store_id);
  2128. if (empty($store)) {
  2129. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】{$modelType} {$agent}待分账金额:{$money} 门店:{$order->store_id} 不存在"], "app_debug.log");
  2130. return $commission;
  2131. }
  2132. switch ($agentType) {
  2133. case UserStringCodeOrder::TYPE_STRING_CODE_STORE_DISTRICT_AGENT_DIVVY:
  2134. //区县代理商 $store['district_id']
  2135. $where['district_id'] = $store['district_id'];
  2136. $where['area_level'] = 1;
  2137. $order->district_agent_status = 1;
  2138. break;
  2139. case UserStringCodeOrder::TYPE_STRING_CODE_STORE_STREET_AGENT_DIVVY:
  2140. //街道代理商 $store['street_id']
  2141. $where['street_id'] = $store['street_id'];
  2142. $where['area_level'] = 4;
  2143. $order->street_agent_status = 1;
  2144. break;
  2145. default: //所有区县代理商分红 $store['district_id']
  2146. $where['area_level'] = 1;
  2147. $order->all_district_agent_status = 1;
  2148. break;
  2149. }
  2150. $where['is_delete'] = 0;
  2151. $where['is_enable'] = 1;
  2152. $admin = Admin::find()->where($where)->asArray()->all();
  2153. $agentNum = count($admin);
  2154. if ($agentNum > 0) {
  2155. $order->save();
  2156. $commissionMoney = bcdiv($money, $agentNum, 4);
  2157. if ($commissionMoney <= 0) {
  2158. //debug_log([__METHOD__, __LINE__, "代理商平均分红 【{$commissionMoney}】小于0.01不分红"], "app_debug.log");
  2159. }
  2160. foreach ($admin as $item) {
  2161. if ($item['saas_user_id']) {
  2162. $res = UserStringCodeOrder::transferAddUserWallet($order, $item['saas_user_id'], $commissionMoney, $agentType, $model_val);
  2163. if ($res) {
  2164. $commission += $commissionMoney;
  2165. }
  2166. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】{$modelType} {$agent}分账金额:{$commissionMoney} 门店:{$order->store_id} {{$agent}}ID:{$item['saas_user_id']}"], "app_debug.log");
  2167. } else {
  2168. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】{$modelType} {$agent}分账金额:{$commissionMoney} 门店:{$order->store_id} {{$agent}}未绑定 SaasId不分红"], "app_debug.log");
  2169. }
  2170. }
  2171. } else {
  2172. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】{$modelType} {$agent}不存在"], "app_debug.log");
  2173. }
  2174. //分红金额小于待分红金额,则分给指定用户
  2175. if ($money > $commission) {
  2176. $commissionMoney = $money - $commission;
  2177. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_SALE_SETTING, UserStringCodePlus::ALLIANCE_STORE_ID, OptionSetting::SHARE_GROUP_NAME, '{}');
  2178. $setting = $setting ? Json::decode($setting['value']) : [];
  2179. if ($setting['string_code_store_push_id']) {
  2180. UserStringCodeOrder::transferAddUserWallet($order, $setting['string_code_store_push_id'], $commissionMoney, $agentType, $model_val, true);
  2181. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】{$modelType} {$agent}分账剩余金额:{$commissionMoney} 代理商剩余让利用户ID:{$setting['string_code_store_push_id']}"], "app_debug.log");
  2182. } else {
  2183. //debug_log([__METHOD__, __LINE__, "串码让利 【{$model_val}】{$modelType} {$agent}分账剩余金额:{$commissionMoney} 代理商剩余让利用户不存在不继续分红"], "app_debug.log");
  2184. return $commission;
  2185. }
  2186. }
  2187. return $money;
  2188. }
  2189. //用于重新执行排位 手动执行 用于店铺id
  2190. public static function giveCoinAction($order, $is_scan, $to_store_id)
  2191. {
  2192. $store_id = $order->store_id;
  2193. $order_id = $order->id;
  2194. $user_id = $order->user_id;
  2195. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  2196. $setting = $setting ? Json::decode($setting['value']) : [];
  2197. $check_res = self::checkSettingByStoreId($store_id, $setting);
  2198. if (!$check_res) {
  2199. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】设置条件不满足"], "app_debug.log");
  2200. return false;
  2201. }
  2202. list($model_switch_shop, $model_switch_alliance) = self::getModelSwitchBySettingArray($setting['string_code_model']);
  2203. if ($to_store_id != -1) {
  2204. if ($model_switch_shop) {
  2205. if ($is_scan) {
  2206. $order_pv = $order->pay_price;
  2207. $money = bcmul($order_pv, $setting['string_code_scan_scale_0'] / 100, 4);
  2208. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[self::MODEL_SHOP] . " " . "赠送店铺分 当面付 联盟PV:【{$order_pv}】比例:【{$setting['string_code_scan_scale_0']}】"], "app_debug.log");
  2209. } else {
  2210. $order_pv_0 = OrderDetail::find()
  2211. ->andWhere(['order_id' => $order['id'], 'is_delete' => 0])
  2212. ->select([
  2213. 'sum(pv_0)',
  2214. ])->scalar();
  2215. $money = bcmul($order_pv_0, $setting['string_code_order_scale_0'] / 100, 4);
  2216. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[self::MODEL_SHOP] . " " . "赠送店铺分 商城单 联盟PV:【{$order_pv_0}】比例:【{$setting['string_code_order_scale_0']}】"], "app_debug.log");
  2217. }
  2218. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[self::MODEL_SHOP] . " " . "赠送店铺分 店铺:【{$store_id}】分值:【{$money}】"], "app_debug.log");
  2219. $log_type = $is_scan ? TempUserWallet::TYPE_SCAN : TempUserWallet::TYPE_ORDER;
  2220. $log_desc = self::MODEL_NAME_LIST[self::MODEL_SHOP] . " " . TempUserWallet::TYPE_NAME_LIST[$log_type] . "【{$order->order_no}】 赠送店铺分";
  2221. $source_table = $is_scan ? "\app\plugins\scanCodePay\models\Order" : "app\models\Order";
  2222. $currency = Currency::findOne(['code' => Currency::CURRENCY_COIN]);
  2223. TempUserWallet::addLog($currency, $store_id, $user_id, $money, $log_desc, $log_type, $source_table, $order_id);
  2224. }
  2225. }
  2226. if ($to_store_id == -1) {
  2227. if ($model_switch_alliance) {
  2228. $store_id = self::ALLIANCE_STORE_ID;
  2229. if ($is_scan) {
  2230. $order_pv = $order->pay_price;
  2231. $money = bcmul($order_pv, $setting['string_code_scan_scale_1'] / 100, 4);
  2232. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[self::MODEL_ALLIANCE] . " " . "赠送联盟分 当面付 联盟PV:【{$order_pv}】比例:【{$setting['string_code_scan_scale_1']}】"], "app_debug.log");
  2233. } else {
  2234. $order_pv_1 = OrderDetail::find()
  2235. ->andWhere(['order_id' => $order['id'], 'is_delete' => 0])
  2236. ->select([
  2237. 'sum(pv_1)',
  2238. ])->scalar();
  2239. $money = bcmul($order_pv_1, $setting['string_code_order_scale_1'] / 100, 4);
  2240. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[self::MODEL_ALLIANCE] . " " . "赠送联盟分 商城单 联盟PV:【{$order_pv_1}】比例:【{$setting['string_code_order_scale_1']}】"], "app_debug.log");
  2241. }
  2242. //debug_log([__METHOD__, __LINE__, self::MODEL_NAME_LIST[self::MODEL_ALLIANCE] . " " . "赠送联盟分 店铺:【{$store_id}】分值:【{$money}】"], "app_debug.log");
  2243. $log_type = $is_scan ? TempUserWallet::TYPE_SCAN : TempUserWallet::TYPE_ORDER;
  2244. $log_desc = self::MODEL_NAME_LIST[self::MODEL_ALLIANCE] . " " . TempUserWallet::TYPE_NAME_LIST[$log_type] . "【{$order->order_no}】 赠送联盟分";
  2245. $source_table = $is_scan ? "\app\plugins\scanCodePay\models\Order" : "app\models\Order";
  2246. $currency = Currency::findOne(['code' => Currency::CURRENCY_COIN]);
  2247. $saas_user_id = SaasUser::findSaasIdByUserId($order->user_id);
  2248. TempUserWallet::addLog($currency, $store_id, $saas_user_id, $money, $log_desc, $log_type, $source_table, $order_id);
  2249. }
  2250. }
  2251. }
  2252. //用于重新执行排位 加入排位
  2253. public static function joinNodeAction($order, $is_scan = 0, $to_store_id = -1)
  2254. {
  2255. $store_id = $order->store_id;
  2256. $user_id = $order->user_id;
  2257. $order_id = $order->id;
  2258. $order_no = $order->order_no;
  2259. $temporder = json_encode($order);
  2260. //debug_log([__METHOD__, __LINE__, "订单信息:【{$temporder}】- $store_id - $user_id - $order_id - $order_no - $is_scan "], "app_debug.log");
  2261. $saas_user_id = SaasUser::findSaasIdByUserId($user_id);
  2262. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  2263. $setting = $setting ? Json::decode($setting['value']) : [];
  2264. $check_res = self::checkSettingByStoreId($store_id, $setting);
  2265. if (!$check_res) {
  2266. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】设置条件不满足"], "app_debug.log");
  2267. return false;
  2268. }
  2269. //门店模式
  2270. $string_code_shop_value = 0;
  2271. if ($store_id != -1) {
  2272. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  2273. $setting = $setting ? Json::decode($setting['value']) : [];
  2274. $string_code_shop_value = $setting['string_code_shop_value'] ? $setting['string_code_shop_value'] : 0;
  2275. }
  2276. //debug_log([__METHOD__, __LINE__, "加入节点 门店模式:{$string_code_shop_value},0品牌模式 1门店模式"], "app_debug.log");
  2277. list($model_switch_shop, $model_switch_alliance) = self::getModelSwitchBySettingArray($setting['string_code_model']);
  2278. if ($to_store_id != -1) {
  2279. if ($model_switch_shop) {
  2280. self::joinNodeByShopModelAction($store_id, $user_id, $setting, self::MODEL_SHOP);
  2281. }
  2282. }
  2283. if ($to_store_id == -1) {
  2284. if ($model_switch_alliance) {
  2285. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, self::ALLIANCE_STORE_ID, OptionSetting::SHARE_GROUP_NAME, '{}');
  2286. $setting = $setting ? Json::decode($setting['value']) : [];
  2287. self::joinNodeByAllianceModelAction(self::ALLIANCE_STORE_ID, $saas_user_id, $setting, self::MODEL_ALLIANCE);
  2288. }
  2289. }
  2290. return true;
  2291. }
  2292. public static function joinNodeByShopModelAction($store_id, $user_id, $setting, $model_val, $string_code_shop_value = 0)
  2293. {
  2294. $user = User::findOne($user_id);
  2295. $saas_user_id = SaasUser::findSaasIdByUserId($user_id);
  2296. $model_name = self::MODEL_NAME_LIST[self::MODEL_SHOP];
  2297. $string_code_root_user_id = self::getRootUserId($store_id, self::MODEL_SHOP);
  2298. $user_string_code = self::findOne(['store_id' => $store_id, 'user_id' => $user_id]);
  2299. if ($user_string_code) {
  2300. //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$model_name},店铺:【{$store_id}】,用户:{$user_id}已加入串码节点"], "app_debug.log");
  2301. return false;
  2302. }
  2303. $root_string_code = self::findOne(['store_id' => $store_id, 'user_id' => $string_code_root_user_id]);
  2304. if (!$root_string_code) {
  2305. //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$model_name},店铺:【{$store_id}】,用户:{$user_id},根节点用户:{$string_code_root_user_id}不存在"], "app_debug.log");
  2306. return false;
  2307. }
  2308. $consume_amount = self::getStoreConsumeAmountAction($store_id, $user_id);
  2309. // //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$model_name},消费金额:{$consume_amount}"], "app_debug.log");
  2310. if (bccomp($consume_amount, $setting['string_code_condition_value'], 4) == -1) {
  2311. $msg = "加入节点 串码模式:{$model_name},店铺:【{$store_id}】,用户:{$user_id},消费:{$consume_amount} 未达到 {$setting['string_code_condition_value']} 元,加入串码节点失败";
  2312. //debug_log([__METHOD__, __LINE__, $msg], "app_debug.log");
  2313. return false;
  2314. }
  2315. $parent_id = !$user['parent_id'] ? $root_string_code['user_id'] : $user['parent_id'];
  2316. // 深度优先,从左至右
  2317. list($real_parent_node, $layer_rank, $area_key) = self::getRealParentNodePlus($store_id, $user_id, $parent_id, $setting['string_code_max_layer'], $model_val, $string_code_shop_value);
  2318. if (empty($real_parent_node['recommend_relation_node'])) {
  2319. $recommend_relation_node = ',' . $real_parent_node->user_id . ',';
  2320. } else {
  2321. $recommend_relation_node = $real_parent_node['recommend_relation_node'] . $real_parent_node->user_id . ',';
  2322. }
  2323. $parent_string_code = self::findOne(['store_id' => $store_id, 'user_id' => $parent_id]);
  2324. if (empty($parent_string_code['recommend_relation'])) {
  2325. $recommend_relation = ',' . $parent_string_code->user_id . ',';
  2326. } else {
  2327. $recommend_relation = $real_parent_node['recommend_relation'] . $parent_string_code->user_id . ',';
  2328. }
  2329. // 保存节点数据
  2330. $user_string_code = new self();
  2331. $user_string_code->store_id = $store_id;
  2332. $user_string_code->user_id = $user_id;
  2333. $user_string_code->parent_id = $parent_id;
  2334. $user_string_code->parent_node = $real_parent_node['user_id'];
  2335. $user_string_code->recommend_relation_node = $recommend_relation_node;
  2336. $user_string_code->layer_node = $real_parent_node['layer_node'] + 1;
  2337. $user_string_code->recommend_relation = $recommend_relation;
  2338. $user_string_code->layer = $parent_string_code['layer'] + 1;
  2339. $user_string_code->area_key = $area_key;
  2340. $user_string_code->layer_rank = $layer_rank;
  2341. $user_string_code->saas_id = $saas_user_id;
  2342. if (!$user_string_code->save()) {
  2343. $errors = json_encode($user_string_code->getErrors());
  2344. $msg = "加入节点 店铺:【{$store_id}】,用户:{$user_id},保存串码节点失败 {$errors}";
  2345. //debug_log([__METHOD__, __LINE__, $msg], "app_debug.log");
  2346. return false;
  2347. }
  2348. // 所有上级节点 团队人数 + 1
  2349. self::setTeamCountInc($store_id, $user_id);
  2350. return true;
  2351. }
  2352. public static function joinNodeByAllianceModelAction($store_id, $saas_user_id, $setting, $model_val, $string_code_shop_value = 0)
  2353. {
  2354. $user_id = $saas_user_id;
  2355. $user = SaasUser::findOne($saas_user_id);
  2356. $model_name = self::MODEL_NAME_LIST[self::MODEL_ALLIANCE];
  2357. $string_code_root_user_id = self::getRootUserId($store_id, self::MODEL_ALLIANCE);
  2358. $user_string_code = self::findOne(['store_id' => $store_id, 'user_id' => $user_id]);
  2359. if ($user_string_code) {
  2360. //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$model_name},用户:{$user_id}已加入串码节点"], "app_debug.log");
  2361. return false;
  2362. }
  2363. $root_string_code = self::findOne(['store_id' => $store_id, 'user_id' => $string_code_root_user_id]);
  2364. if (!$root_string_code) {
  2365. //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$model_name},用户:{$user_id}根节点不存在"], "app_debug.log");
  2366. return false;
  2367. }
  2368. $consume_amount = self::getStoreConsumeAmountAction($store_id, $user_id);
  2369. // //debug_log([__METHOD__, __LINE__, "加入节点 串码模式:{$model_name}, 消费金额:{$consume_amount}"], "app_debug.log");
  2370. if (bccomp($consume_amount, $setting['string_code_condition_value'], 4) == -1) {
  2371. $msg = "加入节点 串码模式:{$model_name},店铺:【{$store_id}】,用户:{$user_id},消费:{$consume_amount}未达到{$setting['string_code_condition_value']}元,加入串码节点失败";
  2372. //debug_log([__METHOD__, __LINE__, $msg], "app_debug.log");
  2373. return false;
  2374. }
  2375. $parent_id = !$user['parent_id'] ? $root_string_code['user_id'] : $user['parent_id'];
  2376. // 深度优先,从左至右
  2377. list($real_parent_node, $layer_rank, $area_key) = self::getRealParentNodePlus($store_id, $user_id, $parent_id, $setting['string_code_max_layer'], $model_val, $string_code_shop_value);
  2378. if (empty($real_parent_node['recommend_relation_node'])) {
  2379. $recommend_relation_node = ',' . $real_parent_node->user_id . ',';
  2380. } else {
  2381. $recommend_relation_node = $real_parent_node['recommend_relation_node'] . $real_parent_node->user_id . ',';
  2382. }
  2383. $parent_string_code = self::findOne(['store_id' => $store_id, 'user_id' => $parent_id]);
  2384. if (empty($parent_string_code['recommend_relation'])) {
  2385. $recommend_relation = ',' . $parent_string_code->user_id . ',';
  2386. } else {
  2387. $recommend_relation = $real_parent_node['recommend_relation'] . $parent_string_code->user_id . ',';
  2388. }
  2389. // 保存节点数据
  2390. $user_string_code = new self();
  2391. $user_string_code->store_id = $store_id;
  2392. $user_string_code->user_id = $user_id;
  2393. $user_string_code->parent_id = $parent_id;
  2394. $user_string_code->parent_node = $real_parent_node['user_id'];
  2395. $user_string_code->recommend_relation_node = $recommend_relation_node;
  2396. $user_string_code->layer_node = $real_parent_node['layer_node'] + 1;
  2397. $user_string_code->recommend_relation = $recommend_relation;
  2398. $user_string_code->layer = $parent_string_code['layer'] + 1;
  2399. $user_string_code->area_key = $area_key;
  2400. $user_string_code->layer_rank = $layer_rank;
  2401. $user_string_code->saas_id = $saas_user_id;
  2402. if (!$user_string_code->save()) {
  2403. $errors = json_encode($user_string_code->getErrors());
  2404. $msg = "加入节点 店铺:【{$store_id}】,用户:{$user_id},保存串码节点失败 {$errors}";
  2405. //debug_log([__METHOD__, __LINE__, $msg], "app_debug.log");
  2406. return false;
  2407. }
  2408. // 所有上级节点 团队人数 + 1
  2409. self::setTeamCountInc($store_id, $user_id);
  2410. return true;
  2411. }
  2412. public static function getStoreConsumeAmountAction($store_id, $user_id)
  2413. {
  2414. // 联盟分
  2415. $user_wallet = TempUserWallet::getCurrencyWallet($store_id, $user_id, Currency::CURRENCY_COIN);
  2416. return $user_wallet['money_total'] ?: 0;
  2417. }
  2418. public static function countOrderPvBonus($order)
  2419. {
  2420. $store_id = $order->store_id;
  2421. $store = Store::findOne($store_id);
  2422. if (!in_array($store->store_type, [Store::TYPE_STORE, Store::TYPE_BRAND])) {
  2423. // 判断店铺类型 {{ text == 0 ? '默认' : text == 1 ? '品牌' : '门店' }}
  2424. // {{ text == 1 ? '独立运营' : text == 2 ? '平台运营' : text == 3 ? '当面付' : text == 4 ? '点餐' : '' }}
  2425. if ($store->business_model == 3) {
  2426. $store->store_type = 2;
  2427. } else {
  2428. $store->store_type = 1;
  2429. }
  2430. $store->save();
  2431. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】类型即不是门店也不是品牌,不进行让利"], "app_debug.log");
  2432. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】business_model:【{$store->business_model}】自动变更店铺类型store_type:【{$store->store_type}】"], "app_debug.log");
  2433. // return false;
  2434. }
  2435. if ($order instanceof ScanOrder) {
  2436. $setting = Option::get(OptionSetting::SHARE_STRING_CODE_DEFAULT_SETTING, $store_id, OptionSetting::SHARE_GROUP_NAME, '{}');
  2437. if (empty($setting)) {
  2438. //debug_log([__METHOD__, __LINE__, "店铺:【{$store_id}】串码红包未设置,不进行让利"], "huifu_payment_debug.log.log");
  2439. return false;
  2440. }
  2441. //串码红包设置
  2442. $setting = Json::decode($setting['value']);
  2443. $bigModelMoney = !empty($setting['string_code_pv_scale_1']) ? bcmul($order->pay_price, $setting['string_code_pv_scale_1'] / 100, 8) : 0;
  2444. $smallModelMoney = !empty($setting['string_code_pv_scale_0']) ? bcmul($order->pay_price, $setting['string_code_pv_scale_0'] / 100, 8) : 0;
  2445. } else {
  2446. $bigModelMoney = OrderDetail::find()
  2447. ->andWhere(['order_id' => $order['id'], 'is_delete' => 0])
  2448. ->select([
  2449. 'sum(pv_1)',
  2450. ])->scalar();
  2451. $smallModelMoney = OrderDetail::find()
  2452. ->andWhere(['order_id' => $order['id'], 'is_delete' => 0])
  2453. ->select([
  2454. 'sum(pv_0)',
  2455. ])->scalar();
  2456. }
  2457. //大模型
  2458. $order->big_model_pv_bonus = $bigModelMoney ?? 0;
  2459. //小模型
  2460. $order->small_model_pv_bonus = $smallModelMoney ?? 0;
  2461. $order->save();
  2462. return $smallModelMoney + $bigModelMoney;
  2463. }
  2464. //商城让利合伙人
  2465. public static function sendMakeConcessionsByOrder($order, $setting, $is_scan, $store)
  2466. {
  2467. $temp_store = json_encode($setting['string_make_doncessions_userlist']);
  2468. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 【商城让利是否开启:{$setting['string_make_doncessions_switch']} 商城订单是否开启:{$setting['string_make_doncessions_order']} 扫码订单是否开启:{$setting['string_make_doncessions_scan']} 商城让利人员:{$temp_store}"], "app_debug.log");
  2469. list($model_switch_shop, $model_switch_alliance) = UserStringCodePlus::getModelSwitchBySettingArray($setting['string_code_model']);
  2470. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 【商城串码模型:{$setting['string_code_model']}"], "app_debug.log");
  2471. if (empty($setting['string_code_make_concessions'])) {
  2472. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 【商城让利人比例:{$setting['string_code_make_concessions']} 未设置"], "app_debug.log");
  2473. return;
  2474. }
  2475. if ($setting['string_code_make_concessions'] <= 0) {
  2476. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 【商城让利人比例:{$setting['string_code_make_concessions']} 设置不正确"], "app_debug.log");
  2477. return;
  2478. }
  2479. if ($model_switch_shop) {
  2480. //执行小模型前验证
  2481. if (is_array($setting['string_make_doncessions_userlist']) && !empty($setting['string_make_doncessions_userlist'])) {
  2482. // $dataSource 是有效的非空数组
  2483. self::sendMakeConcessionsByOrderStore($order, $setting, $is_scan, 0);
  2484. } else {
  2485. // $dataSource 不是有效的数组或是空数组
  2486. if (empty($setting['string_code_make_concessions_saas_id'])) {
  2487. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 小模型 【商城剩余让利人{$setting['string_code_make_concessions']} 未设置 以及 店铺商城让利合伙人 未设置"], "app_debug.log");
  2488. } else {
  2489. //执行发放逻辑
  2490. self::sendMakeConcessionsByOrderStore($order, $setting, $is_scan, 0);
  2491. }
  2492. }
  2493. }
  2494. if ($model_switch_alliance) {
  2495. //执行大模型前验证
  2496. if (is_array($setting['string_make_doncessions_userlist']) && !empty($setting['string_make_doncessions_userlist'])) {
  2497. // $dataSource 是有效的非空数组
  2498. self::sendMakeConcessionsByOrderStore($order, $setting, $is_scan, 1);
  2499. } else {
  2500. // $dataSource 不是有效的数组或是空数组
  2501. if (empty($setting['string_code_make_concessions_saas_id'])) {
  2502. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 大模型 【商城剩余让利人{$setting['string_code_make_concessions']} 未设置 以及 店铺商城让利合伙人 未设置"], "app_debug.log");
  2503. } else {
  2504. //执行发放逻辑
  2505. self::sendMakeConcessionsByOrderStore($order, $setting, $is_scan, 1);
  2506. }
  2507. }
  2508. }
  2509. //检测是否有发放 有直接更新订单状态
  2510. $UserStringCodeOrderlist = UserStringCodeOrder::findAll([
  2511. 'order_id' => $order->id,
  2512. 'is_scan' => $is_scan,
  2513. 'type' => [UserStringCodeOrder::TYPE_STRING_CODE_BRAND_MAKE_DONCESSIONS]
  2514. ]);
  2515. $temp_count = count($UserStringCodeOrderlist);
  2516. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 执行记录有:{$temp_count}"], "app_debug.log");
  2517. if (count($UserStringCodeOrderlist) > 0) {
  2518. $temp_order = json_encode($order);
  2519. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 订单信息:{$temp_order}"], "app_debug.log");
  2520. $order->make_concessions_status = 1;
  2521. if ($order->save()) {
  2522. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 状态修改失败"], "app_debug.log");
  2523. }
  2524. // 计算合并结果的总金额
  2525. $ModelMoney = 0;
  2526. foreach ($UserStringCodeOrderlist as $ordertempr) {
  2527. if ($ordertempr['status'] == 1) {
  2528. $ModelMoney += $ordertempr['money']; // 累加金额
  2529. }
  2530. }
  2531. try {
  2532. if ($order->is_use_platform_mch == 1 && ($order->pay_type == 1 || in_array($order->pay_type, array_keys(Order::HUIFU_PAYMENT_PAY_TYPE)))) {
  2533. //扣除店铺金额
  2534. $subMoney = Store::subStoreMoney($store, $ModelMoney, '扣商城让利合伙人分红', $order->id, $order->user_id);
  2535. if (!$subMoney) {
  2536. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣商城让利合伙人分红:" . $ModelMoney . " 失败"], "app_debug.log");
  2537. }
  2538. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣商城让利合伙人分红:" . $ModelMoney . " 成功"], "app_debug.log");
  2539. } else {
  2540. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 已分账,不用扣商城让利合伙人分红 成功"], "app_debug.log");
  2541. }
  2542. } catch (\Exception $e) {
  2543. //debug_log([__METHOD__, __LINE__, "扣商城让利合伙人分红:{$e->getMessage()}"], "app_debug.log");
  2544. }
  2545. }
  2546. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 执行完成"], "app_debug.log");
  2547. }
  2548. //商城让利合伙人
  2549. public static function sendMakeConcessionsScan($order, $setting, $is_scan, $store, $model_val)
  2550. {
  2551. $temp_store = json_encode($setting['string_make_doncessions_userlist']);
  2552. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 【商城让利是否开启:{$setting['string_make_doncessions_switch']} 商城订单是否开启:{$setting['string_make_doncessions_order']} 扫码订单是否开启:{$setting['string_make_doncessions_scan']} 商城让利人员:{$temp_store}"], "app_debug.log");
  2553. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 【商城串码模型:{$setting['string_code_model']}"], "app_debug.log");
  2554. if (empty($setting['string_code_make_concessions'])) {
  2555. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 【商城让利人比例:{$setting['string_code_make_concessions']} 未设置"], "app_debug.log");
  2556. return;
  2557. }
  2558. if ($setting['string_code_make_concessions'] <= 0) {
  2559. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 【商城让利人比例:{$setting['string_code_make_concessions']} 设置不正确"], "app_debug.log");
  2560. return;
  2561. }
  2562. //执行小模型前验证
  2563. if (is_array($setting['string_make_doncessions_userlist']) && !empty($setting['string_make_doncessions_userlist'])) {
  2564. // $dataSource 是有效的非空数组
  2565. self::sendMakeConcessionsByOrderStore($order, $setting, $is_scan, $model_val);
  2566. } else {
  2567. // $dataSource 不是有效的数组或是空数组
  2568. if (empty($setting['string_code_make_concessions_saas_id'])) {
  2569. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 小模型 【商城剩余让利人{$setting['string_code_make_concessions']} 未设置 以及 店铺商城让利合伙人 未设置"], "app_debug.log");
  2570. } else {
  2571. //执行发放逻辑
  2572. self::sendMakeConcessionsByOrderStore($order, $setting, $is_scan, $model_val);
  2573. }
  2574. }
  2575. //检测是否有发放 有直接更新订单状态
  2576. $UserStringCodeOrderlist = UserStringCodeOrder::findAll([
  2577. 'order_id' => $order->id,
  2578. 'is_scan' => $is_scan,
  2579. 'type' => [UserStringCodeOrder::TYPE_STRING_CODE_BRAND_MAKE_DONCESSIONS]
  2580. ]);
  2581. $temp_count = count($UserStringCodeOrderlist);
  2582. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 执行记录有:{$temp_count}"], "app_debug.log");
  2583. if (count($UserStringCodeOrderlist) > 0) {
  2584. $temp_order = json_encode($order);
  2585. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 订单信息:{$temp_order}"], "app_debug.log");
  2586. $order->make_concessions_status = 1;
  2587. if ($order->save()) {
  2588. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 状态修改失败"], "app_debug.log");
  2589. }
  2590. // 计算合并结果的总金额
  2591. $ModelMoney = 0;
  2592. foreach ($UserStringCodeOrderlist as $ordertempr) {
  2593. if ($ordertempr['status'] == 1) {
  2594. $ModelMoney += $ordertempr['money']; // 累加金额
  2595. }
  2596. }
  2597. try {
  2598. if ($order->is_use_platform_mch == 1 && ($order->pay_type == 1 || in_array($order->pay_type, array_keys(Order::HUIFU_PAYMENT_PAY_TYPE)))) {
  2599. //扣除店铺金额
  2600. $subMoney = Store::subStoreMoney($store, $ModelMoney, '扣商城让利合伙人分红', $order->id, $order->user_id);
  2601. if (!$subMoney) {
  2602. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣商城让利合伙人分红:" . $ModelMoney . " 失败"], "app_debug.log");
  2603. }
  2604. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 扣商城让利合伙人分红:" . $ModelMoney . " 成功"], "app_debug.log");
  2605. } else {
  2606. //debug_log([__METHOD__, __LINE__, $order->order_no . "店铺:" . $store->name . " 已分账,不用扣商城让利合伙人分红 成功"], "app_debug.log");
  2607. }
  2608. } catch (\Exception $e) {
  2609. //debug_log([__METHOD__, __LINE__, "扣商城让利合伙人分红:{$e->getMessage()}"], "app_debug.log");
  2610. }
  2611. }
  2612. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 执行完成"], "app_debug.log");
  2613. }
  2614. // 商城让利合伙人分红
  2615. public static function sendMakeConcessionsByOrderStore($order, $setting, $is_scan, $model_val)
  2616. {
  2617. if (empty($setting['string_make_doncessions_switch'])) {
  2618. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 商城让利合伙人模式未设置"], "app_debug.log");
  2619. return;
  2620. }
  2621. if ($setting['string_make_doncessions_switch'] == 0) {
  2622. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 商城让利合伙人模式未开启"], "app_debug.log");
  2623. return;
  2624. }
  2625. if ($is_scan == 0) {
  2626. //商城订单
  2627. if (empty($setting['string_make_doncessions_order']) || $setting['string_make_doncessions_order'] == 0) {
  2628. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 商城订单商城让利合伙人状态未设置"], "app_debug.log");
  2629. } else {
  2630. //debug_log([__METHOD__, __LINE__, "执行 商城让利人分红"], "app_debug.log");
  2631. /*$order_pv = OrderDetail::find()
  2632. ->andWhere(['order_id' => $order['id'], 'is_delete' => 0])
  2633. ->select([
  2634. 'sum(pv_0)',
  2635. ])->scalar();
  2636. self::sendMakeConcessionsByOrderGrant($order, $order_pv, $setting['string_code_make_concessions'], $setting['string_code_make_concessions_saas_id'], $setting['string_make_doncessions_userlist'], 0);
  2637. $order_pv = OrderDetail::find()
  2638. ->andWhere(['order_id' => $order['id'], 'is_delete' => 0])
  2639. ->select([
  2640. 'sum(pv_1)',
  2641. ])->scalar();*/
  2642. self::sendMakeConcessionsByOrderGrant($order, $order->pay_price, $setting['string_code_make_concessions'], $setting['string_code_make_concessions_saas_id'], $setting['string_make_doncessions_userlist'], $model_val);
  2643. //debug_log([__METHOD__, __LINE__, "执行 商城让利人分红:" . $setting['string_code_make_concessions'] . '======'], "app_debug.log");
  2644. }
  2645. } else {
  2646. //扫码订单
  2647. if (empty($setting['string_make_doncessions_scan']) || $setting['string_make_doncessions_scan'] == 0) {
  2648. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 商城订单商城让利合伙人状态未设置"], "app_debug.log");
  2649. } else {
  2650. //debug_log([__METHOD__, __LINE__, "执行 扫码分红"], "app_debug.log");
  2651. self::sendMakeConcessionsByOrderGrant($order, $order->pay_price, $setting['string_code_make_concessions_scan'], $setting['string_code_make_concessions_saas_id'], $setting['string_make_doncessions_userlist'], $model_val);
  2652. }
  2653. }
  2654. }
  2655. // 商城让利合伙人分红
  2656. public static function sendMakeConcessionsByOrderGrant($order, $transfer_money, $string_code_make_concessions, $push_saas_id, $string_make_doncessions_userlist, $model_val)
  2657. {
  2658. $money = bcmul($transfer_money, $string_code_make_concessions / 100, 4);
  2659. if ($string_make_doncessions_userlist) {
  2660. $moneytran_temp = 0;
  2661. if (is_array($string_make_doncessions_userlist)) {
  2662. // 遍历数组
  2663. $string_make_doncessions_userlist = self::NewUserList($string_make_doncessions_userlist);
  2664. foreach ($string_make_doncessions_userlist as $item) {
  2665. $moneytran = 0;
  2666. //debug_log([__METHOD__, __LINE__, "div1===" . bcmul(bcmul($money, $item['percent'], 8), $item['weight'], 8)], "app_debug.log");
  2667. if ($item['total_weight'] > 0 && bcmul(bcmul($money, $item['percent'], 8), $item['weight'], 8) > 0) {
  2668. $moneytran = bcmul(
  2669. bcdiv(
  2670. bcmul($money, $item['percent'], 8),
  2671. $item['total_weight'],
  2672. 8
  2673. ),
  2674. $item['weight'],
  2675. 8
  2676. );
  2677. }
  2678. //debug_log([__METHOD__, __LINE__, "div2====" . $moneytran] . '====' . $item['total_weight'] . '===' . $item['weight'] . '===' . $item['percent'], "app_debug.log");
  2679. $moneytran = sprintf("%.4f", $moneytran);
  2680. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 总的{$money} 当前商城没设置参与人员:{$item['saas_id']} 获得:{$moneytran}"], "app_debug.log");
  2681. UserStringCodeOrder::transferAddUserWalletAndStoreid($order, $item['saas_id'], $moneytran, UserStringCodeOrder::TYPE_STRING_CODE_BRAND_MAKE_DONCESSIONS, $model_val, $order->store_id, false);
  2682. $moneytran_temp = bcadd($moneytran_temp, $moneytran, 4);
  2683. }
  2684. }
  2685. $moneytran_sy = $money - $moneytran_temp;
  2686. if ($moneytran_sy > 0) {
  2687. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人 总的{$money} 平分后还有剩余:{$moneytran_sy} 直接给剩余让利人{$push_saas_id} "], "app_debug.log");
  2688. UserStringCodeOrder::transferAddUserWalletAndStoreid($order, $push_saas_id, $moneytran_sy, UserStringCodeOrder::TYPE_STRING_CODE_BRAND_MAKE_DONCESSIONS, $model_val, $order->store_id, true);
  2689. }
  2690. } else {
  2691. //debug_log([__METHOD__, __LINE__, "串码让利 商城让利合伙人总的{$money} 当前商城没设置参与人员 全部给剩余让利人:{$push_saas_id}"], "app_debug.log");
  2692. UserStringCodeOrder::transferAddUserWalletAndStoreid($order, $push_saas_id, $money, UserStringCodeOrder::TYPE_STRING_CODE_BRAND_MAKE_DONCESSIONS, $model_val, $order->store_id, true);
  2693. }
  2694. }
  2695. public static function NewUserList($data)
  2696. {
  2697. foreach ($data as &$value) {
  2698. $level_info = \Yii::$app->db->createCommand('select * from cyy_store_partner_level where id=:id')->bindValue(':id', $value['level_id'])->queryOne();
  2699. $value['percent'] = $level_info['profit_rate'] / 100;
  2700. //debug_log([__METHOD__, __LINE__, "div2====" . $level_info['name'] . '=user_id:' . $value['saas_id']], "app_debug.log");
  2701. }
  2702. $total_weights = [];
  2703. foreach ($data as $item) {
  2704. $level_id = $item['level_id'];
  2705. $weight = (int)$item['weight']; // 确保 weight 是整数
  2706. if (!isset($total_weights[$level_id])) {
  2707. $total_weights[$level_id] = 0;
  2708. }
  2709. $total_weights[$level_id] += $weight;
  2710. }
  2711. // Step 2: 将 total_weight 添加到每个数组元素中
  2712. foreach ($data as &$item) {
  2713. $level_id = $item['level_id'];
  2714. $item['total_weight'] = $total_weights[$level_id];
  2715. }
  2716. // 释放引用
  2717. unset($item);
  2718. return $data;
  2719. }
  2720. private static function adAwardSend($store_id, $order_pv, $rate, $manager, $model, $order, $string_code_store_push_id)
  2721. {
  2722. $store = Store::find()->where(['id' => $store_id])->select(['salesman_id', 'district_id'])->asArray()->one();
  2723. $salesman_id = $store['salesman_id'];
  2724. //debug_log([__METHOD__, __LINE__, "============拓展经理:($salesman_id),广告推流店铺id:" . $store_id], "app_debug.log");
  2725. if ($order_pv <= 0) return false;
  2726. $salesman = Salesman::findOne(['id' => $salesman_id, 'is_delete' => 0, 'status' => 1]);
  2727. $admin = Admin::findOne(['id' => $salesman->admin_id, 'is_delete' => 0]);
  2728. $manager_money = $order_pv * $manager / 100;
  2729. if ($manager && $salesman->saas_user_id) {
  2730. //debug_log([__METHOD__, __LINE__, "============拓展经理金额 : " . ($manager_money)], "app_debug.log");
  2731. UserStringCodeOrder::transferAddUserWallet($order, $salesman->saas_user_id, $manager_money, UserStringCodeOrder::TYPE_EXPAND_MANAGER, $model);
  2732. }else{
  2733. if ($string_code_store_push_id){
  2734. UserStringCodeOrder::transferAddUserWallet($order, $string_code_store_push_id, $manager_money, UserStringCodeOrder::TYPE_EXPAND_MANAGER, $model);
  2735. }
  2736. }
  2737. if ($rate){
  2738. $money = $order_pv * $rate / 100;
  2739. if ($admin->advert_push_user_id) {
  2740. //debug_log([__METHOD__, __LINE__, "============广告推流金额 : " . ($money)], "app_debug.log");
  2741. UserStringCodeOrder::transferAddUserWallet($order, $admin->advert_push_user_id, $money, UserStringCodeOrder::TYPE_BD_AGENT, $model);
  2742. }else{
  2743. if ($string_code_store_push_id){
  2744. UserStringCodeOrder::transferAddUserWallet($order, $string_code_store_push_id, $money, UserStringCodeOrder::TYPE_BD_AGENT, $model);
  2745. }
  2746. }
  2747. }
  2748. return true;
  2749. }
  2750. private static function hotAwardSend($saas_id, $rate, $founder, $order_pv, $model, $order)
  2751. {
  2752. $money = $order_pv * $rate / 100;
  2753. //debug_log([__METHOD__, __LINE__, "============热动代理人金额 : " . ($money)], "app_debug.log");
  2754. if ($saas_id && $money > 0) {
  2755. UserStringCodeOrder::transferAddUserWallet($order, $saas_id, $money, UserStringCodeOrder::TYPE_AD_HOT, $model);
  2756. }
  2757. $money = $order_pv * $founder / 100;
  2758. //debug_log([__METHOD__, __LINE__, "============热动广告推流金额 : " . ($money)], "app_debug.log");
  2759. if ($saas_id && $money > 0) {
  2760. UserStringCodeOrder::transferAddUserWallet($order, $saas_id, $money, UserStringCodeOrder::TYPE_STRING_CODE_STORE_DISTRICT_AGENT_DIVVY, $model);
  2761. }
  2762. }
  2763. }